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分钟。
答案 0 :(得分:99)
听起来你的应用程序中有连接泄漏,因为它无法关闭池连接。您只是在<idle> in transaction
个会话中遇到问题,但总体来说连接太多。
杀死连接不是正确的答案,但这是一个好的临时解决方法。
请点击:How do I detach all other users from a postgres database?和How to drop a PostgreSQL database if there are active connections to it?,而不是重新启动PostgreSQL以从PostgreSQL数据库启动所有其他连接。后者显示了更好的查询。
为了设置超时,正如@Doon建议的那样,请How to close idle connections in PostgreSQL automatically?建议您使用PgBouncer代理PostgreSQL并管理空闲连接。如果你有一个错误的应用程序泄漏连接,这是一个非常好的主意;我非常强烈建议配置PgBouncer。
TCP keepalive不会在这里完成这项工作,因为该应用仍处于连接状态,而且不应该存在。
在PostgreSQL 9.2及更高版本中,您可以使用新的state_change
时间戳列和state
的{{1}}字段来实现空闲连接收割机。有一个cron工作运行这样的事情:
pg_stat_activity
在旧版本中,您需要实现复杂的方案,以跟踪连接何时空闲。不打扰;只需使用pgbouncer。
答案 1 :(得分:50)
在PostgreSQL 9.6中,有一个新选项idle_in_transaction_session_timeout
可以完成你描述的内容。您可以使用SET
命令设置它,例如:
SET SESSION idle_in_transaction_session_timeout = '5min';
答案 2 :(得分:18)
在PostgreSQL 9.1中,使用以下查询进行空闲连接。它帮助我摆脱了重启数据库所需的情况。这种情况主要发生在JDBC连接打开且未正确关闭的情况下。
SELECT
pg_terminate_backend(procpid)
FROM
pg_stat_activity
WHERE
current_query = '<IDLE>'
AND
now() - query_start > '00:10:00';
答案 3 :(得分:2)
如果您使用的是postgresql 9.6+,那么在postgresql.conf中可以设置
idle_in_transaction_session_timeout = 30000
(毫秒)
答案 4 :(得分:0)
一种可能的解决方法是允许使用数据库扩展名pg_timeout,而该扩展名无需启用外部计划任务即可启用数据库会话超时。
答案 5 :(得分:0)
另一个选项是将此值设置为“ tcp_keepalives_idle”。查看文档https://www.postgresql.org/docs/10/runtime-config-connection.html中的更多内容。
答案 6 :(得分:0)
断开的连接(即由于网络错误)存在超时,这依赖于操作系统的 TCP 保持连接功能。默认情况下,在 Linux 上,断开的 TCP 连接会在大约 2 小时后关闭(请参阅 sysctl net.ipv4.tcp_keepalive_time
)。
对于放弃的事务 idle_in_transaction_session_timeout
和锁定 lock_timeout
也有超时。建议在 postgresql.conf
中设置这些。
但是正确建立的客户端连接没有超时。如果客户端想要保持连接打开,那么它应该能够无限期地这样做。如果客户端泄漏连接(例如打开越来越多的连接并且永不关闭),则修复客户端。不要不要尝试在服务器端中止正确建立的空闲连接。