pg_replication_origin_advance() 是一个系统函数,用于将给定节点的复制进度设置为指定位置。
pg_replication_origin_advance() 函数在 PostgreSQL 9.5 中添加。
用法
pg_replication_origin_advance (node_nametext,lsnpg_lsn) →void
node_name 对应 pg_replication_origin 的 roname 列,或 pg_replication_origin_status 的 external_id 列。
变更历史
- PostgreSQL 9.5
- 新增于(提交 5aa23504)
示例
为了演示 pg_replication_origin_advance() 的用法,我们设想有两个 PostgreSQL 节点(node1 和 node2),它们都包含一个如下创建的表
CREATE TABLE foo ( id INT NOT NULL PRIMARY KEY, node TEXT, val TEXT )
node2 有一个订阅(“test_sub”),用于将上述表从 node1 同步到 node2。请注意,此订阅是使用选项“disable_on_error = true”(PostgreSQL 15 及更高版本)创建的。初始表同步后,表包含以下内容
postgres=# SELECT * FROM foo; id | node | val ----+----------------+------------------------------- 1 | logical[node1] | 2023-04-16 10:41:41.735911+00 (1 row)
在 node2 上,插入了以下行
postgres=# INSERT INTO foo
VALUES (2,
current_setting('cluster_name'),
clock_timestamp()
);
INSERT 0 1
postgres=# SELECT * FROM foo;
id | node | val
----+----------------+-------------------------------
1 | logical[node1] | 2023-04-16 10:41:41.735911+00
2 | logical[node2] | 2023-04-16 10:46:40.83656+00
(2 rows)
在 node1 上,插入了以下行
postgres=# INSERT INTO foo
VALUES (2,
current_setting('cluster_name'),
clock_timestamp()
);
INSERT 0 1
postgres=# SELECT * FROM foo;
id | node | val
----+----------------+-------------------------------
1 | logical[node1] | 2023-04-16 10:41:41.735911+00
2 | logical[node1] | 2023-04-16 10:47:38.830865+00
(2 rows)
ID 为 2 的行将无法从 node1 复制到 node2,因为它将与 node2 上已存在的行发生冲突。这将在 node2 的 pg_stat_subscription_stats 中有所体现
postgres=# SELECT * FROM pg_stat_subscription_stats; subid | subname | apply_error_count | sync_error_count | stats_reset -------+----------+-------------------+------------------+------------- 16392 | test_sub | 1 | 0 | (1 row)
以及 node2 日志中对应的条目
ERROR: 23505: duplicate key value violates unique constraint "foo_pkey" DETAIL: Key (id)=(2) already exists. CONTEXT: processing remote data for replication origin "pg_16392" during message type "INSERT" for replication target relation "public.foo" in transaction 740, finished at 0/2539AF8 LOG: 00000: subscription "test_sub" has been disabled because of an error
为了解决这种情况,可以为指定的复制源执行 pg_replication_origin_advance() 函数,并提供一个大于上述日志条目中报告的 LSN 值,然后可以重新启用订阅。
postgres=# SELECT pg_replication_origin_advance('pg_16392', '0/2539AF9');
pg_replication_origin_advance
-------------------------------
(1 row)
postgres=# ALTER SUBSCRIPTION test_sub ENABLE;
ALTER SUBSCRIPTION
请注意,提供给 pg_replication_origin_advance() 的 LSN 应仔细选择,否则可能会跳过有效的事务。在上述情况中,它被设置为报告的失败 LSN + 1,假定后续事务是有效的。
参考资料
- PostgreSQL 文档: pg_replication_origin_advance()
