如何在PostgreSQL自动关闭空闲连接?(How to close idle connectio

2019-06-18 03:26发布

某些客户端连接到我们的PostgreSQL数据库,但留下打开的连接。 是否可以告诉PostgreSQL的收一定量的闲置后的连接?

TL; DR

如果您使用PostgreSQL的版本> = 9.2
然后用我想出了解决方案

如果你不想写任何代码
然后用arqnid的解决方案

Answer 1:

对于那些有兴趣谁,这里是我想出了一个解决方案,从激励克雷格·林格的评论:

(......)使用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


Answer 2:

通过像代理服务器连接PgBouncer将关闭后连接server_idle_timeout秒。



Answer 3:

如果您在使用PostgreSQL> = 9.6还有一个更简单的解决方案。 让我们假设你想删除所有空闲连接,每5分钟,刚刚运行以下命令:

alter system set idle_in_transaction_session_timeout='5min';

如果您没有访问作为超级用户(在Azure云为例),请尝试:

SET SESSION idle_in_transaction_session_timeout = '5min';

但是,后者将只在当前会话中,最有可能的是不是你想要的。

禁用功能,

alter system set idle_in_transaction_session_timeout=0;

要么

SET SESSION idle_in_transaction_session_timeout = 0;

(顺便说一下,0为默认值)。

如果你使用alter system ,你必须重新加载配置开始改变和变化是永久性的,你将不必再重新运行查询,如果,例如,你会重新启动服务器。

要检查功能状态:

show idle_in_transaction_session_timeout;


文章来源: How to close idle connections in PostgreSQL automatically?