• mvcc巨无霸【重点】


    1 ru rc

    xxx val1 sac9   rc ru
      start sac13    

    xxx val2 sac13

    undo1 xxx val1 sac9

    update    
       

    select

    start sac18

     
       

    readview

    [13,18]

    min 13

    next 19

    create 13

    直接返回val2
       

    sac13 >= 13 < 19

    &&sac13 属于[13,18]

    证明该记录未提交,不可访问

     
       

    查undo1

     
       

    sac9 < 13

    证明该记录已提交,可访问

    返回val1

     

    2 rc rr

    xxx val1 sac9   rc rr
       

    select

    start sac11

    为了保证事务内可见性,同一个事务多次select,一个事务id

     
       

    readview

    [11]

    min 11

    next 12

    create 11

     
       

    sac9 < 13

    证明该记录已提交

    返回val1

     
      start sac13    

    xxx val2 sac13

    undo1 xxx val1 sac9

    update    
      commit 13    
       

    readview

    [11]

    min 11

    next 14

    create 11

    沿用readview

    readview

    [11]

    min 11

    next 12

    create 11

       

    sac13 >= 11 < 14

    &&sac13 不属于[11]

    证明该记录已提交,可访问

     sac13 > 12

    该记录事务在当前事务生成ReadView后才开启,所以该版本不可以被当前事务访问

         返回val2  查undo1
         

     sac9 < 11

    证明该记录已提交,可访问

    返回val1

     以下为undo删除      
     

    当前事务集合[11]

    next sac 14

       

     undo0 sac13 > 11

    该记录未沉默,仍对一部分事务不可见(比一部分事务readview最小值大)

    它仍有传递链表节点的责任和价值

         
         commit 11  

     unco0 sac13 < 14, C为空

    该记录沉默,对于当前所有事务及将来所有事务,有 sac13 < min sac

    该记录对所有其它事务可见

         
     该记录的链表下一个节点undo1失去价值      
     purge线程删除undo1      

    3 参考:

    https://www.cnblogs.com/jmliao/p/13204946.html MVCC ReadView介绍

    对于使用READ UNCOMMITTED隔离级别的事务来说,由于可以读到未提交事务修改过的记录,所以直接读取记录的最新版本就好了;对于使用SERIALIZABLE隔离级别的事务来说,设计InnoDB的大叔规定使用加锁的方式来访问记录(加锁是啥我们后续文章中说哈);
    对于使用READ COMMITTED和REPEATABLE READ隔离级别的事务来说,都必须保证读到已经提交了的事务修改过的记录,也就是说假如另一个事务已经修改了记录但是尚未提交,是不能直接读取最新版本的记录的,
    核心问题就是:需要判断一下版本链中的哪个版本是当前事务可见的。为此,设计InnoDB的大叔提出了一个ReadView的概念,这个ReadView中主要包含4个比较重要的内容:

    m_ids:表示在生成ReadView时当前系统中活跃的读写事务的事务id列表。

    min_trx_id:表示在生成ReadView时当前系统中活跃的读写事务中最小的事务id,也就是m_ids中的最小值。

    max_trx_id:表示生成ReadView时系统中应该分配给下一个事务的id值。

    小贴士: 注意max_trx_id并不是m_ids中的最大值,事务id是递增分配的。比方说现在有id为1,2,3这三个事务,之后id为3的事务提交了。那么一个新的读事务在生成ReadView时,m_ids就包括1和2,min_trx_id的值就是1,max_trx_id的值就是4。

    creator_trx_id:表示生成该ReadView的事务的事务id。

    小贴士: 我们前边说过,只有在对表中的记录做改动时(执行INSERT、DELETE、UPDATE这些语句时)才会为事务分配事务id,否则在一个只读事务中的事务id值都默认为0。胡说八道,为0还怎么搞mvcc多版本读?

    有了这个ReadView,这样在访问某条记录时,只需要按照下边的步骤判断记录的某个版本是否可见:

    如果被访问版本的trx_id属性值与ReadView中的creator_trx_id值相同,意味着当前事务在访问它自己修改过的记录,所以该版本可以被当前事务访问。
    如果被访问版本的trx_id属性值小于ReadView中的min_trx_id值,表明生成该版本的事务在当前事务生成ReadView前已经提交,所以该版本可以被当前事务访问。
    如果被访问版本的trx_id属性值大于或等于ReadView中的max_trx_id值,表明生成该版本的事务在当前事务生成ReadView后才开启,所以该版本不可以被当前事务访问。
    如果被访问版本的trx_id属性值在ReadView的min_trx_id和max_trx_id之间,那就需要判断一下trx_id属性值是不是在m_ids列表中,如果在,说明创建ReadView时生成该版本的事务还是活跃的,该版本不可以被访问;如果不在,说明创建ReadView时生成该版本的事务已经被提交,该版本可以被访问。
    如果某个版本的数据对当前事务不可见的话,那就顺着版本链找到下一个版本的数据,继续按照上边的步骤判断可见性,依此类推,直到版本链中的最后一个版本。如果最后一个版本也不可见的话,那么就意味着该条记录对该事务完全不可见,查询结果就不包含该记录。

    在MySQL中,READ COMMITTED和REPEATABLE READ隔离级别的的一个非常大的区别就是它们生成ReadView的时机不同。

    READ COMMITTED —— 每次读取数据前都生成一个ReadView

    REPEATABLE READ —— 在第一次读取数据时生成一个ReadView

    https://zhuanlan.zhihu.com/p/166152616 MySQL 的可重复读到底是怎么实现的?图解 ReadView 机制

    https://blog.csdn.net/longgeqiaojie304/article/details/98872857 Mysql隔离性之Read View MVCC ReadView介绍

    4 undo在内存中,什么时候删除?

    4.1 insert

    commit后直接删除

    4.2 update

    设当前活跃事务集合C,其最小值为cmin,nextsac

    当undo sac < cmin,或当C为空且undo sac < nextsac时,undo sac沉默,对将来所有事务可见,则undo sac链表下级 undo sac1可删除

    Mysql Innodb中undo-log和MVCC多版本一致性读 的实现 - chouhe8007 - CSDN博客

    史上最详尽,一文讲透 MVCC 实现原理 - 居士的CSDN - CSDN博客

    (11条消息)mysql innodb中MVCC理解和redo,undo log详解 - harryptter的专栏 - CSDN博客

    (11条消息)【MySQL】InnoDB 中 RC、RR 事务隔离级别下快照读的区别及原因 - chenghan_yang的博客 - CSDN博客

    (12条消息)轻松理解MYSQL MVCC 实现机制 - 杨龙飞的博客 - CSDN博客

    Mysql心路历程:两个"log"引发的"血案" - 心中的理想乡的个人页面 - OSCHINA

  • 相关阅读:
    python生成器和使用gevent操作协程
    python飞机大战
    python控制鼠标键盘+监听键盘
    python生成彩色二维码
    springboot+springcloud+maven相关父子项目创建
    c++求最大公约数
    java8 LocalDateTime
    nginx 代理wss
    vue 全局使用axios
    Vue3.0核心源码解读| 组件渲染:vnode 到真实 DOM 是如何转变的?
  • 原文地址:https://www.cnblogs.com/silyvin/p/13808439.html
Copyright © 2020-2023  润新知