33.6 切换与重建 runbook
runbook 不是命令收藏。它把每个动作绑定到触发条件、证据、风险、停止线、成功谓词与 复位路径。切换场景尤其要防止“命令执行成功”替代“唯一 authority 已建立”。
建议每一步都使用:
step: stable-id
intent: why
preconditions: [...]
command_or_action: exact
risk_class: R0 | R1 | R2 | R3
expected: [...]
evidence: [...]
stop_if: [...]
rollback_or_next_safe_state: [...]
owner: role33.6.1 计划切换、故障切换与人工干预入口
先选路径
healthy leader + maintenance need
-> planned switchover
leader process demonstrably failed/fenced
+ automatic policy healthy
-> observe automatic failover
no accepted leader
+ automatic path cannot complete
+ exact candidate/fence/data risk approved
-> manual failover
replica broken, leader healthy
-> restart/rewind/reinit replica; do not fail over第 20 章已经完整演练 healthy planned switchover;本章正式 run 是 controlled process fault 后的 automatic failover,最后才用 planned switchover 复原教学基线。
R0:只读预检
pig pt list pg-test -o json
pig pt config show -o json加上 SQL:
SELECT pg_is_in_recovery(),
(pg_control_system()).system_identifier,
(pg_control_checkpoint()).timeline_id;检查:
one primary / expected replicas
pause=false
member tags
ttl / loop_wait / retry_timeout
maximum_lag_on_failover
synchronous and failsafe modes
watchdog mode
sender/receiver and replay gap
DCS member/quorum
service path and client probeR0 也要创建 evidence timestamp,不能把几分钟前的健康状态当动作瞬间事实。
R1/R2:计划切换
pig pt switchover --plan
pig pt switchover \
--leader <current> \
--candidate <target>版本选项以 pig pt switchover --help 为准。执行前:
- current leader 与 candidate 都来自 fresh structured state;
- candidate replay 在窗口内;
- 长事务、DDL、备份和批任务已评估;
- client probe 已开始;
- backout candidate 可用;
- 路由与 connection drain owner 在线。
执行后不能立刻退出:
new timeline
old leader streaming
client writes on new authority
unknown outcome reconciled
archive follows new primary
scheduled jobs no duplicateR2/R3:故障与手工切换
自动 failover 通常不需要操作者再发一条 failover 命令;重点是确认 fence、候选和服务 收敛。manual path:
pig pt failover --candidate <exact-member> --plan计划应明确警告 leader 不可用时可能丢失未复制事务。执行前需要独立 reviewer:
old-primary fence
candidate lineage and lag
last ack / unknown manifest
accepted data loss
DCS authority
business owner and incident commander authorization不要用 manual failover 修复 proxy、replica 或 DCS 延迟问题。
重建入口
pig pt reinit <replica> --planreinit 会删除目标 replica 的 PGDATA,属于 R3。它只应在:
- target 已确认是 replica;
- target 数据无需再取证;
- accepted primary/source 明确;
- rewind 不适用或已失败;
- 带宽、WAL retention、tablespace 和密钥已准备;
- post-validation 与 failure cleanup 已写好;
- 两人复核具体 member。
本章 runner 永不执行 managed reinit。
33.6.2 Patroni、DCS、代理和 SQL 证据互证
证据矩阵
| 问题 | Patroni | DCS | SQL | 服务/客户端 |
|---|---|---|---|---|
| 谁是 primary | REST role | leader lock | recovery=false | write health |
| 旧主是否排除 | member state | lease/failsafe | unavailable/recovery | no accepted route |
| 候选是否最新 | timeline/lag | member/sync state | LSN/receiver | token boundary |
| 切换是否完成 | one leader | lock updated | followers streaming | writes succeed |
| 数据是否丢失 | 不直接回答 | 不直接回答 | token/ledger query | client ack manifest |
任一行中出现冲突,都应保存而不是“修正输出”。例如:
DCS leader = A
Patroni REST A = replica
SQL A recovery = true
SQL B recovery = false这不是运行一个 edit-config 的理由,而是 authority contradiction。先停止写、查 timeline 与动作日志。
采集顺序避免自我污染
capture before
start client probe
record action monotonic timestamp
perform one bounded action
capture fence and transition
capture after
reconcile client identities
only then perform cleanup/baseline restore
capture restored如果先 restart/reinit 再取证,就会丢失原 PID、日志、control data 和 timeline 现场。 如果先删除 fixture 再对账,就无法证明 unknown 是否提交。
Secret-free projection
完整 Patroni、DCS 与 inventory 配置含密码、token、证书路径。证据只投影:
scope / member
DCS kind and endpoint count
config booleans and numeric policy
credential present + hash/length where necessary
REST role/state/timeline
raw log hash + selected event counts本章 journal evidence 只保留行数、整体 SHA-256 和 pattern counts,明确
raw_log_exported=false。需要审计原日志时,在受控现场保存,不把它发布到教材。
monotonic 与 UTC 双时钟
UTC 用于跨主机关联,monotonic 用于本机阶段时长:
started_at UTC
started_monotonic_ns
finished_at UTC
finished_monotonic_nsNTP 校时可能让 wall clock 跳变,不能用两个 UTC 字符串相减替代 monotonic duration。 跨主机 monotonic 不能直接比较,因此 fence/promotion 关键顺序最好由同一 observer 记录,另用多主机 UTC/clock offset 辅助。
证据 bundle
requirements + failure model
before phase
fault action
old-primary fence
failed phase + selected candidate
rejoin phase
client event stream + reconciliation
baseline restore action + restored phase
DCS tabletop decision
rewind/basebackup evidence
cleanup
source hashes
positive validation + adversarial mutations
public summary公开摘要
failover-run.json 不含 inventory、密码、原始日志或
临时 service 文件。
33.6.3 集群恢复后重新建立监控与备份健康
HA 恢复不是事故关闭
新主可写后,至少检查:
database authority
replication and slots
client route and unknown outcomes
WAL archive
backup schedule and repository
monitoring/alerts
jobs, CDC, logical replication
capacity and cache
security/audit切换会改变产生 WAL、执行 cron/job、归档、备份和 logical publisher 的节点。只验证
SELECT 1 会漏掉一半恢复工作。
复制与 slot
SELECT application_name, state, sync_state, replay_lsn
FROM pg_stat_replication;
SELECT slot_name, active, restart_lsn, wal_status,
safe_wal_size, invalidation_reason
FROM pg_replication_slots;验收:
- 所有预期 replica streaming;
- 无未知 sender;
- slot owner 与 member/subscriber 对应;
pg_walretained bytes 有界;- rebuild member replay 到验证 LSN;
- logical replication origin/subscription 状态正确。
archive 与 backup
pg_stat_archiver last success/error
pgBackRest stanza status/check
new-primary archive command and credentials
latest backup lineage/timeline
repository capacity and retention
next scheduled backup owner更稳妥的事故关闭门是:在新 topology 上完成一次新的可恢复点,并在计划窗口验证 side restore;至少不能让 backup/archiving warning 被“主库已恢复”盖掉。
服务与应用
- HAProxy 只接受当前 write endpoint;
- PgBouncer 不保留错误 server connection;
- stale DNS/VIP 已收敛;
- application pool 重建;
- old timeline transaction 全部断开或明确结束;
- unknown idempotency token 对账完成;
- scheduler 单实例语义恢复;
- outbox/CDC offset 没有重复或空洞;
- cache/search 等派生系统按权威数据库重建。
监控重新设基线
切换会让:
timeline increase
backend PID reset
cumulative stats reset/restart
cache hit ratio temporarily下降
replica lag spike
connection errors spike
checkpoint/archive timing change这些不是都应静默。给事故窗口加 annotation,保留告警作为证据,再针对已解释的瞬态 调整状态;不要批量关闭告警后忘记恢复。
关闭条件
authority:
unique_primary: true
old_primary: streaming_or_decommissioned
data:
acknowledged_missing: 0
unknown_unreconciled: 0
accepted_loss: documented
replication:
expected_members_streaming: true
slots_reconciled: true
service:
write_route_valid: true
stale_connections_drained: true
recoverability:
archive_healthy: true
backup_healthy: true
restore_followup_scheduled: true
operations:
alerts_restored: true
jobs_and_cdc_validated: true
evidence_bundle_sealed: true
business:
owner_acceptance: approved | pending技术项全绿但 owner_acceptance=pending 时,事故仍不能被描述成“业务已完全恢复”。
上一节:旧主重加入与集群重建 · 返回本章目录 · 下一节:实战:主库故障与 DCS 干扰 · 查看全书目录 · 查看索引中心