112
1 S postgres  5038   876  0  80   0 - 11962 sk_wai 09:57 ?        00:00:00 postgres: postgres my_app ::1(45035) idle                                                                                 
1 S postgres  9796   876  0  80   0 - 11964 sk_wai 11:01 ?        00:00:00 postgres: postgres my_app ::1(43084) idle             

我看到很多。我们正在尝试修复我们的连接泄漏。但与此同时,我们想为这些空闲连接设置一个超时时间,最长可能为 5 分钟。

4

7 回答 7

135

听起来您的应用程序中存在连接泄漏,因为它无法关闭池连接。您不仅遇到<idle> in transaction会话问题,而且总体上连接太多。

杀死连接不是正确的答案,但它是一个不错的临时解决方法。

与其重新启动 PostgreSQL 以从 PostgreSQL 数据库引导所有其他连接,请参阅:如何从 postgres 数据库中分离所有其他用户?如果有活动连接,如何删除 PostgreSQL 数据库?. 后者显示了更好的查询。

对于设置超时,正如@Doon 建议的那样,请参阅如何自动关闭 PostgreSQL 中的空闲连接?,它建议您使用 PgBouncer 来代理 PostgreSQL 并管理空闲连接。如果您有一个错误的应用程序无论如何都会泄漏连接,这是一个非常好的主意;我非常强烈推荐配置 PgBouncer。

TCP keepalive在这里无法完成这项工作,因为应用程序仍然处于连接状态并处于活动状态,但它不应该如此。

在 PostgreSQL 9.2 及更高版本中,您可以使用新的state_change时间戳列和state字段pg_stat_activity来实现空闲连接收割机。让一个 cron 作业运行如下:

SELECT pg_terminate_backend(pid)
    FROM pg_stat_activity
    WHERE datname = 'regress'
      AND pid <> pg_backend_pid()
      AND state = 'idle'
      AND state_change < current_timestamp - INTERVAL '5' MINUTE;

在旧版本中,您需要实现复杂的方案来跟踪连接何时空闲。不打扰; 只需使用 pgbouncer。

于 2012-11-06T05:37:49.790 回答
81

在 PostgreSQL 9.6 中,有一个新选项idle_in_transaction_session_timeout可以完成您所描述的。您可以使用SET命令设置它,例如:

SET SESSION idle_in_transaction_session_timeout = '5min';
于 2017-01-24T01:09:11.220 回答
23

在 PostgreSQL 9.1 中,空闲连接具有以下查询。它帮助我避免了需要重新启动数据库的情况。这主要发生在 JDBC 连接打开但未正确关闭的情况下。

SELECT
   pg_terminate_backend(procpid)
FROM
   pg_stat_activity
WHERE
   current_query = '<IDLE>'
AND
   now() - query_start > '00:10:00';
于 2013-05-16T08:22:01.560 回答
12

如果您使用的是 postgresql 9.6+,那么您可以在 postgresql.conf 中设置

idle_in_transaction_session_timeout = 30000 (毫秒)

于 2018-03-03T20:58:04.567 回答
3

断开连接(即由于网络错误)会超时,这取决于操作系统的 TCP keepalive 功能。默认情况下,在 Linux 上,断开的 TCP 连接会在大约 2 小时后关闭(请参阅 参考资料sysctl net.ipv4.tcp_keepalive_time)。

idle_in_transaction_session_timeout被放弃的事务和锁也有超时lock_timeout。建议将这些设置在postgresql.conf.

但是正确建立的客户端连接没有超时。如果客户端想要保持连接打开,那么它应该能够无限期地这样做。如果客户端正在泄漏连接(例如打开越来越多的连接并且从不关闭),则修复客户端。不要尝试在服务器端中止正确建立的空闲连接。

于 2021-01-06T12:21:46.230 回答
1

允许在没有外部计划任务的情况下启用数据库会话超时的可能解决方法是使用我开发的扩展pg_timeout 。

于 2020-04-05T11:32:40.807 回答
1

另一个选项是将此值设置为“tcp_keepalives_idle”。在文档https://www.postgresql.org/docs/10/runtime-config-connection.html中查看更多信息。

于 2020-12-14T12:11:52.510 回答