(1)MVCC原理实现思路:
通过undo_log多版本链条,加上开启事务时产生的readView(不同隔离级别有不同产生策略),然后再有一个查询的时候,根据readView进行判断的机制,来决定读取哪个版本的数据。实现了多事务并发执行,保证只能读开启事务前提交的数据和当前事务修改的数据,其他情况都不会读到。解决的是读一致性问题
innodb为每行记录实现了三个隐藏字段,用于形成undo_log链
DB_TRX_ID事务id:插入或更新行的最后一个事务的事务ID(创建版本号),自动递增
DB_ROLL_PTR:指向undo_log的回滚指针(删除版本号,记录的也是事务id),
DB_ROW_ID(和MVCC无关,但也属于隐藏字段):行标识
多个事务串行执行的时候,每个人修改了一行数据,都会更新隐藏字段trx_id和roll_pointer,同时之前的多个数据对应的undo_log,会通过roll_pointer指针串联起来,形成一个版本链。
(2)ReedView(读视图)结构:
m_ids{},所有活跃在mysql里执行还未提交的事务id。
min_trx_id,m_ids中最小值。
max_trx_id,不在m_ids内,mysql下一个要生成的事务id。
creator_trx_id,生成readView的事务id。
(3)Read View的判断规则:
1、从数据的最新版本开始判断(undo log)
2、数据版本的trx_id=creator_trx_id,本事务修改,可以访问
3、数据版本的trx_id<min_trx_id(未提交事务的最小id),说明这个版本在生成ReadView已经提交,可以访问
4、数据版本的trx_id>max_trx_id(下一个事务ID),这个版本是生成ReadView之后才开启的事务建立的,不能访问
5、数据版本的trx_id在min_trx_id和max_trx_id之间,则在m_ids中。表明是同时间段开启的事务,不可以访问。
6、如果当前版本不可见,通过roll_pointer就找undo log链中的下一个版本
(4)Mysql中innodb的mvcc实现
RR级别下,事务中的第一个SELECT请求即创建readView;(每个事务都会建立各自的ReadView)
RC级别下,事务中每次SELECT请求都会重新创建readView;