打开PostgreSQL数据库连接的效率

Efficiency of opening PostgreSQL database connections

我们有一个 PostgreSQL 数据库来存储我们的 C++ 应用程序的数据,我们使用 libpqxx 连接到它。

目前,我们为每笔想要 运行 的交易打开一个新的 pqxx::connection。在部署中,我们预计每分钟最多执行四五打事务,我们的应用程序将 运行ning 24x7x365。

根据 PostgreSQL architectural fundamentals,

...[the PostgreSQL server process] starts ("forks") a new process for each connection.

在我看来,我们为每个事务打开一个新 pqxx::connection 的方法确实效率低下,因为我们每分钟间接产生几十个新进程。这是我们真的应该担心的事情吗?

我看到 here on the PostgreSQL wiki PostgreSQL 本身并不维护客户端连接进程池,因此看来我们确实需要担心它。如果是这样,是否有一种 "proper" 方法可以无限期地保留 pqxx::connection 对象,这样每次我需要连接到数据库时都不会分叉一个新进程?请记住,我的应用程序每天都需要 运行,所以我的 TCP 连接在很长一段时间后掉线是不可接受的。

您所做的事情效率低下,但效率不高。 PostgreSQL 在 unix 平台上的 fork 成本很低;后端的创建和销毁成本相当低。

设置、身份验证等确实需要时间,因此您会增加交易延迟。

最好使用连接池,无论是在应用内还是在像 pgbouncer 这样的代理中。也就是说,对于 "a few dozen connections per minute",除非您遇到负载问题,否则我不会太担心。很丑,但还算不错。

TCP 连接不只是 "drop" 在一段时间后。除非你在某些资源有限的有状态 NAT 路由器或防火墙后面,否则它们可以无限期地保持空闲状态。如果你是,你只需要启用 TCP keepalive。没有真正的理由不让连接保持打开状态,只要你愿意。

在任何情况下,您的应用程序应该已经具有连接丢失的重试逻辑,因为后端可能因管理员操作、PostgreSQL 服务器崩溃恢复和重启、错误、服务器资源而终止导致 OOM 等的耗尽。永远不要触发并忘记交易。您的应用程序应该记住从一开始就重做整个 xact 所需的完整状态,直到它收到 xact 已从数据库提交的确认。如果任何步骤出现故障,它应该能够重新连接并重试。