剖析死锁的成因

前两篇内容做了这么多铺垫,有了Delete操作的3种加锁逻辑、InnoDB的死锁预防策略等准备知识之后,再回过头来分析本文最初提到的死锁问题,就会手到拈来,事半而功倍

前两篇内容做了这么多铺垫,有了Delete操作的3种加锁逻辑、InnoDB的死锁预防策略等准备知识之后,再回过头来分析本文最初提到的死锁问题,就会手到拈来,事半而功倍。

首先,假设dltask中只有一条记录:(1, ‘a’, ‘b’, ‘c’, ‘data’)。三个并发事务,同时执行以下的这条SQL:

delete from dltask where a=’a’ and b=’b’ and c=’c’;

并且产生了以下的并发执行逻辑,就会产生死锁:

attachments-2020-11-shd8jQix5fb63ae708399.png

上面分析的这个并发流程,完整展现了死锁日志中的死锁产生的原因。其实,根据事务1步骤6,与事务0步骤3/4之间的顺序不同,死锁日志中还有可能产生另外一种情况,那就是事务1等待的锁模式为记录上的X锁 + No Gap锁(lock_mode X locks rec but not gap waiting)。这第二种情况,也是”润洁”同学给出的死锁用例中,使用MySQL 5.6.15版本测试出来的死锁产生的原因。

此类死锁,产生的几个前提:

Delete操作,针对的是唯一索引上的等值查询的删除;(范围下的删除,也会产生死锁,但是死锁的场景,跟本文分析的场景,有所不同)

至少有3个(或以上)的并发删除操作;

并发删除操作,有可能删除到同一条记录,并且保证删除的记录一定存在;

事务的隔离级别设置为Repeatable Read,同时未设置innodb_locks_unsafe_for_binlog参数(此参数默认为FALSE);(Read Committed隔离级别,由于不会加Gap锁,不会有next key,因此也不会产生死锁)

使用的是InnoDB存储引擎;(废话!MyISAM引擎根本就没有行锁)attachments-2020-11-EheDs8Tn5fb63b0a1206f.png


  • 发表于 2020-11-19 17:29
  • 阅读 ( 22 )

0 条评论

请先 登录 后评论
热爱技术的小仓鼠
热爱技术的小仓鼠

145 篇文章

作家榜 »

  1. NX小编 1233 文章
  2. 58沈剑 311 文章
  3. 热爱技术的小仓鼠 145 文章
  4. 奈学教育 139 文章
  5. 李希沅 | 奈学教育 41 文章
  6. 江帅帅 | 奈学教育 29 文章
  7. 林淮川 | 奈学教育 12 文章
  8. 邱鹏超 3 文章