2025年9月25日: PostgreSQL 18 釋出!
支援的版本:當前 (18) / 17 / 16 / 15 / 14 / 13
開發版本:devel
不支援的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4

28.6. WAL 內部結構 #

WAL會自動啟用;除了確保滿足 WAL 檔案所需的磁碟空間,並進行任何必要的調整(參見 第 28.5 節)之外,管理員無需採取任何操作。WAL檔案,並在寫入每個新記錄時追加到

WAL記錄被追加到WAL檔案。插入位置由一個日誌序列號(LSN)描述,該號碼是 WAL 中的一個位元組偏移量,隨著每個新記錄的寫入而單調遞增。LSN值作為資料型別 pg_lsn 返回。值可以進行比較,以計算它們之間的資料量,因此它們用於測量複製和恢復的進度。WAL資料量,所以它們用於衡量複製和恢復的進度。

WAL檔案儲存在資料目錄下的 pg_wal 目錄中,作為一系列段檔案,通常每個檔案大小為 16MB(但可以透過修改 initdb--wal-segsize 選項來更改大小)。每個段又被劃分為頁面,通常每頁 8kB(此大小可以透過 --with-wal-blocksize configure 選項更改)。WAL 記錄頭在 access/xlogrecord.h 中描述;記錄內容取決於正在記錄的事件型別。段檔案的命名為遞增的數字,從 000000010000000000000001 開始。這些數字不會迴繞,但用完所有數字需要非常非常長的時間。

如果 WAL 位於與主資料庫檔案不同的磁碟上,將會帶來好處。這可以透過(當然是在伺服器關閉的情況下)將 pg_wal 目錄移動到另一個位置,並在主資料目錄的原始位置建立一個指向新位置的符號連結來實現。

目標是WAL的目的是確保日誌在資料庫記錄被修改之前寫入,但這可能會被磁碟驅動器所破壞,這些驅動器會虛假地向核心報告寫入成功,而實際上它們只快取了資料但尚未將其儲存在磁碟上。在這種情況下,斷電可能會導致無法恢復的資料損壞。管理員應儘量確保儲存 PostgreSQL 的 WAL 檔案的磁碟不會做出此類虛假報告(參見 第 28.1 節)。WAL檔案不產生此類虛假報告。

在製作完檢查點並重新整理 WAL 後,檢查點的位置儲存在 pg_control 檔案中。因此,在恢復開始時,伺服器首先讀取 pg_control,然後讀取檢查點記錄;然後,它透過從檢查點記錄中指示的 WAL 位置向前掃描來執行 REDO 操作。由於在檢查點後的第一次頁面修改時,所有更改過的頁面的完整內容都會儲存在 WAL 中(假設 full_page_writes 沒有被停用),因此自上次檢查點以來更改的所有頁面都將被恢復到一致的狀態。

為了處理 pg_control 損壞的情況,我們應該支援反向掃描現有 WAL 段(從最新到最舊)以查詢最新檢查點的可能性。這尚未實現。pg_control 的大小足夠小(小於一個磁碟頁),因此它不會受到部分寫入問題的影響,並且在編寫本文時,還沒有關於僅因無法讀取 pg_control 本身而導致資料庫失敗的報告。所以,雖然它理論上是一個薄弱環節,但在實踐中 pg_control 似乎並不是一個問題。

提交更正

如果您在文件中發現任何不正確之處、與您在使用特定功能時的體驗不符之處,或者需要進一步澄清的地方,請使用 此表格 報告文件問題。