在 MySQL 数据库的日常运维中,误删数据、误更新、人为操作失误等事故时有发生。一旦发生这类问题,如何快速、准确地恢复数据,是每个 DBA 和开发人员必须掌握的核心技能。
而 binlog(二进制日志) 正是实现这类数据恢复的关键工具。
🧠 一、什么是 binlog?为什么它能用于数据恢复?
✅ binlog 是什么?
binlog 是 MySQL 用来记录所有数据变更操作的日志文件,包括:
INSERTUPDATEDELETE
📌 注意:SELECT 不会写入 binlog。
✅ binlog 的作用:
- 主从复制(Replication)
- 数据恢复(Recovery)
- 审计追踪(Audit)
- CDC(Change Data Capture)
🔍 二、binlog 数据恢复的常见场景
| 场景 | 说明 |
|---|---|
| 误删整张表 | DELETE FROM table 或 DROP 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 | 文件必须存在,才能解析 |
| 有恢复工具支持 | 如 binlog2sql、my2sql、mysqlbinlog |
📊 四、不同 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 7月 17 19:32 mysql-bin.002000
-rw-r-----. 1 mysql mysql 1080852579 7月 19 20:11 mysql-bin.002001
-rw-r-----. 1 mysql mysql 1073744846 7月 22 16:30 mysql-bin.002002
-rw-r-----. 1 mysql mysql 835637107 7月 24 17:32 mysql-bin.002003
-rw-r-----. 1 mysql mysql 376266572 7月 25 10:54 mysql-bin.002004
-rw-r-----. 1 mysql mysql 160 7月 24 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 格式解码为可读 SQLv:显示详细信息
🔍 小提示
-
如果你想让输出更清晰,可以加两个
v参数:mysqlbinlog -vv mysql-bin.000001 > output.sq这样会显示列名而不是
@1,@2。但仅限于MySQL > 8.0 且binlog_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'
记录 start 和 end 位置,如:
start_pos = 123400end_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 |