MySQL锁机制

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: MySQL锁机制

MySQL锁机制


一、锁的粒度

  • 表级锁:
  1. 对整张表加锁
  2. 开销小,加锁快,不会出现死锁
  3. 锁粒度大,发生锁冲突的概率高,并发度低


  • 行级锁:
  1. 对表中某行记录加锁
  2. 开销大,加锁慢,会出现死锁
  3. 锁定粒度最小,发生锁冲突的概率最低,并发度高


二、锁的类型

  1. 排它锁(Exclusive),又称为 X 锁,写锁,写锁和其他锁是不兼容的
  2. 共享锁(Shared),又称为 S 锁,读锁,读锁之间是共享记录的
  • X和S锁之间有以下的关系:

SS可以兼容的,XS、SX、XX之间是互斥的,即读锁之间可以共享,读写和写写之间是不兼容的

  • 加锁效果表现:
  1. 一个事务对数据对象 O 加了 S 锁,只能对 O 进行读取操作,加锁期间其它事务能对O 加 S 锁但不能加 X 锁
  2. 一个事务对数据对象 O 加了 X 锁,可以对 O 进行读取和更新,加锁期间其它事务不能对 O 加任何锁


  • 命令显示加锁:
select ... lock in share mode#强制获取共享锁
select ... for update#获取排它锁


三、InnoDB中的锁

InnoDB的一个特点就是行锁,除了行锁,InnoDB还有表锁和间隔锁

InnoDB通过锁和MVCC(多版本并发控制)实现了事物的隔离性,通过锁解决幻读,通过MVCC实现提交读和可重复读


1、串行化怎么解决幻读

  • 范围条件检索时:
  1. 使用非索引项检索,InnoDB使用表锁:

非索引项没有建立索引树,使用行锁的话需要遍历,效率太慢,所以InnoDB直接用表共享锁,将整个表锁住,如果想进行数据插入删除,需要获取排它锁,这是不能兼容的

0b4f9e796c1218d506b3e3e2080525e1.png

  1. 使用索引项检索,InnoDB会使用行锁+间隙锁:

使用二级索引,通过索引找到主键索引加上行锁,在对应条件的二级索引之间加上间隙锁,防止数据的插入

1f2f5d5ad765cdadadaef7eeef85c8ae.png

  • 等值条件检索时:
  1. 使用非索引项检索,InnoDB同样使用表锁

5363b773aaba347d7986ca72caa9f8ac.png

  1. 使用索引项检索,InnoDB使用行锁:

通过索引记录加上行锁,加上行锁就行,主键和唯一索引的值无法重复


  • 特性总结:
  1. InnoDB行锁是通过给索引上的索引项加锁来实现的,而不是给表的行记录加锁实现的,这就意味着只有通过索引条件检索数据,InnoDB才使用行级锁,否则InnoDB将使用表锁,并且当使用的是二级索引时,同样的根据二级索引找到主键索引上的行记录做加锁
  2. 用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB 会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,做“间隙”加锁,以防止幻读


注意:即使SQL中使用了索引,但是经过MySQL的优化器后,如果认为全表扫描比使用索引效率更高,此时会放弃使用索引,因此也不会使用行锁,而是使用表锁,比如对一些很小的表,MySQL就不会去使用索引


2、意向共享锁和意向排他锁

在绝大部分情况下都应该使用行锁,因为事务和行锁往往是选择InnoDB的理由

  • 但个别情况下也使用表级锁 :
  1. 事务需要更新大部分或全部数据,表又比较大,如果使用默认的行锁,不仅这个事务执行效率低,而且可能造成其他事务长时间等待和锁冲突
  2. 事务涉及多个表,比较复杂,很可能引起死锁,造成大量事务回滚


  • 意向锁的本质:

用来加速获取表的表锁的,意向锁是表级锁,协调表锁和行锁的共存关系

  1. 意向共享锁(IS锁):如果表中某个行共享锁被获取了,那么意向共享锁的状态是被获取的
  2. 意向排他锁(IX锁):如果表中某个行排他锁被获取了,那么意向共享锁的状态是被获取的
  3. 如果要获取表共享锁,那么要检查表的表排他锁和意向排他锁
  4. 如果要获取表排他锁,那么要检查表的表排他锁,表共享锁,意向排他锁和意向共享锁

e5a9be7279dc4f93b3552a87ca824558.png


四、死锁

MyISAM 表锁是 deadlock free 的, 这是因为 MyISAM 总是一次获得所需的全部锁,要么全部满足,要么等待,因此不会出现死锁

但在 InnoDB 中,除单个 SQL 组成的事务外,锁是逐步获得的,即锁的粒度比较小,这就决定了在 InnoDB 中发生死锁是可能的

死锁问题一般都是我们自己的应用造成的,和多线程编程的死锁情况相似,大部分都是由于我们多个线程在获取多个锁资源的时候,获取的顺序不同而导致的死锁问题

因此我们应用在对数据库的多个表做更新的时候,不同的代码段,应对这些表按相同的顺序进行更新操作,以防止锁冲突导致死锁问题


五、锁的优化建议

1.尽量使用较低的隔离级别

2.设计合理的索引并尽量使用索引访问数据,使加锁更加准确,减少锁冲突的机会提高并发能力

3.选择合理的事务大小,小事务发生锁冲突的概率小

4.不同的程序访问一组表时,应尽量约定以相同的顺序访问各表,对一个表而言,尽可能以固定的顺序存取表中的行,这样可以大大减少死锁的机会

5.尽量用相等条件访问数据,这样可以避免间隙锁对并发插入的影响

6.不要申请超过实际需要的锁级别

7.除非必须,查询时不要显示加锁


六、MVCC多版本并发控制

MVCC是多版本并发控制(Multi-Version Concurrency Control,简称MVCC),是MySQL中基于乐观锁理论实现隔离级别的方式,用于实现已提交读和可重复读隔离级别,也经常称为多版本数据库

MVCC机制会生成一个数据请求时间点的一致性数据快照 (Snapshot), 并用这个快照来提供一定级别 (语句级或事务级) 的一致性读取。从用户的角度来看,好象是数据库可以提供同一数据的多个版本(系统版本号和事务版本号)

MVCC的本质是快照,生成多版本,其底层所依赖的机制是 undo log 回滚日志,保存了事务发生之前的数据的一个版本,用于事务执行时的回滚操作,同时也是实现多版本并发控制(MVCC)下读操作的关键技术

DB_TRX_ID:对记录做修改的事务ID DB_ROLL_PTR:回滚指针,储存旧版本记录数据的地址

9ccb66ef865108b2bfff1784f079d0b4.png

实现已提交读:

可以解决脏读,但是无法解决不可重复读,MVCC对于每一次select都会生成新的快照,而快照中的数据都是经过事物正确commit后的数据

实现可重复读:

解决脏读,不可重复读,MVCC只会在第一次select才会生成当前事务全局性的快照,快照中的数据都是经过事物正确commit后的数据,后续select会沿用第一次的当前读快照

在这种情况下,可重读度在一定程度上解决了幻读,但是如果事物自己update其他事物提交insert数据,是会显示在快照中的

f30024fc2576b5356da1461245b2a029.png

  • MVCC多版本并发控制中,读操作可以分为两类:

1、快照读(snapshot read)

读的是记录的可见版本,不用加锁,如select

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


2、当前读(current read)

读取的是记录的最新版本,并且当前读返回的记录

如insert,delete,update,select…lock in share mode/for update

  • 快照内容读取原则:
  1. 版本未提交无法读取生成快照
  2. 版本已提交,但是在快照创建后提交的,无法读取
  3. 版本已提交,但是在快照创建前提交的,可以读取
  4. 当前事务内自己的更新,可以读到


t,delete,update,select…lock in share mode/for update

  • 快照内容读取原则:
  1. 版本未提交无法读取生成快照
  2. 版本已提交,但是在快照创建后提交的,无法读取
  3. 版本已提交,但是在快照创建前提交的,可以读取
  4. 当前事务内自己的更新,可以读到
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
19天前
|
存储 关系型数据库 MySQL
MySQL MVCC全面解读:掌握并发控制的核心机制
【10月更文挑战第15天】 在数据库管理系统中,MySQL的InnoDB存储引擎采用了一种称为MVCC(Multi-Version Concurrency Control,多版本并发控制)的技术来处理事务的并发访问。MVCC不仅提高了数据库的并发性能,还保证了事务的隔离性。本文将深入探讨MySQL中的MVCC机制,为你在面试中遇到的相关问题提供全面的解答。
55 2
|
28天前
|
缓存 关系型数据库 MySQL
MySQL并发支撑底层Buffer Pool机制详解
【10月更文挑战第18天】在数据库系统中,磁盘IO操作是性能瓶颈之一。为了提高数据访问速度,减少磁盘IO,MySQL引入了缓存机制。其中,Buffer Pool是InnoDB存储引擎中用于缓存磁盘上的数据页和索引页的内存区域。通过缓存频繁访问的数据和索引,Buffer Pool能够显著提高数据库的读写性能。
77 2
|
1月前
|
SQL 关系型数据库 MySQL
MySQL 锁
MySQL里常见的几种锁
52 3
|
2月前
|
canal 消息中间件 关系型数据库
Canal作为一款高效、可靠的数据同步工具,凭借其基于MySQL binlog的增量同步机制,在数据同步领域展现了强大的应用价值
【9月更文挑战第1天】Canal作为一款高效、可靠的数据同步工具,凭借其基于MySQL binlog的增量同步机制,在数据同步领域展现了强大的应用价值
624 4
|
26天前
|
存储 关系型数据库 MySQL
优化 MySQL 的锁机制以提高并发性能
【10月更文挑战第16天】优化 MySQL 锁机制需要综合考虑多个因素,根据具体的应用场景和需求进行针对性的调整。通过不断地优化和改进,可以提高数据库的并发性能,提升系统的整体效率。
47 1
|
1月前
|
关系型数据库 MySQL Java
MySQL数据锁:Record Lock,Gap Lock 和 Next-Key Lock
本文基于 MySQL 8.0.30 版本及 InnoDB 引擎,深入解析三种行锁机制:记录锁(Record Lock)、间隙锁(Gap Lock)和临键锁(Next-key Lock)。记录锁锁定索引记录,确保事务唯一修改;间隙锁锁定索引间的间隙,防止新记录插入;临键锁结合两者,锁定范围并记录自身,有效避免幻读现象。通过具体示例展示了不同锁的作用机制及其在并发控制中的应用。
106 2
|
1月前
|
存储 关系型数据库 MySQL
MySQL数据库锁:共享锁和独占锁
本文详细介绍了`InnoDB`存储引擎中的两种行级别锁:共享锁(S锁)与排他锁(X锁)。通过具体示例展示了这两种锁的工作机制及其在`InnoDB`与`MyISAM`引擎中的表现差异。文章还提供了锁的兼容性矩阵,帮助读者更好地理解锁之间的互斥关系。最后总结了两种锁的特点及适用场景。适合希望深入了解`MySQL`并发控制机制的读者阅读。
41 1
|
26天前
|
存储 关系型数据库 MySQL
MySQL锁,锁的到底是什么?
【10月更文挑战第16天】MySQL 锁锁定的是与数据和资源相关的对象,其目的是为了保证数据的一致性、避免冲突,并在并发环境下合理协调事务或操作的执行。理解锁的对象和意义对于优化数据库性能、处理并发问题至关重要。
54 0
|
2月前
|
监控 关系型数据库 MySQL
MySQL锁机制与解决死锁问题
MySQL锁机制与解决死锁问题
267 5
|
28天前
|
关系型数据库 MySQL 数据库
mysql锁详解
通过理解并合理运用MySQL中的锁机制,开发者可以有效管理数据库并发访问,平衡性能与数据一致性需求。更多关于MySQL锁的深入探讨和最佳实践,请参考专业的数据库管理资源[[深入MySQL锁机制详解
32 0