RestoreDrill:把备份能不能恢复变成一份审计员认可的报告
阅读时间: 大约 11 分钟
RestoreDrill:把”备份能不能恢复”变成一份审计员认可的报告

每个运维都知道”应该定期测试备份恢复”,但几乎没人真的做——因为没有安全的地方测,也没有时间测。脚本和 cron 也救不了:任务可能悄悄停掉、可能跑在过期数据上,而没人收到通知。restoredrill 把这件事压成一条命令:拉取最新备份、恢复进一个一次性容器、跑你定义的检查、写一份带恢复耗时的 JSON 报告。它的口号很直接——“Untested backups aren’t backups.”(未经测试的备份不是备份)。本文基于其官方 README,拆解这个工具到底解决什么问题、怎么工作、边界在哪。
一、出发点:合规要的不是”做过”,而是”证据”
restoredrill 当前版本 v0.4.0,自称 early days,支持 PostgreSQL 以及从 mysqldump 文件恢复的 MySQL 8,Go 编写、MIT 协议。
它最有洞察的一点在于:这不是一个”备份平台”,而是一个”审计证据生成器”。README 里有几段话把这个动机讲得很透:
- 它按恢复策略设定的节奏运行,而不是常驻连续运行——因为多数合规框架不鼓励”持续测试”这种说法:测试一出现空档,就会成为审计发现;它要给你”跑过了、什么时候跑的”的证据;
- 一份策略文档可以被轻易伪造(不管有意无意),人可以写下”我们每季度测一次”,哪怕过去一年根本没跑;而一份带真实时间戳、由程序生成的报告更难造假;
- 如果你在做 SOC 2、ISO 27001 或 AWS Foundational Technical Review,他们想要的正是这种东西:来自真实恢复的真实日志,展示跑了什么、什么时候跑的。
它也坦率地区分了自己与同类:Databasus 是一个带完整 Web UI、覆盖多数据库引擎的自托管备份平台;BackupDrill 专门做 Supabase(含 Storage 文件)。restoredrill 只做一件事——CI 原生、为审计报告而生的检查,而不是一个仪表盘。它的定位是:你的备份流程已经跑通了,你只需要证明它按计划在跑。
二、怎么工作:一次性容器 + 分层检查
quickstart 把流程压缩到十分钟、且无需碰生产:
pg_dump -Fc -d "$DATABASE_URL" -f backup.dump # 1. 随便导一个库
restoredrill --config quickstart.yml --trigger manual
# restoredrill: PASS, restore took 4.2s, 1/1 checks passed, report: restoredrill-report.json跑完得到一份带时间戳的 JSON,证明一次真实恢复在你笔记本上发生过。备份来源可以是本地磁盘文件、S3(需要 aws CLI)、pgbackrest 仓库,甚至是”别人已经恢复好的一个库”(existing_connection 模式,直接连上去跑检查,不需要 Docker)。
检查分层运行,且全部 fail closed——某一层跑不起来就算失败,而不是”跳过”。这是它区别于”跑个脚本看看”的关键:
- 恢复前预检:备份文件够不够大、归档头能不能读、备份是不是足够新(RPO 新鲜度检查);
- 结构性检查:恢复是否完成、表够不够数、序列与表是否同步;MySQL 侧还会看视图/触发器/事件/存储过程是否带回了不存在的
DEFINER账号; - 读路径检查:行数、数据新鲜度,以及你自己写的 SQL 断言。README 强调:一个恢复进程 exit 0 不代表它没撒谎,必须真的去读数据;
- RTO 证据:恢复实际花了多久,若设了目标就对照目标;
- 环境健全性:容器必须能起来、能接受连接——这同时证明恢复环境本身有足够资源。
三、报告才是产品:为审计员反复打磨的 JSON
README 里有一句话很醒目:“自动化恢复是容易的部分;做出一份审计员一次就接受的报告格式,才是需要真刀真枪迭代的。“它称这个 schema 来自”有人直接付过这笔学费”——三次重写、和真实审计员来回磨了几个月。
报告设计上有几个刻意选择:
- 每个字段永远在场:哪怕某次 drill 不适用,字段也不会缺席。因为审计员常把报告字段复制进表格,一个”有时有、有时没有”的字段会打断这个流程;
- 手动跑和定时跑同 schema:
triggered_by、triggered_by_user、pipeline_job_id让一次手动--trigger manual跑和定时跑承担同样的可问责性; - 真实用了哪个文件:
backup_resolved_key是实际恢复的那个对象,而不只是配置的源;如果源是 S3 前缀,它会选最新的、匹配备份格式的对象,校验和之类的 sidecar 文件不能因为更新就被误选;backup_candidates_considered按顺序记录每个被考虑过的对象及其跳过原因; - RPO/RTO 证据齐全:
backup_age_seconds、rpo_met、restore_duration_seconds、rto_met等; - 失败要可定位:
validation_errors把每个失败检查单独列出来,附失败原因;notify_errors记录通知失败——Slack/webhook URL 挂了本身就是一个 finding,会导致进程即使 drill 通过也以非零码退出; - 时间戳用
"YYYY-MM-DD HH:MM:SS UTC",而不是 epoch 或 RFC3339——因为大多数审计流程最后都是复制进电子表格,这种格式复制过去不会坏。
四、告警与 CI
它不新造仪表盘,而是把结果送进你已经在监控的东西:Prometheus textfile 指标(node_exporter 文本文件),对 restoredrill_last_run_timestamp_seconds 的年龄告警,这样 drill 停了也能被抓到;Slack webhook 收一行 PASS/FAIL;任意 webhook 收完整 JSON。退出码让它天然适合做成定时 CI 任务,仓库里有现成的 GitHub Action(action.yml)和 workflow 示例。
五、客观优势与局限
优势:
- fail closed、可审计:检查跑不起来算失败而不是跳过,报告字段恒定、时间戳友好,直接对准 SOC 2/ISO 27001/AWS FTR 的取证需求;
- 轻量上手:笔记本上一个一次性容器就能跑,不需要 S3、CI、生产凭证,十分钟出第一份报告;
- RPO/RTO 都覆盖:不仅验证”能恢复”,还量化”恢复得多新鲜、多快”;
- 诚实的对比与边界:README 主动点名 Databasus、BackupDrill 谁更合适,不吹自己万能。
局限与官方口径:
- 假设数据库能塞进 runner 上的容器:多 TB 级数据库需要恢复到专用基础设施,restoredrill 目前不支持;
- MySQL 支持很窄:仅 MySQL 8、纯
mysqldumpSQL 文件,不支持 MariaDB、压缩 dump、XtraBackup 等物理备份、也不支持 PITR;且不检查AUTO_INCREMENT漂移(PostgreSQL 有序列完整性检查,MySQL 没有等价物); - pgbackrest 只恢复最新备份:尚不支持按时间点选目标;
ready_timeout默认 120s 无法自适配,大库要先跑一次拿到真实耗时再设值; - 默认以超级用户跑检查:缺角色/授权问题不会暴露,需要额外配
globals_source+verify_as_role才能用应用账号真实验权; existing_connection模式信任你给的连接:它只校验能看到的数据,无法确认”上游那次恢复”本身是否用错了源、连错了库;- 早期项目:v0.4.0,roadmap 上还有 GCS/restic 源、与生产库的差异比对、定时模式等未完成。
六、适合谁用
- 要过 SOC 2 / ISO 27001 / AWS FTR 的小团队:缺的不是备份本身,而是”按节奏真实恢复过”的可交付证据;
- 已经有备份流程、只想补一个”按计划验证”闸门的团队:把它挂在 CI 定时任务里,失败即告警;
- PostgreSQL(或 MySQL 8 mysqldump)用户:尤其已经在用 pgbackrest 或 S3 存备份的。
反过来,如果你需要一个带 Web UI、统一管多引擎备份的平台,README 自己建议你去看 Databasus;如果是 Supabase 专属场景,看 BackupDrill。