Files
gaokao-volunteer-system/docs/BACKUP_AND_RECOVERY_PLAN.md
2026-06-18 13:39:02 +08:00

6.7 KiB
Raw Blame History

BACKUP_AND_RECOVERY_PLAN

最后更新: 2026-06-14 状态: 最小恢复基线(已具备本地快照 + 完整性校验 + restore smoke

1. 目标

为 T12 Web 自助 MVP 建立最小可恢复方案,覆盖:

  • SQLite 数据库
  • 报告 HTML/PDF 文件
  • 上传/分享产物
  • 运行所需关键配置与密钥映射关系
  • 本地可执行的备份、校验、恢复演练入口

2. RPO / RTO 建议

  • RPO: 24 小时内
  • RTO: 4 小时内

说明:当前是轻量单机 MVP不承诺秒级恢复也不等同于生产级多机容灾。

3. 需要备份的对象

  1. 数据库
    • 管理库 data/orders/admin.db
    • 订单库 data/orders.db
    • 分享库 data/share/short_links.db
  2. 文件目录
    • 分享/公开报告目录
    • GAOKAO_PORTAL_UPLOAD_DIR 下的前台附件上传目录
    • 订单记录真实引用的报告 HTML/PDF 产物(orders.audit_report / orders.pdf_path
    • data/examples 中的样例交付物(用于恢复 smoke
  3. 配置与运维资料
    • .env 实际部署值(不入 Git
    • systemd / docker-compose 部署配置
  4. 密钥资料
    • JWT secret
    • Fernet key
    • 支付相关密钥/证书

4. 当前已落地产物

  • scripts/backup_snapshot.sh
    • 生成时间戳快照目录
    • 复制 DB / portal 上传目录 / 订单真实交付物 / 可选 config / 可选 secrets
    • 生成 manifest.json
    • GAOKAO_BACKUP_KEEP 保留最近 N 份
  • scripts/backup_verify.sh
    • 可校验 live staging 或已有快照
    • 校验 SQLite 可读性
    • 校验 manifest.json 哈希完整性
    • live staging 时对 SQLite 使用 sqlite3.backup() 生成 staging 副本,不再裸复制 .db
    • live staging 时同步复制 portal_uploads 与订单挂载交付物
    • 调用 restore smoke
  • scripts/backup_restore_smoke.py
    • 在恢复副本上启动 FastAPI TestClient
    • /health、portal 状态页、报告 HTML、PDF 下载最小链路
    • 只改临时恢复副本,不改原始快照
  • 定时接入口径示例
    • ops/cron/gaokao-backup.crontab.example
    • ops/systemd/gaokao-backup.service
    • ops/systemd/gaokao-backup.timer
    • ops/systemd/gaokao-backup-verify.service
    • ops/systemd/gaokao-backup-verify.timer

5. 最小备份策略

数据库

  • 每日一次目录快照
  • 文件名包含 UTC 时间戳
  • 保留最近 7 份日备(可由 GAOKAO_BACKUP_KEEP 调整)

文件目录

  • 与数据库同批次快照
  • share_reportsportal_uploads、订单挂载交付物、样例报告分开保存,避免后续排障时混淆
  • 订单挂载交付物统一落在 files/order_artifacts/<order_id>/<artifact_kind>/...,保留原始文件路径层级,便于恢复时回填

配置与密钥

  • .env、部署配置、密钥目录不与业务数据库混写到同一路径
  • 通过环境变量显式声明:
    • GAOKAO_PORTAL_UPLOAD_DIR
    • GAOKAO_BACKUP_ENV_FILE
    • GAOKAO_BACKUP_CONFIG_DIR
    • GAOKAO_BACKUP_SECRETS_DIR
  • 只允许受控人员访问

6. 最小 runbook本地可执行

6.1 生成快照

bash scripts/backup_snapshot.sh /tmp/gaokao-backups

可选环境变量:

export GAOKAO_BACKUP_KEEP=7
export GAOKAO_BACKUP_ENV_FILE=/etc/gaokao/.env
export GAOKAO_BACKUP_CONFIG_DIR=/etc/gaokao
export GAOKAO_BACKUP_SECRETS_DIR=/var/lib/gaokao/secrets
export GAOKAO_PORTAL_UPLOAD_DIR=/var/lib/gaokao/portal_uploads

6.2 校验最近一份快照

bash scripts/backup_verify.sh --from-backup /tmp/gaokao-backups/backup-<UTC_TIMESTAMP>

校验内容:

  1. manifest.json 哈希一致
  2. SQLite 文件可打开、表可枚举
  3. 恢复副本可跑最小服务 smoke
    • /health
    • /portal/{token}/status
    • /portal/{token}/report
    • /portal/{token}/report.pdf

6.3 从 live 数据直接做一次恢复演练

bash scripts/backup_verify.sh

该命令会把当前 live DB / 文件 staging 到临时目录后执行同样的校验链。 其中 live SQLite 会通过 sqlite3.backup() 生成一致性副本;--from-backup 模式则直接校验已有快照内容。

7. 定时接入口径

cron 示例

见:ops/cron/gaokao-backup.crontab.example

  • 每天 02:30 生成快照
  • 每周一 03:00 对最近一份快照执行 restore smoke

systemd timer 示例

见:

  • ops/systemd/gaokao-backup.service
  • ops/systemd/gaokao-backup.timer
  • ops/systemd/gaokao-backup-verify.service
  • ops/systemd/gaokao-backup-verify.timer

说明:这些文件只是仓库内口径样例,不代表目标主机已经安装启用。

8. MVP 上线前最低要求

  1. 至少完成一次真实快照生成
  2. 至少完成一次 backup_verify.sh --from-backup ... 演练
  3. 明确密钥存放位置和负责人
  4. 不得再使用“Git 备份即可恢复系统”作为对外或内部结论

9. 当前仍未闭环的外部/后续缺口

  • 异机 / 异地备份尚未落地
  • 目标主机上的 cron / systemd timer 尚未实际安装验收
  • 真实 SMTP / IM / 监控通道的目标机联调与失败演练记录仍未归档
  • 密钥轮换与应急恢复仍缺真实执行记录

10. 不可降级的不变量

  • 备份必须覆盖 4 节列出的所有对象, 不得漏备份 share_reports
  • 备份必须覆盖 portal_uploads 与订单真实引用的 HTML/PDF 交付物
  • 快照必须含 manifest (manifest.json), 含每个文件的 SHA-256
  • 校验必须走 scripts/backup_verify.sh, 不允许用裸 SQLite sqlite3 <file> ".schema" 代替
  • 恢复演练必须是服务级 (FastAPI TestClient) 而不仅是文件级
  • delivered / failed 事件备份必须保留 failure_reason, 用于事后根因分析
  • 备份介质必须使用 24h RPO, 不允许依赖“Git 备份可恢复系统”作为对外口径

11. 流程 (MVP)

定时任务 (cron / systemd timer)
    │
    ▼
1. 快照阶段: 复制 SQLite + 报告 + manifest.json
    │
    ▼
2. 校验阶段: backup_verify.sh 走 restore smoke
    │        ├─ 200 healthz
    │        ├─ 200 portal_status
    │        ├─ 200 portal_report
    │        └─ 200 portal_pdf
    │
    ▼
3. 失败处理: watchdog 退出码 != 0
    │
    ▼
4. 告警: 邮件 / IM / 监控 (P1-8 整改后)

12. 后续工作

  • 接入 P1-8 整改的 service-level smoke (已完成)
  • 增加异机异地备份 (P2-6 之后)
  • 接入告警推送 (P1-8 后续)
  • 备份失败告警链仍需目标主机接入真实 SMTP / IM / monitoring仓库内尚未提供可直接安装的 backup alert service
  • 接入密钥轮换演练 (P2-6 之后)
  • 真实演练记录归档(模板:reports/DR_DRILL_TEMPLATE.md,示例:reports/DR_DRILL_2026-07-01.md
  • 当前 restore smoke 证明的是“最小服务链可用”,不是完整生产级全链恢复