死锁案例 r囧r小猫 2023-01-05 04:00 206阅读 0赞 * # 死锁成因 # 了解了innodb锁的基本原理后,下面分析下死锁的成因。如前面所说,死锁一般是事务相互等待对方资源,最后形成环路造成的。下面简单讲下造成相互等待最后形成环路的例子。 ### 不同表相同记录行锁冲突 ### 这种情况很好理解,事务A和事务B操作两张表,但出现循环等待锁情况。 ![format_png][] 图10 ### 相同表记录行锁冲突 ### 这种情况比较常见,之前遇到两个job在执行数据批量更新时,jobA处理的的id列表为\[1,2,3,4\],而job处理的id列表为\[8,9,10,4,2\],这样就造成了死锁。 ![format_png 1][] 图11 ### 不同索引锁冲突 ### 这种情况比较隐晦,事务A在执行时,除了在二级索引加锁外,还会在聚簇索引上加锁,在聚簇索引上加锁的顺序是\[1,4,2,3,5\],而事务B执行时,只在聚簇索引上加锁,加锁顺序是\[1,2,3,4,5\],这样就造成了死锁的可能性。 ![format_png 2][] 图12 ### gap锁冲突 ### innodb在RR级别下,如下的情况也会产生死锁,比较隐晦。不清楚的同学可以自行根据上节的gap锁原理分析下。 ![format_png 3][] 图13 ## 如何尽可能避免死锁 ## 1)以固定的顺序访问表和行。比如对第2节两个job批量更新的情形,简单方法是对id列表先排序,后执行,这样就避免了交叉等待锁的情形;又比如对于3.1节的情形,将两个事务的sql顺序调整为一致,也能避免死锁。 2)大事务拆小。大事务更倾向于死锁,如果业务允许,将大事务拆小。 3)在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁概率。 4)降低隔离级别。如果业务允许,将隔离级别调低也是较好的选择,比如将隔离级别从RR调整为RC,可以避免掉很多因为gap锁造成的死锁。 5)为表添加合理的索引。可以看到如果不走索引将会为表的每一行记录添加上锁,死锁的概率大大增大。 ## 5 如何定位死锁成因 ## 下面以本文开头的死锁案例为例,讲下如何排查死锁成因。 1)通过应用业务日志定位到问题代码,找到相应的事务对应的sql; 因为死锁被检测到后会回滚,这些信息都会以异常反应在应用的业务日志中,通过这些日志我们可以定位到相应的代码,并把事务的sql给梳理出来。 <table> <tbody> <tr> <td> <p>1</p> <p>2</p> <p>3</p> <p>4</p> <p>5</p> </td> <td> <p><code>start tran</code></p> <p><code>1 deleteHeartCheckDOByToken</code></p> <p><code>2 updateSessionUser</code></p> <p><code>...</code></p> <p><code>commit</code></p> </td> </tr> </tbody> </table> 此外,我们根据日志回滚的信息发现在检测出死锁时这个事务被回滚。 2)确定数据库隔离级别。 执行select @@global.tx\_isolation,可以确定数据库的隔离级别,我们数据库的隔离级别是RC,这样可以很大概率排除gap锁造成死锁的嫌疑; 3)找DBA执行下show InnoDB STATUS看看最近死锁的日志。 这个步骤非常关键。通过DBA的帮忙,我们可以有更为详细的死锁信息。通过此详细日志一看就能发现,与之前事务相冲突的事务结构如下: <table> <tbody> <tr> <td> <p>1</p> <p>2</p> <p>3</p> <p>4</p> <p>5</p> </td> <td> <p><code>start tran</code></p> <p><code>1 updateSessionUser</code></p> <p><code>2 deleteHeartCheckDOByToken</code></p> <p><code>...</code></p> <p><code>commit</code></p> </td> </tr> </tbody> </table> 这不就是图10描述的死锁嘛! [format_png]: /images/20221119/da1c0140e6ca4dacab1dd825c76b9e43.png [format_png 1]: /images/20221119/58ab425542cc4aa499a9734ad01c0451.png [format_png 2]: /images/20221119/01eccf0ab6eb4f3588ee9902ac8dc1a8.png [format_png 3]: /images/20221119/c7d2490474804066833200d5845f9ab9.png
相关 死锁案例 死锁成因 了解了innodb锁的基本原理后,下面分析下死锁的成因。如前面所说,死锁一般是事务相互等待对方资源,最后形成环路造成的。下面简单讲下造成相互等待 r囧r小猫/ 2023年01月05日 04:00/ 0 赞/ 207 阅读
相关 死锁案例 七 一、前言 死锁,其实是一个很有意思也很有挑战的技术问题,大概每个 DBA 和部分开发同学都会在工作过程中遇见 。关于死锁我会持续写一个系列的案例分析,希望能够对想了解死锁 「爱情、让人受尽委屈。」/ 2022年12月13日 01:29/ 0 赞/ 156 阅读
相关 死锁案例 六 一、前言 死锁,其实是一个很有意思也很有挑战的技术问题,大概每个 DBA 和部分开发同学都会在工作过程中遇见 。关于死锁我会持续写一个系列的案例分析,希望能够对想了解死锁 Myth丶恋晨/ 2022年12月13日 01:29/ 0 赞/ 185 阅读
相关 死锁案例六 来源:公众号yangyidba 一、前言 死锁,其实是一个很有意思也很有挑战的技术问题,大概每个 DBA 和部分开发同学都会在工作过程中遇见 。关于死 迷南。/ 2022年12月10日 11:26/ 0 赞/ 169 阅读
相关 死锁案例五 来源:公众号yangyidba 一、前言 死锁其实是一个很有意思也很有挑战的技术问题,大概每个 DBA 和部分开发朋友都会在工作过程中遇见。关 朱雀/ 2022年12月08日 05:07/ 0 赞/ 185 阅读
相关 死锁案例 五 一、前言 死锁其实是一个很有意思也很有挑战的技术问题,大概每个 DBA 和部分开发朋友都会在工作过程中遇见。关于死锁我会持续写一个系列的案例分析,希望能够对想了解死锁的朋 Love The Way You Lie/ 2022年12月08日 01:44/ 0 赞/ 195 阅读
相关 死锁案例 二 一 前言 死锁,其实是一个很有意思也很有挑战的技术问题,大概每个DBA都会在工作过程中遇见。关于死锁我会持续写一个系列的案例分析,希望能够对想了解死锁的朋友有所帮助 深碍√TFBOYSˉ_/ 2022年12月08日 01:44/ 0 赞/ 125 阅读
相关 死锁案例三 来源:公众号yangyidba 一、前言 死锁其实是一个很有意思也很有挑战的技术问题,大概每个 DBA 和部分开发朋友都会在工作过程中遇见。关于死锁我 超、凢脫俗/ 2022年12月02日 04:28/ 0 赞/ 205 阅读
相关 死锁案例一 来源:公众号yangyidba 一、前言 死锁,其实是一个很有意思也很有挑战的技术问题,大概每个 DBA 和部分开发同学都会在工作过程中遇见 。关于死锁我会持 电玩女神/ 2022年11月29日 12:42/ 0 赞/ 204 阅读
相关 死锁案例分享 在实际开发中,死锁的案例可遇不可求。有些人可能开发了5年甚至10年,也没有在生产环境下遇到过死锁案例。如果真的遇到了死锁问题,你应该庆幸,先不要担心能不能解决,毫无疑问的... 小灰灰/ 2020年05月14日 15:52/ 0 赞/ 844 阅读
还没有评论,来说两句吧...