Mysql InnoDB多版本并发控制MVCC( 三 )

1.版本链对于InnoDB存储引擎来说,其聚簇索引记录中包含两个隐藏列:

  • trx_id:一个事务每次对聚簇索引记录做出改动的时候,都会把该事务的事务id复制给此列
  • roll_point:每次对某条聚簇索引记录进行改动的时,都会把旧的版本写入到undo 日志中,此列相当于一个指针,指向修改前的信息

Mysql InnoDB多版本并发控制MVCC

文章插图
每次修改都会形成Undo 日志,所有版本的数据会通过roll_point串联成一个链表,称之为版本链,头节点是当前记录的最新值 。利用版本链控制多个并发事务访问相同记录时的行为称为MVCC多版本并发控制 。
其实在undo日志中,只记录被更新列的信息,而不是记录全部的信息,对于没有记录的列,会通过版本链找少一个版本中的对应列的信息,直到找到聚簇索引叶子节点中的内容2.Read View对于使用Read Uncommitted隔离级别的事务,可以读取到没提交的数据,那么直接读取最新的版本即可 。对于Serializable隔离级别,innodb直接通过加锁来访问记录 。对于read committed 和 repeatable read隔离级别的事务,都必须保证督导的数据是已经提交事务修改过的记录,那么如何判断版本链中的哪个版本的数据是当前事务可见的昵?
innodb 使用的Read View
2.1 read view 的结构
Mysql InnoDB多版本并发控制MVCC

文章插图
  • m_ids:在生成read view时,当前系统中活跃的读写事务id列表
  • min_trx_id:生成read view时,当前系统中活跃的读写事务中最西澳的事务id,也就是m_ids中的最小值
  • max_trx_id:生成read view时,系统应该分配给下一个事务的事务id值
  • creator_trx_id:生成该read view的事务的事务id
2.2 read view 判断某个版本当前事务释放可见的步骤
  1. 如果被访问版本的trx_id和creator_trx_id相同,意味着当前事务在访问自己修改的记录,自然可见
  2. 如果访问版本的trx_id属性值小于read view中的min_trx_id 表明此版本是生成read view之前已经提交的事务,那么自然可见
  3. 如果访问版本的trx_id,大于等于read view中的max_trx_id说明,当前版本数据是生成read view后开启事务产生的,那么自然不可见
  4. 如果访问版本的trx_id 介于min_trx_id和max_trx_id之间,需要判断trx_id是否位于m_ids列表中,如果在说明创建read view时生成该版本的事务还是活跃的,那么该版本,不可被访问,如果不在说明创建read view 时生成该版本的事务已经提交,可以被访问到
如果某个版本数据对当前事务不可见那么需要一直顺着版本链找上一个版本的数据,并通过上述步骤判断是否可见,直到找到可见的版本,如果一直找不到说明该条记录对当前事务不可见,查询结果将不包含该记录 。
2.3 Read Committed和 Repeatable Read的不同