支援的版本:目前 (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檔案,因為每個新記錄都會被寫入。插入位置由日誌序列號 (LSN) 描述,它是 WAL 中的一個位元組偏移量,隨著每個新記錄單調遞增。LSN值以資料類型pg_lsn傳回。可以比較值以計算WAL資料將它們分開,因此它們用於衡量複製和復原的進度。

WAL檔案儲存在資料目錄下的 pg_wal 目錄中,作為一組區段檔案,通常每個檔案大小為 16 MB(但可以透過變更 --wal-segsize initdb 選項來變更大小)。每個區段分為多個頁面,通常每個頁面 8 kB(此大小可以透過 --with-wal-blocksize 配置選項變更)。WAL 記錄標頭在 access/xlogrecord.h 中描述;記錄內容取決於正在記錄的事件類型。區段檔案的名稱會給予不斷增加的數字,從 000000010000000000000001 開始。這些數字不會循環使用,但需要非常非常長的時間才能耗盡可用的數字庫。

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

的目的WAL是確保在變更資料庫記錄之前先寫入日誌,但這可能會被磁碟機所破壞,這些磁碟機錯誤地向核心報告寫入成功,而實際上它們只是快取了資料,尚未將其儲存在磁碟上。在這種情況下,電源故障可能會導致無法復原的資料損毀。管理員應盡量確保保存 PostgreSQL 的磁碟WAL檔案不會發出此類錯誤報告。(請參閱第 28.1 節。)

在建立檢查點並刷新 WAL 後,檢查點的位置會保存在 pg_control 檔案中。因此,在復原開始時,伺服器首先讀取 pg_control,然後讀取檢查點記錄;然後它透過從檢查點記錄中指示的 WAL 位置向前掃描來執行 REDO 操作。由於資料頁面的全部內容都保存在檢查點之後的第一次頁面修改的 WAL 中(假設 full_page_writes 未停用),因此自檢查點以來變更的所有頁面都將恢復到一致的狀態。

為了處理 pg_control 損毀的情況,我們應該支援以相反的順序(從最新到最舊)掃描現有 WAL 區段的可能性,以便找到最新的檢查點。這尚未實作。pg_control 足夠小(小於一個磁碟頁面),不會受到部分寫入問題的影響,並且截至撰寫本文時,尚未收到任何僅僅由於無法讀取 pg_control 本身而導致資料庫失敗的報告。因此,雖然它在理論上是一個弱點,但在實務中,pg_control 似乎不是問題。

提交更正

如果您在文件中發現任何不正確、與特定功能的體驗不符或需要進一步澄清的內容,請使用此表單來回報文件問題。