
作者:胡呈清
爱可生 DBA 团队成员,擅长故障分析、性能优化,个人博客:https://www.jianshu.com/u/a95ec11f67a8,欢迎讨论。
本文来源:原创投稿
*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
MySQL8.0 的死锁日志可以看到事务1持有的锁信息了:

这对我们分析死锁无疑是个很好的帮助,而在 MySQL5.7 是没有这个信息的,一直饱受诟病:

但是这在某些情况下可能会产生一些误会,比如事务1持有锁和等待锁是同一个锁:

必须不是bug,我们来复现这一死锁场景:
##设置RC隔离级别
CREATE TABLE `t2` (
`c1` int(11) NOT NULL,
`c2` int(11) DEFAULT NULL,
PRIMARY KEY (`c1`),
UNIQUE KEY `c2` (`c2`));
insert into t2 values(1,1),(5,4),(20,20);

死锁逻辑:
lock_mode X locks rec but not gap;lock mode S waiting;lock_mode X locks gap before rec insert intention waiting。session1、session2 互相等待,所以形成死锁。session1 等待获取的锁 S Lock 阻塞了 session2 将要获取的锁,这在 MySQL8.0 中就会显示成 session1 持有的锁,同时也是 session1 等待的锁。就是这样。