深色模式
MySQL 恢复演练
摘要:恢复演练是唯一能证明备份有效的手段。本文在独立的演练实例上还原逻辑备份与物理备份,并用 binlog 做时间点恢复(PITR),最后量化 RTO/RPO。
适用环境
bash
# 演练必须在一台独立的测试实例上做,严禁直接覆盖生产库
hostname; mysql -uroot -p -e "SELECT @@server_id, @@datadir;"
# 准备一份备份与对应的 binlog
ls -lh /data/backup/logical/ /data/backup/physical/
mysql -uroot -p -e "SHOW VARIABLES LIKE 'log_bin_basename';"1
2
3
4
5
6
2
3
4
5
6
操作步骤
1. 还原逻辑备份到演练实例
bash
# 新建一个空实例(或临时库)后导入
zcat /data/backup/logical/shopdb_2026-10-09.sql.gz | mysql -uroot -p1
2
2
大文件导入可临时关闭双写与 binlog 加快速度(仅演练实例):
sql
SET GLOBAL foreign_key_checks=0;
SET sql_log_bin=0;1
2
2
2. 用 binlog 做时间点恢复(PITR)
bash
# 从备份文件头部找到备份时刻的 binlog 位置
zcat /data/backup/logical/shopdb_2026-10-09.sql.gz | head -n 30 | grep -i 'CHANGE MASTER'
# 回放从备份点到误操作前一刻的 binlog
mysqlbinlog --start-position=157 --stop-datetime='2026-10-09 14:59:59' \
/data/mysql/data/binlog.0000{12,13,14} | mysql -uroot -p1
2
3
4
5
6
2
3
4
5
6
危险
mysqlbinlog ... | mysql 会真实改写数据,务必先在演练实例上跑通并确认 --stop-datetime 早于误操作时间;对生产库执行前必须备份当前状态。
3. 还原物理备份(XtraBackup)
bash
sudo systemctl stop mysqld
sudo mv /data/mysql/data /data/mysql/data_bak_$(date +%s) # 保留现场
xtrabackup --copy-back --target-dir=/data/backup/physical/full_2026-10-09
sudo chown -R mysql:mysql /data/mysql/data
sudo systemctl start mysqld1
2
3
4
5
6
2
3
4
5
6
4. 校验数据一致性
sql
-- 抽查关键表行数与最新记录
SELECT COUNT(*) FROM shopdb.orders;
SELECT MAX(created_at) FROM shopdb.orders;
-- 检查表是否可用
CHECK TABLE shopdb.orders;1
2
3
4
5
6
2
3
4
5
6
5. 记录演练结果
bash
# 记录耗时,即为本次 RTO
date +%s > /tmp/restore_start # 开始
date +%s > /tmp/restore_end # 结束
echo "RTO(秒)=$(( $(cat /tmp/restore_end) - $(cat /tmp/restore_start) ))"1
2
3
4
2
3
4
演练报告至少包含:备份来源、恢复耗时(RTO)、丢失数据窗口(RPO)、校验结果、发现问题、改进项。
验证
- [ ] 演练实例能正常启动,
SELECT COUNT(*)与预期一致 - [ ] 关键业务表的最大时间戳落在预期窗口内
- [ ] binlog 回放后误操作的数据未被带入
- [ ] RTO/RPO 已记录并满足业务目标
常见坑
WARNING
恢复到新实例后记得清理:应用连接串、复制配置、以及演练期间临时关闭的 sql_log_bin 等参数。
WARNING
备份与 binlog 不匹配(binlog 已被 PURGE 或 expire_logs_days 清理)会导致无法做 PITR;保留期应大于备份周期。
DANGER
--copy-back 要求 datadir 必须为空,非空目录会报错并中止;不要把备份直接拷到正在运行的实例目录上。