MySQL 死锁
MySQL 锁的分类
Record Locks
- 共享锁 S
- 排他锁 X
Gap Locks
- 间隙锁是锁定具体的范围,但是不包含行锁本身。
Next-Key Locks
- 是 Record Lock + Gap Locks 锁定一个范围并且包含索引本身
Auto-Inc Lock
- 是一个特殊的表级锁,当一个事务向含有自增字段的表插入数据时,该事务会获取一个 Auto-Inc Lock,其他事务必须等待直到已经获取锁的 insert 语句结束。
Insert Intention Locks
- 插入意向锁是 Gap 锁的一种,只是针对 insert。当并发事务多条 insert 插入同一个GAP,如果他们不是插入同一行记录,会话之间并不会相互等待。
意向锁
- 意向共享锁 IS
- 意向排他锁 IX
RC/RR 模式下,查询,插入,更新,加锁
RC 模式
SELECT
普通的快照读(MCVV) select 下不加锁,但是,当前读对于 select … from … where … for update 对 where 条件后面的加 LOCK_X | LOCK_REC_NOT_GAP; select … from … where … share model; 这个会根据 where 条件加 S 锁;
INSERT
- 非唯一键插入
对插入的记录加 X 锁
- 唯一键插入 对所有的记录加 X 锁
UPDATE
- 唯一主键
在相应的索引记录上加 X 锁
- 非唯一主键 查到的记录加 X 锁
DELETE
- 满足删除条件的所有记录:LOCK_X + LOCK_REC_NOT_GAP
- 删除的记录不存在:LOCK_X + LOCK_GAP
RR 模式
SELECT
- 普通的快照读不加锁
-
当前读,对于 SELECT … IN SHARE MODE,如果查询的是唯一索引且是等值查询,加 LOCK_X LOCK_REC_NOT_GAP 锁。对于非唯一索引 或者 索引范围查询,加 LOCK_ORDINARY LOCK_S。
UPDATE
- 唯一主键
在相应的索引记录上加 X 锁
-
非唯一主键 查到的记录加 next-key 锁
-
对于没有满足条件的行 加 gap 锁
INSERT
-
非唯一主键 加 X 锁
-
唯一主键
- 先加 LOCK_X + LOCK_ORDINARY 进行唯一键检查
- 插入的位置有意向锁:LOCK_INSERT_INTENTION
- 新数据插入:LOCK_X + LOCK_REC_NOT_GAP
DELETE
- 不存在唯一键
- 存在记录:LOCK_X + LOCK_ORDINARY(NEXT_KEY)
- 不存在记录:LOCK_X + LOCK_GAP
- 记录标记已删除:LOCK_X + LOCK_ORDINARY
- 存在唯一键 (Unique Key)
- 存在记录:LOCK_X + LOCK_REC_NOT_GAP
- 不存在记录:LOCK_X + LOCK_GAP
- 记录标记已删除:LOCK_X + LOCK_ORDINARY