由 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