mysql数据库死锁原因分析

一、死锁模拟复现

1、当前自己电脑的mysql版本8.0.22

2、数据库的隔离级别--可重复读(默认隔离级别)

3、自动提交关闭

4、表结构,age为非唯一索引,对下面整个案例非常重要

5、

1、事务A执行更新操作,更新成功

2、事务B执行更新操作,更新成功

3、事务A执行插入操作,陷入阻塞

4、事务B执行插入操作,插入成功,同时事务A的插入由阻塞变为死锁error,事务A的插入操作变成报错

最终结果如下:

我们发现事务一被回滚,事务二执行成功

那既然是死锁,为什么回滚事务A,而不是事务B,是随机的还是有机制在里面?

我们可以理解死锁是数据库对事务的保护机制,一旦发生死锁,MySQL会选择相对小的事务(undo较少的)进行回滚

分析死锁日志

执行命令 :show engine innodb status

二、介绍mysql中的锁

1、mysql中的锁

记录锁

记录锁其实很好理解,对表中的记录加锁,叫做记录锁,简称行锁

例如:

select * from user where id = 1 for update;

UPDATE SET age = 50 WHERE id = 1;

需要注意的是:

  • id 列必须为唯一索引列或主键列,否则上述语句加的锁就会变成临键锁(有关临键锁下面会讲)。
  • 同时查询语句必须为精准匹配(=),不能为 >、<、like等,否则也会退化成临键锁

记录锁是锁住记录,锁住索引记录,而不是真正的数据记录. 如果要锁的列没有索引,进行全表记录加锁

间隙锁(Gap Locks)

幻读例子

间隙锁 是 Innodb 在 RR(可重复读) 隔离级别 下为了解决幻读问题时引入的锁机制。间隙锁是innodb中行锁的一种

请务必牢记:使用间隙锁锁住的是一个区间,而不仅仅是这个区间中的每一条数据

存在以下间隙

(-∞, 1] (1, 4] (4, 7] (7, +supernum]

临键锁(Next-Key Locks)

Next-key锁是记录锁和间隙锁的组合,它指的是加在某条记录以及这条记录前面间隙上的锁。也可以理解为一种特殊的间隙锁。通过临建锁可以解决幻读的问题。每个数据行上的非唯一索引列上都会存在一把临键锁,当某个事务持有该数据行的临键锁时,会锁住一段左开右闭区间的数据。

需要强调的一点是,InnoDB 中行级锁是基于索引实现的

锁总结:

1、当使用唯一索引来等值查询的语句时, 如果这行数据存在,不产生间隙锁,而是记录锁

2、当使用唯一索引来等值查询的语句时, 如果这行数据不存在,会产生间隙锁

3、当使用唯一索引来范围查询的语句时,对于满足查询条件但不存在的数据产生间隙(gap)锁,如果查询存在的记录就会产生记录锁,加在一起就是临键锁(next-key)锁

4、当使用普通索引不管是锁住单条,还是多条记录,都会产生间隙锁;

5、在没有索引上不管是锁住单条,还是多条记录,都会产生表锁

三、死锁的产生的原因

数据库中有两条数据 id主键,age是非唯一主键

补充:

通过事务A和事务B的update语句,我们可以发现其实它们都持有间隙锁(10,20)的这段范围,说明间隙锁范围是可以相互兼容的,意思就是只要你的10不在我(10,+∞)的间隙锁范围内,那就可以产生部分重合的间隙锁,也就是这里的(10,20)

四、实际开发中如何尽量避免死锁发生

1、不同的应用访问同一组表时,应尽量约定以相同的顺序访问各表。对一个表而言,应尽量以固定的顺序存取表中的行

2、在主键等值更新的时候,尽量先查询数据库中是否有没有满足的条件,如果没有就不用更新,存在才更新

3、尽量使用主键更新数据,因为主键是唯一索引,在等值查询能查看到数据的情况下,只会产生记录锁,不会产生间隙锁,这样产生的死锁概率就减少了,如果是范围查询一样产生间隙锁

4、避免长事务,小事务发生锁的冲突的概率较小

5、在允许幻读和不可重复度的情况下,尽量使用RC的隔离级别,避免gap lock造成的死锁,因为产生死锁经常都跟间隙锁有关,间隙锁的存在本身也是在RR隔离级别来解决幻读的一种措施

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值