并行复制的从库执行FTWRL死锁

本文分析了MySQL从库在并行复制模式下执行FTWRL(Flush Tables With Read Lock)导致的死锁现象。死锁由MDL锁、事务提交顺序和--slave_preserve_commit_order=1选项引起。文中详细解释了死锁的原因、复现步骤及解决方案,并提出了避免死锁的方法,包括设置xtrabackup参数和调整从库配置。
摘要由CSDN通过智能技术生成

最近线上执行备份的从库遇到两个死锁,show full processlist的状态图如下,数据库版本基本是官方5.7.18版本,我们内部做了些许修改,与此次死锁无关。

先说一下结论,图一中162线程是执行innobackup执行的flush tables with read lock;
144是sql线程,并行复制中的Coordinator线程,145/146是并行复制的worker线程,145/146worker线程队列中的事务可以并行执行。
144Coordinator线程分发relaylog中的事务时发现这个事务还不能执行,要等待前面的事务完成提交,所以处于waiting for dependent transaction to commit的状态。145/146线程和备份线程162形成死锁,145线程等待162线程 global read lock 释放,162线程占有MDL::global read lock 全局读锁,申请全局commit lock的时候阻塞等待146线程,146线程占有MDL:: commit lock,因为从库设置slave_preserve_commit_order=1,保证从库binlog提交顺序,而146线程执行事务对应的binlog靠后面,所以等待145的事务提交。最终形成了145->162->146->145的死循环,形成死锁。

同样的图二中,183是备份程序执行的flush tables with read lock;165是sql线程,并行复制的Coordinator线程;166/167是并行复制的worker线程。165Coordinator线程分发的事务还不能执行,进入waiting for dependent transaction to commit的状态,183、166、167三个线程形成死锁,183占有全局读锁,获取全局commit锁的时候进入阻塞,等待167释放事务涉及到表的commit锁;166,167的事务可以并行复制,167占有表级commit锁,但是事务对应的binlog在后面,阻塞等待166先提交进入waiting for preceding transaction to commit的状态;166线程事务执行时提交要获得表级commit锁,但是已经被183占有,所以阻塞等待。这样形成了183->167->166->183的死锁。

三个线程相互形成死锁,在我的经验中还是很少见的,又因为涉及的MDL锁是服务层的锁,死锁检测也不会起作用ÿ

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值