Files
story/docs/production-recovery-evidence.md
T

4.4 KiB

生产等价恢复演练一致性证据

1. 目标与范围

cmd/recovery-conformance把同一候选构建的故障注入、恢复时间线、权威数据摘要、业务连续性、重复效果检查、清理结果和审计引用形成production-recovery-conformance-report-v1。本地Compose演练固定输出LOCAL_RECOVERY/external_validation_required=true;只有预生产或生产等价基础设施完整覆盖四类演练后,报告才为PRODUCTION_EQUIVALENT。

本工具不自行规定RTO/RPO数值。observed_recovery_seconds只记录本次实测用时,是否符合业务方冻结的恢复目标由发布评审判断。报告通过也不替代跨故障域架构审查、云厂商恢复能力或业务发布批准。

2. 必须覆盖的四类演练

演练类型 最低要求
POSTGRES_RESTORE 从生产候选备份恢复到隔离目标,迁移状态、关键权威计数、约束和业务抽查一致,临时恢复目标受控清理
REDIS_REBUILD 清空或替换Redis后,从PostgreSQL权威状态和实际请求重建租约、在线态、限流/重放状态,权威业务数据不变化
SERVICE_ROLLING_RESTART API、Callbacks和Worker按生产部署策略滚动重启,Pod/进程就绪、停机期间Outbox恢复且业务效果只执行一次
PROVIDER_OUTAGE_RECOVERY 供应商停机触发熔断和降级,新启动暂停但历史查询、停止和回收仍可用;供应商恢复后任务最终收敛且告警可关闭

生产等价报告缺少任一类型都会失败。本地报告可以只包含本轮实际执行的子集,但始终不能进入真实恢复门禁。

3. 采集格式

输入文件使用production-recovery-capture-v1并严格拒绝未知字段。顶层绑定候选版本、构建摘要、环境、基础设施、故障域、变更工单、复核人和采集时间。每条演练记录:

  • 演练类型和脱敏场景引用;
  • 开始、完成时间及实测恢复秒数;
  • 恢复成功、数据完整、业务连续、无重复效果和夹具清理五个结果;
  • 恢复前后权威状态摘要,两者必须完全一致;
  • 执行记录、验证记录和审计记录的脱敏引用。

摘要用于比较结构化权威状态,不得直接散列低熵个人数据、Token或密钥。执行记录不得包含数据库连接串、供应商密钥、录音、字幕或个人信息。

4. 自动检查

报告固定包含11项检查:采集版本、来源、候选身份、候选绑定、生产等价环境身份、四类演练覆盖、时间线、恢复与清理、数据完整性、业务连续性/无重复效果、执行验证审计引用。任一项失败则报告为FAIL。

只有来源为PRODUCTION_EQUIVALENT、环境为STAGING/PRODUCTION、故障域和变更工单完整、四类演练全部通过且恢复前后摘要一致时,才设置external_validation_required=false。

5. 命令用法

go run ./cmd/recovery-conformance `
  -capture E:\evidence\production-recovery-capture.json `
  -candidate-version 0.63.0-rc.1 `
  -build-digest sha256:<64位摘要> `
  -output E:\evidence\production-recovery-report.json

输出路径必须是绝对路径。通过返回0,不一致时仍写出失败报告并返回1,参数、文件或JSON错误返回2。报告保存输入SHA-256,避免归档后替换采集文件。

6. 候选证据包门禁

release-evidence-index-v2中的PRODUCTION_RECOVERY不可豁免。第一个文件必须是同候选、全部检查通过且范围为PRODUCTION_EQUIVALENT的官方报告。后续可以附数据库恢复日志、Kubernetes rollout记录、供应商故障工单、告警时间线和签署材料。

没有真实报告时,v3清单固定显示报告以及四类演练共5个缺口。LOCAL_RECOVERY、跨候选、缺故障域、缺演练、数据摘要不一致、重复业务效果或未清理夹具时必须保持PENDING,不能用WAIVED绕过。

7. 本地轻量演练

pwsh -NoProfile -File .\scripts\verify-runtime-recovery.ps1

脚本停止Worker并插入一条唯一Outbox探针,重启API/Callbacks/Worker后确认只执行一次;随后清空Redis,通过真实设备签名请求重建热状态,并确认PostgreSQL权威计数不变。新增步骤把这两类结果生成PASS/LOCAL_RECOVERY报告。脚本不重复执行PostgreSQL备份恢复和供应商停机,因此真实门禁继续保持PENDING;结束后删除Outbox夹具和磁盘报告。