MVCC 版本控制
事务的隔离级别
- 读未提交 ->会有脏读
- 读已提交->会有不可重复读(在一个事务内查询到不同的结果)
- 可重复读->会有幻读(事务 A 根据条件查询得到了 N 条数据,但此时事务 B 删除或者增加了 M 条符合事务 A 查询条件的数据,这样当事务 A 再次进行查询的时候真实的数据集已经发生了变化,但是A却查询不出来这种变化,因此产生了幻读。)
- 串行化
读未提交没有用到MVCC 串行化用了表锁是并发控制最强但是效率最低的
Mvcc组成
- undo log版本链
- 隐藏列
- readView(快照)
隐藏列
- DB_TRX_ID – 记录插入或更新该行的最后一个事务的事务 ID
- DB_ROLL_PTR – 指向改行对应的 undo log 的指针,最新的历史数据
- DB_ROW_ID – 单调递增的行 ID,他就是 AUTO_INCREMENT 的主键 ID
undo log版本链
存储该行的历史数据
ReadView
读已提交每次查询都会创建一个readview
当前事务id
最小事务id(未提交的)
最大事务id(还没开始)
从版本链里面找符合的那一条记录,从最新的版本链开始比较链中的事务id和readView里面的事务集合比较。
读已提交和可重复读的区别是
读已提交是每次查询时候创建一个快照,可重复读是第一次创建readview
可见性算法
1,如果数据行的事务id小于Read View最小事务id,则该行数据对当前事务可见。
2,如果数据行的事务id>=Read View中记录的当前出现的最大事务id+1,则跳转步骤5执行。
3,事务id列表为空,则该行数据可见。
4,如果数据行的事务id大于等于Read View最小事务id,并且
小于Read View中记录的当前出现的最大事务id+1。
判断若存在于活跃事务id列表,则不可见。
判断若不存在于活跃事务id列表,则可见。
5,根据回滚指针在undo log中取出一条记录,从1步骤重复判断,直到找到满足条件的记录,否则返回空。
可见性算法参考链接:https://blog.csdn.net/weixin_43073775/article/details/121384273