回填隔离备份恢复演练执行记录 [08-23-isolated-backup-restore-drill]

从孤儿 worktree(artifacts/isolated-worktrees/20260909-ops-preparation、
20260910-reimbursement-payment-integration)合并回填两轮从未提交的真实
执行记录:

- 2026-09-09 ARM 管理员会话完成首次隔离数据库恢复,回执 DB_RESTORE_PASS,
  66 项迁移精确匹配、12 类关键表可读。
- 2026-09-11 第二次配对恢复,AC1/AC3/AC6 勾选完成;对发票池一条历史缺失
  附件做 SHA-256 比对、来源元数据核对、生产/ARM 归档/周检查点全量搜索,
  均未命中,按用户决定非破坏性标记、暂不追查(AC4 仍未过)。

无产品代码改动,无生产/ARM 操作;仅补齐 Trellis 任务文档与既有证据记录,
使 in_progress 状态反映真实已发生的执行历史。

Co-Authored-By: Claude Sonnet 5 <[email protected]>
这个提交包含在:
2026-09-25 19:45:18 +08:00
共同撰写人 Claude Sonnet 5
父节点 b1d25d3c99
当前提交 5be9f44445
共修改 4 个文件,包含 308 行新增和 4 行删除
@@ -1,5 +1,38 @@
# 隔离备份恢复演练
## 2026-09-09 最小验真阶段(本地准备已批准,远端执行另批)
用户批准综合规划开始本地实施。本 task 不再把安装器/固定 runner 的完善当作下一次数据库恢复验真的前置;新增受控管理员人工最小路径。只在既有授权通道操作,不能以“不用 sudoers”解释为绕过现有读取权限。未收到本次 ARM 真实备份恢复授权,本轮不连接远端。
本阶段数据库结果和配对附件结果分开:数据库退出 0、来源 migration 与关键表检查通过,才可记 DB_RESTORE_PASS;附件未执行记 STORAGE_NOT_TESTED;不启动应用,不宣称应用或完整灾备 RTO 已验证。原整体 Goal、数据库/附件 AC 和历史 NO_GO 保留;最小阶段通过不自动勾选原整体 AC。原 runner 渲染/安装及分段 RTO 不作为本次最小阶段新增工程前置,仅适用于保留的正式演练合同。
保留生产零写入/零重启、影子目标确认、无宿主端口、批次来源与24小时新鲜度、配对摘要、敏感输出限制、非零失败关闭及本轮精确清理。若本地脚本在实际最新批次上失败,保留脱敏诊断并停止;不得现场放宽条件、转用旧批次或自动重试。Attempt 3 底层原因仍未知,不追认所有失败均为工具问题。
## 2026-09-11 本轮执行口径
用户认可在当前无业务关联、影响较低的前提下删除或标记。选择非破坏性标记:复核仍为 archived/manual、原件缺失且无当前业务关联后,在现有任务/恢复缺口记录登记"已知历史附件缺失,保留记录,暂不继续追查"。当前票据接口不允许编辑 archived 记录,不为添加备注绕过状态守卫改库,不新增缺失状态或删除记录。"可能是测试数据"仍是推测,不写成已确认事实。此处置不把恢复 AC4 改为通过,不改校验器、不排除缺失项,也不自动授权部署。
该处置已完成:再次只读核对无当前报销/明细/差旅及同路径附件/回单关联,记录和源文件缺失状态未变;已在本 task 和恢复证据中标记,生产数据保持原样。按用户决定暂不追查,不阻塞其他业务开发/验收;技术恢复仍如实记录 1 条附件引用缺失,发布例外及独立复核不由该标记替代。
用户批准对此前明确提供的单份发票 PDF 读取字节计算 SHA-256,并与唯一缺失记录登记的文件摘要、大小比对。不展示文件内容或原始文件摘要,不遍历 input 目录、不读其他文件,不上传原件、不补回或改生产。只读返回匹配/不匹配;匹配不代表原件已补回、备份已更新或恢复已通过,不匹配则停止,不自动扩查。
本次单文件比对已执行:大小和 SHA-256 均不匹配,不能将它补作登记原件。已按约定停止搜索,未补文件、改库或部署;不推断 PDF 业务内容必然不同。当前仍保留单条历史附件缺失,恢复 AC4 未通过;后续需新的明确原件线索或另批缺失处置方案,不重复恢复或自动扩大搜索。
用户另行批准只读核对唯一缺失记录的创建/归档来源元数据。本轮只定位既有记录 SHA-256 与路径 SHA-256,查询该行的时间、状态、归档原因枚举、创建/上传/更新身份关系布尔值及必要技术元数据;不读取人员账号、个人访问历史、审计 payload、票据正文、金额、备注或银行字段,不改数据。结合本地已发布源码解释字段含义;没有确证不得归因为测试数据或手工删除。
此元数据核对已完成:记录创建于 2026-07-27,约 9 分钟后标记 manual 归档,PDF 技术类型,存有 mock OCR 处理记录;当前无报销/明细/差旅关联。没有读取 OCR 结果或文件内容;不因 mock 或手工归档标记认定为测试数据,也不推断是谁删除了文件。来源入口与缺失原因仍未证实,AC4 未通过;后续内容摘要比对必须单独明确读取范围,任何修复仍另批。
用户进一步批准围绕该唯一缺失引用,只读查历史备份目录项和文件元数据以寻找原件。仅在已有生产/ARM 管理渠道可读的正式备份目录内做有界搜索,按已记录的规范化路径 SHA-256 匹配;不读票据正文、不恢复数据库、不解包落盘、不补文件或改引用。找到目录项只算候选原件,内容一致性与可恢复性仍须另验;权限拒绝、覆盖范围不足和未命中必须分开,不以未找到推断永久丢失。
该限定搜索已完成:生产 7 份、ARM 日归档 7 份及周检查点 4 份均未命中;ARM 另 1 个非规范目录项未纳入,不能称为所有历史备份都已检查。管理员已执行且主会话 SSH 回读结果,不再等待该次密码或执行。缺失引用未修复,AC4 继续未通过,不扩大为永久丢失或测试数据结论。
第三次诊断已确认发票池 1 条引用缺文件。用户另行批准生产侧限定只读核对:最小引用/关联状态和源文件存在性,可对照已固定附件归档目录项;不读票据正文、金额或银行资料,不改数据或生产配置。此限定读取是下文历史"生产仅健康探测"范围的显式补充,不授权恢复生产或修复记录。
用户已同意继续做 ARM 一次性 DB+附件隔离配对恢复;不是生产恢复或发布授权。本轮复用已有 shadow 恢复脚本,以一次管理员终端操作完成前置验证、临时恢复、校验与清理,不再安装历史 runner、sudoers 入口或增加分段计时装置。按原 R1–R4 保留输入身份、时效、隔离、迁移和附件配对边界,R5 记录总耗时与安全失败阶段即可。实际配对恢复已执行:DB 通过、附件引用失败,清理完成;不以本地合成通过替代,也不原样重跑已知失败过程。
固定输入来自今日最新源端校验通过的 fe025e65 备份;若执行时 ARM 最新批次、manifest、来源 build/image 或现存 PostgreSQL 镜像变化,暂停刷新证据,不自动取旧批次或拉镜像。恢复不启动 OA 应用,app 必须标 NOT_TESTED;镜像回退和 DB/附件恢复仍是不同能力。09-09 管理员回传的最小 DB_RESTORE_PASS 已有效记录,不再沿用"从未成功恢复数据库"的旧结论。
## Goal
在不覆盖、不暂停腾讯云生产 OA 的前提下,使用 ARM 备份机上最新的完整异机批次完成一次数据库与附件的隔离影子恢复,证明“备份存在”进一步达到“最新成对数据备份可恢复”,并记录实测数据恢复 RTO、RPO 和脱敏证据。
@@ -61,12 +94,12 @@
## Acceptance Criteria
- [ ] AC1:ARM 最新正式日批次通过文件集、manifest、字节数和 SHA-256 校验,来源构建是当前构建的祖先或相同,且实测 RPO 不超过 24 小时;是否已形成当前构建同源恢复点单独记录。
- [x] AC1:ARM 最新正式日批次通过文件集、manifest、字节数和 SHA-256 校验,来源构建是当前构建的祖先或相同,且实测 RPO 不超过 24 小时;是否已形成当前构建同源恢复点单独记录。2026-09-11 第二次配对执行已证同源 fe025e65、约 9.97 小时;不代表未来批次自动通过。
- [ ] AC2:腾讯云生产在演练前后 `/ready` 均正常,生产容器、数据库、附件、配置、timer 和业务数据零写入、零重启、零切换。
- [ ] AC3:一次性 PostgreSQL 16 影子库无宿主端口,数据库恢复成功;恢复 migration 集合与 manifest 来源提交一致且无失败/未知项,来源与当前 migration 差异已明确;固定 12 类关键表均可读并形成仅含数量的脱敏摘要。
- [x] AC3:一次性 PostgreSQL 16 影子库无宿主端口,数据库恢复成功;恢复 migration 集合与 manifest 来源提交一致且无失败/未知项,来源与当前 migration 差异已明确;固定 12 类关键表均可读并形成仅含数量的脱敏摘要。2026-09-11 第二次配对执行:68 条迁移集合/摘要匹配、异常 0、12 类表通过;附件失败不抹掉此项实证。
- [ ] AC4:附件安全恢复成功,归档与解包普通文件数一致;所有纳入范围的本地附件引用均安全且存在,适用的哈希/大小核对无不一致。
- [ ] AC5:记录本轮数据恢复 RTO、RPO、同源恢复点可用滞后、开始/结束时间、失败点或 finding、Go/Pause/No-Go 结论;即使恢复未开始也保留已观测空窗,不把任何指标表述为完整应用灾备 RTO 或 SLA。
- [ ] AC6:演练结束后本轮容器、端口、网络和临时数据全部清理,ARM 正式归档与现有 dead-man/健康监控不受影响。
- [x] AC6:演练结束后本轮容器、端口、网络和临时数据全部清理,ARM 正式归档与现有 dead-man/健康监控不受影响。2026-09-11 第二次配对执行已清理,源归档摘要与 timer 未变;后续新运行须重新核验。
- [ ] AC7:任务校验、Trellis 治理、流程合同、文档审计、敏感扫描和 `git diff --check` 通过;证据不含敏感信息。
## Out of Scope
@@ -79,7 +112,7 @@
## Blocking Open Questions
- 无。构建门禁已裁决为“来源提交是当前构建祖先或相同 + 批次年龄不超过 24 小时”;实施仍需用户审阅本次修订后的最终规划摘要并再次明确批准。
- 单条历史缺失已按用户决定完成非破坏性标记,来源未证实但暂不继续追查;不再等待其处置授权或管理员密码。实际附件恢复仍未全部通过,不自动改为完整恢复成功。若未来需要修复或生产恢复/部署,仍需对应明确范围与授权。
## Test Plan
@@ -87,3 +120,10 @@
- 通过现有 shadow 恢复脚本完成 PostgreSQL 16 和附件恢复,验证来源提交的 migration 集合、与当前构建的 migration 差异、固定 12 类表及附件引用聚合。
- 复核无宿主端口、生产前后 `/ready`、ARM 监控未受影响和本轮临时对象零残留。
- 运行 task validate、Trellis governance、process contract、docs registry、敏感扫描和 `git diff --check`。
## 2026-09-09 数据库最小恢复执行授权
用户对“通过ARM既有合法管理员通道,核对当时最新正式备份,在一次性隔离PostgreSQL中执行数据库恢复、检查结果并清理本轮临时资源”明确回复“是”。本次只批准数据库,不解包附件、不启动OA、不触碰生产、不改权限或sudoers、不删除正式备份。权限不足或恢复失败停止并报告;不需再次征询同一范围的授权。
最初代理非交互管理员通道检查未通过;随后用户通过既有 root 交互会话执行获批操作。2026-09-09 管理员回传本批次 DB_RESTORE_PASS、66 项 migration 集合匹配、12 类关键表可读和本轮资源清理完成。该结果并非代理独立远端验证;附件与应用仍未验,整体任务保持未完成。详见 research/restore-drill-evidence.md 同日记录。