【MySQL-23】万字总结<InnoDB引擎>——【逻辑存储结果&架构(内存结构,磁盘结构,后台线程)&事务原理&MVCC】

本文主要是介绍【MySQL-23】万字总结<InnoDB引擎>——【逻辑存储结果&架构(内存结构,磁盘结构,后台线程)&事务原理&MVCC】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

大家好吖,欢迎来到 YY 滴MySQL系列 ,热烈欢迎! 本章主要内容面向接触过C++的老铁
主要内容含:
在这里插入图片描述

欢迎订阅 YY滴C++专栏!更多干货持续更新!以下是传送门!

  • YY的《C++》专栏
  • YY的《C++11》专栏
  • YY的《Linux》专栏
  • YY的《数据结构》专栏
  • YY的《C语言基础》专栏
  • YY的《单片机》专栏
  • YY的《STM32》专栏
  • YY的《数据库》专栏

这里写目录标题

  • 总结/概要
  • 一.逻辑存储结构
  • 二.架构
    • 1.内存结构
      • 1.缓冲池:Buffer Pool
      • 2.更改缓冲区:Change Buffer
      • 3.自适应哈希索引:Adaptive Hash index
      • 4.日志缓冲区:Log Buffer
    • 2.磁盘结构
      • 1.系统表空间:System Tablespace
      • 2.表的独立表空间:File-Per-Table Tablespaces
      • 3.通用表空间:GeneralTablespaces
      • 4.撤销表空间:Undo Tablespaces
      • 5.临时表空间:Temporary Tablespaces
      • 6.双写缓冲区:Doublewrite Buffer Files
      • 7.重做日志:Redo Log
    • 3.后台线程——把缓冲池信息刷新到磁盘当中
  • 三.事务原理
    • 1.事务概述
    • 2.重做日志:redolog——实现事务的持久性(物理日志)
    • 3.回滚日志:undolog——实现事务的原子性(逻辑日志)
  • 四.多版本并发控制:MVCC
    • 1.基本概念(当前读/快照读)
      • 1.记录中的隐藏字段
      • 2.undolog版本链
      • 3.读视图:readview介绍
    • 2.原理分析
      • 1.前置知识(版本链数据访问规则&不同隔离级别,生成ReadView的时机不同)【原理分析中有具体使用场景】
      • 2.底层原理分析(RC:读已提交级别)——生成ReadView
      • 3.底层原理分析(RR:可重复读级别)——生成ReadView

总结/概要

在这里插入图片描述

一.逻辑存储结构

在这里插入图片描述

二.架构

  • MySQL5.5版本开始,默认使用|nnoDB存储引擎,它擅长事务处理,具有崩溃恢复特性,在日常开发中使用非常广泛。
  • 下面是InnoDB架构图, 左侧为内存结构,右侧为磁盘结构。
  • 简单看一下,下面有具体介绍
    在这里插入图片描述

1.内存结构

InnoDB引擎的内存架构分为下面四个:

  1. 缓冲池:Buffer Pool
  2. 更改缓冲区:Change Buffer——(针对非唯一,二级索引页)
  3. 自适应哈希索引
  4. 日志缓冲区

1.缓冲池:Buffer Pool

在这里插入图片描述

2.更改缓冲区:Change Buffer

  • Change Buffer的意义
  • 在增删改查时,不用每一次直接操作磁盘IO, 先操作Change Buffer中的数据(合并处理等操作)
  • 再以一定频率把Change Buffer中的数据同步到Buffer Pool ,最后再刷新到磁盘中
    在这里插入图片描述
    在这里插入图片描述

3.自适应哈希索引:Adaptive Hash index

  • InnoDB引擎 默认不支持哈希索引 ,支持 B+树索引。
  • 前情提要,哈希索引优势是快,只需要一次匹配即可(排除哈希冲突情况下)。而B+树则需要匹配两三次。
  • 但哈希索引的局限在于,不能做范围查询,只能做等值匹配等操作
  • 所以自适应哈希索引等于是上了一层自动监控, 如果hash索引更快,他会建立哈希索引
    在这里插入图片描述

4.日志缓冲区:Log Buffer

  • 用于保存日志文件redolog,undolog
    在这里插入图片描述

2.磁盘结构

结构总览,具体解读在下面
在这里插入图片描述

1.系统表空间:System Tablespace

  • System Tablespace: 系统表空间 更改缓冲区 存储区域
  • 如果表是在系统表空间而不是每个表文件或通用表空间中创建的,它也可能包含表和索引数据。(在MySQL5.x版本中还包含InnoDB数据字典、undolog等)
    参数:innodb_data_file_path
    在这里插入图片描述

2.表的独立表空间:File-Per-Table Tablespaces

  • 取决于独立表空间的开关【参数:innodb_file_per_able】是否开启,若开启。则相关数据不会上上文所述系统表空间System Tablespace中存放
  • File-Per-Table Tablespaces:每个表的文件表空间包含单个InnoDB表的数据和索引,并存储在文件系统上的单个数据文件中
    在这里插入图片描述

3.通用表空间:GeneralTablespaces

  • 不自己创建,则没有这块表空间文件
  • GeneralTablespaces:通用表空间,需要通过CREATE TABLESPACE 语法创建通用表空间,在创建表时,可以指定该表空间。
    在这里插入图片描述

4.撤销表空间:Undo Tablespaces

  • Undo Tablespaces:撤销表空间,MySQL实例在初始化时会自动创建 两个默认的undo表空间 (初始大小16M)(图中undo_001,undo_002),用于存储undolog日志。
    在这里插入图片描述

5.临时表空间:Temporary Tablespaces

  • InnoDB 使用会话临时表空间和全局临时表空间。存储用户创建的临时表等数据
    在这里插入图片描述

6.双写缓冲区:Doublewrite Buffer Files

  • 一个中转的缓冲区, 出意外时可以通过双写缓冲区恢复数据
  • Doublewrite Buffer Files:双写缓冲区,innoDB引擎将数据页从Buffer Pool刷新到磁盘前,先将数据页写入双写缓冲区文件中,便于系统异常时恢复数据。
  • 双写缓冲区文件【.dblwr】
    在这里插入图片描述

7.重做日志:Redo Log

  • Redo Log:重做日志,是用来实现事务的持久性。不会一直保存,隔一段时间会清理没有使用的Redo Log
  • 该日志文件由两部分组成: 重做日志缓冲 (redo logbuffer)以及 重做日志文件 (redo log),前者是在内存中,后者在磁盘中。
  • 当事务提交之后会把 所有修改信息 都会存到该日志中,用于在刷新脏页到磁盘时,发生错误时,进行数据恢复使用。
  • 循环写入涉及下面两个文件
    在这里插入图片描述
    在这里插入图片描述

3.后台线程——把缓冲池信息刷新到磁盘当中

  • 后台线程主要作用:把缓冲池信息在合适的时机刷新到磁盘当中
    -

在这里插入图片描述

  • 分为4个线程
  1. Master Thread
    核心后台线程,负责调度其他线程,还负责将缓冲池中的数据异步刷新到磁盘中,保持数据的一致性还包括脏页的刷新、合并插入缓存、undo页的回收
  2. IO Thread
    在InnoDB存储引擎中大量使用了AIO来处理IO请求,这样可以极大地提高数据库的性能,而I0Thread主要负责这些IO请求的回调。
    在这里插入图片描述
  3. Purge Thread
    主要用于回收事务已经提交了的undolog,在事务提交之后,undolog可能不用了,就用它来回收。
  4. Page Cleaner Thread
    协助 Master Thread 刷新脏页到磁盘的线程,它可以减轻 Master Thread 的工作压力,减少阻塞。

三.事务原理

1.事务概述

  • 事务 是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作 作为一个整体 一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。

四大特性:

  1. 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
  2. 一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。
  3. 隔离性(lsolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
  4. 持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。

实现方式

  • 原子性,一致性,持久性 :通过 日志文件 redo log 和undo log实现
  • 隔离性 MVCC 实现

2.重做日志:redolog——实现事务的持久性(物理日志)

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

举例演示:

  1. 我们有一段update,delete操作,操作缓冲区,要去查找有无我们要更新的数据
  2. 如果没有,就通过 后台线程 ,把数据从磁盘中读到缓存池中。
  3. 我们就在缓冲区中对其中数据进行操作,此时磁盘中数据没有变更,其中的变更过的数据就称作“脏页”
  4. 变更过后的数据,经过后台线程,再刷新回磁盘。完成后,内存和磁盘中的数据都保持一致。
  5. 而脏页的数据并不是立即刷新,而是隔一段时间再刷新到磁盘中
  6. 如果此时出错,内存的数据并没有刷新到磁盘中(脏页刷新失败),但是事务已经提交成功了
  7. 此时就需要我们redo log出现了,我们会记录脏页的数据页变化,出错时就会通过其恢复
    在这里插入图片描述

3.回滚日志:undolog——实现事务的原子性(逻辑日志)

  • 回滚日志, 用于记录数据被修改前的信息 ,作用包含两个: 提供回滚 MVCC (多版本并发控制)
  • undo log和redo log记录 物理日志 不一样,它是 逻辑日志
  • 可以认为当delete一条记录时,undolog中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。当执行rollback时,就可以从undolog中的逻辑记录读取到相应的内容并进行回滚。
  • Undo log销毁相关: undolog在事务执行时产生,事务提交时,并不会立即删除undo log,因为这些日志可能还用于MVCC。
  • Undo log存储相关: undolog采用段的方式进行管理和记录,存放在前面介绍的 rollbackseqment 回滚段中,内部包含1024个undo log segment.

四.多版本并发控制:MVCC

1.基本概念(当前读/快照读)

  • 当前读:
    读取的是记录的最新版本 ,读取时还要保证其他并发事务不能修改当前记录, 会对读取的记录进行加锁。对于我们日常的操作,如:select… lock in share mode(共享锁),select … for update、update、insert、delete(排他锁)都是一种当前读。
  • 快照读:
    简单的selec(不加锁)就是快照读 ,快照读,读取的是记录数据的可见版本,有可能是历史数据,不加锁,是非阻塞读。

根据隔离级别不同,会有不同机制:

  1. Read Committed:每次select,都生成一个快照读。
  2. Repeatable Read:开启事务后第一个select语句才是快照读的地方。
  3. Serializable:快照读会退化为当前读。
  • MVCC
    全称 Multi-Version Concurrency Control,多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突,快照读为MySQL实现MVCC提供了一个非阻塞读功能。MVCC的具体实现,还需要依赖于数据库 [ 记录中的三个隐式字段、undo log日志、readView ]

1.记录中的隐藏字段

  • 我们创造完表就有如下图三个字段(绿色),InnoDB会隐式增加三个字段(灰色)
    在这里插入图片描述

2.undolog版本链

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

演示:

  1. 进行事务2时,undo log 会记录下来
    在这里插入图片描述
  2. 进行事务3时。undo log再次记录。
    在这里插入图片描述
  3. 重新定向,DB_ROLL_PTR指向0x00002,0x00002指向0x00001
    在这里插入图片描述
  4. 进行事务4时,undo log再次记录。与步骤3同理
    在这里插入图片描述

3.读视图:readview介绍

  • ReadView(读视图)是 快照读 SOL执行时 MVCC提取数据的依据 ,记录并维护系统当前活跃的事务(未提交的)id
  • ReadView中包含了四个核心字段:
  • 具体如何识别:放到下面原理分析部分实战分析

在这里插入图片描述

2.原理分析

1.前置知识(版本链数据访问规则&不同隔离级别,生成ReadView的时机不同)【原理分析中有具体使用场景】

  • 版本链数据访问规则
    在这里插入图片描述
  • 不同隔离级别,生成ReadView的时机不同
    在这里插入图片描述

2.底层原理分析(RC:读已提交级别)——生成ReadView

  • RC隔离级别下,在事务中每一次执行快照读时生成ReadView。

举例:

  1. 在当前快照读的时候,活跃的事务id(未提交的),有3,4,5——>m_ids:{3,4,5}
  2. 最小活动事务id ——>min_trx_id:3
  3. 预分配事务id(最大事务id+1)——>max_trx_id:6
  4. 创建ReadView的事务id ——>creator_trx_id:5
    在这里插入图片描述
    两次查询我们会得到如下两个ReadView (而RR可重复读级别下就只会有一个)
    在这里插入图片描述
    目前我们已知版本链&版本链数据访问规则
    在这里插入图片描述

开始分析

  • 具体方法:带着我们的记录和undo log中的记录 进行比对(逐个套用规则比对)
  • 我们记录当中DB_TRX_ID=4 ,我们拿它去 比对ReadView当中的四个核心字段
    在这里插入图片描述

在这里插入图片描述

  • 发现记录(这个版本)符合一个规则都不符合————>说明我们本次快照读,查找到的记录不是它。 我们要沿着版本链条继续往下找

  • 第二个版本中当中DB_TRX_ID=3
    在这里插入图片描述
    在这里插入图片描述

  • 比对完规则后发现满足第二个条件(3<4)——>找到版本返回

在这里插入图片描述

3.底层原理分析(RR:可重复读级别)——生成ReadView

  • RR隔离级别下,仅在事务中第一次执行快照读时生成ReadView,后续复用该ReadView。
    - 在场
  • 既然两次查询的ReadView都一样,匹配规则一样,在版本链中查找到的数据也是一样的————保证了可重复读

这篇关于【MySQL-23】万字总结<InnoDB引擎>——【逻辑存储结果&架构(内存结构,磁盘结构,后台线程)&事务原理&MVCC】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1091606

相关文章

SQL Server修改数据库名及物理数据文件名操作步骤

《SQLServer修改数据库名及物理数据文件名操作步骤》在SQLServer中重命名数据库是一个常见的操作,但需要确保用户具有足够的权限来执行此操作,:本文主要介绍SQLServer修改数据... 目录一、背景介绍二、操作步骤2.1 设置为单用户模式(断开连接)2.2 修改数据库名称2.3 查找逻辑文件名

SQL Server数据库死锁处理超详细攻略

《SQLServer数据库死锁处理超详细攻略》SQLServer作为主流数据库管理系统,在高并发场景下可能面临死锁问题,影响系统性能和稳定性,这篇文章主要给大家介绍了关于SQLServer数据库死... 目录一、引言二、查询 Sqlserver 中造成死锁的 SPID三、用内置函数查询执行信息1. sp_w

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM

Python中使用uv创建环境及原理举例详解

《Python中使用uv创建环境及原理举例详解》uv是Astral团队开发的高性能Python工具,整合包管理、虚拟环境、Python版本控制等功能,:本文主要介绍Python中使用uv创建环境及... 目录一、uv工具简介核心特点:二、安装uv1. 通过pip安装2. 通过脚本安装验证安装:配置镜像源(可

LiteFlow轻量级工作流引擎使用示例详解

《LiteFlow轻量级工作流引擎使用示例详解》:本文主要介绍LiteFlow是一个灵活、简洁且轻量的工作流引擎,适合用于中小型项目和微服务架构中的流程编排,本文给大家介绍LiteFlow轻量级工... 目录1. LiteFlow 主要特点2. 工作流定义方式3. LiteFlow 流程示例4. LiteF

canal实现mysql数据同步的详细过程

《canal实现mysql数据同步的详细过程》:本文主要介绍canal实现mysql数据同步的详细过程,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的... 目录1、canal下载2、mysql同步用户创建和授权3、canal admin安装和启动4、canal

SQL中JOIN操作的条件使用总结与实践

《SQL中JOIN操作的条件使用总结与实践》在SQL查询中,JOIN操作是多表关联的核心工具,本文将从原理,场景和最佳实践三个方面总结JOIN条件的使用规则,希望可以帮助开发者精准控制查询逻辑... 目录一、ON与WHERE的本质区别二、场景化条件使用规则三、最佳实践建议1.优先使用ON条件2.WHERE用

MySQL存储过程之循环遍历查询的结果集详解

《MySQL存储过程之循环遍历查询的结果集详解》:本文主要介绍MySQL存储过程之循环遍历查询的结果集,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言1. 表结构2. 存储过程3. 关于存储过程的SQL补充总结前言近来碰到这样一个问题:在生产上导入的数据发现

SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程

《SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程》LiteFlow是一款专注于逻辑驱动流程编排的轻量级框架,它以组件化方式快速构建和执行业务流程,有效解耦复杂业务逻辑,下面给大... 目录一、基础概念1.1 组件(Component)1.2 规则(Rule)1.3 上下文(Conte

MySQL 衍生表(Derived Tables)的使用

《MySQL衍生表(DerivedTables)的使用》本文主要介绍了MySQL衍生表(DerivedTables)的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学... 目录一、衍生表简介1.1 衍生表基本用法1.2 自定义列名1.3 衍生表的局限在SQL的查询语句select