innodb加锁分析

这篇就是走了一遍登博的mysql加锁处理分析

基础知识请移步事务基础

快照读:简单的select操作,属于快照读,是不进行加锁的(也有例外,如Seriable隔离级下,应该是没有其他情况了)

当前读:

  1. lock in share mode;
  2. for update
  3. insert
  4. update
  5. delete

下边分析下这条语句的加锁情况:

delete from t1 where id = 10;
  1. 前提一:id列是不是主键?
  2. 前提二:当前系统的隔离级别是什么?
  3. 前提三:id列如果不是主键,那么id列上有索引吗?
  4. 前提四:id列上如果有二级索引,那么这个索引是唯一索引吗?
  5. 前提五:两个SQL的执行计划是什么?索引扫描?全表扫描?

下表中如无说明,加的锁类型都是X锁。

组合方式 加锁情况分析 备注
id列是主键,RC隔离级别 加记录锁,锁主键,锁对应记录  
id列是二级唯一索引,RC隔离级别 加记录锁,锁主键和二级索引,锁对应的一条记录  
id列是二级非唯一索引,RC隔离级别 加记录锁,锁主键和二级索引,锁对应的几条记录  
id列上没有索引,RC隔离级别 加记录锁,锁所有记录,锁主键 若id列上没有索引,SQL会走聚簇索引的全扫描进行过滤,由于过滤是由MySQL Server层面进行的。因此每条记录,无论是否满足条件,都会被加上X锁。但是,为了效率考量,MySQL做了优化,对于不满足条件的记录,会在判断后放锁,最终持有的,是满足条件的记录上的锁,但是不满足条件的记录上的加锁/放锁动作不会省略。同时,优化也违背了2PL的约束。
id列是主键,RR隔离级别 加记录锁,锁主键,锁对应记录  
id列是二级唯一索引,RR隔离级别 加记录锁,锁主键和二级索引,锁对应记录  
id列是二级非唯一索引,RR隔离级别 二级索引上匹配的记录上加记录锁和二级索引匹配的记录间加GAP锁,对应的主键索引上加记录锁 1.GAP锁,就是RR隔离级别,相对于RC隔离级别,不会出现幻读的关键
id列上没有索引,RR隔离级别 匹配到的主键索引上记录锁,记录之间加GAP锁 semi-consistent read开启的情况下,对于不满足查询条件的记录,MySQL会提前放锁