Postgres libpq 如何判断连接是否已终止
Postgres libpq how to tell if a connection has been terminated
给定以下 libpq 代码:
PGconn * internalConnection = PQconnectdb("my connection string");
if (PQstatus(internalConnection) != CONNECTION_OK)
{
// return error on failure
}
// Kill all connections
if(0 == PQsendQuery(internalConnection, "SELECT pid, (SELECT pg_terminate_backend(pid)) as killed from pg_stat_activity"))
{
// return error on failure
}
执行以下操作:
- 连接到服务器。
- 执行查询,终止所有连接(包括此连接)。
我如何通过客户端得知连接已终止?如果我再次 运行 以下内容:
PQstatus(internalConnection)
我的结果仍然是 CONNECTION_OK
。
使用 MySQL API 我可以在连接上检查 mysql_ping
以查看连接是否仍然打开,但是在 Postgres 上,似乎没有类似的方法打电话(我能找到)。
关于如何从客户端确定连接是否已终止,有什么建议吗?
要通过 libpq
查看连接是否有效,您可以发送空查询字符串:
res = PQexec(conn, "");
并测试结果。
在 PostgreSQL 协议级别,可以使用简单的 Sync
消息更有效地完成此操作,但 libpq
目前没有提供仅发送 Sync
的方法。
不过你不应该那样做。当服务器关闭连接时,它会向客户端发送一个 TCP RST。这应该通知客户端其套接字已关闭。虽然我没有测试过,但我怀疑调用 PQconsumeInput
足以处理连接上的任何剩余数据并注意到套接字已关闭。但是请注意,如果没有要使用的输入,那么此函数将阻止等待来自服务器的消息。
顺便说一句,虽然在这种情况下测试连接是合理的(大概),但通常这是一个非常糟糕的设计。你永远不应该这样做:
- 测试连接
- 运行查询
- 假设成功
因为测试连接和实际执行一个或多个查询之间存在竞争。更不用说查询可能因其他原因而失败。
您的应用程序应该始终能够处理失败的交易,并且能够重试。你应该有适当的逻辑来中止并重试暂时性错误的交易,或者如果连接本身是坏的则重新连接。
PostgreSQL 的 libpq
可以使这比目前对用户更容易。它应该公开一些函数来测试 SQLState
以查看它是否可能是瞬态的,例如,这样应用程序就可以使用单个调用来重试死锁中止、序列化失败等。现在你必须自己做。
给定以下 libpq 代码:
PGconn * internalConnection = PQconnectdb("my connection string");
if (PQstatus(internalConnection) != CONNECTION_OK)
{
// return error on failure
}
// Kill all connections
if(0 == PQsendQuery(internalConnection, "SELECT pid, (SELECT pg_terminate_backend(pid)) as killed from pg_stat_activity"))
{
// return error on failure
}
执行以下操作:
- 连接到服务器。
- 执行查询,终止所有连接(包括此连接)。
我如何通过客户端得知连接已终止?如果我再次 运行 以下内容:
PQstatus(internalConnection)
我的结果仍然是 CONNECTION_OK
。
使用 MySQL API 我可以在连接上检查 mysql_ping
以查看连接是否仍然打开,但是在 Postgres 上,似乎没有类似的方法打电话(我能找到)。
关于如何从客户端确定连接是否已终止,有什么建议吗?
要通过 libpq
查看连接是否有效,您可以发送空查询字符串:
res = PQexec(conn, "");
并测试结果。
在 PostgreSQL 协议级别,可以使用简单的 Sync
消息更有效地完成此操作,但 libpq
目前没有提供仅发送 Sync
的方法。
不过你不应该那样做。当服务器关闭连接时,它会向客户端发送一个 TCP RST。这应该通知客户端其套接字已关闭。虽然我没有测试过,但我怀疑调用 PQconsumeInput
足以处理连接上的任何剩余数据并注意到套接字已关闭。但是请注意,如果没有要使用的输入,那么此函数将阻止等待来自服务器的消息。
顺便说一句,虽然在这种情况下测试连接是合理的(大概),但通常这是一个非常糟糕的设计。你永远不应该这样做:
- 测试连接
- 运行查询
- 假设成功
因为测试连接和实际执行一个或多个查询之间存在竞争。更不用说查询可能因其他原因而失败。
您的应用程序应该始终能够处理失败的交易,并且能够重试。你应该有适当的逻辑来中止并重试暂时性错误的交易,或者如果连接本身是坏的则重新连接。
PostgreSQL 的 libpq
可以使这比目前对用户更容易。它应该公开一些函数来测试 SQLState
以查看它是否可能是瞬态的,例如,这样应用程序就可以使用单个调用来重试死锁中止、序列化失败等。现在你必须自己做。