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条数据的更新开始了.整个过程曲折 ...
随机推荐
- Nginx 解析PHP
配置如下: [root@localhost ~]$ cat /usr/local/nginx/conf/vhost/test.com.conf server { listen 80; server_n ...
- 关于 g++ 编译器
g++由自由软件基金发行,g++是基于类unix的c++编译器,通常在命令行运行.它一般附带于类Unix系统中,因此如果你正在运行Unix或Linux系统,它很可能已经存在于你的系统中.你可以对一个源 ...
- Java bean中布尔类型使用注意
JavaBean是一个标准,遵循标准的Bean是一个带有属性和getters/setters方法的Java类. JavaBean的定义很简单,但是还有有一些地方需要注意,例如Bean中含有boolea ...
- .net写入文本到本地
using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"d:\test\ErrorLog.txt", t ...
- QWidget编写的安卓app
最近为了配套人脸识别的整套设备去检测,特意做了个机关控制app,需要现场修改前端设备和服务器设备的一些参数以便进行检测.qt做一些简单的app还是非常方便的.特意增加了禁用屏保功能.apk文件体验:h ...
- update select 多字段
update Countrys set ( Abbreviation_cn, Abbreviation_en, Two_code,Three_code, Number_code)= (select [ ...
- sencha touch 视图(view) activate与deactivate事件探讨
在sencha touch2.2中采用card布局 之前的需求是考虑show,hide事件发现不可取 http://www.cnblogs.com/mlzs/archive/2013/06/13/31 ...
- SPOJ1007 VLATTICE - Visible Lattice Points
VLATTICE - Visible Lattice Points no tags Consider a N*N*N lattice. One corner is at (0,0,0) and th ...
- IIS "rewrite.dll failed to load. The data is the error." 错误解决方法
在Windows 10 build 17133.73上部署一个较老版本的ASP.NET 2.0程序,访问时候出现: Service Unavailable HTTP Error 503. The se ...
- Web Service Client使用Microsoft WSE 2.0
我安装了WSE 2.0 SP3,Setup Type选择Runtime.如果想要让Visual Studio 2005以上版本集成WSE需稍费周折,默认集成Visual Studio 2005. 1. ...