按读写锁分

  • 共享锁(S锁):也称读锁,多个事务可以同时读取同一行数据,互不干扰,但都不能修改
  • 排他锁(X锁):也称写锁,一旦某个事务获得排他锁,当前事务可读写;其他事务既不能读也不能写,只能等待

兼容性(表锁和行锁都一样):只有S和S是兼容的

==注意:==这个图是【表表】 【行行】,【表行】都通用的:

image-20260513233617991

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

image-20260513234125775

表级的元数据锁:

image-20260513234910604

按粒度划分

全局锁

  • 功能:让整个数据库处于只读状态,其他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

间隙锁

间隙的定义image-20260514111137966

锁定对象:索引记录之间的 空隙(不包含记录本身),防止其他事务往空隙中插入新数据
触发场景:RR 隔离级别下,范围查询等值查询不存在的记录,或者对索引加锁时

1
2
3
-- user 表 id 有 1, 5, 10 三行
BEGIN;
SELECT * FROM user WHERE id = 7 FOR UPDATE; -- id=7 不存在,加间隙锁 (5,10)此时其他事务不能插入 id=6,7,8,9 的数据
1
2
3
BEGIN;
SELECT * FROM user WHERE id BETWEEN 5 AND 10 FOR UPDATE;
-- 加锁范围:记录锁锁住 id=5 和 id=10,间隙锁锁住 (5,10)

==特性==:间隙锁之间互相兼容,即两个事务可以锁住同一个间隙,因为它们目的都是“禁止插入”,而不是互斥

临建锁

定义:记录锁 + 间隙锁
触发场景:RR 隔离级别下,当前读 的默认行锁算法(非唯一索引、范围查询等)

1
2
3
4
-- user 表 id 有 1, 5, 10, 20
BEGIN;
SELECT * FROM user WHERE id > 10 FOR UPDATE;
-- 锁定区间:记录锁锁住 20(最大记录)和上界无穷大,间隙锁锁住 (10,20)、(20,+∞)

插入意向锁

定义:一种特殊的间隙锁,表示事务准备在一个间隙中插入数据
触发场景INSERT 操作在真正插入之前,会在目标间隙加上插入意向锁

1
2
3
4
5
6
7
-- 表 t 有 id 索引:当前记录 id = 10, 20
-- 连接1 先锁住了间隙 (10,20)
BEGIN;
SELECT * FROM t WHERE id = 15 FOR UPDATE; -- 间隙锁 (10,20)

-- 连接2 想要插入 id=18(位于同一间隙)
INSERT INTO t(id) VALUES(18); -- 需要获取插入意向锁,但与连接1的间隙锁冲突,阻塞

作用:多个事务可以在同一间隙上同时加插入意向锁,只要他们插入的位置不同,就不会互相阻塞,从而提升并发;==如果相同了,那就只能一个事务插入成功,其他识事务就主键冲突了==

间隙锁和插入意向锁的兼容情况

image-20260517094936701

==理解:==

  1. 插入意向锁使并发度变高

    image-20260514115553311

  2. 使死锁变的可检测

    image-20260514115644042