首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >一次真实的MySQL容灾演练,带你走通数据恢复的核心技能

一次真实的MySQL容灾演练,带你走通数据恢复的核心技能

作者头像
俊才
发布2026-03-04 14:34:31
发布2026-03-04 14:34:31
1390
举报
文章被收录于专栏:数据库干货铺数据库干货铺

当数据库突然崩溃,或者误删了关键数据,你的应急预案真的能打吗?

深夜,报警铃声骤响,监控大屏上一片刺眼的红色——核心数据库服务异常,业务系统陷入停滞。这不是演习,但胜似演习的日常训练,决定了你在真正危机来临时的反应速度与成败。之前我们写了数据库备份及my2sql工具的介绍,可以参考历史文章:

深入面试场景:为什么XtraBackup比mysqldump更适合生产环境?

解析MySQL Binlog的利器:my2sql 使用指南

近日,我们完成了一次真实的MySQL数据库容灾演练,不玩虚的,直接在生产从库上模拟了两种最让人头疼的场景。现在,带你全程复盘。

一、 演练目标:不求炫技,但求实用

本次演练聚焦两个最核心的目标:

  • 验证有效性:当数据库彻底“躺平”(例如文件坏块,文件被删除等),手里的备份文件能不能真的救急?
  • 发现隐患:在安全的演练环境中,主动给流程“挑刺”,找出文档、工具或步骤中的任何瑕疵

我们选择在从库环境进行所有操作,确保线上业务稳如泰山,这也是演练的第一原则。

演练的故障场景:

  • 场景1:模拟数据库坏块或崩溃场景,需从备份文件中进行备份恢复的场景
  • 场景2: 表中数据被误删除,通过恢复工具进行恢复

二、 实战回顾第一幕:数据库“毁灭”与重生

我们模拟了最彻底的故障——数据库文件损坏或丢失。这意味着,不能靠重启解决,必须从备份中“复活”整个实例。

1. 关闭数据库并删除数据库文件(重命名方式)

2. 拷贝备份文件

3. 进行解压、回放日志等

代码语言:javascript
复制


初次解压后结果如下:

因备份的时候进行过压缩,因此需要再次解压(decompress):

代码语言:javascript
复制
/usr/local/xtrabackup/bin/xtrabackup --decompress --target-dir=../rec --parallel=2

注意: 解压需要安装zstd工具,如果没安装需提前安装。

代码语言:javascript
复制
yum install zstd -y

再次解压后得到了非压缩的文件,如下:

恢复前准备工作:回滚、前滚等

代码语言:javascript
复制
/usr/local/xtrabackup/bin/xtrabackup --prepare --target-dir=../rec

4. 恢复数据库并启动

创建数据好数据库相关目录及配置文件,从已经准备好了的备份文件恢复至目标目录:

代码语言:javascript
复制
[root@vbox rec]# mkdir -p /data/mysql/mysql3307/{data,etc,logs,tmp}
[root@vbox rec]# cp /data/mysql/mysql3307.bak/etc/my.cnf   /data/mysql/mysql3307/etc/
[root@vbox rec]# ll -h /data/mysql/mysql3307

将恢复好的数据恢复至目标目录(move-back或者copy-back方式)

代码语言:javascript
复制
 /usr/local/xtrabackup/bin/xtrabackup --defaults-file=/data/mysql/mysql3307/etc/my.cnf  --move-back  --target-dir=../rec 

此操作不会拷贝zstd压缩的文件,操作后,原先的恢复目录里还剩压缩的文件,如下:

恢复后的目标目录的数据目录下:

继续添加日志文件

代码语言:javascript
复制
touch /data/mysql/mysql3307/logs/mysqld.log

修改目录权限

代码语言:javascript
复制
chown -R mysql:mysql /data/mysql/mysql3307

启动数据库

代码语言:javascript
复制
/usr/local/mysql8.4/bin/mysqld_safe --defaults-file=/data/mysql/mysql3307/etc/my.cnf &

5. 重建主从复制

重置备份信息

代码语言:javascript
复制
reset replica
根据备份文件的binlog信息(GTID)修改gtid值
代码语言:javascript
复制
mysql> SET GLOBAL gtid_purged = '801dab9b-f13d-11f0-bfbb-080027fd316d:1-16393';
Query OK, 0 rows affected (0.00 sec)

修改复制信息

代码语言:javascript
复制
CHANGE REPLICATION SOURCE TO SOURCE_HOST='192.168.56.102',SOURCE_PORT=3306,SOURCE_USER='repl',SOURCE_PASSWORD='XXXXXXX',SOURCE_AUTO_POSITION=1,Get_Source_public_key=1;

启动复制

代码语言:javascript
复制
start replica;

查看复制状态

代码语言:javascript
复制
show replica status\G

至此,恢复完毕

三、 模拟表数据被误删除,需通过恢复工具进行恢复的场景

1 模拟误删除情况

模拟忘记添加where条件,导致全表删除的情况:

2. 生成恢复数据SQL

确定发送异常的时间点及对应的binlog文件

使用my2sql工具生成回滚sql,回滚的SQL存放在rollback_sql

代码语言:javascript
复制
mkdir /data/backup/rollback_sql

生成回滚sql

代码语言:javascript
复制
./my2sql -user xxx -password xxxxx -host 192.168.56.102 -port 3307 -mode repl -work-type rollback -start-file mysql-bin.000021 -start-datetime "2026-02-08 20:40:00" -stop-datetime "2026-02-08 20:43:00" -databases testdb -tables t1 -output-dir /data/backup/rollback_sql

生成的SQL文件如下:

对应的回滚恢复sql如下:

3. 恢复数据

执行恢复操作

代码语言:javascript
复制
source  /data/backup/rollback_sql/rollback.21.sql;

查看恢复后结果

至此被误删除的数据已恢复

四、 演练收获:不止于成功,更在于发现结果令人欣慰:

  • 场景一:成功从物理备份完整恢复数据库并重建复制,验证了全量备份的有效性。
  • 场景二:成功通过解析binlog精准恢复误删数据,验证了快速回滚的能力

但更有价值的,是发现的问题:

  • 预案可以更“傻瓜”:一些关键步骤(如xtrabackup --prepare的参数)在预案中描述可以更详尽,降低关键时刻的操作门槛和误操作风险
  • 工具手册待补齐:像my2sql这样强大的工具,其标准使用命令和常见问题,应该作为附录集成到应急预案中,避免临时查找

五、 结语

容灾演练不是为了证明系统永不故障,而是为了确保在故障发生时,我们心中有图、手中有术、恢复有路。

每一次成功的演练,都是对技术债务的一次偿还,也是对团队信心的一次充值。在数据安全这条路上,再充分的准备都不为过。你,准备好下一次演练了吗?

你是否在MySQL运维中遇到过其他有趣的问题?欢迎在留言区分享你的经历和解决方案!

关注微信公众号「数据库干货铺」,获取更多数据库运维干货。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-02-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据库干货铺 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 二、 实战回顾第一幕:数据库“毁灭”与重生
    • 1. 关闭数据库并删除数据库文件(重命名方式)
    • 2. 拷贝备份文件
    • 3. 进行解压、回放日志等
    • 4. 恢复数据库并启动
    • 5. 重建主从复制
    • 三、 模拟表数据被误删除,需通过恢复工具进行恢复的场景
      • 1 模拟误删除情况
      • 2. 生成恢复数据SQL
      • 3. 恢复数据
  • 四、 演练收获:不止于成功,更在于发现结果令人欣慰:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档