binlog2sql不能直接补齐数据,仅能解析binlog生成回滚或重放SQL;能否补漏取决于迁移期间ROW格式binlog是否完整保留、未被过滤或清理,且需精确指定起止文件与位置,重放前须处理主键冲突并分段验证。

binlog2sql 不能直接“补齐”数据,它只负责解析 binlog 并生成回滚/重放 SQL;能否补漏,取决于你是否保留了迁移期间的完整 binlog,以及事务是否被截断或过滤。
确认 binlog 是否完整且可用
迁移期间 MySQL 必须开启 binlog_format=ROW,且未启用 binlog_ignore_db 或 replicate_ignore_table 等过滤规则——否则 binlog2sql 根本看不到被忽略库表的变更。
- 检查
SHOW VARIABLES LIKE 'binlog_format';,必须是ROW;STATEMENT或MIXED下部分语句无法还原出真实行变更 - 运行
SHOW MASTER LOGS;,确认迁移起止时间对应的所有 binlog 文件(如mysql-bin.000123到mysql-bin.000135)仍存在于datadir下,未被expire_logs_days清理 - 用
mysqlbinlog --base64-output=decode-rows -v mysql-bin.000123 | head -30看前几条事件是否含### UPDATE ...行记录,验证 ROW 格式有效
定位遗漏时间段并提取对应 SQL
binlog2sql 不支持模糊时间匹配,必须提供精确的 start-file、start-pos 和 stop-datetime(或 stop-pos),否则容易多抽或漏抽。
- 迁移开始时刻记为
T1,结束时刻记为T2,用mysqlbinlog --start-datetime="T1" --stop-datetime="T2" mysql-bin.*先粗筛文件范围 - 再用 binlog2sql 定位起始 position:例如
python3 binlog2sql.py -h127.0.0.1 -P3306 -uuser -p'pwd' -dmydb -tmytable --start-file='mysql-bin.000123' --start-datetime='2024-05-20 14:00:00' -B,观察输出首条事件的start-pos - 生成可重放 SQL 时,务必加
--no-primary-key(避免主键冲突)和--flashback(生成反向语句)需谨慎——补漏通常要正向重放,即去掉--flashback,加--only-dml
重放 SQL 前必须处理主键/唯一键冲突
目标库已有部分数据,直接执行 INSERT 会报 Duplicate entry 'xxx' for key 'PRIMARY',binlog2sql 本身不解决冲突,得靠外部逻辑绕过或合并。
- 对 INSERT 类型,改写为
INSERT IGNORE或INSERT ... ON DUPLICATE KEY UPDATE:用 sed 批量替换INSERT INTO `mytable`→INSERT IGNORE INTO `mytable` - UPDATE/DELETE 操作依赖原 row image,若目标库该行已被删或字段值变更,重放可能失效——建议先用
SELECT COUNT(*)对比源库快照与目标库在遗漏时段的变更行数,预估风险 - 严禁在生产库直接重放;先导入到临时库或用
mysql --force收集错误,再人工核对失败语句
真正难的不是跑通 binlog2sql,而是确认那几秒的 binlog 有没有被 purged、有没有被 GTID 跳过、有没有跨库 DDL 导致 position 错位——这些细节一错,补出来的数据就是错的。别信“全量重放”,一定要按表、按时间段分段验证结果行数和 checksum。


















