↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

Wiki / SQLSTATE

3B001 — invalid_savepoint_specification(保存点说明无效)

引用了当前事务中不存在的保存点。

英文手册覆盖始于 PostgreSQL 8.1. 来源历史与运行验证各自保留独立版本边界。

当前阅读 PG 18·选择有来源记录的版本

aliases
未知
class name
Savepoint Exception
condition name
invalid_savepoint_specification
lang
en
sqlstate
3B001

版本定义 PG 18

3B001 — invalid_savepoint_specification(保存点说明无效)

速览 {#at-a-glance}

3B001 表示保存点操作引用了当前事务层级中不存在的保存点。它不同于 25P01:后者表示根本没有活动事务块。

含义 {#meaning}

当 ROLLBACK TO SAVEPOINT 或相关操作无法在当前保存点栈中找到名称时,事务管理器会发出 3B001。PG18 源码模板包含名称;PG10 源码仍使用较早的 no such savepoint 措辞。缺失名称是事务结构问题,不是表数据冲突。

诊断 {#diagnosis}

保存 SQLSTATE、主报文、事务状态和完整保存点序列。检查拼写、保存点是否已经 RELEASE,以及嵌套过程或子事务是否改变了当前层级。显式事务中的 ERROR 会令连接处于 INERROR;回滚之前不要在那里继续执行目录查询或修复 SQL。

处理 {#response}

回滚失败块,开启新的显式事务,并建立名称和嵌套层级都明确的保存点。如果希望保留部分工作,应在风险语句前建立正确名称的保存点,并只回滚到已存在的标记;错误发生后不能凭空恢复缺失标记。重试应视为新的事务计划,并保留业务幂等检查。

报文 {#messages}

18.6 固定源码包含 savepoint "%s" does not exist 及当前层级的相关变体;选定 PG10 输出为 no such savepoint。这些是有源码依据的版本/调用差异,应根据 3B001 和事务状态处理,不要依赖单一英文完整报文。

代表案例 {#case}

verify/cases/3B001/snippets.json(SHA-256 595ce7692e34d36cc31df94c65c7040ee9bc4558fa887c23b56ba3187d235deb)包含显式 BEGIN、已存在的 present 保存点、ROLLBACK TO SAVEPOINT missing,以及回滚后的修复序列。见公开案例导出和结构化证据。

BEGIN;
SAVEPOINT present;
ROLLBACK TO SAVEPOINT missing;
ROLLBACK;
BEGIN;
SAVEPOINT present;
RELEASE SAVEPOINT present;
COMMIT;

运行器使用 autocommit 只是为了让 registry 中的 BEGIN/ROLLBACK/COMMIT 边界完全显式;它断言缺失标记后是 INERROR,恢复提交后是 IDLE。

选定案例在 PostgreSQL 18.6 和 10.21 观察到 3B001。PG18 报 savepoint "missing" does not exist,PG10 报 no such savepoint;两者都让显式事务在 ROLLBACK 前保持 INERROR,之后合法保存点序列可以提交。

版本 {#versions}

目录从 8.0.0 或更早边界到正式快照都记录了 3B001。选定的 18.6 与 10.21 运行证明 SQLSTATE 和恢复边界;主要报文则从旧版泛化措辞变为包含保存点名称的模板。

相关 {#related}

可对照3B000 保存点异常以及没有事务块时的25P01 无活动 SQL 事务。

来源 {#sources}

  • src.errcodes.18.6(SHA-256 6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba)
  • src.xact.18.6(SHA-256 75b012c0b047d1dc905a30975c244beec366e45eac0dbf109fd21bcd611a8e39)
  • src.xact.10.23(SHA-256 9120bd418bd0f18e3f1065a3772c92ff68f3be54e1a8c6d415043197f6daa47c)
  • SAVEPOINT 官方文档 · 本地调用扫描 src.calls.REL_18_6(SHA-256 9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf)

比较版本

SQLSTATE 证据与已记录的运行版本

cases · invalid_savepoint_recovery
{
  "assertions": [
    "SQLSTATE is 3B001",
    "The diagnostic identifies the missing savepoint",
    "The failed block is INERROR until ROLLBACK",
    "A valid SAVEPOINT/RELEASE/COMMIT succeeds afterward"
  ],
  "case_id": "invalid_savepoint_recovery",
  "cleanup": "Drop the case schema with an owner connection.",
  "has_snippet": true,
  "position": 0,
  "preconditions": [
    "A runner-owned disposable target is provisioned."
  ],
  "repair": "Verify the savepoint name and nesting level; rollback the failed block before issuing a new savepoint sequence.",
  "trigger": "Inside a valid explicit transaction, roll back to a savepoint name that was never established, then rollback and establish a valid savepoint.",
  "versions": [
    "10",
    "18"
  ]
}
claims · identity
{
  "claim_id": "identity",
  "limits": "The class-level 3B000 entry is separate from this specific condition.",
  "method": "Read the fixed errcodes.txt row and macro mapping.",
  "position": 0,
  "runtime": [],
  "sources": [
    "src.errcodes.18.6"
  ],
  "statement": "3B001 is the invalid_savepoint_specification condition in Class 3B."
}
claims · savepoint-path
{
  "claim_id": "savepoint-path",
  "limits": "PG10 uses the older no such savepoint wording; the SQLSTATE and state transition are the stable facts here.",
  "method": "Trace ERRCODE_S_E_INVALID_SPECIFICATION in xact.c.",
  "position": 1,
  "runtime": [],
  "sources": [
    "src.xact.18.6",
    "src.calls.REL_18_6"
  ],
  "statement": "RollbackToSavepoint emits a missing-savepoint error when the named savepoint is not present at the current level."
}
claims · recovery
{
  "claim_id": "recovery",
  "limits": "A valid savepoint at another nesting level is a different case.",
  "method": "Run the shared explicit BEGIN/SAVEPOINT/ROLLBACK case and inspect transaction status.",
  "position": 2,
  "runtime": [],
  "sources": [
    "doc.savepoint.18.6"
  ],
  "statement": "A failed ROLLBACK TO SAVEPOINT leaves the explicit transaction in error; ROLLBACK ends that block before a new savepoint sequence."
}
claims · runtime
{
  "claim_id": "runtime",
  "limits": "This covers the selected mechanism only, not all source callers or all driver/pool behavior.",
  "method": "Read the selected runner summaries and raw outputs tied to the shared snippet registry.",
  "position": 3,
  "runtime": [],
  "sources": [
    "runtime.3B001-batch34-20260909.latest",
    "runtime.3B001-batch34-20260909.pg10"
  ],
  "statement": "The selected 3B001 case passed on PostgreSQL 18.6 and 10.21 with the structured SQLSTATE, transaction-state, and repair assertions recorded in the runtime entries."
}
messages · message.savepoint-modern
{
  "limits": "The name is dynamic.",
  "message_id": "message.savepoint-modern",
  "path": "",
  "position": 0,
  "raw": {
    "id": "message.savepoint-modern",
    "limits": "The name is dynamic.",
    "primary_template": "savepoint \"%s\" does not exist",
    "severity_source": "ERROR",
    "sources": [
      "src.xact.18.6"
    ],
    "sqlstate": "3B001"
  },
  "severity": "ERROR",
  "sources": [
    "src.xact.18.6"
  ],
  "templates": [
    {
      "kind": "primary",
      "literal": "savepoint \" \" does not exist",
      "position": 0,
      "role": "",
      "template": "savepoint \"%s\" does not exist"
    }
  ]
}
messages · message.savepoint-pg10
{
  "limits": "PG10 wording omits the savepoint name.",
  "message_id": "message.savepoint-pg10",
  "path": "",
  "position": 1,
  "raw": {
    "id": "message.savepoint-pg10",
    "limits": "PG10 wording omits the savepoint name.",
    "primary_template": "no such savepoint",
    "severity_source": "ERROR",
    "sources": [
      "src.xact.10.23"
    ],
    "sqlstate": "3B001"
  },
  "severity": "ERROR",
  "sources": [
    "src.xact.10.23"
  ],
  "templates": [
    {
      "kind": "primary",
      "literal": "no such savepoint",
      "position": 0,
      "role": "",
      "template": "no such savepoint"
    }
  ]
}
runtimes · runtime.3B001-batch34-20260909.latest · 18.6 (Homebrew) · passed
{
  "cases": [
    "invalid_savepoint_recovery"
  ],
  "limits": "",
  "position": 0,
  "raw": {
    "case_manifest": {
      "path": "verify/cases/3B001/cases.json",
      "sha256": "084e2bb92c6ed5388c30ece2406512434e8134c17880a2c8b8cdecdaca5001bc"
    },
    "cases": [
      "invalid_savepoint_recovery"
    ],
    "id": "runtime.3B001-batch34-20260909.latest",
    "observed": {
      "connection_autocommit": true,
      "primary": "savepoint \"missing\" does not exist",
      "repair": {},
      "severity": "ERROR",
      "sqlstate": "3B001",
      "statuses": {
        "after_error": "INERROR",
        "after_repair": "IDLE",
        "after_rollback": "IDLE"
      }
    },
    "raw": "verify/results/3B001-batch34-20260909/latest/raw.jsonl",
    "raw_sha256": "f01798df2d267371cc2eca0422cf862edf0c30a58edefa138b5a8c2bd451dab5",
    "run_id": "3B001-batch34-20260909",
    "server_version": "18.6 (Homebrew)",
    "snippet_registry": {
      "path": "verify/cases/3B001/snippets.json",
      "sha256": "595ce7692e34d36cc31df94c65c7040ee9bc4558fa887c23b56ba3187d235deb"
    },
    "status": "passed",
    "summary": "verify/results/3B001-batch34-20260909/latest/summary.json",
    "summary_sha256": "8299597b2f31d38a52997a7386c65d71a3dd433a8bf69583bc1f55f6c5e67b95",
    "target": "latest"
  },
  "run_id": "3B001-batch34-20260909",
  "runtime_id": "runtime.3B001-batch34-20260909.latest",
  "server_version": "18.6 (Homebrew)",
  "status": "passed",
  "target": "latest"
}
runtimes · runtime.3B001-batch34-20260909.pg10 · 10.21 (Debian 10.21-1.pgdg90+1) · passed
{
  "cases": [
    "invalid_savepoint_recovery"
  ],
  "limits": "",
  "position": 1,
  "raw": {
    "case_manifest": {
      "path": "verify/cases/3B001/cases.json",
      "sha256": "084e2bb92c6ed5388c30ece2406512434e8134c17880a2c8b8cdecdaca5001bc"
    },
    "cases": [
      "invalid_savepoint_recovery"
    ],
    "id": "runtime.3B001-batch34-20260909.pg10",
    "observed": {
      "connection_autocommit": true,
      "primary": "no such savepoint",
      "repair": {},
      "severity": "ERROR",
      "sqlstate": "3B001",
      "statuses": {
        "after_error": "INERROR",
        "after_repair": "IDLE",
        "after_rollback": "IDLE"
      }
    },
    "raw": "verify/results/3B001-batch34-20260909/pg10/raw.jsonl",
    "raw_sha256": "66ae381dc1edbb309a234751738e015d5bd34b38777f7ae66e7b6eeee549ce91",
    "run_id": "3B001-batch34-20260909",
    "server_version": "10.21 (Debian 10.21-1.pgdg90+1)",
    "snippet_registry": {
      "path": "verify/cases/3B001/snippets.json",
      "sha256": "595ce7692e34d36cc31df94c65c7040ee9bc4558fa887c23b56ba3187d235deb"
    },
    "status": "passed",
    "summary": "verify/results/3B001-batch34-20260909/pg10/summary.json",
    "summary_sha256": "7e4de60ee83cc2e565050d93648c16006a266d3f584f8d1b096aef89b546ebe2",
    "target": "pg10"
  },
  "run_id": "3B001-batch34-20260909",
  "runtime_id": "runtime.3B001-batch34-20260909.pg10",
  "server_version": "10.21 (Debian 10.21-1.pgdg90+1)",
  "status": "passed",
  "target": "pg10"
}
sources · src.errcodes.18.6
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/utils/errcodes.txt",
  "position": 0,
  "sha256": "6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba",
  "source_id": "src.errcodes.18.6",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/errcodes.txt"
}
sources · src.calls.REL_18_6
{
  "commit": "",
  "docs_url": "",
  "kind": "local_artifact",
  "location": "",
  "path": "raw/calls/REL_18_6.jsonl",
  "position": 1,
  "sha256": "9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf",
  "source_id": "src.calls.REL_18_6",
  "tag": "",
  "url": ""
}
sources · src.xact.18.6
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/access/transam/xact.c",
  "position": 2,
  "sha256": "75b012c0b047d1dc905a30975c244beec366e45eac0dbf109fd21bcd611a8e39",
  "source_id": "src.xact.18.6",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/access/transam/xact.c#L4482-L4484"
}
sources · src.xact.10.23
{
  "commit": "02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/access/transam/xact.c",
  "position": 3,
  "sha256": "9120bd418bd0f18e3f1065a3772c92ff68f3be54e1a8c6d415043197f6daa47c",
  "source_id": "src.xact.10.23",
  "tag": "REL_10_23",
  "url": "https://github.com/postgres/postgres/blob/02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4/src/backend/access/transam/xact.c#L3914-L3916"
}
sources · doc.savepoint.18.6
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "https://www.postgresql.org/docs/18/sql-savepoint.html",
  "kind": "upstream_source",
  "location": "",
  "path": "doc/src/sgml/ref/savepoint.sgml",
  "position": 4,
  "sha256": "aa6e167d373da6118249c87404a7b2ff8be8c7df790449814f1d9dc433bbd428",
  "source_id": "doc.savepoint.18.6",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/doc/src/sgml/ref/savepoint.sgml"
}

来源引用

完整定义与证据 JSON

定义来源

center · PostgreSQL 18 · english-manuals:3a16430ec0f037fb2cfa2359bc98bbd7c401b2ee0c9e32e01526e817cb825130

正文语言: zh-Hans · english-manuals:3a16430ec0f037fb2cfa2359bc98bbd7c401b2ee0c9e32e01526e817cb825130