SQL进阶理论篇(十二):InnoDB中的MVCC是如何实现的?

文章目录

  • 简介
  • 事务版本号
  • 行记录的隐藏列
  • Undo Log
  • Read View的工作流程
  • 总结
  • 参考文献

简介

在不同的DBMS里,MVCC的实现机制是不同的。本节我们会以InnoDB举例,讲解InnoDB里MVCC的实现机制。

我们需要掌握这么几个概念:

  • 事务版本号
  • 行记录的隐藏列
  • Undo Log
  • Read View

事务版本号

什么是事务版本号?

每开启一个事务,我们就会从数据库中获得一个事务ID,这个ID就是事务的版本号。它是自增长的,通过这个ID,我们就可以判断不同事务的时间顺序。

行记录的隐藏列

什么是行记录的隐藏列?

InnoDB的叶子段里存储了数据页,数据页中保存了行记录,而在行记录里有一些比较重要的隐藏字段。

如图:

在这里插入图片描述

db_row_id:隐藏的行ID,用来生成默认的聚集索引。如果我们在创建数据表的时候没有指定聚集索引,那么InnoDB就会使用这个隐藏的行ID来创建聚集索引。借以提升查找效率。

db_trx_id:操作这个数据的事务ID,其实就是最后一个对该数据进行插入或者更新的事务ID。

db_roll_ptr:回滚指针,指向这个记录的Undo Log信息。

Undo Log

什么是Undo Log

InnoDB把行记录快照保存在了Undo Log里。

如图所示:

在这里插入图片描述

由上图可见,回滚指针其实是将这个数据行的所有快照记录,通过链表结构串联了起来。每个快照记录都保有了操作的事务ID。

当想要找历史快照的时候,就遍历回滚指针查找即可。

Read View的工作流程

read view是如何工作的?

这个比较复杂。

首先它有什么作用,我们前面讲过,Undo Log里保存了很多历史快照,那么对一个事务来讲,它应该查询哪个历史快照呢?

这时候就需要用到Read View了,其解决了行的可见性问题

一个事务在开启时,会创建属于自己的Read View,这里面保存了事务开启时所有活跃(还没有提交)的事务列表。换个角度理解,这里面保存的其实是不应该让当前事务看到的其他所有事务。(还没提交的事务的内容,原则上是不应该被别人看到的)

Read View里有几个重要的属性:

  • trx_ids:其他活跃事务的ID集合;
  • low_limit_id:trx_ids中最大的事务ID;
  • up_limit_id:trx_ids中最小的事务ID;
  • creator_trx_id:创建这个Read View的事务ID。

如图所示,下面是一个trx_ids集合,其中最大事务为trx8,最小事务是trx2,当前事务是creator_trx_id。

在这里插入图片描述

如果当前事务想要读取某一行记录,而这一行记录保存的最后修改事务ID是trx_id_line,那么有这么几种情况:

如果trx_id_line < up_limit_id,即当前最小活跃事务,就说明在这些活跃事务创建之前,这个行记录就已经被提交了,那么这个行记录对该事务,应该是可见的。

如果trx_id_line > low_limit_id,说明该行记录在这些活跃的事务创建之后才创建,这个行记录对当前事务应该不可见。

如果 up_limit_id < trx_id_line < low_limit_id,说明trx_id_line 这个事务,可能在当前事务创建的时候,还处于活跃状态,所以我们可以去trx_ids里去遍历。如果找到的话,说明这个事务还没提交,那么这条记录应该不可见,没找到的话,说明事务已经提交了,该行记录可见。

原理简单的说,就是在creator_trx_id这个事务创建的时候,如果trx_id_line这个事务是活跃的,那么它对应的行记录是不可见的;如果不是活跃的,那么对应的行记录就是可见的。这个其实就是避免脏读的概念。只不过是通过事务ID大小比较的方式来实现的。

最后,我们串一串完整的流程,当查询一条记录的时候,系统到底是如何通过多版本并发控制技术来找到它的:

  1. 获取当前事务自己的版本号,即事务ID;
  2. 获取自己的Read View;
  3. 查询得到的行记录数据,与Read View中的活跃事务版本号进行比较;
  4. 如果行记录符合Read View的规则,即行记录对当前事务可见,那就直接读这条行记录;如果行记录不符合Read View的规则,即行记录对当前事务不可见(原因见上),那就去Undo Log里获取该行记录符合情况的历史快照;
  5. 最后返回符合规则的数据。

因此,在InnoDB中,MVCC是通过Undo Log + Read View来进行数据读取,Undo Log保存了数据的历史快照,而Read View帮助我们判断当前最新版本的数据是否可见,不可见,那就去Undo Log里取历史。

总结

MVCC是通过乐观锁思想,来保证事务的隔离。

MVCC 的核心就是 Undo Log+ Read View,“MV”就是通过 Undo Log 来保存数据的历史版本,实现多版本的管理,“CC”是通过 Read View 来实现管理,通过 Read View 原则来决定数据是否显示。

需要注意,针对不同的隔离级别,Read View 的生成策略不同。或者说,根据Read View的生成策略不同,MVCC得以实现不同的隔离级别

当隔离级别是读已提交时,一个事务中,每次select查询都会获取一次Read View,如果每次获取到的Read View不同,就会产生不可重复读或者幻读的情况。

当隔离级别是可重复读的时候,一个事务只在第一次select 的时候获取一次Read View,之后的select都是对这个Read View的复用(解决了不可重复读的问题)。同时,在可重复读的隔离级别下,InnoDB会采用MVCC + Next-Key锁的机制来避免幻读问题。

那当隔离级别是读未提交时,就不合适用MVCC来控制了。因为根本就不需要用版本控制了,大家都直接读最新的行记录就可以了。

InnoDB中有三种行级锁:

  • 记录锁:对单个行记录添加锁;
  • 间隙锁(Gap Locking):锁住一个范围,但不包括记录本身。采用间隙锁可以防止幻读的产生(应该是锁住范围,不让范围增加或者减少,但是对记录的update应该还是可以的,估计防止不了不可重复读)。
  • Next-Key锁:锁住一个范围,同时锁定范围本身,相当于是间隙锁+记录锁。

在读已提交的情况下,InnoDB采用的是记录锁;在可重复读的隔离级别下,InnoDB会采用Next-Key锁的机制。

参考文献

  1. 31丨为什么大部分RDBMS都会支持MVCC?

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

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

相关文章

任务十六:主备备份型防火墙双机热备

目录 目的 器材 拓扑 步骤 一、基本配置 配置各路由器接口的IP地址【省略】 1、配置BGP协议实现Internet路由器之间互联 2、防火墙FW1和FW2接口IP配置与区域划分 3、配置区域间转发策略 4、配置NAPT和默认路由 5、配置VRRP组&#xff0c;并加入Active/standby VGMP管…

Windows下配置最新ChromeDriver

1、问题 在使用代码调用谷歌浏览器时会出错&#xff1a; from selenium import webdriver driver webdriver.Chrome() SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 114 Current browser versi…

KSP音频抓包

1. 按照网上其他教程&#xff0c;安装KSP抓音频 Biu~笔记&#xff1a;高通蓝牙ADK&#xff08;38&#xff09;-- KSP in MDE - 大大通(简体站) Biu~笔记&#xff1a;高通蓝牙ADK&#xff08;22&#xff09;--DSP音频链路监听 - 大大通(简体站) <<Biu~笔记&#xff1a;高…

AX7A200教程(9): ov5640摄像头输出显示720p视频

一&#xff0c;功能框图 ov5640摄像头视频通过ddr3缓存后&#xff0c;最后使用hdmi接口进行输出显示 二&#xff0c;摄像头硬件说明 2.1&#xff0c;像头硬件管脚 如下图所示&#xff0c;一共18个管脚 2.2&#xff0c;摄像头电源初始化时序 因这个ov5640摄像头是买的老摄像…

JDK bug:ciObjectFactory::create_new_metadata

文章目录 1、问题2.详细日志3.JDK&#xff1a;bug最终bug链接&#xff1a; 京东遇到过类似bug各位大佬如果有更详细的解答可以留言。 1、问题 Problematic frame: V [libjvm.so0x438067] ciObjectFactory::create_new_metadata(Metadata*)0x327 关键字还是ciObjectFactory::cr…

关键字、标识符、变量、基本数据类型

一、关键字&#xff08;Keyword&#xff09; 定义&#xff1a;被Java语言赋予了特殊含义&#xff0c;用做专门用途的字符串&#xff08;或单词&#xff09; 特点&#xff1a;全部关键字都是小写字母 Java关键字查询关键地址&#xff1a; http:// https://docs.oracle.com/j…

电影小镇智慧旅游项目技术方案:PPT全文111页,附下载

关键词&#xff1a;智慧旅游项目平台&#xff0c;智慧文旅建设&#xff0c;智慧城市建设&#xff0c;智慧文旅解决方案&#xff0c;智慧旅游技术应用&#xff0c;智慧旅游典型方案&#xff0c;智慧旅游景区方案&#xff0c;智慧旅游发展规划 一、智慧旅游的起源 智慧地球是IB…

机器学习:增强式学习Reinforcement learning

收集有标签数据比较困难的时候同时也不知道什么答案是比较好的时候可以考虑使用强化学习通过互动&#xff0c;机器可以自己知道什么结果是好的&#xff0c;什么结果是坏的 Outline 什么是RL Action就是一个functionEnvironment就是告诉这个Action是好的还是坏的 例子 Space i…

算法专题二:滑动窗口

算法专题二&#xff1a;滑动窗口 一.长度最小的子数组&#xff1a;1.思路一&#xff1a;暴力解法2.思路二&#xff1a;滑动窗口双指针3.GIF题目解析&#xff1a;思路一&#xff1a;思路二&#xff1a; 二.无重复字符的最长子串&#xff1a;1.思路一&#xff1a;滑动窗口2.GIF题…

Android-----AndroidManifests.xml 之meta-data

一、概念 meta-data&#xff1a;元数据、文件元数据。主要用来定义一些组件相关的配置值。 metadata是一组供父组件使用的名值对&#xff08;name-value pair&#xff09;&#xff0c;一个组件元素可以包含任意数量的meta-data子元素。这些子元素的值存放在一个 Bundle 对象中…

【具身智能评估9】Open X-Embodiment: Robotic Learning Datasets and RT-X Models

论文标题&#xff1a;Open X-Embodiment: Robotic Learning Datasets and RT-X Models 论文作者&#xff1a;– 论文原文&#xff1a;https://arxiv.org/abs/2310.08864 论文出处&#xff1a;– 论文被引&#xff1a;–&#xff08;12/18/2023&#xff09; 论文代码&#xff1a…

轻量封装WebGPU渲染系统示例<53>- 多盏灯灯光照在地面的效果

WebGPU实时渲染实现模拟多盏灯的灯光照在地面的效果灯光效果 。 当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/material/src/voxgpu/sample/MultiLightsTest.ts 当前示例运行效果: 此示例基于此渲染系统实现&#xff0c;当前示例TypeScript源…

2018年第七届数学建模国际赛小美赛B题世界杯足球赛的赛制安排解题全过程文档及程序

2018年第七届数学建模国际赛小美赛 B题 世界杯足球赛的赛制安排 原题再现&#xff1a; 有32支球队参加国际足联世界杯决赛阶段的比赛。但从2026年开始&#xff0c;球队的数量将增加到48支。由于时间有限&#xff0c;一支球队不能打太多比赛。因此&#xff0c;国际足联提议改变…

计网02-计算机网络参考模型

一、OSI七层参考模型 1、分层的思想 分层模型用于网络协议的设计方法&#xff0c;本质是将网络节点间复杂的通信问题分成若干简单的问题逐一解决&#xff0c;通过网络的层次去找问题&#xff0c;将复杂问题简单化。 2、OSI参考模型 由于早期计算机厂商使用的是私有的网络模…

【PHP入门】2.1-运算符

-运算符- 运算符&#xff1a;operator&#xff0c;是一种将数据进行运算的特殊符号&#xff0c;在PHP中一共有十种运算符之多。 2.1.1赋值运算符 赋值运算&#xff1a;符号是“”&#xff0c;表示将右边的结果&#xff08;可以是变量、数据、常量和其它运算出来的结果&#…

scroll-behavior属性使用方法

定义和用法&#xff1a; scroll-behavior 属性规定当用户单击可滚动框中的链接时&#xff0c;是否平滑地&#xff08;具动画效果&#xff09;滚动位置&#xff0c;而不是直线跳转。 <style>element{/* 核心代码 */scroll-behavior: smooth;} </style> 属性值&am…

云原生之深入解析减少Docker镜像大小的优化技巧

一、什么是 Docker&#xff1f; Docker 是一种容器引擎&#xff0c;可以在容器内运行一段代码&#xff0c;Docker 镜像是在任何地方运行应用程序而无需担心应用程序依赖性的方式。要构建镜像&#xff0c;docker 使用一个名为 Dockerfile 的文件&#xff0c;Dockerfile 是一个包…

linux修改用户uid和gid并且修改文件所有权(所属用户及所属用户组)(chown命令、chgrp命令)(批量修改查找并修改文件、目录uid和gid)

文章目录 修改Linux用户UID和GID以及文件所有权1. 修改用户的UID和GID1.1 用户UID和GID的概念1.2 修改用户UID1.3 修改用户GID 2. 修改文件所有权2.1 文件所有权的概念2.2 修改文件所有者&#xff08;chown命令&#xff09;2.3 修改文件所属用户组&#xff08;chgrp命令&#x…

Gitlab仓库推送到Gitee仓库的一种思路

文章目录 Gitlab仓库推送到Gitee仓库的一种思路1、创建Gitee的ssh公钥&#xff08;默认已有Gitlab的ssh公钥&#xff09;2、添加Gitlab远程仓库地址3、添加Gitee远程仓库地址4、拉取Gitlab远程仓库指定分支到本地仓库指定分支&#xff08;以test分支为例&#xff09;5、推送本地…

PyTorch机器学习与深度学习

近年来&#xff0c;随着AlphaGo、无人驾驶汽车、医学影像智慧辅助诊疗、ImageNet竞赛等热点事件的发生&#xff0c;人工智能迎来了新一轮的发展浪潮。尤其是深度学习技术&#xff0c;在许多行业都取得了颠覆性的成果。另外&#xff0c;近年来&#xff0c;Pytorch深度学习框架受…