不能在生产主库上直接演练,因为单机实例无高可用兜底,演练即真实故障;常见事故包括停服未启、路径误删、未停服务覆盖数据目录、InnoDB页损坏、mysqldump漏参数致数据不一致等。

能直接在单机上验证应急预案,但必须避开生产实例——所有操作必须在隔离环境(如克隆实例、测试机或从库)中完成,否则一次 rm -rf /var/lib/mysql 就真成“删库跑路”了。
为什么不能在生产主库上直接演练
单机实例没有高可用兜底,演练即真实故障。常见误操作包括:
- 用
systemctl stop mysql停服务后忘记启动,导致业务中断超 RTO - 执行
rm -rf /var/lib/mysql时路径输错,清空了系统根目录 - 恢复时没停服务就覆盖数据目录,MySQL 启动失败并报
InnoDB: Database page corruption - 用
mysqldump恢复时漏加--single-transaction,导致部分表数据不一致
这些不是理论风险,是真实发生过的高频事故。演练的第一铁律:任何写操作前先确认 hostname 和 ps aux | grep mysql 输出的 datadir 路径。
用 xtrabackup 模拟介质故障的实操要点
这是最贴近硬盘损坏的演练方式,核心是“删文件 + 从物理备份拉起”。关键步骤和易错点:
- 备份前必须确认
innodb_log_file_size与目标实例一致,否则xtrabackup --prepare会卡住或报错log sequence number check failed - 解压备份时若提示
zstd: command not found,需先运行yum install zstd -y(CentOS)或apt install zstd(Ubuntu) -
xtrabackup --prepare必须执行,它完成 crash recovery 模拟,跳过这步直接启动 MySQL 会触发崩溃重启 - 恢复数据目录后,要手动 chown -R mysql:mysql /var/lib/mysql,否则启动报
Can't start server: can't read dir of '/var/lib/mysql/'
命令链示例(路径按实际调整):
systemctl stop mysql rm -rf /var/lib/mysql/* xtrabackup --decompress --target-dir=/backup/full_20260530 --parallel=2 xtrabackup --prepare --target-dir=/backup/full_20260530 xtrabackup --copy-back --target-dir=/backup/full_20260530 chown -R mysql:mysql /var/lib/mysql systemctl start mysql
用 binlog2sql 模拟误删表/行的闪回流程
适用于 DROP TABLE 或 DELETE WHERE 场景,依赖 binlog 格式为 ROW 且未过期。注意:
- 用户需有
REPLICATION SLAVE权限,否则binlog2sql连接时会报Access denied; you need (at least one of) the SUPER or REPLICATION SLAVE privilege(s) - 执行
mysqlbinlog提取日志时,--start-position和--stop-position必须精确到事务边界,否则可能提取出半个事务,导致恢复失败 -
binlog2sql生成的回滚 SQL 中,INSERT 变 DELETE、UPDATE 变反向 UPDATE,但不会自动处理外键约束,执行前需关掉SET FOREIGN_KEY_CHECKS=0 - 如果 binlog 被 purge(如
expire_logs_days=3),而误操作发生在 4 天前,则此路不通——这时只能靠全量备份+后续 binlog 拼接
典型命令:
python binlog2sql/binlog2sql.py \ -h127.0.0.1 -P3306 -uadmin -p'xxx' \ --start-file='mysql-bin.000005' --start-pos=12345 \ --stop-file='mysql-bin.000005' --stop-pos=12999 \ -d mydb -t user_table \ --flashback > rollback.sql
演练后必须验证的三个硬指标
恢复完成≠演练成功。以下检查缺一不可:
- 连接性:
mysql -u root -e "SELECT 1"不报错,且能查到非空表的COUNT(*) - 一致性:对比恢复前后关键表的
SELECT MD5(CONCAT_WS('|', col1, col2)) FROM t GROUP BY id结果集是否一致 - 时序性:若用了 binlog 回滚,检查
SHOW MASTER STATUS的 position 是否已推进到误操作之后,避免二次应用相同日志
最容易被忽略的是第三点——很多人恢复完就以为结束,结果第二天发现新写入的数据又被回滚了一次,根源就是没重置 binlog 位置或没清理临时恢复库的 relay log。


















