RDS for MySQL备份与恢复:原理、步骤与五个常见坑
数据库出问题时,最先被问到的通常是“有没有备份,能恢复到几点”。华为云 RDS for MySQL 默认就开着自动备份,很多人因此没再细看。可真要恢复时才会碰到各种问题:恢复到当前实例会覆盖什么,Binlog 能往回追多久,跨区域备份为什么没有昨天的数据。本文按官方文档梳理备份的原理和操作,最后讲五个最常见的坑。
一、备份原理:全量 + Binlog 增量
RDS for MySQL 的备份是实例级的,不能只备份某个库。备份文件压缩后存放在对象存储服务(OBS)上,不占用实例本身购买的磁盘空间。
- 全量备份:按备份策略里的时间段和周期执行,分为自动备份和手动备份两种。
- 增量备份(Binlog 备份):系统每 5 分钟或累积一定数据量时,自动备份上一次备份之后新增的 Binlog,不需要用户配置。
两者组合起来,可以提供两种恢复能力:
- 按备份文件恢复:把实例恢复到某个全量备份结束时的状态。
- 恢复到指定时间点(PITR):先找到离目标时间点最近的全量备份做全量恢复,再重放 Binlog 到指定时间点。
RDS for MySQL 默认开启 Binlog,格式为 ROW。可以先确认一下实例状态:
-- 确认 Binlog 已开启、格式为 ROW
SHOW VARIABLES LIKE 'log_bin';
SHOW VARIABLES LIKE 'binlog_format';
-- 查看本地 Binlog 文件列表(注意与 OBS 上的 Binlog 备份区分)
SHOW BINARY LOGS;
二、自动备份:策略与保留天数
自动备份在实例创建时默认开启,出于安全考虑不能关闭。可调整的参数有三项:
| 参数 | 说明 |
|---|---|
| 保留天数 | 同时作用于全量自动备份和 Binlog 备份,默认 7 天,可设 1~732 天;需要更长可提交工单,最长 10 年 |
| 备份时间段 | 指备份的开始时间,不是完成时间;建议选业务低峰 |
| 备份周期 | 按周设置,至少选一天 |
操作入口:进入实例详情页,打开左侧“备份恢复”,在右上角选择“修改备份策略 > 同区域备份策略”。
注意,备份时间段按 UTC 保存。通过 API 设置时,start_time 也是 UTC,例如 "19:00-20:00" 对应北京时间凌晨 3 点到 4 点。
为了保证保留期内都能恢复,系统在清理过期备份时,会额外保留最近一个已超期的全量备份,以及从该全备开始前 24 小时到现在的 Binlog 备份。所以实际占用的空间通常比“保留天数”算出来的要多一点。
三、手动备份:大变更前的“存档点”
做 DDL、批量订正数据或者升级之前,建议先打一个手动备份。手动备份由用户触发,会一直保留,直到手动删除,删除实例后也不会被清理。
在实例列表的操作列中选择“更多 > 创建备份”,或在实例的“备份恢复”页单击“创建备份”即可。备份名称需要 4~64 个字符,以字母开头。
手动备份有几点需要留意:
- 实例正在执行 DDL,或拿不到备份锁时,备份会重试,重试后仍不满足则失败;
- 备份期间会加元数据锁,可能阻塞 DDL 或造成复制延迟;
- 表数量上限 50 万,表太多、内存又紧张时备份容易失败。
如果只想把某几张表导出到别处,可以用 mysqldump 做一份逻辑备份,作为补充:
mysqldump -h <RDS内网地址> -P 3306 -u root -p \
--single-transaction --set-gtid-purged=OFF \
--routines --triggers --events --hex-blob \
--databases order_db > order_db_$(date +%F).sql
四、恢复:新实例、当前实例与已有实例
无论是按备份文件恢复还是 PITR,都有三种目标可选:
- 恢复到新实例:按所选数据新建一个独立实例,原实例不受影响。新实例的引擎和版本与原实例相同,磁盘不能小于原实例,并且作为新实例单独计费。
- 恢复到当前实例:覆盖数据和密码,恢复期间实例不可用。
- 恢复到已有实例:同样会覆盖目标实例,版本和存储空间也有要求。
PITR 的入口在“备份恢复”页右上角,选择“恢复到指定时间点”,可以做实例级恢复,也可以做库表级恢复。库表级恢复先在临时实例上回放,再把数据写回原实例,结果是带时间戳后缀的新库表,不覆盖原表,业务也不中断,适合“误删了一张表”的场景。但它不恢复视图、存储过程和触发器,也不支持中文库表名。
PITR 能恢复的时间范围是:保留期内最早一个全量备份之后的任意时间点。官方给出的实例级 PITR 平均速率约为 80MB/s,可以据此估算恢复耗时。通过 API 恢复到新实例时,restore_time 填的是毫秒级 UTC 时间戳:
# 把北京时间转换成 restore_time 需要的毫秒时间戳
date -d '2026-10-26 09:58:00 +0800' +%s%3N
恢复完成后,先核对数据再切流量:
SELECT COUNT(*), MAX(updated_at) FROM order_db.orders;
CHECKSUM TABLE order_db.orders;
五、跨区域备份与费用
跨区域备份会把全量备份(也可以连同 Binlog 备份)异步复制到另一个区域,用于整个区域出故障时的异地恢复。这项功能需要提交工单申请,只支持部分区域组合,保留时长可设 1~1825 天。
费用方面:RDS 免费提供与实例购买存储空间等量的备份空间,例如买了 200GB 磁盘,备份总量超过 200GB 才开始收费,超出部分按需计费。跨区域备份则另外按目标区域的存储容量和跨区域流量计费。具体单价请以官方价格页为准。
六、五个常见坑
坑一:把“恢复到当前实例”当成撤销。 这个操作会覆盖全部数据和密码,误删之后到恢复之间写入的新数据也会被一起冲掉。建议优先恢复到新实例或用库表级恢复,核对之后再回写。另外,本地 SSD 盘实例不支持恢复到当前实例;MySQL 8.0 做过小版本升级后,升级前的备份也不能恢复到当前实例。
坑二:缩短保留天数,或者直接删实例。 缩短保留天数会立即作用于已有的自动备份。自动备份的生命周期和实例相同,删除实例时会一起被删。下线实例之前,记得先打一个手动备份。
坑三:执行 reset master。 文档明确要求在实例生命周期内不要执行它,否则 PITR 会出现异常。备份中存在大事务时,恢复到新实例也可能失败。平时应避免超大事务,并控制表的数量:
SELECT COUNT(*) AS table_cnt FROM information_schema.tables
WHERE table_schema NOT IN ('mysql','sys','information_schema','performance_schema');
坑四:以为开了跨区域备份就万事大吉。 跨区域备份只对开启后新产生的备份生效。开启日志备份后,要等下一次全备复制完成才能做 PITR。加密备份不支持跨区域。这项功能本身不保证 SLA,对时效要求高的场景,官方建议改用 DRS 做异地同步。另外,删除实例不会删除目标区域的备份,需要手动关闭策略才会清理。
坑五:遗留的手动备份一直在扣费。 实例删除后,赠送的备份空间随之取消,留下的手动备份会按占用量按需计费。账号冻结期间同样没有免费额度。建议定期在“备份管理”里清点手动备份。
总结
- 备份是实例级的:全量备份加上每 5 分钟一次的 Binlog 备份,构成 PITR 的基础;
- 自动备份不能关闭,保留期 1~732 天,时间段按 UTC 保存;
- 大变更前先打手动备份,它会一直保留,删除实例后也还在;
- 恢复时优先选新实例或库表级恢复,慎用“恢复到当前实例”;
- 永远不要执行
reset master,同时控制大事务和表的数量; - 跨区域备份需工单申请、只对新备份生效,也不保证 SLA;
- 免费备份空间与购买的磁盘等量,定期清理不再需要的手动备份;
- 备份是否可用,要靠定期演练来验证。
- 点赞
- 收藏
- 关注作者
评论(0)