什么是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示例:
网友评论