出处: 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)产生的死锁问题的更多相关文章

  1. InnoDB锁机制之Gap Lock、Next-Key Lock、Record Lock解析

    InnoDB锁机制之Gap Lock.Next-Key Lock.Record Lock解析 有意思,解释的很好

  2. MySQL InnoDB锁机制之Gap Lock、Next-Key Lock、Record Lock解析

    MySQL InnoDB支持三种行锁定方式: l   行锁(Record Lock):锁直接加在索引记录上面,锁住的是key. l   间隙锁(Gap Lock):锁定索引记录间隙,确保索引记录的间隙 ...

  3. my39_InnoDB锁机制之Gap Lock、Next-Key Lock、Record Lock解析

    MySQL InnoDB支持三种行锁定方式: 行锁(Record Lock):锁直接加在索引记录上面,锁住的是key. 间隙锁(Gap Lock): 锁定索引记录间隙,确保索引记录的间隙不变.间隙锁是 ...

  4. MySQL Lock--gap before rec insert intention waiting

    在事务插入数据过程中,为防止其他事务向索引上该位置插入数据,会在插入之前先申请插入意向范围锁,而如果申请插入意向范围锁被阻塞,则事务处于gap before rec insert intention ...

  5. 简单的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 ...

  6. Postgresql中无则插入的使用方法INSERT INTO WHERE NOT EXISTS

    一.问题 Postgresql中无则插入的使用方法INSERT INTO WHERE NOT EXISTS,用法请参考样例. 二.解决方案 (1)PostgresSQL INSERT INTO tes ...

  7. autocommit 隔离级别 next lock gap lock 事务隔离级别和锁

    autocommit 隔离级别 https://www.ibm.com/developerworks/cn/opensource/os-mysql-transaction-isolation-leve ...

  8. Innodb锁机制:Next-Key Lock 浅谈

    数据库使用锁是为了支持更好的并发,提供数据的完整性和一致性.InnoDB是一个支持行锁的存储引擎,锁的类型有:共享锁(S).排他锁(X).意向共享(IS).意向排他(IX).为了提供更好的并发,Inn ...

  9. Innodb锁机制:Next-Key Lock 浅谈(转)

    http://www.cnblogs.com/zhoujinyi/p/3435982.html 数据库使用锁是为了支持更好的并发,提供数据的完整性和一致性.InnoDB是一个支持行锁的存储引擎,锁的类 ...

随机推荐

  1. java学习(第三篇)String类

    一.创建一个字符串 1.String(char a[]):用一个字符数组a创建一个string类型 char a[]= {'h','e','l','l','o'}; String s=new Stri ...

  2. java 之 enum(枚举)

    推荐博客 http://blog.csdn.net/javazejian/article/details/71333103

  3. 《LabVIEW 虚拟仪器程序设计从入门到精通(第二版)》一1.3 小结

    本节书摘来自异步社区<LabVIEW 虚拟仪器程序设计从入门到精通(第二版)>一书中的第1章,第1.3节,作者 林静 , 林振宇 , 郑福仁,更多章节内容可以访问云栖社区"异步社 ...

  4. 为给定字符串生成MD5指纹

    import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.apache ...

  5. iOS自定义tabBar

    在我们的项目中经常会自己自定义tabBar因为苹果自带的真的太丑了!也不满足我们的项目需求. 好 开始行动吧! 先上图看下我们最终实现的效果: 继承UItabBar自定义一个自己的tabBar .h# ...

  6. Nodejs与Mysql交互实现(异步写法,同步写法)

    https://blog.csdn.net/think_A_lot/article/details/93498737

  7. 使用JXL.jar实现JAVA对EXCEL的读写操作

    简介: jxl.jar是通过java操作excel表格的工具类库 jxl操作excel包括对象Workbook(工作簿),Sheet(工作表) ,Cell(单元格). 一个excel就对应一个Work ...

  8. 轻量化模型:MobileNet v2

    MobileNet v2 论文链接:https://arxiv.org/abs/1801.04381 MobileNet v2是对MobileNet v1的改进,也是一个轻量化模型. 关于Mobile ...

  9. 在web中使用shiro(会话管理,登出,shiro标签库的使用)

    在shiro的主配置文件中配置,登出的请求经过的过滤器就可以了,在shiro的过滤器中有一个名称为logout的过滤 器专门为我们处理登出请求: 一.shiro会话管理器 shiro中也提供了类似于w ...

  10. Proteus传感器+气体浓度检测的报警方式控制仿真

    Proteus传感器+气体浓度检测的报警方式控制仿真 目录 Proteus传感器+气体浓度检测的报警方式控制仿真 1 实验意义理解 2 主要实验器件 3 实验参考电路 4 实验中的问题思考 4.1 实 ...