当前位置:网站首页>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要大,但是它可能在当前事务开始之前就已经提交了。
边栏推荐
- 当panic或者die被执行时,或者发生未定义指令时,如何被回调到
- Implementing class target method exception using proxy object execution
- PZK学C语言之字符串函数(一)
- 一点点读懂regulator(二)
- typeScript-promise
- 文献阅读十——Detect Rumors on Twitter by Promoting Information Campaigns with Generative Adversarial Learn
- 小黑leetcode冲浪:94. 二叉树的中序遍历
- 建模师经验分享:模型学习方法
- 「津津乐道播客」#397 厂长来了:怎样用科技给法律赋能?
- 堪称奔驰“理财产品”,空间媲美宝马X5,采用了非常运动的外观
猜你喜欢

【字符串函数内功修炼】strlen + strstr + strtok + strerror(三)

未上市就“一举成名”,空间媲美途昂,安全、舒适一个不落

一、爬虫基本概念

社区分享|腾讯海外游戏基于JumpServer构建游戏安全运营能力

OpenCV:10特征检测

【字符串函数内功修炼】strncpy + strncat + strncmp(二)

Nuclei (2) Advanced - In-depth understanding of workflows, Matchers and Extractors
![[Cultivation of internal skills of string functions] strlen + strstr + strtok + strerror (3)](/img/96/946bbef52bd017ac6142c6b7485a86.png)
[Cultivation of internal skills of string functions] strlen + strstr + strtok + strerror (3)

招标公告 | 海纳百创公众号运维项目

线程三连鞭之“线程的状态”
随机推荐
2022年华数杯数学建模
Basic web in PLSQL
Bidding Announcement | Operation and Maintenance Project of Haina Baichuang Official Account
The market value of 360 has evaporated by 390 billion in four years. Can government and enterprise security save lives?
C5750X7R2E105K230KA(电容器)MSP430F5249IRGCR微控制器资料
OpenCV:10特征检测
一点点读懂Thremal(二)
3年,从3K涨薪到20k?真是麻雀啄了牛屁股 — 雀食牛逼呀
【字符串函数内功修炼】strlen + strstr + strtok + strerror(三)
注解@EnableAutoConfiguration的作用以及如何使用
【无标题】线程三连鞭之“线程池”
应用联合、体系化推进。集团型化工企业数字化转型路径
三、实战---爬取百度指定词条所对应的结果页面(一个简单的页面采集器)
Nuclei(二)进阶——深入理解workflows、Matchers和Extractors
4 - "PyTorch Deep Learning Practice" - Backpropagation
学生管理系统架构设计
uniapp horizontal tab (horizontal scrolling navigation bar) effect demo (organization)
基于内容的图像检索系统设计与实现--颜色信息--纹理信息--形状信息--PHASH--SHFT特征点的综合检测项目,包含简易版与完整版的源码及数据!
MySQL的安装与卸载
The Go Programming Language (Introduction)