mysql死锁问题分析

死锁问题分析

起因

起因是线上报了一个死锁问题,然后我就去查看下死锁的原因。

思路

死锁问题的排查,

**日常工作中,应对各类线上异常都要有我们自己的 SOP (标准作业流程) ** ,这样不仅能够提高自己的处理问题效率,也有助于将好的处理流程推广到团队,提高团队的整体处理异常能力。
所以,面对线上偶发的 MySQL 死锁问题,我的排查处理过程如下:


线上错误日志报警发现死锁异常


查看错误日志的堆栈信息


查看 MySQL 死锁相关的日志


根据 binlog 查看死锁相关事务的执行内容


根据上述信息找出两个相互死锁的事务执行的 SQL 操作,根据本系列介绍的锁相关理论知识,进行分析推断死锁原因


修改业务代码


根据1,2步骤可以找到死锁异常时进行回滚事务的具体业务,也就能够找到该事务执行的 SQL 语句。然后我们需要通过 3,4步骤找到死锁异常时另外一个事务,也就是最终获得锁的事务所执行的 SQL 语句,然后再进行锁冲突相关的分析。
第一二步的线上错误日志和堆栈信息一般比较容易获得,第五步的分析 SQL 锁冲突原因中涉及的锁相关的理论在系列文章中都有介绍,没有了解的同学可以自行去阅读以下。
下面我们就来重点说一下其中的第三四步骤,也就是如何查看死锁日志和 binlog 日志来找到死锁相关的 SQL 操作。


链接:https://juejin.cn/post/6885315880444657678

这个思路是对的,针对比较常见场景的问题,我们要积累自己的标准作业流程,一套下来直接找到问题。

现场

那我就直接去数据查看下死锁信息。

登入mysql,并使用:

show engine innodb status*;*

大概查看到数据就是这样

16877594159841687759415941.png

我们查看死锁日志,其实关键信息主要就是,那个dao的方法,然后事务1拿着什么要什么锁,事务2拿着什么要什么锁。

可以看到事务1和事务2都要同一个锁。

这个

死锁产生的必要条件:

互斥。
请求与保持条件。
不剥夺条件。
循环等待。

从日志上来看事务1和事务2都是取争夺同一行的行锁,和前面概念部分提到的三种案例互相循环争夺锁有点不同,怎么看都无法满足循环等待条件。
因为发生死锁的这段逻辑添加了事务管理,因此去看此段业务代码:

作者:JellyfishMIX
链接:https://juejin.cn/post/6844904138921394190
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

跟这个有点像,既然都争夺一个锁造成了死锁,肯定这个业务代码之前有持有另一个事务要的锁。

然后就去业务代码查看下跟这个表有关的update语句。

然后就查看了这么一段有意思的语句。

其实有两个表,一个parent表,一个son表。

大概业务逻辑就是,更新son表,更新parent表。

16877597341441687759734127.png

16877598040031687759803993.png

但是这里有意思的是,更新子表的时候,也关联主表,然后更新。

我第一个思路就是,update的话,如果有join,是不是把另一个也锁了,即使没更新另一个表。

模拟

那我直接就本地测试了下,用parent表和son表来模拟。

son表

16877599250711687759925046.png

parent表

16877599615781687759961561.png

然后就很简单了,事务1执行1,事务2执行1.然后事务1执行2的时候,直接就死锁了。

很明显,update的话,如果有join,是不是把另一个也锁了,即使没更新另一个表。估计是一个s锁,如果是x锁,估计事务2执行1就直接阻塞了。

所以我们update的时候,别join,直接

用update son set son_name=2 where son.parent_id in (select id from parent where id=1 )这种。

总结

所以死锁的标准流程也整理出来了。

1.线上报错,有死锁。

2.直接去数据库拿死锁信息。主要看是哪个表哪个索引死锁了。

3.查看业务代码。主要查看这个业务流程中那个dao执行操作被锁表的。

4.分析一下死锁原因并改正。

分享

分享一下几个死锁案例。

16877503981041687750397536.png文章来源地址https://uudwc.com/A/0ny4e

原文地址:https://blog.csdn.net/Wzy000001/article/details/131396651

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请联系站长进行投诉反馈,一经查实,立即删除!

上一篇 2023年06月27日 16:28
如何校验 MySQL&Oracle 时间字段合规性?
下一篇 2023年06月27日 16:28