MySQL8 间隙锁在11种情况下的锁持有情况分析
测试环境及相关必要知识
测试环境为mysql 8 版本
间隙锁(Gap Lock):用于锁定索引范围之间的间隙,防止其他事务在此间隙中插入新记录。间隙锁主要用于防止幻读问题。
在可重复读的隔离级别下默认打开该锁机制,解决幻读问题,也可手动修改配置文件关闭该锁机制,该锁机制为innodb自动决定间隙范围上锁,无需SQL显式声明锁。
表结构如下
数据如下
Mysql 运行中事务可以在表 information_schema.INNODB_TRX 中查看
Mysql 运行中事务持有的锁可以在表 performance_schema.data_locks 中查看
(一行分割两张图了)
Mysql 运行中事务等待持有锁的事务可以在表 performance_schema.data_lock_waits 中查看
LOCK MODE(锁模式)将出现的锁模式值和解释
S:共享锁(Shared Lock),允许其他事务获取相同对象的共享锁,但不允许排它锁。
X:排它锁(Exclusive Lock),在事务持有排它锁期间,其他事务无法获取相同对象的共享锁或排它锁。
IS:意向共享锁(Intention Shared Lock),表示事务准备获取一个表中某些行的共享锁。
IX:意向排它锁(Intention Exclusive Lock),表示事务准备获取一个表中某些行的排它锁。
SIX:共享意向排它锁(Shared Intention Exclusive Lock),表示事务准备获取一个表中某些行的共享锁,但也准备获取这些行的排它锁。
REC_NOT_GAP是MySQL InnoDB存储引擎中的一个特殊锁模式,用于锁定记录(行)而非间隙(gap)
注意:接下来将看到很多意向锁,意向排他锁并不等于持有了排它锁,只是表明有持有该锁的意向!
LOCK TYPE(锁类型)可能出现的是RECORD (行锁)、TABLE(表锁)
下面的各种情况下MySQL InnoDB锁持有情况的结构是先展示SQL,后展示持有锁的截图
持有锁截图中重要的字段为INDEX_NAME 索引名 LOCK_TYPE 锁类型 LOCK_MODE 锁模式 LOCK_STATUS 锁状态 LOCK_DATA 锁数据
走唯一索引的主键id+指定值+有值情况
begin ;
select * from t_gap_demo where id = 3 for update ;
结果:对id=3的行记录上了行排他锁,当前表的意向排他锁
走唯一索引的主键id+指定值+无值情况
begin ;
select * from t_gap_demo where id = 4 for update ;
插入id=4数据被阻塞,证明(3,]间隙已被锁定,插入id=8数据成功,插入id=2数据成功
结果:对数据7持有了排他锁、间隙锁范围为(3,7] 左开右闭原则
走唯一索引的主键id+指定范围+有值情况
begin ;
select * from t_gap_demo where id between 3 and 8 for update ;
结果:持有了主键索引上的1、3、7、15四行的行锁且无间隙锁,持有表排它锁意向锁,额外还持有了普通索引age上的所有值的排它锁及间隙锁(0到正无穷都锁住了,这个字段没有负数)
这个结果挺让人震惊的,这句SQL居然持有了这么多锁,而且我测试插入id=2,age=1的记录是无法插入的,一直被阻塞。证明age整个范围的间隙锁都是被锁住了的,无法插入任何数据。
额外我还测试了一下该情况下update语句的锁情况
begin ;
update t_gap_demo set age = 1 where id between 3 and 8 ;
结果是锁住了(3,7] (7,15]间隙锁,3、7、15行锁,附带基本的表排他锁意向锁,至于为啥select语句时锁住了整个age间隙,还需要后续研究,有懂的大佬评论一下
走唯一索引的主键id+指定范围+无值情况
begin ;
select * from t_gap_demo where id between 18 and 28 for update ;
id = 14可以插入,id = 16无法插入,阻塞
结果:持有了排它锁,锁住最后一行记录15到正无穷
begin ;
select * from t_gap_demo where id between 10 and 12 for update ;
于是我又好奇假设这个区间无值,但是属于某个间隙呢
结果:持有了这个范围所在间隙的间隙锁 (7,15],15这个行记录的排它锁,表意向排它锁
走普通索引的age+指定值+有值情况
begin ;
select * from t_gap_demo where age = 3 for update ;
结果:主键id=1的记录行锁排它锁锁定、普通索引上3,1 6,3全部锁定行记录加间隙,表意向排它锁
走普通索引的age+指定值+无值情况
begin ;
select * from t_gap_demo where age = 4 for update ;
结果:持有了这个不存在的id处于的这个间隙的间隙锁和两个行记录的排它锁,表意向排它锁
走普通索引的age+指定范围+有值情况
begin ;
select * from t_gap_demo where age between 20 and 40 for update ;
结果:持有了整个范围涉及的间隙的间隙锁、涉及行的排他锁,涉及行记录的主键记录的排它锁(不带间隙锁),表意向排它锁
走普通索引的age+指定范围+无值情况
begin ;
select * from t_gap_demo where age between 78 and 88 for update ;
结果:持有age记录最大值到正无穷的间隙锁,表意向排它锁
拓展:非索引字段范围锁定
begin ;
select * from t_gap_demo where age between 1 and 15 for update ;
结果:持有了整个id范围内所有行记录的排它锁和所在区间(包括左右无穷)的间隙锁,尝试插入id=2,id=16记录都是阻塞状态
总结
经过各种情况下事务对数据的加排它锁测试发现,mysql 8 innodb引擎会对涉及的数据和间隙都加上排他、间隙锁,甚至在普通索引时还会对涉及数据的主键索引也加上不带间隙锁的排它锁(X,REC_NOT_GAP),在非索引字段范围锁定时会对整个数据和间隙锁定,这告诉我们在使用时要注意,追求性能时少使用悲观锁,尽量避免锁竞争、避免死锁,尽量走主键索引或索引、尽量少锁定资源或只锁定最小范围数据、尽量精确操作某行数据,尽量让事务执行时间短,尽量避免同时事务并发操作同间隙内数据以避免死锁。
相关文章:

MySQL8 间隙锁在11种情况下的锁持有情况分析
测试环境及相关必要知识 测试环境为mysql 8 版本 间隙锁(Gap Lock):用于锁定索引范围之间的间隙,防止其他事务在此间隙中插入新记录。间隙锁主要用于防止幻读问题。 在可重复读的隔离级别下默认打开该锁机制,解决幻…...
C# 图片按比例进行压缩
1、对图片进行压缩,保存在本地 对于一个200k的png文件按0.6的缩放比例进行压缩,压缩后的大小为20k左右 对于一个80k的jpg文件按0.6的缩放比例压缩,压缩后为13k左右 public void imageZoom(string name, Double zoomScale){Bitmap btImage …...

猜猜 JavaScript 输出:(! + [] + [] + ![]).length
一起猜 最近看到一个很有意思的题,直接来看,下面这段代码的打印结果是什么? console.log((! [] [] ![]).length) 猜猜看,你的答案是什么,打在评论区。 我的答案是 undefined,正如我的英文名 为什么呢&a…...
MTK Android12静默安装接口
该文档就是在android12系统上提供一个广播接收器,app端发送一个广播,并且带入apk的地址就可以实现安装 1、广播注册 frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.java 首先要导入的依赖 import android.app.P…...

基于电容电流前馈与电网电压全前馈的三相LCL并网逆变器谐波抑制Simulink仿真
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
Python数据攻略-Pandas与统计数据分析
统计学在数据分析中到底有多重要?在数据分析的世界里,统计学扮演着一角色。想象一下你是《三国志》游戏的数据分析师,任务是找出哪个武将最受玩家欢迎,哪些战役最具挑战性等。 你怎么做呢?这就需要统计学的力量了。 文章目录 基础统计方法描述性统计方差和标准差相关性和…...

【gcc】RtpTransportControllerSend学习笔记 1
本文是大神 https://www.cnblogs.com/ishen 的文章的学习笔记。主要是大神文章: webrtc源码分析(8)-拥塞控制(上)-码率预估 的学习笔记。大神的webrtc源码分析(8)-拥塞控制(上)-码率预估 详尽而具体,堪称神作。因为直接看大神的文章,自己啥也没记住,所以同时跟着看代码。跟…...

若依分离版-前端使用
1 执行 npm install --registryhttps://registry.npm.taobao.org,报错信息如下 npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: ktg-mes-ui3.8.2 npm ERR! Found: vue2.6.12 npm ERR! node_modu…...

微信小程序-2
微信开发文档 https://developers.weixin.qq.com/miniprogram/dev/framework/ 一、app.js中的生命周期函数与globalData(全局变量) 指南 - - - 小程序框架 - - - 注册小程序 删除app.js里的东西,输入App回车,调用生命周期 选项 - - - 重新打开此项目…...

卷积神经网络的发展历史-ResNet
ResNet的产生 2015 年,Kaiming He 提出了ResNet(拿到了 2016 年 CVPR Best Paper Award),不仅解决了神经网络中的退化问题还在同年的ILSVRC和COCO 竞赛横扫竞争对手,分别拿下分类、定位、检测、分割任务的第一名。 R…...

基于瞬时无功功率ip-iq的谐波信号检测Simulink仿真
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
node安装,nvm管理器
一、下载nvm,nvm-setup.exe https://github.com/coreybutler/nvm-windows/releases 二、配置NodeJS下载代理镜像(可选) 可以在NVM安装根目录下的setting.txt文件中,配置NodeJS下载代理镜像,解决在线安装NodeJS时速度…...

华为云云耀云服务器L实例评测|Ubuntu云锁防火墙安装搭建使用
华为云云耀云服务器L实例评测|Ubuntu安装云锁防火墙对抗服务器入侵和网络攻击 1.前言概述 华为云耀云服务器L实例是新一代开箱即用、面向中小企业和开发者打造的全新轻量应用云服务器。多种产品规格,满足您对成本、性能及技术创新的诉求。云耀云服务器L…...

C# OpenCvSharp 实现迷宫解密
效果 项目 代码 using OpenCvSharp; using System; using System.Drawing; using System.Windows.Forms;namespace OpenCvSharp_实现迷宫解密 {public partial class Form1 : Form{public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e…...

趣味工具箱小程序源码
趣味工具箱小程序源码,支持功能去水印,精选壁纸,图片压缩,文字生成二维码,图片加水印,模拟来电,手持弹幕,掷骰子…等 使用小工具,一个小程序有几十个功能。 源码下载&am…...

互联网Java工程师面试题·Redis 篇·第二弹
目录 16、Redis 集群方案什么情况下会导致整个集群不可用? 17、Redis 支持的 Java 客户端都有哪些?官方推荐用哪个? 18、Jedis 与 Redisson 对比有什么优缺点? 19、Redis 如何设置密码及验证密码? 20、说说 Redis…...
FreeRTOS入门教程(信号量的概念及API函数使用)
文章目录 前言一、什么是信号量二、信号量种类和对比三、信号量和队列的区别四、信号量相关的函数1.创建函数2.删除函数3.获取和释放信号量函数 总结 前言 本篇文章正式带大家开始学习什么是信号量,并且掌握信号量函数的基本使用方法,并且将和队列进行一…...

简易版Pycharm(2023)+Conda开发环境配置教程
困 扰 不知道为什么,自从Pycharm更新了新的版本以后,在Pycharm中为项目工程配置Python解释器环境时,总是不能像以前那么方便的配置。 比如,当前Conda中有十个不同的开发环境,每个环境一个名称,比如&#x…...

深入浅出,SpringBoot整合Quartz实现定时任务与Redis健康检测(二)
前言 在上一篇深入浅出,SpringBoot整合Quartz实现定时任务与Redis健康检测(一)_往事如烟隔多年的博客-CSDN博客 文章中对SpringBoot整合Quartz做了初步的介绍以及提供了一个基本的使用例子,因为实际各自的需求任务不尽相同因此并…...

小谈设计模式(22)—单例模式
小谈设计模式(22)—单例模式 专栏介绍专栏地址专栏介绍 单例模式点睛所在优缺点分析优点确保只有一个实例全局访问点节省资源线程安全 缺点难以扩展对象的生命周期单一职责原则隐藏依赖关系 Java程序实例实例a分析实例b,更安全分析优化 ——“…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...

《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...

恶补电源:1.电桥
一、元器件的选择 搜索并选择电桥,再multisim中选择FWB,就有各种型号的电桥: 电桥是用来干嘛的呢? 它是一个由四个二极管搭成的“桥梁”形状的电路,用来把交流电(AC)变成直流电(DC)。…...
Vue3中的computer和watch
computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...

6.9-QT模拟计算器
源码: 头文件: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMouseEvent>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);…...