InnoDB对MVCC的实现

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

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

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

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

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

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

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

如果要读的行正在执行 DELETEUPDATE 操作,读操作不等DELETEUPDATE 操作完成。而是读最近的历史版本 ,这种读法叫快照读 (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 logupdate undo log

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

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

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

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

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


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

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

MVCC+Next-key-lock防止幻读

InnoDB存储引擎在 RR 级别下通过 MVCCNext-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.mzph.cn/news/743427.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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;不提供…