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

31.5. 冲突 #

逻辑复制的行为类似于正常的 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