在事务插入数据过程中,为防止其他事务向索引上该位置插入数据,会在插入之前先申请插入意向范围锁,而如果申请插入意向范围锁被阻塞,则事务处于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. SpringMVC @SessionAttribute 使用说明

    百度搜索 @SessionAttribute 这一句绝大多数文章中不存在: 如果Model中没有name参数,而session中存在一个name参数,那么SessionAttribute会讲这个参数塞 ...

  2. C++11新特性— auto 和 decltype 区别和联系

    一. auto简介 编程时候常常需要把表达式的值付给变量,需要在声明变量的时候清楚的知道变量是什么类型.然而做到这一点并非那么容易(特别是模板中),有时候根本做不到.为了解决这个问题,C++11新标准 ...

  3. SQLite添加新的字段

    通过alter添加新的字段SQL语句 "ALTER TABLE 'DiHKChatMessage' ADD 'phoneNum' varchar"; 但是如果这个字段已经存在的话, ...

  4. docker安装并运行rabbitmq

    拉取镜像: [mall@VM_0_7_centos ~]$ [sudo] password for mall: : Pulling from library/rabbitmq 5b7339215d1d ...

  5. [LeetCode] 314. Binary Tree Vertical Order Traversal 二叉树的垂直遍历

    Given a binary tree, return the vertical order traversal of its nodes' values. (ie, from top to bott ...

  6. [LeetCode] 451. Sort Characters By Frequency 根据字符出现频率排序

    Given a string, sort it in decreasing order based on the frequency of characters. Example 1: Input: ...

  7. [LeetCode] 543. Diameter of Binary Tree 二叉树的直径

    Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a b ...

  8. Redis哨兵(Sentinel)模式

    Redis哨兵(Sentinel)模式   主从切换技术的方法是:当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用.这不是一种推荐的方式 ...

  9. TCP/IP学习笔记5--网络的构成要素

    人的灵魂来自一个完美的家园,那里没有任何污秽和丑陋,只有纯净和美丽.----大鱼海棠 1.通信媒介与数据链路 计算机之间通过各种电缆相互连接. 2.网卡 任何一台计算机接入网络都需要网卡,又称网络适配 ...

  10. Java8 时间日期类操作

    Java8 时间日期类操作 Java8的时间类有两个重要的特性 线程安全 不可变类,返回的都是新的对象 显然,该特性解决了原来java.util.Date类与SimpleDateFormat线程不安全 ...