MySQL主从同步不一致遇到的问题

前言

为了更了解binlog日志的结构,于是使用mysqlBinlog工具查看binlog日志,其中选取的binlog日志量是从主库同步过来的,进行重放,导致本地执行的事务与主库的不一致;

笔者在主从同步的binlog格式使用的是mixed,也就是MySQL会判断同步的sql是否会引起主备不一致,当认为同步的sql不会引发不一致,就使用statement格式,否则使用row格式;

statement格式和row格式

statement格式

binlog记录的是执行的sql语句,主备同步使用该格式会 存在不一致问题,例如主库执行delete from t where a>20 and b<10 limit 10; binlog记录的就是该sql,删除时选取的是a索引,删除了主键为1,2的记录。而同步给备库时,因选取的是b索引,删除的是主键3,4的记录,导致主备不一致;

row格式

记录的不再是sql语句,而是两个Event事件语句,分别是Table_map_event(用于指定操作的表是哪个),Delete_rows_event(用于指定删除的行为,也会记录删除的那一行数据),优点是不会存在主备不一致问题;但更占存储空间;

如下图就是row格式的binlog:
图1

begin和commit之间就是要删除的数据,两个Event事件用了CRC32函数进行计算

使用mysqlbinlog工具查看备库的binlog,并重放sql

如上面所说,binlog配置的是mixed格式,在主库执行了该sql

insert into t values(10,10, now());

然后在备库也能看到该sql生效了,但笔者手动删除了该sql,打算从binlog选定日志量恢复,因binlog是二进制,故使用mysqlbin -vv命令明文输出到另一个文件:
在这里插入图片描述

打开test.binlog文件如下图
在这里插入图片描述
看来MySQL认为该sql不会导致主备不一致,主动选择了statement格式,笔者就从中选择了insert into values(100,1,now())在备库进行重放执行(红圈圈住的语句先按下不表,各位看官请先往下看~)

结果:

笔者手动在主库和备库分别执行的now(),加上主备同步延迟的缘故,主键100这行的时间字段是不一样的,后来翻看主库同步过来的binlog日志,发现begin和commit之间,还有如上图2圈住的一行SET TIMESTAMP,也就就是主库同步过来的时间戳,如果笔者不是手动删除该行数据,然后重新执行却漏执行该时间戳语句,就不会导致主备中该行记录不一致;

解决方案以及建议:

删除从主库同步过来的binlog后,切忌直接将statement格式的语句拷贝出来直接执行,如果误删除后,应该找到最近的那一次全量复制的master_log_pos,以及执行删除语句之前的master_log_pos,然后执行

mysqlbinlog /var/lib/mysql/mysql-bin.000005 --start-position1673097 --stop-position=1673374 -vv > /tmp/mysql.binlog
明文输出到MySQL.binlog文件

最后使用source命令执行mysql.binlog文件即可恢复

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值