innodb next-key lock引发的死锁
innodb的事务隔离级别是可重复读级别且innodb_locks_unsafe_for_binlog禁用,也就是说允许next-key lock
CREATE TABLE `LockTest` (
`order_id` varchar(20) NOT NULL,
`id` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`),
KEY `idx_order_id` (`order_id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8
| 事务1 | 事务2 |
|
begin delete from LockTest where order_id = 'D20' |
|
|
begin delete from LockTest where order_id = 'D19' |
|
|
insert into LockTest (order_id) values ('D20') |
|
|
insert into LockTest (order_id) values ('D19') |
|
| commit |
commit |
事务1 执行到insert语句会block住,事务2执行insert语句会提示死锁错误
错误码: 1213
Deadlock found when trying to get lock; try restarting transaction
Execution Time : 00:00:00:000
Transfer Time : 00:00:00:000
Total Time : 00:00:00:000
show engine innodb status 显示死锁信息
------------------------
LATEST DETECTED DEADLOCK
------------------------
2014-04-30 15:01:55 a233b90
*** (1) TRANSACTION:
TRANSACTION 596042, ACTIVE 7 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 320, 2 row lock(s), undo log entries 1
MySQL thread id 10851, OS thread handle 0x2abfb90, query id 251521 10.10.53.122 root update
insert into LockTest (order_id) values ('D20')
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 502 page no 4 n bits 72 index `idx_order_id` of table `test`.`LockTest` trx id 596042 lock_mode X insert intention waiting
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;;
*** (2) TRANSACTION:
TRANSACTION 596041, ACTIVE 19 sec inserting
mysql tables in use 1, locked 1
3 lock struct(s), heap size 320, 2 row lock(s), undo log entries 1
MySQL thread id 10848, OS thread handle 0xa233b90, query id 251522 10.10.53.122 root update
insert into LockTest (order_id) values ('D19')
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 502 page no 4 n bits 72 index `idx_order_id` of table `test`.`LockTest` trx id 596041 lock_mode X
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 502 page no 4 n bits 72 index `idx_order_id` of table `test`.`LockTest` trx id 596041 lock_mode X insert intention waiting
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;;
*** WE ROLL BACK TRANSACTION (2)
简单分析上面的场景先删除再插入的sql是hibernage保存集合关联的处理方式。delete语句删除不存在且删除的order_id大于现有表中的所有order_id,所以delete语句会使用next-key锁住(当前最大-无穷大)
| lock_id | lock_trx_id | lock_mode | lock_type | lock_table | lock_index | lock_space | lock_page | lock_rec | lock_data |
| 596133:502:4:1 | 596133 | X | RECORD | `test`.`LockTest` | idx_order_id | 502 | 4 | 1 | supremum pseudo-record |
| 596134:502:4:1 | 596134 | X | RECORD | `test`.`LockTest` | idx_order_id | 502 | 4 | 1 | supremum pseudo-record |
比较奇怪的是为啥两个事务都拿到了相同区间的(当前最大-无穷大)的X锁。不过换成read-commited级别后就没死锁了。
终于在官方文档找到答案, 区间锁只是用来防止其他事务在区间中插入数据,区间x锁 与区间S锁效果是一样的。也就是说不会因为两个事务都用加相同区间锁而相互等待的
https://dev.mysql.com/doc/refman/5.1/en/innodb-record-level-locks.html
Gap locks in InnoDB are “purely inhibitive”, which means they only stop other transactions from inserting to the gap. Thus, a gap X-lock has the same effect as a gap S-lock.
当两个事务拿到相同区间锁后,就会阻止对方忘区间内做insert操作。所以第一个事务insert会阻塞,第二个事务会提示死锁
innodb next-key lock引发的死锁的更多相关文章
- InnoDB的锁机制浅析(五)—死锁场景(Insert死锁)
可能的死锁场景 文章总共分为五个部分: InnoDB的锁机制浅析(一)-基本概念/兼容矩阵 InnoDB的锁机制浅析(二)-探索InnoDB中的锁(Record锁/Gap锁/Next-key锁/插入意 ...
- zz 关于插入意向间隔锁( insert intention gap lock)产生的死锁问题
出处: http://www.cnblogs.com/sunss/p/3166550.html 昨天看到一个很有意思的死锁,拿来记录下: 环境:deadlock on 事务隔离级别: read com ...
- 关于InnoDB的Next-Key lock
最近一段时间在准备新员工培训的材料,本来打算介绍介绍概念就OK的,但是既然写了事务的章节,就特别想介绍一下锁,介绍了锁,就忍不住想介绍一下Next-Key Lock. 大家知道,标准的事务隔离级别有R ...
- Key lock 的秘密
研究死锁,或者观察sp_lock,有时候最恼人的莫过于你看到下面研究成果的key lock,但是却不知道究竟是哪个page 哪个row被lock住了: Exec sp_lock: 就说上面的key ...
- SQL Server 隐式转换引发的死锁
在SQL Server的应用开发过程(尤其是二次开发)中可能由于开发人员对表的结构不够了解,造成开发过程中使用了不合理的方式造成数据库引擎未按预定执行,以致影响业务.这是非常值得注意的.这次为大家介绍 ...
- mysql之 [ERROR] InnoDB: Unable to lock ./ibdata1, error: 11
问题描述:启动MySQL后,出现连接不上,报 [ERROR] InnoDB: Unable to lock ./ibdata1, error: 11[root@mysql01 ~]# service ...
- index_merge引发的死锁排查
概述 前几天排查了一个死锁问题,最开始百思不得其解,因为发生死锁的两个事务是单语句事务,语句类型相同(where属性列相同,仅值不同),而且语句都走了相同的索引,但最终确实发生了死锁.通过定位排查发现 ...
- 同一张表不同SESSION相互持有对方记录引发的死锁
锁产生的原因:如果有两个会话,每个会话都持有另一个会话想要的资源,此时就会发生死锁. 同一张表不同SESSION持有不同记录 SQL> create table t1(id int); Tabl ...
- oracle大数据量更新引发的死锁问题解决方法及oracle分区和存储过程的思考
前言 前几天上午在对数据库的一张表进行操作的时候,由于这张表是按照时间的一张统计表,正好到那天没有测试数据了,于是我想将表中所有的时间,统一更新到后一个月,于是对80w条数据的更新开始了.整个过程曲折 ...
随机推荐
- VS无法导航到插入点F12失败
关闭VS 开启控制台并导航到Visual安装文件夹,例如C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\ID ...
- Python生成器笔记
Python中三大器有迭代器,生成器,装饰器,本文主要讲述生成器.主要从生成器的概念,本质,以及yield关键字的使用执行过程. 本质:生成器是一类特殊的迭代器,使用了yield关键字的函数不再是函数 ...
- Android对touch事件的拦截,在View Tree上的传递顺序
当发生touch事件时,系统会产生一个MotionEvent并且沿着View Tree开始传递.首先获取MotionEvent是View Tree的根节点,根节点通常是一个ViewGroup,View ...
- epoll实现机制分析
本文只介绍epoll的主要流程而不是分析源代码,如果需要了解更多的细节可以自己翻阅相关的内核源代码. 相关内核代码: fs/eventpoll.c 判断一个tcp套接字上是否有激活事件:net/ipv ...
- python之SQLAlchemy ORM
前言: 这篇博客主要介绍下SQLAlchemy及基本操作,写完后有空做个堡垒机小项目.有兴趣可看下python之数据库(mysql)操作.下篇博客整理写篇关于Web框架和django基础~~ 一.OR ...
- Delphi应用程序的调试(四)The Debug Inspector
调试检查器(The Debug Inspector) Debug Inspector使用户能查看诸如类和记录的数据对象,也可以用它来查看整数.字符数组等简单数据类型,但这类简单数据类型最好是用Watc ...
- Qt编写密钥生成器+使用demo(开源)
在很多商业软件中,需要提供一些可以试运行的版本,这样就需要配套密钥机制来控制,纵观大部分的试用版软件,基本上采用以下几种机制来控制.1:远程联网激活,每次启动都联网查看使用时间等,这种方法最完美,缺点 ...
- JS案例 - 基于vue的移动端长按手势
================================惯例碎碎念前言================================ 当时首先想到要做长按事件的时候,我想到的是vue内部的自 ...
- Android O 获取APK文件权限 Demo案例
1. 通过 aapt 工具查看 APK权限 C:\Users\zh>adb pull /system/priv-app/Settings . /system/priv-app/Settings/ ...
- 部署OpenStack问题汇总(六)-- OpenStack入门需要知道的概念
本博客已经添加"打赏"功能,"打赏"位置位于右边栏红色框中,感谢您赞助的咖啡. 一.网络问题-network 更多网络原理机制可以参考<OpenStack ...