【MySQL】MySQL Binlog 日志恢复实战指南:从误删到精准还原

在 MySQL
数据库的日常运维中,误删数据误更新人为操作失误等事故时有发生。一旦发生这类问题,如何快速、准确地恢复数据,是每个
DBA 和开发人员必须掌握的核心技能。

binlog(二进制日志) 正是实现这类数据恢复的关键工具。


一、什么是 binlog?为什么它能用于数据恢复?

✅ binlog 是什么?

binlog 是 MySQL 用来记录所有数据变更操作的日志文件,包括:

  • INSERT
  • UPDATE
  • DELETE

注意:SELECT 不会写入 binlog。

✅ binlog 的作用:

  • 主从复制(Replication)
  • 数据恢复(Recovery)
  • 审计追踪(Audit)
  • CDC(Change Data Capture)

二、binlog 数据恢复的常见场景

场景 说明
误删整张表 DELETE FROM tableDROP TABLE
误更新数据 UPDATE table SET col = 'wrong_value' WHERE ...
误插入错误数据 INSERT INTO table VALUES(...)
事务回滚失败 事务未正确回滚,导致数据异常

三、binlog 恢复的必备条件

条件 说明
binlog_format=ROW 推荐使用,记录行级变更,适合恢复
binlog_row_image=FULL 记录完整行数据,便于还原
expire_logs_days 设置合理 确保 binlog 未被自动清理
binlog 文件未被 PURGE 文件必须存在,才能解析
有恢复工具支持 binlog2sqlmy2sqlmysqlbinlog

四、不同 binlog 配置对恢复的影响对比表

配置项 推荐值 对恢复的影响
binlog_format ROW 推荐,记录行级变化,恢复更准确
binlog_row_image FULL 推荐,记录完整行数据,便于还原
binlog_rows_query_log_events ON 可选,记录原始 SQL,便于定位问题
expire_logs_days 7~14 推荐,避免日志被清理,影响恢复
sync_binlog 1 推荐,每次提交都刷盘,避免数据丢失
binlog_do_db / binlog_ignore_db 按需配置 控制记录哪些库,避免无关日志干扰

五、实战:使用 binlog 恢复误删数据

场景描述:

你执行了如下 SQL,误删了用户表中的部分数据:

DELETE FROM users WHERE create_time < '2025-07-01';

现在需要恢复这部分数据。


步骤一:确认 binlog 文件和位置

使用 SHOW BINARY LOGS 查看当前 binlog 文件列表:

SHOW BINARY LOGS;

输出示例:

+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 | 104857600 |
| mysql-bin.000002 | 104857600 |
| mysql-bin.000003 | 104857600 |
+------------------+-----------+

或者:查看 /etc/my.cnf 配置文件,查看binlog位置

cat /etc/my.cnf

找到对应内容:

#binlog日志
log_bin=/mydata/binlog/mysql-bin

查看目录下内容

[root@localhost binlog]# ll /mydata/binlog
总用量 4466040
-rw-r-----. 1 mysql mysql 1073746300 717 19:32 mysql-bin.002000
-rw-r-----. 1 mysql mysql 1080852579 719 20:11 mysql-bin.002001
-rw-r-----. 1 mysql mysql 1073744846 722 16:30 mysql-bin.002002
-rw-r-----. 1 mysql mysql  835637107 724 17:32 mysql-bin.002003
-rw-r-----. 1 mysql mysql  376266572 725 10:54 mysql-bin.002004
-rw-r-----. 1 mysql mysql        160 724 17:32 mysql-bin.index


步骤二:使用 mysqlbinlog 解析 binlog 文件

# 提取所有
mysqlbinlog --base64-output=DECODE-ROWS -v mysql-bin.000002 > binlog_parsed.sql

# 提取指定位置范围的内容
mysqlbinlog --start-position=123 --stop-position=456 mysql-bin.000001 -v > partial_output.sql

# 提取指定时间范围的内容
mysqlbinlog -v --start-datetime="2025-07-25 10:00:00" --stop-datetime="2025-07-25 12:00:00" mysql-bin.000001 > output_readable.sql
  • -base64-output=DECODE-ROWS:将 ROW 格式解码为可读 SQL
  • v:显示详细信息

小提示

  • 如果你想让输出更清晰,可以加两个 v 参数:

    mysqlbinlog -vv mysql-bin.000001 > output.sq
    

    这样会显示列名而不是 @1, @2。但仅限于MySQL > 8.0binlog_row_metadata 参数为 FULL


步骤三:查找误删操作的时间点或位置

使用 grep 查找 DELETE 操作:

grep -A 20 "DELETE FROM users" binlog_parsed.sql

输出示例:

# at 123456
#250724 10:00:00 server id 100 end_log_pos 123456 CRC32 0x12345678
DELETE FROM users WHERE create_time < '2025-07-01'

记录 startend 位置,如:

  • start_pos = 123400
  • end_pos = 123500

步骤四:使用 binlog2sql 生成回滚语句(推荐)

安装 binlog2sql

git clone https://github.com/danfengcao/binlog2sql.git
cd binlog2sql
pip install -r requirements.txt

执行恢复命令:

python binlog2sql.py --host=127.0.0.1 --port=3306 \
                     --user=root --password=your_password \
                     --start-file=mysql-bin.000002 \
                     --start-pos=123400 \
                     --end-pos=123500 \
                     --only-types='DELETE' \
                     --output=rollback.sql

生成的 rollback.sql 文件内容如下:

INSERT INTO users VALUES (1, 'Tom', '2024-01-01');
INSERT INTO users VALUES (2, 'Jerry', '2024-02-01');
...

若不想使用 binlog2sql,也可以手动组装恢复sql语句

解析出的日志中提取旧值(即删除前的数据),然后手工编写 INSERT 语句。

示例:

# 提取的原始DELETE 语句
# at 377308574
#250725 10:59:45 server id 100  end_log_pos 377308676 CRC32 0xc88b5091 	Delete_rows: table id 18120 flags: STMT_END_F
### DELETE FROM `test1`
### WHERE
###   @1='1' /* VARSTRING(300) meta=300 nullable=0 is_null=0 */
###   @2='张三' /* VARSTRING(300) meta=300 nullable=1 is_null=0 */
###   @3='111' /* VARSTRING(300) meta=300 nullable=1 is_null=0 */

# 手动转换为INSERT 语句
INSERT INTO test1(id, name, phone)VALUES (1, '张三', '111');


步骤五:执行恢复 SQL

导入恢复文件:

mysql -u root -p your_database < rollback.sql

六、一句话总结

binlog 是 MySQL 数据恢复的“最后一道防线”,通过合理配置 + 高效工具(如 binlog2sql),你可以轻松实现 误删、误更新的精准还原,保障数据安全与业务连续性。


七、推荐工具与命令汇总

工具 用途 命令示例
mysqlbinlog 解析 binlog 文件 mysqlbinlog --base64-output=DECODE-ROWS -v mysql-bin.000001
binlog2sql 生成回滚 SQL python binlog2sql.py --start-file=mysql-bin.000001 --only-types='DELETE'
my2sql 支持多种恢复模式 my2sql -logFile=mysql-bin.000001 -sqlTypes="DELETE" -workType recoverBinlog

你可能感兴趣的:(【MySQL】MySQL Binlog 日志恢复实战指南:从误删到精准还原)