Redrock Postgres 搜索 英文
版本: 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17

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)。可以使用带有终止 LSN(即 LSN 0/14C0378)的 ALTER SUBSCRIPTION ... SKIP 跳过产生冲突的事务。终止 LSN 可以是在发布方上提交或准备事务的 LSN。另外,也可以通过调用 pg_replication_origin_advance() 函数来跳过事务。在使用此函数之前,需要通过 ALTER SUBSCRIPTION ... DISABLE 暂时禁用订阅,或者可以使用带 disable_on_error 选项的订阅。然后,可以使用 pg_replication_origin_advance() 函数,并且带 node_name(即 pg_16395)以及终止 LSN 的下一个 LSN(即 0/14C0379)。origins 的当前位置可以在 pg_replication_origin_status 系统视图中看到。请注意,跳过整个事务包括跳过可能不违反任何约束条件的更改。这很容易使订阅方不一致。

streaming 模式的 parallel 时,失败事务的终止 LSN 可能不会被记录。在这种情况下,可能需要将流模式改为 onoff 并再次引起相同冲突,以便失败事务的终止 LSN 将被写入服务器日志。有关终止 LSN 的用法,请参阅 ALTER SUBSCRIPTION ... SKIP