1、什么作用
在Innodb存储引擎中的实现主要改进了数据库并发能力,从而更好地处理读/写冲突,同时实现无锁定、无阻塞的读/写操作
2. 解决什么问题
MVCC解决脏读,不能重复读取。 MVCC使用快照读取解决了部分幻读问题,但由于是修正时仍在使用的当前读取,因此存在幻读问题。 幻引线问题最终使用间隙锁定解决
3. 使用范围
MVCC仅适用于隔离级别“REPEATABLE READ”、“READ COMMITTED”
4、两个概念
MVCC主要用于快照读取查询
5.MVCC实现原理
MVCC是通过使用两个隐式字段、还原日志和读视图建立版本之间的连接和版本比较来实现的
隐身字段
DB_ROW_ID :集群索引不存在。
DB_TRX_ID :创建记录上次修改此记录的事务处理标识。
DB_ROLL_PTR :指向此记录的上一个版本的回滚指针。
undo log
插入时发生的还原日志、更新
删除时发生的还原日志
read-view
由执行查询时尚未提交的所有事务ID的数组和已经创建的最大事务ID组成。
版本比较规则
trx_id min_id :由于事务已提交,因此将显示数据。 trx_id max_id表示此版本将由将来开始的事务生成,并且不会显示。 min_id=trx_id=max_id存在两种情况。 a ) row的trx_id位于数组中,表示此版本是由尚未提交的事务生成的,是不可见的,但您当前的事务是可见的。 b ) row的trx_id不在数组中,表示已提交的事务生成了版本。6. 示例1
表中的基础数据为name='kaka '
还原日志生成的版本链
readview [ 100,101 ],102基于read-view规则,其中事务ID100为min_id,且事务ID102为max_id。 由于事务ID102不在数组中,因此此版本表示是由已提交的事务生成的
7.示例2
select的第二次查询结果
版本链
读视图即[ 100,101 ],102
当前数据的事务ID为100
根据规则落入名为min_id=trx_id=max_id的区间
它还表示当前行的事务ID100位于读视图数组中,此时的事务必须提交才能显示
继续在版本链下寻找。 此时,找到的事务ID仍为100,与上述过程一致
搜索版本链时,您会发现事务ID为102
102是read-view的max_id,同样落入min_id=trx_id=max_id区间,但与以前不同,事务102不在数组中,而是此版本的事务
最后回来的是牛
8.示例3
以可重复读取级别生成的读视图是基于同一事务的初始快照读取生成的
版本链
读视图仍然是[ 100,101 ],102
首先,对事务101的版本链的比较显示,事务101和事务100落入min_id=trx_id=max_id这一区间,并且还位于数组中,因此数据不可见。
如果你继续在版本链中找,你会去交易102。 这是最大的事务ID,不在数组中,所以可以看到。
然后最终回到了牛虻。
9.示例4
与情况3中的图不同,添加了查询语句。 如果这两个语句的执行时间一致,会返回相同的结果吗?
版本链
首先,这里的读视图发生了变化。 此时的read-view为[101],102。
如果将当前事务ID101与版本链规则进行比较,则会将其放到min_id=trx_id=max_id中,并且数组中不显示任何数据。
然后进入版本链,找到下一个数据的事务ID。 还是101。 和以前的数据一致。
下一个是事务ID100。
事务ID100为trx_idmin_id,表示此版本由已提交的事务生成,并且由于事务已提交,因此将显示数据。
所以最终会回到牛虻2。
参考:无知! 她突然问我MVCC的实现原理