MySQL的binlog是二进制日志文件,记录了数据库所有数据变更操作,是数据恢复、主从复制的核心依赖。当发生数据误删、误更新等故障时,通过解析binlog可以还原操作前的状态,完成数据恢复。

一、binlog基础与开启配置
binlog有三种模式:STATEMENT记录SQL语句,ROW记录每行数据的变更,MIXED是前两种的混合模式。恢复场景推荐使用ROW模式,能精准还原数据变更细节。
首先检查binlog是否开启,执行以下SQL:
-- 查看binlog开启状态,ON为已开启 SHOW VARIABLES LIKE 'log_bin'; -- 查看当前binlog格式 SHOW VARIABLES LIKE 'binlog_format';
如果未开启,需要修改MySQL配置文件my.cnf(Windows下是my.ini),添加以下配置后重启服务:
[mysqld] # 开启binlog log_bin=mysql-bin # 设置binlog格式为ROW binlog_format=ROW # 设置binlog过期时间,单位天,避免日志占满磁盘 expire_logs_days=7
二、binlog恢复常用工具
恢复binlog主要用到两个官方工具:
mysqlbinlog:用于解析binlog文件,将二进制内容转为可读的SQL语句或者按位置、时间筛选日志mysql:用于执行解析后的SQL语句,完成数据回滚
三、具体恢复场景演示
场景1:恢复整张误删的表
假设我们有一张test库的user表,执行了DROP TABLE user;误删,现在需要恢复。
第一步,查看当前binlog文件列表,找到误操作发生的时间段对应的binlog:
SHOW MASTER LOGS;
第二步,用mysqlbinlog解析对应binlog,筛选误操作前的日志,导出为SQL文件:
# 按时间筛选,导出2024-05-01 10:00:00到2024-05-01 10:30:00之间的日志 mysqlbinlog --start-datetime="2024-05-01 10:00:00" --stop-datetime="2024-05-01 10:30:00" /var/lib/mysql/mysql-bin.000003 > recover.sql
第三步,检查recover.sql内容,确认包含user表的创建和插入语句后,执行恢复:
mysql -u root -p test < recover.sql
场景2:恢复误更新的数据
假设执行了UPDATE user SET age=0 WHERE id<100;,误将100条用户年龄清零,需要回滚。
首先通过binlog找到该更新操作的起始和结束位置:
# 查看binlog内容,找到对应UPDATE操作的位置点 mysqlbinlog --base64-output=DECODE-ROWS -v /var/lib/mysql/mysql-bin.000003 | grep -A 10 -B 10 "UPDATE user"
假设找到起始位置是1234,结束位置是5678,解析这段位置的日志生成回滚SQL:
mysqlbinlog --start-position=1234 --stop-position=5678 --base64-output=DECODE-ROWS -v /var/lib/mysql/mysql-bin.000003 > update_recover.sql
解析后的日志会包含每行数据更新前的值,手动整理成反向UPDATE语句后执行即可恢复数据。
四、恢复注意事项
- 恢复前一定要对当前数据库做全量备份,避免恢复操作失误导致数据二次丢失
- 如果是主从架构,恢复前先断开主从同步,避免恢复操作同步到从库
- binlog文件不要随意删除,建议设置合理的过期时间,保留足够的恢复窗口
- ROW模式下binlog文件体积较大,需要定期清理,同时结合全量备份+增量备份的方案,提升恢复效率
注意:binlog只能恢复数据变更操作,无法恢复未开启binlog之前的数据,因此建议生产环境默认开启binlog,并配合定期全量备份使用。