选择 打开 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

文档 / SQL 状态码 / Class 25 事务状态无效

25P04 transaction_timeout

事务超时

ERROR 已实测 详解 实测通过

类别
Class 25 事务状态无效
严重等级
ERROR
条件名
transaction_timeout
宏名称
ERRCODE_TRANSACTION_TIMEOUT
启用版本
17
状态
活跃

版本覆盖

  1. 18
  2. 17
  3. 16
  4. 15
  5. 14
  1. 13
  2. 12
  3. 11
  4. 10
  1. 19 beta
  2. 20 dev

速览

25P04transaction_timeout 触发的 FATAL 条件,覆盖显式 BEGIN 事务和由单条语句隐式启动的事务。选定的 18.6 案例使用 300 ms;PG10 因设置不可用而在源码/版本预检阶段跳过,不会探测未知设置。另有 PG16.15/PG17.11 的版本边界对照:PG16 返回设置不可用的 42704,PG17 实际产生 FATAL 25P04;该对照独立于选定基础案例。

含义

transaction_timeout 限制显式或隐式事务的存活时间,包括事务打开期间执行或等待的时间。触发后 PostgreSQL 发出 terminating connection due to transaction timeout 并终止会话。它不同于只中止一条语句的 statement_timeout,也不同于只覆盖客户端在开放事务中空闲时间的 idle_in_transaction_session_timeout。若 transaction_timeout 小于或等于其中任一设置,较长的超时会被忽略;预备事务不受此设置约束。

诊断

在支持该设置的服务器上,先在目标会话自身检查有效的 SHOW transaction_timeoutSHOW statement_timeoutSHOW idle_in_transaction_session_timeout。控制连接上的 SHOWpg_settings 反映的是观察者后端,不能用来确认另一个会话实际通过 SET 得到的值。再从控制连接查看 pg_stat_activitypidapplication_namestatexact_startstate_changequery_startquery 等字段,定位所属应用或连接池,并判断事务是在执行还是空闲。按 backend PID、SQLSTATE 25P04、error_severity = FATAL 和精确报文匹配日志收集器记录。选定的 18.6 运行中驱动也暴露了 25P04,原连接已关闭;新的连接成功执行 SELECT 1。PG10 在发送 SET transaction_timeout 之前就由最低版本预检跳过。

处理

丢弃已终止的会话并重连。对合法的长事务,可缩短工作、拆分工作单元或提高有效超时以控制在预算内;不要为了掩盖错误而降低超时。只有部署明确接受取消该保护时才设为 0。服务器关闭终止的会话时会在退出前回滚开放且尚未完成的事务;死亡连接不能再接收 ROLLBACK。已知尚未在该会话上提交的事务,不能通过该连接恢复。若另一种网络故障使客户端无法确定 COMMIT 是否到达服务器,应从新连接对账业务结果再重试;选定案例没有发送提交,不能据此声称存在这种不确定性。本批 PG10 没有兼容设置。

可复现案例

在一次性实例上执行过的场景。其中 2 个附有可执行 SQL,正文相应小节里给出。

transaction_timeout PG 18 有 SQL

前置条件

  • A runner-owned disposable target is provisioned.

触发

On a server supporting transaction_timeout, set it, BEGIN, wait, and probe the terminated session.

断言

  • The original session is terminated by the timeout when supported
  • The collector records FATAL 25P04 for the matching backend PID
  • A fresh connection can execute SELECT 1
  • PG10 is explicitly not applicable

处置

Use the state-specific recovery documented on the page; do not reuse a terminated connection.

清理

Drop the case schema with an owner connection.

transaction_timeout_version_boundary PG 16 / 17 有 SQL

前置条件

  • A disposable PostgreSQL 16 or 17 target

触发

Probe transaction_timeout on PG16; on PG17 set it, BEGIN, wait, and probe the terminated session.

断言

  • PG16 records the actual unsupported-setting diagnostic and recovers
  • PG17 records exact FATAL 25P04 collector fields and a registry-based fresh connection probe

处置

Treat PG16 as unsupported for this setting; for PG17 use a fresh connection after the FATAL and determine unfinished work from the application transaction boundary.

清理

Drop the case schema with an owner connection.

FATAL 报文

服务器源码固定报出 terminating connection due to transaction timeout,严重级别为 FATAL;原连接会被终止。

报文模板

源码里的格式串,不是某一次运行的输出。%s 之类是占位符,实际报文会填入对象名与取值。适用范围一栏是核验时留下的原始英文记录,未经翻译。

主消息 terminating connection due to transaction timeout

来源:src/backend/tcop/postgres.c @ REL_18_6

适用范围:This is a static FATAL message; the driver may expose or omit SQLSTATE depending on client stack.

实测诊断

18.6 (Homebrew) / latest:FATAL SQLSTATE 25P04;主报文 terminating connection due to transaction timeout;backend PID 30576;原连接已关闭 True;CSV 日志 25P04;JSON 日志 25P04;新连接探测 110.21 (Debian 10.21-1.pgdg90+1) / pg10:案例 not_applicable(最低版本预检;未探测该目标不支持的设置)。

单独的边界对照:16.15 / pg16 因设置不可用返回 42704 并保持 IDLE,因此不计作 25P04 覆盖;17.11 / pg17 在 300 ms 后由 PID 73 产生 FATAL 25P04,CSV 与 JSON 都记录 FATAL 25P04,原连接关闭,新连接为 IDLE。这些记录不计入选定基础案例。

代表案例

下列 SQL 片段不是一次性粘贴脚本:在测试连接上执行设置、PID 和 BEGIN 后停止发送查询,由独立观察连接或日志收集器等待 FATAL;原连接终止后,另开新连接执行最后的探测。运行器从共享语句清单(registry)读取这些语句,完整断言、日志收集器关联、环境和清理见 案例导出

-- set_timeout
SET transaction_timeout = '300ms';
-- backend_pid
SELECT pg_backend_pid();
-- begin
BEGIN;
-- probe
SELECT 1;

上述片段的 SQLSTATE、诊断、状态和修复断言来自共享语句清单(registry)(SHA-256 d05a26e56716c5c8c178f741843e6b14be87423ec9d1eb1a026ff67a57ce4658);结构化证据

作者证据 ID:identitytimeout-pathruntimeruntime.version-boundary。选定基础运行记录:runtime.25P04-batch2c-latest-20260909.latest。单独的边界记录:runtime.25P04-boundary-pg16-20260909.pg16runtime.25P04-boundary-pg17-20260909.pg17

单独的边界对照已经记录了可用性结果:PG16 返回 42704,PG17 继续并实际产生 FATAL 25P04。这个边界块是分支说明,不能整块一次性粘贴执行。在 PG16 上先执行 SHOW transaction_timeout;得到预期的 42704 后,如需证明连接仍健康,应在同一连接执行 SELECT 1,然后停止,跳过 SET transaction_timeoutBEGIN 和等待超时。在 PG17 或更高版本上,只有 SHOW 成功后才在目标连接执行 SET transaction_timeout、记录 PID 并执行 BEGIN;随后停止发送查询,由观察连接或日志收集器等待旧连接出现 FATAL 并关闭,最后只在新连接上执行探测。这些边界记录用于诊断对照,不增加选定基础案例数量。

-- availability_probe
SHOW transaction_timeout;
-- set_timeout
SET transaction_timeout = '300ms';
-- backend_pid
SELECT pg_backend_pid();
-- begin
BEGIN;
-- probe
SELECT 1;

版本与边界

锁定目录首次观察到 transaction_timeout 为 17.0。选定的 18.6 案例以 CSV/JSON 日志收集证据和新连接探测通过。单独的 PG17.11 边界案例实际记录了 FATAL 25P04,PG16.15 则记录设置不可用的 42704;两者都不替代选定基础运行。PG10 是真实的 not_applicable 最低版本预检跳过:handler 不会发送或探测未知设置,因此这不构成更早版本边界证据。

来源

证据

断言

每条断言都写明了是怎么核实的,以及它不覆盖什么。这一层是核验时留下的原始英文记录,照原样呈现,未经翻译。

  • 25P04 is transaction_timeout in Class 25.

    核实方式Read the fixed condition row and macro.

    不覆盖The locked catalogue first observes this condition in PostgreSQL 17.0; no earlier runtime claim is made.

    来源src/backend/utils/errcodes.txt

  • ProcessInterrupts emits FATAL 25P04 when an explicit or implicitly started transaction exceeds transaction_timeout.

    核实方式Trace the timeout interrupt and the fixed configuration documentation.

    不覆盖The selected PG10 target lacks this setting and is explicitly not applicable; the session is terminated when the path fires.

    来源src/backend/tcop/postgres.c · doc/src/sgml/config.sgml · raw/calls/REL_18_6.jsonl

  • The selected PostgreSQL 18.6 case received FATAL 25P04 for the exact backend PID and recovered only by opening a fresh connection; the PG10 case is not applicable.

    核实方式Match collector records by PID, SQLSTATE, and message, then probe a fresh connection.

    不覆盖This verifies 18.6 and the PG10 applicability boundary only; it does not claim all intermediate releases without an adjacent source check.

  • The fixed monitoring documentation defines pg_stat_activity as one row per server process with current activity, including xact_start and state_change; pg_settings is defined over pg_show_all_settings for the current backend. Capture timeout settings on the timed session itself, because SHOW or pg_settings on an observer connection cannot establish another backend's effective SET value.

    核实方式Read the fixed monitoring view documentation and system-view definition before writing the observer/session diagnostic split.

    不覆盖Visibility of pg_stat_activity fields depends on observer privileges; the selected runtime records establish PID/log correlation, not universal monitoring permissions.

    来源doc/src/sgml/monitoring.sgml · src/backend/catalog/system_views.sql

  • The fixed protocol documentation states that when the backend closes a connection it rolls back any open incomplete transaction before exiting; the driver cannot send a later ROLLBACK on that closed session.

    核实方式Read the fixed protocol session-termination rule and align the recovery prose with the FATAL path.

    不覆盖This establishes server-side rollback on forced connection close; it does not resolve a separate network failure after a client may have sent COMMIT.

    来源doc/src/sgml/protocol.sgml

  • On the fixed availability-boundary registry case, PostgreSQL 16.15 rejects SHOW transaction_timeout with 42704 and remains IDLE, while PostgreSQL 17.11 receives FATAL 25P04 after a 300 ms timeout in an idle-in-transaction session; the original session closes and a fresh connection is IDLE.

    核实方式Compare the fixed PG16 availability probe and PG17 timeout summaries, including driver diagnostics, both collector severities, PID correlation, termination, and fresh-connection recovery.

    不覆盖This is a bounded PG16.15/PG17.11 comparison for transaction_timeout. PG16 42704 is not 25P04 coverage; the records do not replace the selected 18.6 run or establish every intermediate minor release.

    来源doc/src/sgml/config.sgml · doc/src/sgml/protocol.sgml

运行记录

目标服务器版本结果覆盖案例
latest 18.6 (Homebrew) passed transaction_timeout
pg10 10.21 (Debian 10.21-1.pgdg90+1) not_applicable transaction_timeout
pg16 16.15 (Debian 16.15-1.pgdg13+2) not_applicable transaction_timeout_version_boundary
pg17 17.11 (Debian 17.11-1.pgdg13+2) passed transaction_timeout_version_boundary

同类 SQL 状态码

状态码 条件名 宏名称 严重等级 版本
Class 25 事务状态无效 Invalid Transaction State 13 个
25000 invalid_transaction_state ERRCODE_INVALID_TRANSACTION_STATE ERROR 7.4
事务状态无效的类别码,多见于内部状态检查。 活跃
25001 active_sql_transaction ERRCODE_ACTIVE_SQL_TRANSACTION ERROR 7.4
命令不能在活动事务块中执行,如 VACUUM。 活跃
25002 branch_transaction_already_active ERRCODE_BRANCH_TRANSACTION_ALREADY_ACTIVE ERROR 7.4
分支事务已经活动,范围窄于 25001。 活跃
25003 inappropriate_access_mode_for_branch_transaction ERRCODE_INAPPROPRIATE_ACCESS_MODE_FOR_BRANCH_TRANSACTION ERROR 7.4
分支事务使用了不适用的访问模式。 活跃
25004 inappropriate_isolation_level_for_branch_transaction ERRCODE_INAPPROPRIATE_ISOLATION_LEVEL_FOR_BRANCH_TRANSACTION ERROR 7.4
分支事务使用了不适用的隔离级别。 活跃
25005 no_active_sql_transaction_for_branch_transaction ERRCODE_NO_ACTIVE_SQL_TRANSACTION_FOR_BRANCH_TRANSACTION ERROR 7.4
分支事务缺少活动的 SQL 事务。 活跃
25006 read_only_sql_transaction ERRCODE_READ_ONLY_SQL_TRANSACTION ERROR 7.4
命令试图在只读事务中写入数据。 活跃
25007 schema_and_data_statement_mixing_not_supported ERRCODE_SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED ERROR 7.4
事务中不支持混合模式语句与数据语句。 活跃
25008 held_cursor_requires_same_isolation_level ERRCODE_HELD_CURSOR_REQUIRES_SAME_ISOLATION_LEVEL ERROR 7.4
持有游标要求与操作相同的事务隔离级别。 活跃
25P01 no_active_sql_transaction ERRCODE_NO_ACTIVE_SQL_TRANSACTION ERROR 7.4
操作需要活动事务块,如自动提交下的 SAVEPOINT。 活跃
25P02 in_failed_sql_transaction ERRCODE_IN_FAILED_SQL_TRANSACTION ERROR 7.4
事务已失败,后续语句被拒绝直到 ROLLBACK。 活跃
25P03 idle_in_transaction_session_timeout ERRCODE_IDLE_IN_TRANSACTION_SESSION_TIMEOUT ERROR 9.6
会话在开放事务中空闲超时,被服务器终止。 活跃
25P04 transaction_timeout ERRCODE_TRANSACTION_TIMEOUT ERROR 17
事务运行超过 transaction_timeout 被终止。 活跃