我是靠谱客的博主 香蕉香氛,最近开发中收集的这篇文章主要介绍MySQL死锁,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

死锁原因:隔离级别、GAP锁、索引的顺序及业务逻辑

  • 尽量使用较低的隔离级别,比如如果发生了间隙锁,你可以把会话或者事务的事务隔离级别更改为 RC(read committed)级别来避免,但此时需要把 binlog_format 设置成 row 或者 mixed 格式

  • 精心设计索引,并尽量使用索引访问数据,使加锁更精确,从而减少锁冲突的机会;

  • 选择合理的事务大小,小事务发生锁冲突的几率也更小;

  • 给记录集显示加锁时,最好一次性请求足够级别的锁。比如要修改数据的话,最好直接申请排他锁,而不是先申请共享锁,修改时再请求排他锁,这样容易产生死锁;

  • 不同的程序访问一组表时,应尽量约定以相同的顺序访问各表,对一个表而言,尽可能以固定的顺序存取表中的行。这样可以大大减少死锁的机会;

一、不同表相同记录行锁冲突

这种情况很好理解,事务A和事务B操作两张表,但出现循环等待锁情况

二、相同表记录行锁冲突

这种情况比较常见,之前遇到两个job在执行数据批量更新时,jobA处理的的id列表为[1,2,3,4],而job处理的id列表为[8,9,10,4,2],这样就造成了死锁。

三、gap锁冲突

innodb在RR级别下,如下的情况也会产生死锁,比较隐晦。不清楚的同学可以自行根据上节的gap锁原理分析下。

四、不同索引锁冲突

这种情况比较隐晦,事务A在执行时,除了在二级索引加锁外,还会在聚簇索引上加锁,在聚簇索引上加锁的顺序是[1,4,2,3,5],而事务B执行时,只在聚簇索引上加锁,加锁顺序是[1,2,3,4,5],这样就造成了死锁的可能性。

五、死锁检测

wait-for graph原理

我们怎么知道上图中四辆车是死锁的?他们相互等待对方的资源,而且形成环路!我们将每辆车看为一个节点,当节点1需要等待节点2的资源时,就生成一条有向边指向节点2,最后形成一个有向图。我们只要检测这个有向图是否出现环路即可,出现环路就是死锁!这就是wait-for graph算法。

六、死锁检测命令

#1、查看正在进行中的事务
SELECT *
FROM information_schema.INNODB_TRX
#2、查看正在锁的事务
SELECT *
FROM INFORMATION_SCHEMA.INNODB_LOCKS;
#3、查看等待锁的事务
SELECT *
FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
#4、查询是否锁表
SHOW OPEN TABLES
WHERE In_use > 0;
#在发生死锁时,这几种方式都可以查询到和当前死锁相关的信息。
#5、查看最近死锁的日志
SHOW ENGINE innodb STATUS

最后

以上就是香蕉香氛为你收集整理的MySQL死锁的全部内容,希望文章能够帮你解决MySQL死锁所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(87)

评论列表共有 0 条评论

立即
投稿
返回
顶部