36.7 实战:复盘四类事故并完成全书结业
最后一次实验不再连接数据库。它把第 32~35 章公开证据作为不可改写的输入,验证我们 能否在不夸大结论的前提下形成跨事故控制路线,并把全书能力映射为可答辩的证据。
36.7.1 汇总 ch32–ch35 的证据、决策与用户影响
实验合同
先读:
requirements.json:输入、风险和验收;incident-catalog.json:source pointer、影响、时间线与判断;control-backlog.json:十二项控制合同;capability-map.json:ch01~ch36 结业证据;negative-cases.json:36 个必须拒绝的语义篡改;lab-contract.md:事实、行动与认证边界;topology.mmd:离线数据流。
静态检查会创建临时输出,编译、验证后删除;它没有网络/SSH/数据库入口:
static/labs/ch36/task.sh lint创建一份自己的 closure bundle:
evidence_dir="$(mktemp -d /tmp/pg36-ch36-evidence.XXXXXX)"
PG36_EVIDENCE_DIR="$evidence_dir" \
static/labs/ch36/task.sh compile
PG36_EVIDENCE_DIR="$evidence_dir" \
static/labs/ch36/task.sh allcompile 拒绝覆盖非空目录。all 只消费已有 bundle,重新验证 source hash、JSON
Pointer、控制合同、路线和 36 个 mutant。它不会执行 backlog。
输出结构
closure-report.json
postmortem-portfolio.json
roadmap-90d.json
capability-assessment.json
input-manifest.json
source-manifest.json
validation-report.json
negative-report.json
public-summary.json
review.txt四份输入分别绑定:
../ch32/pitr-run.json
../ch33/failover-run.json
../ch34/overload-run.json
../ch35/rescue-run.json每条 fact 保存:
{
"id": "F35-CHECKSUM",
"source_pointer": "/physical_page/offline_bad_checksums",
"expected": 1,
"actual": 1,
"matches_source": true,
"knowledge_stage": "during-response"
}编译器重新从源文件解析 actual。修改报告里的数字、pointer、source schema 或 hash
都会失败;事后解释也不能改写 knowledge_stage。
四份事故记录
| 记录 | 影响证据 | 决策 | 验收/边界 |
|---|---|---|---|
| ch32 误写 | fixture 1,000 victims、1,000 wrong outbox、外发 0 | exclusive PITR + audited delta | 恢复 1,000,保留 100 条合法后写,fixture loss 0 |
| ch33 主库失效 | 160 attempts、130 ack、最大 ack gap 6,211.692334 ms | fence → promote → reconcile → rejoin | ack missing 0、unknown unresolved 0;不是生产 RTO |
| ch34 资源压力 | flow 30/21 admitted/9 rejected;retained WAL 42,611,296 B | flow 与 retention 分开 route | exact fixture 清理;managed mutations 0 |
| ch35 完整性 | 1 byte、1 bad checksum、XX001;另一 case checksum 0 + version mismatch | trusted copy;REINDEX 后 REFRESH | checksum/amcheck/业务不变量通过,原件保留 |
impact.kind 只能是 simulated 或 observed-sandbox。报告中没有真实用户、生产数据或
生产影响。
事实与叙事分离
catalog 为每个 incident 保留:
impact statement -> source fact IDs
decision route -> basis fact IDs
ordered timeline
control theme IDs
claims not made这使读者可以质疑叙事而不改写证据。例如 ch33 的 observed gap 确实是
6,211.692334 ms,但 claims_not_made 明确拒绝“这就是生产 RTO”;ch35 确实翻转
一个 byte,但不声称模拟真实控制器或内存故障。
36.7.2 找出跨事故重复出现的控制缺口
先找共同问题,不先宣布生产有缺陷
四次实验可以支持:
these mechanisms repeatedly matter不能直接支持:
your production platform lacks them所以七个结果都标为:
status = production-assessment-required
basis = exercise-exposed-risk-not-confirmed-production-deficiency正式报告中 production_gaps_confirmed=0。真实采用时,要用本地 inventory、policy、
runtime、访谈和演练逐项把 status 更新为 present/effective、gap、exception
或 not-applicable。
七个共同主题
| 主题 | 出现章节 | 生产评估问题 |
|---|---|---|
| observation contract | 32/33/34/35 | user impact、identity、数据库与业务证据是否可关联 |
| production claim gate | 32/33/34/35 | sandbox timing/route 是否会被误当目标或批准 |
| business validation | 32/33/35 | 恢复是否超越 process/topology 到业务事实 |
| reversible exact scope | 32/33/34/35 | mutation/cleanup 是否有目标、guard、rollback |
| unknown outcome | 32/33 | timeout/ack/commit 是否能按稳定 token 对账 |
| classifier stop route | 34/35 | 缺失/冲突证据是否阻止错误动作 |
| lineage and authority | 32/33/35 | source、timeline、writer authority 是否可证明 |
出现次数不等于优先级。用 production exposure、impact、现有控制强度、验证成本和多事故 覆盖率排序。
主题必须双向一致
每个 incident 列出 theme IDs,每个 theme 又列 incident IDs。validator 检查双向 membership,并要求至少两个 incident 才能称 cross-incident。删除一个主题、把主题 缩成单事故或引用不存在的 incident 都会被拒绝。
控制不是事故类型的一一映射
同一个 target-identity gate 可以保护:
- PITR 不恢复错 cluster;
- failover 不接纳错 lineage;
- overload mitigation 不取消无关会话/slot;
- rescue 不改写 managed/unique PGDATA。
同一事故也需要多类控制:
prevent exact target + safeguard
detect user SLI + source-bound evidence
mitigate admission / fence / stop route
recover restore / rejoin / reconcile平台 backlog 优先寻找这类多边覆盖,但仍保留专用控制,例如 collation dependency 重建或 outbox 对账。
识别“控制存在但无效”
生产评估不能只问“有没有”:
implemented?
deployed to intended scope?
operating now?
tested against negative case?
effective at cutting the causal edge?
evidence still valid?
exceptions complete?有 backup job 但从未 restore,不算已验证 recover control;有 runbook 但 current version 无法执行,也不算;有 safeguard 但 generic token 可绕过 target identity, 只能算弱控制。
36.7.3 输出 90 天改进路线、平台 backlog 与复验计划
路线是参考 proposal,不是自动变更
十二项 action 均为:
status proposed
production_execution_approved false每项包含 stable owner role、P0/P1、due day、source themes、control type、artifact、 verification procedure、pass condition、evidence to close、failure condition 与 revalidation days。采用者要把 role、scope、date 和 approval 映射到自己的组织。
Day 0~30:先让风险可见、危险动作可停
| Action | 控制 |
|---|---|
| A36-01 | 版本化 incident observation/evidence schema,并让缺字段 packet 失败 |
| A36-02 | destructive workflow 强制 exact target、data/traffic/authority 与 approval |
| A36-03 | 定义 request idempotency token 与 unknown-outcome reconciliation |
| A36-04 | 分开 user-impact SLI 与 PostgreSQL/host 诊断 telemetry |
这一阶段不承诺完成所有架构改造,先建立 identity、证据和 stop line。没有这些基础, 后续演练可能只是在更好地记录错误动作。
Day 31~60:证明四条恢复能力
| Action | 控制 |
|---|---|
| A36-05 | 多 PITR candidate + legitimate delta + business manifest |
| A36-06 | fence/failover/client reconciliation/rejoin |
| A36-07 | flow/retention blind classifier + ambiguous stop |
| A36-08 | checksum/amcheck/collation review + clone-only rescue |
| A36-09 | Pigsty inventory、release、safeguard 与 dangerous playbook review |
演练用隔离环境,生产不被当作故障注入场。失败产物被保留并转 action;不能为了按期 完成把 pass condition 改成“脚本退出 0”。
Day 61~90:把局部改进变成持续系统
| Action | 控制 |
|---|---|
| A36-10 | 用生产测量/有边界演练修订 SLO、RPO、RTO、容量与安全 ADR |
| A36-11 | 每月聚合重复 theme、过期 evidence 与 exception |
| A36-12 | blind 90-day game day + 独立 effectiveness review |
第 90 天不是项目结束。control registry 根据 revalidation_days 继续检查 30/60/90/180
天周期;版本、拓扑、workload 或依赖变化会提前使证据失效。
validator 如何对抗“纸面完成”
36 个 live mutant 覆盖六组失败:
source integrity
drop incident, change fact/pointer/schema/hash
epistemic boundary
claim production impact, rewrite knowledge stage, remove claims-not-made
cross-incident reasoning
single-incident theme, unknown membership, missing theme
action quality
no owner/due/verification/failure/revalidation, vague result
governance
mark closed, auto-approve production, incomplete roadmap
graduation
duplicate chapter coverage, auto-certify learner正式结果:
run_id 91c4464b-89f7-4145-9708-f07256d747ce
input files hash-bound 4
compiler source files bound 12
live mutants rejected 36 / 36
database connections 0
SSH connections 0
external dispatch 0
production mutation 0
production_ch36_gate pending公开摘要 SHA-256:
c00463cfedbd4d880d60d6af2f3401d568ef7549948f4cbd062c9b500e53117b摘要见 closure-run.json。raw formal bundle 不发布,
因为公开教材只需要去敏结论和可重跑 source。
36.7.4 回看从 SQL 到生产的能力地图
十二个可答辩能力域
capability-map.json 将 36 章恰好覆盖一次:
| 能力域 | 章节 | 读者应能交付 |
|---|---|---|
| context/workflow | 1–2 | 精确身份、对象地图和可重跑任务 |
| model/integrity | 3–4 | 用 schema/type/constraint 编码业务不变量 |
| transaction/programming | 5–6 | 解释 MVCC、事务与服务端副作用 |
| query engineering | 7–9 | 从 plan/stats/workload 证明优化 |
| concurrency/release | 10–12 | 兼容发布、锁边界、rollback 与 contract test |
| extension workloads | 13–18 | 按语义、生命周期、风险和退出选择扩展 |
| service baseline | 19–22 | 用 Pigsty 交付 route/HA/backup/recovery |
| security/governance | 23–25 | least privilege、SLO/SOP 与 observation contract |
| capacity/maintenance | 26–28 | 可复现 envelope、调优、vacuum/freeze/bloat |
| evolution | 29–30 | migration/upgrade candidate、cutover 与 rollback |
| incident/recovery | 31–35 | blind classify、保护权威与证据、正确恢复 |
| platform learning | 36 | 将证据转成控制并独立验证效果 |
地图完整只证明教材没有漏章,不证明具体读者掌握。因此正式结果必须保持:
learner_assessment.status not-assessed
automatic_certification false
assessment_required true结业不是记忆命令
对每个域,读者完成四层答辩:
explain
用自己的话说明机制、边界与反例
execute
在授权环境完成实验并保留机器证据
diagnose
面对隐藏场景从 evidence 选择 route,而不是背答案
design
把一次结果转成适合本地 service 的控制、验证和复位只会复制 psql、playbook 或恢复命令,不构成专家能力;只会讲原理、不能从 runtime
证明状态,也不构成。PostgreSQL 原生证据、Pigsty 平台状态和业务事实要互相校验。
建个人结业 portfolio
portfolio/
environment-and-version-contract/
schema-and-transaction-design/
query-and-concurrency-cases/
release-and-service-baseline/
backup-ha-security-observability/
capacity-maintenance-evolution/
incident-recovery/
postmortem-and-control/每份 evidence 标注:
produced_by:
environment_authority:
version_and_topology:
source_hashes:
claim:
what_it_does_not_prove:
reviewer:
verified_at:
valid_until:真正的结业由你所在环境的 owner/reviewer 根据证据决定,而不是本书脚本替组织签字。
从哪里继续
读完全书不是把 PostgreSQL 变成“学完的知识”,而是获得一套持续更新的方法:
先确认身份与目标
再从原生证据理解 PostgreSQL
用 Pigsty 把能力组合成服务
用业务不变量决定是否真的正确
用隔离演练证明恢复
用复盘和平台默认值防止同类路径重演下一步选择一个真实但低风险的 service,把本节 12 项参考 backlog 做本地
present/gap/not-applicable/exception 评估,只批准一项最小、可验证改进。完成它、
保存效果证据、安排重验,然后再进入下一项。这比一次性宣布“数据库平台建设完成”
更接近长期可靠性。
上一节:将控制固化到平台 · 返回本章目录 · 返回全书导读 · 查看全书目录 · 查看索引中心