↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 13 / 12 / 11 / 10

29.6. 冲突 #

逻辑复制的行为类似于普通的 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 可能不会被记录。这种情况下,可能需要把 streaming 模式改为 on 或 off,并再次触发相同的冲突,以便将失败事务的完成 LSN 写入服务器日志。关于完成 LSN 的用法,请参见 ALTER SUBSCRIPTION ... SKIP。

报告文档问题

阅读 上游文档. 通过 PostgreSQL 文档反馈表单.