两文说透MySQL里的各种锁(下篇)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: 两文说透MySQL里的各种锁(下篇)

在上篇中,我们介绍了MySQL中的全局锁和表锁。

今天,我们专注于介绍一下锁,这个在日常开发和面试中常常困扰我们的问题。


8.jpg

1. 行锁基础


由于全局锁和表锁对增删改查的性能都会有较大影响,所以,我们自然会想到,

只需要对有修改的行加锁就行了,这就是行锁。

在事务中,事务1更新了一行主键为1的数据行,那么,在这个事务释放锁之前,事务2是不能操作的。


9.jpg


另外,有一个很多人容易混淆的概念,就是行锁什么时候释放?搞清这个事情,需要了解什么叫作 两阶段锁。什么是两阶段锁呢?举个例子你就明白了。


10.jpg


这里事务2执行后会是什么结果呢?

如果你明白了两阶段锁的含义,你就会知道,事务2的updat语句会阻塞,直到事务1提交以后才能继续执行。

所以,这里再次强调一下,两阶段锁的含义。

在 InnoDB 事务中,行锁是在需要的时候才加上的,但并不是语句执行完了了就立刻释放, 而是要等到事务结束时才释放。

注意,除了update语句能加写锁外,另外,还有一种对select语句加写锁的方式,就是当前读:Select …. for update


2.行锁进阶


2.1 什么是幻读

面试的时候,面试官经常会喜欢问数据库的事务隔离级别。

大家要能回答出四种隔离级别,四种隔离级别的含义。

再多问一点,会问你什么是脏读,什么是幻读,哪个隔离级别会解决什么问题。

首先明确一下,什么是幻读?

同样是一个事务,在事务中前后两次查询,出现了不同的结果。不同之处在于,脏读是针对update,也就是同一行的数据出现了不一致。

注意,幻读出现的场景

  • 事务的隔离级别为可重复读,且是当前读
  • 幻读仅专指新插入的行,在范围查询中,后一次查询出现了新的数据行。


2.2 怎么解决幻读


这些如果你都能答上,面试官可能会继续追问,幻读是怎么产生的,又是怎么被解决的。

即使我们给所有update涉及的行都加上了行锁,还是无法解决新插入的记录,因为这些记录原本不存在,自然无法加上行锁。

那怎么办呢?为了解决这个问题,innodb只好引入新的锁,间隙锁(Gap Lock)。

间隙锁,锁的是两个值之间的空隙。

举个例子:

在四条记录,ID=0,10,20,30中,会产生如下的五个间隙范围


11.jpg


间隙锁就是对这五个间隙范围加锁,防止新的记录插入。

注意,行锁的冲突是行与行之间的冲突,是行锁与行锁之间的。与间隙锁冲突的是往“间隙中插入数据”这个操作,间隙锁本身不会产生冲突。

间隙锁和行锁合称为next-key lock。每个next-key lock是前开后闭的。间隙锁本身是前开后开的。

标准的事务隔离级别中,可重复读只解决脏读问题,无法解决幻读问题。但是在innodb中,用next-key lock解决了幻读的问题。


3.关于行锁的优化应用


3.1 两阶段锁的优化应用


上面的基础知识中,解释了什么是 两阶段锁。

那么,对我们业务开发中有什么借鉴意义呢?

既然我们知道了,行锁必须在整个事务完全提交后才会释放,那么,如果我们的事物中需要锁住多行,就要把最可能造成锁冲突,或者是锁住最多行的语句尽可能地往后放。举个例子,小A在线上购买了商家B的一个产品,这个购买的动作可以简化为3个操作:1)小A的银行账户余额扣款x;

2)商家B的银行账户余额增加x;

3)添加一条交易记录;

这里,涉及到两个update操作,和一个insert操作。为了保证交易的原子性,将三个动作放在了一个事务中。

那怎么安排三个语句的先后顺序呢?如果不仔细考虑,那么就可能是随意选个123或者213的顺序了。

仔细想想呢?

显然,这里最容易造成冲突的是步骤2),可能同时有多个用户购买商家B的产品,然后需要给商家B的余额做update操作。

     另外,步骤3)是insert操作,最不容易出现锁冲突。

所以,最好的步骤顺序是3)-> 1) -> 2),将最容易产生冲突的操作放在最后执行,那么会比2)->1) ->3)的顺序,大大提高并发度。


3.2 间隙锁的问题与优化


间隙锁的引入也带来了一些新的问题,比如:降低并发度,可能导致死锁。

因为间隙锁的引入,可能会导致同样的语句锁住了更大的范围。

那怎么办呢?

注意,间隙锁在可重复读级别下才是有效的。

所以,只要我们的业务不需要可重复读的保证,我们就可以把隔离级别设置为读提交(也是阿里云rds数据库的默认隔离级别),就没有间隙锁了。

然后,为了解决可能的数据和日志不一致的问题,需要把binlog格式设置为row。

读提交级别 + binlog的row格式,也是一般公司数据库的标准配置。

现在,你知道原因了吧:


参考:

丁奇《MySQL 实战45讲》

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
5月前
|
SQL AliSQL 关系型数据库
MYSQL的全局锁和表锁
本文介绍了MySQL中的锁机制,包括全局锁、表级锁及其应用场景。全局锁通过`Flush tables with read lock (FTWRL)`实现,主要用于全库逻辑备份,但会阻塞更新和结构变更操作。表级锁分为显式表锁(`lock tables`)和元数据锁(MDL),前者用于控制并发访问,后者自动加锁以确保读写正确性。文章还探讨了如何安全地为小表添加字段,建议通过设置DDL等待时间或使用MariaDB/AliSQL的NOWAIT/WAIT功能避免业务阻塞。这些方法有助于在高并发场景下优化数据库性能与安全性。
128 0
|
SQL 关系型数据库 MySQL
MySQL 锁
MySQL里常见的几种锁
195 3
|
8月前
|
关系型数据库 MySQL 网络安全
如何排查和解决PHP连接数据库MYSQL失败写锁的问题
通过本文的介绍,您可以系统地了解如何排查和解决PHP连接MySQL数据库失败及写锁问题。通过检查配置、确保服务启动、调整防火墙设置和用户权限,以及识别和解决长时间运行的事务和死锁问题,可以有效地保障应用的稳定运行。
337 25
|
9月前
|
存储 关系型数据库 MySQL
MySQL进阶突击系列(06)MySQL有几种锁?| 别背答案,现场演示一下
本文详细解析了MySQL InnoDB存储引擎的锁机制,涵盖读锁、写锁、意向锁、记录锁、间隙锁和临键锁等8种锁类型。重点探讨了不同锁类型的加锁与释放方式,以及事务并发场景下的实战验证。通过具体示例,展示了在不同情况下锁的行为及其对事务的影响。文章还特别强调了锁的作用范围主要是索引,并解释了锁如何影响数据的读写操作。最后总结了并发事务中加锁规则,帮助读者深入理解MySQL的锁机制。
|
12月前
|
存储 关系型数据库 MySQL
优化 MySQL 的锁机制以提高并发性能
【10月更文挑战第16天】优化 MySQL 锁机制需要综合考虑多个因素,根据具体的应用场景和需求进行针对性的调整。通过不断地优化和改进,可以提高数据库的并发性能,提升系统的整体效率。
619 1
|
关系型数据库 MySQL Java
MySQL数据锁:Record Lock,Gap Lock 和 Next-Key Lock
本文基于 MySQL 8.0.30 版本及 InnoDB 引擎,深入解析三种行锁机制:记录锁(Record Lock)、间隙锁(Gap Lock)和临键锁(Next-key Lock)。记录锁锁定索引记录,确保事务唯一修改;间隙锁锁定索引间的间隙,防止新记录插入;临键锁结合两者,锁定范围并记录自身,有效避免幻读现象。通过具体示例展示了不同锁的作用机制及其在并发控制中的应用。
1168 2
|
存储 关系型数据库 MySQL
MySQL数据库锁:共享锁和独占锁
本文详细介绍了`InnoDB`存储引擎中的两种行级别锁:共享锁(S锁)与排他锁(X锁)。通过具体示例展示了这两种锁的工作机制及其在`InnoDB`与`MyISAM`引擎中的表现差异。文章还提供了锁的兼容性矩阵,帮助读者更好地理解锁之间的互斥关系。最后总结了两种锁的特点及适用场景。适合希望深入了解`MySQL`并发控制机制的读者阅读。
435 1
|
监控 关系型数据库 MySQL
MySQL锁机制与解决死锁问题
MySQL锁机制与解决死锁问题
588 5
|
12月前
|
存储 关系型数据库 MySQL
MySQL锁,锁的到底是什么?
【10月更文挑战第16天】MySQL 锁锁定的是与数据和资源相关的对象,其目的是为了保证数据的一致性、避免冲突,并在并发环境下合理协调事务或操作的执行。理解锁的对象和意义对于优化数据库性能、处理并发问题至关重要。
319 0
|
12月前
|
关系型数据库 MySQL 数据库
mysql锁详解
通过理解并合理运用MySQL中的锁机制,开发者可以有效管理数据库并发访问,平衡性能与数据一致性需求。更多关于MySQL锁的深入探讨和最佳实践,请参考专业的数据库管理资源[[深入MySQL锁机制详解
224 0

推荐镜像

更多