Mysql的加锁情况详解
最近在复习mysql的知识点,像索引、优化、主从复制这些很容易就激活了脑海里尘封的知识,但是在mysql锁的这一块真的是忘的一干二净,一点映像都没有,感觉也有点太难理解了,但是还是想把这块给啃下来,于是想通过这篇文章把复盘过程中所有的知识点给记录下来,特别是实操部分
文章目录
- 一、mysql的锁介绍
- 共享锁
- 排他锁
- 记录锁(Record Locks)
- 间隙锁
- 临键锁
- 二、加锁情况实操
- 1. 表无显式主键和索引
- 数据准备
- 不加任何查询条件的查询
- 添加条件查询
- 2. 表有显式主键无索引
- 数据准备
- 不带任何条件的查询
- 通过id查询
- 3. 表无显式主键有索引
- 数据准备
- 不带任何条件的查询
- 带普通索引ID的查询
- 带唯一索引的id查询
- 4.表有显式主键和普通索引
- 数据准备
- 不带任何条件的查询
- where条件是普通索引字段
- where条件是主键字段
- where条件同时包含普通索引字段和主键索引字段
- 5.表有显式主键和唯一索引
- 数据准备
- 不带条件查询
- where条件是唯一索引字段
- where条件是主键
- where条件是主键和唯一索引
- 总结
一、mysql的锁介绍
mysql里有一堆锁,但是会存在一些概念上的交叉,所以这里只列举出常用的,或者说面试中常问的锁进行介绍,如下:
共享锁
共享锁又叫读锁,S锁,加了共享锁的数据还可以被其他事务加共享锁,但是不能被其他事务加排他锁,主要用于保证数据在读取过程中的一致性。可通过lock in share mode显示的给sql加上共享锁
select * from t lock in share mode;
排他锁
排他锁又叫写锁,X锁,加了排他锁的数据不能被其他事务再加排他锁或者共享锁,直到该排他锁被释放;可以通过for update显示的给sql加排他锁,当然,实际工作中不会使用for update,mysql在执行update、insert、delete等DML操作的时候会自动加排他锁;
select * from t for update;
记录锁(Record Locks)
记录锁也可以理解成行锁,作用在索引上,只锁某一行记录
间隙锁
间隙锁锁定的是索引记录锁之间的间隙,或者是索引最小值之前后者最大值之后的间隙,只在RR级别以上被使用;只阻止其他事务插入到间隙中,他们不阻止其他事务在同一个间隙上获得间隙锁
临键锁
临键锁=记录锁+间隙锁
二、加锁情况实操
约定:
- 关闭事务自动提交,我们需要在事务里观察加锁情况:set autocommit=0
- 使用show engine innodb status\G观察锁的情况
- 查看mysql关于锁日志的输出是否打开(默认关闭):show variables like ‘innodb_status_output%’;
- 打开开关:set global innodb_status_output_locks=on; set global innodb_status_output=on;
- 只演示mysql的默认隔离界别RR下锁的情况,RC隔离级别大部分加的都是行锁
- mysql的表一定会有聚簇索引的,有主键使用主键作为聚簇索引,没主键使用唯一且非空列作为聚簇索引,否则使用自己维护的rowid作为聚簇索引
- mysql的锁都是加在索引上的
1. 表无显式主键和索引
数据准备
create table t(id int default null,name char(20) default null);
insert into t values(10,'10'),(20,'20'),(30,'30');
不加任何查询条件的查询
- sql
begin;
select * from t for update;
show engine innodb status\G
- 图示

- 分析
- 表t没有主键没有唯一非空列,所以会创建一条聚簇索引
- 查询的是全表,没有限制任何条件,所以加的是聚簇索引的临键锁,由于聚簇索引是rowid,所以范围这里我们看不懂
- 由于没有主键和索引,所以加上条件的查询和不加条件是一样的,这里就不再重复展示了
添加条件查询
- sql
begin;
select * from t where id = 10 for update;
show engine innodb status\G
- 图示同上
- 分析
- 可以发现,从结果上课与不加条件加锁情况是一致的,都是加的聚簇索引的临键锁;
- 限制了条件和全表查询一样是因为mysql锁是加在索引上的,并不是加在数据10上的;
- 不加的话理论上在插入一条id=10的记录也是可以的,这一就出现幻读了
2. 表有显式主键无索引
数据准备
create table t2(id int primary key not null,name char(20) default null);
insert into t2 values(10,'10'),(20,'20'),(30,'30');
不带任何条件的查询
- sql
begin;
select * from t2 for update;
show engine innodb status\G
- 图示

- 分析
- 结果与1中一样,区别在于这里的id是主键,聚簇索引就是id了,在图里就能显示的看到临建锁的范围了,虽然是16进制的,转换后就是表里对应的10,20,30
通过id查询
- sql
begin;
select * from t2 where id = 10 for update;
show engine innodb status\G
- 图示

- 分析
- 可以看到,此情况只加了id的记录锁,因为id就是聚簇索引,锁住这一行记录就可以了
3. 表无显式主键有索引
数据准备
create table t3(id int default null,name char(20) default null);
create index idx_id on t3(id);
insert into t3 values(10,'10'),(20,'20'),(30,'30');
不带任何条件的查询
与1.2类似,加的都是聚簇索引的临键锁
带普通索引ID的查询
- sql
begin;
select * from t3 where id = 10 for update;
show engine innodb status\G
- 图示

- 分析
- 如图,会加聚簇索引的记录所,id的临建锁,id的间隙锁,锁的范围如上图,由此可见我们此时可以插入30之后的数据,不能插入10之前的数据,如下图:

- 如图,会加聚簇索引的记录所,id的临建锁,id的间隙锁,锁的范围如上图,由此可见我们此时可以插入30之后的数据,不能插入10之前的数据,如下图:
带唯一索引的id查询
- sql
create table t4(id int default null,name char(20) default null);
create unique index idx_id on t4(id);
insert into t4 values(10,'10'),(20,'20'),(30,'30');
begin;
select * from t4 where id = 10 for update;
show engine innodb status\G
- 图示

- 分析
- 因为是唯一索引,且可以为空,所以mysql还会创建聚簇索引,所以此时加的是唯一索引id的记录锁,聚簇索引
4.表有显式主键和普通索引
数据准备
create table t5(id int not null,name char(20) default null,primary key(id),key idx_name(name));
insert into t5 values(10,'10'),(20,'20'),(30,'30');
不带任何条件的查询
- sql
begin;
select * from t5 for update;
show engine innodb status\G
-
图示

-
分析
- 主键id的记录锁(锁表里的每行记录),普通索引name的临键锁
where条件是普通索引字段
- sql
begin;
select * from t5 where name='10' for update;
show engine innodb status\G
- 图示

- 分析
- 主键id的记录锁(锁id=10一条记录)、普通索引name的临键锁,范围:(-∞,10],普通索引name的间隙锁:(10,20)
where条件是主键字段
- sql
begin;
select * from t5 where id=10 for update;
show engine innodb status\G
-
图示

-
分析
- 查询条件是主键的话就简单了,直接加id的记录锁即可
where条件同时包含普通索引字段和主键索引字段
- sql
begin;
select * from t5 where id=10 and name='10' for update;
show engine innodb status\G
- 分析
- 与单查主键一致,都只是上主键id的记录锁
5.表有显式主键和唯一索引
数据准备
create table t6(id int not null,name char(20) default null,primary key(id),unique key idx_name(name));
insert into t6 values(10,'10'),(20,'20'),(30,'30');
不带条件查询
- sql
begin;
select * from t6 for update;
show engine innodb status\G
- 图示

- 分析
与普通索引类似,会加主键的记录锁,锁定表里的每条记录,然后加唯一索引的临键锁,范围是:(-∞,10],(10,20],(20,30],(30,10)
where条件是唯一索引字段
- sql
begin;
select * from t6 where name='10' for update;
show engine innodb status\G
- 图示

- 分析
- 两个行锁,分别是主键索引的行锁和唯一索引的行锁
where条件是主键
- sql
begin;
select * from t6 where id=10 for update;
show engine innodb status\G
- 分析
- 只会加主键的行锁
where条件是主键和唯一索引
- sql
begin;
select * from t6 where id=10 and name='10' for update;
show engine innodb status\G
- 分析
- 与只加主键一致,还是只会加主键的行锁;一般涉及到主键的查询都会只锁主键的行锁
总结
至此,mysql加锁的分析就结束了,其实挺绕的,实际总是与自己想的不一致,但是要秉持一个原则,就是mysql的锁除了保证并发事务的情况下对数据的安全读写外,还会用来解决幻读问题;有时候从幻读的角度出发,那么也就理解了为什么会这样加锁了
相关文章:
Mysql的加锁情况详解
最近在复习mysql的知识点,像索引、优化、主从复制这些很容易就激活了脑海里尘封的知识,但是在mysql锁的这一块真的是忘的一干二净,一点映像都没有,感觉也有点太难理解了,但是还是想把这块给啃下来,于是想通…...
hive3.1.2编译spark3安装包
此安装包是《去破解站长》在公司真实生产环境所使用的安装包。 引言:Hive引擎包括:默认MR、tez、sparkDownload:www.qupojie.com 1、Hive on Spark 1、Hive onSpark:Hive既作为存储元数据又负责SQL的解析优化,语法是HQL语法&…...
网络安全,文明上网(1)享科技,提素养
前言 在这个信息化飞速发展的时代,科技的快速进步极大地丰富了我们的生活,并为我们提供了无限的可能性。然而,随着网络世界的不断扩张,增强我们的网络素养成为了一个迫切需要解决的问题。 与科技同行,培育网络素养 技术…...
ESP32 烧录问题
ESP32 烧录问题 1.无法连接 Connecting......................................A fatal error occurred: Failed to connect to ESP32: No serial data received.这个表示通过串口连接esp32失败,可能存在多种原因,比如串口选择错误。 所选串口不是连接…...
CnosDB 实时流式计算:优化时序数据处理与降采样解决方案
在处理时序数据时,数据写入周期通常与数据采集设备的频率相关,有时每秒钟就需要处理大量的数据点。长时间处理如此多的数据会导致存储问题。一个有效的解决方案是使用流式计算,将原始数据进行降采样。 流式计算在时序数据库中指对实时数据流…...
ApiChain 从迭代测试用例到项目回归测试 核心使用教程
项目地址:ApiChain 项目主页 环境变量 环境变量是在特定的开发环境(开发、测试、uat等)下,保存的一份数据集,环境变量是发送网络请求或者执行单测的一个重要数据源。环境变量根据作用范围可以分为全局环境变量、项目…...
数据集-目标检测系列- 花卉 玫瑰 检测数据集 rose >> DataBall
数据集-目标检测系列- 花卉 玫瑰 检测数据集 rose >> DataBall DataBall 助力快速掌握数据集的信息和使用方式,会员享有 百种数据集,持续增加中。 贵在坚持! 数据样例项目地址: * 相关项目 1)数据集可视化项…...
django从入门到实战(四)——模型与数据库
1. 模型的定义与数据迁移 1.1 模型的定义 在 Django 中,模型是一个 Python 类,用于定义数据库中的数据结构。每个模型类对应数据库中的一张表,类的属性对应表中的字段。 示例: from django.db import modelsclass Blog(models…...
LeetCode:1008. 前序遍历构造二叉搜索树
目录 题目描述: 代码: 第一种: 第二种: 第三种:分治法 题目描述: 给定一个整数数组,它表示BST(即 二叉搜索树 )的 先序遍历 ,构造树并返回其根。 保证 对于给定的测试用例,总是有可能找到具有给定需求的二叉搜索树。 二叉搜索树 是一棵…...
gdb - 调试工具 - 入门 (一)
GDB(GNU Debugger)是GNU项目调试器的缩写,它是Linux下一个强大的C/C(以及其他语言如Fortran)程序调试工具。以下是对GDB的详细解释: 一、GDB的功能 GDB允许开发者对程序执行进行深入控制,可以…...
Swift内存访问冲突
内存的访问,发生在给变量赋值的时候,或者传递值(给函数)的时候,例如 var one 1//向one的内存区域发起一次写的操作 print("\(one)")//向one的内存区域发起一次读的操作 在 Swift 里,有很多修改…...
深入理解Spring(三)
目录 2.1.3、Spring配置非自定义Bean 1)配置Druid数据源交由Spring管理 2)配置Connection交由Spring管理 3)配置日期对象交由Spring管理 4)配置MyBatis的SqlSessionFactory交由Spring管理 2.1.4、Bean实例化的基本流程 1)Bean信息定义对象-BeanDefinition 2)DefaultLi…...
TB6612电机驱动模块使用指南
实物图: 简介:TB6612是一款双路H桥型直流电机驱动模块,可以控制两个直流电机的转速和方向 H桥:(双路H桥就是有两个这个结构) 引脚图:...
Paper -- 洪水深度估计 -- 利用图像处理和深度神经网络绘制街道照片中的洪水深度图
基本信息 论文题目:Flood depth mapping in street photos with image processing and deep neural networks 中文题目: 利用图像处理和深度神经网络绘制街道照片中的洪水深度图 作者及单位: Bahareh Alizadeh Kharazi,美国得克萨斯州立大…...
学习C#中的BackgroundWorker 组件
1. BackgroundWorker 组件概述 许多经常执行的操作可能需要很长的执行时间。 例如: 图像下载 Web 服务调用 文件下载和上载(包括点对点应用程序) 复杂的本地计算 数据库事务 本地磁盘访问(相对于内存访问来说其速度很慢&…...
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
大家好,欢迎来到程序视点!我是小二哥! 前言 在VUE项目开发中,一些数据常常被多个组件频繁使用,为了管理和维护这些数据,就出现了状态管理模式。 今天小二哥要给大家推荐的不是VueX,而是称为新…...
PCB 间接雷击模拟
雷击是一种危险的静电放电事件,其中两个带电区域会瞬间释放高达 1 千兆焦耳的能量。雷击就像一个短暂而巨大的电流脉冲,会对建筑物和电子设备造成严重损坏。雷击可分为直接和间接两类,其中间接影响是由于感应能量耦合到靠近雷击位置的物体。间…...
JAVA泛型和顺序表ArrayList
目录 泛型 泛型的定义: 泛型的实例化: 泛型的使用: 顺序表ArrayList 顺序表ArrayList的两种实例化方法: ArrayList常用的方法: 1. add 方法 2. size ( ) 方法 3. get 方法 4. set 方法 5. 顺序表的三种遍历元素的方法…...
Qt桌面应用开发 第六天(鼠标事件 定时器事件 定时器类 事件分发器 事件过滤器)
目录 1.1鼠标进入和离开enterEvent\leaveEvent 1.2鼠标按下释放和移动mousePressEvent\mouseReleaseEvent\mouseMoveEvent 1.3定时器事件timerEvent 1.4定时器类QTimer 1.5事件分发器event 1.6事件过滤器eventFilter 1.1鼠标进入和离开enterEvent\leaveEvent 事件&#x…...
Javascript高级—深入JS模板字符串的高级用法
深入JS模板字符串的高级用法:解锁动态内容生成的无限可能 在JavaScript编程中,模板字符串(Template Literals)自ES6(ECMAScript 2015)引入以来,就以其简洁、直观的特性迅速成为开发者们生成动态…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
