逻辑复制的行为类似于正常的 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
。
如果您在文档中发现任何不正确、与您使用特定功能的体验不符或需要进一步澄清的地方,请使用此表单报告文档问题。