备份策略 — 操作日志

记录恢复演练记录、手动操作备忘。

格式

## YYYY-MM-DD: 操作简述

- **类型:** 恢复演练 / 手动操作 / 配置变更
- **触发原因:** 常规演练 / 故障恢复 / 配置变更
- **操作内容:**
- **耗时:**
- **结果:** 成功 / 部分成功 / 失败
- **备注:**

2026-05-30: 备份方案阶段复盘(定稿)

  • 类型: 阶段性反思
  • 审阅人: 用户 + 大锤(Hermes Agent)
  • 操作内容: 详见下方——汇总决策、弯路、经验
  • 结果: 完成 ✅

决策记录

决策选择理由
备份工具restic + resticprofile去重+加密成熟稳定,resticprofile 统一管理多 profile 和调度
密码存储macOS KeychainFileVault 未开,Keychain 系统级加密比明文文件更安全
密码策略本地盘 + NAS 共用同一 restic 密码简化管理(ADR Phase 4.1.1)
profile 分层P0-P3 四级按敏感度 + 变动频率分级,高频小数据(P0)与低频大数据(P2)分开
P0 调度方式无独立 schedule,通过 daily group 触发配置不常变,无需单独定时启动
调度格式resticprofile 日程表达式 → launchd plistresticprofile schedule 将日程转为 macOS launchd 服务
配置结构resticprofile 0.33 标准格式(version: "1" + profile 级 key)0.32 的 flat 旧格式已废弃,新版用标准 YAML
旧方案处理保留 backup.sh(tar+gz)但未标注废弃需补充 # DEPRECATED 避免混淆
外置盘未挂载backup-run.sh 失败不阻塞失败日志可读,但无缓重或告警机制
云存储暂缓成本 + 外置盘未到位,先做本地部分

弯路记录

  1. resticprofile 配置格式 ~8 轮修复 — 0.33 与早期版本的 YAML 结构差异大。应先用 resticprofile dump 验证解析结果,不要盲信文档图示。
  2. Keychain ACL 理解不足set-key-partition-list 只适用于证书/key 条目,通用密码用 add-generic-password -A 即可,不需要 ACL 额外授权。
  3. set -e 习惯性加但不严谨grep 无匹配导致脚本提前退出,基本功问题。
  4. p0 无独立 schedule 导致多轮调整 — 首次 resticprofile schedule --all 只生成 p1/p2/p3 的 plist,后发现 schedule 只对有 backup.schedule 字段的 profile 生效。p0 通过 group 触发是设计选择,不是疏忽。
  5. 旧 backup.sh 未清理 — tar+gz 旧脚本仍留在 DEV/scripts/,新用户可能被误导。
  6. launchd plist 未做外置盘依赖检查 — 3 个 plist 按时间触发,但外置盘可能未挂载,restic 报错后 launchd 记失败。无缓重机制,外置盘首次接入前定时任务会持续失败。

经验归档

  1. 先 dump 再信文档 — 新版本工具先用 resticprofile dump 验证配置解析,不要盲信文档图示。
  2. Keychain ACL 场景区分 — 通用密码用 add-generic-password -A 允许所有应用访问即可;set-key-partition-list 只适用于钥匙串中的 key/证书条目,不是通用密码的替代方案。
  3. group 调度规则schedule 只对有 backup.schedule 字段的 profile 生成 plist。无独立 schedule 的 profile(如 p0)通过 group 触发。
  4. 分层备份的核心价值在恢复 — 备份速度差不多,但恢复时的选择性天差地别。P0 逐级恢复最大程度缩短关键数据 RTO。
  5. 外置盘依赖的定时任务 — launchd + 可移动介质需考虑 graceful failure:失败日志可读、不影响启动、恢复后自动重试。
  6. 新旧方案及时清理 — 旧脚本标注 # DEPRECATED 或移出 PATH,避免混淆。
  7. 纯本地只能做到 2-1 — 3-2-1 策略的”异地”副本必须依赖云或 NAS。

外置盘容量提示

P1 ~67GB(DEV + Documents + Pictures)+ P2 ~12GB(Downloads + Movies/Music)+ restic 元数据 + 多版本快照。建议外置盘 ≥ 256GB,首次全量前确认可用空间足够。backup-init.sh 已有 df 检查作为防线。


2026-05-30: launchd 定时任务 + 初始化脚本

  • 类型: 配置变更
  • 操作内容:
    • profiles.yaml 中所有 profile 增加 schedule(systemd 日历格式)
    • resticprofile schedule --all 生成 3 个 launchd plist
    • backup-init.sh — 外置盘接入后一键初始化 repo + 首次备份
    • backup-run.sh — 后续手动运行备份(支持 p0/p1/p2/p3/daily/full)
  • 结果: 成功 ✅
  • 备注: p0 无独立 schedule(配置不常变),通过 daily group 或 backup-run.sh full 触发

2026-05-30: Keychain ACL 修正

  • 类型: 配置变更
  • 操作内容: set-key-partition-list 不支持通用密码条目,改用 -A 标志重建 Keychain 条目,launchd 进程可直接读取
  • 结果: 成功 ✅

2026-05-30: resticprofile 配置 + 关键词扫描脚本

  • 类型: 配置变更
  • 触发原因: Phase 4/6 实施
  • 操作内容:
    • 生成 restic repo 密码(32 字节随机),存入 macOS Keychain(服务名 restic-password
    • ~/.config/resticprofile/profiles.yaml:p0(密钥配置)/p1(代码文档)/p2(媒体)/p3(系统配置)四个 profile
    • ~/DEV/scripts/backup-keyword-scan.py + ~/.config/backup-keyword-scan.yaml 默认配置
    • 扫描备份策略文档验证:检出 6 处命中(ADR 合规讨论区的”机密”和”客户信息”——误报,扫描机制正常)
  • 结果: 成功
    • ✅ resticprofile 4 个 profile 全部正确解析
    • ✅ 关键词扫描脚本可运行,首次自动生成默认配置
    • ⏳ ACL 配置待执行(需登录密码)
    • ⏳ repo 初始化待执行(需外置盘)
  • 备注: 关键词扫描脚本集成到云出境步骤(非本地备份),待 Phase 5 实施时挂载

2026-05-30: SOPS + age 原型验证

  • 类型: 手动操作
  • 触发原因: 常规验证
  • 操作内容: 验证 SOPS + age 加密→git→解密恢复全链路。加密对象为 GenericAgent/mykey.py(真实密钥模板文件,43727 字符)
  • 结果: 成功
    • ✅ age 密钥对生成正常
    • ✅ SOPS + age 加密成功,输出为 JSON 格式(AES256_GCM + age 封装)
    • ✅ 解密后与原文件完全一致(diff 确认)
    • ✅ 密钥导出格式正确,可存入密码管理器
  • 安装方式: brew install age sops,安装到 /opt/homebrew/Cellar/
  • 备注: 原型通过,SOPS + age 工作流可实施