我的编程空间,编程开发者的网络收藏夹
学习永远不晚

MySQL锁分类

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

MySQL锁分类

        

        有没有觉得MySQL里面的锁有很多?比如排它锁、共享锁、意向锁、插入意向锁、间隙锁、临界锁、记录锁、全局锁锁、表锁、页锁以及行销等。其实,这么多锁存在相互包含的情况,他们是数据库锁不同分类标准导致的。

        锁最终是加在索引上的。

目录

1.锁的分类标准

2.按锁的粒度划分

        2.1 全局锁

        2.2 表级锁

        2.3 页级锁

        2.4 行级锁          

3.按锁的兼容性划分

        3.1共享锁

        3.2排它锁

4.按锁的模式划分

        4.1 记录锁

        4.2 间隙锁

        4.3 临界锁

        4.4 意向锁

        4.5 插入意向锁

        4.6 自增锁


1.锁的分类标准

        锁可以根据 加锁机制、锁粒度、兼容性以及锁模式来区分(直接开抄,原出处不明,因为在太多文章看到了,分不清谁是原创!

MySQL :: MySQL 5.7 Reference Manual :: 14.7.1 InnoDB Locking

2.按锁的粒度划分

        2.1 全局锁

        全局锁就是对整个数据库实例加锁。MySQL 提供了一个加全局读锁的方法,命令是

Flush tables with read lock (FTWRL)。

        当你需要让整个库处于只读状态的时候,可以使用这个命令,之后其他线程的以下语句会被阻塞:数据更新语句(数据的增删改)、数据定义语句(包括建表、修改表结构等)和更新类事务的提交语句。

           全局锁的典型使用场景是:做全库逻辑备份 。 

   

        2.2 表级锁

         MySQL 里面表级别的锁有两种:一种是表锁,比如自增锁,一种是元数据锁(meta data lock,MDL)。

        表锁是MySQL中最大粒度的锁定机制,会锁定整张表,可以很好的避免死锁,是 MySQL 中最大颗粒度的锁定机制。表锁由 MySQL Server 实现,一般在执行 DDL 语句时会对整个表进行加锁,比如说ALTER TABLE等操作。在执行 DML 语句时,也可以通过LOCK TABLES显式指定对某个表进行加锁。

        2.3 页级锁

        页级锁是 MySQL 中比较独特的一种锁定级别,在其他数据库管理软件中并不常见。页级锁的颗粒度介于行级锁与表级锁之间,所以获取锁定所需要的资源开销,以及所能提供的并发处理能力同样也是介于上面二者之间。另外,页级锁和行级锁一样,会发生死锁。页级锁主要应用于 BDB 存储引擎。

        2.4 行级锁          

       MySQL 的行锁是在引擎层由各个引擎自己实现的, 且锁定颗粒度在 MySQL 中是最小的,比如 MyISAM 引擎就不支持行锁,行级锁主要应用于 InnoDB 存储引擎。不支持行锁意味着并发控制只能使用表锁,对于这种引擎的表,同一张表上任何时刻只能有一个更新在执行,这就会影响到并发度,只针对操作的当前行进行加锁,所以行级锁发生锁定资源争用的概率也最小。比如事务 A 更新了一行,而这时候事务 B 也要更新同一行,则必须等事务 A 的操作完成后才能进行更新。

        MySQL中3种锁的特性可大致归纳如下:

        

3.按锁的兼容性划分

        3.1共享锁

-- 加锁方式:共享锁SELECT...LOCK IN SHARE MODE

        3.2排它锁

-- 加锁方式:排它锁SELECT...FOR UPDATE 

InnoDB实现标准的行级锁定,其中有两种类型的锁, 共享锁(S)和排它锁(X)。

  • 共享锁允许持有锁,读取行的事务。

  • 排它锁允许持有锁,更新或删除行的事务。

4.按锁的模式划分

        4.1 记录锁

             记录锁(Record Locks)属于为行锁,表示对某一行记录加锁。

-- id 列为主键列或唯一索引列SELECT * FROM test WHERE id = 10 FOR UPDATE;

        id为10的行记录会被锁住,可以防止插入,更新或删除行。

        记录锁总是锁定索引记录(SELECT和UPDATE都会加锁),即使表没有定义索引。对于这种情况, InnoDB创建一个隐藏的聚集索引并使用该索引进行记录锁定。但因为可能会扫描全表,那么该锁也就会退化为表锁。

        注意:

  • id列必须为唯一索引或主键列,否则上述语句加的锁会变成临键锁。
  • 查询语句必须为精准匹配=,不能>、<、like等,否则也会退化成临键锁。

        4.2 间隙锁

        间隙锁(Gap Locks)是对索引(非唯一索引)记录之间的间隙,锁定一个区间:加在两个索引之间,或者加在第一个索引之前,或者加在最后一个索引之后的间隙。

        注意!间隙锁锁住的是一个区间,而不仅仅是这个区间中目前仅存在的数据行。

SELECT * FROM test WHERE id BETWEEN 10 and 15 FOR UPDATE;

        例如上面的语句,那(10,15)整个区间的记录行都会被锁住,即id为11,12,13,14数据行的插入操作都会被阻塞,但是10和15两条记录行并不会被锁住。对于唯一索引,如果使用等值查询,那么间隙锁会退化为行锁。

-- 身份证号,唯一索引SELECT * FROM user WHERE identity_id = 100;

        这里还值得注意的是,间隙锁只阻止其他事务插入到间隙中,并不阻止其他事务在同一个间隙上获得间隙锁,所以 gap x lock 和 gap s lock 有相同的作用,即不同的事务可以在间隙上持有冲突的锁。 例如,事务 A 可以在间隙上持有共享间隙锁(间隙 S 锁),而事务 B 在同一间隙上持有排他间隙锁(间隙 X 锁)。允许冲突间隙锁的原因是,如果从索引中清除记录,则必须合并不同事务在记录上持有的间隙锁。

        总结:

        1.间隙锁锁区间的索引,使用唯一索引搜索唯一行不需要间隙锁定。

        2.在READ COMMITTED(RC)隔离级别下,不会使用gap lock,在RR级别及以上(Serializable)才会使用它。

        3.间隙锁可以共存。一个事务采用的间隙锁不会阻止另一个事务在同一间隙上采用间隙锁。共享和排他间隙锁之间没有区别。它们彼此不冲突,并且执行相同的功能。

        

        4.3 临界锁

        临键锁(Next-Key)简单理解是 “记录锁+间隙锁” 的组合,但Next-Key lock与record lock加锁的粒度一样,都是加在一条索引记录上的。一个next-key lock=对应的索引记录的record lock+该索引前面的间隙的gap lock,通过临键锁可以解决幻读的问题。

        默认情况下,InnoDB在 REPEATABLE READ事务隔离级别运行,在这种情况下,InnoDB使用临键锁进行搜索和索引扫描,以防止幻像行,比如select ... in share mode或者select ... for update语句。但即使你的隔离级别是RR,如果你这是使用普通的select语句,那么InnoDB将是快照读,不会使用任何锁,因而还是无法防止幻读

        记住了,锁住的是索引前面的间隙!比如一个索引包含值,10,11,13和20。那么,临键锁的范围如下,左开右闭:

(negative infinity, 10](10, 11](11, 13](13, 20](20, positive infinity)

        总结:InnoDB在RR事务隔离级别下,在根据非唯一索引对记录行进行UPDATE \ FOR UPDATE \ LOCK IN SHARE MODE 操作时,InnoDB 会获取该记录行的临键锁 ,并同时获取该记录行下一个区间间隙锁。

        4.4 意向锁

        意向锁(Intention Locks)是表级锁,指示事务稍后需要(或想要,表明锁的意向)对表中的行使用哪种类型的锁(共享锁或独占锁),即用来标识该表上面有数据被锁住(或即将被锁)

意向锁有两种类型:

  • 意向共享锁(IS):一个事务在获取(任何一行/或者全表)S锁之前,一定会先在所在的表上加IS锁。

  • 意向排它锁(IX):一个事务在获取(任何一行/或者全表)X锁之前,一定会先在所在的表上加IX锁。

意图锁定协议如下:

  • 在事务可以获取表中行的共享锁之前,它必须首先获取IS表上的锁或更强的锁。

  • 在事务获得表中行的排他锁之前,它必须首先获得IX 表的锁。

表级锁类型兼容性总结在以下矩阵中:

        如果请求事务与现有锁兼容,则向请求事务授予锁,但如果与现有锁冲突,则不会。事务一直等到冲突的现有锁被释放。如果锁定请求与现有锁定发生冲突并且由于会导致死锁而无法授予 ,则会发生错误。

                除了全表请求(例如,LOCK TABLES ... WRITE)之外,意向锁锁不会阻止任何内容。意向锁的主要目的是表明有人正在锁定一行,或者打算锁定表中的一行。

      这里说一下意向锁存在的目的:可以快速判断该表是否存在行锁。

         比如,事务T1,用X锁来锁住了表上的几条记录,那么此时表上存在IX锁,即意向排他锁。那么此时事务T2要进行LOCK TABLE … WRITE的表级别锁的请求,可以直接根据意向锁是否存在而判断是否有锁冲突,就不。

       再比如,事务1在表1上加了S锁后,事务2想要更改某行记录,需要添加IX锁,由于不兼容,所以需要等待S锁释放;如果事务1在表1上加了IS锁,事务2添加的IX锁与IS锁兼容,就可以操作,这就实现了更细粒度的加锁。

        

        4.5 插入意向锁

        插入意向锁(Insert Intention Locks)是在插入一条记录行前,由 INSERT 操作产生的一种特别的间隙锁。

        该锁用以表示插入意向,当多个事务在同一区间插入位置不同的多条数据时,事务之间不需要互相等待。假设存在两条值分别为 4 和 7 的记录,两个不同的事务分别试图插入值为 5 和 6 的两条记录,每个事务在获取插入行上独占的(排他)锁前,都会获取(4,7)之间的间隙锁,但是因为数据行之间并不冲突,所以两个事务之间并不会产生冲突(阻塞等待)。

总结来说,插入意向锁的特性可以分成两部分:

  1. 插入意向锁是一种特殊的间隙锁,如果说间隙锁锁住的是一个区间,那么插入意向锁锁住的就是一个点。

  2. 插入意向锁之间互不排斥,所以即使多个事务在同一区间插入多条记录,只要记录本身(主键、唯一索引)不冲突,那么事务之间就不会出现冲突等待。

        需要强调的是,虽然插入意向锁中含有“意向锁”三个字,但是它并不属于意向锁而属于间隙锁,因为意向锁是表锁而插入意向锁是行锁。

        4.6 自增锁

        自增锁(auto-inc Locks)是一种特殊的表级锁,主要用于事务中插入自增字段(AUTO_INCREAMENT),也就是我们最常用的自增主键id。在最简单的情况下,如果一个事务正在向表中插入值,则任何其他事务都必须等待插入到该表中,以便第一个事务插入的行接收连续的主键值。

        可以通过配置项 innodb_autoinc_lock_mode调整自增锁算法:传统模式(还没有锁模式这个概念时,InnoDB 的自增锁运行的模式)、连续模式(MySQl 8.0以前的默认模式)以及交叉模式。

        深入剖析 MySQL 自增锁 - 掘金

来源地址:https://blog.csdn.net/qq_28683865/article/details/127952390

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

MySQL锁分类

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

2023-09-09

Mysql 锁的类型

基于锁的属性分类:共享锁、排他锁。基于锁的粒度分类:行级锁(INNODB)、表级锁(INNODB、MYISAM)、页级锁(BDB引擎 )、记录锁、间隙锁、临键锁。基于锁的状态分类:意向共享锁、意向排它锁。共享锁(Share Lock)共享锁又称读锁,简称S锁;
Mysql 锁的类型
2015-05-05

分类与应用:了解MySQL锁的类型和用途

MySQL 锁的分类与应用在并发访问数据库的情况下,为了保证数据的一致性和完整性,MySQL 提供了锁机制。锁可以将关键资源进行保护,控制并发事务对数据的访问和修改。本文将介绍 MySQL 锁的分类和应用,并提供具体的代码示例。一、MySQ
分类与应用:了解MySQL锁的类型和用途
2023-12-21

常见的MySQL锁类型

MySQL 中常见的锁类型,需要具体代码示例导言:在数据库中,当多个客户端同时对同一数据进行读取或修改时,会出现并发操作的问题。为了保证数据的一致性和完整性,数据库引擎采用了锁机制来控制对共享数据的访问。MySQL 作为一种常用的关系型数据
常见的MySQL锁类型
2023-12-21

MySQL InnoDB锁类型及锁原理实例解析

目录锁共享锁排他锁意向锁记录锁间隙锁临键锁死锁死锁产生条件行锁发生死锁表锁发生死锁锁的释放事务阻塞死锁的避免锁的日志行锁的原理不带任何索引的表带主键索引的表带唯一索引的表结论1.表必定有索引2.唯一索引数据行加锁,主键索引同样被锁锁锁是用
2022-11-27

MySQL锁等待与死锁问题分析

前言: 在 MySQL 运维过程中,锁等待和死锁问题是令各位 DBA 及开发同学非常头痛的事。出现此类问题会造成业务回滚、卡顿等故障,特别是业务繁忙的系统,出现死锁问题后影响会更严重。本篇文章我们一起来学习下什么是锁等待及死锁,出现此类问
2022-05-22

MySQL实现分布式锁

这篇文章主要介绍了MySQL实现分布式锁,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
2022-11-13

Java中的锁有哪些分类

今天就跟大家聊聊有关Java中的锁有哪些分类,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。公平锁/非公平锁可重入锁独享锁/共享锁互斥锁/读写锁乐观锁/悲观锁分段锁偏向锁/轻量级锁/重
2023-05-31

MySQL死锁案例分析

最近项目中某个模块稳定复现MySQL死锁问题,本文记录死锁的发生原因以及解决办法。1. 预备知识1.1 表锁和行锁表锁表锁是MySQL中最基本的锁策略,并且是开销最小的策略。表锁会锁定整张数据表,用户的写操作(插入/删除/更新)前,都需要获取写锁(写锁会相互阻
MySQL死锁案例分析
2015-02-06

编程热搜

目录