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

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

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

25001 active_sql_transaction

活动 SQL 事务

ERROR 已实测 详解 实测通过

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

版本覆盖

速览

25001 表示当前活动 SQL 事务违反了命令要求的事务边界。本案例在 BEGIN 后执行 VACUUM,得到精确错误;回滚后在事务块外执行 VACUUM 成功且连接保持 IDLE

含义

该码覆盖多条路径:PreventInTransactionBlock 会拒绝事务块、子事务或函数中的禁用 utility,源码分别格式化为 %s cannot run inside a transaction block%s cannot run inside a subtransaction%s cannot be executed from a function。其他路径会拒绝写入后的逻辑复制槽、子事务中的快照导出,或查询开始后的导入快照设置。在已经活动的事务中再次 BEGIN 是独立的 WARNING,因此严重级别和恢复方式取决于具体源码路径。

诊断

记录 SQLSTATE、严重级别、主报文、事务状态和命令。本案例的 VACUUM ERROR 后显式会话进入 INERROR,只有 ROLLBACK 恢复 IDLE。函数或子事务报错时,应先结束该上下文,再把命令作为位于任何显式事务块之外的一条独立顶层 utility 命令发出(例如驱动自动提交的单条命令);在同一 wrapper 内重试仍不满足 PreventInTransactionBlock。逻辑复制槽和快照报错则要检查是否已有写入、子事务或查询;“事务已在进行中”的 WARNING 不是 VACUUM 的 ERROR,本身不要求回滚。随后选定修复在事务块外执行 VACUUM,并断言成功和 IDLE

处理

禁用 utility 若位于不合适的事务块、函数或子事务中,应移到位于任何显式事务块之外的一条独立顶层命令(通常在自动提交连接上执行);不要把“顶层”理解为另一个 BEGIN。显式事务中的 ERROR 后先执行 ROLLBACK,再执行该命令。逻辑复制槽必须在此前没有写入的事务中创建;快照导出不能位于子事务,SET TRANSACTION SNAPSHOT 必须早于任何查询。重复 BEGINWARNING 应保留已有事务,不要仅因警告就回滚。应按精确源码路径处理,不能机械套用 VACUUM 修复。

可复现案例

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

vacuum_inside_transaction PG 10 / 18 有 SQL

前置条件

  • A disposable table exists
  • VACUUM is issued after an explicit BEGIN

触发

Run VACUUM inside an explicit transaction block.

断言

  • SQLSTATE is 25001
  • The transaction enters INERROR and rollback restores IDLE
  • The same connection can execute a follow-up query
  • VACUUM succeeds after rollback outside the transaction block

处置

Run transaction-control-restricted utility commands outside the transaction block; rollback the failed transaction before reuse.

清理

Drop the case schema with an owner connection.

实测诊断

18.6 (Homebrew) / latest:SQLSTATE 25001;primary VACUUM cannot run inside a transaction block;after_error INERROR;after_rollback IDLE;status_after_vacuum IDLE10.21 (Debian 10.21-1.pgdg90+1) / pg10:SQLSTATE 25001;primary VACUUM cannot run inside a transaction block;after_error INERROR;after_rollback IDLE;status_after_vacuum IDLE

报文模板

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

主消息 %s cannot run inside a transaction block

来源:src/backend/access/transam/xact.c @ REL_18_6

适用范围:The %s substitution is the command name; this is one ERROR path for 25001.

主消息 %s cannot run inside a subtransaction

来源:src/backend/access/transam/xact.c @ REL_18_6

适用范围:The format string is source-backed; substitutions are supplied by the executing path.

主消息 there is already a transaction in progress

来源:src/backend/access/transam/xact.c @ REL_18_6

适用范围:This source path is explicitly WARNING and must not be presented as the VACUUM ERROR template.

主消息 %s cannot be executed from a function

来源:src/backend/access/transam/xact.c @ REL_18_6

适用范围:The %s substitution is the command name; this branch is rejected because it is called from a function.

主消息 cannot create logical replication slot in transaction that has performed writes

来源:src/backend/replication/logical/logical.c @ REL_18_6

适用范围:The source condition is a transaction that already has a top-level transaction ID from writes.

主消息 cannot export a snapshot from a subtransaction

来源:src/backend/utils/time/snapmgr.c @ REL_18_6

适用范围:The branch rejects export from the current subtransaction; prior committed subtransactions are handled separately by the source.

主消息 SET TRANSACTION SNAPSHOT must be called before any query

来源:src/backend/utils/time/snapmgr.c @ REL_18_6

适用范围:The command must be at the top level of a fresh transaction before a query establishes the snapshot.

源码报文模板

选定的 VACUUM 运行没有覆盖以下源码分支:

  • ERROR %s cannot run inside a subtransaction%s 替换为命令名)。
  • ERROR %s cannot be executed from a function%s 替换为命令名)。
  • ERROR cannot create logical replication slot in transaction that has performed writes
  • ERROR cannot export a snapshot from a subtransaction
  • ERROR SET TRANSACTION SNAPSHOT must be called before any query
  • WARNING there is already a transaction in progress

这些是源码证据,不是本案例新增的运行结论。

代表案例

本例中,VACUUM 在显式 BEGIN 块内被拒绝;ROLLBACK 后,同一 utility 作为事务块外的独立命令成功。完整 setup、断言与清理见案例导出

-- create
CREATE TABLE items(id integer PRIMARY KEY, note text NOT NULL);
-- seed
INSERT INTO items VALUES (1, 'seed');
-- begin
BEGIN;
-- trigger
VACUUM items;
-- rollback
ROLLBACK;
-- followup
SELECT 1 AS usable;
-- repair
VACUUM items;

本案例对应的 SQLSTATE、诊断、事务状态和修复断言均来自经核对的案例 registry;见结构化证据案例导出

作者证据 ID:identity, utility-path, other-paths, runtime。选定运行记录:runtime.25001-batch1-latest2-20260909.latest, runtime.25001-batch1-pg10b-20260909.pg10

版本与边界

锁定目录在 7.4 已观察到该条件,并在列出的正式快照中均存在。选定的 VACUUM 案例在 18.6 与 10.21 通过,包含回滚恢复和事务块外成功修复;其他 25001 路径仅有源码证据。

来源

证据

断言

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

  • 25001 is active_sql_transaction in Class 25.

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

    不覆盖The code covers several operations that require a transaction boundary, including subtransactions and function execution.

    来源src/backend/utils/errcodes.txt

  • A utility such as VACUUM cannot run inside an explicit transaction block; xact.c formats the statement name into the 25001 primary message.

    核实方式Trace PreventInTransactionBlock and the VACUUM transaction restriction.

    不覆盖Some commands are allowed inside transactions; inspect the command-specific contract rather than retrying blindly.

    来源src/backend/access/transam/xact.c · doc/src/sgml/ref/vacuum.sgml · raw/calls/REL_18_6.jsonl

  • The same SQLSTATE has distinct source templates for subtransactions, function execution, logical replication slots after writes, and snapshot operations; a WARNING “there is already a transaction in progress” is a separate severity path.

    核实方式Read all fixed 25001 report groups selected by the source call scan.

    不覆盖Severity and recovery depend on the exact path; do not treat every 25001 as an ERROR.

    来源src/backend/access/transam/xact.c · raw/calls/REL_18_6.jsonl · src/backend/replication/logical/logical.c · src/backend/utils/time/snapmgr.c · src/backend/utils/time/snapmgr.c

  • The selected VACUUM case returned 25001 on PG18.6 and PG10.21, entered INERROR, recovered after ROLLBACK, accepted a follow-up query, and then completed VACUUM outside the transaction block with the connection IDLE.

    核实方式Read the selected summaries and raw diagnostics.

    不覆盖The case covers VACUUM in a transaction, not logical replication slots, snapshot export, function calls, or warning handling.

运行记录

目标服务器版本结果覆盖案例
latest 18.6 (Homebrew) passed vacuum_inside_transaction
pg10 10.21 (Debian 10.21-1.pgdg90+1) passed vacuum_inside_transaction

同类 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 被终止。 活跃