zz 关于插入意向间隔锁( insert intention gap lock)产生的死锁问题
出处: http://www.cnblogs.com/sunss/p/3166550.html
昨天看到一个很有意思的死锁,拿来记录下:
环境:deadlock on
事务隔离级别: read commited
表结构:

root@test 08:34:01>show create table lingluo\G
*************************** 1. row ***************************
Table: lingluo
Create Table: CREATE TABLE `lingluo` (
`a` int(11) NOT NULL DEFAULT '0',
`b` int(11) DEFAULT NULL,
`c` int(11) DEFAULT NULL,
`d` int(11) DEFAULT NULL,
PRIMARY KEY (`a`),
UNIQUE KEY `uk_bc` (`b`,`c`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk
1 row in set (0.00 sec)

session 1:

root@test 08:45:51>select * from lingluo;
+--------+------+------+------+
| a | b | c | d |
+--------+------+------+------+
| 1 | 2 | 3 | 4 |
| 500 | 100 | 200 | 43 |
| 1000 | 10 | 20 | 43 |
| 10001 | 21 | 21 | 32 |
| 100202 | 213 | 213 | 312 |
| 100212 | 214 | 214 | 312 |
+--------+------+------+------+
6 rows in set (0.00 sec) root@test 08:46:38>begin;
Query OK, 0 rows affected (0.00 sec) root@test 08:47:04>insert into lingluo values(100213,215,215,312);
Query OK, 1 row affected (0.00 sec)

session 2:
root@test 08:46:02>begin;
Query OK, 0 rows affected (0.00 sec) root@test 08:47:20>insert into lingluo values(100214,215,215,312);
Query OK, 1 row affected (12.77 sec)
session3:
root@test 08:46:24>begin;
Query OK, 0 rows affected (0.00 sec) root@test 08:47:23>insert into lingluo values(100215,215,215,312);
session 1 rollback前:

---TRANSACTION 4F3D6F33, ACTIVE 3 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 376, 1 row lock(s), undo log entries 1
MySQL thread id 18124715, OS thread handle 0x7fea34912700, query id 1435660081 localhost root update
insert into lingluo values(100215,215,215,312)
------- TRX HAS BEEN WAITING 3 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 3351 page no 4 n bits 80 index `uk_bc` of table `test`.`lingluo` trx id 4F3D6F33 lock mode S waiting
------------------
TABLE LOCK table `test`.`lingluo` trx id 4F3D6F33 lock mode IX
RECORD LOCKS space id 3351 page no 4 n bits 80 index `uk_bc` of table `test`.`lingluo` trx id 4F3D6F33 lock mode S waiting
---TRANSACTION 4F3D6D24, ACTIVE 5 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 376, 1 row lock(s), undo log entries 1
MySQL thread id 18124702, OS thread handle 0x7fe706fdf700, query id 1435659684 localhost root update
insert into lingluo values(100214,215,215,312)
------- TRX HAS BEEN WAITING 5 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 3351 page no 4 n bits 80 index `uk_bc` of table `test`.`lingluo` trx id 4F3D6D24 lock mode S waiting
------------------
TABLE LOCK table `test`.`lingluo` trx id 4F3D6D24 lock mode IX
RECORD LOCKS space id 3351 page no 4 n bits 80 index `uk_bc` of table `test`.`lingluo` trx id 4F3D6D24 lock mode S waiting
---TRANSACTION 4F3D4423, ACTIVE 33 sec
2 lock struct(s), heap size 376, 1 row lock(s), undo log entries 1
MySQL thread id 18124692, OS thread handle 0x7fe73c89a700, query id 1435651549 localhost root
TABLE LOCK table `test`.`lingluo` trx id 4F3D4423 lock mode IX
RECORD LOCKS space id 3351 page no 4 n bits 80 index `uk_bc` of table `test`.`lingluo` trx id 4F3D4423 lock_mode X locks rec but not gap

/****
session 1上的转为显式锁:lock_mode X locks rec but not gap
session 2等待的锁:lock mode S waiting
session 3等待的锁:lock mode S waiting
***/
session 1 rollback
session 2插入成功
session 3:
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
这个时候show engine innodb status:

5 lock struct(s), heap size 1248, 3 row lock(s), undo log entries 1
MySQL thread id 18124702, OS thread handle 0x7fe706fdf700, query id 1435659684 localhost root
TABLE LOCK table `test`.`lingluo` trx id 4F3D6D24 lock mode IX
RECORD LOCKS space id 3351 page no 4 n bits 80 index `uk_bc` of table `test`.`lingluo` trx id 4F3D6D24 lock mode S
RECORD LOCKS space id 3351 page no 4 n bits 80 index `uk_bc` of table `test`.`lingluo` trx id 4F3D6D24 lock mode S
RECORD LOCKS space id 3351 page no 4 n bits 80 index `uk_bc` of table `test`.`lingluo` trx id 4F3D6D24 lock_mode X insert intention
RECORD LOCKS space id 3351 page no 4 n bits 80 index `uk_bc` of table `test`.`lingluo` trx id 4F3D6D24 lock mode S locks gap before rec

死锁信息:

------------------------
LATEST DETECTED DEADLOCK
------------------------
130701 20:47:57
*** (1) TRANSACTION:
TRANSACTION 4F3D6D24, ACTIVE 13 sec inserting, thread declared inside InnoDB 1
mysql tables in use 1, locked 1
LOCK WAIT 4 lock struct(s), heap size 1248, 2 row lock(s), undo log entries 1
MySQL thread id 18124702, OS thread handle 0x7fe706fdf700, query id 1435659684 localhost root update
insert into lingluo values(100214,215,215,312)
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 3351 page no 4 n bits 80 index `uk_bc` of table `test`.`lingluo` trx id 4F3D6D24 lock_mode X insert intention waiting
*** (2) TRANSACTION:
TRANSACTION 4F3D6F33, ACTIVE 11 sec inserting, thread declared inside InnoDB 1
mysql tables in use 1, locked 1
4 lock struct(s), heap size 1248, 2 row lock(s), undo log entries 1
MySQL thread id 18124715, OS thread handle 0x7fea34912700, query id 1435660081 localhost root update
insert into lingluo values(100215,215,215,312)
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 3351 page no 4 n bits 80 index `uk_bc` of table `test`.`lingluo` trx id 4F3D6F33 lock mode S
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 3351 page no 4 n bits 80 index `uk_bc` of table `test`.`lingluo` trx id 4F3D6F33 lock_mode X insert intention waiting
*** WE ROLL BACK TRANSACTION (2)

原因:
s1 , type_mode=1059 //s2为s1转换隐式锁为显式锁
s2, type_mode=1282 //检查重复键,需要加共享锁,被s1 block住,等待S锁
s3, type_mode=1282 // 被s1 block住,等待S锁
s1, type_mode=547 //s1回滚,删除记录,lock_update_delete锁继承,
s2, type_mode=546 //创建s锁 LOCK_GAP | LOCK_REC | LOCK_S
s3, type_mode=546 //创建s锁 LOCK_GAP | LOCK_REC | LOCK_S
s2, type_mode=2819 // LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION
s3, type_mode=2819 // LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION
当s1回滚后,s2和s3获得s锁,但随后s2和s3又先后请求插入意向锁,因此锁队列为:
s2(S GAP)<—s3(S GAP)<—s2(插入意向锁)<–s3(插入意向锁) s3(s锁),s2(x锁),s3(x锁)形成死锁。
这样的死锁不光出现在unique key,还包括primary key(unique key的特殊形式)
印风的博客里有更详细的代码级别的记录,有兴趣的可以看下
另外如果:deadlock off的话,即使session 1rollback了,session 2和session 3还是处于等待的状态,除非超过了innodb_lock_wait_timeout的时间,报
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
这个情况和官方的这篇文章是一样的http://dev.mysql.com/doc/refman/5.5/en/innodb-locks-set.html
zz 关于插入意向间隔锁( insert intention gap lock)产生的死锁问题的更多相关文章
- InnoDB锁机制之Gap Lock、Next-Key Lock、Record Lock解析
InnoDB锁机制之Gap Lock.Next-Key Lock.Record Lock解析 有意思,解释的很好
- MySQL InnoDB锁机制之Gap Lock、Next-Key Lock、Record Lock解析
MySQL InnoDB支持三种行锁定方式: l 行锁(Record Lock):锁直接加在索引记录上面,锁住的是key. l 间隙锁(Gap Lock):锁定索引记录间隙,确保索引记录的间隙 ...
- my39_InnoDB锁机制之Gap Lock、Next-Key Lock、Record Lock解析
MySQL InnoDB支持三种行锁定方式: 行锁(Record Lock):锁直接加在索引记录上面,锁住的是key. 间隙锁(Gap Lock): 锁定索引记录间隙,确保索引记录的间隙不变.间隙锁是 ...
- MySQL Lock--gap before rec insert intention waiting
在事务插入数据过程中,为防止其他事务向索引上该位置插入数据,会在插入之前先申请插入意向范围锁,而如果申请插入意向范围锁被阻塞,则事务处于gap before rec insert intention ...
- 简单的sqlserver批量插入数据easy batch insert data use loop function in sqlserver
--example 1: DECLARE @pid INT,@name NVARCHAR(50),@level INT,@i INT,@column2 INT SET @pid=0 SET @name ...
- Postgresql中无则插入的使用方法INSERT INTO WHERE NOT EXISTS
一.问题 Postgresql中无则插入的使用方法INSERT INTO WHERE NOT EXISTS,用法请参考样例. 二.解决方案 (1)PostgresSQL INSERT INTO tes ...
- autocommit 隔离级别 next lock gap lock 事务隔离级别和锁
autocommit 隔离级别 https://www.ibm.com/developerworks/cn/opensource/os-mysql-transaction-isolation-leve ...
- Innodb锁机制:Next-Key Lock 浅谈
数据库使用锁是为了支持更好的并发,提供数据的完整性和一致性.InnoDB是一个支持行锁的存储引擎,锁的类型有:共享锁(S).排他锁(X).意向共享(IS).意向排他(IX).为了提供更好的并发,Inn ...
- Innodb锁机制:Next-Key Lock 浅谈(转)
http://www.cnblogs.com/zhoujinyi/p/3435982.html 数据库使用锁是为了支持更好的并发,提供数据的完整性和一致性.InnoDB是一个支持行锁的存储引擎,锁的类 ...
随机推荐
- 字符串的z型转换
class Solution(object): def convert(self, s, numRows): if numRows==1: return ...
- React-Native iOS真机调试(新版)
2019独角兽企业重金招聘Python工程师标准>>> React-Native iOS真机调试 看到网上很多以前的文章 找到两种方法 一 修改AppDelegate 把URL的替换 ...
- ELK收集日志到mysql数据库
场景需求 在使用ELK对日志进行收集的时候,如果需要对数据进行存档,可以考虑使用数据库的方式.为了便于查询,可以同时写一份数据到Elasticsearch 中. 环境准备 CentOS7系统: 192 ...
- lua 发送http请求
lua发送http请求,luajit默认没有http.lua库,需要下载并存放到luajit对应目录. 一.下载http.lua和http_headers.lua库 参考:https://www.zi ...
- 数据库SQL语言从入门到精通--Part 4--SQL语言中的模式、基本表、视图
数据库从入门到精通合集(超详细,学习数据库必看) 前言: 使用SQL语言时,要注意SQL语言对大小写并不敏感,一般使用大写.所有符号一定是西文标点符号(虽然是常识,但我还是提一嘴) 1.模式的定义与删 ...
- POJ - 2251 Dungeon Master(搜索)
You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of un ...
- 06 ORM常用字段 关系字段 数据库优化查询
一.Django ORM 常用字段和参数 1.常用字段 models中所有的字段类型其实本质就那几种,整形varchar什么的,都没有实际的约束作用,虽然在models中没有任何限制作用,但是还是要分 ...
- U盘安装Proxmox VE(一)
转自我的个人博客:U盘安装Proxmox VE(一) 年前搞了个星际蜗牛B款机箱,利用手头之前海淘dq77kb组装了个四盘位的Server. 组装完毕后,直接在实体机安装了centos 7.使用这几个 ...
- Java 创建并应用PPT幻灯片母版
幻灯片母版,可在幻灯片中预先存储设计模板信息,包括字形.占位符大小或位置.背景设计和配色方案等:对设定好的母版可应用于所有幻灯片,也可设计多个不同母版应用于不同幻灯片.下面通过Java代码示例介绍如何 ...
- 201771030120-王嫄 实验一 软件工程准备 <课程学习目的思考>
项目 内容 课程班级博客链接 https://edu.cnblogs.com/campus/xbsf/nwnu2020SE 这个作业要求链接 https://www.cnblogs.com/nwnu- ...