是否有空闲的PostgreSQL连接超时?

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分钟。

这听起来像你的应用程序连接泄漏 ,因为它无法closures池连接 。 您<idle> in transaction会话中没有<idle> in transaction问题,但总体连接数太多。

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

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

要设置超时,请参阅@Doonbuild议,请参阅如何自动closuresPostgreSQL中的空闲连接? ,build议您使用PgBouncer代理PostgreSQL并pipe理空闲连接。 这是一个非常好的主意,如果你有一个错误的应用程序无论如何泄漏连接; 我强烈build议configurationPgBouncer。

一个TCP Keepalive不会在这里做这个工作,因为这个应用程序仍然是连接的并且还活着,它不应该是。

在PostgreSQL 9.2及更高版本中,可以使用新的state_change timestamp列和state_changestatus字段来实现空闲连接收割者。 有一个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; 

在旧版本中,您需要实现复杂的scheme,以跟踪连接何时闲置。 不要打扰 只需使用pgbouncer。

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

 SET SESSION idle_in_transaction_session_timeout = '5min'; 

在PostgreSQL 9.1中,空闲连接和下面的查询。 它帮助我避免了重新启动数据库所需的情况。 这主要发生在打开JDBC连接并未正确closures的情况下。

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