Binlog2SQL 闪回的前提只有两个:MySQL binlog_format=ROW,并且包含误操作时间段的 binlog 文件没有 purge。满足这两条,工具通过 binlog 里的行前/行后镜像生成逆向 SQL——INSERT 变 DELETE、UPDATE 把 SET 和 WHERE 互换、DELETE 重新插回原行——输出可直接执行的回滚脚本。binlog2sql 只解析 DML(INSERT/UPDATE/DELETE),DDL 闪不回去;statement 或 mixed 格式的 binlog 没有完整的行镜像,闪不出正确的逆向语句 [4]。参考资料里的命令和输出都是公开文章里贴过的真实内容。
一条命令跑出回滚 SQL
最直接的用法是这样:连接参数走标准 mysql client 的 -h/-P/-u/-p,定位参数四选一叠用——--start-file 指定 binlog 文件、--start-position / --stop-position 圈位点、--start-datetime / --stop-datetime 圈时间、--table 圈表、--sql-type 限定 INSERT/UPDATE/DELETE [1][4]。不加 --flashback 时输出原始 SQL,便于核对范围;确认匹配到的是误操作那条语句后再加 --flashback 重跑生成逆向 SQL。输出默认打到 stdout,回滚脚本不要直接 pipe 给 mysql 客户端,先重定向到文件人工看一遍:
python binlog2sql.py \
-h127.0.0.1 -P3306 -uflashback -pflashback \
--start-file='mysql-bin.000123' \
--start-datetime='2024-02-02 14:00:00' \
--stop-datetime='2024-02-02 14:10:00' \
--sql-type=DELETE \
-dtest_db -ttarget_table \
--flashback > flashback.sql
执行 flashback.sql 之前先用 head / grep 过一遍文件,确认里头只有预期的那条误操作生成的逆向语句,避免工具误圈到一段提交范围里把正常事务也回滚掉。
先确认能不能闪回:binlog 必须是 ROW 格式
ROW 格式之外的所有场景都闪不回。常见的第一步是登录实例自查:
show variables like 'binlog_format';
show master status;
返回 ROW 才算满足前提之一。还要确认:误操作发生的时段里 binlog_format 没有被中途切换过(中途切换过的 binlog 段 ROW 镜像不完整);对应的 binlog 文件没有被 purge binary logs 清掉,也没有超过 expire_logs_days 自动清理——binlog 一旦没了,binlog2sql 就无能为力,只能靠之前的逻辑备份或者全量备份加增量 binlog 重放 [4]。
按 danfengcao/binlog2sql 官方仓库说明,工具需要在 MySQL 5.6 / 5.7 这种能输出完整 row 镜像的版本上跑,更早的版本官方不保证兼容性,需要自己验证。
安装:Python 2.7 与三个依赖包
参考资料里的安装链是 Python 2.7 + setuptools + PyMySQL + wheel + mysql-replication [1][4]。CentOS 6 默认带的是 Python 2.6,需要先源码编译 2.7,再把 /usr/bin/python 软链替换过去 [4]。编译前先确认依赖:
yum -y install gcc automake autoconf libtool make
yum install zlib-devel
yum install openssl*
yum install -y bzip2*
然后解包、修改 Setup.dist 打开 ssl 和 zlib 模块(不打开后装模块会报错)、编译安装、替换软链 [4]:
tar -zxvf Python-2.7.15.tgz
vi /usr/src/Python-2.7.15/Modules/Setup.dist
# 把 ssl 和 zlib 段前面的 # 去掉
cd /usr/src/Python-2.7.15
./configure --prefix=/usr/local/python2.7
make && make install
ln -s /usr/local/python2.7/bin/python2.7 /usr/bin/python2.7
/usr/bin/python2.7 /usr/bin/python
pip 不存在时通过 get-pip.py 引导安装 [1]:
wget https://bootstrap.pypa.io/get-pip.py
python get-pip.py
接下来克隆工具仓库并装依赖 [1]:
git clone https://github.com/danfengcao/binlog2sql.git
cd binlog2sql
pip install -r requirements.txt
正常情况下会看到类似这样的输出 [1]:
pip 9.0.1 from /usr/lib/python2.7/site-packages (python 2.7)
Requirement already satisfied: PyMySQL==0.7.8 in /usr/lib/python2.7/site-packages (from -r requirements.txt (line 1))
Requirement already satisfied: wheel==0.24.0 in /usr/lib/python2.7/site-packages (from -r requirements.txt (line 2))
Requirement already satisfied: mysql-replication==0.9 in /usr/lib/python2.7/site-packages (from -r requirements.txt (line 3))
工具链是 Python 2 时代写的,Python 3 环境能不能直接用需要按官方仓库的说明自行验证。
给解析用户授权:最小权限集
解析 binlog 需要 replication 相关权限,但 binlog2sql 不写库,最小权限是 SELECT + REPLICATION SLAVE + REPLICATION CLIENT [1]:
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO flashback@'localhost' IDENTIFIED BY 'flashback';
不需要 SUPER 或更高级别的权限。'localhost' 改成 '%' 视实际连接来源而定,本地解析就保留 'localhost'。
解析参数怎么圈定误操作范围
定位时一般先用宽泛的时间窗口跑一次不带 --flashback 的查询,从输出里确认 binlog 文件名、起始位点和结束位点,然后缩小到精确位点或单表再跑带 --flashback 的版本 [1][4]。误操作发生的时间之后越久,binlog 文件名可能换过,要先 show binary logs 列一下当前还存活的 binlog 文件,避免 --start-file 指错。--stop-position 设成误操作 commit 之后的下一个位点,能保证覆盖整条事务不会漏掉行。
几个闪不回去的情况
DDL(CREATE / ALTER / DROP / TRUNCATE 等)闪不了,binlog2sql 只支持 DML [4]。statement 或 mixed 格式闪不了——这两种格式的 binlog 没有完整行前/行后镜像,工具逆向不出等价 SQL。binlog 被 purge 或超过 expire_logs_days 自动清理之后也闪不了,这种情况下工具根本拿不到那段二进制日志。
DELETE 闪回生成的 INSERT 语句需要原表主键存在 [4]。如果原表主键已经被后续事务改写,或者目标表压根没有主键,回滚 SQL 跑起来要么无效要么定位不准确,遇到这种情况需要先人工确认能否补主键或加唯一索引,再决定要不要回滚。
从主库直接解析会对主库带来读 binlog 的开销,生产环境更稳妥的做法是把 binlog 文件 scp 到远端解析,或者在从库上解析 [4],主库只用来给 flashback 用户授权就够。
FAQ
DDL 误操作(drop table、truncate)能闪回吗?
不能。binlog2sql 只支持 DML,DDL 闪回需要依赖其他工具(比如 MyFlash),前提同样是 ROW 格式且对应 binlog 未被清理 [4]。
回滚 SQL 直接执行会触发主从复制吗?
如果回滚 SQL 是在主库上执行的,它会作为新的事务写进主库 binlog 然后复制到从库;如果只是把回滚脚本应用到从库用于核对,那是手动执行的事务,不会写到 binlog 里。具体在哪个节点执行要看业务:核对环境的从库上执行通常更安全,确认无误后再考虑要不要把这笔回滚写到主库。
binlog 已经被 purge 了还能恢复吗?
binlog2sql 救不回来,只能依赖之前做过的逻辑备份或者全量备份 + 增量 binlog 重放。生产环境建议设置合理的 expire_logs_days,并且 binlog 的归档策略要和备份节奏对齐,避免出现”备份里有但 binlog 找不到”的尴尬。
参考来源
[1] NICE源码网《Mysql误操作后利用binlog2sql快速回滚的方法详解》
[4] CSDN《mysql binlog 闪回_MYSQL工具之binlog2sql闪回》











暂无评论内容