Show HN: Restoredrill – 验证您的 Postgres 备份恢复
摘要
Restoredrill 是一个开源工具,通过将 PostgreSQL 备份恢复到容器中并运行验证检查来自动化测试备份,从而生成符合审计要求的报告,以确保合规性。
查看缓存全文
缓存时间: 2026/08/27 15:24
ahmadpiran/restoredrill
来源:https://github.com/ahmadpiran/restoredrill
restoredrill
未经验证的备份不是备份。 restoredrill 能证明您的 PostgreSQL 备份确实可以恢复。它会获取最新备份,将其恢复到临时的 Postgres 容器中,运行您定义的检查,并生成一份包含恢复时间的 JSON 报告。
状态:v0.1.0,处于早期阶段。仅支持 PostgreSQL。后续可能会有变化。
为什么需要它
每个人都知道应该测试恢复。但几乎没人这么做,因为没有安全的地方可以恢复,也永远没有足够的时间。自动化此项工作的团队通常自己编写定时任务和脚本,而这些脚本会悄无声息地失败:演练停止运行,或者开始恢复同一个过时的文件,而一个月内都无人察觉。
restoredrill 让演练成为只需一条命令的习惯,让跳过演练变得醒目。它按照您的恢复策略设定的计划运行,而不是持续运行。许多 GRC(治理、风险与合规)建议会明确警告不要做持续性的声明,因为任何中断都可能成为审计问题。restoredrill 证明您已按计划执行了所承诺的事项。
政策文档很容易伪造,无论是有意还是无意。“我们每季度测试一次”的声明可能是上周才写的,实际上一年都没有运行过任何测试。而带有时间戳、机器生成的报告则更难伪造。
如果您正在进行 SOC 2、ISO 27001 或 AWS 基础技术审查,这正是他们要求的证据类型:来自真实恢复的日志,与运行内容和时间相关联。
与同类工具的区别
这个领域还有其他工具。
Databasus (https://github.com/databasus/databasus) 是一个功能完善的自托管备份平台,支持 Postgres、MySQL、MariaDB 和 MongoDB,带有完整的 Web UI 和内置的恢复验证功能。如果您想在一个仪表盘上管理多个数据库引擎的备份,可以从它开始。BackupDrill (https://backupdrill.com) 为 Supabase 提供了类似的功能,甚至包括存储文件。
restoredrill 只做一件狭义的事:一个 CI 原生的检查,生成一份适合审计员查看的报告,而不是一个仪表盘。它采用全面失败关闭策略,包含 RPO(恢复点目标)新鲜度预检查、您自定义的 SQL 断言,并跟踪 RTO(恢复时间目标)与目标的差距。每个字段始终存在,以便能干净地复制到 SOC 2、ISO 27001 或 AWS FTR 的证据包中。如果您已有备份工具,只需要它按计划恢复的证明,这就是您需要的工具。
快速入门:十分钟,无需访问生产环境
不测试恢复的常见借口是“没有安全的地方可以做”。其实是有的:您自己笔记本电脑上的临时容器。
-
导出您现有的任何 PostgreSQL。Supabase、RDS、本地开发库,都可以:
pg_dump -Fc -d "$DATABASE_URL" -f backup.dump -
将
examples/quickstart.yml复制到旁边(或将backup.source指向您保存备份的位置)。 -
运行它:
$ restoredrill --config quickstart.yml --trigger manual restoredrill: PASS, 恢复耗时 4.2秒, 1/1 项检查通过, 报告: restoredrill-report.json
就这样。无需 S3、CI 或生产凭证。您现在就有一个 JSON 文件,证明发生了一次真实的恢复,带有时间戳,在您的笔记本电脑上,大约十分钟完成。一旦这步成功,添加真正的检查(行数、数据新鲜度、您自己的 SQL 断言,参见 examples/restoredrill.yml)并将其指向您真实的备份。
检查内容
检查分层运行。每项检查都是失败关闭的:如果检查无法运行,则视为失败,而不是跳过。
- 预检查:在恢复开始前进行:备份文件是否足够大、其归档头是否可读、以及它是否确实是最近的(RPO 检查)。这能捕获静默失败的备份定时任务,它只是留下同一个陈旧的文件。
- 结构检查:恢复是否完成、表数量是否足够、序列是否与其表同步。一个序列值落后于其列的最大值的情况,通常只有在真实灾难后的第一次 INSERT 时才会发现。restoredrill 现在就能捕获它。
- 读取路径检查:行数、数据新鲜度以及您编写的任何 SQL 断言。一次恢复可以正常退出但仍在说谎,直到有人真正读取数据。一个真实案例:恢复进程正常退出,但其后的数据库已静默损坏。这些检查就是为了这个。
- RTO 证据:恢复实际耗时,如果您设定了目标,则与之对比。
- 环境健全性检查:容器必须能正常启动并接受连接,这也证明了恢复环境有足够的工作空间。
证据报告
报告才是这里的核心产品。自动化恢复是容易的部分。获得一份审计员首次就能接受的报告格式需要真正的迭代。这个模式来自直接付出过代价的人:三次重写和与真实审计员数月的反复沟通。
每个字段始终存在,不会因为不适用而缺失。审计员经常将这些复制到电子表格中,一个有时存在有时不存在的字段会破坏流程。关键字段包括:
triggered_by/triggered_by_user/pipeline_job_id:无论调度器运行此任务,还是人工点击按钮(--trigger manual --triggered-by [email protected]),模式都相同。手动运行与计划运行具有相同的问责性。backup_resolved_key:实际被演练的文件或对象,而不仅仅是配置的来源。如果您的来源是 S3 前缀,restoredrill 会选择最新的对象,但前提是它确实看起来像正确的备份格式。在真实备份之后上传的校验文件或其他辅助文件,不能仅仅因为更新就胜出。backup_candidates_considered:restoredrill 查看的每个 S3 前缀对象,按顺序排列,以及跳过的原因。对于非前缀来源则为空。backup_timestamp/backup_age_seconds/rpo_target_seconds/rpo_met:上述描述的新鲜度和 RPO 证据。restore_initiated_at/restore_completed_at/restore_duration_seconds/rto_target_seconds/rto_met:RTO 证据,如果您设定了目标,则与之对比衡量。validation_errors:每个失败的检查作为其独立字段,包含失败内容和原因。如果一次运行失败,您需要知道什么坏了,而不仅仅是它坏了。notify_errors:失效的 Slack 或 webhook URL 是一个问题,而不是静默的无操作。如果通知目标发送失败,它会显示在这里,并且进程以非零代码退出,即使演练本身通过了。- 所有时间戳都是字面量
"YYYY-MM-DD HH:MM:SS UTC"字符串,而不是纪元时间或 RFC3339 格式。大多数审计员工作流最终是复制粘贴到电子表格中,这种格式能很好地适应。
JSON 报告保留了对实际运行内容的可检查性。没有精美的 PDF 摘要要求您或您的审计员仅仅信任它。
单次报告本身无法显示您的恢复是否随时间变慢。这是交给您将这些报告输入的工具的工作:日志聚合器、仪表盘,甚至电子表格。每份报告都包含 restore_duration_seconds,因此很容易绘制图表。
要求
- Docker
- PostgreSQL 备份:
pg_dump -Fc归档文件或纯 SQL 转储,本地或 S3 中(S3 来源需要awsCLI)
告警:无需新仪表盘
restoredrill 将结果发送到您已经在使用的工具中:
- Prometheus:
output.prometheus_textfile写入 node_exporter 文本文件指标。根据restoredrill_last_run_timestamp_seconds的时间进行告警。这是您的“在 N 小时内已验证”的信号,能捕获静默停止运行的演练。 - Slack:
notify.slack_webhook_url收到一行 PASS/FAIL 摘要,并列出失败的检查。 - 其他任何工具:
notify.webhook_url通过 POST 收到完整的 JSON 报告。
任何目标投递失败都会显示在 notify_errors 中,进程也会以非零代码退出:通知静默失败是同样的问题,只是在更高一层。
CI 用法
退出码使其成为天然的定时 CI 任务。参见 .github/workflows/restoredrill.yml 了解一个可行示例,或直接在您自己的工作流中使用 action.yml。当人工手动运行时,传递 --trigger manual(和 --triggered-by)。无论哪种方式,证据输出看起来都一样。
限制
- 临时容器模型假设您的数据库能轻松装入运行器上的容器。多太字节(TB)的数据集需要不同的方法(恢复到专用基础设施)。restoredrill 目前不是为此设计的。
pg_dump级别的验证不涉及 PITR(时间点恢复)或 WAL(预写日志)重放。支持这两者的 pgBackRest 支持已列入计划。- 归档完整性预检查仅适用于
pg_dump_custom。纯 SQL 转储没有目录头可供检查,因此对于这种格式没有等效的预检查。这是一个真实的缺口,而非疏忽:pg_dump_sql损坏会在稍后、代价更高的恢复阶段才被发现。 - 同样的缺口适用于从 S3 前缀中选择正确的文件。restoredrill 可以检查
pg_dump_custom候选文件的内容(它查找PGDMP头),但纯 SQL 没有这样的签名。当您将前缀来源与pg_dump_sql结合使用时,backup.s3_object_pattern是必需的。restoredrill 会在配置加载时失败,而不是猜测哪个是真正的备份文件。 - 我们没有在此引用具体的 SOC 2 或 ISO 27001 条款号。报告是围绕控制项的实际要求构建的(根据您策略设定的频率,记录在案且可证明的恢复测试),但错误地引用合规条款比不引用更糟。请查看您自己的控制项描述和审计员,而不是相信我们的条款号。
路线图
- pgBackRest 仓库(PITR 路径验证)
- GCS 备份来源
- MySQL,然后是 restic
- 差异检查(恢复与生产在备份前窗口期的对比)
- 定时模式
构建
go build ./cmd/restoredrill
测试
go test ./...
序列完整性检查有一个 Docker 支持的集成测试(它会启动一个真实的 Postgres 容器)。如果 Docker 不可用,它会干净地跳过。
许可证
相似文章
PostgresBench: 一个可复现的 Postgres 服务基准测试
ClickHouse 发布了 PostgresBench,这是一个公开且可复现的基准测试,用于比较托管式 Postgres 服务,它使用标准的 pgbench 工具,在多个缩放因子下运行类似 TPC-B 的工作负载。
@Docker:Docker Captain @nickjanetakis 发布了一篇关于在 Docker 中备份 PostgreSQL 的精彩指南,涵盖本地存储及……
Docker 分享了 Nick Janetakis 编写的一篇全面指南,介绍如何在 Docker 中备份 PostgreSQL,涵盖本地存储、S3 以及开源工具 Plakar,实现可靠的每日备份和恢复。
pgBackRest 将继续发展
pgBackRest,一款流行的 PostgreSQL 备份工具,宣布将在一系列赞助商(包括 Amazon Web Services、Supabase 等)的支持下继续开发,确保长期可持续性。
用Rust重写的Postgres,现已100%通过Postgres回归测试
pgrust是用Rust重写的PostgreSQL 18.3,通过了所有46k+回归测试,旨在通过Rust和AI辅助使Postgres更易于修改。它是磁盘兼容的,并且可以从现有的Postgres数据目录启动。
Show HN: Streambed – 将Postgres流式传输到S3上的Iceberg,支持Postgres Wire协议
Streambed是一个开源的CDC引擎,它将Postgres的WAL变更流式传输到S3上的Iceberg表,并内置了一个使用DuckDB的查询服务器,该服务器支持Postgres wire协议。