MySQL Lock--gap before rec insert intention waiting
在事务插入数据过程中,为防止其他事务向索引上该位置插入数据,会在插入之前先申请插入意向范围锁,而如果申请插入意向范围锁被阻塞,则事务处于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的更多相关文章
- Mysql死锁如何排查:insert on duplicate死锁一次排查分析过程
前言 遇到Mysql死锁问题,我们应该怎么排查分析呢?之前线上出现一个insert on duplicate死锁问题,本文将基于这个死锁问题,分享排查分析过程,希望对大家有帮助. 死锁案发还原 表结构 ...
- autocommit 隔离级别 next lock gap lock 事务隔离级别和锁
autocommit 隔离级别 https://www.ibm.com/developerworks/cn/opensource/os-mysql-transaction-isolation-leve ...
- zz 关于插入意向间隔锁( insert intention gap lock)产生的死锁问题
出处: http://www.cnblogs.com/sunss/p/3166550.html 昨天看到一个很有意思的死锁,拿来记录下: 环境:deadlock on 事务隔离级别: read com ...
- 磁盘爆满导致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起不来 ...
- [MySQL] lock知识梳理
MySQL Lock机制 INDEX: MySQL事务隔离级别 MVCC MySQL Lock类型 MySQL MDL CONTENT: 1. MySQL事务隔离级别 Read Uncommit RU ...
- Mysql加锁过程详解(7)-初步理解MySQL的gap锁
Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...
- MySQL replace into 说明(insert into 增强版)
MySQL replace into 说明(insert into 增强版) 在插入数据到一个表时,通常是这种情况:1. 先推断数据是否存在: 2. 假设不存在,则插入:3.假设存在,则更新. 在 S ...
- mysql中 REPLACE INTO 和 INSERT INTO 的区别
mysql中 REPLACE INTO 和 INSERT INTO 的区别 REPLACE INTO 和 INSERT INTO 功能类似,都是像表中插入数据,不同点在于:REPLACE INTO 首 ...
- 高效的MySQL的批插入 BULK INSERT
原文:http://www.open-open.com/code/view/1453702496573 MySQL的批插入 BULK INSERT和load data的速度差不多,并且可靠. 语法如下 ...
随机推荐
- Oracle系列三 过滤和排序
WHERE子句 使用WHERE 子句,将不满足条件的行过滤掉. 示例: SELECT employee_id, last_name, job_id, department_id FROM employ ...
- 运行 puppeteer 报错 chrome: error while loading shared libraries: libpangocairo-1.0.so.0: cannot open shared object file: No such file or directory
运行 puppeteer 报错 chrome: error while loading shared libraries: libpangocairo-1.0.so.0: cannot open sh ...
- [LeetCode] 253. Meeting Rooms II 会议室 II
Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si ...
- HLSL Shader编程基础总结
转自:https://blog.csdn.net/Blues1021/article/details/47093487 基本前提概念 Shader是一种映射到GPU硬件汇编语言上的高级语言,Shade ...
- 【视频开发】【Live555】live555实现h264码流RTSP传输
1.概述 liveMedia 库中有一系列类,基类是Medium,这些类针对不同的流媒体类型和编码. 其中的StreamFrame类文件(如MPEG4VideoStreamFramer)为流传输关键. ...
- idea创建一个springboot项目
第一种通过maven创建: 1.点击Create New Project 2.创建maven项目,选择jdk版本,点击next. 3.填写GroupId和ArtifactId,都是自定义的,然后点击n ...
- Oracle Spatial 中的弧段及弧相关拓扑错误
1.报告说明 此报告用于验证下列问题: ORACLE SPATIAL 0.05m的最小拓扑容差值是否可以被修改 原始数据通过ARCGIS入库数据精度是否有损失 修改ORACLE SPATIAL图层的最 ...
- 第07组 Beta冲刺(1/4)
队名:秃头小队 组长博客 作业博客 组长徐俊杰 过去两天完成的任务:学习了很多东西 Github签入记录 接下来的计划:继续学习 还剩下哪些任务:后端部分 燃尽图 遇到的困难:自己太菜了 收获和疑问: ...
- 重回ubutntu12.04小记(装完ubuntu做的几件事)
原来一直是在windows下用虚拟机跑redhat 和debian 做实验和一些工程,以前也装过ubuntu和windows双系统,但是换电脑后,就一直懒得捣鼓了. 现在,由于长期需要在linux上做 ...
- [转帖]Linux教程(8)-Linux中的进程和日志㐇、
Linux教程(8)-Linux中的进程和日志 2018-08-20 23:42:23 钱婷婷 阅读数 3554更多 分类专栏: Linux教程与操作 Linux教程与使用 版权声明:本文为博主原 ...