锁
按读写锁分
- 共享锁(S锁):也称读锁,多个事务可以同时读取同一行数据,互不干扰,但都不能修改
- 排他锁(X锁):也称写锁,一旦某个事务获得排他锁,当前事务可读写;其他事务既不能读也不能写,只能等待
兼容性(表锁和行锁都一样):只有S和S是兼容的
==注意:==这个图是【表表】 【行行】,【表行】都通用的:

表级意向锁的情况(因为意向锁是加行锁的时候加的,那我一个表有很多行,加各自的行锁就会加对应的意向锁,所以意向锁之间不冲突)

表级的元数据锁:

按粒度划分
全局锁
- 功能:让整个数据库处于只读状态,其他DML/DDL操作都会被阻塞。
- 使用场景:全库逻辑备份(但InnoDB使用
mysqldump --single-transaction更好) - 主要命令:
FLUSH TABLES WITH READ LOCK;(上锁) /UNLOCK TABLES;(解锁)。
表级锁
- 表锁:基本的表级别S/X锁,粒度大,并发性能低。使用
LOCK TABLES ... READ/WRITE命令控制 - 元数据锁(MDL):保护表结构,避免DML和DDL冲突。由系统自动控制,==访问表时加MDL读锁,修改表结构时加MDL写锁==
- 意向锁:由InnoDB在加行锁之前自动添加,告诉系统“我准备要加行锁了”
- 作用:提高加表锁时的判断效率,无需遍历全表检查行锁
- 类型:意向共享锁 (IS) 与 **意向排他锁 (IX)**【不同的行锁对应不同的表级意向锁】
- **自增锁 (AUTO-INC)**:保证并发插入时自增主键(
AUTO_INCREMENT)的唯一性。可通过innodb_autoinc_lock_mode参数配置模式
行级锁
InnoDB 的行锁是基于索引的。如果
WHERE条件没有使用索引(或索引失效),则行锁会升级为全表锁
记录锁
二级索引,除了二级索引记录会被加锁,如果回表去查询了,那么逐渐索引记录也会被加上锁
锁定对象:单条索引记录
触发场景:等值查询 且查询条件为 唯一索引(包括主键)时,且记录存在
X锁:
1 | SELECT * FROM user WHERE id = 10 FOR UPDATE |
S锁:
1 | SELECT * FROM user WHERE id = 10 LOCK IN SHARE MODE |
间隙锁
间隙的定义
锁定对象:索引记录之间的 空隙(不包含记录本身),防止其他事务往空隙中插入新数据
触发场景:RR 隔离级别下,范围查询 或 等值查询不存在的记录,或者对索引加锁时
1 | -- user 表 id 有 1, 5, 10 三行 |
1 | BEGIN; |
==特性==:间隙锁之间互相兼容,即两个事务可以锁住同一个间隙,因为它们目的都是“禁止插入”,而不是互斥
临建锁
定义:记录锁 + 间隙锁
触发场景:RR 隔离级别下,当前读 的默认行锁算法(非唯一索引、范围查询等)
1 | -- user 表 id 有 1, 5, 10, 20 |
插入意向锁
定义:一种特殊的间隙锁,表示事务准备在一个间隙中插入数据
触发场景:INSERT 操作在真正插入之前,会在目标间隙加上插入意向锁
1 | -- 表 t 有 id 索引:当前记录 id = 10, 20 |
作用:多个事务可以在同一间隙上同时加插入意向锁,只要他们插入的位置不同,就不会互相阻塞,从而提升并发;==如果相同了,那就只能一个事务插入成功,其他识事务就主键冲突了==
间隙锁和插入意向锁的兼容情况
==理解:==
插入意向锁使并发度变高

使死锁变的可检测

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 夏天的风吹向哪里!


