31.6 实战:盲抽症状的桌面演练
本节不对数据库制造故障。它先从 Pigsty FULL/L3 沙箱采集一份最小只读上下文,再从
八个场景中盲抽两个,把本章协议压缩进前十五分钟。这里有两个容易混淆的 “level”:
Pigsty FULL/L3 监控接入层级:PG + node + pool + HA + logs
experiment L0 风险层级:read-only,在线 mutation 为零参考 run 的响应由程序生成,用来证明合同和 validator 自洽;真正的人员训练必须由主持人 只发盲包、按请求提供证据卡并独立评分。
31.6.1 随机症状、误导性首发告警与缺失信息
先读合同
完整边界见
lab-contract.md,环境与验收条件见
requirements.json,响应协议见
incident-contract.json,拓扑与路由见
topology.mmd,参与者填写
response-template.json。
先做纯静态检查:
static/labs/ch31/task.sh lint完整参考 run 需要连接已经确认的四节点开发沙箱,但在线阶段只有只读 SQL、Patroni REST
和 pgBackRest info:
export PG36_EVIDENCE_DIR="$(
mktemp -d "${TMPDIR:-/tmp}/pg36-ch31.XXXXXX"
)"
export PG36_CH31_SEED=pg36-ch31-reference-v1
static/labs/ch31/task.sh all也可以分步执行:
static/labs/ch31/task.sh capture
static/labs/ch31/task.sh exercise
static/labs/ch31/task.sh verify
static/labs/ch31/task.sh reviewcapture 显式使用 BEGIN READ ONLY、短 statement/lock timeout,只保存聚合会话、复制、
slot、archive、control identity 和缩减后的 HA/backup 上下文。它不读取业务行、不保存
query text 或原始日志。exercise 完全离线,不 pause Patroni、不 failover、不重启、不
terminate connection、不改路由、不恢复 backup。
八个场景让首发症状“不够用”
| 场景 | 首发误导 | 正确主路线 |
|---|---|---|
| 订单数下降、复制延迟为零 | 把同步副本误当历史副本 | PITR |
| 数据库健康、退款突然增长 | 把技术健康误当语义正确 | PITR |
| 写端点 503、primary up | 把接入故障误当 primary 故障 | HA |
| DCS timeout、节点自称 primary | 相信单节点自报角色 | HA |
| connection timeout、CPU 43% | 只看 CPU,忽略连接槽和 pool | OVERLOAD |
| 满盘且 replica lag | 把 lag 当根因,想手删 WAL | OVERLOAD |
| checksum mismatch、lag 为零 | 把同步状态当完整性证明 | INTEGRITY |
| seq/index 结果不同 | 把 REFRESH VERSION 当重建 | INTEGRITY |
每个 blind packet 只包含:
- initial signal 与已报告用户影响;
- 可以请求的证据卡 ID、问题、层次和时间成本;
- 十五分钟 deadline 与作答规则。
它不会包含 hidden truth、严重度答案、route、required card、safe/dangerous action 或
证据 observation。facilitator-pack.json 才保存这些内容。场景源文件本身是公开教材,
所以这种隔离是教学流程而非密码学保密;正式考核应由主持人控制文件访问或使用私有
派生场景。
“没有证据”也要进入记录
参与者请求一张暂时不可得的证据卡时,主持人应回答:
unavailable / permission denied / collector down / retention expired而不是替换成“正常”。参与者要决定是换独立观察面、升级权限 owner、缩小动作,还是 因为关键事实缺失而保持 stop line。事故能力的一部分就是在证据不完整时拒绝不安全的 确定性。
31.6.2 分别按单人和团队模式完成前十五分钟
主持方式
- 主持人运行参考工具并单独保管 evidence directory;
- 只把一个 blind packet 与空白 response template 发给参与者;
- 参与者先声明五轴影响和当前 severity;
- 参与者按 ID 请求证据卡,主持人从 facilitator pack 逐张返回 observation;
- 每个有副作用的建议都要求 risk、owner、expected、stop、rollback;
- 第 15 分钟停止,参与者发布状态更新并完成 handoff;
- 最后才揭示 hidden truth、required cards、safe/dangerous actions。
参考 run 固定 seed 抽到:
solo integrity-collation-index -> INTEGRITY
team data-accidental-delete -> PITR随机 seed 可改变题目,但 runner 会保证两题属于不同路线。不要重复抽到熟题就假装完成 盲测;应记录 seed、场景使用历史和参与者是否见过答案。
solo 与 team 使用同一张答卷
solo 模式四个 role 都由 solo-oncall 承担,但按时间串行切换;team 模式要求 IC、
operator、scribe、business liaison 是四个不同 actor。两者都必须做到:
required evidence complete minute < route decision minute <= 15
all actions belong to declared safe action set
dangerous_actions_executed = []
decision log starts at minute 0 and ends at minute 15
at least one stakeholder update before or at minute 15
production_authorized = false团队可以让多个 R0 track 并行,但仍只有一个 operator token;单人不能用“我自己复核过” 冒充独立 R2/R3 review。
一份可复用评分表
| 项目 | 分值 | 失分例 |
|---|---|---|
| 五轴影响与 severity | 15 | 把 unknown 写成无影响 |
| 现场和恢复能力保护 | 20 | 未围住 writer;建议删除 WAL |
| 跨层证据选择 | 20 | 只看一张 dashboard |
| 技术 route 与目标 | 15 | severity 直接决定 failover |
| 决策日志与 stop line | 15 | 动作无预期、回退和结果 |
| 角色、升级与沟通 | 10 | 多人同时改;不报 unknown |
| 机密与生产边界 | 5 | 粘贴凭据;宣称已获生产授权 |
发生以下任一项应直接判定需要重练,不用总分掩盖:
- 在证明 writer 唯一前 promote;
- 删除现役
pg_wal; - 在原始证据上执行覆盖式修复;
- 未经业务 owner 直接覆盖事后合法写入;
- 把 facilitator 未提供的信息自行当成事实。
程序生成的 responses.json 只是一份 schema-complete reference,不是答题者成绩。真人
评分要保存自己的 response、主持人发卡时间和讨论录音/记录权限,并由未参与执行的人
复核。
31.6.3 在 Pigsty L3 输出时间线、决策日志、证据包与路由选择
正式参考现场
正式 run 在 pg-test 捕获:
PostgreSQL version 18.4
system identifier bound to pgBackRest stanza identity
timeline 11
Patroni 1 running primary + 2 running replicas
physical replication streams 2, max sent/replay gap 0 bytes
pgBackRest status / backups 0 / 6
SQL transaction READ ONLY
raw query / raw log absent / absent
online mutation none现场的 pg_stat_archiver.failed_count 为 21,但 last failure 在
2026-07-29T18:57:58Z,last archived success 在
2026-07-30T01:36:16Z。这正说明累计失败数不能直接解释成“当前归档故障”。本章不因
看到 21 就 reset 统计或修改 archive;它保留 reset 与时间,交给真实趋势和 backup
证据解释。
“repo 中有 6 份 backup”也不等于恢复通过。本次没有执行 restore,公开结论只写
pgbackrest_status=0 和 backup count;第 21、32 章的恢复证据才回答可恢复性。
私有证据与公开摘要分层
证据目录包含:
preflight-evidence.json
blind-packets.json
facilitator-pack.json
responses.json
exercise-evidence.json
negative-report.json
validation-report.json
public-summary.json
review.txt目录权限为 0700、文件为 0600。review 拒绝 credential URI、SCRAM verifier、
private key、clear password、raw SQL/log field,并检查 preflight、盲包、答案、
exercise 与 public summary 属于同一 run。
公开参考摘要见
incident-run.json。它只保留环境轮廓、路线、安全
边界与验收计数,不公开 facilitator 答案和 live 细节。
反例验证防止“格式漂亮的伪响应”
正式 validator 要求:
31 declared counterexamples rejected
18 live evidence mutants rejected
12 source files hash-bound它会拒绝:
- severity 被允许直接选择 route;
- blind packet 泄露 hidden truth 或 expected route;
- required evidence 未齐就决策;
- solo/team role 语义不成立;
- action 属于 dangerous set 或晚于 minute 15;
- decision log 缺 expected/stop/rollback;
- live capture 不是 READ ONLY、cluster/timeline/topology 不匹配;
- backup system identifier 不同;
- source/upstream/evidence hash 被替换;
- 任何 production gate 被打开。
对同一份私有证据可以重复:
static/labs/ch31/task.sh verify
static/labs/ch31/task.sh review但修改实验源文件、盲包或 response 后,不能继续复用旧 exercise hash;应开启新 run, 保留旧包作为历史。
本章交付物不是根因报告
合格的第 31 章 handoff 应包括:
severity and five-axis basis
current user/data/recovery impact
authoritative or still-unknown writer/timeline
active fences and automation state
evidence manifest and decision timeline
chosen route and alternatives rejected
first safe action / stop line / owner
next update and escalation requests参考 run 最终结论是:
read-only-context-and-tabletop-protocol-demonstrated
human_competency_claimed = false
production_ch31_gate = pending下一章从第一条路线开始:面对已经提交的误删误改,怎样选准恢复目标、在隔离实例完成 PITR,并把历史正确状态与事后合法写入重新合并。
上一节:单人值守与团队响应 · 返回本章目录 · 下一章:PITR 与误操作恢复——妙手回春 · 查看全书目录 · 查看索引中心