# 页与 checksum 证据

LLMS 索引： [llms.txt](/llms.txt)

---

PostgreSQL data checksum 是发现部分静默字节变化的重要机制，但不是万能完整性证明。
理解其单位、触发时机和未覆盖面，才能正确解释一次成功或失败的检查。

## 35.3.1 checksum 是否启用及其检测边界 {#item-35-3-1}

### 先确认，而不是假设

在线只读确认：

```sql
SHOW data_checksums;

SELECT data_page_checksum_version
FROM pg_control_init();
```

data checksum 是 cluster 级属性，不按 database/table 单独启用。启用时，每个 data page
在写入时更新 checksum，读取时校验。PostgreSQL 18 上游 `initdb` 默认启用 checksum，
但 `--no-data-checksums` 或部署工具的显式选项仍可关闭；因此生产判断必须读取实际
control state，不能从版本号反推。

离线检查：

```bash
pg_checksums --check --pgdata=/exact/clone/pgdata
```

官方要求 PostgreSQL **clean shutdown** 后运行 `pg_checksums`。返回码为 0 表示本次
扫描没有 checksum error，非 0 表示至少检测到一次失败。不要只解析人类输出而忽略
exit status，也不要对正在运行或有其他 writer 的 PGDATA 执行。

如需限定已知 relation filenode，可用：

```bash
pg_checksums --check \
  --filenode=16395 \
  --pgdata=/exact/clone/pgdata
```

这适合复验定位，不替代 full-cluster scan。
`filenode` 数字本身不包含 database/tablespace 身份，证据中仍要同时保存 catalog 对象
与完整相对路径，不能把这个过滤参数当作全局唯一对象标识。

### 覆盖与不覆盖

checksum 保护 data pages，但官方明确不覆盖：

- internal data structures 的全部状态；
- temporary files；
- 业务语义与跨行不变量；
- 是否遗漏了整个 relation/file；
- collation/operator class 规则改变；
- 被正确重写成错误内容的合法页面。

它也不是纠错码：能发现不一致，不能根据 checksum 自动恢复原字节。

### 读时检测的含义

在线读取坏页通常中止当前 transaction。若 page 仍在 shared buffer 且损坏发生在存储
副本上，何时重新从设备读会影响首次发现时间；因此“昨天没报错”不证明昨天设备上
没有坏块。离线全扫与经过业务访问的在线读覆盖不同。

`ignore_checksum_failure=on` 只会在报告 warning 后尝试继续；官方警告它可能导致
crash、传播或隐藏损坏。它不是高可用开关，本章实验保持 off。

## 35.3.2 日志、块号、关系文件与物理定位 {#item-35-3-2}

### 从数据库 identity 映射到文件

对还可查询的 clone：

```sql
SELECT c.oid,
       n.nspname,
       c.relname,
       c.relkind,
       c.relfilenode,
       pg_relation_filenode(c.oid) AS current_filenode,
       pg_relation_filepath(c.oid) AS relative_path,
       pg_relation_size(c.oid) AS bytes
FROM pg_class AS c
JOIN pg_namespace AS n ON n.oid = c.relnamespace
WHERE c.oid = 'public.target_table'::regclass;
```

使用 `pg_relation_filenode/path`，不要假设 OID 等于当前 filenode。TRUNCATE、REINDEX、
某些 ALTER/rewrites 会更换 filenode；tablespace 又改变相对路径。

PostgreSQL 默认 block size 常见为 8192，但应从实际 control data确认：

```sql
SELECT database_block_size
FROM pg_control_init();
```

日志块号 $b$ 对应 relation fork 内的字节范围：

$$
[b \times B,\ (b+1)\times B)
$$

其中 $B$ 是实际 block size。这只是定位数学，不是授权用十六进制编辑器修改该范围。

### 先确定 fork 与 segment

大 relation 会分成 segment；relation 还有：

```text
main fork
_fsm free space map
_vm visibility map
_init unlogged initialization fork
TOAST relation and indexes
```

错误路径、block 和 relation identity 一起保存。index 的 block 2 与 heap 的 block 2
不是同一数据；同名 relation 在不同 database/tablespace 也不同。

### 日志与 SQLSTATE

保留：

```text
SQLSTATE
severity
relation/database/backend identity if available
block number and file path
statement/query_id with privacy controls
UTC and log sequence
preceding kernel/storage messages
```

本章正式 bit-flip case 的在线顺序扫描返回 `XX001`，但教材没有把 raw stderr 导出，
因为错误文本可能带 object/query 信息。生产证据可在受控位置保存完整原日志，再制作
去敏投影用于协作。

### 物理定位不等于根因定位

找到 `base/5/16395 block 2` 只说明错误出现在哪里。根因仍可能在：

```text
memory / CPU
filesystem / volume / controller / drive
hypervisor / cloud storage
DMA / firmware
PostgreSQL or extension bug
offline operator action
backup/restore transfer
```

需要跨层证据，而不是仅替换这一文件。

## 35.3.3 存储故障先修基础设施，再谈数据库重建 {#item-35-3-3}

### 不要把健康数据恢复到坏底座

如果设备仍报告 error、filesystem 不稳定、memory test 未过或 hypervisor path 不可信，
在原主机恢复 backup 可能再次损坏干净数据。安全路线：

```text
fence suspect host/storage from authority
preserve device and filesystem evidence
provision verified clean failure domain
restore/reseed from verified source
validate before accepting traffic
keep suspect media isolated for analysis
```

RAID rebuild、filesystem repair、cloud volume detach/attach 都会改变现场，应由对应专业
团队纳入同一时间线。数据库团队不要在唯一卷上自行执行 `fsck -y`。

### 健康底座的验收

```text
hardware/controller/drive diagnostics
kernel error-free observation window
filesystem consistency and mount semantics
memory/CPU health
power and time synchronization
firmware/driver/package baseline
write durability assumptions
independent backup/restore test
```

“新 VM”也不自动独立：它可能仍使用相同宿主机、storage pool、image 或坏备份。

### 重建后仍要扫描

新副本需要：

```text
clean PostgreSQL startup/recovery
pg_checksums on a clean-stopped clone or scheduled validation
amcheck by risk-ranked object set
business invariants and query equivalence
replication/archive/backup health
service role and endpoint identity
monitoring and alert observation window
```

若从 physical backup 恢复，损坏页可能被原样复制；“restore 成功”只说明工具完成传输。
[第 21 章](/backup-recovery/)的 restore drill 要与本章的 integrity checks 组合。

### 本节结论

```text
checksum error
  -> page evidence
  != root component
  != automatic data-loss estimate
  != permission to edit/delete
```

下一节处理 checksum 可能发现不了、却会让查询返回错误答案的派生结构。

---

[上一节：先分类再抢救](../02/) · [返回本章目录](../) · [下一节：索引、collation 与 `amcheck`](../04/) ·
[查看全书目录](/toc/) · [查看索引中心](/indexes/)
