Is there a timeout for idle PostgreSQL connections?

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

I see a lot of them. We are trying to fix our connection leak. But meanwhile, we want to set a timeout for these idle connections, maybe max to 5 minute.

249382 次浏览

这听起来像是在应用程序中有一个 接线泄漏,因为它是 fails to close pooled connections。不仅仅是 <idle> in transaction会话有问题,而且总体上连接太多。

切断连接不是解决这个问题的正确答案,但这是一个可以接受的临时解决方案。

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

如@Doon 建议的,设置超时请参见 如何自动关闭 PostgreSQL 中的空闲连接?,它建议您使用 PgBouncher 代理 PostgreSQL 并管理空闲连接。如果您有一个漏洞百出的应用程序,它无论如何都会泄漏连接,那么这是一个非常好的主意; 我 非常强烈建议配置 PgBouncher。

TCP Keepalive在这里无法完成任务,因为应用程序仍然连接在一起,而且是活的,它不应该这样。

在 PostgreSQL 9.2及以上版本中,可以使用新的 state_change时间戳列和 pg_stat_activitystate字段来实现空闲连接收割机。让 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;

在旧版本中,您需要实现复杂的方案来跟踪连接何时空闲。不用麻烦了,只要使用 pgbuncer。

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

SELECT
pg_terminate_backend(procpid)
FROM
pg_stat_activity
WHERE
current_query = '<IDLE>'
AND
now() - query_start > '00:10:00';

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

SET SESSION idle_in_transaction_session_timeout = '5min';

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

idle_in_transaction_session_timeout = 30000 (毫秒)

允许在没有外部调度任务的情况下启用数据库会话超时的一种可能的解决方案是使用我开发的扩展 超时

另一个选项是设置此值“ tcp _ keepalives _ dle”。

对于中断的连接有一个超时(即由于网络错误) ,这依赖于操作系统的 TCP 保持活动特性。默认情况下,在 Linux 上,断开的 TCP 连接在约2小时后关闭(参见 sysctl net.ipv4.tcp_keepalive_time)。

对于放弃的事务(idle_in_transaction_session_timeout)和锁(lock_timeout)也有超时。建议在 postgresql.conf中设置这些值。

But there is no timeout for a properly established client connection. If a client wants to keep the connection open, then it should be able to do so indefinitely. If a client is leaking connections (like opening more and more connections and never closing), then fix the client. Do 没有 try to abort properly established idle connections on the server side.