团队为一次机房迁移准备了两年的冷备方案:每日备份文件上传到对象存储,脚本每月验一次文件是否完整(能解压、能读到表结构)。迁移当天真的要用时才发现,恢复一次需要十四个小时——而业务给的可接受停机窗口是四小时。
冷备的核心问题不是"有没有备份",而是恢复需要多久,以及这个时长是不是业务能接受的。前者可以测,后者必须先问清楚。两者之间往往差着一个数量级。
1. 冷备的三个指标
| 指标 | 含义 | 谁决定 |
|---|---|---|
| RPO | 能容忍丢多少数据(恢复点) | 业务 |
| RTO | 能容忍停多久(恢复时长) | 业务 |
| 实际恢复时长 | 真跑一遍要多久 | 只能实测 |
三者的对齐要在方案设计阶段完成,而不是在事故现场。一个可用的顺序是:先问业务"能接受丢多少、停多久",再拿这两个数倒推方案档位,最后用实测的恢复时长回填验证。反过来(先定方案再套指标)几乎总会得到"方案看起来合理、指标没人对过"的结果。
前两个是业务给的约束,第三个是技术事实。三者不一致时,方案不成立——而这三种数字经常从来没有被放在一起对齐过。常见情况是备份策略按"每天一次"设计(RPO 24 小时),而业务以为"数据一条都不会丢"。
2. 恢复时长由什么决定
| 组成 | 典型量级 | 可压缩性 |
|---|---|---|
| 拉取备份文件 | 分钟到小时(取决于体积与带宽) | 中(预置副本、就近存储) |
| 解压与导入 | 小时级(取决于数据量) | 低(受 IO 限制) |
| 索引重建 | 小时级 | 中(可延后) |
| 校验与比对 | 小时级 | 中(抽样) |
| 切换与验证 | 分钟到小时 | 低(受流程限制) |
还有一个常被忽略的成本项:人员与流程。恢复往往不是一个人能完成的动作——需要权限、需要业务方确认数据截止点、需要切换到备用入口。这些协调动作在演练中通常被跳过,而在真实事故里它们可能占掉总时长的一大半。
第二项是主要成本,而它几乎不可压缩:导入一亿行要花的时间,大致等于数据量除以 IO 吞吐。所以缩短恢复时长的真正手段不是优化脚本,而是减少要恢复的数据量——增量备份、分层恢复、只恢复关键表。
// 先量出来,再谈优化:恢复流程的阶段耗时必须可观测
restore_start=$(date +%s)
fetch_backup; echo "fetch $(( $(date +%s) - restore_start ))s"
import_dump; echo "import $(( $(date +%s) - restore_start ))s"
rebuild_indexes; echo "index $(( $(date +%s) - restore_start ))s"
verify_counts; echo "verify $(( $(date +%s) - restore_start ))s"
// 只有分段耗时,才知道该压哪一段;只测总时长等于没测
3. 三种恢复粒度的取舍
| 粒度 | 数据量 | 恢复时长 | 适用 |
|---|---|---|---|
| 全量恢复 | 全部 | 最长 | 灾难、整库损坏 |
| 单库/单表恢复 | 部分 | 中 | 局部误删、单表损坏 |
| 行级恢复 | 极少 | 短(但需要额外工具) | 误操作、误更新 |
三种粒度的成本差别不是线性的:全量恢复的时长随数据量线性增长,而单表与行级恢复的时长几乎与总量无关。所以随数据增长,粗粒度恢复越来越不可行,细粒度恢复的价值越来越高。
第三项最容易被忽略,而它恰恰是最常发生的场景:一条错误的 UPDATE 少了 WHERE,影响三万行。这种情况不需要恢复整个库,只需要把这三万行还原。没有行级恢复能力时,团队只能用全量恢复去解决一个小问题,代价从分钟级变成小时级。
-- 行级恢复的两种实现:从备份表或从解析的 binlog
-- 方式一:备份中带上"恢复窗口"内的表快照
CREATE TABLE orders_restore_20261110 LIKE orders;
INSERT INTO orders_restore_20261110 SELECT * FROM orders WHERE updated_at < '2026-11-10 02:00:00';
-- 方式二:用 binlog 反向解析出被误改的行(需要 binlog 保留与工具)
-- 关键:这两种能力都要在事故发生前就验证过
冷备的另一个实际约束是备份与版本的绑定。恢复出来的数据要能被当前代码正确读取,就需要知道"这份备份对应哪个版本的 schema"。没有这层记录时,恢复后第一件事往往是排查为什么应用启动失败。
// 备份元数据:五项,缺一项都可能让恢复失败
backup_id: 2026-11-09T02:00Z
schema_version: V20261105_03
app_version: 2.14.3
row_counts: {orders: 12000000, users: 800000}
checksum: sha256:9f2c...
4. 验证的四个层次
| 层次 | 做法 | 能发现什么 |
|---|---|---|
| 完整性 | 文件能解压、校验和匹配 | 备份损坏 |
| 可读性 | 能导入到临时库、表结构对 | 格式或版本不兼容 |
| 业务可用性 | 抽查关键表行数与业务核对 | 数据缺失或截断 |
| 真实恢复 | 完整跑一次恢复并计时 | RTO 是否成立 |
四个层次之间存在一个跳跃:前三层验证的是"备份文件没问题",第四层验证的是"恢复流程没问题"。文件与流程是两件不同的东西,前者可以自动化检查,后者必须有人在隔离环境里真的走一遍。
前三个层次大多数团队都做过,第四个很少做——而只有第四个能回答"能不能用"。
// 真实恢复演练:在隔离环境跑完整流程并记录时长
bin/restore-drill \
--backup s3://bucket/2026-11-09.sql.gz \
--target db-drill.internal \
--verify "orders:12000000,users:800000" \
--report drill-2026-11.md
// 输出的恢复时长必须与业务给的 RTO 对比,而不是只看"成功"
5. 冷备与热备的分界
| 方案 | 切换时长 | 成本 | 适用 RTO |
|---|---|---|---|
| 冷备(仅备份文件) | 小时级 | 最低 | 天级 |
| 温备(定期恢复的备用环境) | 十分钟到小时 | 中 | 小时级 |
| 热备(实时复制) | 分钟级 | 高 | 分钟级 |
| 多活 | 秒级 | 最高 | 秒级 |
判断的关键是RTO 与成本的对应关系。要求分钟级 RTO 却只做冷备,方案本身就不成立;反之,业务能接受一天停机却做了多活,是过度投入。
四档方案的选择可以用一个简单的问题定:如果现在机房不可用,多久之后业务能继续。答案如果是"一天",冷备就够;如果是"一小时",必须温备;"几分钟"意味着热备或双活。技术方案跟着这个答案走,而不是跟着预算走。
多数系统的真实需求落在"温备"这一档,而它恰恰是最少被选择的——因为它需要"定期把一个环境真的恢复起来",这件事既有成本又要持续维护。
6. 排错:五种"备了但用不了"
| 现象 | 成因 | 处理方向 |
|---|---|---|
| 备份文件无法解压 | 传输中断或压缩工具版本不符 | 校验和 + 定期抽样解压 |
| 恢复后应用报错 | 表结构与当前代码不匹配 | 备份与版本绑定记录 |
| 恢复完成但数据不对 | 备份时点晚于业务预期 | 明确 RPO 并写入文档 |
| 恢复很慢超出窗口 | 从未实测,只有估算 | 做一次计时演练 |
| 需要恢复时权限不足 | 存储权限只在个别人手里 | 恢复权限至少两人可用 |
排错时还可以先确认一件更基础的事:最近一次成功恢复是什么时候。答不出来,说明这台机器的恢复流程从未被验证,所有关于"能恢复"的判断都是推断。
第五项是组织问题,但它在事故现场最致命:备份在,脚本在,没人有权限从对象存储拉取。恢复权限的可用性与备份的存在性同等重要。
恢复流程本身也需要版本管理。不少团队的恢复脚本是三年前写的,与当前的库版本、路径约定、权限模型都已不匹配——它躺在文档里,看起来像一份能力,实际是一份过期说明。
// 恢复脚本的自检:每次演练前先确认它还能跑通到"只差导入"这一步
bin/restore.sh --dry-run --check-access --check-tools
// 输出应包含:存储可读、解压工具在位、目标库可连、磁盘余量足够
// dry-run 不通过时立刻修脚本,而不是在事故时才发现
7. 边界:什么情况不必做完整演练
| 场景 | 为什么 | 做法 |
|---|---|---|
| 数据可完全重建(缓存、派生数据) | 无恢复价值 | 不备份,直接重建 |
| 无状态服务 | 恢复即重新部署 | 不涉及数据恢复 |
| 试验环境 | 数据无价值 | 只做完整性检查 |
| 已有热备且切换演练过 | 冷备只是兜底 | 降低演练频率 |
判断口径一句话:这套数据丢了,业务会损失什么。答不出损失,就不必为它做恢复演练;答得出,就必须有实测的恢复时长和可用的恢复权限。
8. 自测
- RPO、RTO 与实际恢复时长分别由谁决定?三者不一致时方案为什么不成立?
- 恢复时长的主要组成部分中,哪一项几乎不可压缩?缩短总时长该从哪下手?
- 为什么行级恢复能力最常被忽略却最常用?没有它会发生什么?
- 验证的四个层次中,哪一层才能回答"能不能用"?前三层各能发现什么?
- 要求分钟级 RTO 却只做冷备,问题出在哪一步判断?温备为什么最少被选?
- 为什么"恢复权限"与"备份是否存在"同等重要?