mysql锁机制详解

第71讲:MySQL锁机制详解:表级锁、元数据锁和意向锁的全面解析与实践指南 如下图所示,在多个并发客户端的情况下,第一个客户端开启了表共享读锁,那么DQL查询操作在多个客户端上都可以查询数据,不受影响,但是当有DDL/DML类的修改表数据的操作时,第一个客户端直接会提示表中存在锁,第二个客户端的写操作会处于阻塞状态,当第一个客户端释放锁之后,第二个客户端的写操作才能正常执行。共享读锁不会影响其他客户端的读,但是会阻塞其他客户端的写。 阅读详情

前言

  之前项目中用到事务,需要保证数据的强一致性,期间也用到了mysql的锁,但当时对mysql的锁机制只是管中窥豹,所以本文打算总结一下mysql的锁机制。

  本文主要论述关于mysql锁机制,mysql版本为5.7,引擎为innodb,由于实际中关于innodb锁相关的知识及加锁方式很多,所以没有那么多精力罗列所有场景下的加锁过程并加以分析,仅根据现在了解的知识,结合官方文档,说说自己的理解,如果发现有不对的地方,欢迎指正。

概述

  总的来说,InnoDB共有七种类型的锁:

  • 共享/排它锁(Shared and Exclusive Locks)
  • 意向锁(Intention Locks)
  • 记录锁(Record Locks)
  • 间隙锁(Gap Locks)
  • 临键锁(Next-key Locks)
  • 插入意向锁(Insert Intention Locks)
  • 自增锁(Auto-inc Locks)

mysql锁详解

1. 共享/排它锁(Shared and Exclusive Locks)

  • 共享锁(Share Locks,记为S锁),读取数据时加S锁
  • 排他锁(eXclusive Locks,记为X锁),修改数据时加X锁

  使用的语义为:

  • 共享锁之间不互斥,简记为:读读可以并行
  • 排他锁与任何锁互斥,简记为:写读,写写不可以并行

  可以看到,一旦写数据的任务没有完成,数据是不能被其他任务读取的,这对并发度有较大的影响。对应到数据库,可以理解为,写事务没有提交,读相关数据的select也会被阻塞,这里的select是指加了锁的,普通的select仍然可以读到数据(快照读)。

2. 意向锁(Intention Locks)

  InnoDB为了支持多粒度锁机制(multiple granularity locking),即允许行级锁与表级锁共存,而引入了意向锁(intention locks)。意向锁是指,未来的某个时刻,事务可能要加共享/排它锁了,先提前声明一个意向。

  1. 意向锁是一个表级别的锁(table-level locking);
  2. 意向锁又分为:
  3. 意向共享锁(intention shared lock, IS),它预示着,事务有意向对表中的某些行加共享S锁;
  4. 意向排它锁(intention exclusive lock, IX),它预示着,事务有意向对表中的某些行加排它X锁;

  加锁的语法为:

select ... lock in share mode;  要设置IS锁;
select ... for update;       要设置IX锁;

  事务要获得某些行的S/X锁,必须先获得表对应的IS/IX锁,意向锁仅仅表明意向,意向锁之间相互兼容,兼容互斥表如下:

 

IS

IX

IS

兼 容

兼 容

IX

兼 容

兼 容

  虽然意向锁之间互相兼容,但是它与共享锁/排它锁互斥,其兼容互斥表如下:

 

S

X

IS

兼 容

互 斥

IX

互 斥

互 斥

  排它锁是很强的锁,不与其他类型的锁兼容。这其实很好理解,修改和删除某一行的时候,必须获得强锁,禁止这一行上的其他并发,以保障数据的一致性。

分享更多关于C/C++ Linux后端开发网络底层原理知识学习提升 学习资料,完善技术栈,内容知识点包括Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等等。

 

 

3. 记录锁(Record Locks)

  记录锁,它封锁索引记录,例如(其中id为pk):

create table lock_example(id smallint(10),name varchar(20),primary key id)engine=innodb;

  数据库隔离级别为RR,表中有如下数据:

10, zhangsan
20, lisi
30, wangwu
select * from t where id=1 for update;

  其实这里是先获取该表的意向排他锁(IX),再获取这行记录的排他锁(我的理解是因为这里直接命中索引了),以阻止其他事务插入,更新,删除id=1的这一行。

4. 间隙锁(Gap Locks)

  间隙锁,它封锁索引记录中的间隔,或者第一条索引记录之前的范围,又或者最后一条索引记录之后的范围。依然是上面的例子,InnoDB,RR:

select * from lock_example
    where id between 8 and 15 
    for update;

  这个SQL语句会封锁区间(8,15),以阻止其他事务插入id位于该区间的记录。

  间隙锁的主要目的,就是为了防止其他事务在间隔中插入数据,以导致“不可重复读”。如果把事务的隔离级别降级为读提交(Read Committed, RC),间隙锁则会自动失效。

5. 临键锁(Next-key Locks)

  临键锁,是记录锁与间隙锁的组合,它的封锁范围,既包含索引记录,又包含索引区间。

  默认情况下,innodb使用next-key locks来锁定记录。但当查询的索引含有唯一属性的时候,Next-Key Lock 会进行优化,将其降级为Record Lock,即仅锁住索引本身,不是范围。

  举个例子,依然是如上的表lock_example,但是id降级为普通索引(key),也就是说即使这里声明了要加锁(for update),而且命中的是索引,但是因为索引在这里没有UK约束,所以innodb会使用next-key locks,数据库隔离级别RR:

事务A执行如下语句,未提交:
select * from lock_example where id = 20 for update;

事务B开始,执行如下语句,会阻塞:
insert into lock_example values('zhang',15);
insert into lock_example values('zhang',15);

  如上的例子,事务A执行查询语句之后,默认给id=20这条记录加上了next-key lock,所以事务B插入10(包括)到30(不包括)之间的记录都会阻塞。临键锁的主要目的,也是为了避免幻读(Phantom Read)。如果把事务的隔离级别降级为RC,临键锁则也会失效。

6. 插入意向锁(Insert Intention Locks)

  对已有数据行的修改与删除,必须加强互斥锁(X锁),那么对于数据的插入,是否还需要加这么强的锁,来实施互斥呢?插入意向锁,孕育而生。

  插入意向锁,是间隙锁(Gap Locks)的一种(所以,也是实施在索引上的),它是专门针对insert操作的。多个事务,在同一个索引,同一个范围区间插入记录时,如果插入的位置不冲突,不会阻塞彼此。

Insert Intention 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.

  举个例子(表依然是如上的例子lock_example,数据依然是如上),事务A先执行,在10与20两条记录中插入了一行,还未提交:

insert into t values(11, xxx);

  事务B后执行,也在10与20两条记录中插入了一行:

insert into t values(12, ooo);

  因为是插入操作,虽然是插入同一个区间,但是插入的记录并不冲突,所以使用的是插入意向锁,此处A事务并不会阻塞B事务。

7. 自增锁(Auto-inc Locks)

  自增锁是一种特殊的表级别锁(table-level lock),专门针对事务插入AUTO_INCREMENT类型的列。最简单的情况,如果一个事务正在往表中插入记录,所有其他事务的插入必须等待,以便第一个事务插入的行,是连续的主键值。

AUTO-INC lock is a special table-level lock taken by transactions inserting into tables with AUTO_INCREMENT columns. In the simplest case, if one transaction is inserting values into the table, any other transactions must wait to do their own inserts into that table, so that rows inserted by the first transaction receive consecutive primary key values.

  举个例子(表依然是如上的例子lock_example),但是id为AUTO_INCREMENT,数据库表中数据为:

1, zhangsan
2, lisi
3, wangwu

  事务A先执行,还未提交: insert into t(name) values(xxx);

  事务B后执行: insert into t(name) values(ooo);

  此时事务B插入操作会阻塞,直到事务A提交。

总结

  以上总结的7种锁,个人理解可以按两种方式来区分:

  1. 按锁的互斥程度来划分,可以分为共享、排他锁;

  • 共享锁(S锁、IS锁),可以提高读读并发;
  • 为了保证数据强一致,InnoDB使用强互斥锁(X锁、IX锁),保证同一行记录修改与删除的串行性;

  2. 按锁的粒度来划分,可以分为:

  • 表锁:意向锁(IS锁、IX锁)、自增锁;
  • 行锁:记录锁、间隙锁、临键锁、插入意向锁;

  其中

  1. InnoDB的细粒度锁(即行锁),是实现在索引记录上的(我的理解是如果未命中索引则会失效);  
  2. 记录锁锁定索引记录;间隙锁锁定间隔,防止间隔中被其他事务插入;临键锁锁定索引记录+间隔,防止幻读;
  3. InnoDB使用插入意向锁,可以提高插入并发;
  4. 间隙锁(gap lock)与临键锁(next-key lock)只在RR以上的级别生效,RC下会失效;

分享更多关于C/C++ Linux后端开发网络底层原理知识学习提升 学习资料,完善技术栈,内容知识点包括Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等等。

视频学习资料点击:C/C++Linux服务器开发/Linux后端开发架构师-学习视频

mysql的锁机制详解 *锁是计算机协调多个进程或线程并发访问某一资源的机制。**在数据库中,除传统的 计算资源(如CPU、RAM、I/O等)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一 个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。相对其他数据库而言,MySQL的锁机制比较简单,其最 显著的特点是不同的存储引擎支持不同的锁机制。 阅读详情

相关推荐

自动化测试软件设计:C# + VISA 库实现多接口(GPIB/USB)测试仪器控制

本文介绍了如何利用C#和VISA库开发支持多接口的自动化测试软件。VISA库作为标准化API,能够统一控制GPIB、USB等不同接口的测试设备。文章详细阐述了软件设计目标,包括多接口支持、统一控制、自动化脚本执行等功能。重点讲解了C#中VISA库的安装配置,并提供了设备控制类的核心代码实现,涵盖设备连接、命令发送、响应读取等关键操作。通过具体示例展示了GPIB和USB设备的连接方式,并扩展了自动化测试脚本功能。该方案具有高扩展性和维护性,适用于电子设备测试、生产线检测等多种场景,为自动化测试系统开发提供了实

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1714

Mysql锁详解(行锁、表锁、意向锁、Gap锁、插入意向锁)

mysql

qq_23350817的博客 2966

STM32HAL库学习笔记九——LCD显示

本文不会对驱动编写做特别详细的描述,以记录CubeMX的部署流程为主。

weixin_44762233的博客 6919

很经典的C++知识

Overload和Override的区别,Overload方法是否可以改变返回值类型? 答:Overload是重载的意思,Override是覆盖的意思,也就是重写。 (1)重载Overload表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同),重载发生在同一个类中。 (2)重写Override表示子类中的方法可以与父类中的某个方法的名称和参数完全相同

FeelTouch Labs 1993

【AI实践】Dify调用本地和在线模型服务

Ollama可以本地部署模型,如何集成私有数据、如何外部应用程序对接,因此需要有一个应用开发框架。ip地址需要换成自己电脑的IP地址;模型名称需要和Ollama模型名称保持一致;docker是虚拟环境的主机,Ollama部署在本地主机,无法通过本机访问。找到Ollama,配置本地Ollama已经验证的模型,如phi3。在docker页面里面,也可以看到running。docker已经安装完成的情况下。,打开dify,注册登录后。在工作区选择调用即可。

AI_Gump的博客 4858

Autosar PNC网络管理配置(1)-基于ETAS软件

Autosar PNC网络管理配置(1)-基于ETAS软件

赞的博客 2733

秋招C++开发学习之路day31

sql的四种连接查询 内连接 inner join 或者 join 外连接 1.左连接left join 或者 left outer join 2.右连接 right jion 或者 right outer join 3.完全外连接 full join 或者 full outer join 建立新的数据库: create database testjoin; 创建两个表: person表:id...

weixin_42925054的博客 324

3.摄像头组件- CVP (ISP)

本文介绍 车载摄像头组件-ISP

2401_83458819的博客 1618

mysql常见面试知识点

mysql

qq_23350817的博客 362

ThingsBoard 场景联动需求

当初有个兄弟请我帮他实现一个需求,需求如上,很简单,实现完成后我怕他操作不来,又写了这份文档给他,今天把这个文档的场景发出来,大家也可以学习一下思路我把需要模拟设备的指令都总结在下面,连接参数截图讲解如下:温度传感器风扇光照传感器灯。

AldrichEugene 1234

解析AI人工智能领域AI芯片的散热技术

当你用ChatGPT写代码、用AI生成高清图片时,背后的AI芯片可能正在“发高烧”——全球TOP500超算的平均功耗已突破10兆瓦,单颗GPU的峰值功耗超过700W(相当于3台家用空调同时运行)。本文将聚焦AI芯片的散热技术,覆盖从基础原理到前沿方案的全链条解析,帮助读者理解“散热为什么比算力更重要”。

AIGC应用创新大全的博客 937

MySQL 锁机制详解

表级锁、行锁、意向锁、共享锁、排他锁、死锁

Bbb36921的博客 1506

TEA-Tiny Encryption算法在FPGA的实现

在FPGA原型中,我们定义了一个TEA_FPGA模块,该模块包含一个输入数据端口(plain)、一个输入密钥端口(key)和一个输出数据端口(cipher)。在模块中,我们通过32轮的循环处理来实现TEA算法的加密过程,并将最终结果存储在cipher变量中。由于FPGA硬件的高速性能,这种基于HDL的TEA算法实现可以在短时间内完成大量的数据加密处理,从而提高加密效率和性能。总之,在FPGA中实现TEA算法可以大大提高加密效率和性能,通过使用硬件描述语言HDL来实现可以更高效、更快速地完成数据加密操作。

BitSlinger的博客 272

MySql锁机制详解

MySql锁机制

Ives_WangShen的博客 580

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

MySQL锁机制详解

锁(Lock)是数据库用来管理并发访问的机制,防止多个事务同时修改同一数据导致数据不一致。核心作用保证数据一致性实现事务隔离控制并发访问定义:两个或多个事务相互等待对方持有的锁,形成循环等待。经典示例时间线 事务A 事务B-- 持有id=1的锁-- 持有id=2的锁-- 等待id=2的锁 ←-- 等待id=1的锁 ←死锁!

先度过菜鸟阶段 843

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

关于mysql锁机制详解

锁概述   MySQL的锁机制,就是数据库为了保证数据的一致性而设计的面对并发场景的一种规则。   最显著的特点是不同的存储引擎支持不同的锁机制,InnoDB支持行锁和表锁,MyISAM支持表锁。   表锁就是把整张表锁起来,特点是加锁快,开销小,不会出现死锁,锁粒度大,发生锁冲突的概率高,并发相对较低。   行锁就是以行为单位把数据锁起来,特点是加锁慢,开销大,会出现死锁,锁粒度小,发生锁冲突的概率低,并发度也相对表锁较高。 MyISAM锁 MyISAM的锁调度   在MyISAM引擎中,读锁

资深系统架构,深耕高并发研发与 AI 大模型工程化落地。技术栈以 Python (AI/NLP/RAG/Agent) 与 Golang (高并发架构) 为双核心,兼具 PHP 大型应用经验。专注算法落地、复杂系统设计及团队技术赋能 377

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Mysql 锁机制详解

锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(如CPU、RAM、I/O等)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。本章我们着重讨论MySQL锁机制的特点,常见的锁问题,以及解决MySQL

Byron's notebook 772

Mysql锁机制详解

Mysql锁: 在多线程当中如果想保证数据的准确性是如何实现的呢?没错,通过同步实现。同步就相当于是加锁。加了锁以后有什么好处呢?当一个线程真正在操作数据的时候,其他线程只能等待。当一个线程执行完毕后,释放锁。其他线程才能进行操作! 那么我们的MySQL数据库中的锁的功能也是类似的,处理事务的隔离性中,可能会出现脏读、不可重复读、幻读的问题,所以,锁的作用也可以解决这些问题! 在数据库中,数据是一种供许多用户共享访问的资源,如何保证数据并发访问的一致性、有效性,是所有数据库必须解决的一个问题,

itzhuzhu的博客 1542

MySQL中的锁机制详解

MySQL的锁机制通过多粒度锁(表级、行级)和多种锁模式(记录锁、间隙锁等),在保证数据一致性的同时提高并发性能。理解不同锁的特性、兼容性及适用场景,能帮助开发者优化数据库设计和事务逻辑。MySQL中的锁机制是确保数据一致性和并发控制的核心组成部分。行级锁锁定表中的特定行,其他行仍可被访问。InnoDB引擎支持行级锁。表级锁锁定整张表,影响所有行。适用于并发要求较低的场景。意向锁是表级锁,用于协调行级锁与表级锁的冲突。

千层冷面的博客 1499

关于MySQL的锁机制详解

锁概述   MySQL的锁机制,就是数据库为了保证数据的一致性而设计的面对并发场景的一种规则。   最显著的特点是不同的存储引擎支持不同的锁机制,InnoDB支持行锁和表锁,MyISAM支持表锁。   表锁就是把整张表锁起来,特点是加锁快,开销小,不会出现死锁,锁粒度大,发生锁冲突的概率高,并发相对较低。   行锁就是以行为单位把数据锁起来,特点是加锁慢,开销大,会出现死锁,锁粒度小,发生锁...

u011252402的专栏 268
上一篇: 后端开发10道经典面试题的剖析, 技术方向如何决定职业方向
下一篇: 详解内存池设计与实现
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值