MVCC多版本并发控制

mvcc是基于快照读取的,提高数据库的读写性能,在读取数据的时候不需要加锁     

与之对应的是(当前读)加锁读取

mvcc作用于读已提交,可重复读 (undolog /版本链 /readview)


红色的是undolog日志,所有的记录(红色绿色)称为版本链

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进来就解决了幻读

你可能感兴趣的:(MVCC多版本并发控制)