mvcc是基于快照读取的,提高数据库的读写性能,在读取数据的时候不需要加锁
与之对应的是(当前读)加锁读取
mvcc作用于读已提交,可重复读 (undolog /版本链 /readview)
UNDOLOG就是存储历史变更数据,回滚指针指向上一个历史版本
readView:就是一个快照 作用于:让你知道你在版本链中你用那条记录,就是去版本链中去select找到具体用哪一个版本
参数:m_ids:生成readview,活跃的事务id列表即 > 没有commit的事务id (1.2.3)
min_rtx_id:表明是m_ids中最小的id 》指的就是1
max_trx_id:表明ReadView系统中应该分配给下一个事物的id 指的是4
creator_trx_id:生成该ReadView这个事务的事务id == trx_id
具体选用哪一个是要ReadView和trx_ID共同作用于查看那个版本。trx_ID是每条记录的事务id
选用方法:
trx_ID == creatorID 可以访问
trx_ID < MIN_TX_ID 可以访问,比没有提交的事务都早。那表明是都已经提交了的可以访问
rtx_ID > MAX_TX_ID 不可以访问,肯定没有提交
min_trx_id < rtx_id< mac_trx_id :如果trx_id在m_ids中是不可以访问这个版本的,反之可以
举例:如果m_ids是(1.3.4)当trx_id是2的话就可以访问
读已提交是每次select都会生成readview,所以会出现第一次select,事务没有提交生成的readview读取不到该数据,但是第二次select 事务已提交,生成的readview就会出现能读到,这就出现不可重读的问题。
如何实现不可重复读?
生成readview是以事务为单位的(读已提交是以select为单位的)。所以一个事务中有多个select的话还是同一个readview(一个事务才会生成一个readview)
幻读 == insert 解决方式:间隙锁
比如我select >2 然后其他事务insert 。 select出来的数据就多了,幻读的实现就是把>2的数据全部都上了锁,所以不会insert进来就解决了幻读