首页 / Mysql / 通过唯一索引S锁与X锁来了解MySQL死锁套路

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

在初学者从源码理解MySQL死锁问题中介绍了使用调试 MySQL  源码的方式来查看死锁的过程,这篇文章来讲讲一个常见的案例。
这次我们讲一段唯一索引 S 锁与 X 锁的爱恨情仇

在初学者从源码理解MySQL死锁问题中介绍了使用调试 MySQL  源码的方式来查看死锁的过程,这篇文章来讲讲一个常见的案例。
这次我们讲一段唯一索引 S 锁与 X 锁的爱恨情仇

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

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

第一条语句

在调试中得到的结果如下

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

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

第二条语句

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

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

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

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

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

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://www.54gcs.cn/sql/mysql/5205.html

helwo作者

上一篇
下一篇

为您推荐

发表评论

联系我们

联系我们

在线咨询: QQ交谈

邮箱: web@5vo.cn

工作时间:周一至周五,9:00-17:30,节假日休息
关注微信
微信扫一扫关注我们

微信扫一扫关注我们

手机访问
手机扫一扫打开网站

手机扫一扫打开网站

返回顶部
跳至工具栏