当前位置:网站首页>MVCC是什么
MVCC是什么
2022-08-04 23:36:00 【大佬,菜菜,带带】
什么是MVCC
MVCC是一种同一主键的行记录保存多个版本的机制,实现在并发读-写情况下不加锁读,同时解决了脏读、不可重复读。
MVCC如何实现
MVCC通过版本链实现。
什么是版本链
版本链就是一个链表,每个节点上保存的是行记录的一个版本,其中头节点是行记录的最新版本,头节点后的第一个节点是行记录最新版本的上一个版本,头节点后的第二个节点是行记录最新版本的上上一个版本,以此类推。
版本链如何实现
版本链又是如何实现的呢?其实InnoDB的行记录中除了我们自定义的列之外,还有三个隐藏列,分别是trx_id,roll_pointer,row_id:
trx_id:事务id,表示这条行记录是哪个事务生成/修改的
roll_pointer:指向undo log中这条行记录的上一个版本
row_id:当用户没有指定主键且没有非null的唯一列时,使用
row_id作为主键
通过roll_pointer就形成了版本链,有了版本链就可以查询到行记录的每个版本。
如何解决脏读、不可重复读问题
假如是我们来解决脏读和不可重复读问题,在有版本链的情况下应该如何解决呢?(一条行记录,创建/修改它的事务已经提交了,下面将简称已提交行记录,反之为未提交行记录)
脏读是指读到了未提交行记录,我们很容易想到:版本链上那么多版本,我们读一条已提交行记录不就行了?
不可重复读是指在一个事务中两次读取一个行记录,但是获取到的数据不一致,原因是在两次读取的间隔中有其他事务修改了这个行记录并提交了,那如果在当前事务提交之前无论读多少次都读取版本链上的同一个
已提交行记录,这样的话读到的数据不就一样了?那么哪个版本才能让我们在当前事务提交之前的各个时期都能读取到呢?那就是当前事务开始时的已提交行记录。至于当前事务开始时的未提交行记录甚至是当前事务开始之后才生成的未提交/已提交行记录都是不行的。
提炼一下解决脏读和不可重复读需要的条件:
解决脏读是需要读一个
已提交行记录;解决不可重复读是需要读取
当前事务开始之前的已提交行记录。
也就是说我们只要读取当前事务开始时的已提交行记录,并且当前事务没有提交之前每次都读同一个版本,那就可以解决脏读和不可重复读问题。
非礼勿视——ReadView
大概的思路就是这样,但是我们怎么知道我们读取的行记录是不是在当前事务开始时就已经提交了呢?这时候就轮到行记录隐藏字段trx_id上场了。
可能大家会想到,喔!我懂了!直接判断行记录的事务id和当前事务id的大小就行了,小于当前事务id的就是在当前事务开始时就已经提交的行记录;大于当前事务id的就是在当前事务开始之后才提交的行记录。
需要注意的是,事务id是事务对行记录创建/修改时分配的,而不是事务提交的时候分配的。一个事务的事务id小,但是因为操作比较多,可能比其他事务id大的事务提交的时间还要晚。所以只凭行记录事务id和当前事务id是无法判断生成这条行记录的事务是否是在当前事务之前提交的。
那么到底是如何实现判断的呢?InnoDB设计了一个ReadView,这个ReadView很简单,就4个部分,分别是:
m_ids:当前事务生成ReadView时活跃事务的列表(简称活跃列表)min_trx_id:活跃列表中最小的事务id(最小事务id)max_trx_id:生成ReadView时下一个要分配的事务id(最大事务id)creator_trx_id:生成ReadView的事务id(当前事务id)
有了ReadView我们就可以知道我们读取的这个行记录是不是在当前事务开始时就已经提交了:
首先这个版本的行记录事务id一定不能大于或者等于最大事务id,如果不满足,说明生成这个行记录的事务是在当前事务开始之后才生成的,肯定不行。
如果这个版本的行记录事务id比最小事务id要小,说明在当前事务生成时它已经提交了,可以读。
如果这个版本的行记录事务id和当前事务id一样,说明这个记录是当前事务修改/生成的,可以读。
如果这个版本的事务id比最小事务id要大,但是又比最大事务id要小,那就难办了,我们得看它是否在活跃事务列表中:
如果在,那说明这个行记录在当前事务开始时还没有提交,不行;
如果不在,那说明这个行记录在当前事务开始时提交了,可以读。
为什么需要活跃列表:一些事务的事务id比最小事务id要大,但是它可能在当前事务开始之前就已经提交了。
边栏推荐
- The market value of 360 has evaporated by 390 billion in four years. Can government and enterprise security save lives?
- PZK学C语言之字符串函数(一)
- 基于内容的图像检索系统设计与实现--颜色信息--纹理信息--形状信息--PHASH--SHFT特征点的综合检测项目,包含简易版与完整版的源码及数据!
- 隐私计算综述
- 测试技术:关于上下文驱动测试的总结
- 加解密在线工具和进制转化在线工具
- uniapp horizontal tab (horizontal scrolling navigation bar) effect demo (organization)
- The Controller layer code is written like this, concise and elegant!
- 资深游戏建模师告知新手,游戏场景建模师必备软件有哪些?
- 怎么将自己新文章自动推送给自己的粉丝(巨简单,学不会来打我)
猜你喜欢

社区分享|腾讯海外游戏基于JumpServer构建游戏安全运营能力
![[Happy Qixi Festival] How does Nacos realize the service registration function?](/img/df/5793145da45bc80d227b0babfac914.png)
[Happy Qixi Festival] How does Nacos realize the service registration function?

【七夕情人节特效】-- canvas实现满屏爱心

App测试和Web测试的区别

C5750X7R2E105K230KA(电容器)MSP430F5249IRGCR微控制器资料

PID Controller Improvement Notes No. 7: Improve the anti-overshoot setting of the PID controller

The market value of 360 has evaporated by 390 billion in four years. Can government and enterprise security save lives?
情人节---快来学习一下程序员的专属浪漫吧

4 - "PyTorch Deep Learning Practice" - Backpropagation

uniapp horizontal tab (horizontal scrolling navigation bar) effect demo (organization)
随机推荐
web3.js
I was rejected by the leader for a salary increase, and my anger rose by 9.5K after switching jobs. This is my mental journey
Community Sharing|Tencent Overseas Games builds game security operation capabilities based on JumpServer
【七夕情人节特效】-- canvas实现满屏爱心
什么是次世代建模(附学习资料)
Service Mesh落地路径
Nuclei(二)进阶——深入理解workflows、Matchers和Extractors
The Controller layer code is written like this, concise and elegant!
功耗控制之DVFS介绍
Laravel 实现redis分布式锁
Ab3d.PowerToys and Ab3d.DXEngine Crack
入门3D游戏建模师知识必备
当panic或者die被执行时,或者发生未定义指令时,如何被回调到
typeScript-promise
[Cultivation of internal skills of memory operation functions] memcpy + memmove + memcmp + memset (4)
Bidding Announcement | Operation and Maintenance Project of Haina Baichuang Official Account
请你说一下final关键字以及static关键字
uniapp sharing function - share to friends group chat circle of friends effect (sorting)
对写作的一些感悟
【软件测试】常用ADB命令