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

47.2. 邏輯解碼概念 #

47.2.1. 邏輯解碼 #

邏輯解碼是將資料庫表格的所有持久性變更提取成連貫且易於理解的格式的過程,該格式無需詳細了解資料庫的內部狀態即可解釋。

PostgreSQL 中,邏輯解碼是通過解碼預寫日誌的內容來實現的,該日誌描述了儲存層級的變更,轉化為應用程式特定的形式,例如元組串流或 SQL 語句。

47.2.2. 複製槽 #

在邏輯複製的上下文中,槽代表可以以它們在原始伺服器上進行的順序重播給客戶端的變更串流。 每個槽會串流來自單一資料庫的一系列變更。

注意

PostgreSQL 還有串流複製槽(請參閱第 26.2.5 節),但它們在那裡的使用方式略有不同。

複製槽具有一個在 PostgreSQL 集群中所有資料庫中唯一的識別符。 槽會獨立於使用它們的連線而持久存在,並且是可防止崩潰的。

在正常運作下,邏輯槽將只發出一次變更。 每個槽的目前位置僅在檢查點持久保存,因此在崩潰的情況下,槽可能會返回到較早的 LSN,這將導致伺服器重新啟動時再次傳送最近的變更。 邏輯解碼客戶端負責避免多次處理同一訊息所造成的不良影響。 客戶端可能希望記錄它們在解碼時看到的最後一個 LSN,並跳過任何重複的資料,或者(在使用複製協定時)請求從該 LSN 開始解碼,而不是讓伺服器決定起點。 複製進度追蹤功能是為此目的而設計的,請參閱複製來源

單一資料庫可以存在多個獨立的槽。 每個槽都有其自己的狀態,允許不同的消費者從資料庫變更串流中的不同點接收變更。 對於大多數應用程式,每個消費者都需要一個單獨的槽。

邏輯複製槽對接收器的狀態一無所知。 甚至可能有多個不同的接收器在不同的時間使用同一個槽; 他們只會從最後一個接收器停止使用它們的時間開始接收變更。 在任何給定時間,只有一個接收器可以從一個槽使用變更。

邏輯複製槽也可以在熱備用伺服器上建立。 為了防止 VACUUM 從系統目錄中移除所需的列,應該在備用伺服器上設定 hot_standby_feedback。 儘管如此,如果任何所需的列被移除,則槽會失效。 強烈建議在主伺服器和備用伺服器之間使用實體槽。 否則,hot_standby_feedback 將工作,但僅在連線存活時(例如,節點重新啟動會破壞它)。 然後,主伺服器可能會刪除備用伺服器上的邏輯解碼可能需要的系統目錄列(因為它不知道備用伺服器上的 catalog_xmin)。 如果主伺服器上的 wal_level 降低到小於 logical,則備用伺服器上現有的邏輯槽也會失效。 一旦備用伺服器偵測到 WAL 串流中的這種變更,就會立即執行此操作。 這意味著,對於落後的 walsender(如果有的話),一些 WAL 記錄直到主伺服器上的 wal_level 參數變更才會被解碼。

建立邏輯槽需要有關目前所有執行中交易的資訊。 在主伺服器上,此資訊可直接取得,但在備用伺服器上,此資訊必須從主伺服器取得。 因此,建立槽可能需要等待主伺服器上發生一些活動。 如果主伺服器處於閒置狀態,則在備用伺服器上建立邏輯槽可能需要相當長的時間。 可以透過在主伺服器上呼叫 pg_log_standby_snapshot 函式來加速此過程。

小心

複製槽在崩潰後會持續存在,並且對其消費者 (consumer) 的狀態一無所知。 即使沒有連線使用它們,它們也會阻止移除所需的資源。 這會消耗儲存空間,因為只要複製槽需要,VACUUM 就無法移除所需的 WAL 或系統目錄中的所需列。 在極端情況下,這可能會導致資料庫關閉以防止交易 ID 迴繞(請參閱第 24.1.5 節)。 因此,如果不再需要槽,則應將其刪除。

47.2.3. 複製槽同步 #

在主要伺服器上的邏輯複製槽可以使用 pg_create_logical_replication_slotfailover 參數,或者是在建立槽時使用 CREATE SUBSCRIPTIONfailover 選項,然後在備用伺服器上呼叫 pg_sync_replication_slots,來與熱備用伺服器同步。透過在備用伺服器上設定 sync_replication_slots,可以在 slotsync 工作程序中定期同步故障轉移槽。為了使同步能夠運作,必須在主要伺服器和備用伺服器之間建立實體複製槽(即,primary_slot_name 應在備用伺服器上配置),並且必須在備用伺服器上啟用 hot_standby_feedback。還需要在 primary_conninfo 中指定有效的 dbname。強烈建議在主要伺服器上的 synchronized_standby_slots 列表中命名該實體複製槽,以防止訂閱者消耗變更的速度快於熱備用伺服器。即使配置正確,由於等待 synchronized_standby_slots 中命名的槽,預期在將變更傳送到邏輯訂閱者時會有一些延遲。當使用 synchronized_standby_slots 時,主要伺服器不會完全關閉,直到與 synchronized_standby_slots 中指定的實體複製槽相關聯的相應備用伺服器確認已收到 WAL,且已達到主要伺服器上最新的刷新位置。

在故障轉移後恢復邏輯複製的能力取決於故障轉移時備用伺服器上同步槽的 pg_replication_slots.synced 值。只有在故障轉移之前在備用伺服器上達到同步狀態為 true 的持久槽才能在故障轉移後用於邏輯複製。臨時同步槽不能用於邏輯解碼,因此無法恢復這些槽的邏輯複製。例如,如果由於訂閱被停用而導致同步槽無法在備用伺服器上變成持久槽,則即使訂閱已啟用,也無法在故障轉移後恢復訂閱。

若要在從同步邏輯槽故障轉移後恢復邏輯複製,則必須變更訂閱的 'conninfo' 以指向新的主要伺服器。這可以使用 ALTER SUBSCRIPTION ... CONNECTION 來完成。建議先停用訂閱,再提升備用伺服器,並在變更連線字串後重新啟用訂閱。

小心

在提升期間,舊的主要伺服器有可能再次啟動,如果未停用訂閱,則邏輯訂閱者可能會在變更連線字串之前,繼續從舊的主要伺服器接收資料,即使在提升之後也是如此。這可能會導致資料不一致的問題,從而阻止邏輯訂閱者從新的主要伺服器繼續複製。

47.2.4. 輸出插件 #

輸出插件將來自預寫式日誌的內部表示法的資料轉換為複製槽的消費者所期望的格式。

47.2.5. 匯出的快照 #

當使用串流複製介面建立新的複製槽時(請參閱 CREATE_REPLICATION_SLOT),會匯出一個快照(請參閱 Section 9.28.5),該快照將顯示資料庫的確切狀態,在此之後,所有變更都將包含在變更串流中。這可用於透過使用 SET TRANSACTION SNAPSHOT 讀取建立槽時資料庫的狀態來建立新的複本。然後,可以使用此交易來傾印該時間點的資料庫狀態,之後可以使用槽的內容更新該狀態,而不會遺失任何變更。

建立快照並非總是可能的。特別是,當連接到熱備用伺服器時,它將會失敗。不需要匯出快照的應用程式可以使用 NOEXPORT_SNAPSHOT 選項來抑制它。

提交更正

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