Mysql MVCC

什么是MVCC

MVCC(Multi-Version Concurrency Control)多版本并发控制,是Mysql利用记录的版本链和ReadView,来控制 Innodb 并发事务访问相同记录的行为。

版本链

在InnoDB引擎中,每一张表中都会包含两个隐藏字段:trx_id、roll_pointer

  • trx_id:存储事务字段,当一个事务去操作某一行数据的时候,会将自己的事务ID赋值给trx_id字段;
  • roll_pointer:回滚指针,当一个事务更新一行数据的时候,并不会马上删除掉旧的数据记录,而是将更新之后数据的roll_pointer指向旧的数据记录,然后把旧的数据记录存储到undo log中,形成一个版本。随着更新的次数的增多所有的版本链成一条链,形成版本链。
    版本链如下图所示:
    版本链

ReadView

ReadView中存在4个比较重要的概念

  • m_ids:当ReadView创建时,记录当前系统中所有活跃事务ID列表,即未提交事务ID列表;
  • min_trx_id:当ReadView创建时,记录当前系统中活跃事务最小事务ID,即最早创建且未提交的事务ID;
  • max_trx_id:当ReadView创建时,记录当前系统中应该分配给下一个事务的ID,即预分配事务ID;
  • creator_trx_id:当ReadView创建时,记录当前事务ID,即创建ReadView的事务ID;

ReadView生成时机

  • 读已提交隔离级别:读取数据前都会生成一个ReadView(当前读),解决脏读;
  • 可重复读隔离级别:第一次读取数据前生成一个readview(快照读),解决不可重复读和幻读;

ReadView访问过程

undo log的数据中包含的trx_id是否符合如下条件:

  • trx_id == creator_trx_id,如果被访问版本的trx_id与ReadView中的creator_trx_id值相等,说明当前事务访问的是自己修改过的记录,所以该版本的记录可以被当前事务访问
  • trx_id < min_trx_id,如果被访问版本的trx_id的值小于ReadView中min_trx_id的值,说明生成该版本事务在当前事务生成ReadView之前已经提交,所以该版本的记录可以被当前事务访问
  • trx_id ≥ max_trx_id,如果被访问版本的trx_id的值大于等于ReadView中max_trx_id的值,说明生成该版本事务在当前事务生成ReadView之后才被开启,所以该版本的记录不可以被当前事务访问
  • min_tr_id ≤ trx_id < max_trx_id,如果被访问版本trx_id的值在ReadView的min_trx_id和max_trx_id之间,则需要判断被访问版本是否在ReadView的 m_ids中存在;
    如果在m_ids中存在,则说明创建readview时生成该版本的事务还是活跃的,该版本不可以被访问
    如果在m_ids中不存在,则说明创建readview时生成该版本的事务已经被提交,该版本可以被访问

ReadView示例:

ReadView

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 问题 多事务同时访问数据库中的相同数据时 读 + 读:多个事务对相同数据全部是读操作时,不会产生任何并发问题 读 ...
    Zeppelin421阅读 258评论 0 1
  • 前言 最近在学MySQL,决定记录一下,能写多少写多少,不定时更新,加油。 正文 分几个部分来吧,大致如下: 字符...
    sunyelw阅读 1,113评论 0 0
  • 1、前言 mvcc 即多版本并发控制,即通过多版本的方式实现读写数据的高并发,主要是通过多版本和锁来实现的。多版本...
    放开那个BUG阅读 185评论 0 1
  • 1. 多个undo log形成的链表 InnoDB存储引擎中,它的聚簇索引记录中都包含两个必要的隐藏列,分别是: ...
    小胖学编程阅读 1,461评论 0 13
  • 转自:https://mp.weixin.qq.com/s?__biz=MzA5MDA5Njk0NQ==&mid=...
    五指魅力阅读 237评论 0 0