美文网首页
基于Undo Log版本链快照读原理

基于Undo Log版本链快照读原理

作者: 朱飞 | 来源:发表于2021-09-27 14:59 被阅读0次

    1、抛砖引玉问题:
    (1)什么是Undo Log?
    作用1-回滚日志:每次事务在执行DML语句,便会将相反的DML写入undo log,等到事务RollBack时使数据恢复到事务最开始状态(原子性操作);

    作用2-非锁定一致性读:当前事务读取的某一行被其他事务锁定时,它可以从undo log中分析出该行记录以前的数据是什么,从而提供该行版本信息,让用户实现非锁定一致性读取,实现原理:

    采用“链”的方式保存数据变化,这个多版本就是通过“链”来遍历访问的

    (2)版本链是如何组织的?
    TRX_ID:行记录产生时的事务ID
    DB_ROLL_PTR:指向行记录变更前的数据行版本


    Undo Log版本链.png

    2、关于undo log版本链何时删除的问题?
    (1)undo log不是会被删除吗?
    (2)中间数据被删除了,版本链会被破坏?
    答:MySQL InnDO引擎确保版本链数据“不在被引用”后再删除,官网是说法时,一致性读保证数据一致性时候,没有别的并行事务引用的时候再删除。

    3、版本链到底是如何运行机制保证数据一致性读的呢?这里需要引出一个新的概念:
    (1)快照读:最普通的SELECT查询语句;
    (2)快照读:insert、update、delete、select ... for update、select ... lock in share mode;
    (3) ReadView:快照读SQL执行时,MVCC提取数据的依据;
    注意:是快照读时,才使用MVCC提取数据,当前读时,使用Next-Key Lock(行锁+间隙锁);

    4、ReadView概念说明,ReadView是一个数据结构,包含4个字段:
    (1)m_ids:当前活跃的事务编号集合
    (2)min_trx_id:最小活跃事务编号
    (3)max_trx_id:预分配事务编号(当前最大事务编号N+1)
    (4)creator_trx_id:ReadView创建者的事务编号

    读已提交(RC):在每一次快照读时候生成一个ReadView


    RC隔离级别下ReadView.png

    可重复读(RR):在每一次快照读时候生成一个ReadView

    5、版本链数据访问规则:
    (1)判断当前事务id是否等于creator_id,如果等于说明数据就是自己这个事务更改的,可以访问
    (2)判断trx_id < min_trx_id?成立说明数据已提交,可以访问;
    (3)判断trx_id > max_trx_id? 成立说明该事务在ReadView生成以后才开启,不允许访问;
    (4)判断 min_trx_id < trx_id <= max_trx_id ? ,成立则在m_ids中对比,不存在说明事务已提交,可以访问;

    6、按照以上访问规则由上而下进行版本链的数据判断

    第一次快照读(RC、RR):

    (1)判断数据版本 (trx_id=3)= creator_id(4)?成立说明数据就是自己这个事务修改的,可以访问;-- 显然这里不成立,即:事务C结果无法访问;

    (2)判断当前事务id(trx_id=3)< min_trx_id=2 ?成立说明数据已提交,可以访问;-- 显然这里不成立,即:trx_id=2行不可访问;

    (3)判断当前事务id(trx_id=3)> max_trx_id=5? 成立说明该事务在ReadView生成以后才开启,不允许访问; -- 显然这里不成立

    (4)判断 min_trx_id=2 < =(trx_id=3) <= max_trx_id=5 ? ,成立则在m_ids中对比,不存在说明事务已提交,可以访问; -- 这里trx_id在m_ids内,显然未提交

    在RC模式下,trx_id为2和3都是活跃事务id(在m_ids集合内),显然无法访问,只有trx_id=1 < min_trx_id,说明已提交,可访问;

    第二次快照读(RC):
    (1)trx_id=3,在活跃id中且不小于最小事务id(min_trx_id),所以不可访问;
    (2)trx_id=2,满足min_trx_id=2 < =(trx_id=2) <= max_trx_id=5 ,且不在活跃id集合(m_ids)中,所以可以访问;

    第二次快照读(RR):始终是第一次快照读的结果一致,只是第一次ReadView的复用;

    所以RR隔离级别解决了不可重复读的问题;

    7、RR隔离级别使用MVCC可以解决幻读的问题吗?
    答:
    能:连续多次快照读,ReadView会产生复用,无幻读问题;

    但不是完全解决:两次ReadView之间产生“当前读”,当前读会产生新的ReadView,导致产生幻读;

    相关文章

      网友评论

          本文标题:基于Undo Log版本链快照读原理

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