MySQL锁的分类?(根据加锁的范围)
- 全局锁
- 表级锁
- 表锁
- 元数据锁(MDL)
- 意向锁
Auto-Inc锁
- 行级锁
- 记录锁(Record Lock)
- 间隙锁(Gap Lock)
- 临键锁(Next-Key Lock)
对MySQL锁的分析
全局锁:主要用于全库逻辑备份
# 执行全局锁
flush tables with read lock
# 释放全局锁
unlock tables
表锁:
- 表级别的共享锁,就是读锁
- 表级别的独占锁,就是写锁
# 读锁
lock tables users read;
# 写锁
lock tables users write;
# 释放锁
unlock tables
当我们对一个表加读锁时,本线程只能读,不能写;其它线程也只能读,不能写
元数据锁(MDL):当我们对这个数据库表操作时,会自动给这个表加MDL锁
- 对一张表进行增删改查时,加的是
MDL读锁 - 对表结构变更时,加的是
MDL写锁
MDL是为了保证当用户对表进行CRUD时,防止其它线程对这个表结构进行修改
MDL是在事务提交后,才会释放
意向锁:目的是为了快速判断是否有记录被加锁
- 意向独占锁和意向共享锁都是
表级锁,不会与行级的共享锁和独占锁发生冲突 - 意向锁之间也不会发生冲突
- 意向锁只会和共享表锁和独占表锁发生冲突
# 先在表上加上意向共享锁,然后读取的记录加共享锁
select ... lock in share mode;
# 先在表上加上意向独占锁,然后对读取的记录加独占锁
select ... for update;
Auto-Inc锁:是一个特殊的表锁机制
- 在插入数据时,可以不指定主键的值,数据库会自动给主键赋递增的值
- 锁的释放:不是在一个事务提交后释放,而是在执行完插入语句后,立即释放锁
- 一个事务在持有
Auto-Inc锁的过程中,其它事务如果向该表插入数据时,会被阻塞- 从而保证插入数据时,被
Auto_Increment修饰的字段的值,是连续递增的
- 从而保证插入数据时,被
Record Lock:称为记录锁,锁住的是一条记录
但是记录锁是有S锁和X锁之分的:
- 当一个事务对一条记录加了 S 型记录锁后,其他事务也可以继续对该记录加 S 型记录锁,但是不可以对该记录加 X 型记录锁
- 当一个事务对一条记录加了 X 型记录锁后,其他事务既不可以对该记录加 S 型记录锁,也不可以对该记录加 X 型记录锁

Gap Lock:称为间隙锁,只存在于可重复读隔离级别
- 目的是为了解决可重复读隔离级别下的幻读现象
- 间隙锁之间是兼容的
Next-Key Lock:临键锁,是记录锁和间隙锁的组合,锁定一个范围,并且锁定记录本身
- 临键锁是 前开 后闭 的区间,即 (]
- 同时临键锁也满足记录锁X和S锁之间的兼容性
所以临键锁即能保存记录,又能阻止其它事务将新记录插入到被保护的前面的间隙中
这里为大家拓展一个
插入意向锁
插入意向锁:
业务场景:一个事务在插入一条记录的时候,需要判断插入的位置是否被其他事务加了临键锁。如果有临键锁,插入操作就会发生阻塞,直到拥有间隙锁的那个事务提交为止,在此期间,会生成一个插入意向锁,表明有事务想在某个区间插入新纪录,但是现在处于等待状态
插入意向锁:虽然名字有意向锁,但是并不是意向锁,它是一种特殊的间隙锁,属于行级别锁