InnoDB对MVCC的实现

MVCC是啥? (Multiversion Concurrency Control) 多版本并发控制

是个方法,是个思想。 解决多并发事务操作同一数据库数据,数据保持一致的问题。

怎么做:每个数据行上维护多个版本

当一个事务要对数据进行修改,为该事务创建一个数据快照,而不直接修改实际数据行。

读操作:有多个版本的数据,读最接近,早于事务开始时间的版本

写操作:不动原来的数据。事务重新创建一个副本操作,回滚了就无事发生,提交了就生成新一版数据。事务操作期间t0-t1的读,都读t0的版本。

为防止版本无限增长,定期进行回收,把不需要的旧版本数据删了,释放空间。

如果要读的行正在执行 DELETE 或 UPDATE 操作,读操作不等DELETE 或 UPDATE 操作完成。而是读最近的历史版本 ,这种读法叫快照读 (snapshot read)。


好 有了方法 要实现MVCC,InnoDB具体是怎么做的

为了实现MVCC,InnoDB 准备了三个东西:隐藏字段、Read View、undo log。

InnoDB 存储引擎为每行数据添加三个隐藏字段:

  • DB_TRX_ID:表示最后一次插入或更新该行的事务 id。delete 被视为更新,会在记录头 Record header 中的 deleted_flag 字段将其标记为已删除。

  • DB_ROLL_PTR: 回滚指针,指向该行的 undo log 。该行未被更新,则为空

  • DB_ROW_ID:如果没有设置主键且该表没有唯一非空索引,InnoDB 会使用该 id 来生成聚簇索引

会生成一个东西叫快照,即Read View,记录正在运行得事务的ID

这么多版本的数据放在哪里,放在undo log。

一个事务来了,要读a,InnoDB找到a,看Read View属性和DB_TRX_ID,判断是否可见,可见,直接读走。不可见,InnoDB通过DB_ROLL_PTR找到undo log中的最近历史版本读。

开始时间不同,每个事务读到的数据版本可能不同,同一个事务中,用户只能看到该事务开始时读的值和事务本身做的修改。

在 InnoDB 存储引擎中 undo log 分为两种:insert undo log 和 update undo log

insert undo log:指在 insert 操作中产生的 undo log。insert 操作的记录只对事务本身可见,对其他事务不可见,该 undo log 可以在事务提交后直接删除。不需要进行 purge 操作

update undo log:update 或 delete 操作中产生的 undo log。该 undo log可能需要提供 MVCC 机制,因此不能在事务提交时就进行删除。提交时放入 undo log 链表,等待 purge线程 进行最后的删除

不同事务或者相同事务对同一记录行的修改,会使该记录行的 undo log 成为一条链表,链首就是最新记录,链尾是最早的旧记录。

InnoDB 中,创建一个新事务后,执行每个 select 语句前,都会创建一个快照(Read View),快照保存当前数据库中正活跃(没有 commit)的事务的 ID 号,即保存的是系统中当前不应该被本事务看到的其他事务 ID 列表(即 m_ids)。

当用户在这个事务中要读取某个行时,InnoDB 会将该记录行的 DB_TRX_ID 与 Read View 中的一些变量及当前事务 ID 进行比较,判断是否满足可见性条件。


InnoDB 使用 MVCC生成 Read View 的时机不同:

  •  RC : 每次select 前都生成一个Read View (m_ids 列表) 只要提交了都能读
  •  RR :只在事务开始后 第一次select 前生成一个Read View(m_ids 列表)同一事务中要读到一样的数据

MVCC+Next-key-lock防止幻读

InnoDB存储引擎在 RR 级别下通过 MVCC和 Next-key Lock 来解决幻读问题:

1.执行普通 select,以 MVCC 快照读读数据

只在事务开启后第一次查询生成 Read View ,一直使用到事务提交。生成 Read View 之后其它事务的更新、插入记录版本对当前事务不可见,实现可重复读和防止快照读下的 “幻读”。

2.执行 select...for update/lock in share mode、insert、update、delete 等当前读

在当前读下,读的都是最新数据,如果其它事务有插入新记录,并且刚好在当前事务查询范围内,就会产生幻读!InnoDB 使用 Next-key Lock解决。执行当前读时,锁定读到的记录和它们的间隙,防止其它事务在查询范围内插入数据。没有新增,就没有幻读。

 

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

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

相关文章

mysql转达梦的python脚本

mysql_ddl: CREATE TABLE ops_app_import (id char(32) NOT NULL COMMENT 主键ID,pkg_name varchar(255) NOT NULL DEFAULT COMMENT 导入包名称,pkg_md5 varchar(32) NOT NULL COMMENT 导入包md5值,backup_pkg_name varchar(255) DEFAULT COMMENT 备份包名称,bac…

[剪藏] - 由哇哈哈和农夫山泉所想到的

哇哈哈和农夫山泉的缠斗最近冒出来一个有趣的点:营销大于内容的胜利。 具体来说是这样的:农夫山泉很多年前做广告,说纯净水没有矿物质,长期喝是不利于人体健康的。农夫还做了个营销的对比实验,大概是用矿泉水养水仙花&…

龙芯杯赛道-学习过程记录

Preface&免责声明: 由于参赛资料企业并未开源,所以我不能开放出有关参赛的资料 但是我会在这里记录参赛时看不懂的一系列知识补充 ------------------------------------------------------------------------------------------------------- TSEN…

音视频开发之旅(75)- AI数字人进阶--GeneFace++

目录 1.效果展示和玩法场景 2.GeneFace原理学习 3.数据集准备以及训练的过程 5.遇到的问题与解决方案 6.参考资料 一、效果展示 AI数字人进阶--GeneFace(1) AI数字人进阶--GeneFace(2) 想象一下,一个专为你打造的…

前端算法 - 查找

1 二分查找 /*** param {number[]} nums* param {number} target* return {number}*/ var search function (nums, target) {let left 0, right nums.length - 1while (left < right) {let mid Math.floor((left right) / 2)if (target < nums[mid]) {right mid -…

为什么 VSCode 不用 Qt 而要用 Electron?

为什么 VSCode 不用 Qt 而要用 Electron? 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「Qt 的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&am…

Python基础课堂最后一课23——正则对象

文章目录 前言一、正则对象是什么&#xff1f;二、正则表达式基本分类1.普通字符2.元字符 总结 前言 很开心能和你们一些学习进步&#xff0c;在这一个多月的时间中&#xff0c;是你们让我坚持了下来&#xff0c;完成了python基础课堂编写&#xff0c;不管如何&#xff0c;我们…

C语言学习(第二十课)初识函数5(函数递归2)

#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<string.h> //编写函数&#xff0c;不允许创建临时变量&#xff0c;求字符串长度 ///1、可以使用临时变量的写法&#xff1a; //int my_strlen(char* str) //{ // int count 0; // while (*s…

安卓Java面试题 121- 130

131. Android垃圾回收机制和程序优化System.gc( ) ?垃圾收集算法的核心思想:对虚拟机的可用内存空间,即堆空间中的对象进行识别,如果对象正在被引用,则称其为存活对象,反之,如果对象不再被引用,则为垃圾对象,可以回收其占据的空间,用于再分配。 JVM进行次GC的频率很高…

Linux系统——Nginx脚本拦截拓展

可能会有些无聊的人对服务器的Nginx服务进行恶意访问网站、API接口&#xff0c;会影响到用户的体验&#xff0c;我们可以做一个简单的脚本对恶意访问的IP做一个有效的拦截&#xff0c;揪出这些IP地址&#xff0c;然后将其进行禁用。 在Nginx的conf目录下新建一个blockip.conf文…

Python(C_Cpp)分析模拟Arduino和Raspberry Pi(单板机)CAN总线和车载单元测试

要点 CAN总线释义&#xff1a;物理层结构&#xff0c;数据帧&#xff0c;数据交换&#xff0c;总线接口物理模块。一对Arduino CAN &#xff08;Arduino C 处理&#xff09;总线项目&#xff1a; 发送端发送随机数据&#xff0c;接收端接收并计算。发送端点动信号&#xff0c;…

certificate has expired or is not yet valid:npm和node证书过期问题

在 1 月 22 日&#xff0c;淘宝原镜像域名&#xff08;registry.npm.taobao.org&#xff09;的 HTTPS 证书正式到期。如果想要继续使用&#xff0c;需要将 npm 源切换到新的源&#xff08;registry.npmmirror.com&#xff09;&#xff0c;否则会报错。 解决方案切换到新的源&a…

HTML表单

本文章属于学习笔记&#xff0c;在https://www.freecodecamp.org/chinese/learn/2022/responsive-web-design/中练习 四、HTML表单 CSS 1、vh单位表示视口高度&#xff0c;等于视口高度的1%。这使得它相对于视口高度。height:100vh; 2、设置 body 的默认 margin 为 0 来重置…

【掌握版本控制:Git 入门与实践指南】远程操作|标签管理

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;泥中に咲く—ウォルピスカーター 0:34━━━━━━️&#x1f49f;──────── 4:46 &#x1f504; ◀️ ⏸ ▶…

汽车IVI中控开发入门及进阶(十三):语音识别

前言: IVI中控上的语音识别,在目前市场上也是非常显眼的一个创新,大幅改变了传统IVI的操作习惯。 语音识别Speech recognition,也称为自动语音识别(ASR)、计算机语音识别或语音到文本,是一种使程序能够将人类语音处理成书面格式的能力。 语音识别Speech recognition是计…

数码管的静态显示(二)

1.原理 要按照上图的顺序传递位选和段选的数据。 因为q0是最高位&#xff0c;共阳极数码管结构是dp....a&#xff0c;所以应该先传入低位a&#xff0c;而a在上图中的8段2进制编码中是seg[7]&#xff0c;所以段选信号的顺序是seg[0],...seg[7]。 因为输出信号是两个时钟&#x…

Docker入门笔记(1)

Docker入门笔记&#xff08;1&#xff09; 容器技术入门 之前我的WIT问卷管理系统在阿里云上部署需要好多配置&#xff0c;各个环境耦合的比较紧密&#xff0c;花了不少时间去做部署和调配。 现在有了Docker以后&#xff0c;我们可以把各种组件配置好&#xff0c;然后打包成…

使用ScottPlot库在.NET WinForms中快速实现大型数据集的交互式显示

前言 在.NET应用开发中数据集的交互式显示是一个非常常见的功能&#xff0c;如需要创建折线图、柱状图、饼图、散点图等不同类型的图表将数据呈现出来&#xff0c;帮助人们更好地理解数据、发现规律&#xff0c;并支持决策和沟通。本文我们将一起来学习一下如何使用ScottPlot库…

C语言snprintf():将格式化字符串输出到数组中

snprintf() 是 C语言的一个标准库函数&#xff0c;定义在<stdio.h>头文件中。 snprintf() 函数的功能是格式化字符串&#xff0c;并将结果存储在指定的字符数组中。该函数的原型如下&#xff1a; int snprintf(char *str, size_t size, const char *format[,argument...…

websocket逆向案例

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、案例地址二、分析流程三、逆向参数四、webSocket 交互位置总结 前言 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供…