27 KiB
27 KiB
隔离备份恢复演练实施计划
2026-09-11 配对恢复准备(未执行)
用户曾回传一次 DB_RESTORE_PASS:66 条迁移集合匹配、12 类表已验、隔离资源已清理。这是管理员回执,不是本轮独立复验;不能继续写“数据库从未成功恢复”。附件与应用配对恢复尚未证明。
接续采用简单隔离流程,不再扩复杂演练器。先获准只读核验最新本地/ARM 自然批次、manifest/包大小摘要、来源版本、时效、磁盘和独立镜像制品。历史备份时点及旧磁盘数值不当成今日事实。
实际恢复需单独授权具体隔离目标与资源:同一 manifest 的 DB 和附件恢复到一次性 PostgreSQL 与空目录;源/目标身份隔离、禁生产数据库连接及通知/OCR/支付外联;核对迁移、关键表、附件引用存在性与适用大小摘要,必要应用只读。只回传脱敏匹配数和异常类别,不输出记录或文件路径。仅清理本轮创建资源,旧备份和回滚制品不删。
摘要匹配不等于实测恢复;旧镜像不撤销留痕删除或票据释放;若未来恢复生产,备份时点后数据丢失风险仍须另批。当前只准备清单,未 SSH、未复制或恢复真实备份。
执行前门禁
- 确认任务已在用户审阅最终规划摘要后由
task.py start进入in_progress。 - 只读确认本地
main、当前生产构建事实、来源/当前 migration 集合和现有恢复脚本;现场两构建均为 65 且目录无变化,但后续执行不硬编码数量。 - 只读确认生产公网
/ready正常;不读取生产数据库或执行生产写入。 - 连接 ARM 后只读核对 receiver 配置有效、最新正式日批次身份、dead-man 状态、Docker 可用性和磁盘余量;不列出完整目录或原始 manifest。
- 磁盘安全预算至少满足“批次总字节数 5 倍 + 2 GiB”;不足则
PAUSE。 - 若当前账号没有对正式归档只读和本轮临时区/Docker 的最小权限,停止并给用户一条窄权限操作步骤;不得申请通用 root shell 或扩大既有健康监控 sudo 入口。
有序执行清单
- 生成不含主机信息的本轮 run id,记录 UTC 开始时间和生产前置
/ready状态。 - 在 ARM 正式日归档中选择 manifest 时间最新的 complete 批次,验证三文件、字节数、SHA-256 与 24 小时 RPO 门禁;在本地仓库确认来源提交是当前构建祖先或相同,并单独记录是否严格相等。
- 创建权限
0700的本轮临时工作区;启动 RTO 计时,复制整个批次并对临时副本重新执行同一校验。 - 创建无宿主端口、无业务网络、无持久 volume 的一次性 PostgreSQL 16 容器;数据库名含
drill,凭据随机且仅存在本轮进程环境。 - 使用
scripts/restore-db.sh的 shadow 合同恢复数据库;任何警告、确认不匹配或 restore 非零立即停止后续验证并进入清理。 - 从来源提交动态冻结 migration 名称集合;通过错误即停的只读 SQL 验证恢复库成功且未回滚的 migration 集合精确匹配来源、无失败/未知项,并静态记录来源与当前构建的 migration 差异;随后验证固定 12 类关键表并记录行数。
- 使用
scripts/restore-storage.sh恢复附件到本轮空目录;比较归档与解包普通文件数。 - 在影子库中聚合本地附件引用,以不输出路径的校验程序验证路径安全、文件存在及适用的大小/SHA-256;记录引用总数和不一致数。
- 所有数据检查通过时停止 RTO 计时;按 manifest 时间计算 RPO,记录当前发布到首个同源恢复点的可用滞后,形成区分“原始数据可恢复性”和“当前 schema 升级状态”的
GO/PAUSE/NO_GO脱敏结论。 - 清理本轮容器、临时网络(若有)、临时附件目录、临时批次副本和临时凭据;确认无本轮残留。
- 再次只读检查生产公网
/ready和 ARM dead-man/健康 timer 状态,确认演练没有影响在线生产与现有监控。 - 将证据写入当前 task,并在既有事实源补充当前状态;不提交任何真实备份、日志或业务内容。
Attempt 1 执行状态
- 最新 ARM 候选在
select_latest_batch阶段因 manifestbuild_mismatch失败关闭;复制、容器创建、数据库恢复和附件恢复均未开始。 - 失败后的只读复核确认:公网
/ready与生产自动备份 unit 的构建短标识一致,两个生产侧事实均为7b86ffb3;因此当前不是计划事实源过期或备份 unit 冻结构建漂移。 - ARM 一次性 root 入口和本轮 runtime 均为零残留,两个监控 timer 仍为 active;本轮 5 个普通用户暂存文件已按 SHA-256 精确匹配并删除,未宽泛删除目录。
- Attempt 1 保持
NO_GO。在当时取得最新 ARM manifest 的脱敏构建短标识、run id 配对关系和 manifest 摘要一致性前,不进入第 3 步及之后的恢复流程。
Attempt 1 后只读调查清单
- 生成固定无参数的 root-owned ARM 只读身份探针和最小 sudoers,只允许读取 receiver 路径配置及最新正式日归档。
- 本地执行
bash -n、候选 SHA-256、sudoers candidatevisudo(环境可用时)和禁止写入/恢复关键字人工复核。 - 上传到 ARM 普通用户私有暂存目录;由用户输入 sudo 密码安装固定入口,安装前再次核对全部候选 SHA-256 和系统 sudoers 语法。
- 运行一次固定入口,记录构建短标识、批次年龄、manifest 配对、产物聚合完整性和入口自清理状态。
- 对照公网
/ready与生产自动备份 unit 的当前短标识:相等时记录同源恢复点已形成;不相等时在本地仓库核对是否为当前构建祖先,祖先且完整/新鲜仍可形成原始恢复重试方案,未知或非祖先才NO_GO。 - 按 SHA-256 精确删除普通用户暂存文件;不得删除 ARM 正式归档或宽泛清理目录。
只读调查执行结果
- 探针候选通过本地/ARM SHA-256、Bash 语法和 ARM sudoers candidate 校验。
- 固定入口只读读取最新正式批次并自删除;未复制、解包、启动容器或恢复数据。
- 最新批次
ec682565在 24 小时内,run id/目录配对及 DB/附件大小、SHA-256 均通过,但与当前7b86ffb3不匹配。 - 只读对时确认自动备份合同刷新晚于最新批次生成;finding 收敛为“发布后尚未产生新构建恢复点”。
- root 入口残留为 0,3 个普通用户候选及暂存目录已按精确身份清理,两个 ARM 监控 timer 仍 active。
- 08-24 最新自然批次只读探针通过:来源与当前构建相同、年龄不超过 24 小时、run id 配对及 DB/附件 SHA-256 均通过;临时入口和暂存零残留。当前可提交恢复重试审批,尚未获得恢复授权。
Attempt 2 恢复重试结果
- 用户批准后安装并执行动态 migration 集合版固定恢复入口。
- ARM 正式归档最新批次首次门禁通过,并开始复制到本轮私有临时区。
- 临时副本复检因 runner 错把正式源目录 basename 身份规则应用到固定名
batch而触发batch_identity;失败阶段为create_isolated_runtime,数据库容器和恢复均未开始。 - runtime、root 入口、6 个普通用户候选和暂存目录均精确清理为零残留,两个 ARM 监控 timer 保持 active。
- 修订 runner:正式源目录继续强制 basename/run id 配对;临时副本 manifest run id 重绑到源侧已验证 run id,并继续校验完整内容合同及源/副本元数据精确一致。补齐 2 正例 + 3 负例后重新执行只读身份探针,实际恢复另行批准。
Attempt 3 准备批准边界
- 用户已批准修复 runner,并重新执行 08-25 最新正式批次只读身份探针。
- 回归已覆盖:正式源通过、同内容改名副本通过、内容篡改副本失败、源 basename/run id 错配失败、副本 run id 与源侧已验证 run id 不同失败。
- Attempt 3 未复用 Attempt 2 新鲜度:08-25 最新批次年龄约 6 小时 11 分,来源与当前构建相同,run id 配对、大小与 SHA-256 均通过。
- 用户复核探针后明确批准 Attempt 3 实际恢复,范围仅限 ARM 隔离影子恢复。
Attempt 3 恢复结果与停止点
- 修复后的候选在本地和 ARM 通过 SHA-256、Bash 与 sudoers 语法校验后安装;正式归档门禁和临时副本源侧身份重绑通过。
- runner 在
restore_database阶段因restore-db.sh返回非零而以database_restore_failed失败关闭;migration、12 类关键表、附件恢复与关联验证均未执行。 - 一次性容器、本轮 runtime、临时 root 入口和普通用户候选均精确清理为零残留;ARM 两个监控 timer 保持 active,生产演练后
/ready仍为相同构建的PASS。 - 在任何 Attempt 4 前修复失败诊断合同:分别记录 dump 列表校验与实际 restore 的脱敏阶段码,并确保失败清理前只保留安全聚合诊断;本地回归已通过,远端探针和实际恢复仍需重新批准。
Attempt 4 前的修复清单
- runner 在调用
restore-db.sh前,以同一 PostgreSQL 16 容器对临时副本执行独立pg_restore --list,记录dump_list=PASS|FAIL|NOT_RUN。 - 独立确认影子目标数据库名与连接状态,记录
target_confirmation=PASS|FAIL|NOT_RUN;不输出数据库名或连接信息。 - 仅在前两项通过后执行实际 restore,记录
restore_apply=PASS|FAIL|NOT_RUN;失败类别区分为dump_list_failed、restore_target_confirmation_failed或restore_apply_failed_after_list_pass。 - 原始 stderr 只进入本轮
0600私有日志并随 runtime 删除;最终输出只含 allowlist 阶段状态和既有脱敏聚合。 - 补三条阶段负例、敏感输出负例和每条失败路径零残留回归;通过后重新执行最新批次身份探针,再请求 Attempt 4 实际恢复批准。
Attempt 3 后本地修复结果
dump_list、target_confirmation、restore_apply固定输出PASS/FAIL/NOT_RUN,并增加执行路径、脚本/pg_restore 退出码、对象错误计数与稳定类别。- 诊断在清理前输出;注入 apply 退出码
23后,调用方在 runtime/access 清理完成后仍可读取阶段状态和退出码。 - partial-success 规则保持失败关闭:任何 pg_restore 非零均为
FAIL/NO_GO,不设置可忽略对象错误白名单。 - PostgreSQL 16 custom dump 直接驱动真实
scripts/restore-db.sh的 Docker stdin 与 host-file 两条路径,均恢复成功。 - dump-list 失败、目标确认失败、apply 失败及敏感输出负例通过;既有成对备份/恢复回归和自动异机备份合同通过。
- 用户另行批准并完成 Attempt 4 前最新批次只读探针:构建
SAME、年龄约 7 小时 24 分、run id/产物完整性与 migration 集合门禁通过,入口及暂存零残留;尚未执行实际恢复。
Attempt 4 前的持久化门禁
- 将已验证的 runner 和附件校验器从个人 workspace 收敛为
scripts/qa/下的跟踪文件,不改变恢复边界或生产脚本。 - 将八类 runner 回归收敛为可独立执行的
run-offhost-shadow-restore-runner-contract.sh,直接驱动真实restore-db.sh双路径。 - 合同脚本必须机械验证三阶段诊断、执行路径、两个退出码、非零失败关闭、源/副本身份、dynamic migration、敏感输出和清理顺序;对候选生成稳定 SHA-256。
- 运行新合同、既有成对备份/恢复、自动异机备份 74 项、Trellis 治理与敏感扫描;全部通过后才允许把跟踪文件打包为 Attempt 4 候选。
- 本阶段仅本地修改与测试;新批次探针结果和持久化门禁均通过后,再单独申请 Attempt 4 实际恢复。
Attempt 4 前持久化门禁结果
- runner 已收敛为
scripts/qa/offhost-shadow-restore-runner.template.sh;现场路径、账号、容器/数据库命名、timer、构建和 migration 指纹均为经严格校验的私有渲染字段。 - 附件关联校验器已收敛为
scripts/qa/validate-offhost-shadow-restore-attachments.py。 scripts/qa/run-offhost-shadow-restore-runner-contract.sh可独立复跑并提供render模式;相同私有配置生成确定性候选 SHA-256,shell 注入在输出候选前失败关闭。- 源/副本身份、内容篡改、dynamic migration、附件安全、三阶段诊断、真实 restore 双路径、NOT_RUN、退出码、清理顺序和敏感输出合同全部通过。
- 新增三个文件由
check-sensitive-content.mjs定向扫描,3/3文件、finding0;本地测试容器残留0。 .gitignore增加/.restore-drill-private/专用目录;合同分别证明仓库内未忽略的私有 JSON、未忽略的现场候选均在创建输出前失败,ignored 输入/输出正例通过。- 私有原始日志保留唯一初始化截断,五个固定阶段均以标记分隔并追加写;静态合同拒绝后续阶段再次截断。
- 完整复跑 runner 合同、既有隔离备份/恢复演练和自动异机备份 74 项;task、Trellis、process、默认/定向敏感扫描及空白门禁通过,测试容器和本地私有路径残留均为
0。 - Attempt 4 最新批次只读探针重新执行并通过;候选已由提交
5ec7db1的跟踪模板确定性渲染,完整合同、依赖钉住和 SHA-256 复核通过。 - 用户批准 Attempt 4 后,候选在 ARM 安装前再次通过 SHA 清单与语法校验并执行;
dump_list=PASS/0,随后在target_confirmation阶段失败,实际 restore apply、migration、关键表和附件均未运行。 - Attempt 4 runtime、临时 root 入口和普通用户上传暂存均清理为
PASS/0;按预先裁决规则转入本地合同路径与 ARM 实际环境的只读差异调查,不直接修补 runner 或创建 Attempt 5。 - 只读差异矩阵与本地精确复现收敛到 PostgreSQL 初始化就绪竞态:合同夹具等待连续两次真实查询,runner 仅等待首次
pg_isready;本地稳定数据库上的同一 target query 为PASS/0,ARM 所有临时对象复核残留0。 - Attempt 4 后正式归档只读探针与执行前为同一构建和同一 manifest 脱敏摘要,run id 配对、产物 SHA-256、24 小时新鲜度均通过;探针入口与暂存残留
0,正式归档内容级零修改已补证。 - 演练后腾讯云生产
/ready已由执行方沿既有只读路径补证:状态PASS、12 位构建前缀7b86ffb3c9ef,与演练前一致;未记录地址或原始响应。 - 用户已批准仅在本地实施和回归 PostgreSQL 稳定就绪修复;该批准不包含连接 ARM 或执行 Attempt 5。
Attempt 5 前仅本地修复结果
- 在跟踪 runner 中以容器内 TCP 回环
127.0.0.1的真实SELECT current_database()作为结构性就绪判据,并以最多 60 次、间隔 1 秒、连续两次成功且名称精确匹配作为额外保险,替换首次 Unix socketpg_isready即通过逻辑;名称错配立即失败,查询非零重置连续成功计数。 - 增加 target query 退出码、名称匹配、尝试次数和连续成功次数的 allowlist 诊断,区分查询非零与名称错配;私有原始日志、失败先诊断后清理和零残留边界不变。
- 可复跑合同直接提取并驱动 rendered runner 中同一稳定就绪函数;fixture 外围与 runner 不同源的等待循环已删除。
- “socket 可用但 TCP 不可用仍失败”、首次失败后恢复、streak 重置、名称错配立即失败、永久查询失败有界退出五类回归通过;真实
restore-db.shDocker stdin/host-file、源/副本身份、dynamic migration、附件安全、敏感输出和清理合同继续通过。 - 已审计合同全部覆盖机制,未发现第二套自写等价恢复逻辑;完整 runner 的 migration/12 类表/附件编排仍只能由真实隔离恢复验证,已作为明确限制保留,不能由本地组件合同替代。
scripts/restore-db.sh相对生产构建字节未改;runner、成对备份/恢复、自动异机备份 74 项、task、Trellis、process、docs、敏感扫描和空白门禁均通过。- 本地修复阶段未连接 ARM、未生成或安装 Attempt 5 现场入口;提交后已重新选择最新批次、执行只读探针、重新渲染候选并核对 SHA-256,实际恢复另行取得了明确批准。
Attempt 5 前只读身份探针结果
- 用户批准后仅安装并执行最新正式批次只读探针;未复制、解包、启动容器、读取业务数据或执行恢复。
- 最新批次来源与当前生产构建相同,探针时年龄
64625秒且不超过 24 小时;run id 配对、DB/附件大小与 SHA-256、source digest 均通过。 - 来源/当前 migration 目录为
65/65、差异0;仓库 HEAD 相对生产构建的应用代码漂移文件数0。 - 探针 root 入口与普通用户暂存残留均为
0;按已验证私有配置取得的 dead-man/健康 timer 实际 unit 状态为active/active。 - 本次探针完成时 RTO 八阶段实现尚未批准,因此当时未渲染 Attempt 5 最终候选、未生成最终候选 SHA-256,也未执行实际恢复;后续本地实现授权单独追加,不改写该时点事实。
Attempt 5 前 RTO 分阶段实施(已批准仅本地实现)
- 设计口径已固定为总 RTO 加八段串行秒数:批次复制、容器启动、dump list、目标确认、restore apply、migration/12 类表、附件恢复与关联校验、最终源/副本复核。
- runner 增加固定 allowlist 阶段字段,成功时八段均为非负整数且精确加总为
data_restore_rto_seconds;失败时已完成段和当前失败段保留数字,后续段为NOT_RUN。 - 合同注入各阶段成功/失败,验证最长 TCP 轮询只进入目标确认阶段、后续
NOT_RUN、总数精确加总、输出不含路径/SQL/凭据;原有清理与恢复合同继续通过。 - 用户批准的当前边界仅为本地修改 runner、更新可复跑合同并执行回归;不连接 ARM、不重新渲染 Attempt 5 现场候选、不执行实际恢复。
- 八阶段计时与完整合同通过后,满足 24 小时门禁的批次已直接进入 Attempt 5 候选渲染、SHA-256 核对、只读探针和实际恢复审批流程;期间未插入新的非阻断增强。
- 八阶段状态必须在失败路径清理前输出;阶段边界沿用
dump_list、target_confirmation、restore_apply等既有诊断词汇,不建立第二套同义命名。
Attempt 5 最终候选与执行前探针
- 从提交
0b94b97的跟踪模板和 ignored 私有配置完成两次确定性渲染;候选字节一致、完整 runner 合同通过,候选 SHA-256 为7904052aa5a8c31d54734bc2fbf2d9caf2dac8b0116135119519f8467b3dae27。 - 候选固定的是生产构建前缀和来源 migration 集合指纹,不固定探针时的 source run id;实际执行会在 ARM 上重新选择当时最新正式批次,并对该批次重新执行完整身份、产物 SHA-256、24 小时 RPO 和 migration 集合门禁。
- 最终只读探针重新选择执行时最新正式批次:来源构建与当前生产相同,年龄
68889秒且不超过 24 小时,run id/目录配对、DB/附件完整性和 source digest 均通过。 - 本地复核来源/当前 migration 为
65/65、差异0,候选 migration 指纹与来源集合一致,应用代码漂移和scripts/restore-db.sh字节漂移均为0。 - 探针 root 入口、sudoers 和普通用户暂存残留均为
0;本地 runner 合同容器残留为0。本阶段未复制、解包或恢复正式归档,未连接腾讯云生产。 - Attempt 5 实际隔离恢复已在新鲜度门禁成立时另行批准并执行;紧邻执行前探针通过,但 runner 在选择实际恢复批次之前即因依赖库入口合同失败,因此本轮不存在“实际选择批次”,不能宣称恢复输入与探针批次相同。
Attempt 5 实际结果与安装器差异调查
- 安装前候选 SHA-256 与已批准值精确一致;紧邻执行前只读探针通过,批次年龄
70444秒,来源构建与当前生产相同,run id 配对、产物完整性和 source digest 门禁通过。 - runner 在
entry_contract阶段以restore_library_missing失败关闭;批次选择、正式归档复制、PostgreSQL 容器启动、数据库/附件恢复和全部八阶段 RTO 均未运行,原始结果保留为NO_GO。 - 失败分类为
installer_path_mismatch:已批准 runner 从固定libexec位置加载三项依赖,本轮一次性安装器却把同一组依赖安装到相似但不同的lib位置。该结论指向演练安装器,不证明 runner 或备份不可用。 - 对错误安装目录做精确只读检查:三项依赖均为 root 拥有的普通文件、SHA-256 前缀与本地包一致、额外条目数
0;随后只清理该已确认目录并得到runner_lib_cleanup=PASS。 - 诊断脚本在 sudo 上下文中用
$HOME推断普通用户暂存位置,导致自删除误指向 root 家目录;随后由普通用户外层对已知暂存脚本执行精确清理。后续安装器不得在 sudo 脚本中用$HOME推断调用用户路径。 - Attempt 5 后腾讯云生产
/ready为PASS,12 位构建前缀仍为7b86ffb3c9ef;失败发生在归档选择之前,未触碰腾讯云生产或正式归档内容。 - 最终只读复核确认 runner/probe 入口与 sudoers、正确
libexec、错误lib、普通用户暂存、Docker 容器和 runtime 六类残留全部为0,dead-man/健康 timer 为active/active;复核脚本自身清理PASS。 - ignored/workspace 安装器已把三项依赖安装目标对齐 runner 已批准的
libexec合同;诊断脚本改用经 basename、普通文件和非链接校验的调用路径自清理,不再以 sudo$HOME推断普通用户路径。runner 与候选字节未改、无需重新渲染。 - 再次实际恢复前重新选择满足 24 小时门禁的新鲜批次,执行只读身份探针并单独申请实际恢复批准;不得复用 Attempt 5 的批次新鲜度或既有实际恢复授权。
08-27 最新批次只读身份探针
- 安装器与 rendered runner/probe 的共享路径完成本地静态核对:runner
SELF_PATH/LIB_DIR/SUDOERS_PATH、probeSELF_PATH/SUDOERS_PATH均在首次特权写入前精确比对;WORK_ROOT未在安装器重复编码,sudoers candidate 从最终路径推导。 - 探针上传准备中一次 basename 截取错误被远端 SHA-256 校验在普通用户暂存阶段拦截;未执行 sudo、未安装入口、未读取归档。三个已确认截短文件逐个精确清理后,以真实 basename 重传并通过三文件 SHA-256 与 Bash 语法校验。
- 最新正式批次只读探针执行成功:来源构建与当前生产相同,run id/目录配对、DB/附件产物完整性和 source digest 均通过;探针入口与普通用户暂存残留为
0/0。 - 最新批次年龄
124137秒,约 34 小时 29 分,超过 24 小时门禁37737秒,约 10 小时 29 分;本次恢复前置判定为NO_GO/stale_latest_batch,不得改选旧批次或执行实际恢复。 - 用户批准后完成生产与 ARM 两侧只读调查:daily/watchdog timer 均按计划触发但最近 service 均
exit-code/1;ARM 最新原子归档超龄且存在两个不完整 partial,定位为生产到 ARM 的传输未完成,不是调度漏跑或完整传输后的 finalize 失败。 - dead-man 实际阈值为
93600秒并正确记录FAIL_OFFHOST_DEADMAN/archive_stale;journal 聚合存在一次sent=true,证明 detector 与发送调用未被去抖静默抑制。健康 timer 保持 active,两端调查入口和暂存均清理为零残留。 - 两个 partial 证明 SSH 会话已完成初始认证并开始写入,后续排查不再以密钥失效、authorized_keys 或 host key 初始拒绝为首要假设;独立事件调查优先采集 partial 聚合字节偏移、真实 rsync 退出码和传输持续时间。
- 在生产自动备份传输恢复、ARM 形成新的 24 小时内原子批次之前,恢复演练保持阻塞;补跑备份、修复传输配置/网络、修改 timer 或发送测试告警均需新的明确批准。
- 将生产到 ARM 的传输中断拆为独立 Trellis 生产事件任务,当前演练任务只保留交叉引用和阻塞关系;创建任务、生产侧只读深查与实际修复均另行取得批准。
验证命令类别
- 本地/仓库:
bash -n覆盖备份、DB 恢复、附件恢复和 receiver 脚本;只读统计 migration 目录。 - ARM 前置:receiver
validate-config、systemd 公共状态、Docker 版本/容量、候选 manifest 脱敏校验。 - 恢复输入:
sha256sum、manifest schema/文件集/字节数校验、pg_restore --list、tar -tzf/tar -tvzf。 - DB 验证:
psql -v ON_ERROR_STOP=1的 migration 名称/状态集合和固定表计数查询;本地用 Git 比较来源/当前 migration 目录,不执行 migrate。 - 附件验证:
find普通文件计数及不输出路径的 Python 只读校验;只输出引用数和 mismatch 数。 - 任务门禁:
python3 ./.trellis/scripts/task.py validate .trellis/tasks/08-23-isolated-backup-restore-drillnode scripts/qa/check-trellis-governance.mjsnode scripts/qa/check-process-contract.mjs --baseline --jsonnode scripts/qa/audit-docs.mjs --check-registrynode scripts/qa/check-sensitive-content.mjsgit diff --check
具体远端命令在执行阶段依据 ARM 已安装的 root-owned receiver 配置生成,不把真实地址、账号、目录或凭据写入本计划。
停止条件
- 最新批次不存在、超过 24 小时、manifest 或 SHA-256 不一致,或来源提交未知/不是当前构建祖先或相同。仅“不严格相等”不再单独停止。
- 权限、Docker、PostgreSQL 16 或磁盘预算不满足。
- 命令目标可能指向腾讯云生产、ARM 正式归档、receiver 管理目录或既有容器/网络。
- DB restore、migration、固定表、附件安全、文件引用、哈希/大小任一检查失败。
- 生产
/ready在演练期间异常,或现有 ARM dead-man/健康监控状态改变。 - 清理对象身份不明确。此时保留现场并报告,不使用宽泛删除命令。
变更与证据文件边界
- 允许写入:当前 Trellis task、既有 OPS7 Runbook/人工试运行报告中的脱敏状态摘要、本轮 ARM 私有临时区和一次性 Docker 对象。
- 禁止写入:产品代码、migration、生产/ARM 正式配置、生产 DB/附件、ARM 正式归档、企业微信。
- 计划新增的 task 内证据:
research/restore-drill-evidence.md;只在实施实际发生后创建。
审查与收口
- 本任务涉及真实备份数据和远端运维边界。执行完成后做一次只读复核,重点确认:生产零变更、归档未修改、RTO/RPO 口径正确、附件验证没有漏项、敏感内容未进入证据、临时对象已清理。
- 若现有脚本需要修改,回到规划阶段补充设计和新的批准;不得在远端临时放宽 shadow/路径/确认门禁。
- 门禁通过后用中文 commit 引用
08-23-isolated-backup-restore-drill,是否推送仍按用户当时授权执行。