MySQL进阶突击系列(06)MySQL有几种锁?| 别背答案,现场演示一下

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云原生数据库 PolarDB 分布式版,标准版 2核8GB
简介: 本文详细解析了MySQL InnoDB存储引擎的锁机制,涵盖读锁、写锁、意向锁、记录锁、间隙锁和临键锁等8种锁类型。重点探讨了不同锁类型的加锁与释放方式,以及事务并发场景下的实战验证。通过具体示例,展示了在不同情况下锁的行为及其对事务的影响。文章还特别强调了锁的作用范围主要是索引,并解释了锁如何影响数据的读写操作。最后总结了并发事务中加锁规则,帮助读者深入理解MySQL的锁机制。

读书笔记:自卑这个词听起来不太好听,我更倾向于是个人对现实的清醒认识以及坦然面对。自卑和自卑情结有着本质区别。比如学历差,如果可以坦然接受面对学历背景不好,并能认识到需要更加努力才能弥补差距,自卑将被划为动力。如果总是以自身条件差为借口和原因,觉得自己做不到或无法实现xx。或者认为如果我学历好,我也可以做到或者实现xx。这样就是自卑情结。


一、前言背景

二、MySQL InnoDB的锁类型

2.1 读锁和写锁(S锁和X锁)

2.2 意向锁

2.3 记录锁

2.4 间隙锁

2.5 临键锁

三、MySQL加锁、释放锁有多少种方式

3.1 读锁-S锁,加锁和释放锁方式

3.2 写锁-X锁

3.2.1 主动加锁

3.2.2 自动加锁

四、事务并发场景实战验证

4.1 并发事务同时读和写,不冲突demo实战

4.2 并发事务加锁读和加锁写,锁冲突demo实战

4.3 事务里的select 查询默认是否加读锁?实战验证

4.4 那么多事务并发、读写加锁和不加锁场景?能否一句话讲透

五、MySQL的锁,锁的是索引?


一、前言背景

     说到数据库锁,我们最常见的、最先想到的是行锁、表锁。MySQL 的InnoDB存储引擎,支持行级锁,而MYISAM支持的是表级锁。这个锁粒度的区别,让InnoDB在互联网海量数据高并发时代,得以脱颖而出,成为MySQL默认的存储引擎。而MYISAM,则适合在一次性大批量更新导入,后续日常查多写少的场景使用。

二、MySQL InnoDB的锁类型

     MySQL5.7 版本的 InnoDB有8种锁,包括读锁、写锁、意向锁、记录锁、间隙锁、临键锁、写入意向锁、自增主键锁。实际上我们最常见关注的是读锁、写锁。意向锁,是表级别的锁,然后记录锁、间隙锁、临键锁,只是不同锁范围的表现形式。今天重点分享的是并发事务下,读写锁深入实践理解。

2.1 读锁和写锁(S锁和X锁)

     读锁-S锁,全称是shared (S) locks ,写锁-又称排它锁,全称是 exclusive (X) locks。

     此外也有很多说法,比如共享锁和独占锁。而在MySQL里,共享锁就是读锁。写锁就是排它锁和独占锁。

     在MySQL并发事务情况下:如果一行数据被加了读锁,允许其他事务读、以及加读锁,但是不允许其他事务加写锁。

     如果一行数据被加了写锁,不允许其他事务继续申请加读锁、以及写锁。

     也就是数据的读锁与读锁之间不互斥,而写锁与写锁、读锁互斥。

2.2 意向锁

     在MySQL 5.7  意向锁Intention Locks,属于表级别的锁。当表里的某些数据加读锁或者写锁后,会给表也加上意向读、意向写锁标识。当系统需要给这张表添加表锁的时候,就会判断这个标识,是否有数据已经被加锁,而无需全表扫描,提高表加锁效率。

     表级意向锁,日常我们用的非常少,除非是DBA,研发对此应用几乎不需要了解。因为意向读锁、意向写锁彼此不互斥。这个意向锁,真正影响的是表锁。但是表锁比如DDL,给表新增修改删除某个字段属性,自动会触发表锁。表加了排他锁后,表里的数据,自然无法直接申请更新数据的排它锁,需要等表锁释放后,才能申请行级别的排它锁。

2.3 记录锁

    记录锁全称是Record Locks。这里附带说一下,记录锁、间隙锁、临键锁特指锁的范围。比如id是主键或者是索引,

select * from user_mvcc_demo where id=3 for update;

    这里触发的就是行的排它锁-而范围是记录级锁,给id=3这行数据精准加锁。

2.4 间隙锁

     间隙锁,全称是Gap Locks。间隙锁的作用是锁住某个范围。比如事务A把id范围【1,4】的数据都加了排它锁,那事务B再尝试给id=4的数据加锁,就会失败。

     这里锁的范围就是间隙锁。作用是可以避免该范围被新增或者删除,以及其他事务尝试修改该范围的数据。比如表里有id=1,4,9三条数据。如果对select * from user_mvcc_demo where id>=1 and id<=4 for update;加锁,那么就可以有效阻塞,新增id=2,3的数据。可以有效避免幻读。

     总结起来:间隙锁,用于锁住目标范围数据的【间隙】或者说空隙,可以避免幻读。

2.5 临键锁

    临键锁全称Next-Key Locks。实际上就是临键锁=记录锁+间隙锁。看起来不太好理解,容易和间隙锁搞混。可以这么理解:临键锁,不仅锁住范围数据的间隙,也锁住了相关行前后间隙。

    比如事务A把id范围【1,7)的数据都加了排它锁,实际因为触发了临键锁,事务B尝试给id=7的数据加锁,就会需要等待,无法直接加锁。

三、MySQL加锁、释放锁有多少种方式

3.1 读锁-S锁,加锁和释放锁方式

     可以在sql 末尾增加 lock in share mode的方式去加读S锁。比如:

begin;

select * from user_mvcc_demo where id=1  lock in share mode;

     释放读锁,当事务结束后会自动释放。比如commit,或者rollback,或者会话超时,也都会自动释放。

3.2 写锁-X锁

3.2.1 主动加锁

    可以在sql 末尾增加for update的方式去加写X锁。比如:

begin;

select * from user_mvcc_demo where id=1 for update;

3.2.2 自动加锁

    在事务里,insert、update、delete语句都是会自动加写锁。

四、事务并发场景实战验证

4.1 并发事务同时读和写,不冲突demo实战

     场景设计:事务A查询id=1的数据,但是不加读锁。另一个事务B尝试加锁更新,是否会被卡住?

事务1- 读id=1数据。

begin;

select * from user_mvcc_demo where id=1;

事务2-直接尝试加独占锁

select * from user_mvcc_demo where id=1  for update;

预期效果:事务B直接加锁成功,并可以执行更新。

具体示例:

    首先,事务AB、并发开启并执行查询id=1的数据,结果互不干扰。

然后事务B继续对name值进行更新并查询。

update user_mvcc_demo set name='拉丁解牛说技术002' where id=1;

select * from user_mvcc_demo where id=1;

结论:

      在MySQL InnoDB存储引擎下,事务并发读写,两个事务没有受写锁的影响。底层就是系列五,之前说的MVCC机制,undoLog版本链支持严格按照事务隔离级别去读数据、更新数据。MVCC的设计,大幅提升MySQL InnoDB存储引擎的事务并发能力。

4.2 并发事务加锁读和加锁写,锁冲突demo实战

     场景设计:事务A查询id=1的数据,并加了读锁,另一个事务B尝试加锁更新,是否会被卡住?

事务1- 读id=1数据,并加读锁。

begin;

select * from user_mvcc_demo where id=1 lock in share mode;

事务2-直接尝试加独占锁

select * from user_mvcc_demo where id=1  for update;

预期效果:事务B会被卡住,直到超时,或者事务1提交释放锁。

具体示例:

demo结果:事务1一直未提交事务释放锁,最后事务B,加锁超时失败。

4.3 事务里的select 查询默认是否加读锁?实战验证

      事务A里,查询id=1的数据;事务B对id=1的数据进行加写锁,是否会读事务A的重复读有影响?

如下图:

     结论:MySQL的select查询,默认是不加读锁。

     而且并发事务下,事务B虽然对id=1加了写锁,事务A里仍然可以继续查id=1的数据。底层就是基于readView机制去读事务隔离级别下对应的数据。如下:事务A可以重复读,没有被写锁阻塞。

4.4 那么多事务并发、读写加锁和不加锁场景?能否一句话讲透

      我们很容易看到并理解,“数据被加了读S锁,大家可以共享读,但是不可以被再加写X锁。然后数据如果被加了写X锁,就不能被读。”

     这句话其实有一定误导性,末尾数据加了X锁,不可以读。实际应该是:数据加了X锁,数据可以读,但是不能加读锁。

     如果数据已经被加了写锁,其他事务要进行加读锁(比如select * from t1 where id=1 lock in share mode),那肯定就是不能读。如下:

首先事务B,加了写锁:

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from user_mvcc_demo where id=1 for update;

然后事务A尝试加读锁,就会被阻塞卡住。

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from user_mvcc_demo where id=1 lock in share mode;

结果如下图:

最后事务A,加读锁超时失败。

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

这个demo,另一个场景,即使事务B里读数据进行加了排它锁,如果事务A不加读锁直接读,是可以直接读到数据。

     一句话总结:并发事务,数据被加了写锁,此时不可以再被加读锁。如果被加了读锁,事务可以共享读,但不能被加写锁。

    其他的,在非主动加锁(xxx for update,xxx lock in share mode)情况下,事务可以自由并发进行读写,互不干扰,并发效率很高。

五、MySQL的锁,锁的是索引?

     日常我们如果给特定id=xx的值进行加锁,不管是update xx 还是通过select xx for update方式,如果id这列不是主键,就会被触发表锁,锁住整张表。如果id是主键,也就是索引。那就是锁定一行数据而已。

     比如如下案例demo,表里有3条数据,id分别为1、2、3。

     在事务A里给id=1的数据加了排它锁。然后事务B仍然可以给id=2、3的数据加排他锁。

     随后,事务A尝试给已经被事务B加锁的id=2的数据加锁,就需要等待排队。

效果如下图:

好了,今天先分享到这,下一篇再见。


推荐阅读拉丁解牛相关专题系列(欢迎交流讨论):

1、JVM进阶调优系列(3)堆内存的对象什么时候被回收?

2、JVM进阶调优系列(2)字节面试:JVM内存区域怎么划分,分别有什么用?

3、JVM进阶调优系列(1)类加载器原理一文讲透

4、JAVA并发编程系列(13)Future、FutureTask异步小王子

5、MySQL进阶突击系列(05)突击MVCC核心原理 | 左右护法ReadView视图和undoLog版本链强强联合

相关文章
|
14天前
|
供应链 监控 安全
对话|企业如何构建更完善的容器供应链安全防护体系
阿里云与企业共筑容器供应链安全
171330 12
|
16天前
|
供应链 监控 安全
对话|企业如何构建更完善的容器供应链安全防护体系
随着云计算和DevOps的兴起,容器技术和自动化在软件开发中扮演着愈发重要的角色,但也带来了新的安全挑战。阿里云针对这些挑战,组织了一场关于云上安全的深度访谈,邀请了内部专家穆寰、匡大虎和黄竹刚,深入探讨了容器安全与软件供应链安全的关系,分析了当前的安全隐患及应对策略,并介绍了阿里云提供的安全解决方案,包括容器镜像服务ACR、容器服务ACK、网格服务ASM等,旨在帮助企业构建涵盖整个软件开发生命周期的安全防护体系。通过加强基础设施安全性、技术创新以及倡导协同安全理念,阿里云致力于与客户共同建设更加安全可靠的软件供应链环境。
150295 32
|
24天前
|
弹性计算 人工智能 安全
对话 | ECS如何构筑企业上云的第一道安全防线
随着中小企业加速上云,数据泄露、网络攻击等安全威胁日益严重。阿里云推出深度访谈栏目,汇聚产品技术专家,探讨云上安全问题及应对策略。首期节目聚焦ECS安全性,提出三道防线:数据安全、网络安全和身份认证与权限管理,确保用户在云端的数据主权和业务稳定。此外,阿里云还推出了“ECS 99套餐”,以高性价比提供全面的安全保障,帮助中小企业安全上云。
201961 14
对话 | ECS如何构筑企业上云的第一道安全防线
|
2天前
|
机器学习/深度学习 自然语言处理 PyTorch
深入剖析Transformer架构中的多头注意力机制
多头注意力机制(Multi-Head Attention)是Transformer模型中的核心组件,通过并行运行多个独立的注意力机制,捕捉输入序列中不同子空间的语义关联。每个“头”独立处理Query、Key和Value矩阵,经过缩放点积注意力运算后,所有头的输出被拼接并通过线性层融合,最终生成更全面的表示。多头注意力不仅增强了模型对复杂依赖关系的理解,还在自然语言处理任务如机器翻译和阅读理解中表现出色。通过多头自注意力机制,模型在同一序列内部进行多角度的注意力计算,进一步提升了表达能力和泛化性能。
|
6天前
|
存储 人工智能 安全
对话|无影如何助力企业构建办公安全防护体系
阿里云无影助力企业构建办公安全防护体系
1251 8
|
7天前
|
人工智能 自然语言处理 程序员
通义灵码2.0全新升级,AI程序员全面开放使用
通义灵码2.0来了,成为全球首个同时上线JetBrains和VSCode的AI 程序员产品!立即下载更新最新插件使用。
1291 24
|
9天前
|
机器学习/深度学习 自然语言处理 搜索推荐
自注意力机制全解析:从原理到计算细节,一文尽览!
自注意力机制(Self-Attention)最早可追溯至20世纪70年代的神经网络研究,但直到2017年Google Brain团队提出Transformer架构后才广泛应用于深度学习。它通过计算序列内部元素间的相关性,捕捉复杂依赖关系,并支持并行化训练,显著提升了处理长文本和序列数据的能力。相比传统的RNN、LSTM和GRU,自注意力机制在自然语言处理(NLP)、计算机视觉、语音识别及推荐系统等领域展现出卓越性能。其核心步骤包括生成查询(Q)、键(K)和值(V)向量,计算缩放点积注意力得分,应用Softmax归一化,以及加权求和生成输出。自注意力机制提高了模型的表达能力,带来了更精准的服务。
|
7天前
|
消息中间件 人工智能 运维
1月更文特别场——寻找用云高手,分享云&AI实践
我们寻找你,用云高手,欢迎分享你的真知灼见!
563 22
1月更文特别场——寻找用云高手,分享云&AI实践
|
6天前
|
机器学习/深度学习 人工智能 自然语言处理
|
12天前
|
人工智能 自然语言处理 API
阿里云百炼xWaytoAGI共学课DAY1 - 必须了解的企业级AI应用开发知识点
本课程旨在介绍阿里云百炼大模型平台的核心功能和应用场景,帮助开发者和技术小白快速上手,体验AI的强大能力,并探索企业级AI应用开发的可能性。