MySQL知识点总结(四)——MVCC

news2024/9/28 7:17:19

MySQL知识点总结(四)——MVCC

  • 三个隐式字段
    • row_id
    • trx_id
    • roll_pointer
  • undo log
  • read view
  • MVCC与隔离级别的关系
  • 快照读和当前读

MVCC全称是Multi Version Concurrency Control,也就是多版本并发控制。它的作用是提高事务的并发度,通过MVCC机制,数据库可以不通过加锁,也能保证事务的隔离性。MySQL的InnoDB存储引擎也有自己的MVCC机制的实现,通过MVCC机制保证了“读已提交”和“可重复读”两个隔离级别下的隔离性。

要理解MVCC,就要理解InnoDB里面的三样东西:“数据行记录中的三个隐式字段”、“undo log”、“read view”。理解了这三个东西,也就是理解了MVCC。

在这里插入图片描述

三个隐式字段

当我们使用InnoDB作为我们某个库表的存储引擎时,我们添加到该库表中的数据行记录,InnoDB都会默认给该行记录添加三个隐式字段,这三个隐式字段分别是“row_id”、“trx_id”、“roll_pointer”。

在这里插入图片描述

row_id

这个是InnoDB为每一个行记录生成的一个唯一的id,它和主键一样,都可以唯一标识一条行记录。当我们没有给我们的库表定义主键、也没有定义唯一索引时,InnoDB就会拿它来作为库表的主键。

于是,InnoDB中库表主键的选取,首先看库表是否有显式定义主键列,如果有,那么当前库表的主键就是我们显式定义的主键列;如果没有定义主键,但是我们定义了唯一索引,那么当前库表的主键就是我们定义的唯一索引(多个唯一索引,选其中一个);如果我们没有定义主键列,也没有定义唯一索引,那么InnoDB就会把row_id作为当前库表的主键。

在这里插入图片描述

trx_id

“trx_id”是事务id,记录的是当前行记录是被哪个事务修改提交的。

InnoDB会为每个开启的事务分配一个递增的id,用于唯一标识一个事务,当某个事务修改了某个行记录时,就会在这个行记录的trx_id隐式字段中记录当前事务的id。

在这里插入图片描述

roll_pointer

roll_pointer是回滚指针,当一个事务对某库表的一条行记录进行修改时,会把该行记录先拷贝到undo log日志中作为一个历史版本,然后再对该行记录进行修改,并且使用一个roll_pointer指针指向undo log中该行记录的历史版本。

在这里插入图片描述

undo log

undo log是InnoDB的回滚日志,用于事务回滚。每次对库表进行增删改,InnoDB都会把涉及到的行记录的历史版本拷贝到undo log中,然后使用行记录中的隐式字段“roll_pointer”指向undo log中该行记录的最近的版本,这样,undo log就形成了一个链表,沿着roll_pointer回滚指针,我们可以不断的往前追溯某个行记录的历史版本。

在这里插入图片描述

有了undo log,就可以实现事务的可重复读,只要当前事务通过某种机制记住该行记录哪个历史版本对于自己是可见的,然后每次读取该行记录时都读取这个历史版本,就可以实现可重复读,其他事务也可以照常进行更新操作,不会被阻塞。

而这个机制就是“read view”,read view记录了当前活跃的事务id,也就是已开启但还未提交的事务对于的事务id。有了“read view”,当前事务读取某库表的行记录时,就可以沿着roll_pointer指针往前进行遍历,拿到该行记录的每个版本对应的trx_id字段,在read view中进行比对,如果发现trx_id在read view中是存在的,那说明这个版本是当前某个活跃事务修改(但未提交)的,因此对于当前事务尚不可见,直到遍历到某个版本,发现在read_view中不存在,那么就可以读取这个版本。

在这里插入图片描述

read view

“read view”是一种快照,它不仅记录了当前有哪些事务正处于活跃状态,还记录了当前活跃事务中最小的id,以及下一个开启的事务将会被分配的事务id。

在这里插入图片描述

比如当前活跃的事务对应的事务id是5、4、3,那么read view就会通过一个列表trx_ids记录[3,4,5]。通过trx_ids可以得知,当最小的活跃事务id是3,InnoDB用一个变量up_limit_id记录这个3,然后下一个开启的事务被分配的事务id是6,InnoDB用一个变量low_limit_id记录这个6。

在这里插入图片描述

这样,通过read view不但可以得知当前活跃事务,也可以知道在当前事务开启前已经提交的最新事务是多少,比如这里的read view记录的时[3,4,5],那就可以知道在当前事务开启以前,最新提交的事务是2,那么trx_id小于等于2(trx_id < up_limit_id)的行记录对于当前事务都是可见的。

除此以外,也可以知道下一个要开启的事务被分配的事务id是多少,比如这里比如这里的read view记录的时[3,4,5],那就可以知道下一个要开启的事务会被分配事务id为6。如果在当前事务开启之后,又开启了其他事务,并且提交了修改,那么被修改的行记录的trx_id就是大于等于6的(trx_id >= low_limit_id),对于当前事务来说是不可见,只能沿着roll_pointer往前追溯,读取历史版本。

因此,当一个事务读取某库表的某行记录时,这个可见性的判断逻辑就是这样:

  1. 判断当前记录的trx_id是否小于up_limit_id:如果是,那么当前行记录对于当前事务是可见的;如果不是,执行下一步的判断逻辑(步骤2)。
  2. 判断trx_id是否大于等于low_limit_id:如果是,那么当前行记录对于当前事务是不可见的,只能沿着roll_pointer指针往前遍历,读取当前行记录的上一个历史版本,并且回到步骤1重新比对;如果不是,那么执行下一步的判断逻辑(步骤3)。
  3. 判断trx_id是否在trx_ids列表中:如果是,那么表示当前行记录是当前某个活跃的事务修改的,执行下一步判断逻辑(步骤4);如果不是,那么表示当前行记录是在当前事务开启并生成read view前就已经提交了的,那么对于当前事务来说可见,读取该版本的行记录。
  4. 判断trx_id是否是当前事务自己的id:如果是,那么表示是自己做的修改,还是可见的;否则对于当前事务来说也是不可见,只能沿着roll_pointer指针往前遍历,读取当前行记录的上一个历史版本,并且回到步骤1重新比对。

在这里插入图片描述

MVCC与隔离级别的关系

我们知道隔离级别从低到高有四个:读未提交、读已提交、可重复读、串行化。在InnoDB中,读已提交和可重复读这两个隔离级别就是通过MVCC保证的。

在读已提交隔离级别下,事务的每次SQL都会生成一个新的read view,这是它可以读到其他事务最新提交的修改的原因。比如现在有一个事务A读取某库表id为5的这一条记录,读到【name】字段的值“zhagnsan”。此时,另一个事务B修改了该库表id为5的这一行记录的【name】字段为“lisi”,并提交了。此时事务A再次读取该库表id为5的这一行记录,在读取前,会重新生成read view,由于事务B已经提交了,活跃事务列表trx_ids中就不包含事务B的事务id了,因此事务B修改id为5的行记录的【name】字段为“lisi”,是可以被事务A读到的,这就是不可重复读问题出现的原因。

在这里插入图片描述

而在可重复读隔离级别下,read view只在当前事务开启后,第一次发起读操作时生成一遍,后续就不再生成。也就是说,在可重复读隔离级别下,一个事务的read view一旦生成,后续就不再改变,即使中间有某个活跃的事务修改数据并提交了,当前事务的read view也不会发生变化,再次发起读操作时也不会再重新生成read view,因此read view的trx_ids中还是记录着这个已提交的事务的事务id,因此该修改对于当前事务就不可见,不会被当前事务读取到。

在这里插入图片描述

快照读和当前读

上面这种通过MVCC读取一个行记录的历史版本的做法,就是快照读,也就是说我们读到的是数据的历史版本。

而当前读则是保证读到的一定是当前行记录的最新版本,那什么时候会触发快照读,什么时候会触发当前读呢?

当一个事务开启以后,一般的select语句都是快照读,只有显式地添加“lock in share mode”或者“for update”的select语句才会进行当前读,因为这两个语句是加锁的语句,都已经要加锁了,就没有必要走MVCC的逻辑了。

除此以外,“update”、“insert”、“delete”等SQL也会触发当前读,因为增删改这种写操作必然是要基于最新的行记录的,如果对一个历史版本的数据进行修改是毫无意义的,并且写操作是需要保证绝对的隔离性的,否则就会发送更新丢失,因此写操作也会加锁,那么就会触发当前读。

在这里插入图片描述

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

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

相关文章

西瓜书学习笔记——主成分分析(公式推导+举例应用)

文章目录 算法介绍实验分析 算法介绍 主成分分析&#xff08;Principal Component Analysis&#xff0c;PCA&#xff09;是一种常用的降维技术&#xff0c;用于在高维数据中发现最重要的特征或主成分。PCA的目标是通过线性变换将原始数据转换成一组新的特征&#xff0c;这些新…

web前端--------渐变和过渡

线性渐变&#xff0c;是指颜色沿一条直线进行渐变&#xff0c;例如从上到下、从左到右。 当然&#xff0c;CSS中也支持使用角度来设置渐变的方向&#xff0c;角度单位为deg。 0deg&#xff0c;为12点钟方向&#xff0c;表示从下到上渐变。 90deg&#xff0c;为3点钟方向&…

C++ | 部分和函数partial_sum的使用技巧

如果你需要处理一个数组的前缀和&#xff0c;或者数组中某一段元素的前缀和&#xff0c;你会怎么做呢&#xff1f; partial_sum函数是STL中的函数&#xff0c;用于计算范围的部分和&#xff0c;并从结果开始分配范围中的每个元素&#xff0c;range[first,last)中相应元素的部分…

nest.js实现登录验证码功能(学习笔记)

安装express-session npm i express-session 引入 注册session import * as session from express-session;import { NestFactory } from nestjs/core; import {DocumentBuilder,SwaggerModule, } from nestjs/swagger;import { AppModule } from ./app.module;async functio…

(五)springboot 配置多数据源连接mysql和hive

项目结构如下 mysql 执行如下建表语句&#xff0c;并插入一条测试数据 1 2 3 4 5 CREATE TABLE user ( id int(11) NOT NULL, name varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_ge…

计算机服务器中了DevicData勒索病毒如何解密,DevicData勒索病毒解密流程

网络数据安全一直是企业关心的主要话题&#xff0c;近期&#xff0c;云天数据恢复中心接到很多企业的求助&#xff0c;企业的计算机服务器遭到了DevicData勒索病毒攻击&#xff0c;导致企业计算机服务器瘫痪无法正常工作&#xff0c;严重影响了工作业务开展。经过云天数据恢复中…

【C语言】大小写字母的相互转化:多种方法解析及原理说明

在 C 语言编程中&#xff0c;我们经常需要进行大小写字母的相互转化。这种转化可以用于实现字符串的大小写转换、字符的大小写比较等操作。本篇博客将介绍多种方法来实现大小写字母的相互转化&#xff0c;并说明其原理和使用场景。 目录 方法一&#xff1a;标准库函数 方法二…

C# Onnx yolov8 水表读数检测

目录 效果 模型信息 项目 代码 训练数据 下载 C# Onnx yolov8 水表读数检测 效果 模型信息 Model Properties ------------------------- date&#xff1a;2024-01-31T10:18:10.141465 author&#xff1a;Ultralytics task&#xff1a;detect license&#xff1a;AGPL-…

在VMware Workstation上安装深度系统Deepin V23 Beta3

原文链接&#xff1a;在VMware上安装深度Deepin V23 Beta3 大家好&#xff01;深度系统&#xff08;Deepin&#xff09;以其美观的界面和用户友好的设计而受到广泛欢迎。最近&#xff0c;深度系统的最新版本Deepin V23 Beta3已经发布。今天&#xff0c;我将为大家带来如何在VMw…

Vivado_2018.3文件 source无法自动更新,并且tb仿真文件不显示set as top,需要关闭Vivado之后重启

如下图所示&#xff0c;如果没有set as top这个选项&#xff0c;在确认代码没有问题的情况下&#xff0c;则需要重启vivado. 正常情况下如果有多个_tb仿真文件&#xff0c;会在simulation sources——sim_1下显示&#xff0c;_tb文件前面会有箭头 点开箭头之后&#xff0c;会发…

Matomo 访问图形显示异常

近期我们的把 PHP 系统完全升级后&#xff0c;访问 Matomo 的站点有关访问的曲线无法显示。 出现的情况如下图&#xff1a; 我们可以看到图片中有关的访问曲线无法显示。 如果具体直接访问链接的话&#xff0c;会有下面的错误信息。 问题和解决 出现上面问题的原因是缺少 ph…

Chemkin模拟HFC-125对碳氢燃料燃烧抑制的影响

1 机理建立 抑制剂的详细机理包含四个子机理: (1)烷烃/空气燃烧子机理:(2) 氟碳抑制子机理;(3)氯氟交互作用子机理;(4)碳抑制子机理。对于碳氢火焰燃烧采用AramcoMech的 C1-C4 机理&#xff0c;包含 111 个组分&#xff0c;784 步基元反应。涉及到氟组分在碳氢火焰中的抑制反应…

【QT】贪吃蛇小游戏 -- 童年回忆

成品展示 项目分析&#xff1a; &#x1f40d;基本元素如下 &#x1f40d;小蛇的设计&#xff0c;初始大小蛇头占一个方块&#xff0c;蛇身占两个方块。 &#x1f40d;关于小蛇的移动&#xff0c;采用蛇头前进方向增加一个方块&#xff0c;蛇尾减掉一个方块的实现方法。 &#…

算法学习——华为机考题库3(HJ21 - HJ25)

算法学习——华为机考题库3&#xff08;HJ21 - HJ30&#xff09; HJ21 简单密码 描述 现在有一种密码变换算法。 九键手机键盘上的数字与字母的对应&#xff1a; 1–1&#xff0c; abc–2, def–3, ghi–4, jkl–5, mno–6, pqrs–7, tuv–8 wxyz–9, 0–0&#xff0c;把密码…

2023年计算机视觉领域突破性研究有哪些?

B站&#xff1a;啥都会一点的研究生公众号&#xff1a;啥都会一点的研究生 ​回顾2023年&#xff0c;计算机视觉领域有哪些较为突出的研究成果&#xff1f;一起看看吧 SAM(Segment Anything Model) SAM 由 Meta AI 开发&#xff0c;是 CV 中分割任务的基础模型&#xff0c;彻…

富文本编辑器CKEditor4简单使用-05(开发自定义插件入门)

富文本编辑器CKEditor4简单使用-05&#xff08;开发自定义插件入门&#xff09; 1. CKEditor4插件入门1.1 关于CKEditor4插件的简单安装与使用1.2 参考 2. 开发自定义插件——当前时间插件2.1 创建插件文件目录结构2.2 编写插件原代码2.2.1 编写代码框架2.2.2 创建编辑器命令2.…

【blender插件】(1)快速开始

特性 blender的python API有如下特性: 编辑用户界面可以编辑的任意数据(场景,网格,粒子等)。修改用户首选项、键映射和主题。运行自己的配置运行工具。创建用户界面元素,如菜单、标题和面板。创建新的工具。场景交互式工具。创建与Blender集成的新渲染引擎。修改模型的数据…

迪文串口屏数据的隐藏功能

一、概述 由于项目中在使用迪文屏显示数据的时候&#xff0c;需要在数据为0的时候不显示0&#xff0c;而迪文屏默认的数据变量在无值的时候显示为0&#xff0c;此时可以使用数据的隐藏功能指令 二、具体实现方法 1、可以使用描述指针地址来实现数据的隐藏&#xff0c;查看应用…

「效果图渲染」效果图与3D影视动画渲染平台

效果图渲染和3D影视动画渲染都是视觉图像渲染的领域应用。效果图渲染主要服务于建筑、室内设计和产品设计等行业&#xff0c;这些领域通常对视觉呈现的精度和细节有较高要求。与之相比&#xff0c;3D影视动画渲染则普遍应用于电影、电视、视频游戏和广告等媒体领域&#xff0c;…

2024年第四届工业自动化、机器人与控制工程国际会议 | Ei、Scopus双检索

会议简介 Brief Introduction 2024年第四届工业自动化、机器人与控制工程国际会议&#xff08;IARCE 2024&#xff09; 会议时间&#xff1a;2024年7月5 -7日 召开地点&#xff1a;中国成都 大会官网&#xff1a;www.iarce.org 2024年第四届工业自动化、机器人与控制工程国际会…