跳至内容

35.2 先分类再抢救

“corruption”不是一个恢复方案。至少要区分:存储的字节/页是否错误、从源数据派生的 结构是否错误、业务意义是否错误。检测工具、恢复来源和可接受损失都不同。

35.2.1 物理页、存储与 checksum 错误

物理异常的证据链

典型入口:

checksum mismatch
invalid page / invalid page header
could not read/write block
short read
I/O error / filesystem remount read-only
storage medium error / controller reset
unexpected relation segment size or missing file

这些信号仍需定位:

one block / one relation / one tablespace / one device / many hosts
heap / index / toast / catalog / WAL / control
primary only / replica too / backup copy too
read-time detection / write-time failure / recovery-time failure

checksum failure 说明“读出的 data page 与页内 checksum 不一致”,不自动说明是磁盘: 坏内存、DMA/controller、虚拟化、filesystem、软件 bug 或离线篡改都可能改变字节。

交叉副本不能只比较 SQL 行

在相同 system identifier/lineage 下,可比较:

same relation identity and logical object
same or corresponding block/LSN context
primary, replica, backup and storage snapshot
kernel/storage errors on each host

物理 replica 可能从 primary 接收已经损坏的逻辑变化,也可能各自发生局部介质损坏; 共享存储/镜像又可能让“多个副本都有同样错误”并不独立。恢复源要有独立故障域与实际 校验,不是名字叫 replica 就可信。

默认路线

preserve corrupt original
verify hardware/storage path
identify last known-good source
restore/reseed a new working copy
validate physical + logical + business state

只有在没有健康来源且明确接受损失时,才考虑 best-effort extraction。

35.2.2 索引、排序规则与派生结构错误

派生结构可以重建,但先证明 source

index、materialized view、search vector、rollup 与 cache 都由别的状态生成。典型信号:

amcheck raises B-tree invariant error
same predicate gives seqscan/indexscan different rows
unique index behavior conflicts with expected equality
collation stored version differs from provider actual version
OS/ICU upgrade changes comparison rules
primary and standby use different provider versions

先关闭 planner 路径做诊断时,只在 clone 或有界 read-only 查询里进行:

BEGIN READ ONLY;
SET LOCAL enable_indexscan = off;
SET LOCAL enable_indexonlyscan = off;
SET LOCAL enable_bitmapscan = off;
-- bounded invariant query
ROLLBACK;

这只能帮助比较,不是修复,也不能保证 seqscan 本身绕过 heap 损坏。

collation 是外部语义依赖

collation object 把 SQL 名称映射到 libc 或 ICU provider。text B-tree 的顺序依赖比较 规则;provider 升级后,旧 index 中 tuple 的物理顺序可能不再满足新比较规则。仅更新 collversion 会消除 mismatch 提示,却不会重新排列已有 index。

因此安全顺序是:

inventory affected collation dependencies
  -> verify on clone
      -> REINDEX affected indexes/materialized structures
          -> validate
              -> REFRESH VERSION metadata

数据库级 default collation 还会影响更多对象;要从 catalogs 枚举依赖,不能只重建 报错的第一条 index。

派生异常也可能来自 heap

heapallindexed 发现 heap tuple 没有对应 index tuple 时,原因可能是 index 本身,也 可能是 heap/visibility/transaction state 异常。REINDEX 后 amcheck 通过只是一个信号; 还要验证 heap、toast、constraints 和业务 invariants。

35.2.3 逻辑不变量、应用写错与语义损坏

checksum 全绿也可能数据完全错误

UPDATE accounts SET balance = 0;
wrong tenant predicate
duplicate external event applied twice
currency unit conversion error
missing ledger entry
referential rule enforced only in application
out-of-order CDC correction

PostgreSQL 会把这些合法写入按 WAL、checksum 和 replication 正确保存。物理工具不会 知道“余额不应为负”或“订单总额应等于明细”。

业务不变量应提前定义:

-- 结构约束能表达的尽量进入数据库
ALTER TABLE account
ADD CONSTRAINT balance_domain CHECK (balance >= 0);

跨行、跨表、跨系统不变量需要 reconciliation:

row count by partition/tenant
sum/count/min/max with known semantic
ledger debit = credit
event id uniqueness and sequence
source-system vs database token
snapshot + change-log continuity

MD5/SHA digest 适合证明同一有序投影是否相同,不证明投影本身业务正确;必须绑定 SQL、 排序、NULL/encoding 与 snapshot time。

恢复路线

  • 错误发生时间明确且需整体回退:PITR 到隔离实例,再做差异恢复;
  • 有审计/事件/ledger:按稳定业务 ID 重放或补偿;
  • 上游系统为事实源:重新同步并核对删除/版本;
  • 局部错误且可逆:受控 correction transaction;
  • 外部副作用已经发生:数据库恢复之外做业务补偿。

不要在原实例上反复 PITR。第 32 章的恢复目标、timeline 与 replay 验证仍适用。

35.2.4 三类问题的恢复来源不同

决策矩阵

已证明的异常首选 source典型动作核心验收
heap data pageverified backup/replica/snapshotrestore/reseed new copychecksum + rows + business
index onlyverified heapREINDEX exact dependencyamcheck + query equivalence
collation driftheap + intended provider/versionreindex then refreshdependency + order + invariants
materialized/derivedauthoritative base tables/eventsrebuild/refreshsource-to-derived reconciliation
app wrong writePITR/audit/event/upstreamrecover/diff/compensatebusiness invariants
multiple/unknownimmutable evidence + expert analysisstop and escalatemissing facts resolved

分类置信度

不要把一个工具的结果写成绝对结论:

classification: physical-page
confidence: high
supports:
  - data_checksums=on
  - offline pg_checksums bad=1
  - scan raises XX001 on exact heap
contradicts:
  - none observed
not_proven:
  - root hardware component
  - other pages are clean
  - backups are independent and usable

pg_checksums 找到 1 个坏 checksum,不等于整个集群只有 1 处问题:可能还有未覆盖对象、 业务语义损坏或未来才读出的设备错误。反过来全绿也只覆盖被扫描的 data pages。

停止线

以下任一出现,路线转 STOP_AND_ESCALATE

  1. system identifier、timeline 或 binary/PGDATA 归属不明;
  2. 原始 evidence 已被多次写入,动作时间线无法复原;
  3. checksum、amcheck、业务结果相互矛盾;
  4. 所有已知 backup/replica 可能共享故障;
  5. 唯一副本无法安全克隆;
  6. 需要 zero_damaged_pagesignore_invalid_pagespg_resetwal 才能继续;
  7. 数据损失范围涉及监管、财务、隐私或安全事件。

上一节:现场保护与操作边界 · 返回本章目录 · 下一节:页与 checksum 证据 · 查看全书目录 · 查看索引中心

最后更新于