美文网首页
MVCC可见性判断

MVCC可见性判断

作者: 祁小彬 | 来源:发表于2022-04-06 14:44 被阅读0次

    RR隔离级别下,创建一个新事务后,执行第一个select语句的时候,innodb会创建一个Read View,Read View 中会保存系统当前其他活跃事务id列表(即trx_ids)。当用户在这个事务中要读取某个记录行的时候,innodb会将该记录行的DB_TRX_ID(记为trx_id)与该Read View中的一些变量进行比较,判断是否满足可见性条件。

    1. 如果 trx_id < up_limit_id(低水位), 那么表明“最新修改该行的事务”在“当前事务”创建快照之前就提交了,所以该记录行的值对当前事务是可见的。跳到步骤5。

    2. 如果 trx_id >= low_limit_id(高水位), 那么表明“最新修改该行的事务”在“当前事务”创建快照之后才修改该行,所以该记录行的值对当前事务不可见。跳到步骤4。

    3. 如果 up_limit_id <= trx_id < low_limit_id, 表明“最新修改该行的事务”在“当前事务”创建快照的时候可能处于“活动状态”或者“已提交状态”;所以就要对活跃事务列表trx_ids进行查找(源码中是用的二分查找,因为是有序的):

    4. 如果在活跃事务列表trx_ids中能找到 id 为 trx_id 的事务,表明可能是下面两种情况。这些情况下,这个记录行的值对当前事务都是不可见的,跳到步骤4

    5. 在“当前事务”创建快照前,“该记录行的值”被“id为trx_id的事务”修改了,但没有提交

    6. 在“当前事务”创建快照后,“该记录行的值”被“id为trx_id的事务”修改了(不管有无提交)

    7. 在活跃事务列表中找不到,则表明“id为trx_id的事务”在修改“该记录行的值”后,在“当前事务”创建快照前就已经提交了,所以记录行对当前事务可见,跳到步骤5。

    8. 在该记录行的 DB_ROLL_PTR 指针所指向的undo log回滚段中,取出最新的的旧事务号DB_TRX_ID, 将它赋给trx_id,然后跳到步骤1重新开始判断。

    9. 将该可见行的值返回。

    innodb中的Repeatable Read级别, 只有事务在begin之后,执行第一条select(读操作)时, 才会创建一个快照(read view),将当前系统中活跃的其他事务记录起来;并且事务之后都是使用的这个快照,不会重新创建,直到事务结束。

    在innodb中的Read Committed级别, 事务在begin之后,执行每条select(读操作)语句时,快照会被重置,即会重新创建一个快照(read view)。

    image.png

    这样,对于当前事务的启动瞬间来说,一个数据版本的 row trx_id,有以下几种可能:

    • 如果落在绿色部分,表示这个版本是已提交的事务或者是当前事务自己生成的,这个数据是可见的;

    • 如果落在红色部分,表示这个版本是由将来启动的事务生成的,是肯定不可见的;

    • 如果落在黄色部分,那就包括两种情况

    • 若 row trx_id 在数组中,表示这个版本是由还没提交的事务生成的,不可见;

    • 若 row trx_id 不在数组中,表示这个版本是已经提交了的事务生成的,可见。

    一个数据版本,对于一个事务视图来说,除了自己的更新总是可见以外,有三种情况:

    • 版本未提交,不可见;
    • 版本已提交,但是是在视图创建后提交的,不可见;
    • 版本已提交,而且是在视图创建前提交的,可见。

    相关文章

      网友评论

          本文标题:MVCC可见性判断

          本文链接:https://www.haomeiwen.com/subject/ojirsrtx.html