终止 postgres 复制模式连接的正确方法

Posted

技术标签:

【中文标题】终止 postgres 复制模式连接的正确方法【英文标题】:Correct way to terminate a postgres replication mode connection 【发布时间】:2017-11-21 12:43:44 【问题描述】:

我有以下代码可以在 PostgreSQL 9.4 中启用逻辑解码:

pg_recvlogical -h localhost --slot test_slot --create-slot
pg_recvlogical -h localhost --slot test_slot --start -f -

我生成了一个 node.js 子进程来运行此代码并监听更改,但是我不确定终止连接的正确程序是什么。我通常只是从命令行CNTRL+C 或在代码中终止子进程,但我总是收到pg_recvlogical: unexpected termination of replication stream: 错误。终止此连接的正确方法是什么?

【问题讨论】:

你不想pg_recvlogical -h localhost --slot test_slot --drop-slot?.. 这会杀死插槽 - 我只想终止与它的连接。 如果你不能用--start -f 发送SIGINT 来处理,你可能不得不杀死它ny pid?.. 在代码中,我使用 'SIGINT' 信号来终止进程,但我仍然收到相同的错误。 啊-抱歉。我现在明白了 - 你想取消通知 【参考方案1】:

PostgreSQL documentation says,

--开始 从 --slot 指定的逻辑复制槽开始流式传输更改,一直持续到被信号终止。如果服务器端更改流以服务器关闭或断开连接结束,则循环重试,除非指定 --no-loop。

所以我假设标准的 Linux 信号含义适用。因此,SIGINTSIGQUIT 应该是可以接受的,给应用程序完成时间。

我要做的是发送SIGINT,然后进入一个循环,检查/proc/$PID_/stat是否存在,自定义超时后,我发送SIGKILLwait $PID_

kill -2 $PID_
for i in `seq 1 8`; do
    if [ ! -f /proc/$PID_/stat ] ; then
        RETURN_CODE=`wait $PID_`;
        break;
    fi
    sleep 1;
done
if [ -f /proc/$PID_/stat ] ; then
    kill -9 $PID_;
    RETURN_CODE=`wait $PID_`;
fi

这就是 Bash,但任何体面的平台/语言都会有工具来做这件事。 缩短了,所以可能有错误:)

【讨论】:

【参考方案2】:

我执行以下操作来杀死一个僵尸活动复制槽。

    使用带有 ssh 的 CLI 连接到安装了 postgres 的服务器。
ssh -i <generated_security_key_name/path>.pem <username>@<hostIp>
    一旦连接到服务器中的虚拟机。键入以下命令以连接到 postgres sql。
sudo -i -u <postgres-username>
    您可以使用 psql,它是一个基于终端的 PostgreSQL 前端
psql
    根据您的复制槽检查 pid。
select * from pg_replication_slots;

输入以下内容将其杀死。

sudo kill <pid>

【讨论】:

以上是关于终止 postgres 复制模式连接的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

python连接postgres方法

在 Windows 中,停止 postgres 服务会导致节点崩溃并显示“错误:由于管理员命令而终止连接”

Postgres维护的正确顺序

具有多个模式和用户的连接池 Postgres

如何正确拆除多人连接会话?

如何检查子进程是不是正确终止? [复制]