mysql gap锁 死锁,通过唯一索引S锁与X锁来了解MySQL死锁套路

在初学者从源码理解MySQL死锁问题中介绍了使用调试 MySQL  源码的方式来查看死锁的过程,这篇文章来讲讲一个常见的案例。

这次我们讲一段唯一索引 S 锁与 X 锁的爱恨情仇

我们来看一个简化过的例子

我们用之前介绍过的源码分析方式,先来看下这两条语句分别加什么锁,然后分析死锁形成的过程。

第一条语句

在调试中得到的结果如下

154U12M6-0.jpg

可以看到这条语句对唯一键 uk_name 加共享锁(S锁),而且成功。

第二条语句

通过唯一键更新数据库字段。

这种情况在之前的文章已经介绍过,会对唯一索引加 X 锁,然后对主键索引加 X 锁

154U15H7-1.jpg

154U13933-2.jpg

这样就可以非常轻松的复现死锁的问题了,步骤如下

1.开启两个 session,分别 begin

2.session1 执行INSERT ignore INTO t1 (name, level) VALUES ('A',0);

3.session2 执行INSERT ignore INTO t1 (name, level) VALUES ('A',0);

4.session1 执行update t1 set level = 1 where name = "A"; 进入等待状态

5.session2 执行update t1 set level = 1 where name = "A";,死锁产生,被回滚,同时事务 1 执行成功

详细的锁状态变化如下

t1

t2

备注

INSERT IGNORE INTO

-

t1成功获得uk的S锁 DB_SUCCESS

-

INSERT IGNORE INTO

t2成功获得uk的S锁 DB_SUCCESS

UPDATE

-

t1尝试获得uk的X锁,但没有成功,处于等待状态 DB_LOCK_WAIT

-

UPDATE

t2尝试获得uk的X锁,发现死锁产生 DB_DEADLOCK

-

Deadlock

t2释放S锁

成功

-

-

死锁日志如下:

来详细看一下这个死锁日志

事务 1 想获取 uk_name 唯一索引上的 X 锁 (非 gap 锁的记录锁)

事务 2 持有uk_name 唯一索引上的 S 锁(共享锁)

事务 2 想获得 uk_name 唯一索引上的 X 锁(非 gap 锁的记录锁)

跟之前理论上推断的结论是一致的

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://juejin.im/post/5ce3cfa46fb9a07ece67a4a9

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值