pg_replication_origin_advance()
是一个系统函数,用于将给定节点的复制进度设置为指定位置。
pg_replication_origin_advance()
添加于 PostgreSQL 9.5。
用法
pg_replication_origin_advance (node_name
text
,lsn
pg_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()