MVCC
mvcc是多版本并发控制。维护一个数据的多个版本,使读写没有冲突
隐式字段
DB_TRX_ID:最近修改事务id,记录插入这条记录或最后一次修改该记录的事务id
DB_ROLL_PTR:回滚指针,指向这条记录的上一个版本,用于配合undo log,指向上一个版本
DB_ROW_ID:隐藏主键,如果表结构没有指定主键,将会生产隐藏主键
undo log
回滚日志,再insert delete update的时候产生的便于数据回滚的日志。
当insert的时候,产生的undo log 日志只在回滚时需要,在事务提交后,可被立即删除。
当update delete 的时候,产生的undo log日志不仅在回滚时需要,mvcc版本访问也需要,不会被立即删除
undo log的版本链
哪个事务修改了数据就记录最近提交的那个,头部是最新的旧纪录,尾部是最早的旧记录
readview
readview(读视图):是快照读sql执行时mvcc提取事务的依据,记录并维护当前活跃的事务(未提交)id。
当前读
读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。
第二次读到的是事务B提交的数据
快照读
简单的select(不加锁)就是快照读,快照读,读取的是记录数据的可见版本,有可能是历史数据,不加锁,是非阻塞读。
read committed(读已提交):每次select都生成一个快照读
repeatable read(读未提交):开启事务后第一个select语句才是快照读。
readview核心字段
事务5第一次查询的时候,此时事务2已经提交了,所以m_ids就是事务3、4、5
min_trx_id就是3
max_trx_id就是5+1=6
creator_trx_id就是事务5
版本链数据访问规则
当前事务id就是创建者的事务id,说明这个数据是当前事务更改的
当前事务id小于于最小事务id,说明数据已经提交了可以访问
当前事务id大于最大事务id,说明当前事务时在readview生产之后开启的
当前事务大于等于最小事务id,并且小于等于最大事务id或者不在版本链中,说明数据已经提交可以访问
在RC(读已提交)隔离级别下,在事务每执行一次快照读时生成一个readview
第一次查询,事务2已经提交,事务3、4还未提交
第二次查询,事务3已经提交,事务4还未提交
第一个read view得到事务2提交的版本
第二个read view得到事务3提交的版本
在RR(可重复读)隔离级别下,仅在事务第一次执行快照读时生成一个readview,后续服用改readview
都只能查到事务2提交的数据
总结
都只能查到事务2提交的数据