橘子学MYSQL之MVCC(中)

本文详细探讨了MVCC(多版本并发控制)在RC(读已提交)隔离级别下的工作原理。在RC隔离级别下,每次读取都会生成一个新的一致性视图,通过限制读取的版本范围来实现读已提交。文章通过实例展示了事务在RC隔离级别下的查询过程,解释了为何在RC级别可能会出现不可重复读的现象,并分析了这种设计的优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本篇主要以实际的操作来看一下MVCC在RC和RR这两个隔离级别下面的一个表现。

RC隔离级别

1、一致性视图生成时机

RC级别下面的一致性视图是在每次读取的时候都会生成一个。这里说一下,虽然读取生成一致性视图,但是其事务id也就是trx_id是在你第一次做增删改处理才赋予一个值的,普通查询就是0,前面说过了。

2、版本控制验证

1、开启两个事务,把隔离级别设置为RC
在这里插入图片描述
此时数据库里面只有一个初始数据。
在这里插入图片描述
根据上篇的描述我们在第一个事务里面做一些操作,以此来生成版本链。在第二个事务里面对别的表做更新操作,让他生成事务id。
在这里插入图片描述
此时做完了修改,我们来看看事务id。
在这里插入图片描述
OK,此时事务id都被分配,事务1的trx_id是2795535,事务2的trx_id是2795537。好像不是递增的,可能和生成规则那里有关,涉及表空间那里,这个此处不深究。
在这里插入图片描述
此时开启第三个事务,隔离级别依然是RC。
在这里插入图片描述
这个事务没有做操作,所以他的trx_id就是0。
我们来查询一下这个id=1的数据,然后看看mvcc的表现。注意此时事务1,2都还没有提交。
在这里插入图片描述
因为事务三只做了查询,此时他的事务号就是0,在此时他开启事务做查询那一刻生成一致性视图,此时这个一致性视图的属性值分别是:
1、m_ids:[2795535,2795537]
2、min_trx_id:2795535
3、max_trx_id:2795538
4、creator_trx_id:0
此时他开始从id=1的这个数据此时的版本链开始遍历,我再把版本链贴一下。
在这里插入图片描述
第一步:版本链上的最新数据是内马尔,其事务号是2795537,在m_ids当前活跃集合里面,说明你开启查询那一刻,内马尔这个数据是活跃的事务,还没提交呢。没提交的东西在RC下不能被看到,所以这个版本不可见。
第二步:继续顺着版本链往下走到苏牙这个版本,事务号是2795535,也在m_ids下面,所以不可见。
第三步:继续顺着版本链往下走到了梅西这个版本,看到了事务号是95,最开始插入时候的事务,此时他不在m_ids里面,并且小于min_trx_id,说明你开启事务查询的时候,这个事务的数据已经提交了,读已提交可以读到数据,所以结果就是梅西。

3、设计分析

这就是他的查询过程,我们分析一下设计。这里存在的设计就是他是每次读取都会生成一个视图,在RC隔离级别下,这种方式是保证了读已提交,他通过限制你读取的范围,保证了你读取到的都是不活跃的事务,也就是提交的事务,解决了RU下的读未提交的问题。
但是因为每次都会生成新的视图,可能在一个事务中读到两次数据,两次之间有的活跃的事务提交了,导致你读到的数据不一致,出现不可重复读。这就是RC规则的实现。
OK,具体其他场景就可以按着这个路子分析了,这里不多说了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值