innoDB对MVCC的实现

InnoDB存储引擎在 RR 级别下通过 MVCC和 Next-key Lock 来解决幻读问题:

1、执行普通 select,此时会以 MVCC 快照读的方式读取数据

在快照读的情况下,RR 隔离级别只会在事务开启后的第一次查询生成 Read View ,并使用至事务提交。所以在生成 Read View 之后其它事务所做的更新、插入记录版本对当前事务并不可见

这里用到了隐藏字段

DB_TRX_ID(6字节):表示最后一次插入或更新该行的事务 id。

DB_ROLL_PTR(7字节) 回滚指针,指向该行的 undo log 。如果该行未被更新,则为空

若聚簇索引记录DB_TRX_ID小于事务id则可见,如果不可见,则根据DB_ROLL_PTR取出快照记录的DB_TRX_ID再进行循环判断。

image-20220227212834866

实现了可重复读和防止快照读下的 “幻读”

2、执行 select…for update/lock in share mode、insert、update、delete 等当前读,使用间隙锁加锁

在当前读下,读取的都是最新的数据,如果其它事务有插入新的记录,并且刚好在当前事务查询范围内,就会产生幻读!InnoDB 使用 Next-key Lock 来防止这种情况。当执行当前读时,会锁定读取到的记录的同时,锁定它们的间隙,防止其它事务在查询范围内插入数据。只要我不让你插入,就不会发生幻读

对于读已提交和重复读

在事务隔离级别 RC 和 RR (InnoDB 存储引擎的默认事务隔离级别)下,InnoDB 存储引擎使用 MVCC(非锁定一致性读),但它们生成 Read View 的时机却不同

  • 在 RC 隔离级别下的 每次select 查询前都生成一个Read View (m_ids 列表)
  • 在 RR 隔离级别下只在事务开始后 第一次select 数据前生成一个Read View(m_ids 列表)

然后根据数据可见性算法,导致RC的问题为不可重复读,RR解决了不可重复读

 

posted @ 2022-07-17 19:03  山野村夫01  阅读(77)  评论(0编辑  收藏  举报