PostgreSQL 逻辑复制在 CREATE SUBSCRIPTION 挂起

问题描述 投票:0回答:1

我对 PostgreSQL 逻辑复制版本 15 有问题。(我也在 v10 和 v12 上测试过,但有同样的问题)。 测试需要复制,所以源数据库和目标数据库在同一台服务器上。

在我设置的配置文件中:

postgresql.conf

wal_level = logical  # if I have "replica", I can't subscribe

pg_hba.conf

local replication all
host replication all 127.0.0.1/32 trust
host replication all ::1/128               trust

在我做的源数据库中:

CREATE PUBLICATION repl_name
   FOR TABLE table1, table2, table3, ...;

在这个阶段的 pgAdmin 中我有:

CREATE PUBLICATION
Query returned successfully in 59 msec.

但是,在日志中,我对每个表都有一条消息:

2023-05-17 17:02:07.537 CEST [25356] ERROR: role "backup_user" does not exist
2023-05-17 17:02:07.537 CEST [25356] STATEMENT:  GRANT SELECT ON SEQUENCE public.table1 TO backup_user;

这可能与以下事实有关:在我的计算机上,它正在从进行此复制的客户端还原备份。

但不知道有没有打扰到你,因为打字后:

select * from pg_catalog.pg_publication;

我可以看到我的出版物:

"20438"   "stack_repl"    "10"   false   true    true   true   true   false

但是我这里没看到:

select * from pg_stat_replication;

我觉得可能跟还没有订阅有关

真正的问题出现在我要订阅的时候。 首先,它用

table1
table2
table3
等表恢复数据库。自然地,表是空的。

我输入命令:

CREATE SUBSCRIPTION sub_test
   CONNECTION 'dbname=dbname host=localhost port=5432 user=postgres password=12345'
   PUBLICATION repl_name;

pgAdmin 无休止地旋转。即使我周末离开电脑,它也无法完成。

它显示在日志中:

2023-05-17 17:22:24.178 CEST [25376] LOG:  logical decoding found initial starting point at 0/A0D6F338
2023-05-17 17:22:24.178 CEST [25376] DETAIL:  Waiting for transactions (approximately 1) older than 3712 to end.
2023-05-17 17:22:24.178 CEST [25376] STATEMENT:  CREATE_REPLICATION_SLOT "sub_test" LOGICAL pgoutput (SNAPSHOT 'nothing')

我向你保证,我已经为这个问题苦苦挣扎了很长时间,我需要支持/提示我可以做些什么来让数据开始复制。

database postgresql replication logical-replication
1个回答
0
投票

您可能正在同一数据库集群中的两个数据库之间设置逻辑复制。这使得

CREATE SUBSCRIPTION
永远挂起,正如 文档 所描述的那样:

创建连接到同一数据库集群的订阅(例如,在同一集群中的数据库之间复制或在同一数据库内复制)只有在复制槽不是作为同一命令的一部分创建时才会成功。否则,

CREATE SUBSCRIPTION
呼叫将挂起。为了使它工作,单独创建复制槽(使用函数
pg_create_logical_replication_slot
和插件名称
pgoutput
)并使用参数
create_slot = false
创建订阅。这是一个实施限制,可能会在未来的版本中取消。

所以这就是成功之路:

  • 连接到主数据库并创建插槽:

    SELECT pg_create_logical_replication_slot('sub_test', 'pgoutput');
    
  • 然后连接备库,运行:

    CREATE SUBSCRIPTION sub_test
       CONNECTION 'dbname=dbname host=localhost port=5432 user=postgres password=12345'
       PUBLICATION repl_name
       WITH (create_slot = false);
    
© www.soinside.com 2019 - 2024. All rights reserved.