第73讲:深入理解MySQL数据库InnoDB存储引擎:内存结构、磁盘结构与后台线程全面解析

文章目录

    • 1.InnoDB存储引擎的架构
    • 2.InnoDB存储引擎的内存结构
      • 2.1.Buffer Pool缓冲池
      • 2.2.Change Buffer更改缓冲区
      • 2.3.自适应Hash索引
      • 2.4.Log Buffer日志缓冲区
    • 3.InnoDB存储引擎的磁盘结构
      • 3.1.System Tablespace系统表空间
      • 3.2.File-Per-Table Tablespaces每个表都有单独的表空间
      • 3.3.General Tablespaces通用表空间
      • 3.4.Undo Tablespaces撤销表空间
      • 3.5.Temporary Tablespaces临时表空间
      • 3.6.Doublewrite Buffer Files双写缓冲区
      • 3.7.Redo Log重做日志
    • 4.InnoDB存储引擎的后台线程
      • 4.1.Master Thread核心后台线程
      • 4.2.IO Thread IO线程
      • 4.3.Purge Thread回收undo log的线程
      • 4.4.Page Cleaner Thread协助后台线程刷新脏页到磁盘的线程
    • 5.InnoDB的存储引擎的架构连贯

1.InnoDB存储引擎的架构

在MySQL5.5版本之后,默认使用InnoDB作为数据库存储引擎,它擅长事务的处理,具有崩溃恢复的特性,在日常的开发中使用最为广泛。

在InnoDB存储引擎的架构中,由两部分主要组成,分别是内存结构(IN-Memory Structures)和磁盘结构(ON-Disk Structures)。

image-20220623230441277

2.InnoDB存储引擎的内存结构

在InnoDB存储引擎的内存结构中,主要分为四大部分:Buffer Pool(缓冲池)、Change Buffer(更改缓冲区)、Adaptive Hash Index(自适应HASH索引)、Log Buffer(日志缓冲区)。

image-20220623131249287

2.1.Buffer Pool缓冲池

内存结构中最主要的就是Buffer Pool缓冲池了,InnoDB存储引擎是基于磁盘文件存储数据的,访问磁盘的效率和访问内存的效率,两者之间的速度相差是非常大的,为了尽可能的弥补磁盘和内存之间I/O效率差值,通常情况下就是将磁盘中的数据加载到内存中的缓冲池里面,避免频繁访问磁盘影响磁盘I/O的性能。

Buffer Pool缓冲池是内存中的一个区域,可以缓存磁盘中经常需要被操作的数据,当执行增删改查这类操作时,会先操作缓冲池中的数据,如果缓冲池中没有数据,将会从磁盘中加载数据并缓存到缓冲池,数据在缓存池中被处理之后,再通过一定的频率刷新到磁盘中,从而减少磁盘IO,加快处理速度。

如上图所示,在缓冲池中看到有很多歌小方块,这个表示Page页,缓冲池的单位也是Page页。底层会采用链表数据结构管理所有的Page页。

在缓冲池中的Page分为三种类型:(图中将每种类型的Page以不同颜色区分)

  • free page:空闲page,未被使用的页。
  • clean page:被使用的page,但是里面的数据没有被修改过。
  • dirty page:脏页,被使用的page,并且里面的数据修改过,但是还没有刷新到磁盘,与磁盘中的数据产生了不一致。

在InnoDB的缓冲池中不仅缓存了索引页和数据页,还包含了undo页、插入缓存、自适应哈希、InnoDB的锁信息等。

2.2.Change Buffer更改缓冲区

Change Buffer是更改缓冲区,主要是针对二级索引打造的,当执行DML增删改的语句时,如果操作的数据Page页没有在Buffer Pool缓冲池中,那么不会直接从操作磁盘中的数据,而是将数据变更后的内容存放在更改缓冲区中。当未来被操作的数据被Buffer Pool缓冲池读取到了,此时再讲Change Buffer更改缓冲区中更改的内容与Buffer Pool中的数据进行合并回复,最后通过一定的频率,将合并后的数据刷新到磁盘中。

Change Buffer简单来说就是当DML语句操作的数据不在缓冲池时,将语句对数据更改后的内容记录在Change Buffer更改缓冲区中,然后当要操作的数据被读取到缓冲池后,再将更改缓冲区中的数据与缓冲池中的数据合并,最后刷新到磁盘。

我们来思考一下,Change Buffer更改缓冲区有什么作用呢?当Buffer缓冲池没有数据时,直接读取磁盘的数据进行更不行吗?当然是不行的,因为二级索引通常都是非唯一的,并也是以相对随机的顺序写入到二级索引中,同样当删除和更新时,就会影响索引结构中不相邻的二级索引页,如果每次更改数据都直接操作磁盘,那么也会造成大量的磁盘I/O消耗,从而影响性能。

2.3.自适应Hash索引

自适应Hash索引主要是用来优化Buffer Pool缓冲池中的数据查询的,MySQL的InnoDB不支持Hash索引数据结构,Hash索引结构中等值匹配的检索效率远远超过B+Tree,因为Hash索引只需要一次IO就可以检索到数据,而B+Tree则需要多次匹配,所以Hash索引的效率要远超B+Tree。

虽然InnoDB不支持Hash索引的数据结构,但是却提供了自适应H时候索引的功能,在进行等值匹配时,依然可以具备Hash索引的效率。

InnoDB存储引擎会监控对表上各索引页的查询,如果观察到在特定的条件下hash索引可以提升速度,则建立hash索引,称之为自适应hash索引。

Hash不适合做范围查询和模糊匹配。

自适应哈希索引,无需人工干预,统统由系统根据情况自动判断。

通过以下命令可以看到自适应哈希有没有开启。
mysql> show variables like '%adaptive_hash_index%';
+----------------------------------+-------+
| Variable_name                    | Value |
+----------------------------------+-------+
| innodb_adaptive_hash_index       | ON    |
| innodb_adaptive_hash_index_parts | 8     |
+----------------------------------+-------+
2 rows in set (0.01 sec)

2.4.Log Buffer日志缓冲区

Log Buffer是日志缓冲区,这个日志缓冲区并不是我们理解的日志,在InnoDB存储引擎中会将要写入磁盘中的数据(redo )保存在日志缓冲区中,默认的大小为16MB,日志缓冲区的日志会定期刷新到磁盘中,如果需要更新、插入或者删除等等很多事务时,可以适当增大日志缓冲区的大小。

通过日志缓冲区可以节省磁盘I/O。

日志缓冲区可设置的参数:

  • innodb_log_buffer_size:设置缓冲区的大小
  • innodb_flush_log_at_trx_commit:日志刷新到磁盘的策略,共包含三个值:
    • 1:每次事务提交时将数据写入到日志缓冲区,并刷新到磁盘,默认值。
    • 0:每秒将数据写入到日志缓冲区并刷新到磁盘一次。
    • 2:每次事务提交时将数据写入到日志缓冲区,并且每秒刷新到磁盘一次。
mysql> show variables like 'innodb_log_buffer_size';
+------------------------+----------+
| Variable_name          | Value    |
+------------------------+----------+
| innodb_log_buffer_size | 16777216 |
+------------------------+----------+
1 row in set (0.00 sec)

mysql> show variables like 'innodb_flush_log_at_trx_commit';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1     |
+--------------------------------+-------+
1 row in set (0.00 sec)

3.InnoDB存储引擎的磁盘结构

磁盘结构主要分为七个部分,分别是System Tablespace(系统表空间)、File-Per-Table Tablespaces(每个表都有单独的表空间)、General Tablespaces(通用表空间)、 Undo Tablespaces(撤销表空间)、 Temporary Tablespaces(临时表空间)、Doublewrite Buffer Files(双写缓冲区)、Redo Log(重做日志)。

image-20220623230524330

3.1.System Tablespace系统表空间

系统表空间是Change Buffer更改缓冲区的存储区域,更改缓冲区中的数据都在系统表空间中,如果MySQL系统中的表没有自己独立的表空间文件,或者也没有使用通用表空间,此时系统表空间就是该表的表空间。

系统表空间中可能会包含表和索引数据,在MySQL5.x版本中还包含InnoDB数据字典、undolog等。

查看系统表空间路径:

mysql> show variables like 'innodb_data_file_path';
+-----------------------+------------------------+
| Variable_name         | Value                  |
+-----------------------+------------------------+
| innodb_data_file_path | ibdata1:12M:autoextend |
+-----------------------+------------------------+
1 row in set (0.01 sec)

#默认的系统表空间文件是ibdata1
[root@mysql ~]# ll /var/lib/mysql/ibdata1 
-rw-r----- 1 mysql mysql 12582912 6月  21 23:49 /var/lib/mysql/ibdata1

3.2.File-Per-Table Tablespaces每个表都有单独的表空间

如果开启了Innodb_file_per_table参数后,每个表都会有独立的表空间文件,在表空间文件中包含了这张表的数据和索引。该参数默认开启。

mysql> show variables like 'innodb_file_per_table';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_file_per_table | ON    |
+-----------------------+-------+

每个表都有单独的ibd表空间文件。

image-20220623232054941

3.3.General Tablespaces通用表空间

通用表空间,可以示多张表使用一个表空间来存放数据和索引,我们可以创建一个表空间,然后再创建表的时候指定表使用哪一个通用表空间。

创建表空间的语法格式:

CREATE TABLESPACE 表空间名称 ADD DATAFILE '表空间文件路径' BEGIN = '存储引擎名称'

创建表时指定使用哪一个表空间:

CREATE TABLE xxxx TABLESPACE 表空间名称

3.4.Undo Tablespaces撤销表空间

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

[root@mysql ~]# ll /var/lib/mysql/undo_00*
-rw-r----- 1 mysql mysql 33554432 621 23:51 /var/lib/mysql/undo_001
-rw-r----- 1 mysql mysql 33554432 621 23:54 /var/lib/mysql/undo_002

3.5.Temporary Tablespaces临时表空间

InnoDB使用会话临时表空间和全局临时表空间,存储用户创建的临时表的数据。

3.6.Doublewrite Buffer Files双写缓冲区

双写缓冲区,InnoDB引擎将数据页从Buffer Pool缓冲池刷新到磁盘之前,还会将数据页写入到双写缓冲区中,便于系统异常时,可以恢复数据。

[root@mysql ~]# ll /var/lib/mysql/#ib_16384_*
-rw-r----- 1 mysql mysql  196608 6月  21 23:54 /var/lib/mysql/#ib_16384_0.dblwr
-rw-r----- 1 mysql mysql 8585216 6月  21 23:41 /var/lib/mysql/#ib_16384_1.dblwr

3.7.Redo Log重做日志

重做日志用来实现事务的持久性,该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log),前者是在内存中,后者是在磁盘中,当事务提交之后,会把所有修改的信息存放在该日志中,当刷新脏页数据到磁盘时,发送了错误,可以通过日志文件进行数据的恢复。

[root@mysql ~]# ll /var/lib/mysql/ib_logfile*
-rw-r----- 1 mysql mysql 50331648 621 23:54 /var/lib/mysql/ib_logfile0
-rw-r----- 1 mysql mysql 50331648 621 23:54 /var/lib/mysql/ib_logfile1

4.InnoDB存储引擎的后台线程

在InnoDB的后台线程中,主要分为四类:Master Thread(核心后台线程) 、IO Thread(IO线程)、Purge Thread(回收undo log的线程)、Page Cleaner Thread(协助后台线程刷新脏页到磁盘的线程)

4.1.Master Thread核心后台线程

核心后台线程主要负责调度其他的线程,还负责将缓冲池中的数据异步刷新到磁盘中,保持数据的一致性,还包括脏页的刷新、合并插入缓存、undo页的回收等。

4.2.IO Thread IO线程

在InnoDB的存储引擎中使用了大量的AIO来处理IO请求,这样可以极大的提高数据库的性能,而IO线程主要负责这些IO请求的回调。

IO线程又分为四类:

  • Read Thread:负责读操作。默认4个
  • Write Thread:负责写操作。默认4个
  • Log Thread:负责将日志缓冲区刷新到磁盘。默认1个
  • Insert Buffer Thread:负责将写缓冲区的内容刷新到磁盘。默认1个

可以通过以下命令查看InnoDB的状态信息。

show engine innodb status \G;

4.3.Purge Thread回收undo log的线程

主要用于回收undo log的线程,当事务已经提交了,undo log可能就不再使用了,如果不回收,会占用大量的磁盘空间。

4.4.Page Cleaner Thread协助后台线程刷新脏页到磁盘的线程

协助核心后台线程刷新脏页数据到磁盘的线程,可以减轻Master Thread的工作压力,减少阻塞。

5.InnoDB的存储引擎的架构连贯

在前面已经讲解了InnoDB的内存结构和磁盘结构以及后台线程,那么一起来看一下InnoDB架构到底是如何工作的。

如下图所示:用户操作数据库表中的数据时,首先在内存结构的缓冲区里找到对应的数据,如果缓冲区中没有要处理的数据,那么会从磁盘的表空间文件里加载数据到缓冲区,当我们增删改查时,都是在缓冲区里操作的,当数据处理完毕后,经过一定的频率通过一组后台线程,将数据刷新到磁盘中的表空间里,进行数据的持久化。

Undo log和Redo log中的数据会定期回收,不会一直存放在磁盘空间。

image-20220623235212782

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ROS话题通信基本操作(C++)

目录 一、发布 1、实现步骤 2、代码实例 二、接收 1、实现步骤 2、代码实例 三、配置运行 1、修改CMakeLists.txt 2、运行结果 一、发布 1、实现步骤 1.包含头文件 2.初始化 ROS 节点:命名(唯一) 3.实例化 ROS 句柄 4.实例化 发布者 对象 5.组织被发布的数据&#…

大学里面转专业介绍

目录 个人情况转专业过程中的经验分享转专业后的学习建议和心态调整转专业后的时间平衡 个人情况 信息科学与工程学院计算机科学与技术专业2019级本科生,曾从物理与微电子科学学院后转入信息科学与技术学院。学习成绩连续三年专业前10% 项目:爬虫项目、…

AIGC+医疗专题:生成式人工智能于医疗健康

今天分享的是AI系列深度研究报告:《AIGC医疗专题:生成式人工智能于医疗健康》。 (报告出品方:AREFACT) 报告共计:23页 医疗保健中生成性人工智能的崛起: 在承诺与控制之间导航 Generative Al已经历了大规…

【开源】基于Vue.js的实验室耗材管理系统

文末获取源码,项目编号: S 081 。 \color{red}{文末获取源码,项目编号:S081。} 文末获取源码,项目编号:S081。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 耗材档案模块2.2 耗材入库模块2.3 耗…

NowCoder | KY11 二叉树遍历

NowCoder | KY11 二叉树遍历 OJ链接 简单来说就是构建这个二叉树定义结构体通过递归方式根据输入的字符串构建二叉树。对于输入字符串中的每个字符&#xff0c;如果是 ‘#’ 表示空节点&#xff0c;否则创建一个新节点&#xff0c;并递归地构建左右子树。 #include <limit…

五个轻量级免费 PDF 阅读器

便携式文档格式 (PDF) 是商业中最常用的文档类型之一。它们不仅是创建精心设计的文档的更通用的解决方案&#xff0c;而且还具有交互性和安全性。因此&#xff0c;对于寻求具有专业外观的文档的企业来说&#xff0c;PDF 是理所当然的选择。 当谈到查看这些文档时&#xff0c;大…

BUU SQL COURSE 1

四 发现有登录框&#xff0c;爆破半天也爆破不出来&#xff0c;只能从别的地方下手了 F12一下 发现了一个传参 进去发现id可以传参&#xff0c;sql注入一下试试 前三个都有回显&#xff0c;当id4的时候页面没有回显了&#xff0c;正好验证 了页面 有三个新闻 当order by 3的时…

交通强国添力量 无人机巡航为何备受期待?

在高速建设交通强国的过程中&#xff0c;交通运输部海事局计划完善“陆海空天”一体化水上交通运输安全保障体系。无人机巡航系统将在提升海事船舶监管和水上搜救能力方面发挥关键作用&#xff0c;以构建更为全面的监管体系。尽管已初步建立了海事监管体系&#xff0c;但仍存在…

大佬齐聚首钢园,会碰撞出什么火花-百度APOLLO线下沙龙

陈老老老板&#x1f9d9;‍♂️ &#x1f46e;‍♂️本文专栏&#xff1a;生活&#xff08;主要讲一下自己生活相关的内容&#xff09; &#x1f934;本文简述&#xff1a;生活就像海洋,只有意志坚强的人,才能到达彼岸 &#x1f473;‍♂️上一篇文章&#xff1a; 年度总结-你觉…

接口测试详解,一篇足矣。。

本文主要分为两个部分&#xff1a; 第一部分&#xff1a;主要从问题出发&#xff0c;引入接口测试的相关内容并与前端测试进行简单对比&#xff0c;总结两者之前的区别与联系。但该部分只交代了怎么做和如何做&#xff1f;并没有解释为什么要做&#xff1f; 第二部分&#xf…

Java画爱心

Java画爱心代码&#xff0c;每个人都可以被需要 效果图 源代码 package com.example.test; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Image; import java.awt.Toolkit; import javax.swing.JFrame; class Cardioid extend…

Echarts大屏可视化_02 球体模块制作

继续跟着b站大佬pink老师学大屏可视化 球体模块制作 1.球体模块布局 HTML <div class"column"><div class"no"><div class"no-hd"><ul><li>125811</li><li>104563</li></ul></div&g…

Node-red在Windows上离线部署

Node-red在Windows上离线部署 前言 在实际项目的使用过程中&#xff0c;生产环境的服务器很多情况下是不允许使用外部网络的&#xff0c;因此&#xff0c;基于npm直接安装的模式&#xff0c;在很多情况下不适用&#xff0c;需要考虑如何将Node-red进行离线安装&#xff1b; …

RH850P1X芯片学习笔记-Overview

文章目录 Outline产品列表功能框图特点Pin和引脚功能CPU系统CPUFPU浮点运算单元中断处理保护机制指令缓存Local RAMGlobal RAM处理器间通信和相互排斥机制 操作模式中断功能DMA电源供电Reset控制单元时钟控制单元CSIH-SPIMCAN看门狗计时器系统计时器GTM通用定时器模块外设互联P…

使用python+poco+夜神模拟器进行自动化测试实例

网易最近出的一款自动化UI测试工具&#xff1a;Airtest 挺火的&#xff0c;还受到谷歌的推荐。我试着用了一下&#xff0c;感觉优缺点还是蛮明显的。对初学者来说&#xff0c;能用到的也就是图像识别的功能&#xff0c;这块做得比老牌的按键精灵弱很多。不过Airtest集合了poco框…

windows10系统下替换、修改jar中的文件并重新打包成jar文件然后运行

目录 1、jar文件简述2、问题来源3、操作步骤3.1 解压jar包3.2 替换或者更改操作3.3 重新打成jar包3.4 确认是否修改成功3.5 运行程序 附录&#xff1a;常见命令参数 1、jar文件简述 JAR 文件就是 Java Archive &#xff08; Java 档案文件&#xff09;&#xff0c;它是 Java 的…

四川柩震栩电子商务有限公司可靠吗?

作为当今互联网时代的领军者&#xff0c;抖音已经成为了一个家喻户晓的平台。而在这个平台上&#xff0c;一家名为四川柩震栩电子商务有限公司的企业也崭露头角&#xff0c;他们的电商服务正改变着整个电商行业的格局。 四川柩震栩电子商务有限公司是一家充满活力和创新精神的企…

字节跳动开源基于SD1.5的 MagicAnimate 一张照片秒变真人舞蹈视频

从今天起&#xff0c;在社交平台上看到的小姐姐舞蹈短视频很可能就是AI生成的。字节跳动新开源基于SD1.5的MagicAnimate&#xff0c;它只需要一张照片和一组动作&#xff0c;就能生成近似真人的舞蹈视频。 项目地址&#xff1a;MagicAnimate使用入口地址 Ai模型最新工具和软件a…

Linux 输入输出重定向

Linux 系统默认的输入输出有3种类型&#xff0c;分别为标准输入、标准输出、错误输出&#xff0c;并且Linux 还为这几类设备分别分配了一个所谓的文件描述符&#xff0c;如下是他们之间的对应关系。 输入输出类型文件描述符系统中设备名通常对应的物理设备标准输入设备0/dev/s…

激光SLAM:Faster-Lio 算法编译与测试

激光SLAM&#xff1a;Faster-Lio 算法编译与测试 前言编译测试离线测试在线测试 前言 Faster-LIO是基于FastLIO2开发的。FastLIO2是开源LIO中比较优秀的一个&#xff0c;前端用了增量的kdtree&#xff08;ikd-tree&#xff09;&#xff0c;后端用了迭代ESKF&#xff08;IEKF&a…