MySQL加锁规则详解:一行改动为何引发大量锁
需积分: 0 70 浏览量
更新于2024-07-01
收藏 981KB PDF 举报
"MySQL加锁规则详解"
在MySQL数据库中,特别是在InnoDB存储引擎下,锁定机制对于并发控制和事务隔离至关重要。本文将深入探讨在可重复读(Repeatable Read)隔离级别下的加锁规则,主要关注于行级锁,特别是Next-Key Locks。这些规则适用于MySQL 5.x系列至5.7.24以及8.0系列至8.0.13。
首先,我们需要了解两个基本原则:
1. **加锁的基本单位是Next-Key Lock**:Next-Key Lock是一种结合了行锁与间隙锁的机制,它锁定的是一个前开后闭的区间,即包括当前行并锁定相邻的间隙。
2. **查找过程中访问到的对象才会加锁**:只有在查询过程中实际访问到的索引记录才会被锁定,未被访问到的不会加锁。
接着,有两个优化策略:
1. **优化1:等值查询与唯一索引**:在唯一索引上进行等值查询时,Next-Key Lock会退化为行锁,仅锁定匹配的那一行。
2. **优化2:等值查询的右边界**:在索引上进行等值查询且向右遍历时,如果最后一个值不满足等值条件,Next-Key Lock会退化为间隙锁,只锁定到不满足条件的最后一个值前的区间。
然而,有一个需要注意的“bug”或异常情况:
**唯一索引上的范围查询**:当在唯一索引上执行范围查询时,锁会一直持续到不满足条件的第一个值,即使这个值并不在查询范围内。
举例说明:
例如,假设我们有表`t`,结构如下:
```sql
CREATE TABLE `t` (
`id` int(11) NOT NULL,
`c` int(11) DEFAULT NULL,
`d` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_c_d` (`c`,`d`)
) ENGINE=InnoDB;
```
当我们执行如下等值查询:
```sql
SELECT * FROM `t` WHERE `id` = 7;
```
由于表中没有id为7的记录,Next-Key Lock会锁定(id=6, id=7)的区间,形成一个间隙锁,防止其他事务在这个范围内插入数据,从而保证可重复读的隔离级别。
对于范围查询,比如:
```sql
SELECT * FROM `t` WHERE `id` > 7;
```
在唯一索引`id`上,锁会锁定(id=8, id=最大值)的区间,即使表中可能没有大于7的id,也会锁定到不满足条件的第一个值(如果有)。
这些规则有助于理解MySQL中的锁行为,帮助避免死锁并优化并发性能。在实际应用中,根据业务场景选择适当的事务隔离级别和索引设计,可以有效减少不必要的锁竞争,提升系统性能。同时,随着MySQL版本的更新,加锁策略可能会有所变化,因此开发者需要时刻关注官方文档和最新动态。如果你在验证这些规则时发现不符之处,应当进一步研究或报告问题,以便共同进步。
点击了解资源详情
点击了解资源详情
点击了解资源详情
2022-08-03 上传
2022-08-04 上传
2020-12-15 上传
2021-03-27 上传
2020-12-15 上传
蟹蛛
- 粉丝: 32
- 资源: 323