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

MySQL官方文档解释如下:

INSERT sets an exclusive lock on the inserted row. This lock is an index-record lock, not a next-key lock (that is, there is no gap lock) and does not prevent other sessions from inserting into the gap before the inserted row.Prior to inserting the row, a type of gap lock called an insertion intention gap lock is set. This lock signals the intent to insert in such a way that multiple transactions inserting into the same index gap need not wait for each other if they are not inserting at the same position within the gap.If a duplicate-key error occurs, a shared lock on the duplicate index record is set. This use of a shared lock can result in deadlock should there be multiple sessions trying to insert the same row if another session already has an exclusive lock.

准备测试数据:

## 创建测试表
CREATE TABLE `tb1001` (
`order_id` int() NOT NULL,
`order_num` int() DEFAULT NULL,
`order_type` int() DEFAULT NULL,
PRIMARY KEY (`order_id`),
KEY `idx_order_type` (`order_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ## 准备测试数据
insert into tb1001(order_id,order_num,order_type)
values(,,),(,,),(,,),(,,);

先执行事务(事务132868):

BEGIN;
update tb1001
set order_num=
where order_type=;

再执行事务(事务ID 132869):

BEGIN;
update tb1001
set order_type=
where order_id=;

查看事务锁和阻塞信息

SELECT * FROM INNODB_LOCK_WAITS \G
*************************** . row ***************************
requesting_trx_id:
requested_lock_id: :::
blocking_trx_id:
blocking_lock_id: ::: select * from INNODB_LOCKS \G
*************************** . row ***************************
lock_id: :::
lock_trx_id:
lock_mode: X,GAP
lock_type: RECORD
lock_table: `db002`.`tb1001`
lock_index: idx_order_type
lock_space:
lock_page:
lock_rec:
lock_data: ,
*************************** . row ***************************
lock_id: :::
lock_trx_id:
lock_mode: X
lock_type: RECORD
lock_table: `db002`.`tb1001`
lock_index: idx_order_type
lock_space:
lock_page:
lock_rec:
lock_data: ,

事务132868上锁信息:

---TRANSACTION , ACTIVE  sec
lock struct(s), heap size , row lock(s), undo log entries
MySQL thread id , OS thread handle , query id 127.0.0.1 admin
TABLE LOCK table `db002`.`tb1001` trx id lock mode IX RECORD LOCKS space id page no n bits index idx_order_type of table `db002`.`tb1001` trx id lock_mode X
Record lock, heap no PHYSICAL RECORD: n_fields ; compact format; info bits
: len ; hex 73757072656d756d; asc supremum;; Record lock, heap no PHYSICAL RECORD: n_fields ; compact format; info bits
: len ; hex ; asc ;;
: len ; hex ; asc ;; Record lock, heap no PHYSICAL RECORD: n_fields ; compact format; info bits
: len ; hex ; asc ;;
: len ; hex ; asc ;; RECORD LOCKS space id page no n bits index PRIMARY of table `db002`.`tb1001` trx id lock_mode X locks rec but not gap
Record lock, heap no PHYSICAL RECORD: n_fields ; compact format; info bits
: len ; hex ; asc ;;
: len ; hex ; asc ;;
: len ; hex 24000000230a28; asc $ # (;;
: len ; hex ; asc ;;
: len ; hex ; asc ;; Record lock, heap no PHYSICAL RECORD: n_fields ; compact format; info bits
: len ; hex ; asc ;;
: len ; hex ; asc ;;
: len ; hex 24000000230a49; asc $ # I;;
: len ; hex ; asc ;;
: len ; hex ; asc ;;

事务132869上锁信息:

---TRANSACTION , ACTIVE  sec updating or deleting
mysql tables in use , locked
LOCK WAIT lock struct(s), heap size , row lock(s), undo log entries
MySQL thread id , OS thread handle , query id 127.0.0.1 admin updating
update tb1001 set order_type= where order_id=
------- TRX HAS BEEN WAITING SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id page no n bits index idx_order_type of table `db002`.`tb1001` trx id lock_mode X locks gap before rec insert intention waiting
Record lock, heap no PHYSICAL RECORD: n_fields ; compact format; info bits
: len ; hex ; asc ;;
: len ; hex ; asc ;; ------------------
TABLE LOCK table `db002`.`tb1001` trx id lock mode IX
RECORD LOCKS space id page no n bits index PRIMARY of table `db002`.`tb1001` trx id lock_mode X locks rec but not gap
Record lock, heap no PHYSICAL RECORD: n_fields ; compact format; info bits
: len ; hex ; asc ;;
: len ; hex ; asc ;;
: len ; hex 250000002407c6; asc % $ ;;
: len ; hex 8000000a; asc ;;
: len ; hex ; asc ;; RECORD LOCKS space id page no n bits index idx_order_type of table `db002`.`tb1001` trx id lock_mode X locks gap before rec insert intention waiting
Record lock, heap no PHYSICAL RECORD: n_fields ; compact format; info bits
: len ; hex ; asc ;;
: len ; hex ; asc ;;

由于执行事务(事务132868)按照order_type=2条件更新,因此先使用索引idx_order_type定位到order_type=2的记录并加锁(ROW LOCK),再根据二级索引上包含的主键索引值找到表上order_id=2和order_id=4的记录并加锁(ROW LOCK),加锁如下:

由于执行事务(事务132869)按照order_id=3条件更新,先根据主键定位到order_id=3并加锁(ROW LOCK),然后根据主键中数据(order_type=1+ order_id=3)到索引idx_order_type上找到满足条件的记录并加锁,UPDATE操作将数据(1,3)更新为(2,3),因此会将索引idx_order_type上记录(1,3)标记为删除,然后在记录(2,2)和(2,4)之间插入新记录(2,3),在插入记录前,为防止其他事务在该物理位置上插入其他数据,需要先在索引idx_order_type上申请记录(2,2)和(2,4)之间插入意向锁(Insert Intention Gap Lock),其加锁如下:

而由于索引记录(2,4)上已被事务132868加锁(X LOCK+ ROW LOCK),因此导致加插入意向锁(Insert Intention Gap Lock)被阻塞,处于“lock_mode X locks gap before rec insert intention waiting”的等待状态。

MySQL Lock--gap before rec insert intention waiting的更多相关文章

  1. Mysql死锁如何排查:insert on duplicate死锁一次排查分析过程

    前言 遇到Mysql死锁问题,我们应该怎么排查分析呢?之前线上出现一个insert on duplicate死锁问题,本文将基于这个死锁问题,分享排查分析过程,希望对大家有帮助. 死锁案发还原 表结构 ...

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

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

  3. zz 关于插入意向间隔锁( insert intention gap lock)产生的死锁问题

    出处: http://www.cnblogs.com/sunss/p/3166550.html 昨天看到一个很有意思的死锁,拿来记录下: 环境:deadlock on 事务隔离级别: read com ...

  4. 磁盘爆满导致MySQL无法启动:Disk is full writing './mysql-bin.~rec~' (Errcode: 28). Waiting for someone to free space...

    今天收到监控邮件说博客访问失败.打开页面一看,硕大的502 Bad Gateway,ping了一下VPS发现是通的,SSH连接上去看了下Nginx日志发现没问题,重启lnmp的时候发现Mysql起不来 ...

  5. [MySQL] lock知识梳理

    MySQL Lock机制 INDEX: MySQL事务隔离级别 MVCC MySQL Lock类型 MySQL MDL CONTENT: 1. MySQL事务隔离级别 Read Uncommit RU ...

  6. Mysql加锁过程详解(7)-初步理解MySQL的gap锁

    Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...

  7. MySQL replace into 说明(insert into 增强版)

    MySQL replace into 说明(insert into 增强版) 在插入数据到一个表时,通常是这种情况:1. 先推断数据是否存在: 2. 假设不存在,则插入:3.假设存在,则更新. 在 S ...

  8. mysql中 REPLACE INTO 和 INSERT INTO 的区别

    mysql中 REPLACE INTO 和 INSERT INTO 的区别 REPLACE INTO 和 INSERT INTO 功能类似,都是像表中插入数据,不同点在于:REPLACE INTO 首 ...

  9. 高效的MySQL的批插入 BULK INSERT

    原文:http://www.open-open.com/code/view/1453702496573 MySQL的批插入 BULK INSERT和load data的速度差不多,并且可靠. 语法如下 ...

随机推荐

  1. 《精通CSS第3版》(6)内容布局(定位+水平布局)

  2. EasyNVR网页Chrome无插件播放摄像机视频功能二次开发之云台控制接口示例代码

    随着多媒体技术和网络通信技术的迅速发展,视频监控技术在电力系统.电信行业.工业监控.工地.城市交通.水利系统.社区安防等领域得到越来越广泛的应用.摄像头直播视频监控通过网络直接连接,可达到的世界任何角 ...

  3. [LeetCode] 21. Merge Two Sorted Lists 合并有序链表

    Merge two sorted linked lists and return it as a new list. The new list should be made by splicing t ...

  4. SpringBoot系列教程web篇之Thymeleaf环境搭建

    上一篇博文介绍了如何使用Freemaker引擎搭建web项目,这一篇我们则看一下另外一个常见的页面渲染引擎Thymeleaf如何搭建一个web项目 推荐结合Freemaker博文一起查看,效果更佳 1 ...

  5. win10安装网络适配器

    上面这个有些叫Microsoft Loopback Adapter

  6. jQuery “没有属性”选择器

    可以使用.not() 或 :not() 选择器. $('.container:not([data-timestamp])') 或者 $('.container').not('[data-timesta ...

  7. 【转帖】MIPS构架之:我和龙芯有个约会

    MIPS构架之:我和龙芯有个约会 https://www.eefocus.com/mcu-dsp/364490 <处理器史话>之十二 2016-06-24 12:21 作者:付丽华预计 1 ...

  8. Automatically generating nice graphs at end of your Load Test with Apache JMeter and JMeter-Plugins

    Update as of November 2017: Since JMeter 3.0, last version being 3.3, JMeter provides Out Of The Box ...

  9. day31——recv工作原理、高大上版解决粘包方式、基于UDP协议的socket通信

    day31 recv工作原理 源码解释: Receive up to buffersize bytes from the socket. 接收来自socket缓冲区的字节数据, For the opt ...

  10. vue+element+upload实现头像上传

    后台 @RequestMapping("/up") public JSONObject up(@RequestParam("picFile") Multipar ...