出处: http://www.cnblogs.com/sunss/p/3166550.html

昨天看到一个很有意思的死锁,拿来记录下:

环境:deadlock on

事务隔离级别: read commited

表结构:

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

session 1:

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

session 2:

  1. root@test 08:46:02>begin;
  2. Query OK, 0 rows affected (0.00 sec)
  3.  
  4. root@test 08:47:20>insert into lingluo values(100214,215,215,312);
  5. Query OK, 1 row affected (12.77 sec)

session3:

  1. root@test 08:46:24>begin;
  2. Query OK, 0 rows affected (0.00 sec)
  3.  
  4. root@test 08:47:23>insert into lingluo values(100215,215,215,312);

session 1 rollback前:

  1. ---TRANSACTION 4F3D6F33, ACTIVE 3 sec inserting
  2. mysql tables in use 1, locked 1
  3. LOCK WAIT 2 lock struct(s), heap size 376, 1 row lock(s), undo log entries 1
  4. MySQL thread id 18124715, OS thread handle 0x7fea34912700, query id 1435660081 localhost root update
  5. insert into lingluo values(100215,215,215,312)
  6. ------- TRX HAS BEEN WAITING 3 SEC FOR THIS LOCK TO BE GRANTED:
  7. 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
  8. ------------------
  9. TABLE LOCK table `test`.`lingluo` trx id 4F3D6F33 lock mode IX
  10. 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
  11. ---TRANSACTION 4F3D6D24, ACTIVE 5 sec inserting
  12. mysql tables in use 1, locked 1
  13. LOCK WAIT 2 lock struct(s), heap size 376, 1 row lock(s), undo log entries 1
  14. MySQL thread id 18124702, OS thread handle 0x7fe706fdf700, query id 1435659684 localhost root update
  15. insert into lingluo values(100214,215,215,312)
  16. ------- TRX HAS BEEN WAITING 5 SEC FOR THIS LOCK TO BE GRANTED:
  17. 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
  18. ------------------
  19. TABLE LOCK table `test`.`lingluo` trx id 4F3D6D24 lock mode IX
  20. 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
  21. ---TRANSACTION 4F3D4423, ACTIVE 33 sec
  22. 2 lock struct(s), heap size 376, 1 row lock(s), undo log entries 1
  23. MySQL thread id 18124692, OS thread handle 0x7fe73c89a700, query id 1435651549 localhost root
  24. TABLE LOCK table `test`.`lingluo` trx id 4F3D4423 lock mode IX
  25. 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:

  1. ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

这个时候show engine innodb status:

  1. 5 lock struct(s), heap size 1248, 3 row lock(s), undo log entries 1
  2. MySQL thread id 18124702, OS thread handle 0x7fe706fdf700, query id 1435659684 localhost root
  3. TABLE LOCK table `test`.`lingluo` trx id 4F3D6D24 lock mode IX
  4. RECORD LOCKS space id 3351 page no 4 n bits 80 index `uk_bc` of table `test`.`lingluo` trx id 4F3D6D24 lock mode S
  5. RECORD LOCKS space id 3351 page no 4 n bits 80 index `uk_bc` of table `test`.`lingluo` trx id 4F3D6D24 lock mode S
  6. 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
  7. 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

死锁信息:

  1. ------------------------
  2. LATEST DETECTED DEADLOCK
  3. ------------------------
  4. 130701 20:47:57
  5. *** (1) TRANSACTION:
  6. TRANSACTION 4F3D6D24, ACTIVE 13 sec inserting, thread declared inside InnoDB 1
  7. mysql tables in use 1, locked 1
  8. LOCK WAIT 4 lock struct(s), heap size 1248, 2 row lock(s), undo log entries 1
  9. MySQL thread id 18124702, OS thread handle 0x7fe706fdf700, query id 1435659684 localhost root update
  10. insert into lingluo values(100214,215,215,312)
  11. *** (1) WAITING FOR THIS LOCK TO BE GRANTED:
  12. 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
  13. *** (2) TRANSACTION:
  14. TRANSACTION 4F3D6F33, ACTIVE 11 sec inserting, thread declared inside InnoDB 1
  15. mysql tables in use 1, locked 1
  16. 4 lock struct(s), heap size 1248, 2 row lock(s), undo log entries 1
  17. MySQL thread id 18124715, OS thread handle 0x7fea34912700, query id 1435660081 localhost root update
  18. insert into lingluo values(100215,215,215,312)
  19. *** (2) HOLDS THE LOCK(S):
  20. RECORD LOCKS space id 3351 page no 4 n bits 80 index `uk_bc` of table `test`.`lingluo` trx id 4F3D6F33 lock mode S
  21. *** (2) WAITING FOR THIS LOCK TO BE GRANTED:
  22. 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
  23. *** 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. visual stdio 2012快捷键

    为什么80%的码农都做不了架构师?>>>   VS2012变化的快捷键:注释::VS2010是(Ctrl+E,C),VS2012是(Ctrl+K, Ctrl+C),实际操作,按住Ct ...

  2. apache、nginx配置openssl自签名证书

    1.生成私钥 生成rsa私钥,des3算法,2048位强度.server.key是秘钥文件名,需要提供一个至少4位的密码. [root@localhost ~]# openssl genrsa -de ...

  3. WLAN 无线网络 03 - RF 基础

    射频(Radio frequency),又称无线电频率.无线射频.高周波,常被用来当成无线电的同义词,为在3 kHz至300 GHz这个范围内的震荡频率,这个频率相当于无线电波的频率,以及携带着无线电 ...

  4. MySQL5.7 并行复制

    MySQL5.7 并行复制 1.缘由: 某天看到主从复制延时的告警有点频繁,就想着是不是彻底可以解决一下. 一般主从复制,有三个线程参与,都是单线程:Binlog Dump(主) ----->I ...

  5. Forrester:开源APM发展势头强劲

    在企业的运营团队看来,系统的稳定性和可靠运行时间是至关重要的.因此,企业更乐意向能够负责的技术提供商购买开发完整的.有文档记录的,并且有售后支持的工具或软件. 一般来说,运营团队没有额外精力来应付新奇 ...

  6. Longest XXX

    Longest Common Substring Brute Force 遍历a和b所有位置的组合,向后延伸,直到遇到两个不同的字符,复杂度是\(n^3\)级别. class Solution { p ...

  7. B. Phoenix and Beauty(贪心构造)

    \(给定序列长n的数组和k.完美数组的定义是数组中每一个连续k项的子段和为定值\) \(现在要求插入一些数使得数组满足条件,输出你构造的新数列.\) \(\color{Red}{----------- ...

  8. 单调队列+二分 G - Queue 小阳买水果

    B. Queue 这个题目会做的很偶然,突然想到的,因为我们要求离这只海象的最远的比他年轻的海象,这个年轻的海象可以用单调栈维护. 就是从前往后遍历一遍,单调栈里面存年龄从小往大的海象,这个为什么这么 ...

  9. 基于3D NAND层差异的固态盘请求调度算法研究立项 报告

    Abstract SSD(Solid State Drive),因其超高的读写性能,以及价格的走低趋势逐渐占据市场,为人们带来更好的用户体验,也为企业级的高并行业务需要提供了一定支持,近几年来SSD的 ...

  10. CC2530ADC转换

    一.ADC简介 ADC支持 14 位的模拟数字转换,具有多达12 位的 ENOB(有效数字位).它包括一个模拟多路转换器,具有多达8 个各自可配置的通道,以及一个参考电压发生器.转换结果通过DMA写入 ...