在事务插入数据过程中,为防止其他事务向索引上该位置插入数据,会在插入之前先申请插入意向范围锁,而如果申请插入意向范围锁被阻塞,则事务处于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. Linux_CentOS 中systemctl 管理服务、防火墙 firewalld 以及 SELinux 配置

    使用 systemctl 管理服务 systemctl 就是 service 和 chkconfig 这两个命令的整合,在 CentOS 7 就开始被使用了,systemctl是系统服务管理器命令,它 ...

  2. Redis 操作帮助类

    首先从Nuget中添加StackExchange.Redis包 1.Redis连接对象管理帮助类 using Mvc.Base; using Mvc.Base.Log; using StackExch ...

  3. Linux MySQL 5.6.43 安装

    [注意] 1.首先安装在默认目录 /usr/local/mysql,如需更改数据存储目录,进行2.3两步 2.如果需要修改数据目录,将my.nf 中的 datadir=/usr/local/mysql ...

  4. [译]在你的GitHub主页固定仓库

    原文来源:https://github.blog/2016-06-16-pin-repositories-to-your-github-profile/ 您现在可以在GitHub主页上展示最能代表您工 ...

  5. 调用k8s api遇到CERTIFICATE_VERIFY_FAILED的问题解决方法

    前言 python3.5.6版本,django1.1.12版本 最近要调用k8s接口,k8s接口的使用方法请参考官网的说明:戳我 调用k8s接口时,遇到 CERTIFICATE_VERIFY_FAIL ...

  6. [LeetCode] 366. Find Leaves of Binary Tree 找二叉树的叶节点

    Given a binary tree, find all leaves and then remove those leaves. Then repeat the previous steps un ...

  7. 【ARM-Linux开发】Ubuntu下的/usr目录权限,导致不能使用sudo命令的修复

    刚开始运行sudo时,报了下面这个错误 sudo: must be setuid root,于是上网找解决方法,搜索出来的都是这样解决的 ls -l  /usr/bin/sudochown root: ...

  8. javascript高德地图实现点击marker消失marker

    javascript高德地图实现点击marker消失marker <pre> var markers = []; var positions = [[120.17718, 30.21772 ...

  9. [hdu 1062] Text Reverse | STL-stack

    原题 题目大意: t组数据,每组为一行,遇到空格时讲前面的单词反转输出. 题解: 显然的栈题,遇到空格时将当前栈输出清空即可 #include<cstdio> #include<st ...

  10. liunx mysql数据库目录迁移

    1.查看mysql安装目录 从目录etc/my.cnf中查看安装目录 2.进入mysql目录,停止mysql服务 命令: cd usr/local/mysql 命令:service mysql sto ...