2012-09-12 58 views
26

某些客户端连接到我们的postgresql数据库,但保持连接打开。 是否可以告诉Postgresql在一定数量的不活动之后关闭这些连接?如何自动关闭PostgreSQL中的空闲连接?

TL; DR

如果您使用PostgreSQL的版本> = 9.2
然后用the solution I came up with

如果你不想写任何代码
然后使用arqnid's solution

+2

你可以使用cron作业来看看,当连接上一个活动(见'pg_stat_activity')和使用' pg_terminate_backend'来杀死旧的。以简单的查询轻松表达。不过,我不确定'pg_terminate_backend'在古老的8.3中是否可用。 –

回答

27

对于那些有兴趣谁,这里是我想出了一个解决方案,从Craig Ringer的评论的启发:

(...)使用cron作业来看看当连接最后有效(见和pg_stat_activity),并使用pg_terminate_backend杀死旧的(...)

选择的解决方案可以归结如下:。

  • 首先,我们升级到Postgresql 9.2。
  • 然后,我们安排一个线程每秒运行一次。
  • 当线程运行时,它会查找任何旧的非活动连接。
    • 的连接被认为是不活动的如果状态要么idleidle in transactionidle in transaction (aborted)disabled
    • 连接被认为是如果其最后状态已经改变超过5分钟。
  • 还有其他线程与上面相同。但是,这些线程以不同的用户连接到数据库。
  • 我们至少为连接到我们数据库的任何应用程序打开一个连接。 (rank()功能)

这是SQL查询在线程中运行:

WITH inactive_connections AS (
    SELECT 
     pid, 
     rank() over (partition by client_addr order by backend_start ASC) as rank 
    FROM 
     pg_stat_activity 
    WHERE 
     -- Exclude the thread owned connection (ie no auto-kill) 
     pid <> pg_backend_pid() 
    AND 
     -- Exclude known applications connections 
     application_name !~ '(?:psql)|(?:pgAdmin.+)' 
    AND 
     -- Include connections to the same database the thread is connected to 
     datname = current_database() 
    AND 
     -- Include connections using the same thread username connection 
     usename = current_user 
    AND 
     -- Include inactive connections only 
     state in ('idle', 'idle in transaction', 'idle in transaction (aborted)', 'disabled') 
    AND 
     -- Include old connections (found with the state_change field) 
     current_timestamp - state_change > interval '5 minutes' 
) 
SELECT 
    pg_terminate_backend(pid) 
FROM 
    inactive_connections 
WHERE 
    rank > 1 -- Leave one connection for each application connected to the database 
+0

最后,我们转到Postgresql 9.2以获得'pg_terminate_backend'的优势。我们使用了一个类似cron的工作来定期调用'pg_terminate_backend'。 – Stephan

+0

你可以发表你使用的脚本吗? – Andrus

+0

@Andrus查看我答案中的更新。 – Stephan

10

通过代理连接,如PgBouncer,这将在server_idle_timeout秒后关闭连接。

+0

可以pg pool II做同样的事吗? – wolf97084

+0

@ wolf97084看到这个答案:http:// stackoverflow。com/a/30769511/363573 – Stephan

+0

@Stephan谢谢!如果你没有在评论中标记我,我会想念答案。 – wolf97084