MySQL 加锁

2018/11/29

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
  1. 非唯一键插入

对插入的记录加 X 锁

  1. 唯一键插入 对所有的记录加 X 锁
UPDATE
  1. 唯一主键

在相应的索引记录上加 X 锁

  1. 非唯一主键 查到的记录加 X 锁
DELETE
  1. 满足删除条件的所有记录:LOCK_X + LOCK_REC_NOT_GAP
  2. 删除的记录不存在:LOCK_X + LOCK_GAP

RR 模式

SELECT
  1. 普通的快照读不加锁
  2. 当前读,对于 SELECT … IN SHARE MODE,如果查询的是唯一索引且是等值查询,加 LOCK_X LOCK_REC_NOT_GAP 锁。对于非唯一索引 或者 索引范围查询,加 LOCK_ORDINARY LOCK_S。
UPDATE
  1. 唯一主键

在相应的索引记录上加 X 锁

  1. 非唯一主键 查到的记录加 next-key 锁

  2. 对于没有满足条件的行 加 gap 锁

INSERT
  1. 非唯一主键 加 X 锁

  2. 唯一主键

  • 先加 LOCK_X + LOCK_ORDINARY 进行唯一键检查
  • 插入的位置有意向锁:LOCK_INSERT_INTENTION
  • 新数据插入:LOCK_X + LOCK_REC_NOT_GAP
DELETE
  1. 不存在唯一键
  • 存在记录:LOCK_X + LOCK_ORDINARY(NEXT_KEY)
  • 不存在记录:LOCK_X + LOCK_GAP
  • 记录标记已删除:LOCK_X + LOCK_ORDINARY
  1. 存在唯一键 (Unique Key)
  • 存在记录:LOCK_X + LOCK_REC_NOT_GAP
  • 不存在记录:LOCK_X + LOCK_GAP
  • 记录标记已删除:LOCK_X + LOCK_ORDINARY

死锁分析2.0 待补充

Search

    Table of Contents