# XX001 — data_corrupted

> PostgreSQL SQLSTATE XX001 的源码核验与诊断参考。
---

# XX001

## 速览 {#at-a-glance}

`XX001` 报告完整性不变量失败。固定源码覆盖 PGLZ TOAST 数据损坏、堆中不可能的 MultiXact/XID freeze 状态，以及 `amcheck` 检测到的元组/索引不匹配（其根因仍可能是堆/HOT 链）。

<!-- BEGIN SQLSTATE FACTS: generated by scripts/generate.py; do not edit -->

| 字段 | 值 |
| --- | --- |
| SQLSTATE | `XX001` |
| 条件名 | `data_corrupted` |
| 状态 | `有效` |
| 已知存在于 | `7.4` |
| 锁定快照 | `9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3` |
| 宏 | `ERRCODE_DATA_CORRUPTED` |
| 别名 | `—` |

<!-- source facts: data/errcodes/XX001.json -->
<!-- END SQLSTATE FACTS -->

## 含义 {#meaning}

TOAST 解压器无法解码保存的压缩 datum 时，会以 `ERRCODE_DATA_CORRUPTED` 报错。堆 freeze 在 MultiXact 早于 `relminmxid`、在 freeze cutoff 前仍运行，或带有早于 `relfrozenxid`/可移除 cutoff 的 update XID 时，也使用此码。这些是存储数据和事务元数据的一致性检查，不是普通输入错误。

`amcheck` 的 `heapallindexed` 回调报告堆元组缺少匹配的索引元组。源码注释明确指出，表面上的索引扫描问题仍可能源于堆损坏、错误的 HOT 安全性判断或其他底层故障；可选提示只是建议使用更强的检查函数。

## 消息 {#messages}

- **ERROR**，SQLSTATE `XX001`：`compressed pglz data is corrupt`。
- **ERROR**，SQLSTATE `XX001`：`found multixact %u from before relminmxid %u`。
- **ERROR**，SQLSTATE `XX001`：`multixact %u from before multi freeze cutoff %u found to be still running`。
- **ERROR**，SQLSTATE `XX001`：`multixact %u contains update XID %u from before relfrozenxid %u`。
- **ERROR**，SQLSTATE `XX001`：`multixact %u contains committed update XID %u from before removable cutoff %u`。
- **ERROR**，SQLSTATE `XX001`：`heap tuple (%u,%u) from table "%s" lacks matching index tuple within index "%s"`。
  - 通过 `bt_index_check` 进入时（该入口取得 `AccessShareLock`，并向回调传入 `readonly=false`），提示为：`Retrying verification using the function bt_index_parent_check() might provide a more specific error.` `bt_index_parent_check` 入口取得 `ShareLock`、传入 `readonly=true`，不会附加这个提示。这里的 readonly 是内部校验模式，与 SQL 事务的 `transaction_read_only` 设置无关。

## 诊断 {#diagnosis}

保留完整消息与标识符、关系/索引名称、数据块/页面上下文、校验和与副本比较、日志以及首次发现不变量的操作。TOAST 要定位所属表和压缩 datum 路径；堆消息要检查 relfrozenxid/relminmxid 与 MultiXact 历史，不能手工改系统目录。对 `amcheck` 记录调用的是 `bt_index_check`/`AccessShareLock` 还是 `bt_index_parent_check`/`ShareLock`，以及是否有提示；不要先假定索引是根因。

## 处理 {#response}

按完整性事件处理。显式事务中的 `ERROR` 需要先 `ROLLBACK`，或回到已有保存点，再发送 SQL；回滚不会修复存储对象。用只读流程比较可信备份、副本、校验和和存储历史，再按事故方案恢复或重建受影响表/TOAST 数据。只有证据确认损坏局限于索引时才考虑 REINDEX；它不是堆、TOAST、XID 或 MultiXact 不变量的通用修复。若另有 FATAL 或进程终止，恢复后使用新连接；不要为测试而制造损坏。

## 版本 {#versions}

锁定目录从 7.4 记录此条件；固定 TOAST、堆和 amcheck 源码覆盖 PostgreSQL 18.6。本源码页没有运行损坏或崩溃实验。

## 相关 {#related}

[`XX002`](../xx002/)、[`58030`](../58030/)、[`72000`](../72000/)

## 来源 {#sources}

[`src/backend/access/common/toast_compression.c#L90-L100`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/access/common/toast_compression.c#L90)

[`src/backend/access/heap/heapam.c#L6983-L7042`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/access/heap/heapam.c#L6983)

[`contrib/amcheck/verify_nbtree.c#L2760-L2818`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/contrib/amcheck/verify_nbtree.c#L2760)

[`contrib/amcheck/verify_nbtree.c#L252-L305`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/contrib/amcheck/verify_nbtree.c#L252)

[`contrib/amcheck/verify_common.c#L60-L149`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/contrib/amcheck/verify_common.c#L60)

结构化[证据记录](../../data/evidence/xx001.json)保存完整性消息组、条件提示和源码/运行边界。
