PostgreSQL 在進入 8.0 版時,整套系統的架構大變,新增了不少功能和架構, Tablespace 就是其中一項。當我第一次在 pgAdmin III 上看到 Tablespace 這個字眼出現時,我是非常興奮的,因為要在較大型的資料庫中,才會有這種概念。尤其是之前有 Oracle 的實作經驗,所以看到熟悉的字眼出現時,備感親切,而內心對它充滿期待。但是在進一步深入研究後,就有如被潑了一桶冷水一樣,PostgreSQL 的 Tablespace 和 Oracle 的 Tablespace 功能上差距還不小,實作上更是不一樣。
首先來說明一下,什麼是 Tablespace?Tablespace 一般都翻譯成表格空間。而表格空間,按照手冊上的定義,是整個系統的資料主體。其實呢,用白話一點的說法,Tablespace 是實體資料儲存的基本單位。以官方的說法來說,Tablespace,也就是表格空間,當初設計的目的是為了 DBMS 整體調校之用。這個目的和 Oracle 的 Tablespace 的設計目的很像,但是實作上卻是有不少差距。
在作業系統層面,Tablespace 是以目錄的形式存在檔案系統中。而所有存放在該 Tablespace 的物件,則是以子目錄或檔案的形式儲存在硬碟中。還記得前一陣子我所發表的 PostgreSQL 如何組織資料 的內容吧!PostgreSQL 把它所有的物件都以目錄和檔案的形式,用物件的 OID 為識別,分別儲存起來。Tablespace 身為 Databses、Tables 等等物件的 container,當然一定也是以類似的方式儲存在檔案系統當中。不同的是,除了預設的兩個 Tablespaces 以外,其餘自訂的 Tablespace 在檔案系統中是以 symbolic links 的形式存在的。就是因為它在檔案系統中,是以 symbolic links 的形式存在,因此,Windows 版本的 PostgreSQL,由於作業系統的功能限制,「理論上」使用者無法建立自己的 tablespace。我不清楚 PostgreSQL Win32 版是否設計了一個新的方式,能夠讓 Windows 2003/2008 打破這個理論上的藩籬。但是我確定在 Windows XP/Vista 上,很不幸的,可說是「幾乎」沒有可能性,讓使用者使用這部份的功能(或許加裝 Cygwin 能夠解決,但是這一點我還要測試一下)。
至於為什麼 Tablespace 要以 Symbolic Links 形式存在於檔案系統中,要知道原因,我想先從介紹 Oracle 的架構說起。Oracle 的資料物件,並不像 PostgreSQL 一樣,是以各別的檔案儲存起來的。Oracle 的 DBMS 底層是一堆黑盒子。Oracle 的底層是由一堆 Datafiles 和 Control files 組合而成。資料物件全部統一儲存在 Datafiles 中,而儲存的方式和細部,由 Control files 的定義來設定。而 Datafile 的內部儲存方式,則是一個黑盒子。也由於還要搭配 Control files 才能存取資料,所以你無法用簡單而有效率的方式來備份、維護資料庫,而要去準備一堆認證課程,用一堆工具;不管是 Oracle 的或第三方的;才能好好維護 Oracle 中的資料。而 Tablespace 在 Oracle 當中,雖然也是 DBMS 的最基本的 container,但是它卻是由一堆 Datafiles 和 Control files 組合而成,自成一個戰鬥單位。所以當你要做系統調校時,你可以讓該 Tablespace 所屬 Datafiles 和 Control files 分別儲存在不同的硬碟中,或是其它的安排。在這些實體儲存單位的妥善安排,來提高系統的效能。再來是當原本的儲存空間不足的時候,你也可以再找一顆新的硬碟來掛上,再在這顆新硬碟中新增新的 Datafiles,這樣就可以輕鬆的解決儲存空間不足的問題。當然,Oracle 如何把資料分散在這些 Datafiles 中,手冊故意寫得很神祕,感覺上 DBMS 會很神奇的幫你找出最有效率的儲存方式來安排在這些 Datfiles 當中,但是,who knows?sales talk 吧!
至於 PostgreSQL,我在前一篇 PostgreSQL 如何組織資料 已經展示了,PostgreSQL 是以各別的目錄和檔案方式儲存在實體儲存媒介上。這個方法的優點是開放、透明,缺點就是吃掉不少 inode(以 Unix 來說)。由於每個物件都是以各別檔案存在,所以就以邏輯上而言,身為它們的 container,Tablespace 必然要以目錄的形式存在。但是,要如何做到像 Oracle 一樣,如何使用 Tablespace 把資料物件分散到另一顆硬碟或以 NFS 掛上另一台機器的檔案系統?這時就出了邏輯上的問題了。在檔寀系統中,同一台機器中,在目錄以上已經沒有更大的 container 單位了。那麼如果要在 PostgreSQL 上實作出類似的功能,恐怕對 Tablespace 的定義就要有所改變。因此,在 PostgreSQL 上,Tablespace 不但是邏輯的存取容器,也是基本的實體儲存容器;不像 Oracle,Tablespace 只是邏輯上的容器,實體則是那些 Datafiles 和 Control files。而要做到跨硬碟或 NFS mount,那麼就用到了 Unix 的 Symbolic links,因為用 Symbolic links,可以在 $PGDATA 下留下一條連結,連結到另一顆硬碟或另一台機器分享出來的空間。這樣做又簡單、又有效率。
但是問題就出在跨到 Windows 下時,由於 Windows 沒有 Symbolic links 的概念,只有一個很難用的「捷徑」,這下子問題就來了,因為「捷徑」並不等於 symbolic links,兩者的使用和定義完全不同。把 Tablespace 轉移到 Windows 的實作上,看樣子還有不少努力的空間。
接著,我們來聊聊那兩個預設的 Tablespace:pg_global 和 pg_default。官方文件中對於這兩個 Tablespace 的用途是這樣說的:「PostgreSQL 使用 pg_global 來存放和系統有關的物件;使用 pg_default 表格空間來存放使用者建立的資料庫物件」。也就是說,在 Oracle 當中,每個 Tablespace 的 Control files 當中的內容,在 PostgreSQL 是由一個專屬的 Tablespace pg_global 來統一管理;而預設是你所建立的所有物件會存放在 pg_default 這個表格空間;當然如果你指定存放在你所建立的自訂表格空間,那麼物件就會存到你指定的表格空間裏;若是沒指定,PostgreSQL 就當作你打算使用預設位置,所以就會存在 pg_default。
在這篇文章的最後,我們來看看在官方的文件定義上,有關 Tablespace 的文字。在中文化文件中,有下列幾行文字:
表格空間決定著DBMS整體效能的重點調校之一,還有:
在以下的情況 DBA 就有必要考量 Tablespace 的分割與配置:以上是中國 PostgreSQL 社群翻的「葡萄牙文式」的中文化文件的內容。只要是台灣人,大概都懂得我在說些什麼。其實這段文字主要是在說明為什麼要有表格空間。PostgreSQL 社群加入表格空間這個物件的目的,和 Oracle 是一樣的,主要目的在於效能的調校。所以當發生單一硬碟中的 transaction logs 和資料本身存取的存取競爭時(這東西要說明還要再寫一篇文章!),你就必須考慮把資料物件存到另一顆硬碟上,因為存取競爭勢必降低效能。另外,大型物件和小型物件並存在一個表格空間時,由於硬碟存取資料是「隨機」的,所以小型物件勢必淹沒在大型物件中,這樣小型物件的存取效能也一定會降低。再來就是資料本身和索引也是會產生類似存取競爭的情況,所以一個存取量大的資料表格,或許要考慮把它的索引放到另一個硬碟中。而要把物件存到另一個硬碟中的方法,就是採用 tablespace。
資料間具有競爭系統效能.
大型物件資料表與小型物件資料表應該分別在不同的 Tablespace.
分離資料和索引的存放空間是不錯的效能強化
至於如何建立 pg_global 和 pg_default 之外的 tablespace,以及這兩個預設的 tablespace 又存在哪裏呢?就留在下一篇文章中介紹,本文就先在此打住。

沒有留言:
張貼留言