记一次特殊的Mysql死锁场景

在MySQL 5.7.27版本中,一个RR隔离级别的从节点出现SQL线程中断和死锁现象。通过日志分析,发现死锁由insert into select和update语句引起。在两个并发session中模拟该情况,确认了死锁原因。解决方案是将抽数session的隔离级别更改为READ COMMITTED,以避免类似死锁。

记一次特殊的Mysql死锁场景

题外话

mysql版本为5.7.27,隔离级别为RR。

一、故障现象

Mysql的一个从节点,数据未同步,检查发现SQL线程中断,然后在error.log查到如下信息,而且还比较多

| master_prdxxx001 |         1 |      NULL | OFF           | xxxxdab9-49ed-11e8-b5ee-005056axxx:122598975 |              1213 | Worker 1 failed executing transaction 'e3bedab9-49ed-11e8-b5ee-005056a1a8ba:122598975' at master log mysql-bin.000405, end_log_pos 185432301; Deadlock found when trying to get lock; try restarting transaction | 2020-06-14 01:38:49  |

可以看到是发生了死锁,很奇怪从节点没有写业务,怎么会有死锁产生?
带着问题,写了一个脚本去抓取sql语句,发现了一些可疑的insert和update语句:
a_tmp为临时使用的表,a为需同步主节点数据的表。

insert into a_tmp select * from a;
update a_tmp set xx=.... where ...;

怀疑是上述类型的语句造成的,故进行了模拟测试:

1、创建同样的表tb01和tb02,插入两条数据到tb01。
在这里插入图片描述
在这里插入图片描述
2、模拟update和insert语句加锁
session 1:
在这里插入图片描述
session 2:
在这里插入图片描述
回到session 1:
在这里插入图片描述
此时发生了锁等待,说明tb01的id=2这条记录被其他事务锁住了

回到session 2:
在这里插入图片描述
死锁发生,故可以判断此为发生死锁的原因

二、故障处理

使用innodb引擎,在正常情况下,读和写是不会相互阻塞的,但这里的特殊情况是:
1、不是简单的select xxx from xxx;而是insert into xxx select xxx from xxx;
2、隔离级别为RR;

由于此mysql实例为边缘系统,和相关人员沟通后,了解到有场景是直接在从节点抽数,造成了此情况。

解决方案:把抽数相关的session改为RC级别,不再出现死锁情况。
set session transaction isolation level READ COMMITTED;

三、总结

此次只是遇到了一个特殊的场景,但也提醒了我们,隔离级别不同,相应的锁粒度是不一样的。

哎哟,不错噢! - - - - - - 欢迎指出有误的地方以及补充更好的方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值