出处: 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. NPM 私有仓库的搭建

    NPM 私有仓库的搭建 为什么搭建私有仓库 balabala,当然是有需求的时候嘛 搭建流程 介绍和安装verdaccio 备注: 程序启动后,配置文件为/home/work/.config/verd ...

  2. 接近8000字的Spring/SpringBoot常用注解总结!安排!

    0.前言 大家好,我是 Guide 哥!这是我的 221 篇优质原创文章.如需转载,请在文首注明地址,蟹蟹! 本文已经收录进我的 75K Star 的 Java 开源项目 JavaGuide:http ...

  3. 【Linux题目】第五关

    1. 如何取得/etiantian文件的权限对应的数字内容,如-rw-r-r 为644,要求使用命令取得644或0644这样的数字. 解答: 方法1:用sed获取stat filename里的属性值 ...

  4. 开发AI+诊疗生发系统,「先锋汇美」借力人工智能辅助诊疗实现头皮医学检测...

    困扰年轻人的脱发问题萌生了新兴的产业链.36氪先前曾剖析过近来火热的植发市场,更多人则选择"防范于未然","头皮检测"服务备受关注.此前,人们对"头皮 ...

  5. Java实现zip文件解压[到指定目录]

    2019独角兽企业重金招聘Python工程师标准>>> package com.ljheee.ziptool.core; import java.io.File; import ja ...

  6. Linux下创建 code diff 和 合并 patch

    Linux 下经常需要给别人提供 patch 以及合 patch,这时需要用到 Linux 的 diff 和 patch 命令. 1. diff 命令 diff 命令常用来比较文件.目录,也可以用来制 ...

  7. 图论--2-SAT--HDU/HDOJ 4115 Eliminate the Conflict

    Problem Description Conflicts are everywhere in the world, from the young to the elderly, from famil ...

  8. 一个简单的wed服务器SHTTPD(2)———— 客户端请求分析

    //start from the very beginning,and to create greatness //@author: Chuangwei Lin //@E-mail:979951191 ...

  9. MySQL 基础入门

    MySQL 是最流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System:关系数据库管理系统)应用 ...

  10. JavaWeb----Servler

    Servlet简介 Servlet就是sun公司开发动态web的一门技术 Sun在这些API中提供一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需要完成两个小步骤: 编写一个类, ...