当数据库突然崩溃,或者误删了关键数据,你的应急预案真的能打吗?
深夜,报警铃声骤响,监控大屏上一片刺眼的红色——核心数据库服务异常,业务系统陷入停滞。这不是演习,但胜似演习的日常训练,决定了你在真正危机来临时的反应速度与成败。之前我们写了数据库备份及my2sql工具的介绍,可以参考历史文章:
深入面试场景:为什么XtraBackup比mysqldump更适合生产环境?
近日,我们完成了一次真实的MySQL数据库容灾演练,不玩虚的,直接在生产从库上模拟了两种最让人头疼的场景。现在,带你全程复盘。
一、 演练目标:不求炫技,但求实用
本次演练聚焦两个最核心的目标:
我们选择在从库环境进行所有操作,确保线上业务稳如泰山,这也是演练的第一原则。
演练的故障场景:
我们模拟了最彻底的故障——数据库文件损坏或丢失。这意味着,不能靠重启解决,必须从备份中“复活”整个实例。



初次解压后结果如下:

因备份的时候进行过压缩,因此需要再次解压(decompress):
/usr/local/xtrabackup/bin/xtrabackup --decompress --target-dir=../rec --parallel=2

注意: 解压需要安装zstd工具,如果没安装需提前安装。
yum install zstd -y再次解压后得到了非压缩的文件,如下:

恢复前准备工作:回滚、前滚等
/usr/local/xtrabackup/bin/xtrabackup --prepare --target-dir=../rec
创建数据好数据库相关目录及配置文件,从已经准备好了的备份文件恢复至目标目录:
[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方式)
/usr/local/xtrabackup/bin/xtrabackup --defaults-file=/data/mysql/mysql3307/etc/my.cnf --move-back --target-dir=../rec 
此操作不会拷贝zstd压缩的文件,操作后,原先的恢复目录里还剩压缩的文件,如下:

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

继续添加日志文件
touch /data/mysql/mysql3307/logs/mysqld.log
修改目录权限
chown -R mysql:mysql /data/mysql/mysql3307
启动数据库
/usr/local/mysql8.4/bin/mysqld_safe --defaults-file=/data/mysql/mysql3307/etc/my.cnf &
重置备份信息
reset replica
根据备份文件的binlog信息(GTID)修改gtid值

mysql> SET GLOBAL gtid_purged = '801dab9b-f13d-11f0-bfbb-080027fd316d:1-16393';
Query OK, 0 rows affected (0.00 sec)
修改复制信息
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;
启动复制
start replica;查看复制状态
show replica status\G
至此,恢复完毕
模拟忘记添加where条件,导致全表删除的情况:

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

使用my2sql工具生成回滚sql,回滚的SQL存放在rollback_sql
mkdir /data/backup/rollback_sql生成回滚sql
./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如下:

执行恢复操作
source /data/backup/rollback_sql/rollback.21.sql;查看恢复后结果

至此被误删除的数据已恢复
但更有价值的,是发现的问题:
五、 结语
容灾演练不是为了证明系统永不故障,而是为了确保在故障发生时,我们心中有图、手中有术、恢复有路。
每一次成功的演练,都是对技术债务的一次偿还,也是对团队信心的一次充值。在数据安全这条路上,再充分的准备都不为过。你,准备好下一次演练了吗?
你是否在MySQL运维中遇到过其他有趣的问题?欢迎在留言区分享你的经历和解决方案!
关注微信公众号「数据库干货铺」,获取更多数据库运维干货。