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

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

百科 / 错误代码 / Class XX 内部错误

XX000 internal_error

内部错误

ERROR 源码确认 参考 不适用

类别
Class XX 内部错误
严重等级
ERROR
条件名
internal_error
宏名称
ERRCODE_INTERNAL_ERROR
启用版本
7.4
状态
活跃

版本覆盖

速览

XX000 是类别 XX Internal Error 中的 internal_error 条件。PostgreSQL 源码目录把这个类别描述为“本不应发生”的条件和软件缺陷。它是通用的诊断边界,不能据此断言数据库已经损坏。

这个代码也有机械的默认来源。在错误栈初始化时,没有后续显式代码的 ERROR 或更高级别会先使用 ERRCODE_INTERNAL_ERRORWARNING 级别从 ERRCODE_WARNING01000)开始;低于 WARNING 的级别若没有自己的代码则从 00000 开始。显式 errcode() 可以选择其他 SQLSTATE。因此,XX000 可能来自没有显式 SQLSTATE 的默认 elog(ERROR, ...) 路径,也可能来自主动报告内部错误的路径。

严重级别和连接后果取决于具体路径。ERRORFATALPANIC 是不同的协议严重级别;扩展测试代码甚至可以在 NOTICE 中显式携带 XX000。应把严重级别、事务状态、连接状态、源码位置和完整诊断放在一起读取。

代表性案例 internal_error_safety_boundary 只做源码核验,未实测自然触发路径。由于强行制造内部损坏或故障会越过安全的临时数据库边界,PostgreSQL 18.6 和 10.21 上均记录为 not_applicable,也没有用手写 RAISE 冒充服务器内部失败。

含义与触发路径

18.6 的定义是在类别 XX 下的 XX000 E ERRCODE_INTERNAL_ERROR internal_error。这个类别注释有意保持宽泛。对于数据损坏(XX001)和索引损坏(XX002)还有更具体的代码;选用 XX000 不会自动把通用内部报文升级成这两种诊断。

需要区分两种源码模式:

  1. 默认内部代码。 后端路径调用没有显式 SQLSTATE 的 elog(ERROR, ...),或以同样方式到达 ereport(ERROR, ...)elog.c 会把这个错误初始化为 XX000,但报文和源码函数仍能指出所属子系统。
  2. 显式内部代码。 某条路径调用 errcode(ERRCODE_INTERNAL_ERROR),因为某个不变量或操作系统/服务结果被视为不可能或不可用。18.6 中的例子包括 B-tree 重检时无法重新找到索引元组、动态共享内存控制段无效、尝试重新定义非占位配置参数,以及 UUID 生成无法取得强随机字节。

显式代码不会强制唯一的严重级别。共享内存路径报告 FATAL,而 B-tree、GUC 和 UUID 例子报告 ERROR。一个访问控制测试钩子还会在 NOTICE 中显式报告 ERRCODE_INTERNAL_ERROR,说明 SQLSTATE 与严重级别是分开的字段。这个钩子只是源码例子,不是普通生产提示表示内部故障的证据。

报文与诊断

XX000 没有统一的主报文。源码中可见的代表性模板包括:

  • failed to re-find tuple within index "%s",并提示索引表达式可能不是不可变的(nbtinsert.c)。
  • dynamic shared memory control segment is not valid,出现在 FATAL 初始化路径(dsm.c)。
  • attempt to redefine parameter "%s"guc.c)和 could not generate random valuesuuid.c)。
  • 默认 elog(ERROR, ...) 路径中的 invalid page pd_lower %u pd_upper %u pd_special %ubufmask.c);没有其他显式代码替换时,默认映射会提供 XX000

这些都是具体路径的诊断模板。应记录 SQLSTATE、两种严重级别字段、主报文、详细信息、提示、上下文、源码文件、函数、行号、后端 PID、数据库和服务器版本。本地化文本和模板措辞可能变化;源码路径和结构化字段比报文子串更稳定。

报文模板

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

主消息 failed to re-find tuple within index "%s"
HINT This may be because of a non-immutable index expression.

来源:src/backend/access/nbtree/nbtinsert.c(lines 754-766) @ REL_18_6

适用范围:The message belongs to the UNIQUE_CHECK_EXISTING btree path and carries a relation/constraint context.

主消息 dynamic shared memory control segment is not valid

来源:src/backend/storage/ipc/dsm.c(lines 436-445) @ REL_18_6

适用范围:This path terminates the backend session; it is not a generic client-side error template.

主消息 attempt to redefine parameter "%s"

来源:src/backend/utils/misc/guc.c(lines 4964-4970) @ REL_18_6

适用范围:The template belongs to the custom GUC placeholder invariant path.

主消息 could not generate random values

来源:src/backend/utils/adt/uuid.c(lines 544-552) @ REL_18_6

适用范围:The message reports failure of the strong-random provider in the UUID path.

主消息 invalid page pd_lower %u pd_upper %u pd_special %u

来源:src/backend/access/common/bufmask.c(lines 70-85) @ REL_18_6 · src/backend/utils/error/elog.c(lines 442-454) @ REL_18_6

适用范围:The XX000 code is supplied by the default mapping because this elog call has no explicit errcode.

主消息 in %s: %s %s %s [%s]

来源:src/test/modules/test_oat_hooks/test_oat_hooks.c(lines 238-248) @ REL_18_6

适用范围:This is a test-module hook diagnostic demonstrating severity/code separation, not a production internal-error occurrence.

诊断

在重试或重启前保留完整的客户端错误和对应服务器日志。先按协议严重级别分类:

  • ERROR 通常会中止当前显式事务,但回滚后后端连接仍可使用。
  • FATAL 会结束后端会话,客户端需要建立新连接才能继续。
  • PANIC 是影响服务器的紧急路径,进程和连接后果必须根据服务器日志和进程监管状态确认。
  • 显式携带 XX000WARNINGNOTICE 具有不同控制流,单凭它既不能证明内部故障,也不能断言事务中止。

随后按源码函数和子系统归类。检查是否有先发生的 I/O、内存、扩展、索引、配置或并发故障;比对确切服务器构建和固定源码版本;寻找是否重复出现。只有当诊断指向相关对象时,才使用只读的目录、索引或页面检查。不能仅凭类别名推断损坏,也不要用手写 RAISE EXCEPTION 来制造复现:那默认测试的是 P0001,不是服务器内部路径。

处理

按照严重级别和子系统处理。ERROR 要先回滚事务再发无关命令;FATAL 后重新建立连接;PANIC 后遵循服务器重启和事故流程。内部错误若源码指向不变量、存储、索引或共享内存边界,不应盲目重试。

收集服务器版本、确切 SQL、后端和服务器日志、源码位置、关系对象或其他对象身份,以及近期配置和扩展变化。如果证据指向损坏,应根据事故流程在适当时停止写入,保留副本或快照,并使用 PostgreSQL 文档化的恢复与支持流程。如果证据指向没有损坏迹象的软件或扩展缺陷,则隔离可复现条件并比较受支持的版本。正确处理取决于这些证据,而不是 XX000 本身。

可复现案例

在一次性实例上执行过的场景。

internal_error_safety_boundary PG 10 / 18

前置条件

  • A source-confirmed internal error path

触发

No deterministic safe SQL trigger is used; forcing internal corruption would violate the disposable-case safety boundary.

断言

  • The directory and source paths are recorded
  • The batch marks the natural runtime trigger not applicable rather than fabricating one

处置

Preserve diagnostics, stop treating the session as healthy when appropriate, and investigate the exact server path with supportable evidence.

清理

No runtime resources are created.

版本

目录记录 XX000 存在于锁定的 7.4–8.4.22 pre-9.0 正式源码、9.0.23 至 18.6 的全部正式快照及 19 Beta 3 预览快照。同 tag 的 REL8_1_4 errcodes.sgml 表已经列出 XX000 和条件名 internal_error,因此至少可以确认 8.1.4 已有该条件名。9.0 头文件视图中的类标题为 Internal Error (PostgreSQL-specific error class),到 9.1 的文本定义变为 Internal Error。7.0–7.3 仍有候选源码缺口;这些是目录观察边界,不是确切实现引入日期的断言。

18.6 固定源码 commit 为 724edf9bde9d356724ad384a2e196edc3c9f80f7。默认严重级别到代码的映射以及上面的源码路径均有 18.6 证据。代表性运行案例没有接受确定且安全的 SQL 触发方式,因此两个目标的运行时状态均保持 not_applicable

来源

证据

断言

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

运行记录

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

同类错误代码

Class XX 内部错误 下的其他成员。