MySQL--》深度解析InnoDB引擎的存储与事务机制
目录
InnoDB架构
事务原理
MVCC
InnoDB架构
从MySQL5.5版本开始默认使用InnoDB存储引擎,它擅长进行事务处理,具有崩溃恢复的特性,在日常开发中使用非常广泛,其逻辑存储结构图如下所示,

下面是InnoDB架构图,左侧为内存结构,右 侧为磁盘结构,如下所示:

内存结构:主要有以下几部分组成,其特点如下所示:
1)Buffer Pool:缓冲池是主内存中的一个区域,里面可以缓存磁盘上经常操作的真实数据,在执行增删改查操作时,先操作缓冲池中的数据(若缓冲池没有数据,则从磁盘加载并缓存),然后再以一定频率刷新到磁盘,从而减少磁盘I0,加快处理速度。
缓冲池:以Page页为单位,底层采用链表数据结构管理Page,根据状态可以将Page分为三种类型:
free page:空闲page,未被使用。·
cleanpage:被使用page,数据没有被修改过。·
dirtypage:脏页,被使用page,数据被修改过,也中数据与磁盘的数据产生了不一致。
2)ChangeBuffer:更改缓冲区(针对于非唯一二级索引页),在执行DML语句时,如果这些数据Page没有在BufferPool中,不会直接操作磁盘,而会将数据变更存在更改缓冲区ChangeBuffer中,在未来数据被读取时,再将数据合并恢复到BufferPool中,再将合并后的数据刷新到磁盘中。与聚集索引不同,二级索引通常是非唯一的,并且以相对随机的顺序插入二级索引。同样,删除和更新可能会影响索引树中不相邻的二级索引页,如果每一次都操作磁盘,会造成大量的磁盘IO。有了ChangeBuffer之后,我们可以在缓冲池中进行合并处理,减少磁盘lO。
3)AdaptiveHashIndex:自适应hash索引,用于优化对BufferPool数据的查询。InnoDB存储引擎会监控对表上各索引页的查询,如果观察到hash索引可以提升速度,则建立hash索引l,称之为自适应hash索引。自适应哈希索引,无需人工干预,是系统根据情况自动完成。参数:adaptive_hash_index
4)LogBuffer:日志缓冲区,用来保存要写入到磁盘中的log日志数据(redolog、undolog),默认大小为16MB,日志缓冲区的日志会定期刷新到磁盘中。如果需要更新、插入或删除许多行的事务,增加日志缓冲区的大小可以节省磁盘1/0。
参数:innodb_log_buffer_size:缓冲区大小
innodb_flush_log_at_trx_commit:日志刷新到磁盘时机
磁盘结构:主要有以下几部分组成,其特点如下所示:
1)SystemTablespace:系统表空间是更改缓冲区的存储区域。如果表是在系统表空间而不是每个表文件或通用表空间中创建的,它也可能包含表和索引数据。(在MySQL5.x版本中还包含lnnoDB数据字典、undolog等)参数:innodb_data_file_path
2)File-Per-TableTablespaces:每个表的文件表空间包含单个lnnoDB表的数据和索引,并存储在文件系统上的单个数据文件中。参数:innodb_file_per_table
3)GeneralTablespaces:通用表空间,需要通过CREATETABLESPACE语法创建通用表空间,在创建表时,可以指定该表空间。
4)UndoTablespaces:撤销表空间,MySQL实例在初始化时会自动创建两个默认的undo表空间(初始大小16M),用于存储undolog日志。
5)Temporary Tablespaces:InnoDB使用会话临时表空间和全局临时表空间。存储用户创建的临时表等数据。
6)DoublewriteBufferFiles:双写缓冲区,innoDB引擎将数据页从BufferPool刷新到磁盘前,先将数据页写入双写缓冲区文件中,便于系统异常时恢复数据。
7)RedoLog:重做日志,是用来实现事务的持久性。该日志文件由两部分组成:重做日志缓冲(redologbuffer)以及重做日志文件(redolog),前者是在内存中,后者在磁盘中。当事务提交之后会把所有修改信息都会存到该日志中,用于在刷新脏页到磁盘时,发生错误时,进行数据恢复使用。
后台线程:InnoDB存储引擎缓冲池中主要有四个后台线程,它们主要内容如下:

1)Master Thread:核心后台线程,负责调度其他线程,还负责将缓冲池中的数据异步刷新到磁盘中,保持数据的一致性,还包括脏页的刷新、合并插入缓存、undo页的回收。
2)I0 Thread:在lnnoDB存储引擎中大量使用了AIO来处理IO请求,这样可以极大地提高数据库的性能,而IOThread主要负责这些lO请求的回调,线程类型如下所示:
| 线程类型 | 默认个数 | 职责 |
|---|---|---|
| Read thread | 4 | 负责读操作 |
| Write thread | 4 | 负责写操作 |
| Log thread | 1 | 负责将日志缓冲区刷新到磁盘 |
| Insert buffer thread | 1 | 负责将写缓冲区内容刷新到磁盘 |
3)Purge Thread:主要用于回收事务已经提交了的undolog,在事务提交之后,undolog可能不用了,就用它来回收。
4)Page Cleaner Thread:协助MasterThread刷新脏页到磁盘的线程,它可以减轻Master Thread的工作压力,减少阻塞。
事务原理
事务:事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败,其特性如下所示:
1)原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
2)一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。
3)隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
4)持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。
这些特性涉及的原理主要分为以下两者情况:

1)redo log:重做日志,记录的是事务提交时数据页的物理修改是用来实现事务的持久性,该日志文件由两部分组成:重做日志缓冲(redologbuffer)以及重做日志文件(redologfile),前者是在内存中,后者在磁盘中。
当事务提交之后会把所有修改信息都存到该日志文件中,用于在刷新脏页到磁盘,发生错误时,进行数据恢复使用,如下所示:

2)undo log:回滚日志,用于记录数据被修改前的信息,作用包含两个:提供回滚和 MVCC(多版本并发控制)。
undo log和redo log记录物理日志不一样,它是逻辑日志。可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。
当执行rollback时,就可以从undolog中的逻辑记录读取到相应的内容并进行回滚,如下所示:
undo log销毁:undo log在事务执行时产生,事务提交时,并不会立即删除undo log,因为这些日志可能还用于MVCC。
undo log存储:undo log采用段的方式进行管理和记录,存放在前面介绍的rollback segment回滚段中,内部包含1024个undo log segment。
MVCC
MVCC:通过在数据库中保存多个数据版本,允许读操作不加锁,同时写操作不会阻塞读取从而提高并发性能,MVCC依赖于事务的快照隔离(Snapshot Isolation)级别,确保每个事务看到的是一致的视图,对于读取数据主要分为以下两种:
1)当前读:读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁,对于我们日常的操作,如:select...lock in share mode(共享锁),select...for update、update、insert、delete(排他锁)都是一种当前读。
2)快照读:简单的select(不加锁)就是快照读,快照读读取的是记录数据的可见版本,有可能是历史数据,不加锁,是非阻塞读。
Read Committed:每次select都生成一个快照读。
Repeatable Read:开启事务后第一个select语句才是快照读的地方。
Serializable:快照读会退化为当前读。
其实现原理如下图所示:

MVCC使得读写操作没有冲突,快照读为MySQL实现MVCc提供了一个非阻塞读功能,MVCC的具体实现还需要依赖于数据库记录中的三个隐式字段、undo log日志、readView,如下:
隐式字段:当我们创建一张表的时候,默认记录中会有三个隐藏的字段,如下所示:

| 隐藏字段 | 含义 |
|---|---|
| DB_TRX_ID | 最近修改事务ID,记录插入这条记录或最后一次修改该记录的事务ID。 |
| DB_ROLL_PTR | 回滚指针,指向这条记录的上一个版本,用于配合undolog,指向上一个版本。 |
| DB_ROW_ID | 隐藏主键,如果表结构没有指定主键,将会生成该隐藏字段。 |
undo log日志:回滚日志,在insert、update、delete的时候产生的便于数据回滚的日志:
当insert的时候,产生的undolog日志只在回滚时需要,在事务提交后,可被立即删除
当update、delete的时候,产生的undolog日志不仅在回滚时需要,在快照读时也需要,不会立即被删除。
不同事务或相同事务对同一条记录进行修改,会导致该记录的undo log生成一条记录版本链表,链表的头部是最新的旧记录,链表尾部是最早的旧记录,如下所示:

readView:readView(读视图)是快照读SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的事务(未提交的)id,readView中包含了四个核心字段如下所示:
| 字段 | 含义 |
|---|---|
| m_ids | 当前活跃的事务ID集合 |
| min_trx_id | 最小活跃事务ID |
| max_trx_id | 预分配事务ID,当前最大事务ID+1(因为事务ID是自增的) |
| creator_trx_id | ReadView创建者的事务ID |
版本链数据的访问规则如下所示:

不同的隔离级别,生成的readView的时机不同,如下所示:
1)read committed:在事务中每一次执行快照读时生成的readView,如下所示:

比如当前我们访问这条记录的事务id小于我们的最小活动事务的id,那么就说明当前的这条记录已经提交了,此时就说明这一次快照读就是我们当前访问的这条记录,如下是DB_TRX_ID为2就是我们要访问的记录:

2)repeatable read:仅在事务第一次执行快照读时生成readView,后续复用该readView

相关文章:
MySQL--》深度解析InnoDB引擎的存储与事务机制
目录 InnoDB架构 事务原理 MVCC InnoDB架构 从MySQL5.5版本开始默认使用InnoDB存储引擎,它擅长进行事务处理,具有崩溃恢复的特性,在日常开发中使用非常广泛,其逻辑存储结构图如下所示, 下面是InnoDB架构图…...
Visio2021下载与安装教程
这里写目录标题 软件下载软件介绍安装步骤 软件下载 软件名称:Visio2021软件语言:简体中文软件大小:4.28G系统要求:Windows10或更高,64位操作系统硬件要求:CPU2GHz ,RAM4G或更高下载链接&#…...
实战纪实 | 真实HW漏洞流量告警分析
视频教程在我主页简介和专栏里 目录: 一、web.xml 文件泄露 二、Fastjson 远程代码执行漏洞 三、hydra工具爆破 四、绕过验证,SQL攻击成功 五、Struts2代码执行 今年七月,我去到了北京某大厂参加HW行动,因为是重点领域—-jr&…...
【AI论文】扩散对抗后训练用于一步视频生成总结
摘要:扩散模型被广泛应用于图像和视频生成,但其迭代生成过程缓慢且资源消耗大。尽管现有的蒸馏方法已显示出在图像领域实现一步生成的潜力,但它们仍存在显著的质量退化问题。在本研究中,我们提出了一种在扩散预训练后针对真实数据…...
重回C语言之老兵重装上阵(十六)C语言可变参数
C语言可变参数 在C语言中,标准库提供了一些函数允许接收可变数量的参数。最典型的例子就是 printf 和 scanf,它们能够处理不确定数量的参数。为了实现这一功能,C语言提供了可变参数函数的概念。 1. 可变参数函数的概念 可变参数函数是指函数…...
深拷贝、浅拷贝、移动语义
C 中的拷贝方式 1. 深拷贝(Deep Copy) 定义 深拷贝会复制对象的全部内容,包括对象中动态分配的资源。新对象与原对象完全独立,任何对新对象的修改都不会影响原对象。 实现 通常通过显式的拷贝构造函数或拷贝赋值运算符&#…...
双向链表在系统调度、游戏、文本编辑及组态方面的应用
在编程的奇妙世界里,数据结构就像是一把把神奇的钥匙(前面我们介绍过单向链表的基础了,这里我们更进一步),能帮我们打开解决各种问题的大门。今天,咱们就来聊聊其中一把特别的钥匙——双向链表。双向链表和…...
实践网络安全:常见威胁与应对策略详解
📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 引言 在数字化转型的浪潮中,网络安全的重要性已达到前所未有的高度。无论是个人用户、企业,还是政府机构…...
关于2024年
关于2024年 十分钟前我从床上爬起来,坐在电脑面前先后听了《黄金时代》——声音碎片和《Song F》——达达两首歌,我觉得躺着有些无聊,又或者除夕夜的晚上躺着让我觉得有些不适,我觉得自己应该爬起来,爬起来记录一下我…...
Hive:Hive Shell技巧
在终端命令窗口不能直接执行select,creat等HQL命令,需要先进入hive之后才能执行,比较麻烦,但是如果使用Hive Shell就可以直接执行 在终端只执行一次Hive命令 -e 参数, "execute"(执行),使用-e参数后会在执行完Hive的命令后退出Hive 使用场景:…...
Markdown Viewer 浏览器, vscode
使用VS Code插件打造完美的MarkDown编辑器(插件安装、插件配置、markdown语法)_vscode markdown-CSDN博客 右键 .md 文件,选择打开 方式 (安装一些markdown的插件) vscode如何预览markdown文件 | Fromidea GitCode - 全球开发者…...
快速分析LabVIEW主要特征进行判断
在LabVIEW中,快速分析程序特征进行判断是提升开发效率和减少调试时间的重要技巧。本文将介绍如何高效地识别和分析程序的关键特征,从而帮助开发者在编写和优化程序时做出及时的判断,避免不必要的错误。 数据流和并行性分析 LabVIEW的图形…...
【Super Tilemap Editor使用详解】(十五):从 TMX 文件导入地图(Importing from TMX files)
Super Tilemap Editor 支持从 TMX 文件(Tiled Map Editor 的文件格式)导入图块地图。通过导入 TMX 文件,你可以将 Tiled 中设计的地图快速转换为 Unity 中的图块地图,并自动创建图块地图组(Tilemap Group)。以下是详细的导入步骤和准备工作。 一、导入前的准备工作 在导…...
JavaScript系列(45)--响应式编程实现详解
JavaScript响应式编程实现详解 🔄 今天,让我们深入探讨JavaScript的响应式编程实现。响应式编程是一种基于数据流和变化传播的编程范式,它使我们能够以声明式的方式处理异步数据流。 响应式编程基础概念 🌟 💡 小知识…...
Lustre Core 语法 - 布尔表达式
Lustre v6 中的 Lustre Core 部分支持的表达式种类中,支持布尔表达式。相关的表达式包括and, or, xor, not, #, nor。 相应的文法定义为 Expression :: not Expression| Expression and Expression| Expression or Expression | Expression xor Expression | # (…...
python学opencv|读取图像(四十六)使用cv2.bitwise_or()函数实现图像按位或运算
【0】基础定义 按位与运算:全1取1,其余取0。按位或运算:全0取0,其余取1。 【1】引言 前序学习进程中,已经对图像按位与计算进行了详细探究,相关文章链接如下: python学opencv|读取图像&…...
C# 添加、替换、提取、或删除Excel中的图片
在Excel中插入与数据相关的图片,能将关键数据或信息以更直观的方式呈现出来,使文档更加美观。此外,对于已有图片,你有事可能需要更新图片以确保信息的准确性,或者将Excel 中的图片单独保存,用于资料归档、备…...
工作总结:压测篇
前言 压测是测试需要会的一项技能,作为开发,有点时候也要会一点压测。也是被逼着现学现卖的。 一、压测是什么,以及压测工具的选择 压测,即压力测试,是一种性能测试手段,通过模拟大量用户同时访问系统&am…...
11JavaWeb——SpringBootWeb案例02
前面我们已经实现了员工信息的条件分页查询以及删除操作。 关于员工管理的功能,还有两个需要实现: 新增员工 修改员工 首先我们先完成"新增员工"的功能开发,再完成"修改员工"的功能开发。而在"新增员工"中…...
vs2022+tesseract ocr识别中英文 编译好的库下载
测试图片 效果 编译其实挺麻烦的,可参考:在Windows上用Visual Studio编译Tesseract_windows编译tesseract-CSDN博客 #include "baseapi.h" #include "allheaders.h" #include <iostream> #include <fstream> // 用于文…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...
淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...
