
作者 | 市隐
來源 | 阿裡技術公衆号
一 概述
PostgreSQL是一個功能非常強大的、源代碼開放的客戶/伺服器關系型資料庫管理系統(RDBMS),PostgreSQL被業界譽為“先進的開源資料庫”,支援NoSQL資料類型(JSON/XML/hstore),主要面向企業複雜查詢SQL的OLTP業務場景,提供PostGIS地理資訊引擎、阿裡雲自研多元多模時空資訊引擎等。
本文着重介紹PostgreSQL的資料目錄,其中儲存着配置檔案、資料檔案、事務日志和WAL日志等重要檔案,所有客戶建立的資料檔案和初始配置檔案都可以在資料目錄中找到,是以資料目錄是重要的客戶價值所在。
二 名詞
1 OID
資料庫對象是資料庫存儲或引用的資料結構體,資料庫本身也是資料庫對象,同時包括表、索引、視圖、序列和函數等。Object ID是資料庫對象的唯一辨別符,儲存在無符号四位元組的整形變量中,所有資料庫對象各自對應一個OID。PostgreSQL有兩個視圖各司其職,分别儲存着不同類别的OID,其中pg_database儲存資料庫本身對象的OID,pg_class儲存表、索引和序列等對象的OID。
2 Relation
關系代表非資料庫本身的資料庫對象,包括表、視圖、索引和toast等,不包括資料庫本身。
3 MVCC
Multi-Version-Concurrency-Control是一種并發控制機制,資料庫引擎根據不同的事務隔離級别,通過查詢事務快照和事務送出日志來完成元組的可見性檢查。如果希望了解資料庫機制原理,MVCC是必不可少的學習知識。
4 Page
資料庫檔案在Linux平台被劃分為預設8K固定長度的page進行管理,通過啟動參數BLCKSZ可以預設page的大小。如果page設低了,相同資料量的檔案需要分裂成更多的page,IO次數和索引分裂次數都會增加,性能會降低較多;如果page設高了,page内部的資料檢索效率會降低,性能一樣會降低不少,一般來說8K和16K對于資料庫系統來說是最優解。
三 資料目錄
資料目錄預設在/var/lib/pgsql/data下,支援使用環境變量$PG_DATA管理。下圖所示是資料目錄的一級結構,後續會重點介紹具有代表性的重要檔案和目錄,比如base、pg_xact等。
四 base
1 概述
base目錄存儲使用者建立的資料庫檔案,及隸屬于使用者資料庫的所有關系,比如表、索引等。
2 一級目錄
目錄結構分為兩級,第一級結構如下圖所示,一級目錄名是使用者資料庫對象的OID,1代表的是postgres資料庫,一級目錄内的二級子檔案都是隸屬于該資料庫對象的關系,包括表、索引、視圖等。
3 二級檔案
二級子檔案如下圖所示,存儲着某個資料庫内的所有關系,包括表、索引、視圖等,這裡以postgres資料庫目錄示例。二級子檔案分為三大類,第一類是以關系OID命名的主資料檔案,第二類是檔案名以_fsm結尾的空閑空間映射檔案,第三類是檔案名以_vm結尾的可見性映射檔案。
4 主資料檔案
主資料檔案存儲隸屬于對應資料庫下的資料庫關系檔案,包括資料、索引等,客戶最重要的業務資料便是存儲在主資料檔案中。
當關系檔案大小低于RELSEG_SIZE × BLCKSZ時,資料庫引擎建立名稱為pg_class.relfilenode的單檔案,反之會切分為名稱如pg_class.relfilenode.segno的多個檔案。單個關系檔案内部被劃分為預設8K固定大小的多個page并存儲在磁盤上,8K可以在initdb時通過BLCKSZ參數修改配置。主資料檔案寫入時,會先将元組資料從行指針數組的底部開始堆疊,直到空間耗盡。
使用者通過SQL查詢到的單行資料記錄對應單個元組(tuple),因為MVCC機制的原因,元組可能是無法查詢到舊版本資料,也可能是活躍的新版本資料,舊版本資料會在未來的某個時刻被清理。當查詢沒有命中索引觸發順序掃描時,資料庫引擎順序掃描page的行指針讀取到元組,反之如果命中B樹索引,引擎會通過索引檔案的元組,通過索引鍵的TID值讀取到元組。
下圖是主資料檔案的層級結構。
下表格是上圖所示page内部結構的中繼資料資訊。
下表格是上圖所示tuple内部結構的中繼資料資訊。
5 FSM
FSM是空閑空間映射檔案,記錄着heap和index的每個page的空閑空間資訊,有利于快速定位到有充足空閑空間的page以便存儲tuple,如果沒有定位到則需要擴充新page。除了Hash Index檔案沒有FSM檔案,其他heap和index都需要FSM檔案。
總體上,FSM采用3-4級多叉樹的結構組織FSM page,單個FSM page内部采用完全二叉樹的結構進行管理,進階别FSM page的葉子節點關聯低級别的FSM page,低級别FSM Page的葉子節點存儲着heap、index page的可用空間數目,而非葉子結點依次存儲葉子節點的最大可用空間數目,每個節點占用1個位元組。
6 VM
VM是可見性映射檔案,記錄着每個heap page的可見性資訊,是以index page并沒有vm檔案。一方面它可以提高vacumn的執行效率,另一方面通過vm檔案可以感覺到page内的元組是否全部可見,如果全部可見的話,查詢引擎查詢索引元組直接擷取到資料即可,不必再通路資料元組檢查可見性,減少了回表次數,極大提升了查詢的效率。
VM采用位圖的結構存儲可見性資訊,每個heap page隻在vm檔案中存儲2位,第一位代表元組是否全部可見,第二位代表元組是否全部被當機。
#define VISIBILITYMAP_ALL_VISIBLE 0x01
#define VISIBILITYMAP_ALL_FROZEN 0x02
五 global
global目錄存儲pg_control及資料庫叢集次元的資料庫及其關系,非客戶次元的資料,例如pg_database、pg_class等。目錄内的檔案結構和base是一緻的。
global目錄檔案結構如下圖所示。
2 pg_control
pg_control檔案記錄資料庫叢集控制資訊,包括initdb初始化、WAL和checkpoint的資訊。
六 pg_wal
pg_wal是WAL機制中的wal日志存儲目錄。PG10及之後的高版本改目錄名為pg_wal,10之前目錄名稱是pg_xlog。
2 WAL機制
Write-Ahead-Logging:日志先行機制。資料變更優先寫入日志檔案,事務失敗則變更記錄被忽略,事務成功再選擇合适時機寫入資料檔案,資料的刷盤速度慢于日志刷盤速度。當資料庫系統崩潰後,引擎會從上一次成功的checkpoint點開始依次重放wal記錄,如果LSN>pd_lsn則重放wal記錄,反之跳過,確定資料記錄恢複到崩潰前的狀态。
3 檔案結構
4 wal segment
wal段檔案存儲着資料庫行記錄明細,每一條記錄明細都是服務于資料庫恢複操作的,確定前後資料一緻。首先針對資料的任意一次修改操作均被記錄在wal段檔案中,包括insert、update和delete,其次系統的一些管理行為也會被記錄在wal段檔案中,例如事務送出和vacuum等行為。
wal段檔案命名形如00000001 00000001 00000092,檔案名共24位,前8位是timeline,中間8位是logid,後8位是logseg,logseg的前6位始終是0,後2位是lsn的前2位。根據wal段檔案名的最後2位,wal記錄根據對應的LSN分别記錄在不同的wal段檔案中。
5 .history
.history檔案内容包括原.history檔案,目前時間線切換記錄和切換原因,作用于資料庫的時間點恢複行為。當資料庫引擎從多個時間線的備份中恢複時,資料庫從.history檔案中找到從pg_control的start_timeline到指定的recovery_target_timeline間的所有wal段檔案進行恢複。
6 archive_status
archive_status是wal段檔案的備份目錄,包括.ready和.done檔案。超出wal_keep_segments數目限制的wal日志會在archive_status目錄内被打标,歸檔操作完成後被進一步移除。
7 .ready
.ready是同名wal段檔案在archive_status目錄内的标記檔案,代表該wal段檔案可被歸檔。wal段檔案在資料目錄中的存儲檔案數量是有上限的,一般通過wal_keep_segments參數來限制,是以資料庫引擎在wal段檔案個數達到上限後會在archive_status目錄内增加可移除的wal段檔案的标記檔案,檔案名是原wal段檔案名後增加.ready字尾,等待歸檔工具進行歸檔。
8 .done
.done是同名wal段檔案在archive_status目錄内的标記檔案,代表該wal段檔案已被歸檔,可以被清理。資料庫引擎預設通過archive_command指令對.ready檔案進行歸檔,歸檔成功與否取決于archive_command指令傳回true還是false,當archive_command傳回true時,代表與.ready檔案同名的wal段檔案已被歸檔,引擎再将該檔案的擴充名重命名為.done,等待資料庫引擎在下一次的checkpoint時進一步清理原wal段檔案。
七 pg_xact
pg_xact是事務送出日志(Commit Log)的存儲目錄,事務送出日志預設256KB,檔案名形如NNNN,系統初始化後從0000開始遞增至FFFF。PG 10及之後的高版本改目錄名為pg_xact,10之前目錄名稱是pg_clog。
下圖是pg_xact目錄下的clog檔案,027E前的檔案因為事務已被當機,是以被vacuum清理完畢。
2 Commit Log
事務送出日志存儲資料庫的單個事務運作狀态。Commit Log由共享記憶體中一組8KB的page組成,每個page包含一列數組,每個數組元素包含XID和該事物的實時狀态。當page不足時,建立新的page來存儲新的事務。
八 配置檔案
1 postgresql.conf
postgresql.conf檔案存儲着配置檔案的位置、資源限制、叢集複制等參數資料,是資料庫運作時最重要的配置檔案。
2 postgresql.auto.conf
postgresql.auto.conf檔案存儲着資料庫的全局配置參數,資料庫引擎在啟動時加載postgresql.auto.conf檔案後,覆寫postgresql.conf檔案中已有的配置,形成最終的資料庫啟動配置。
3 pg_hba.conf
pg_hba.conf檔案負責用戶端的連接配接和認證,起到防火牆的作用,格式是:TYPE / DATABASE / USER / ADDRESS / METHOD。
九 總結
本文從肉眼可見的資料目錄及其子檔案開始展開,由淺入深直到不可見的源碼結構體次元,詳細介紹了資料目錄及其子檔案的結構和作用。大家通過了解資料目錄的檔案體系結構,能夠對PostgreSQL資料庫全貌有個總體概覽,無論是日常運維、核心研發,還是業務開發,這些都是必須掌握的基礎知識。
阿裡雲開發者社群“乘風者計劃”重磅來襲!誠邀千名技術部落客入駐
無論你是小白亦或大神,隻要來社群釋出3篇原創技術博文,即可獲得入駐勳章和精美禮品。發文越多,可解鎖更多勳章和官方流量扶持、招聘推薦,個人品牌包裝、頂級大會門票、專家對話沙龍等諸多重磅權益。快來更新打怪吧!
點選這裡,參加乘風者計劃~