锁日志输出参考八怪大神
版本:Percona MySQL 5.7.22
对于锁的学习我做了一些输出详细参考如下:
https://github.com/gaopengcarl/percona-server-locks-detail-5.7.22.git
其中有readme
问题列表
- 事务1拿到X锁,事务2申请X锁,事务1在申请S锁会阻塞么
- replace into为什么死锁
接下来我们做两个实验,验证问题
表结构
CREATE TABLE `tmp` (
`id` int(11) NOT NULL,
`code` int(11) DEFAULT NULL,
`name` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `code` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
表数据
实验1
事务隔离级别RR
操作过程
事务1|事务2
-|-
update tmp set name = name - 1 where code = 5;|-
-|select * from tmp where code = 5 for update;
select * from tmp where code = 5 lock in share mode;|--
锁获取日志
结论
问题1得到验证,事务1是可以申请到S锁的
实验2
在进行实验2前,首先得说明replace into语句,针对已经存在的记录,语句可以拆分为delete+insert,下面我们假设两个事务同时执行这个语句
事务隔离级别RR
- 操作过程
事务1 | 事务2 |
---|---|
delete from tmp where code = 5; | - |
- | delete from tmp where code = 5; |
insert into tmp values(10,5,5); | ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction |
-
锁获取日志
死锁分析、按照上面执行sql的顺序
事务1 | 事务2 |
---|---|
LOCK_X LOCK_NOT_GAP | - |
- | LOCK_X-LOCK_NEXT_KEY 阻塞 |
LOCK_S-LOCK_NEXT_KEY | 死锁回滚 |
事务1拿到X记录锁,
事务2检测到冲突,获取X|NK锁,被事务1阻塞
事务1检测到冲突,申请获取S|NK,被事务2阻塞
结论
replace into死锁,如上分析,并不是之前理解的那样,事务拿到记录X锁,获取S锁还需要在等待,而是直接就能拿到