浅谈mysql mvcc

目录

前言

mvcc 是如何工作的?

数据的更新


前言

mvcc 与一个事物的隔离级别有关,未提交读永远读的是当前值,串行化是通过加锁实现,这两种隔离级别都与mvcc 没有任何关系。只要一提到mvcc应该想到的是读提交以及可重复读,大家有没有想过都是mvcc,为啥这两个隔离级别所呈现的结果有些不一样呢?难道会有两套mvcc 吗?当然不是,对于这个问题,稍后我会说明的。

我先举一个简单的例子。下面是一个表的初始化语句。

CREATE TABLE `t` (`id` int(11) NOT NULL,`k` int(11) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB;
insert into t(id, k) values(1,1),(2,2);
sessionAsessionBsessionA

在此我说明下,sessionA 是在同一个事物下,事务的隔离级别是可重复读,sessionB 是另外一个事物。是不是感觉很神奇,sessionB 对数据操作成功了,sessionA 没有收到任何干扰。

是不是感觉sessionA 在begin 的时候像相机一样为数据表拍了一张快照。而这个快照也是我们常说的一致性读视图即 consistent read view。它的作用是事务执行期间用来定义“我能看到什么数据”。

mvcc 是如何工作的?

在上面我们讲到了快照,大家是不是感觉我在扯淡,100G的库,你也去快照,你要拷贝100G的数据,别人不会拍死你,放心好了拍不死我的。

其实在启动一个事物的时候,并不需要拷贝数据,只需要在事物系统申请一个事物id 叫做 transaction id,这个id 是原子递增的,意味着一个数据库不会出现两个相同的事物id

每行数据也都是有多个版本的。每次事务更新数据的时候,都会生成一个新的数据版本,并且把 transaction id 赋值给这个数据版本的事务 ID,记为 row trx_id。同时,旧的数据版本要保留在undo log 里,并且在新的数据版本中,能够有信息可以直接拿到它。

可以这么说,数据表中的一行记录,其实可能有多个版本,每个版本都有自己的row trx_id。

按照可重复读的定义,一个事物启动的时候,能够看到所有已经提交的事物结果。但是之后其他事物的更新,它却看不见。

它是怎么找到自己能够看见的数据呢,会拿到每个版本的 row trx_id,如果是在我启动以后生成的row trx_id,继续往前找,直到找到自己提交的或者是本事物启动之前提交的。

为了方便比较,在实现上,innodb 为每个事物构建一个数组,用来保存这个事物启动瞬间,当前正在“活跃” 的所有事物ID。“活跃” 指的是,启动了还没有提交的。

数组里面事务 ID 的最小值记为低水位,当前系统里面已经创建过的事务 ID 的最大值加 1 记为高水位。

这个视图数组和高水位,就组成了当前事物的一致性视图。

而数据版本的可见性规则,就是基于数据的 row trx_id 和这个一致性视图的对比结果得到的。

就拿一致性视图而言,规则是这样的:

  1. 如果 row trx_id 小于这个视图数组的最小值,说明已经提交了,那么这个数据就是可见的。

  2. 如果 row trx_id 大于这个高水位,肯定不可见呀,说明事物还没有创建

  3. 如果 row trx_id 在 最小值和高水位之间又有两种情况:row trx_id刚好就在视图数组是说明还没有提交也不可见,不在视图数组里说明提交了就可见。

所以你现在知道了,InnoDB 利用了“所有数据都有多个版本”的这个特性,实现了“秒级创建快照”的能力。

所以一个数据版本,对于一个事务视图来说,除了自己更新总是可见以外,有三种情况:

  1. 版本未提交,不可见;

  2. 版本已提交,但是是在视图创建后提交的,不可见;

  3. 版本已提交,而且是在视图创建前提交的,可见。

下面我在在回到最开始提到的那个问题,读提交为啥又有些不一样呢,让我们在回顾一下什么是读提交,在事务中,我们可以读到已经提交的事物,只要在我事物中的任何一个时刻提交的,我都可以读到。上面的规则对于读提交同样适用,只不过读提交是在每个select语句都会去申请一个transaction id作为它的row trx_id,同时也会构建一个新的事物数组。

数据的更新

上面我们讲到了mvcc,其实只是在select 用到,如果是update ,或者下面的语句。

select k from t where id=1 lock in share mode;
​
select k from t where id=1 for update;

大家都知道更新数据都是先读后写的,而这个读,只能读当前的值,称为“当前读”(current read)。

或者是select 语句加上了 share mode 共享锁 或者 for update 拍他锁,这些都只能用到当前读,与mvcc 没有一点关系了。

所以这些语句执行后,会对行进行加锁,update 加行锁,share mode 加的是读锁, for update 加的是写锁。读到最新的数据

而这些锁都是两阶段锁,从加锁开始到事物结束。这么做对于数据库来说也是无赖之举,为了保证数据的一致性,是数据的同步技术。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/712057.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue+element ui上传图片到七牛云服务器

本来打算做一个全部都是前端完成的资源上传到七牛云的demo,但是需要获取token,经历了九九八十一难,最终还是选择放弃,token从后端获取(springboot)。如果你们有前端直接能解决的麻烦记得私我哦!…

『Linux从入门到精通』第 ㉒ 期 - 动静态库

文章目录 💐专栏导读💐文章导读🐧什么是库?🐧为什么要有库?🐧写一个自己的库🐦方法一🐦方法二 静态库🐦标准化🐦方法三 动态库🐦配置动…

python中自定义报错

class MyError(Exception):def __init__(self,num):#录入的数Exception.__init__(self)self.numnumdef __str__(self):return 这是我定义的第%d个异常 %(self.num)使用 try:raise MyError(4) except MyError as e:print(e)raise 其作用是指定抛出的异常名称,以及异常…

数据结构题目①——数组

前言 本篇文章为博主进行代码随想录——数组练习后的总结会涉及到每一道题目的详细的思路整理,以及本人的易错点,希望对大家有所帮助 数组介绍: 数组在C语言中就已经有所涉及,它是一个最基础的数据结构,而在数据结构中…

three 层级模型

group.remove(mesh1,mesh2);Vector3与模型位置、缩放属性 Group层级模型(树结构) 创建了两个网格模型mesh1、mesh2,通过THREE.Group类创建一个组对象group,然后通过add方法把网格模型mesh1、mesh2作为设置为组对象group的子对象,然后在通过执行scene.a…

jenkins部署maven项目

流程: jenkins从代码仓库读取代码,将代码文件放入jenkins的工作空间,将jenkins工作空间的代码进行打包,将jar包远程发送给服务器。 一:所需插件二:Tools 三:System: 配置ssh连接的…

python63-Python的循环之循环使用else

Python的循环都可以定义else代码块&#xff0c;当循环条件为False 时&#xff0c;程序会执行else代码块。如下代码示范了为while循环定义else代码块。 # !/usr/bin/env python# -*- coding: utf-8 -*-# Time : 2024/01# Author : Laopicount_i 0while count_i < 5:print(c…

Java集合相关面试题(2024大厂高频面试题系列)

1、说一说Java提供的常见集合&#xff1f;&#xff08;画一下集合结构图&#xff09; 在java中提供了量大类的集合框架&#xff0c;主要分为两类&#xff1a; 第一个是Collection 属于单列集合&#xff0c;第二个是Map 属于双列集合 在Collection中有两个子接口List和Set。…

【力扣hot100】刷题笔记Day14

前言 又是新的一周&#xff0c;快乐的周一&#xff0c;快乐地刷题&#xff0c;今天把链表搞完再干活&#xff01; 114. 二叉树展开为链表 - 力扣&#xff08;LeetCode&#xff09; 前序遍历 class Solution:def flatten(self, root: Optional[TreeNode]) -> None:if not r…

【IC前端虚拟项目】inst_buffer子模块DS与RTL编码

【IC前端虚拟项目】数据搬运指令处理模块前端实现虚拟项目说明-CSDN博客 需要说明一下的是,在我所提供的文档体系里,并没有模块的DS文档哈,因为实际项目里我也不怎么写DS毕竟不是每个公司都和HISI一样对文档要求这么严格的。不过作为一个培训的虚拟项目,还是建议在时间充裕…

Docker技术概论(3):Docker 中的基本概念

Docker技术概论&#xff08;3&#xff09; Docker 中的基本概念 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://…

基于java+springboot女士电商平台系统源码+文档设计

基于javaspringboot女士电商平台系统源码文档设计 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末获取源…

C语言----动态内存管理(2)

1.这里总结动态内存管理里面的错误 &#xff08;1&#xff09;使用malloc开辟空间以后直接赋值 这个就是malloc开辟失败返回空指针&#xff0c;直接给空指针赋值就是错误的&#xff0c; tip1:使用malloc开辟空间以后一定要判断是否为空 &#xff08;2&#xff09; 越界访问…

Python批量提取文件夹中图片的名称及路径到指定的.txt文件中

目录 一、代码二、提取效果 一、代码 import os# 定义要保存的文件名 file_name "TestImage/Image_Visible_Gray.txt"# 读取文件夹路径 folder_path "TestImage/Image_Visible_Gray"# 遍历文件夹中的所有文件 with open(file_name, "w") as f…

可移植性(兼容性)测试指南

可移植性是指应用程序能够安装到不同的环境中&#xff0c;在不同的环境中使用&#xff0c;甚至可以移动到不同的环境中。当然&#xff0c;前两者对所有系统都很重要。就PC软件而言&#xff0c;鉴于操作系统、共存和互操作应用程序、硬件、带宽可用性等方面的快速变化&#xff0…

Stable Diffusion中的Clip模型

基础介绍 Stable Diffusion 是一个文本到图像的生成模型&#xff0c;它能够根据用户输入的文本提示&#xff08;prompt&#xff09;生成相应的图像。在这个模型中&#xff0c;CLIP&#xff08;Contrastive Language-Image Pre-training&#xff09;模型扮演了一个关键的角色&a…

Biotin aniline,生物素苯胺,用于研究蛋白质结构和功能

您好&#xff0c;欢迎来到新研之家 文章关键词&#xff1a;769933-15-5&#xff0c;Biotin aniline&#xff0c;生物素苯胺&#xff0c;Biotin-aniline&#xff0c;生物素-苯胺 一、基本信息 【产品简介】&#xff1a;Biotin aniline is composed of three parts: biotin, w…

个人或者小团队选择C语言还是c++?

个人或者小团队选择C语言还是c? 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「C语言的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff0…

使用Python语言实现一个基于动态数组的序列队列

一、动态数组的实现 首先&#xff0c;我们需要创建一个DynamicArray类&#xff0c;该类将管理我们的动态数组。 动态数组能够动态地调整其大小&#xff0c;以容纳更多的元素。 目录 一、动态数组的实现 代码示例&#xff1a; 二、序列队列的实现 接下来&#xff0c;我…

代码随想录算法训练营第五天

● 自己看到题目的第一想法 242. 有效的字母异位词 方法&#xff1a; 方法一&#xff1a; 暴力法 1. 分别对s, t排序 2. 遍历s与t 判断s[i]!t[i] 返回 false 否则 返回true思路&#xff1a; 注意&#xff1a; 代码&#xff1a; bool cmp(char a, char b){return a<b;…