【PostgreSQL17新特性之-事务级别超时参数transaction_timeout】

PostgreSQL数据库里有多个和会话相关的参数,PostgreSQL17-beta1版本新增了一个transaction_timeout参数,来限制事务的持续时间。

当前的一些和会话相关的超时参数如下

复制代码
+-------------------------------------+---------+------+-------------------------------------------------+---------+---------+---------+------------+----------+
|                name                 | setting | unit |                    category                     | context | vartype | min_val |  max_val   | enumvals |
+-------------------------------------+---------+------+-------------------------------------------------+---------+---------+---------+------------+----------+
| idle_in_transaction_session_timeout | 0       | ms   | Client Connection Defaults / Statement Behavior | user    | integer | 0       | 2147483647 |          |
| idle_session_timeout                | 0       | ms   | Client Connection Defaults / Statement Behavior | user    | integer | 0       | 2147483647 |          |
| lock_timeout                        | 0       | ms   | Client Connection Defaults / Statement Behavior | user    | integer | 0       | 2147483647 |          |
| statement_timeout                   | 0       | ms   | Client Connection Defaults / Statement Behavior | user    | integer | 0       | 2147483647 |          |
| transaction_timeout                 | 0       | ms   | Client Connection Defaults / Statement Behavior | user    | integer | 0       | 2147483647 |          |
+-------------------------------------+---------+------+-------------------------------------------------+---------+---------+---------+------------+----------+
(5 rows)
参数名 作用
idle_in_transaction_session_timeout IDLE IN TRANSACTION状态会话超时时间
idle_session_timeout IDLE 状态会话超时时间
lock_timeout 锁等待超时时间
statement_timeout 一条SQL语句执行的超时时间
transaction_timeout 一个事务执行的超时时间

一、关于transaction_timeout参数

复制代码
Expanded display is on.
postgres<17beta1>(ConnAs[postgres]:PID[21590] 2024-05-28/17:08:02)=# select * from pg_settings where name like 'transaction_timeout';
+-[ RECORD 1 ]----+-----------------------------------------------------------------------------------------------------+
| name            | transaction_timeout                                                                                 |
| setting         | 0                                                                                                   |
| unit            | ms                                                                                                  |
| category        | Client Connection Defaults / Statement Behavior                                                     |
| short_desc      | Sets the maximum allowed duration of any transaction within a session (not a prepared transaction). |
| extra_desc      | A value of 0 turns off the timeout.                                                                 |
| context         | user                                                                                                |
| vartype         | integer                                                                                             |
| source          | default                                                                                             |
| min_val         | 0                                                                                                   |
| max_val         | 2147483647                                                                                          |
| enumvals        |                                                                                                     |
| boot_val        | 0                                                                                                   |
| reset_val       | 0                                                                                                   |
| sourcefile      |                                                                                                     |
| sourceline      |                                                                                                     |
| pending_restart | f                                                                                                   |
+-----------------+-----------------------------------------------------------------------------------------------------+

1.相关注意

如果transaction_timeout值为0,则认为超时控制无效。如果transaction_timeout小于或等于idle_in_transaction_session_timeout或statement_timeout,则忽略较长的超时。

2.使用场景

可以根据实际场景合理配置,一定程度避免长事务。

比如一个事务内发出许多低延迟的查询,但是一个事务内执行的SQL数量很大的时候,整个事务需要很长时间处理。可以通过该参数让这个长的事务回滚。

二、transaction_timeout参数效果测试

首先编辑一个SQL文件,编辑test_transaction_timeout.sql

内容如下:

复制代码
begin;
\timing
set statement_timeout = 1500;
--set transaction_timeout=3000;
select  'ysla tests-1';
select pg_sleep(1);
select  'ysla tests-2';
select pg_sleep(1);
select  'ysla tests-3';
select pg_sleep(1);
select  'ysla tests-4';
commit;

在一个事务里重复执行打印字符以及pg_sleep(1)函数,这两部分分别当作低延迟的查询。然后在事务的开头设置statement_timeout = 1500。transaction_timeout参数暂时先注释掉。事务中的任何 SQL 语句都不会花费超过 1500 毫秒的时间,因此事务将运行完成。

下面跑一下结果,可以看到未触发statement_timeout超时,事务正常结束了。

复制代码
[postgres@xmaster-PostgreSQL-17beta1-06 ~]$ psql -f test_transaction_timeout.sql
Border style is 2.
Line style is ascii.
BEGIN
Timing is on.
SET
Time: 0.168 ms
+--------------+
|   ?column?   |
+--------------+
| ysla tests-1 |
+--------------+
(1 row)

Time: 0.298 ms
+----------+
| pg_sleep |
+----------+
|          |
+----------+
(1 row)

Time: 1013.626 ms (00:01.014)
+--------------+
|   ?column?   |
+--------------+
| ysla tests-2 |
+--------------+
(1 row)

Time: 0.334 ms
+----------+
| pg_sleep |
+----------+
|          |
+----------+
(1 row)

Time: 1014.618 ms (00:01.015)
+--------------+
|   ?column?   |
+--------------+
| ysla tests-3 |
+--------------+
(1 row)

Time: 0.741 ms
+----------+
| pg_sleep |
+----------+
|          |
+----------+
(1 row)

Time: 1014.584 ms (00:01.015)
+--------------+
|   ?column?   |
+--------------+
| ysla tests-4 |
+--------------+
(1 row)

Time: 0.343 ms
COMMIT
Time: 0.525 ms

然后把SQL文件里的transaction_timeout参数的注释打开,此时,statement_timeout=1500,事务内的任何 SQL 语句都不会超过 1500ms,但第三次pg_sleep(1)执行的时候将超过transaction_timeout设置的3s阈值,导致超时错误,会话将被终止,事务也被终止。可以看到打印的信息里也显示了: FATAL: terminating connection due to transaction timeout

表示是由于触发了transaction_timeout参数的阈值而引发的连接断开。

复制代码
[postgres@xmaster-PostgreSQL-17beta1-06 ~]$ psql -f test_transaction_timeout.sql
Border style is 2.
Line style is ascii.
BEGIN
Timing is on.
SET
Time: 0.185 ms
SET
Time: 0.090 ms
+--------------+
|   ?column?   |
+--------------+
| ysla tests-1 |
+--------------+
(1 row)

Time: 0.520 ms
+----------+
| pg_sleep |
+----------+
|          |
+----------+
(1 row)

Time: 1000.747 ms (00:01.001)
+--------------+
|   ?column?   |
+--------------+
| ysla tests-2 |
+--------------+
(1 row)

Time: 0.365 ms
+----------+
| pg_sleep |
+----------+
|          |
+----------+
(1 row)

Time: 1004.818 ms (00:01.005)
+--------------+
|   ?column?   |
+--------------+
| ysla tests-3 |
+--------------+
(1 row)

Time: 0.440 ms
psql:test_transaction_timeout.sql:10: FATAL:  terminating connection due to transaction timeout
psql:test_transaction_timeout.sql:10: server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
psql:test_transaction_timeout.sql:10: error: connection to server was lost

所以,PostgreSQL17-beta1新增的这个务级别超时参数transaction_timeout,在结合我们实际场景合理配置的情况下,可以一定程度避免长事务,避免数据库里存在:单个SQL执行时间短,但是单个事务里包含的SQL较多导致的长事务。需要额外提一嘴的是,如果实际业务就是做的一个事务里包含大量的低延迟SQL,那最好是和业务沟通是否可以进行优化拆分,毕竟参数只是限制时长,达到阈值让他回滚,避免数据库里的事务长时间存在。但是不能从源头上阻止此类长事务的产生。

相关推荐
CCIE-Yasuo7 小时前
网络安全-学习数据库-Mysql-2
数据库·学习·mysql
这个DBA有点耶7 小时前
内核级AI与多模融合:AI数据库在海外场景的落地要点
数据库·人工智能·架构
涛思数据(TDengine)7 小时前
从工业本体到 AI 原生:TDengine 出席 2026 QCon 分享工业数据基础设施路径
大数据·数据库·人工智能·tdengine·工业
Jesse_EC7 小时前
换乘次数最少的路径 SQL 查询详解与实战经验——从 WITH RECURSIVE 到 pgRouting
数据库·postgresql
工控丫丫7 小时前
帆软看板中经常使用的公式函数及经常搭的组合
前端·javascript·数据库
这个DBA有点耶9 小时前
云数据库半夜卡顿,CPU才30%?深挖云盘IOPS突发限制与内核挂起机制
数据库·mysql·云原生
无言听风雨丶10 小时前
Redis 运维实战与排错
运维·数据库·redis
小天源11 小时前
智叟云集系统 · 架构与职责分层
服务器·前端·数据库
herinspace12 小时前
管家婆实用贴-SQL 2008如何修改成混合模式
服务器·数据库·sql·管家婆软件·财务软件·合肥管家婆软件
打螺丝的小李12 小时前
制造企业质量管理系统的三类产品形态:分别解决什么问题
数据库·制造