MySQL__锁

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
性能测试 PTS,5000VUM额度
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: MySQL__锁

文章目录

😊 @ 作者:Lion J
`💖 @ 主页:
https://blog.csdn.net/weixin_69252724`
🎉 @ 主题: MySQL__锁)
⏱️ @ 创作时间:2024年04月27日
————————————————

什么是MySQL的锁?

锁是一种常见的并发事务的控制方式。

表锁与行锁有什么区别

  • 表级锁: MySQL 中锁定粒度最大的一种锁,是针对非索引字段加的锁,对当前操作的整张表加锁,实现简单,资源消耗也比较少,加锁快,不会出现死锁。不过,触发锁冲突的概率最高,高并发下效率极低。表级锁和存储引擎无关,MyISAM 和 InnoDB 引擎都支持表级锁。
  • 行级锁: MySQL 中锁定粒度最小的一种锁,是 针对索引字段加的锁 ,只针对当前操作的行记录进行加锁。 行级锁能大大减少数据库操作的冲突。其加锁粒度最小,并发度高,但加锁的开销也最大,加锁慢,会出现死锁。行级锁和存储引擎有关,是在存储引擎层面实现的。

1. 什么叫做针对索引字段加锁?
针对索引字段加锁是指在执行 SQL 操作时,数据库会根据索引来对数据行进行加锁,而不是对整个表进行加锁。这样的锁定方式被称为行级锁,因为它仅锁定正在操作的行,而不是整个表。
2. 如果查询不走索引字段, 那还怎么加锁, 直接加表锁吗?
别说,还真是. 如果不走索引, 那他查询时候不知道给哪一行数据加锁, 就只能给表加锁了. 此时就根据操作语句来看是加什么锁, 看是共享锁还是独占锁. InnoDB存储引擎一般对于普通的查询语句来说都是加共享锁

  • 当查询字段是索引字段时,MySQL 可以直接利用索引进行定位,并且只需要锁定索引对应的行,而不需要锁定整个表或者额外的间隙。这样可以最大程度地减少锁定的范围,提高并发性能,同时确保了事务的隔离性和一致性。
  • 当查询字段不是索引字段时,MySQL 需要进行全表扫描或者范围扫描,无法直接利用索引定位到符合条件的行。在这种情况下,为了保证查询结果的一致性,MySQL 可能会使用表级锁定或者间隙锁,以确保事务之间不会出现干扰或者幻读现象。这会增加锁定的范围,降低并发性能,但能保证数据的完整性。

行级锁使用注意什么?

InnoDB 的行锁是针对索引字段加的锁,表级锁是针对非索引字段加的锁。当我们执行 UPDATE、DELETE 语句时,如果 WHERE条件中字段没有命中唯一索引或者索引失效的话,就会导致扫描全表对表中的所有行记录进行加锁。这个在我们日常工作开发中经常会遇到,一定要多多注意!!!

InnoDB 有哪几类行锁?

  • 记录锁:也被称为记录锁,属于单个行记录上的锁。
  • 间隙锁:锁定一个范围,不包括记录本身。
  • 临键锁:临键锁是查询时InnoDB根据查询的条件而锁定的一个范围,这个范围中包含有间隙锁和记录锁;临键锁=间隙锁+记录锁。
    其设计的目的是为了解决Phantom Problem(幻读);主要是阻塞insert,但由于临键锁中包含有记录锁,因此临键锁所锁定的范围内如果包含有记录,那么也会给这些记录添加记录锁,从而造成阻塞除insert之外的操作;

间隙锁 和 临表锁的使用?

在默认情况下, InnoDB在RR的事务级别下, 使用间隙锁和索引扫描来防止幻读的情况, 在默认的隔离级别 RR下,行锁默认使用的是 Next-Key Lock(临键锁)。
  • 如果操作的索引是唯一索引或主键, 数据存在情况
就会将临键锁降级为记录所只对操作的数据进行加锁, 仅仅是 锁住索引本身,而不是范围。
  • 如果Sql语句的条件判断字段如果为唯一索引,且给不存在的记录加锁时,行锁会优化为间隙锁给前后间隙加锁。例如:

在这里插入图片描述

记录3-8, 已经被事务1锁住了导,导致事务2inset不了

  • 如果Sql语句的条件判断字段如果为非唯一索引, 那么就会给此数据, 以及此数据前后的数据加上间隙锁

在这里插入图片描述
比如查询:

SELECT * FROM cum WHERE age = 6 LOCK IN SHARE MODE,那么id为(1,6],[6,10)的数据会加锁。  
  • 范围查询的Sql语句的条件判断字段如果为唯一索引,会将此行数据和后面的全部间隙加上锁。例如:

比如执行:

SELECT * FROM cum WHERE id >= 10 LOCK IN SHARE MODE,那么会将[10,无穷大)加锁。

注意:间隙锁唯一目的是防止其他事务将数据插入间隙。间隙锁可以共存,一个事务采用的间隙锁不会阻止另一个事务在同一间隙上采用间隙锁。

对于行锁(记录锁, 间隙锁, 临表锁)都是区分一个共享锁和排他锁的

共享锁与排他锁?

不论是表级锁还是行级锁,都存在共享锁(S 锁)和排他锁(X 锁)这两类:

  • 共享锁(S 锁):又称读锁,事务在读取记录的时候获取共享锁,允许多个事务同时获取。
  • 排他锁(X 锁):又称写锁/独占锁,事务在修改记录的时候获取排他锁,不允许多个事务同时获取。如果一个记录已经被加了排他锁,那其他事务不能再对这条事务加任何类型的锁。

排他锁与任何的锁都不兼容,共享锁仅和共享锁兼容。

在这里插入图片描述
由于 MVCC 的存在,对于一般的 SELECT 语句,InnoDB 不会加任何锁, 都是使用 一致性非锁定读的方式来加共享锁方式
不过, 你可以通过以下语句显式加共享锁或排他锁。

 # 共享锁
SELECT ... FOR SHARE;
# 排他锁
SELECT ... FOR UPDATE;

什么是意向锁?

如果需要用到表锁的话,如何判断表中的记录没有行锁呢,一行一行遍历肯定是不行,性能太差。
我们需要用到一个叫做意向锁的东东来快速判断是否可以对某个表使用表锁。

意向锁是表级锁,共有两种:

  • 意向共享锁 :事务有意向对表中的某些记录加共享锁(S 锁),加共享锁前必须先取得该表的 意向共享锁。
  • 意向排他锁:事务有意向对表中的某些记录加排他锁(X 锁),加排他锁之前必须先取得该表的意向排他锁。

意向锁是由数据引擎自己维护的,用户无法手动操作意向锁,在为数据行加共享/排他锁之前,InooDB 会先获取该数据行所在在数据表的对应意向锁。

这种机制可以帮助快速判断表中的记录是否被锁定,从而优化锁定的策略,减少不必要的等待时间和资源浪费。

当前读与快照读区别?

快照读(一致性非锁定读)

就是单纯的 SELECT 语句,但不包括下面这两类 SELECT 语句:
# 排他
SELECT ... FOR UPDATE
# 共享锁  
SELECT ... LOCK IN SHARE MODE;
# 共享锁 
SELECT ... FOR SHARE;

快照即记录的历史版本,每行记录可能存在多个历史版本(这是数据库的多版本技术)。
快照读的情况下,如果读取的记录正在执行 UPDATE/DELETE 操作,读取操作不会因此去等待记录上 X 锁的释放,而是会去读取行的一个快照
只有在事务隔离级别 RC(读取已提交) 和 RR(可重读)下,InnoDB 才会使用一致性非锁定读:

  • 在 RC 级别下,对于快照数据,一致性非锁定读总是读取被锁定行的最新一份快照数据。这也就是为什么会导致不可重复读的原因
  • 在 RR 级别下,对于快照数据,一致性非锁定读总是读取本事务开始时的行数据版本。快照读比较适合对于数据一致性要求不是特别高且追求极致性能的业务场景。

当前读 (一致性锁定读)

就是给行记录加 X 锁或 S 锁。

当前读的常用语句如下

# 加一个X锁
SELECT...FOR UPDATE
# 加一个S锁
SELECT...LOCK IN SHARE MODE
# 加一个S锁
SELECT...FOR SHARE
# 加一个X锁
INSERT...
UPDATE...
DELETE...
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
SQL 关系型数据库 MySQL
MySQL 锁
MySQL里常见的几种锁
53 3
|
2月前
|
存储 关系型数据库 MySQL
优化 MySQL 的锁机制以提高并发性能
【10月更文挑战第16天】优化 MySQL 锁机制需要综合考虑多个因素,根据具体的应用场景和需求进行针对性的调整。通过不断地优化和改进,可以提高数据库的并发性能,提升系统的整体效率。
82 1
|
2月前
|
关系型数据库 MySQL Java
MySQL数据锁:Record Lock,Gap Lock 和 Next-Key Lock
本文基于 MySQL 8.0.30 版本及 InnoDB 引擎,深入解析三种行锁机制:记录锁(Record Lock)、间隙锁(Gap Lock)和临键锁(Next-key Lock)。记录锁锁定索引记录,确保事务唯一修改;间隙锁锁定索引间的间隙,防止新记录插入;临键锁结合两者,锁定范围并记录自身,有效避免幻读现象。通过具体示例展示了不同锁的作用机制及其在并发控制中的应用。
167 2
|
2月前
|
存储 关系型数据库 MySQL
MySQL数据库锁:共享锁和独占锁
本文详细介绍了`InnoDB`存储引擎中的两种行级别锁:共享锁(S锁)与排他锁(X锁)。通过具体示例展示了这两种锁的工作机制及其在`InnoDB`与`MyISAM`引擎中的表现差异。文章还提供了锁的兼容性矩阵,帮助读者更好地理解锁之间的互斥关系。最后总结了两种锁的特点及适用场景。适合希望深入了解`MySQL`并发控制机制的读者阅读。
64 1
|
3月前
|
监控 关系型数据库 MySQL
MySQL锁机制与解决死锁问题
MySQL锁机制与解决死锁问题
310 5
|
2月前
|
存储 关系型数据库 MySQL
MySQL锁,锁的到底是什么?
【10月更文挑战第16天】MySQL 锁锁定的是与数据和资源相关的对象,其目的是为了保证数据的一致性、避免冲突,并在并发环境下合理协调事务或操作的执行。理解锁的对象和意义对于优化数据库性能、处理并发问题至关重要。
66 0
|
2月前
|
关系型数据库 MySQL 数据库
mysql锁详解
通过理解并合理运用MySQL中的锁机制,开发者可以有效管理数据库并发访问,平衡性能与数据一致性需求。更多关于MySQL锁的深入探讨和最佳实践,请参考专业的数据库管理资源[[深入MySQL锁机制详解
41 0
|
3月前
|
关系型数据库 MySQL 数据库
Mysql的锁
本文介绍了MySQL中表级锁和行级锁的区别,其中MyISAM仅支持表级锁,而InnoDB支持表级锁和行级锁,默认为行级锁。表级锁锁定整个表,实现简单,资源消耗少,但并发度低;行级锁仅锁定相关记录,减少冲突,提高并发度,但加锁开销大。此外,还介绍了共享锁和排他锁的概念及意向锁的作用。
|
3月前
|
存储 SQL 关系型数据库
MySQL 的锁机制,那么多的锁,该怎么区分?
MySQL 的锁机制,那么多的锁,该怎么区分?
43 0
|
4月前
|
监控 关系型数据库 MySQL
在Linux中,mysql的innodb如何定位锁问题?
在Linux中,mysql的innodb如何定位锁问题?