专栏首页杨建荣的学习笔记一个MySQL死锁问题的反思

一个MySQL死锁问题的反思

很早之前我写过几篇关于MySQL死锁的分析,比如

换个角度看待MySQL死锁的一点简单认识

MySQL死锁的两个小案例

MySQL在RR隔离级别下的unique失效和死锁模拟

两个死锁的实例 (r5笔记第90天)

这样分析一个死锁问题

但是感觉不过瘾,而且分析的都是一些特定的场景,好像还缺少一些举一反三的感觉,所以今天就补上这一波。

MySQL里的锁兼容列表大体是这样的关系,如果第一次看会有些晕,感觉抓不住重点,其实有一点小技巧。

首先InnoDB实现了两种类似的行锁,即S(共享锁)和X(排他锁),而InnoDB层面的表级意向锁有IS(意向共享锁)和IX9意向排他锁),意向锁之间是互相兼容的,这句话很重要,按照这个思路里面一半的内容就明确了。而另外一部分则是S和X的兼容性。带着S锁和X锁的组合都是互相排斥,只有一类场景例外,那就是都是S锁,是兼容的。所以这个图按照这个思路几乎不用记就能基本理解了。

看起来S锁的组合是很柔和的,从这种场景来看保持兼容,那么出死锁的概率应该很低吧,其实在RR,RC隔离级别下我们可以逐步扩展然后举一反三。

如果S锁的组合在两个会话中是互相兼容,那么接下来的X锁的组合就是互相排斥的。

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

mysql> create table dt1 (id int unique

Query OK, 0 rows affected (0.03 sec)

会话1:

begin;

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

会话2:

begin;

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

会话1:

insert into dt1 values(1); --阻塞

会话2:

insert into dt1 values(2); --触发死锁

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

我们进度稍快一些,我们可能很少看到直接声明share mode的方式,但是有很多时候由其他的场景会触发,其中的一个主要原因就在于对于duplicate数据的检查会开启S锁。这是比较特别的一点,需要注意。

按照这一点来扩展,很容易就可以扩展到3个会话中。

会话1只是负责插入一条数据,会话2,3也紧接着插入一条记录(会话2,3自动提交),但是因为唯一性索引的检查,会导致会话2和会话3都开启了S锁,因为兼容,所以暂时还没影响。如果会话1正常提交,会话2,3的检查会生效,导致数据插入不了,违反唯一性约束,但是我们反其道而行,就可以用一个rollback来释放锁,紧接着会话2和会话3都会获得S锁成功,紧接着获得X锁,细节算法就不说了。这个时候互相阻塞,导致会话3产生死锁,会话2的数据插入依然会成功。

会话1:

begin;

insert into dt1 values(1);

会话2:

insert into dt1 values(1);

会话3:

insert into dt1 values(1);

会话1:

rollback;

看起来很精巧的小测试,但是里面蕴含这大道理,比如按照这个思路,如果后面的两个语句都是delete,也会触发死锁。有的时候我们可以正面来图例,或者通过死锁日志来推理。给我的一个启发是太极。

放在锁的角度来理解就会好很多。

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

按照这个思路,我们可以继续扩展出几个场景。比如delete的方式。

按照这样的思路,可以构建出很多的死锁场景来。

本文分享自微信公众号 - 杨建荣的学习笔记(jianrong-notes),作者:r14笔记第39天

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-11-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 换个角度看待MySQL死锁的一点简单认识

    在MySQL锁机制的部分,一般都会提到一个所模式的兼容矩阵,看起来比较枯燥,而且不大容易理解。 ? 那我们可以换个角度,取出其中的一个冲突场景,比如下面的场景...

    jeanron100
  • 关于ora-02391问题的总结(r6笔记第40天)

    关于ORA问题的分析和解决其实是一个很好的学习思路,抓住一个每一个ORA错误,然后进一步分析一些原因,总结,总会有不一样的收获,还是那句话,任何问题背后都是有原...

    jeanron100
  • 运维平台中的业务树梳理思考

    今天和同事聊了下业务树建设的事情,也收获了不少的建议和想法。从最开始要建设应用管理的时候,自己就在犯疑惑,这个应用管理该怎么做。从我接触的很多业务来说,这个业务...

    jeanron100
  • pandas画图的几个技巧

    我们经常会用pandas处理数据,处理完之后,很多时候会画个图看看。但是pandas默认的曲线就只有十种颜色,如果我们要绘制的数据过多,就会出现颜色重复。其实很...

    钱塘小甲子
  • 前端基础-ES5继承

    实现方式:在子类构造函数中,调用父类构造函数的(call, apply, bind)方法,使用子类构造函数的this去冒充父类构造函数的this。

    cwl_java
  • 13招神技 让你在数据科学和数据分析工作中脱颖而出

    我有幸在很早参与了一个大数据科学项目,我非常喜欢其中的工作,甚至我意识到我的努力可以增加一些公司的价值。 然而,可悲的是,只有不到30%的数据科学项目最终实施了...

    CDA数据分析师
  • 观点 | 博士离开学术界算不算失败?牛津大学博士有话要说

    作为一名即将毕业的博士生,我发现自己正被黯淡的就业前景和学术前途所困。这种缺乏希望的未来可能会增加学生的压力,导致他们变得焦虑甚至抑郁(T. M. Evans ...

    机器之心
  • python中如何退出多层循环

     2、使用函数配合return关键字 实现跳出循环(在函数内部只要执行完return语句 则直接退出函数)

    py3study
  • Pc微信转账记录Ocr识别备注 金额

    cxt084
  • ACTF2020新生赛-Include

    访问?file=php://filter/read/convert.base64-encode/resource=flag.php

扫码关注云+社区

领取腾讯云代金券