MySQL的MVCC【学习笔记】

MVCC

事务的隔离级别分为四种,其中Read Committed和Repeatable Read隔离级别,部分实现就是通过MVCC(Multi-Version Concurrency Control,多版本并发控制)

版本链

  • 版本链是通过undo日志实现的,

  • 事务每次修改一次记录,都会生成一条undo日志,将记录被修改字段之前的值、trx_id、roll_pointer写到undo日志中,

  • 修改记录的同时将当前事务的id赋值给记录的trx_id,记录的roll_pointer指向刚生成的undo日志,这样子就构成了由roll_pointer字段串起来的链表,叫做版本链

  • 当然插入类型的undo日志没有roll_pointer,是版本链的尾节点,当然它对于MVCC机制也没有作用。

ReadView

ReadView(一致性视图)是实现Read Committed和Repeatable Read隔离级别的一个重要结构。上述两种隔离级别,要求事务不能读到另一个活跃事务没有没有提交的修改的记录。当检索到该条记录,就会通过ReadView中的属性对比记录和undo日志上的trx_id进行筛选,不符合条件则按照版本链不断向后遍历。

  • ReadView中包含以下属性:

    • m_ids:创建ReadView时,当前系统中活跃的读写事务的id列表。

    • min_trx_id:创建ReadView时,当前系统中活跃的读写事务的最小id,也就是m_ids的最小值。

    • max_trx_id:创建ReadView时,系统应该分配给下一个事务的id。不是m_ids的最大值。

    • creator_trx_id:创建ReadView的事务的id

  • 过滤可视记录

    • 针对 聚簇索引 记录 :访问记录的筛选过程,如果符合条件,则会返回结果,否则沿着版本链向后遍历,当前访问呢记录的trx_id如果

      • 小于min_trx_id, 则说明修改该记录的事务已经提交,符合要求。

      • 大于等于max_trx_id, 则说明修改该记录的事务在创建ReadView时还未出生,不符合要求

      • 被包含在m_ids, 则说明修改该记录的事务在创建ReadView时还未提交,不符合要求

      • 等于creator_id ,则说明这条记录就是自己改的,符合要求

      • 其他情况都符合要求。

    • 二级索引记录: 首先会根据记录所在页的的Page Header的PAGE_MAX_TRX_ID属性(表示修改该页的最大的事务id)进行粗略判断

      • 如果该值小于min_trx_id,则该页的所有记录都符合要求,可以被当前事务看见

      • 否则就会回表,通过聚簇索引记录来判断。

  • 隔离级别运用

    • Read Committed:每次读取数据前创建一个ReadView,可能会导致,同一个事务读取同一条记录两次,结果都不一样(期间有事务修改记录并提交了)

    • Repeatable Read:每个事务第一次读取记录前创建一个ReadView,该事务内读取所有数据都一致。

purge阶段

  • 每个事务生成的undo日志被划为一组,并且事务提交时,还会生成一个事务no分配给这组undo日志(事务no全局变量,每次分配后自增1)

  • 生成ReadView时会获取当前系统的事务no并且加一存储起来(这个不算分配)

  • 如果undo日志组的事务no小于当前系统事务no最小ReadView的事务no,则说明这组事务永远不会被访问到,就可以被回收了,如果这组undo日志中有逻辑删除记录的情况,则将这条记录彻底删除。

相关推荐
yuxb7310 分钟前
Docker学习笔记(二):镜像与容器管理
笔记·学习·docker
且行志悠43 分钟前
Mysql的使用
mysql
白鹭44 分钟前
MySQL源码部署(rhel7)
数据库·mysql
666和7771 小时前
Struts2 工作总结
java·数据库
还听珊瑚海吗1 小时前
SpringMVC(一)
数据库
星期天要睡觉3 小时前
MySQL 综合练习
数据库·mysql
Y4090013 小时前
数据库基础知识——聚合函数、分组查询
android·数据库
乖女子@@@3 小时前
React笔记_组件之间进行数据传递
javascript·笔记·react.js