跳轉到內容

PostgreSQL/頁面佈局

來自華夏公益教科書,開放的書籍,開放的世界


PostgreSQL 將資料和關聯索引儲存在單獨的檔案中:每個表一個檔案,每個索引一個檔案。檔案被分成 8192 位元組(8 KiB)的塊。這是 PostgreSQL 磁碟 I/O 的最小單位。當前使用的塊在例項的共享記憶體中以 1:1 的比例映象。在 PostgreSQL 中,“塊”通常稱為“頁面”,雖然“頁面”一詞可能在底層檔案系統中被不同地解釋,例如:4 KiB 或其他一些 2^n 值。

資料檔案的所有頁面在邏輯上是等價的,而索引檔案根據索引的需求使用不同的頁面型別(元資料頁面、根頁面、內部樹頁面、葉頁面,…)。然而,資料檔案和所有型別索引檔案的頁面的物理佈局是相同的。

每個頁面包含 5 個主要部分

  1. 頁面頭:關於頁面的通用資訊。
  2. ItemId:指向專案的指標陣列。它會隨著時間的推移而增長或縮小。
  3. 空閒空間:頁面的未用空間。
  4. 專案:一組實際資料,分別對應行或一組索引條目。它會隨著時間的推移而增長或縮小。
  5. 特殊空間:資料檔案不使用它。索引檔案根據索引型別的需求對其進行結構化。

每增加一行或一個索引條目,就會在第 2 個部分末尾建立一個新的 ItemId,並在第 4 個部分開頭建立一個新的專案。結果,空閒空間從其左右兩側縮小。

頁面頭包含 24 個位元組,幷包含諸如頁面校驗和、空閒空間開始和結束的偏移量或特殊空間的偏移量、WAL 處理的資訊、佈局版本號以及一些其他標誌等資訊。

每個ItemId包含 4 個位元組,幷包含相應專案的偏移量和長度。

在資料檔案的情況下,每個專案(= 行)包含

  • 專案頭:23 個位元組,包含各種事務 ID、當前或更新的元組 ID、資料偏移量以及各種標誌。
  • 空值點陣圖:標記當前為 NULL 的列。該地圖是可選的:如果表只包含非空列,那麼它就是多餘的。
  • 資料:行的每個屬性的值 - 如果不為 NULL。屬性的順序和型別儲存在系統架構中。在可變長度資料型別的情況下,當前使用的長度儲存在屬性的開頭。

在索引檔案的情況下,專案包含索引條目,它們根據索引型別以不同的方式進行結構化。

特殊空間僅供索引檔案用於其自身目的,例如:頁號、頁面型別、相同級別頁面中的(雙重)連結列表、樹級,… 。資料檔案不需要這種附加資訊。它們被組織為一個堆,這意味著它們的頁面在邏輯上是等價的,頁面之間沒有任何特殊順序或層次結構。附加資料始終被放置到下一個空閒空間或一個新分配的頁面。

通常,資料檔案的某些部分透過其頁號直接讀取和寫入。但這並不罕見,它們被完全讀取。這是透過順序掃描來完成的。這種全面的順序訪問(作為在索引檔案中跟隨連結列表的類比)——在大多數情況下——透過其預讀技術由底層檔案系統進行最佳化。這尤其有助於位於旋轉磁碟 (HDD) 上的檔案,而對於 SSD 來說,這種優勢會略微消失。

[編輯 | 編輯原始碼]

PostgreSQL 文件關於頁面佈局


華夏公益教科書