Mysql 锁学习笔记

Innodb锁

SQL 行锁类型说明
INSERT ...排他锁自动加锁
UPDATE ...排他锁自动加锁
DELETE ...排他锁 自动加锁
SELECT (正常)不加任何锁
SELECT ... LOCK IN SHARE MODE共享锁在 SELECT 之后加 LOCK IN SHARE MODE
SELECT ... FOR UPDATE排他锁在 SELECT 之后加 FOR UPDATE

共享锁与排它锁

以下是官网给出的定义,其实共享锁也称为读锁,排他锁可称写锁。

  • A shared (S) lock permits the transaction that holds the lock to read a row.

  • An exclusive (X) lock permits the transaction that holds the lock to update or delete a row.

翻译:

  • 共享锁是允许事务获取锁去读一行数据。
  • 排他锁是允许事务获取锁去更新或者删除一行数据。

锁兼容级别

共享锁S排它锁X
共享锁SYESNO
排它锁XNONO

注:以上YES代表可以共存,NO代表不能共存。

意向锁 - 表级锁

以下是官方给出的两种意向锁解释

  • An intention shared lock (IS) indicates that a transaction intends to set a shared lock on individual rows in a table.

  • An intention exclusive lock (IX) indicates that a transaction intends to set an exclusive lock on individual rows in a table.

翻译:

  • 意图共享锁(IS)表明事务打算对表中的单个行设置共享锁。
  • 意图排他锁(IX)表示事务打算对表中的单个行设置排他锁。

代码示例

SELECT…FOR SHARE设置IS锁,SELECT…FOR UPDATE设置一个IX锁。

The intention locking protocol is as follows:

  • Before a transaction can acquire a shared lock on a row in a table, it must first acquire an IS lock or stronger on the table.

  • Before a transaction can acquire an exclusive lock on a row in a table, it must first acquire an IX lock on the table.

意图锁定协议如下:

  • 在事务获得表中某一行的共享锁之前,它必须首先获得表上的IS锁或更强的锁。
  • 在事务获得表中某一行的排他锁之前,它必须首先获得该表上的IX锁。

表级锁类型兼容性

XIXSIS
XConflictConflictConflictConflict
IXConflictCompatibleConflictCompatible
SConflictConflictCompatibleCompatible
ISConflictCompatibleCompatibleCompatible

行锁

记录锁总是锁定索引记录,即使表没有定义索引。对于这种情况,InnoDB创建一个隐藏的聚集索引,并使用该索引进行记录锁定。

隐藏的聚集索引:MySQL :: MySQL 8.3 Reference Manual :: 17.6.2.1 Clustered and Secondary Indexes

  • 当你在一个表上定义一个PRIMARY KEY时,InnoDB使用它作为聚集索引。应该为每个表定义一个主键。如果没有逻辑上唯一且非空的列或列集可以使用主键,则添加一个自动增量列。自动递增列值是唯一的,并在插入新行时自动添加。
  • 如果你没有为一个表定义PRIMARY KEY, InnoDB使用第一个UNIQUE索引,并且所有的KEY列都定义为not NULL作为集群索引。
  • 如果一个表没有PRIMARY KEY或合适的UNIQUE索引,InnoDB会在包含行ID值的合成列上生成一个隐藏的集群索引GEN_CLUST_INDEX。这些行按照InnoDB分配的行ID排序。行ID是一个6字节的字段,随着新行插入而单调增加。因此,按行ID排序的行在物理上是按插入的顺序排列的。

代码示例

-- 事务A获取记录锁(共享锁)
START TRANSACTION;
SELECT * FROM table_name WHERE condition FOR SHARE;
-- 事务B尝试获取记录锁(排他锁)
START TRANSACTION;
SELECT * FROM table_name WHERE condition FOR UPDATE;

间隙锁

间隙锁是在索引记录之间的间隙上的锁,或者在第一个索引记录之前或最后一个索引记录之后的间隙上的锁。

如果id没有被索引,或者有一个非唯一的索引,语句将锁定前面的空白。间隙锁之间不冲突。

如果将事务隔离级别更改为READ COMMITTED,间隙锁失效。

代码示例

SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 For UPDATE;
//防止其他事务将值15插入到列t.c1中,无论列中是否已经存在这样的值,
因为范围中所有现有值之间的间隙被锁定。

临键锁 - 行锁加间隙锁

如果一个会话对索引中的记录R具有共享锁或排他锁,则另一个会话不能在索引顺序R之前的空白中插入新的索引记录。

左开右闭,即不锁住左边界,但会锁住右边界。临键锁的主要设计目的是为了解决所谓的“幻读”问题。
(-infinity, 1]
(1, 7]
(7, +infinity)

-- 使用临键锁查询数据

SELECT * FROM users WHERE id > 1 FOR UPDATE;

插入意向锁

插入意图锁是insert操作在行插入之前设置的一种间隙锁。这个锁以这样一种方式表示插入的意图,即插入到相同索引间隙中的多个事务如果不在间隙内的相同位置插入,则不需要彼此等待。

假设存在值为4和7的索引记录。分别尝试插入值为5和6的事务,在获得插入行上的排他锁之前,每个事务都用插入意图锁锁住4和7之间的间隙,但不会相互阻塞,因为行不冲突。

自增锁

AUTO-INC锁是一种特殊的表级锁,用于在具有AUTO_INCREMENT列的表中插入事务。在最简单的情况下,如果一个事务正在向表中插入值,那么任何其他事务都必须等待对该表进行自己的插入,以便第一个事务插入的行接收连续的主键值。

innodb_autoinc_lock_mode变量控制用于自动增量锁定的算法。它允许您选择如何在可预测的自动递增值序列和插入操作的最大并发性之间进行权衡。

SELECT的加锁规则 (RR)

查看锁状态命令

查看当前事务等待锁sql
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
使用sys.innodb_lock_waits系统视图(仅适用于MySQL 8.0及以上版本)
SELECT * FROM sys.innodb_lock_waits;
查看死锁信息(TRANSACTIONS)
SHOW ENGINE INNODB STATUS
查询所有进程
show processlist;
在使用的表
show open tables where in_use > 0;
查看当前出现的所有锁​​​​​​​
SELECT * FROM information_schema.INNODB_LOCKs;

3.0 前置条件

# 表结构(姓名、公司、工号)
userinfo (Id PK, username, company, usercode);

# 表中包含四条记录
5, Gates, Microsoft, 24
7, Bezos, Amazon,35
11, Jobs, Apple,37
14, Elison, Oracle,38

3.1 主键检索

1. 记录存在的情况

# 5是存在的记录,行锁
mysql> select * from userinfo where id=5 for update;

mysql> update userinfo set username = "Brand" where id = 5;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

# X 排他锁
# RECORD 记录锁
mysql> select * from performance_schema.data_lock_waits;
+---------------+-------------+
| lock_mode     | lock_type|
+---------------+-------------+
| X             | RECORD   |
+---------------+-------------+

2. 记录不存在的情况

# 6是不存在的记录,间隙锁,锁住的区间为(5,7),对应上面的前置条件
mysql> select * from userinfo where id = 6 for update;

mysql>  insert into user values(6, 'Brand', 'Ali',100);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transactio

# X 排他锁 + Gap 间隙锁
# RECORD 记录锁
mysql> select * from performance_schema.data_lock_waits;
+---------------+-------------+
| lock_mode     | lock_type|
+---------------+-------------+
| X,GAP         | RECORD   |
+---------------+-------------+

3.2 唯一索引检索

与主键检索结果一致,因为这两种都是可以唯一确定索引值和区间范围的。

3.3 普通索引检索

1. 记录存在的情况 左开右闭

# 24是存在的记录,更新行锁,插入间隙锁。24要算在内,锁住的区间为 usercode的(-oo,35]
,对应上面的前置条件
mysql> select * from userinfo where usercode = 24 for update;

mysql> insert into user values(6, 'Brand', 'Ali',25);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

# X 排他锁
# RECORD 记录锁  + Gap 间隙锁
mysql> select * from performance_schema.data_lock_waits;
+---------------+-------------+
| lock_mode     | lock_type|
+---------------+-------------+
| X,GAP         | RECORD   |
+---------------+-------------+

2. 记录不存在的情况 左开右闭

# 25是不存在的记录,间隙锁,锁住的区间为 usercode的(24,35],对应上面的前置条件
mysql> select * from userinfo where id = 25 for update;

mysql>  insert into user values(6, 'Brand', 'Ali',26);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transactio

# X 排他锁 + Gap 间隙锁
# RECORD 记录锁
mysql> select * from performance_schema.data_lock_waits;
+---------------+-------------+
| lock_mode     | lock_type|
+---------------+-------------+
| X,GAP         | RECORD   |
+---------------+-------------+

3.4 索引的范围检索

索引包括主键(默认)、唯一索引和其他普通索引

mysql> select * from userinfo where id > 4 for update;

mysql> insert into user values(66, 'Brand', 'Ali',25);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

# X 排他锁 + Gap 间隙锁
# RECORD 记录锁
mysql> select * from performance_schema.data_lock_waits;
+---------------+-------------+
| lock_mode     | lock_type|
+---------------+-------------+
| X,GAP         | RECORD   |
+---------------+-------------+

3.5 普通检索(无索引)

表锁,因为需要扫描整张表。扫描期间所有的操作都不能被获取或变更。

3.6 总结

  • 事务隔离级别为可重复读(Repeated Read, RR)
  • 以主键或唯一索引作为查询条件,有存在值(记录)时是行锁,不存在值时触发间隙锁。
  • 普通索引作为查询条件,恒定间隙锁。
  • 索引作为查询条件,并以范围取值时,产生间隙锁。
  • 无索引时的普通检索,产生表锁。

参考文章

MySQL :: MySQL 8.3 Reference Manual :: 17.7.1 InnoDB Locking

https://www.cnblogs.com/wzh2010/p/18030866

https://www.cnblogs.com/qdhxhz/p/15598873.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/569454.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SCA-CNN-LSTM多输入回归预测|正余弦优化算法-卷积-长短期神经网络|Matlab

目录 一、程序及算法内容介绍: 基本内容: 亮点与优势: 二、实际运行效果: 三、算法介绍: 四、完整程序下载: 一、程序及算法内容介绍: 基本内容: 本代码基于Matlab平台编译&am…

[笔试训练](五)

013 游游的you__牛客网 (nowcoder.com) 题目&#xff1a; 题解&#xff1a; 组成一个you需要一个o且能得2分&#xff0c;而组成相邻字母oo需要两个o&#xff0c;只能得1分。优先考虑组成尽可能多的you&#xff0c;再考虑剩下的o&#xff0c;放一起。 #include <iostream…

【C++】C++的四种类型转换

一、C语言中的类型转换 在C语言中有两种类型转换&#xff0c;隐式类型转换和显示类型转换。 如果赋值运算符左右两侧类型不同&#xff0c;或者形参与实参类型不匹配&#xff0c;或者返回值类型与接收返回值类型不一致时&#xff0c;就需要发生类型转化。 隐式类型转换&#…

汽车IVI中控开发入门及进阶(十六):carplay认证

现在有些中控采用高通的芯片如8155、8295等,实现多屏互动等,但是也有一些车型走低成本方案,比如能够实现HiCar、CarLife或者苹果Apple的Carplay等能进行手机投屏就好了。 能实现CarPlay功能通过Carplay认证,也就成了一些必须的过程,国产车规级中控芯片里,开阳有一款ARK1…

Android SDK Manager安装Google Play Intel x86 Atom_64 System Image依赖问题

Package Google Play Intel x86 Atom_64 System Image,Android API R, revision 2 depends on SDK Platform Android R Preview, revision 2 问题 一开始以为网络还有依赖包没有勾选&#xff0c;尝试了很多次&#xff0c;勾选这边报错对应的license即可。此时点击一下其他licen…

深入探索Go语言:io库的实战应用全解析

深入探索Go语言&#xff1a;io库的实战应用全解析 引言io库概览Reader接口Writer接口Closer接口Seeker接口 文件操作打开和关闭文件读取文件写入文件错误处理 数据读写技巧使用缓冲读写缓冲读取缓冲写入 复用缓冲区提高读写效率的技巧 处理I/O流网络I/O的处理创建简单的HTTP服务…

cdo 修改 calendar 为标准的格式

使用ncl脚本时出现警告&#xff1a;day_of_year: illegal calendar proleptic_gregorian 其原因是读取的降水nc文件是我手动合并生成&#xff0c;所以时间的calendar不是很标准&#xff0c;数据信息如下所示&#xff0c;可以发现Calendar是proleptic_gregorian&#xff0c;这…

前端补充17(JS)

一、JS组成成分 JS的组成成分&#xff0c;由三部分组成 第一、ECMAScript&#xff1a;语法规则&#xff0c;如何定义变量&#xff0c;数据类型有哪些&#xff0c;如何转换数据类型&#xff0c;if判断 if-else while for for-in forEach do-while switch 数组 函数 对…

Python小功能实现(链接下载图品并存储到EXCEL中)

import os import requests from openpyxl import Workbook from openpyxl.drawing.image import Image from concurrent.futures import ThreadPoolExecutor# 图片链接列表 image_urls ["https://uploads/file/20230205/f85Lpcv8PXrLAdmNUDE1Hh6xqkp0NHi2gSXeqyOb.png&q…

3月魅力彩妆行业数据分析:某国产品牌彩妆产品销额将近30亿!

彩妆行业发展多年&#xff0c;经历了多重红利期和激烈的市场竞争后&#xff0c;进入到缓慢发展时期。 根据鲸参谋数据显示&#xff0c;今年3月在线上电商平台&#xff08;淘宝天猫京东&#xff09;彩妆产品销量累计超过6700万件&#xff0c;同比去年下降了29%&#xff1b;销售…

基于spring boot学生综合测评系统

基于spring boot学生综合测评系统设计与实现 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件…

C语言 | Leetcode C语言题解之第41题缺失的第一个正数

题目&#xff1a; 题解&#xff1a; int firstMissingPositive(int* nums, int numsSize) {for (int i 0; i < numsSize; i) {while (nums[i] > 0 && nums[i] < numsSize &&nums[nums[i] - 1] ! nums[i]) {int t nums[nums[i] - 1];nums[nums[i] -…

用代码给孩子造“钱”

起因 作为家里有两个娃的奶爸&#xff0c;时长为了孩子乱花钱而焦虑不已。然后最近看到一段短视频说了这么段话。 父母不要被动给孩子买东西&#xff0c;而是定期给孩子钱。让孩子自己管钱培养她对于钱的认知和理财的观念。 突然感觉大师我悟了。感觉值得一试。于是就打算给他…

【爬虫】多线程爬取图片

多线程爬虫 多线程爬虫概述1.1 多线程的优势1.2 多线程的挑战 设计多线程爬虫1.1 项目设计1.2 项目流程1.3注意事项 总结 多线程爬虫概述 在当今信息爆炸的时代&#xff0c;网络爬虫&#xff08;Web Scraper&#xff09;已成为获取和分析网络数据的重要工具。而多线程爬虫&…

【树莓派学习】开发环境配置

【树莓派学习】开发环境配置 ​ Raspberry Pi OS作为基于Linux的系统&#xff0c;其默认网络配置在国内的网络环境下容易出现访问慢甚至无法连接等问题&#xff0c;不便于我们的学习&#xff0c;同时&#xff0c;树莓派上C/C的使用需要单独安装WiringPi。本文主要介绍如何更改…

蓄能勃发,酷开科技携酷开系统“软硬结合”提升大屏实力

智慧大屏以全新媒体形态之姿在过去几年快速增长&#xff0c;截至去年上半年&#xff0c;国内联网电视总量覆盖达5.26亿&#xff0c;其中智能电视终端活跃量达3.22亿&#xff0c;在PC、Mobile流量增长已显疲态的背景下&#xff0c;大屏的高速发展意味着一个新的赛道的崛起&#…

使用甘特图来做时间管理

在这个追求效率的时代,掌握高超的时间管理技能几乎等同于掌控了成功。事实上,时间就是金钱,更是稀缺资源。那么,如何高效地规划和利用时间呢?甘特图应该是您的必备武器之一。 甘特图(Gantt chart)名字虽然有些陌生,但它的使用范围确实广泛。无论是全职妈妈安排家务,还是上市公…

蓝桥杯-网络安全-练习题-crypto-rsa

共模攻击 直接脚本即可 import libnum import gmpy2import random random.seed(123456)e1 random.randint(100000000, 999999999) print(e1) e2 65537 n 7265521127830448713067411832186939510560957540642195787738901620268897564963900603849624938868472135068795683…

低代码技术的全面应用:加速创新、降低成本

引言 在当今数字化转型的时代&#xff0c;企业和组织面临着不断增长的应用程序需求&#xff0c;以支持其业务运营和创新。然而&#xff0c;传统的软件开发方法通常需要大量的时间、资源和专业技能&#xff0c;限制了企业快速响应市场变化和业务需求的能力。在这样的背景下&…

VS窗口固定尺寸的方法

Dialog每次都要找窗口尺寸固定的设置&#xff0c;因此在这个地方做个笔记 下次就好检索了。年级大了 脑子不够用了。
最新文章