我正在测试 2 个 PostgreSQL 11 数据库之间的逻辑复制以用于我们的生产(由于这个答案,我能够设置它 - PostgreSQL logical replication - create subscription hangs)并且效果很好。
现在我正在测试可以在生产数据库上自动设置它的脚本和程序,但是我遇到了逻辑复制槽的奇怪问题。
由于设置中的一些更改需要重新启动,我不得不重新启动逻辑副本——这当然也可能在将来发生在副本上。但是 master 上的逻辑复制槽没有断开连接,并且对于某些 PID 仍然处于活动状态。
我放弃了对 master 的订阅(我仍然只是测试)并尝试使用新的逻辑复制槽重复整个过程,但我面临着奇怪的情况。
我无法使用新名称创建新的逻辑复制槽。在旧的逻辑复制槽上运行的进程仍处于活动状态并显示wait_event_type=Lock
和wait_event=transaction
。
当我尝试使用pg_create_logical_replication_slot
创建新的逻辑复制槽时,我遇到了类似的情况。新插槽已创建 - 我在 pg_catalog 中看到它,但对于发出此命令的会话的 PID,它被标记为活动,并且命令无限期挂起。当我检查进程时,我可以看到这个命令以相同的等待值锁定/事务处于活动状态。
我试图在 postgresql.conf 中激活参数“lock_timeout”并重新加载配置,但它没有帮助。
杀死旧的挂起进程很可能会导致整个 postgres 崩溃,因为它是“walsender”进程。它在进程列表中仍然可见,副本的 IP 状态为“idle wating”。
我试图找到一些可以帮助我强制 postgres 停止这个 walsender 的参数。但是设置 wal_keep_segments 或 wal_sender_timeout 并没有改变任何东西。我什至试图停止复制更长的时间 - 没有效果。
有没有办法在不重新启动整个 postgres 的情况下解决这种情况?就像强制 walsender 超时或事务锁定等...
因为如果在生产中发生这样的事情,我将无法使用重新启动或任何其他“蛮力”。谢谢...
更新: “Walsender”进程在一段时间后“消失”,但日志没有显示任何关于它的信息,所以我不知道它到底是什么时候发生的。我只能猜测它取决于 tcp_keepalives_* 参数。Debian 9 的默认值为 2 小时以保持空闲进程。所以我尝试在 postgresql.conf 中设置这些参数,并将在以下测试中看到。