如何处理MySQL死锁问题

分类:编程技术 时间:2024-02-20 15:47 浏览:0 评论:0
0
小编给大家分享一下如何处理MySQL死锁问题。相信大多数人对此还不是很了解,所以分享这篇文章供大家参考。希望您读完这篇文章后能有所收获。咱们一起去吧。查出!

MySQL中的锁兼容性列表一般都有这种关系。如果你第一次读,你会有点困惑,感觉抓不住重点。其实还有一个小技巧。

首先,InnoDB实现了两种类似的行锁,即S(共享锁)和Lock),意向锁是相互兼容的,这句话很重要,根据一半的内容就清楚了对这个想法。另一部分是S和X兼容性。 S锁和X锁的组合是互斥的,除了一种情况例外,即它们都是S锁并且是兼容的。所以按照这个思路,这张图基本不用背就能看懂。

看来S锁的组合很软。从这个场景来看,如果保持兼容的话,死锁的概率应该很低。事实上,在 RR 和 RC 隔离级别下,我们可以逐渐展开并举一反三。

如果两个会话中S锁的组合是互兼容的,那么后续的X锁的组合是互斥的。

那么在两个并发会话的场景下,死锁步骤如下:

mysql> create table dt1(id int unique

查询正常,0 行受影响(0.03 秒)

会话 1:

开始;

在共享模式下选择 *from dt1 锁;--显式共享锁

会话2:

begin;

select *from dt1 lock in share mode; --显式共享锁

会话1:

insert into dt1values(1); --阻塞

会话2:

insert into dt1values(2); --触发死锁

所以上面语句的特点就很明显了,插入的数据是1和 2 分别。看来互补冲突是不可能的。

我们的进度稍微快一点,我们可能很少看到直接声明share模式,但是经常是其他场景触发的。主要原因之一是检查重复数据会打开S锁。这是一个比较特殊的点,需要注意。

按照这个来扩展,可以轻松扩展到3个会话。

会话1只负责插入一条数据,会话2和3也插入一条记录(会话2和3自动提交)。不过由于唯一索引检查的原因,会话2和会话3都会被I开启S锁,由于是兼容的,所以暂时没有影响。如果session 1正常提交,session 2和session 3的检查就会生效,导致数据没有插入,违反了唯一性约束。但是,如果我们反其道而行之,我们可以使用回滚来释放锁,然后sessions 2和3会成功获取S锁,立即获取X锁。具体算法就不讨论了。此时,它们互相阻塞,导致会话3出现死锁,但是会话2的数据插入仍然会成功。

会话 1:

开始;

插入 dt1 值(1);

会话 2:

插入 dt1 值(1);

会话 3:

插入 dt1 值(1);

会话 1:

rollback;

看起来是一个很微妙的小测试,但是却包含了这个大道理。比如按照这个思路,如果下面两条语句都是delete,也会触发死锁。有时我们可以直接使用图例或者通过死锁日志进行推理。我的灵感之一是太极拳。

从锁的角度来理解会好很多。

用一张不太形象的图,左边是会话1中的插入操作,右边是会话2和会话3中的插入操作,都持有S锁,那么就会有同样的原因。原因是事务回滚后,他们的S锁会升级为X锁,导致死锁发生。

按照这个思路,我们可以继续拓展几个场景。例如删除方法。

按照这个思路,可以构造出很多死锁场景。

以上就是《如何处理MySQL死锁问题》文章的全部内容,感谢您的阅读!相信大家都有一定的了解,希望分享的内容对大家有所帮助。如果您想了解更多知识,请关注行业资讯频道!

1. 本站所有资源来源于用户上传或网络,仅作为参考研究使用,如有侵权请邮件联系站长!
2. 本站积分货币获取途径以及用途的解读,想在本站混的好,请务必认真阅读!
3. 本站强烈打击盗版/破解等有损他人权益和违法作为,请各位会员支持正版!
4. 编程技术 > 如何处理MySQL死锁问题

用户评论