MySQL隔离性的实现

2022-01-25 19:13:43

写隔离

MySQL 利用锁机制保护并发访问资源,实现写隔离。

根据保护的资源分类有如下锁:

latch(闩锁):rwlock、mutex,主要保护内存资源;    
MDL: Metadata_lock,元数据(DDL 操作);
table_lock: 表级别 
  lock table t1 read ;
  mysqldump、XBK(PBK):备份非InnoDB数据时,触发FTWRL全局锁表(Global)。
  行锁升级为表锁。
row lock:InnoDB 默认锁粒度,加锁方式都是在索引加锁的。
  record lock : 记录锁,在聚簇索引锁定。RC 级别只有 record lock。
  gap lock    : 间隙锁,在辅助索引间隙加锁。RR 级别存在。防止幻读。
    next lock   : 下一键锁,GAP+Record。RR 级别存在。防止幻读。

什么是幻读,RR 又是如何防止幻读?

幻读:在当前事务读到了另一个事务 insert 的数据。

解决:

功能性上可分为:

IS   : select * from t1 lock in shared mode;
S    : 读锁。             
IX   :  意向排他锁。表上添加的。 select * from t1 for update;
X    :  排他锁,写锁。

读隔离

MySQL 利用 MVCC + 隔离级别 实现读隔离。

隔离级别的读隔离:

MVCC利用乐观锁机制,实现非锁定读取。

做每一个查询操作时,会在当前事务获取到系统最新的快照,此处被称为 read view。

read view:RV,版本号集合。

每个事务后续的查询都基于当前事务中最新的快照进行查询,而不去找原表数据,所以实现了读的隔离。

Read view 在 RC 和 RR 隔离级别下的生成规则有所不同。

RC 级别下每个查询操作就会生成一个新的 read view,当前事务也能读取到其它事务 commit 的 read view,后续的查询都是基于前最新的 read view。
RR 级别下从第一个查询开始就生成一个 global consistence snapshot read view,该 read view 一直伴随着事务生命周期的结束,这也是 RR 隔离级别下支持可重复读的一个原因。

快照技术由 undo log 来提供。

总结:

  1. MVCC采用乐观锁机制,实现非锁定读取。
  2. 在 RC 级别下,事务中可以立即读取到其他事务 commit 过的readview。
  3. 在 RR 级别下,事务中从第一次查询开始,生成一个一致性 readview,直到事务结束。