MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)

文章目录

  • 一、InnoDB引擎逻辑储存结构
  • 二、架构——内存结构
  • 三、架构——磁盘结构
  • 四、架构——后台线程
  • 五、事务原理
    • 持久性:redo log。重做日志
    • 原子性:undo log。回滚日志
  • 六、MVCC基本概念
  • 七、MVCC实现原理
  • 八、undo log日志 回滚日志,版本链
  • 九、readView 读视图 决定查询读取 的记录

本文将带您遍览 InnoDB 存储引擎的内部机制,深入其逻辑存储结构和内存架构,解析页、段、区至行的层级,揭秘索引与数据是如何存放的。深入缓冲池的秘密,发现 InnoDB 如何以 Buffer Pool 为纽带,缓解物理硬盘与内存间的速度差异,保持高效。掌握更改缓冲区的智慧,理解非唯一二级索引背后的故事。嗅探自适应哈希索引和日志缓冲区,探寻其提升查询与事务写入的神奇之处。
文章还展现了 InnoDB 独特的磁盘结构布局,包含一应俱全的系统表空间、表级空间和特有的回滚机制,为数据的持久化与安全性搭建了坚实的基础。揭示了后台线程如何无声地协助数据在内存和磁盘间舞动,以及事务原理的严密逻辑,事务的 ACID 特性在 InnoDB 中如何实现。
最后,本文还深入探讨了 MVCC 的实现原理和细节,通过生动的快照读和 ReadView 机制,让并发控制如丝般顺滑,值得每位数据库爱好者细细品味。

一、InnoDB引擎逻辑储存结构

在这里插入图片描述

在这里插入图片描述

段,分为数据段、索引段、回滚段,InnoDB是索引组织表,数据段是B+树的非叶子结点,段用来管理多个区

区,表空间的单元结构,每个区大小为1M,默认情况下InnoDB存储引擎页大小为16K,即一个区公共有64个连续的页

页,是InnoDB存储引擎磁盘管理的最小单元,每个页的大小默认为16KB。为了保证页的连续性,每次InnoDB都会向磁盘申请4-5个区

行,InnoDB存储引擎数据是按照行进行存放的

记录中的每一列col1,col2,col3
两个隐藏列
Trx id,最后一次操作该行的事务ID
Roll pointer,每次对改行记录进行改动时,会把旧版本写入undo日志中,该值是指针,通过它可以找到之前没有改动的旧版本

二、架构——内存结构

在这里插入图片描述
InnoDB存储引擎基于磁盘文件存储,在物理硬盘和在内存中的速度相差很大,为了尽可能弥补这两者之间的I/O效率的差值,就需要把经常使用的数据加载到缓冲池中,避免每次访问都进行非常慢的且大部分都是随机的磁盘I/O。

在InnoDB的缓冲池中不仅缓存了索引页和数据页,还包含了undo页、插入缓存、自适应哈希索引以及 InnoDB的锁信息等等。
## Buffer Pool缓冲池
在这里插入图片描述
缓冲池 Buffer Pool,是主内存中的一个区域,里面可以缓存磁盘上经常操作的真实数据,在执行增 删改查操作时,先操作缓冲池中的数据(若缓冲池没有数据,则从磁盘加载并缓存),然后再以一定频率刷新到磁盘,从而减少磁盘IO,加快处理速度。

缓冲池以Page页为单位,底层采用链表数据结构管理Page。根据状态,将Page分为三种类型:

free page:空闲page,未被使用
clean page:被使用page,数据没有被修改过
dirty page:脏页,被使用page,数据被修改过,页中数据与磁盘的数据产生了不一致
## Change Buffer 更改缓冲区(针对于非唯一的二级索引页)
在这里插入图片描述
在执行DML(数据 增删改)语句时,如果这些数据Page 没有在Buffer Pool中,不会直接操作磁盘,而会将数据变更存在更改缓冲区 Change Buffer 中,在未来数据被读取时,再将数据合并恢复到Buffer Pool中,再将合并后的数据以一定频率刷新到磁盘中。

意义:与聚集索引不同,二级索引通常是非唯一的,并且以相对随机的顺序插入二级索引。同样,删除和更新 可能会影响索引树中不相邻的二级索引页,如果每一次都操作磁盘,会造成大量的磁盘IO。有了 ChangeBuffer之后,我们可以在缓冲池中进行合并处理,减少磁盘IO

## Adaptive Hash Index 自适应哈希索引
在这里插入图片描述
用于优化对Buffer Pool数据的查询。MySQL的innoDB引擎中虽然没有直接支持 hash索引,但是提供功能,即自适应hash索引。

hash索引对于等值匹配,一般性能高于B+树,因为hash索引一般只需要一次IO即可,而B+树可能需 要几次匹配,所以hash索引的效率要高,但hash索引又不适合做范围查询、模糊匹配等。

因此InnoDB存储引擎会监控对表上各索引页的查询,如果观察到在某条件下hash索引效率更高, 则建立hash索引,称为自适应hash索引。 自适应哈希索引无需人工干预,是系统根据情况自动完成。

## Log Buffer 日志缓冲区
在这里插入图片描述
Log Buffer:日志缓冲区,用来保存要写入到磁盘中的log日志数据(redo log 、undo log), 默认大小为 16MB,日志缓冲区的日志会定期刷新到磁盘中。如果需要更新、插入或删除许多行的事务,增加日志缓冲区的大小可以节省磁盘 I/O。
参数:innodb_log_buffer_size:缓冲区大小
参数:innodb_flush_log_at_trx_commit:日志刷新到磁盘时机,取值主要包含以下三个:
1日志在每次事务提交时写入并刷新到磁盘,默认值
0: 每秒将日志写入并刷新到磁盘一次
2: 日志在每次事务提交后写入,并每秒刷新到磁盘一次

三、架构——磁盘结构

在这里插入图片描述
磁盘结构

## System Tablespace 系统表空间

是更改缓冲区Change Buffer 的存储区域。如果表在系统表空间而不是每个表文件或通用表空间中创建的,它也可能包含表和索引数据。(在MySQL5.x版本中还包含InnoDB数据字典、undolog等)
## File-Per-Table Tablespaces

每张表的独立表空间,则每个表的文件表空间包含单个InnoDB表的数据和索引 ,并存储在文件系统上的单个数据文件中。 一个.ibd 对应一个表
## General Tablespaces 通用表空间

需要通过 CREATE TABLESPACE 语法创建通用表空间,在创建表时,可以指定该表空间

#创建表空间
CREATE TABLESPACE ts_name ADD DATAFILE 'file_name' ENGINE = engine_name;
#创建表时指定表空间
CREATE TABLE xxx ... TABLESPACE ts_name;
#-----------举例-----------
create tablespace ts_01 add datafile 'mydb01.ibd' engine = innodb;
创建表空间成功后,后续创建表时 可以指定把表创建至该表空间里

## Undo Tablespaces 撤销表空间

撤销表空间,MySQL实例在初始化时会自动创建两个默认的undo表空间(初始大小16M),用于存储 undo log日志,undo_001, undo_002

在这里插入图片描述

## Temporary Tablespaces 临时会话表空间

InnoDB 使用会话临时表空间和全局临时表空间。存储用户创建的临时表等数据。
## Doublewrite Buffer Files 双写缓冲区

双写缓冲区,innoDB引擎将数据页从Buffer Pool刷新到磁盘前,先将数据页写入双写缓冲区文件中,便于系统异常时恢复数据

在这里插入图片描述

## Redo Log 重做日志

用来实现事务的持久性。该日志文件由两部分组成:重做日志缓冲区(redo log buffer)(在内存结构的Log Buffer中)以及 重做日志文件(redo log),前者是在内存中,后者在磁盘中。

当事务提交之后会把所有修改信息存到该日志中,用于在刷新脏页到磁盘 发生错误时,进行数据恢复使用。以循环方式写入重做日志文件,涉及两个文件

在这里插入图片描述

四、架构——后台线程

内存中的数据和磁盘的数据 是怎么 写入和读取的呢?后台线程
在这里插入图片描述

## Master Thread(核心后台线程):
是MySQL的一个核心后台线程,负责管理和协调其他后台线程的工作,并将缓冲池中的数据异步刷新到磁盘中,保持数据的一致性;脏页的刷新、合并插入缓存、undo页的回收

## IO Thread(读写线程):
异步非阻塞IO 极大地提高数据库的性能,这些线程负责处理InnoDB存储引擎的IO请求,包括读取和写入磁盘上的数据。
在这里插入图片描述
在这里插入图片描述
## Purge Thread(清理线程):
Purge Thread负责回收已完成提交事务的undo log,将其释放以供后续事务使用。

## Page Cleaner Thread(页清理线程):
该线程负责在InnoDB存储引擎中执行脏页的刷新操作,将脏页写回磁盘,以确保数据的持久性和一致性。协助Master Thread。

五、事务原理

事务:一组操作的集合,要么全部成功,要么全部失败:

事务的四大特性:(ACID)原子性,一致性,隔离性,持久性

A:事务是不可分割的最小操作单元,要么全部成功,要么全部失败

C:事务完成时,必须使所有的数据都保持一致状态

I:数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行

D:事务一旦提交或回滚,它对数据库中的数据的改变就是永久的
在这里插入图片描述

持久性:redo log。重做日志

记录事务提交时,对数据页的物理修改,实现事务的持久性
包含两部分:重做日志缓冲(内存结构中的Log Buffer)与 磁盘的重做日志文件,提交后会把所有修改信息保存到该文件中,用于当刷新脏页到磁盘发生错误时 进行数据恢复使用
update/delete执行:
先看内存的BufferPool中有没有该页,如果没有该页则通过后台线程从磁盘中把页读到Buffer Pool
直接操作缓冲区中的数据,该页变成脏页
首先把数据页的物理变化记录在内存中的RodoLogBuffer,commit 事务提交的时候,redologBuffer会直接把数据页变化刷新到磁盘当中,即ib_logfile0,ib_logfile1中
在某个时机 该页以一定频率刷新到磁盘中进行持久化,若此时出错,则可以通过磁盘文件中的redo_log进行数据恢复
若脏页顺利写入磁盘,则redolog文件就不再需要,因此每过一段时间就清理一次redo log日志,是循环性的,不是永久的
在这里插入图片描述
日志文件都是追加的,是顺序磁盘I/O,效率比数据在磁盘的随机存取快速的多

WAL 先写日志 Write-Ahead Logging

原子性:undo log。回滚日志

在这里插入图片描述
用于记录被修改前的信息,作用包括两个:提供回滚 和 MVCC(多版本并发控制)

undo log 和 redo log 记录的物理日志不一样,它是逻辑日志。可以认为当delete一条记录时,undo log会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的 update记录(执行update之前 数据长的样子)。当执行rollback时,就可以从undo log中的逻辑记录读取到相应的内容并进行回滚

Undo log 销毁:undo log在事务执行时产生,事务提交时,并不会立即删除undo log,因为这些日志可能还用于MVCC

Undo log 存储:undo log采用段的方式进行管理和记录,存放在段中的rollback segment 回滚段中,内部包含1024个undo log segment

六、MVCC基本概念

在这里插入图片描述
当前读:读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。对于我们日常的操作,如:select … lock in share mode(共享锁),select … for update、update、insert、delete(排他锁)都是一种当前读。

客户端1使用select 语句,客户端2使用 update语句进行更新,因为当前隔离级别是可重复读,因此客户端1无法看到客户端2事务对数据的更改
在这里插入图片描述

当前读
在这里插入图片描述
快照读:简单的select(不加锁)就是快照读,快照读 读取的是记录数据的可见版本,有可能是历史数据, 不加锁,是非阻塞读

Read Committed 读已提交:每次select,都生成一个快照读
Repeatable Read 可重复高读:开启事务后第一个select语句才是快照读的地方。即第一次select查询产生快照读,后面的select查询直接使用前面的快照数据
Serializable 串行化:快照读会退化为当前读,每次读取都需要加锁
MVCC: Multi-Version Concurrency Control,多版本并发控制

维护一个数据的多个版本, 使得读写操作没有冲突,快照读 为MySQL实现MVCC提供了一个非阻塞读功能。MVCC的具体实现 依赖于数据库记录中的三个隐式字段、undo log日志、readView

七、MVCC实现原理

在这里插入图片描述
在这里插入图片描述

八、undo log日志 回滚日志,版本链

undo log日志 回滚日志

在insert、update、delete的时候产生的便于数据回滚的日志。
当insert的时候,产生的undo log日志只在回滚时需要,在事务提交后,可被立即删除
update、delete时,产生的undo log日志不仅在回滚时需要,在快照读时也需要,不会立即被删除

undo log 版本链

最终不同事务或相同事务对同一条记录进行修改,会导致该记录的undolog生成一条 记录版本链表。
链表的头部是最新的旧记录,链表尾部是最早的旧记录。
那么每次查询的时候,返回哪一个版本的记录呢?ReadView的作用
在这里插入图片描述

九、readView 读视图 决定查询读取 的记录

ReadView(读视图)是 快照读 SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的事务 (未提交的)id

在这里插入图片描述
在这里插入图片描述
不同的隔离级别,生成ReadView的时机不同:

READ COMMITTED :在事务中每一次执行快照读时生成ReadView
在这里插入图片描述
在这里插入图片描述

REPEATABLE READ:仅在事务中第一次执行快照读时生成ReadView,后续复用该ReadView

在RR隔离级别下,只是在事务中第一次快照读时生成ReadView,后续都是复用该 ReadView,那么既然ReadView都一样, ReadView的版本链匹配规则也一样, 那么最终快照读返 回的结果也是一样的
在这里插入图片描述
因此,MVCC的实现原理就是通过 InnoDB表的隐藏字段、UndoLog 版本链、ReadView来实现的。 而MVCC + 锁,则实现了事务的隔离性。 而一致性则是由redolog 与 undolog保证
在这里插入图片描述

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

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

相关文章

shell中正则表达式讲解

1. 概念 在进行程序设计的过程中,用户会不可避免地遇到处理某些文本的情况。有的 时候,用户还需要查找符合某些比较复杂规则的字符串。对于这些情况,如果 单纯依靠程序设计语言本身,则往往会使得用户通过复杂的代码来实现。但 是&…

在linux上不依赖于Nignx等服务器部署ASP.NET Core 7.0 WebAPI

笔者近期需要部署一款基于B/S架构的后端程序在linux的Debian发行版上,本文章以本次部署遇到的问题为线索,总结如何在Debian上部署ASP.NET Core7.0WebAPI应用程序。 在linux上不依赖于Nignx等服务器部署ASP.NET Core 7.0 WebAPI 1.先决条件2.应用发布3.部…

3D可视化项目,选择unity3D还是three.js,是时候挑明了。

2023-08-10 23:07贝格前端工场 Hi,我是贝格前端工场,在开发3D可视化项目中,是选择U3D还是three,js时,很多老铁非常的迷茫,本文给老铁们讲清楚该如何选择,欢迎点赞评论分享转发。 一、Unity3D和three.js简…

[Mac软件]Adobe Substance 3D Stager 2.1.4 3D场景搭建工具

应用介绍 Adobe Substance 3D Stager,您设备齐全的虚拟工作室。在这个直观的舞台工具中构建和组装 3D 场景。设置资产、材质、灯光和相机。导出和共享媒体,从图像到 Web 和 AR 体验。 处理您的最终图像 Substance 3D Stager 可让您在上下文中做出创造性…

网络原理——HTTPS

HTTPS是 在HTTP的基础上,引入了一个加密层(SSL)。 1. 为什么需要HTTPS 在我们使用浏览器下载一些软件时,相信大家都遇到过这种情况:明明这个链接显示的是下载A软件,点击下载时就变成了B软件,这种情况是运…

计算机设计大赛 深度学习手势检测与识别算法 - opencv python

文章目录 0 前言1 实现效果2 技术原理2.1 手部检测2.1.1 基于肤色空间的手势检测方法2.1.2 基于运动的手势检测方法2.1.3 基于边缘的手势检测方法2.1.4 基于模板的手势检测方法2.1.5 基于机器学习的手势检测方法 3 手部识别3.1 SSD网络3.2 数据集3.3 最终改进的网络结构 4 最后…

深入理解Python中的JSON模块:基础大总结与实战代码解析【第102篇—JSON模块】

深入理解Python中的JSON模块:基础大总结与实战代码解析 在Python中,JSON(JavaScript Object Notation)模块是处理JSON数据的重要工具之一。JSON是一种轻量级的数据交换格式,广泛应用于Web开发、API通信等领域。本文将…

WinForms中的Timer探究:Form Timer与Thread Timer的差异

WinForms中的Timer探究:Form Timer与Thread Timer的差异 在Windows Forms(WinForms)应用程序开发中,定时器(Timer)是一个常用的组件,它允许我们执行定时任务,如界面更新、周期性数据…

osi模型,tcp/ip模型(名字由来+各层介绍+中间设备介绍)

目录 网络协议如何分层 引入 osi模型 tcp/ip模型 引入 命名由来 介绍 物理层 数据链路层 网络层 传输层 应用层 中间设备 网络协议如何分层 引入 我们已经知道了网络协议是层状结构,接下来就来了解了解下网络协议如何分层 常见的网络协议分层模型是OSI模型 和 …

windows 连接 Ubuntu 失败 -- samba服务

1. windows10连接ubuntu的时候,提示不允许一个用户使用一个以上用户名与服务器或共享资源的多重连接,中断与此服务器或共享资源的所有连接,然后再试一次 2. 换一台同事的电脑却又可以连上,我之前一直能用的,隔一段时间…

UE5 C++ 单播 多播代理 动态多播代理

一. 代理机制,代理也叫做委托,其作用就是提供一种消息机制。 发送方 ,接收方 分别叫做 触发点和执行点。就是软件中的观察者模式的原理。 创建一个C Actor作为练习 二.单播代理 创建一个C Actor MyDeligateActor作为练习 在MyDeligateAc…

【蓝桥杯】包子凑数(DP)

一.题目描述 二.输入描述 三.输出描述 四.问题分析 几个两两互质的数,最大公约数是1,最小公倍数是他们的乘积。 两个互质的数a和b最小不能表示的数就是(a-1)(b-1)-1,即,两个互质的数…

uniapp_微信小程序日历

一、需求要求这样 二、代码实现 <view class"calender" click"showriliall"><text class"lineText">探视日期&#xff1a;</text><text class"middleText">{{timerili}}</text><image src"/s…

Ubuntu服务器fail2ban的使用

作用&#xff1a;限制ssh远程登录&#xff0c;防止被人爆破服务器&#xff0c;封禁登录ip 使用lastb命令可查看到登录失败的用户及ip&#xff0c;无时无刻的不在爆破服务器 目录 一、安装fail2ban 二&#xff0c;配置fail2ban封禁ip的规则 1&#xff0c;进入目录并创建ssh…

【c++leetcode】1382. Balance a Binary Search Tree

问题入口 DSW (DAY, STOUT & WARREN) ALGORITHM 时间复杂度O(n) class Solution { public:int makeVine(TreeNode* grand, int cnt 0){auto n grand->right;while (n ! nullptr){if(n->left ! nullptr){auto old_n n;n n->left;old_n->left n->righ…

力扣hot100题解(python版18-21题)

18、矩阵置零 给定一个 *m* x *n* 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法**。** 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]]示例…

Stable Diffusion WebUI 折腾新篇章

原文&#xff1a;https://blog.iyatt.com/?p13123 1 前言 第一次玩 Stable Diffusion WebUI 是三十几天前&#xff0c;当时还在用四年半前&#xff08;大学前暑假&#xff09;买的轻薄本&#xff0c;而在半年前独显还坏了&#xff0c;所以是纯纯的用 CPU 折腾&#xff0c;刚…

【Android】View事件体系基础

文章目录 坐标系View滑动layout方法offserLeftAndRight() 和 offsetTopAndBottom()LayoutParams(布局参数)View动画scrollTo/scrollBy 解析Activity的构成 坐标系 分为Android坐标系和View坐标系 可以用 getWidth() 和 getHeight() 获取View自身的宽度和高度 对于ViewgetX() …

【c语言】内存函数

欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 目录 memcpy函数的使用和模拟实现 memcpy函数的使用 memcpy函数的模拟实现 memmove的使用和模拟实现 memmove的使用 memmove的模拟实现 memset函数的使用 memcmp函数…

pdf转word文档怎么转?分享4种转换方法

pdf转word文档怎么转&#xff1f;在日常工作中&#xff0c;我们经常遇到需要将PDF文件转换为Word文档的情况。无论是为了编辑、修改还是为了重新排版&#xff0c;将PDF转为Word都显得尤为重要。那么&#xff0c;PDF转Word文档怎么转呢&#xff1f;今天&#xff0c;就为大家分享…