資料面試題:PostgreSQL 18 如何讓邏輯複製在主備切換後繼續?
題幹與適用場景
一個 PostgreSQL 18 主庫透過邏輯複製把變更傳送給分析叢集和外部訂閱者。主庫可能故障切換到實體備庫,請設計複製槽、參數、訂閱者檢查和切換順序,確保切換後邏輯複製從正確位置繼續,且不把「備庫已同步」誤當成「訂閱者已追平」。
面試官考察點
- 是否區分邏輯複製槽、實體複製槽、WAL 保留和訂閱者確認位置。
- 是否理解 failover 槽複製到備庫是非同步的,切換前必須驗證就緒。
- 是否能使用
pgreplicationslots、LSN 和訂閱狀態證明安全切換。 - 是否能處理槽失效、訂閱者落後、計畫切換與意外故障。
回答前需要釐清的問題
- 訂閱者是 PostgreSQL 還是外部系統,是否能在新主庫重新連線?
- 允許的 RPO 是零、有限 LSN 差距,還是可接受重新快照?
- 主備之間是否啟用實體複製槽與同步備用確認?
- 切換由編排器執行還是人工執行,誰負責凍結寫入和更新連線?
30 秒回答框架
我會在主庫為每個需要故障轉移的邏輯複製槽啟用 failover,讓槽狀態同步到熱備;同時設定實體同步約束,避免訂閱者先看到主庫已確認但備庫尚未持久化的變更。切換前檢查備庫上的槽已 synced、未失效,並確認訂閱者所需槽全部就緒。提升備庫後更新連線,驗證訂閱者從新主庫繼續消費,再解除寫入凍結。若非同步同步未追平,就按 RPO 選擇延遲切換或接受重建訂閱。
分步驟深入解答
1. 邏輯複製槽保存什麼
邏輯複製槽保存解碼進度和未被訂閱者確認的 WAL 保留邊界。槽不會自動等同於訂閱者健康;訂閱者停止消費時,主庫可能持續保留 WAL 並增加磁碟壓力。
2. 建立 failover 槽
PostgreSQL 18 支援在建立邏輯槽時設定 failover,也可在建立訂閱時啟用對應選項。範例使用 SQL 展示意圖,實際參數名和權限應以目標版本文件與部署方式複核。
SELECT *
FROM pg_create_logical_replication_slot('analytics_slot', 'pgoutput', false, true);槽的 failover 標誌允許其狀態被同步到熱備,但不代表同步已完成。
3. 備庫側同步開關
備庫需要啟用接收並套用邏輯槽同步的設定,例如 syncreplicationslots。主庫還應透過 synchronizedstandbyslots 指定必須先追上的實體槽,避免邏輯訂閱者進度超過可用於接管的備庫。
4. 非同步同步為何要單獨確認
槽同步邏輯複製的是狀態,過程本身是非同步的。主庫發生故障時,備庫可能已經有資料頁,卻沒有最新槽確認位置;直接提升會讓訂閱者找不到需要的起點,或產生重複與缺口。
5. 切換前檢查槽狀態
在候選備庫查詢 pgreplicationslots,確認目標槽已同步、不是臨時槽、沒有失效原因,並與訂閱者清單逐項對應。
SELECT slot_name,
synced,
temporary,
invalidation_reason,
confirmed_flush_lsn
FROM pg_replication_slots
WHERE slot_type = 'logical';只有所有必要槽都符合條件,才把備庫標記為可接管。
6. PostgreSQL 訂閱者的額外確認
對 PostgreSQL 訂閱者,還要確認訂閱端已消費到與槽同步相容的位置。不能只看主備實體複製延遲;應結合訂閱狀態、最後接收 LSN 和業務延遲判斷。
7. 外部訂閱者的切換
外部系統通常不能自動理解 PostgreSQL 的槽狀態。切換編排器應先凍結或暫停消費,提升備庫後更新連線和槽名稱,再用冪等事件與應用層偏移量驗證沒有跳過資料。
8. 故障與復原路徑
計畫切換可以等待所有槽同步完成;意外故障則按 RPO 判斷是否接受缺口、延遲切換或重建訂閱。舊主庫恢復後不能直接併入寫入路徑,應先隔離、重新建立實體複製,再核對槽和訂閱狀態。
設計取捨與邊界
- failover 槽提高邏輯複製可復原性,卻增加槽同步和 WAL 監控複雜度。
- 等待槽完全同步降低資料缺口,卻可能延長故障切換時間。
synchronizedstandbyslots約束邏輯進度與實體備庫追趕關係,不等於對所有外部訂閱者提供端到端零丟失保證。- 槽失效、磁碟逼近上限和訂閱者長期停擺必須有告警與清理策略,不能只依賴切換腳本。
落地計畫與證據
- 在 PostgreSQL 18 測試叢集建立 failover 邏輯槽,驗證主備設定和權限。
- 注入訂閱者停擺、WAL 堆積、槽未同步和主庫突失,記錄 LSN 與復原結果。
- 自動化切換前查詢
pgreplicationslots,將槽清單與訂閱者清單逐項比對。 - 在計畫切換與意外故障兩條路徑分別演練暫停、提升、改連、追平和回滾。
- 對照 PostgreSQL 18 Logical Replication Failover、Logical Decoding 和 Streaming Replication 文件複核參數與限制。
常見誤區與追問
誤區一:備庫有資料就代表邏輯複製可接管
邏輯槽狀態非同步同步,資料頁追平不代表槽位置已可用。必須檢查槽的同步和失效欄位。
誤區二:只監控實體複製延遲
還要監控訂閱者消費位置、槽確認 LSN、WAL 保留量和業務延遲,否則可能在實體層健康時發生邏輯積壓。
誤區三:把 failover 參數當成自動切換
它提供槽狀態同步能力,不負責提升備庫、更新連線或驗證外部訂閱者。切換仍需要編排和演練。
追問:槽沒同步完能否立即提升?
只有在明確接受 RPO、缺口或重建成本時才可以;預設應等待同步完成並把結果寫入切換門禁。
追問:如何避免重複消費?
保存事件唯一鍵或來源 LSN,切換後讓訂閱者從可驗證位置繼續,並用冪等處理和對帳任務處理重放。