闲置的PostgreSQL连接是否超时?


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


您如何连接到数据库?socketTimeout可能是您想要的。
Doon 2012年

我们拥有旧版的Pylons网络应用程序,并且使用了SQLAlchemy,但显然我们没有正确使用它。我不记得了 我们正在尝试解决泄漏问题。socketTimeout从文档中看起来像这样完全关闭了与数据库的连接。我试图关闭每个空闲状态,并在建立连接后立即启动计数器。
user1012451


@ user1012451当您说“关闭每个空闲”时,您是指终止<IDLE> in transaction会话,使会话处于运行<IDLE>状态但仍处于状态吗?换句话说,终止事务但不终止会话?(投票:不清楚的问题)
克雷格·林格

一段时间后,@ CraigRinger,我们达到最大的客户端连接。为了解决这个问题,我们必须重新启动webapp,这也将强制重新启动postgresql。这消除了所有连接。当我们idle永远看到这些内容时,我们在问是否可以为每个连接/会话设置超时(老实说,我不知道正确的术语,对不起)。如果一个普通的Web应用程序需要5分钟的交易时间,那肯定是错误的....
user1012451

Answers:


118

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

终止连接不是解决此问题的正确方法,但这是一个可以解决的临时解决方法。

与其重新启动PostgreSQL以从PostgreSQL数据库启动所有其他连接,不如参见:如何将所有其他用户与 PostgreSQL数据库分离?以及如果存在活动连接如何删除PostgreSQL数据库?。后者显示了更好的查询。

有关设置超时的信息,如@Doon所示,请参见如何自动关闭PostgreSQL中的空闲连接?,建议您使用PgBouncer代理PostgreSQL和管理空闲连接。如果您有一个错误的应用程序仍然会泄漏连接,那么这是一个很好的主意。我强烈建议配置PgBouncer。

一个TCP存活不会在这里做的工作,因为该应用程序仍处于连接状态,充满活力,它只是不应该。

在PostgreSQL 9.2及更高版本中,您可以使用new state_changetimestamp列和stateof字段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。


4
很好,但是它将杀死其他PgAdmin后端。使用附加条件application_name =''
Andrew Selivanov 2013年

1
如果我使用pgbouncer,可以运行pg_terminate_backend吗?
亨利·邱

@HenleyChiu我不明白为什么不这样做,尽管我没有特别检查。
Craig Ringer 2013年

1
运行该命令似乎已杀死了我的WAL发送者进程
Joseph Persie

@CraigRinger甚至psql连接都被视为空闲连接。以及为什么必须首先关闭空闲连接。我有一个运行时间很长的代码,它与pg建立连接,执行一些dml操作,然后在队列中等待消息,然后再执行一些dml操作。即使这样与邮资的联系是idle。我为什么要关闭它。
维伦(Viren)2016年

72

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

SET SESSION idle_in_transaction_session_timeout = '5min';

1
不得不问这么简单的问题真是太难了,但是我通常是数据库的新手-您能否举一个非常基本的示例说明如何使用此功能?
sg

PostgreSQL早期版本中的类似内容?
sdsc81

不,以前的版本需要类似于其他答案的内容。
shosti

您是否需要在每次数据库重新启动时设置此参数?还是一旦做完就可以忘记?谢谢
fresko '18 -10-8

5
SET SESSION仅用于当前会话(一旦打开新连接,它将恢复为默认值)。您还可以使用ALTER DATABASE SET idle_in_transaction_session_timeout = '5min'或使用配置文件在数据库级别上设置配置参数(请参阅postgresql.org/docs/current/static/config-setting.html)。
shosti

22

在PostgreSQL 9.1中,带有以下查询的空闲连接。它帮助我避免了重启数据库时出现的情况。大多数情况是在JDBC连接打开且未正确关闭的情况下发生的。

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

1
pg_terminate_backend是因为8.4
安德鲁银行

8

如果您使用的是PostgreSQL 9.6+,则可以在postgresql.conf中进行设置

idle_in_transaction_session_timeout = 30000 (毫秒)


0

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.