支援的版本:目前 (17) / 16 / 15 / 14 / 13
開發版本:devel
不支援的版本:12 / 11 / 10 / 9.6

63.1. 通用 WAL 紀錄 #

雖然所有內建的 WAL 記錄模組都有自己的 WAL 記錄類型,但也有通用的 WAL 記錄類型,以通用的方式描述頁面的變更。

注意

通用 WAL 紀錄在邏輯解碼期間會被忽略。如果您的擴充功能需要邏輯解碼,請考慮使用自訂 WAL 資源管理器。

用於建構通用 WAL 紀錄的 API 定義在 access/generic_xlog.h 中,並在 access/transam/generic_xlog.c 中實作。

若要使用通用 WAL 紀錄機制執行 WAL 記錄的資料更新,請依照下列步驟

  1. state = GenericXLogStart(relation) — 開始為給定的關聯建構通用 WAL 紀錄。

  2. page = GenericXLogRegisterBuffer(state, buffer, flags) — 註冊要在目前通用 WAL 紀錄中修改的緩衝區。此函數會傳回指向緩衝區頁面的臨時副本的指標,應在其中進行修改。(請勿直接修改緩衝區的內容。)第三個引數是適用於該操作的旗標的位元遮罩。目前唯一的此類旗標是 GENERIC_XLOG_FULL_IMAGE,表示 WAL 紀錄中應包含完整頁面影像,而不是差異更新。如果頁面是新的或已完全重寫,通常會設定此旗標。GenericXLogRegisterBuffer 可以重複執行,如果 WAL 記錄的動作需要修改多個頁面。

  3. 將修改套用至在上一步驟中取得的頁面影像。

  4. GenericXLogFinish(state) — 將變更套用至緩衝區,並發出通用 WAL 紀錄。

WAL 紀錄的建構可以在上述任何步驟之間透過呼叫 GenericXLogAbort(state) 來取消。這將捨棄對頁面影像副本的所有變更。

使用通用 WAL 紀錄機制時,請注意以下幾點

  • 不允許直接修改緩衝區!所有修改都必須在從 GenericXLogRegisterBuffer() 取得的副本中進行。換句話說,建立通用 WAL 紀錄的程式碼永遠不應為自己呼叫 BufferGetPage()。但是,呼叫者仍有責任在適當的時間釘住/取消釘住和鎖定/解鎖緩衝區。從 GenericXLogRegisterBuffer() 之前到 GenericXLogFinish() 之後,必須持有每個目標緩衝區的獨佔鎖定。

  • 緩衝區的註冊(步驟 2)和頁面影像的修改(步驟 3)可以自由混合,也就是說,這兩個步驟可以按任何順序重複執行。請記住,緩衝區應按照重播期間要取得鎖定的相同順序註冊。

  • 可以為通用 WAL 紀錄註冊的緩衝區的最大數量為 MAX_GENERIC_XLOG_PAGES。如果超過此限制,將會拋出錯誤。

  • 通用 WAL 假設要修改的頁面具有標準版面配置,尤其是在 pd_lowerpd_upper 之間沒有有用的資料。

  • 由於您正在修改緩衝區頁面的副本,因此 GenericXLogStart() 不會啟動關鍵區段。因此,您可以安全地在 GenericXLogStart()GenericXLogFinish() 之間進行記憶體配置、拋出錯誤等等。唯一的實際關鍵區段存在於 GenericXLogFinish() 內部。也無需擔心在錯誤結束期間呼叫 GenericXLogAbort()

  • GenericXLogFinish() 負責標記緩衝區為髒頁並設定其 LSN。您不需要明確地執行此操作。

  • 對於未記錄的關聯,一切都以相同的方式運作,只是不會發出實際的 WAL 紀錄。因此,您通常不需要對未記錄的關聯進行任何明確的檢查。

  • 通用 WAL 重做函數將按照註冊的相同順序取得緩衝區的獨佔鎖定。在重做所有變更之後,鎖定將以相同的順序釋放。

  • 如果未為註冊的緩衝區指定 GENERIC_XLOG_FULL_IMAGE,則通用 WAL 紀錄包含舊頁面影像和新頁面影像之間的差異。此差異基於逐位元組比較。對於在頁面中移動資料的情況,這不是非常緊湊,並且未來可能會得到改進。

提交更正

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