邏輯複製的行為與正常的 DML 操作類似,即使訂閱節點上的資料已在本地變更,資料仍會更新。 如果傳入的資料違反任何約束,複製將會停止。 這被稱為衝突。 在複製 UPDATE
或 DELETE
操作時,遺失的資料不會產生衝突,並且這些操作會被簡單地跳過。
邏輯複製操作以擁有訂閱的角色的權限執行。 目標表上的權限失敗將導致複製衝突,啟用列層級安全策略也會導致複製衝突,即使訂閱擁有者受到列層級安全策略的約束,無論任何策略是否通常會拒絕正在複製的INSERT
、UPDATE
、DELETE
或 TRUNCATE
。 對於列層級安全策略的此限制,可能會在未來版本的 PostgreSQL 中取消。
衝突將產生錯誤並停止複製; 必須由使用者手動解決。 有關衝突的詳細訊息可以在訂閱者的伺服器日誌中找到。
解決方法可以是更改訂閱者上的資料或權限,使其與傳入的變更不衝突,或者跳過與現有資料衝突的交易。 當衝突產生錯誤時,複製將不會繼續,並且邏輯複製工作程序將向訂閱者的伺服器日誌發出以下訊息
ERROR: duplicate key value violates unique constraint "test_pkey" DETAIL: Key (c)=(1) already exists. CONTEXT: processing remote data for replication origin "pg_16395" during "INSERT" for replication target relation "public.test" in transaction 725 finished at 0/14C0378
可以從伺服器日誌中找到包含違反約束的變更的交易的 LSN 和複製來源名稱(在上述情況下,LSN 為 0/14C0378,複製來源為 pg_16395
)。 可以使用 ALTER SUBSCRIPTION ... SKIP
和完成 LSN(即 LSN 0/14C0378)來跳過產生衝突的交易。 完成 LSN 可以是交易在發布者上提交或準備好的 LSN。 或者,也可以透過呼叫 pg_replication_origin_advance()
函數來跳過交易。 在使用此函數之前,需要暫時停用訂閱,可以透過 ALTER SUBSCRIPTION ... DISABLE
,或者,訂閱可以使用 disable_on_error
選項。 然後,您可以使用 pg_replication_origin_advance()
函數,使用 node_name
(即 pg_16395
)和完成 LSN 的下一個 LSN(即 0/14C0379)。 可以在 pg_replication_origin_status
系統檢視表中看到來源的目前位置。 請注意,跳過整個交易包括跳過可能不會違反任何約束的變更。 這很容易使訂閱者不一致。
當 streaming
模式為 parallel
時,可能不會記錄失敗交易的完成 LSN。 在這種情況下,可能需要將串流模式變更為 on
或 off
,並再次導致相同的衝突,以便將失敗交易的完成 LSN 寫入伺服器日誌。 有關完成 LSN 的使用,請參閱 ALTER SUBSCRIPTION ... SKIP
。
如果您在文件中發現任何不正確、與您使用特定功能的經驗不符或需要進一步澄清的地方,請使用 此表單來報告文件問題。