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

29.6. 衝突 #

邏輯複製的行為與正常的 DML 操作類似,即使訂閱節點上的資料已在本地變更,資料仍會更新。 如果傳入的資料違反任何約束,複製將會停止。 這被稱為衝突。 在複製 UPDATEDELETE 操作時,遺失的資料不會產生衝突,並且這些操作會被簡單地跳過。

邏輯複製操作以擁有訂閱的角色的權限執行。 目標表上的權限失敗將導致複製衝突,啟用列層級安全策略也會導致複製衝突,即使訂閱擁有者受到列層級安全策略的約束,無論任何策略是否通常會拒絕正在複製的INSERTUPDATEDELETETRUNCATE。 對於列層級安全策略的此限制,可能會在未來版本的 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。 在這種情況下,可能需要將串流模式變更為 onoff,並再次導致相同的衝突,以便將失敗交易的完成 LSN 寫入伺服器日誌。 有關完成 LSN 的使用,請參閱 ALTER SUBSCRIPTION ... SKIP

提交更正

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