资料参考:https://blog.csdn.net/thesprit/article/details/112970122
    https://www.bilibili.com/video/BV1t5411u7Fg?from=search&seid=11898621611946908479&spm_id_from=333.337.0.0
    mvcc翻译过来叫多版本并发控制,主要针对事务隔离级别中的read commit读已提交可重复读
    首先我们要知道两个概念,一个叫快照读,一个叫当前读,快照读是实现是基于这个多版本并发控制的,那既然是多版本,那就可能读取的数据并不是最新的,不用上锁;而当前读是读取最新的数据,会上锁,而且是悲观锁
    mvcc原理:
    mvcc是基于版本链read views来实现的
    如下图所示,这就是版本链,在InnoDB中,一张表必须包含两个字段,trx_id和roll_pointer,trx_id : 事务字段,当一个事务去操作某个行的数据时,会将自己的事务Id赋值给trx_id字段,roll_pointer : 回滚指针,当一个事务更新了一个字段的时候,并不会直接删除掉之前的字段,而是将该指针指向之前的字段存储到undo blog


    image.png
    然后还有一个概念叫readView,他相当于一个保存活跃事务id的集合,什么叫活跃事务id呢,就是在本事务执行的时候,还有哪些事务正在进行且还没有提交的事务,他的作用就是控制你能看到版本链中哪条数据,他主要包含了几个概念:

    • m_ids,哪些事务正在执行且还没有提交的事务id,就会保存在这里
    • min_trx_id:m_ids中最小值
    • max_trx_id:下一个要生成的事务id,因为事务id自增,那假设m_ids中最大的是60,则max为61
    • creator_trx_id,每开启一个事务都会生成一个 ReadView,而 creator_trx_id 就是这个开启的事务的 id。读事务时为0

    这样在访问某条记录时,只需要按照下边的步骤判断该记录在版本链中的某个版本(trx_id)是否可见
    1、trx_id2、trx_id>max_trx_id 这说明版本链里面都没有,不可以被当前事务访问
    3、m_ids列表中最小的事务id < trx_id < m_ids列表中最大的事务id 此处比如m_ids为[5,6,7,9,10]
    ①、若trx_id在m_ids中,比如是6,说明创建 ReadView 时生成该版本的事务还是活跃的,该版本不可以被访问。
    ②、若trx_id不在m_ids中,比如是8:说明创建 ReadView 时生成该版本的事务已经被提交,该版本可以被访问。
    一句话说:当trx_id在m_ids中,或者大于m_ids列表中最大的事务id的时候,这个版本就不能被访问。

    对于mvcc来说,因为trx_id