mysql slave 线程 简书_MySQL:从库明明回放了某事务但是 SQL 线程报错

接到客户反馈:主库执行 drop了一张表,从库没有对应的表,就报错了:'Unknown table '%-.100s' error code=1051'

提供了 show slave status 结果,确实是报错在 drop table 那里。

MySQL 版本:5.6.21

现场排查过程:

1. show slave status 确认错误位置:

binlog file name:binlog.056429

position:682219

gtid_excuted_set: 636d6b66-xxxx:1-769622000:769622017:769622035-769622037:xxxx:xxx-xxx (有很多空洞,原因是开启了并行复制)

2. 解析主库 binlog.056429,发现在报错 position:682219 确实是 drop table ,但是这个位置的事务的 gtid 为 636d6b66-xxxx:769621968 ,与从库 gtid_excuted_set 不匹配:意味这从库已经回放过 636d6b66-xxxx:769621968 这个事务,但是sql 线程却报错在这个事务

3. 解析从库当前的 binlog,发现确实已经回放了 636d6b66-xxxx:769621968 事务。为什么 sql 线程会报错在一个已经回放过的事务?

4. 重启复制,报同样的报错

5. 相信科学,再看一遍错误日志,重新思考下面这个信息。启动复制时,初始化 slave sql thread,位置确实是 binlog.056429:682219

753fb3751dfb

6. 问题出在哪?初始化 slave sql thread 时,读取的是 sql thread 回放的位置:slave_relay_log_info,保存在 mysql.slave_relay_log_info 表中,查看结果确实是 binlog.056429:682219,与 error log 中一致:

753fb3751dfb

7. slave_relay_log_info 表应该在每次事务提交时更新(当事务涉及表为 innodb 表时),但是这里显然没有更新。所以当启动复制时,slave sql thread 会从错误的位置开始回放事务,但是这个事务对应的表已经删除了,所以报错

8. 直接原因已经定位到,reset slave 清空复制位点信息、relay log,再 start slave,问题解决

疑问

虽然这里解决了问题,但是为什么 slave_relay_log_info 表中的复制位点信息没有更新呢?对此我进行了一些资料查找,设计了一些测试,得到了更细致的认识,但最终还是没能解决这个疑问。可以看另外两篇文章:

《slave_relay_log_info 表认知的一些展开》https://www.jianshu.com/p/6506bf3c883e

《关于 slave_relay_log_info 表的一些测试》https://www.jianshu.com/p/65c8caf01dd8

提示

之前一直对 master_auto_position 比较模糊,潜意识里一直觉得 GTID 取代了 position,排查错误时解析 binlog 找的是 gtid 位置,实际上还是得靠 position,这才是复制的真实位置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值