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条数据的更新开始了.整个过程曲折 ...
随机推荐
- HTML 水平线
<hr /> 标签可以在 HTML 页面中创建水平线,通常用来分隔文章中的小节 <!DOCTYPE HTML> <html> <body> <p& ...
- Unity Shader 获取模型空间坐标
CGPROGRAM // Physically based Standard lighting model, and enable shadows on all light types #pragma ...
- 第三篇:配置Hadoop的Eclipse开发环境
前言 在先前的文章中,已经介绍了如何在Ubuntu Kylin操作系统下搭建Hadoop运行环境,而现在将在之前工作的基础上搭建Eclipse开发环境. 配置 开发环境:Eclipse 4.2,其他同 ...
- python文件操作笔记
一.python中对文件.文件夹操作时经常用到的os模块和shutil模块常用方法. 1.得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd() 2.切换工作目录: os.c ...
- linux系统开机自启程序-需要-root用户 -启动 -
#!/bin/bashsh /home/hwjc/RSA/release2017-02-23/release2017-02-23/install.shsh /etc/init.d/mqtt.shifc ...
- c++学习笔记—二叉树基本操作的实现
用c++语言实现的二叉树基本操作,包括二叉树的创建.二叉树的遍历(包括前序.中序.后序递归和非递归算法).求二叉树高度,计数叶子节点数.计数度为1的节点数等基本操作. IDE:vs2013 具体实现代 ...
- spring基础---->spring自定义初始化(二)
这里新增了对ref属性的支持,并且过滤了已经解析的元素.人生有两个词很棒,一言不合和不提也罢. spring自定义对ref属性支持 项目的结构如下:新增一个ThirdBean类,修改了ParseXml ...
- Excel2010如何合并列数据
小编以下图的Excel数据文件为例,如下图,有两列数据,第一列是歌曲名,第二列是该歌曲的演唱者,他们是有关联呢,那么如何把他们合并到同一列呢. 首先点击第3列的开始空白格,在这里编辑公式 =a1& ...
- 网狐荣耀平台找不到存储过程 'GSP_GS_LoadGameMatchItem'错误解决
把RYGameMatchDB的存储过程复制到RYGameScoreDB即可,GSP_GS_InsertGameMatchItem和GSP_GS_DeleteGameMatchItem也一样 由于存储过 ...
- java(3) 面向对象
1.super关键字 * 使用super关键字调用父类的成员变量和成员方法.具体格式: super.成员变量 super.成员方法([参数1,参数2...]) * 使用super关键字调用父类的构造方 ...