1. 背景
生产环境中常见事故:
- DELETE误执行
- TRUNCATE误操作
- 用户权限表被清空
- 操作日志被删除
- 批量 UPDATE错误
例如:
DELETE FROM sys_user;
DELETE FROM sys_oper_log;
如果没有备份,如何恢复?
MySQL提供的 binlog 可以记录所有数据库变化,通过解析 binlog 可以实现数据恢复。
2. Binlog恢复原理
2.1 Binlog是什么?
MySQL binlog:
Binary Log(二进制日志)
记录:
- INSERT
- UPDATE
- DELETE
- DDL
例如:
执行:
DELETE FROM sys_user WHERE id=1;
binlog记录:
删除了一条记录
原始数据:
id=1
username=test
恢复:
反向生成:
INSERT INTO sys_user VALUES(...);
2.2 Binlog不是回收站
区别:
回收站
删除文件
↓
保存完整文件
↓
恢复
Binlog
记录操作过程
↓
需要反向执行
所以:
binlog恢复 = 反向重放操作。
3. 恢复前检查
3.1 确认binlog开启
进入MySQL:
SHOW VARIABLES LIKE 'log_bin';
结果:
ON
3.2 查看binlog列表
不要直接猜文件。
执行:
SHOW BINARY LOGS;
例如:
binlog.000164
binlog.000165
binlog.000166
3.3 查看当前binlog
SHOW MASTER STATUS;
例如:
File:
binlog.000167
Position:
39521277
4. 安装binlog2sql
4.1 安装依赖
Ubuntu:
apt update
apt install python3 python3-venv git -y
4.2 下载binlog2sql
cd /opt
git clone https://github.com/danfengcao/binlog2sql.git
进入:
cd binlog2sql
4.3 创建虚拟环境
python3 -m venv venv
进入:
source venv/bin/activate
4.4 安装依赖
pip install -r requirements.txt
如果:
pymysqlreplication
异常:
安装:
pip install mysql-replication
5. 定位事故时间
例如:
发现:
2026-08-12 01:24
误删除。
不要直接:
错误:
mysqlbinlog binlog.000166
因为不知道文件。
应该:
根据:
SHOW BINARY LOGS;
判断。
6. 使用mysqlbinlog查看原始数据
6.1 普通查看
mysqlbinlog binlog.000166
只能看到:
Delete_rows
Update_rows
6.2 推荐:-vvv详细解析
注意:
必须:
--no-defaults
否则可能报:
unknown variable 'default-character-set=utf8mb4'
执行:
mysqlbinlog \
--no-defaults \
-vvv \
--start-datetime="2026-08-12 01:00:00" \
--stop-datetime="2026-08-12 08:00:00" \
binlog.000166 \
> /tmp/binlog.sql
输出:
### DELETE FROM sys_oper_log
### WHERE
@1=123
@2='000000'
@3='登录日志'
7. binlog2sql恢复
DELETE恢复
原:
DELETE FROM sys_oper_log
恢复:
INSERT INTO sys_oper_log
执行:
python binlog2sql.py \
-h 127.0.0.1 \
-u root \
-p 'password' \
-d rene-ems \
-t sys_oper_log \
--start-file binlog.000166 \
--start-datetime "2026-08-12 01:00:00" \
--stop-datetime "2026-08-12 02:00:00" \
-B \
> restore.sql
8. 注意:binlog2sql不是绝对可靠
实际生产遇到:
问题1:字段错位
例如:
错误:
create_time='Gazquez Energy'
原因:
binlog2sql解析:
@1
@2
@3
但是当前表结构:
已经变化。
解决:
使用:
mysqlbinlog -vvv
确认:
真实字段:
@1=user_id
@2=tenant_id
@3=dept_id
然后生成恢复SQL。
9. 通用恢复方式(推荐)
不要针对某个表写脚本。
应该做通用恢复工具:
输入:
binlog文件
时间范围
数据库
表名
自动:
mysqlbinlog -vvv
↓
解析DELETE_ROWS
↓
读取表结构
↓
@1映射字段
↓
生成INSERT
支持:
DELETE
恢复:
DELETE
↓
INSERT
UPDATE
恢复:
UPDATE old
↓
UPDATE new
INSERT
恢复:
INSERT
↓
DELETE
10. 恢复前必须备份
不要直接恢复生产。
执行:
mysqldump \
-uroot \
-p \
rene-ems \
> before_restore.sql
11. 恢复流程标准化
生产事故:
发现误操作
↓
记录时间
↓
停止写入
↓
SHOW BINARY LOGS
↓
确定binlog文件
↓
mysqlbinlog -vvv分析
↓
确认影响表
↓
生成恢复SQL
↓
测试库验证
↓
生产恢复
12. 生产环境最佳实践
不要只依赖binlog。
建议:
每日全备
例如:
02:00
mysqldump / xtrabackup
binlog保留
例如:
30天
延迟从库
例如:
主库
|
|
延迟1小时从库
误删:
直接从延迟库恢复。
总结
这次事故最大的经验:
- binlog不是回收站,是操作录像
- binlog2sql不是100%可靠,需要验证字段映射
- mysqlbinlog -vvv 是最终可信来源
- 恢复前必须确认表结构
- 生产环境应该使用全备 + binlog + PITR方案