PostgreSQL 14: 新增 idle_session_timeout 参数

John Doe 七月 17, 2025

你希望自动断开长时间空闲的连接吗?现在,PostgreSQL 可以超时断开空闲连接了。

在山坡漫步的大象

特性提交日志

新增 idle_session_timeout 参数。

这个 GUC 变量的工作方式与 idle_in_transaction_session_timeout 十分相似,都是在会话等待新的客户端查询时间过长时终止会话。但它适用于未处于事务中的情况,而非处于事务中时。

讨论:https://postgr.es/m/763A0689-F189-459E-946F-F0EC4458980B@hotmail.com

示例

提交日志中的特性描述已经很清晰了,我们直接来看实际操作。

首先,确认一下单位:

select * from pg_settings where name = 'idle_session_timeout' \gx
-[ RECORD 1 ]---+-------------------------------------------------------------------------------
name            | idle_session_timeout
setting         | 0
unit            | ms
category        | Client Connection Defaults / Statement Behavior
short_desc      | Sets the maximum allowed idle time between queries, when not in a transaction.
extra_desc      | A value of 0 turns off the timeout.
context         | user
vartype         | integer
source          | default
min_val         | 0
max_val         | 2147483647
enumvals        | [null]
boot_val        | 0
reset_val       | 0
sourcefile      | [null]
sourceline      | [null]
pending_restart | f

接下来,我们把这个值设置得短一些,重新加载配置,然后进行测试:

select pg_reload_conf();
 pg_reload_conf
----------------
 t
(1 row)

select * from pg_settings where name = 'idle_session_timeout' \gx
-[ RECORD 1 ]---+-------------------------------------------------------------------------------
name            | idle_session_timeout
setting         | 10000
unit            | ms
category        | Client Connection Defaults / Statement Behavior
short_desc      | Sets the maximum allowed idle time between queries, when not in a transaction.
extra_desc      | A value of 0 turns off the timeout.
context         | user
vartype         | integer
source          | configuration file
min_val         | 0
max_val         | 2147483647
enumvals        | [null]
boot_val        | 0
reset_val       | 10000
sourcefile      | /home/pgdba/data/postgresql.auto.conf
sourceline      | 3
pending_restart | f

保持连接,什么也不做。10秒后,在日志中就会看到:

2025-07-12 11:33:38.892 CST redrock@redrock 61973 [local] LOG:  duration: 2.827 ms  statement: select * from pg_settings where name = 'idle_session_timeout' 
2025-07-12 11:33:48.892 CST redrock@redrock 61973 [local] FATAL:  terminating connection due to idle-session timeout
2025-07-12 11:33:48.892 CST redrock@redrock 61973 [local] LOG:  disconnection: session time: 0:01:59.743 user=redrock database=redrock host=[local]

在 psql 会话中,并不会立即看到任何变化,连接断开时通常都是这样,但当我们尝试运行查询时:

select 1;
FATAL:  terminating connection due to idle-session timeout
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.

让我们在事务中进行测试,看看会怎么样:

begin;

select now();
              now              
-------------------------------
 2025-07-12 11:36:32.131091+08
(1 row)

...

select clock_timestamp(), now(), clock_timestamp() - now();
        clock_timestamp        |              now              |    ?column?     
-------------------------------+-------------------------------+-----------------
 2025-07-12 11:37:23.368718+08 | 2025-07-12 11:36:32.131091+08 | 00:00:51.237627
(1 row)

如你所见,尽管我们的连接闲置了大约 50 秒,连接也没有被断开。

另外,该参数值的最大值可设置为 2147483647,且单位是毫秒,这意味着最大的 idle_session_timeout 可以是24天20小时31分左右23秒。这对于检测闲置连接来说,已经足够长了。

这应该会帮助到数据库管理员清除无用的连接。

非常不错的体验,感谢所有参与的社区人员。

参考

提交日志:https://git.postgresql.org/pg/commitdiff/9877374bef76ef03923f6aa8b955f2dbcbe6c2c7