Mysql进阶【2】论述锁机制,SQL加锁情况

Mysql进阶【2】论述锁机制,SQL加锁情况_第1张图片  

1.MySQL 的锁机制

1.1按粒度分有三种:

  1. 全局锁:核心服务层实现,锁住数据库,full table with read lock;
  2. 表级锁:核心服务层实现,锁住数据库中的某张表
    1. 加表级读锁:本事务不能读取其他未加锁的表的信息
  3. 行级锁:存储引擎层实现,锁住的是某行的索引,也可以是索引的间隙
    1. 记录锁(Record Locks):锁定索引中一条记录。
    2. 间隙锁(Gap Locks):要么锁住索引记录中间的值,要么锁住第一个索引记录前面的值或者最后一个索引记录后面的值。
    3. 临键锁(Next-Key Locks):是索引记录上的记录锁和在索引记录之前的间隙锁的组合(间隙锁 + 记录锁)。
    4. 插入意向锁(Insert Intention Locks):做insert操作时添加的对记录id的锁。

行锁的锁是加在索引上,而非数据本身

  1. 临键锁(Next-Key Locks)相当于记录锁 + 间隙锁【左开右闭区间
  2. 间隙锁:未查询到该条语句,则加上间隙锁,保证索引间隙不被插入其他数据,防止幻读。锁住的是一个索引区间,开区间,不包括两边。
  3. 记录锁:等值查询,锁叫加在该条记录的索引上,而非记录本身

1.2按功能划分两种:

  1. 共享锁Shared Locks(S锁、读锁):加了读锁的记录,允许其他事务在加读锁(select....lock in share mode)
  2. 排他锁Exclusive Locks(X锁,写锁):写锁一加,其他事务不能在加其他写锁或者读锁(select for update)

2.分析 SQL 的锁定情况:delete from tt where uid = 123;

2.1读已提交RC

  1. 如果uid是索引,并且也是主键,并且找到了这台记录的话,会给这条记录加上写锁
  2. uid是唯一索引,不是主键,首先找到这条记录加上写锁,然后拿着主键去主键索引中找到这个记录也加上写锁。
  3. uid不是唯一索引,查询结果不唯一,查询到所有的符合条件的记录加锁,并且通过主键找到主键索引并加上锁
  4. uid不是索引,全表扫描都加上写锁,无论时候符合条件都加上写锁

2.2可重复读【RR】隔离级别

  1. 如果uid是索引,并且也是主键【查找到这条记录,然后给记录加写锁】
  2. uid是唯一索引,不是主键,【辅助索引里查找符合条件的记录,加上写锁,在拿主键到主键索引里边查找对应数据,也加上写锁】
  3. uid不是唯一索引,查询结果不唯一,【查找到符合条件的所有记录,记录不唯一加上写锁,然后再拿主键到主键索引里边查找到对应所有记录也加上写锁,并且记录间的数据加上间隙锁,查找下一个不符合条件的数据加上,符合条件与不符合条件之间的间隙加上间隙锁】
  4. uid不是索引【全表扫描,所有记录加上写锁与间隙锁,设置innodb_locks_unsafe_for_binlog 参数,对于不满足查询条件的记录,MySQL会提前放写锁,不加间隙锁】

 

 

你可能感兴趣的:(数据库,sql,mysql,数据库)