MVCC 实现原理

💟这里是CS大白话专场,让枯燥的学习变得有趣!

💟没有对象不要怕,我们new一个出来,每天对ta说不尽情话!

💟好记性不如烂键盘,自己总结不如收藏别人!

💌 在讲解 MVCC 之前先来看一下 MySQL 中事务的四种隔离级别

🍠 读未提交:一个事务可以读到另一个事务未提交的数据。

🍠 读已提交(RC):Oracle 默认,如果一个事务还没有提交,其他事务不能读到该数据。

🍠 可重复读(RR):MySQL 默认,事务A在读到一条数据之后,事务B对该数据进行了修改并提交,事务A再读该数据还是原来的内容,这就需要 MVCC 来实现。

🍠 可串行化:读写加锁。

💌 快照读(一致性读):使用快照信息显示基于某个时间点的查询结果,而不考虑与此同时运行的其它事务所执行的修改。(select * from XXX)

🍠 在 RC 中,每次读取都会重新生成一个快照,总是读取行的最新版本,因此事务中每次 select 也可以看到其它已提交事务所做的修改。

🍠 在 RR 中,快照会在事务中第一次查询语句执行时生成,只有在本事务中对数据进行更改才会更新快照,但会产生幻读。如果在本事务中已经执行了一次 select,其它事务执行了更改数据的操作并已提交,在本事务再次 select 时看不到其它事务所做的更改。

P.S. 当前读:insert、update、delete、select...for update 等。

 💌 脏读、不可重复读、幻读的区别:

🍠 脏读:读取了未提交事务的数据(读取阶段,事务进行了回滚等)。

🍠 不可重复读:同一个事务先后两次查询的数据不一致,可能两次查询之间另一个事务执行了更新的操作并已提交。

🍠 幻读:在同一个事务当中先后两次查询结果的总数不一致(插入阶段)。

💌 接下来我们就仔细研究下 MVCC 如何实现 RR 的:

我们知道 MySQL 的三大日志:undo log、redo log、bin log,涉及到回滚的就是 undo log,主要保存了数据的基本信息:

此外,还包含两个隐藏字段 trx_id roll_pointer

🍠 trx_id :当前这个事务的 id,递增。

🍠 roll_pointer:一个指针,指向上一个版本的 undo log,形成版本链。

💌 基于 undo log 版本链实现 ReadView 机制,它是快照读提取数据的依据:

  • m_ids:当前活跃的事务 id 集合。
  • min_trx_id:m_ids 里最小事务 id。
  • max_trx_id:下一个要生成的事务 id。
  • creator_trx_id:ReadView 创建者的事务 id。

 根据 ReadView 在版本链中提取满足条件的数据:

🍠 判断当前事务 trx_id 是否等于 creator_trx_id,等于则可以访问(update 之后立即 select)。

🍠 判断 trx_id 是否小于 min_trx_id,小于则已提交,可访问。

🍠 判断 trx_id 是否大于 max_trx_id,大于则是当前 ReadView 生成后产生的,不可访问。

🍠 在二者之间,若不在 m_ids 中则已提交,可访问。

 💌 由此 MVCC 可实现可重复读~~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值