【MySQL进阶(三)】 InnoDB体系架构之内存池(buffer pool)

news2024/11/28 6:37:34

InnoDB体系架构之内存池

  • 一、InnoDB 体系结构
  • 二、缓冲池 buffer pool
    • 内部结构
    • free 链(管理空闲缓冲页)
      • 怎么知道数据页是否被缓存?
    • flush 链表(管理脏页)
      • 1. 脏页
      • 2. 链表结构
      • 3. 刷盘时机
    • LRU 链表(控制数据热度,淘汰策略)

一、InnoDB 体系结构

下图显示了 InnoDB 存储引擎的体系结构。

请添加图片描述
图中的内存池主要负责以下工作:

  • 维护所有进程/线程需要访问的多个内部数据结构;
  • 缓存磁盘上的数据,方便快速的读取,同时在对磁盘文件的数据修改之前在这里缓存。
  • 重做日志(redo log)缓冲。

图中的后台线程主要作用是负责刷新内存池中的数据,保证缓存池中的内存缓存是最近的数据。此外将已修改的数据文件刷新到磁盘文件中,同时保证在数据库中发生异常的情况下 InnoDB 能恢复到正常运行状态。(如:Master Thread:负责将缓存池中的数据异步刷新到磁盘;IO Thread:异步处理IO请求,提高数据库的性能

二、缓冲池 buffer pool

InnoDB 存储引擎是基于磁盘进行存储的,并将其中的记录按照页的方式进行管理。由于【磁盘速度】和【内存速度】相比根本不值一提,所以一般基于磁盘的数据库系统通常使用缓冲技术来提高数据库的整体性能。

缓冲池简单来说就是一块内存区域。在数据库中进行读取页的操作,首先将磁盘中读到的页存放到缓冲池中,这个过程称为将页【FIX】在缓冲池中。下一次再读相同的页时,首先判断是否在缓冲池中,不再的话再读取磁盘中的页。

对于 InnoDB 存储引擎而言,其缓冲池的配置是通过参数 innodb_buffer_pool_size 来设置的。

my.cnf 下的配置

在这里插入图片描述

这个数据是字节数,转换一下就是256MB。
在这里插入图片描述

内部结构

整个 buffer pool 是由缓冲页和控制块组成的:

  • 缓冲页:buffer pool 中存放的【数据页】称之为【缓冲页】,和磁盘上的数据页是一一对应的,都是16KB,缓冲页的数据,是从磁盘上加载到 buffer pool 当中的一个完整页。
  • 控制块:他是缓冲页【描述信息】,这一块区域保存的是数据页所属的表空间号,数据页编号,数据页地址,以及一些链表相关的节点信息等,每个控制块大小是缓冲页的5%左右,大约是800个字节。

其内部结构如下,buffer pool 的前一部分存储【控制块】,后一部分存储【缓冲页】,如果中间有未被利用的空间,就叫他【内存碎片】吧。

在这里插入图片描述

buffer pool 的初始化:数据库会在启动的时候,安装配置中的 buffer pool 的大小,去向操作系统申请一块内存,作为 buffer pool 的内存区域,然后会按照默认的缓存页的大小【16KB】以及对应的【800字节左右】的【控制块】的大小,在buffer pool 中划分出一个一个的缓存页和一个一个与其对应的描述数据(控制块)。此时的buffer pool 像一个干净的本子,没有书写任何内容。

free 链(管理空闲缓冲页)

InnoDB 在设计之初,将所有的【空闲的缓冲页】所对应的【控制块】作为一个个的节点,形成一个链表,这个链表就是free链,翻译过来就是空闲链表。如下图所示:

在这里插入图片描述
由上图可知,free 链表是一个双向链表,链表上除了控制块以外,还有一个基础节点,存储了free 链由多少个描述信息块,也就是由多少个空闲的缓存页,以及指向链表头尾的指针。

当我们加载数据的时候,会从free链中找到空闲的缓存页,把数据页的【表空间和数据页】号写入【控制块】。

加载数据到缓存页后,会把缓存页对应的控制块从free链表中移除。

怎么知道数据页是否被缓存?

已经有了 free 链表用来【保存空闲的页】,但是,当下一次访问时,要如何知道当前要访问的页是不是已经被缓存了,最直接的思路就是将buffer poll 里面的缓存数据【全部遍历一遍】。显然不合理。

事实上,使用【表空间号+页号】即可确定唯一的页,那就可以直接设计一个【hash表】,使用【表空间号+页号】当做key,使用【控制块地址】做value,每次查询的时候只需要将key进行查找即可,时间复杂度为O(1),这样即可快速定位到缓存的页。

大致流程如下图所示:

在这里插入图片描述

flush 链表(管理脏页)

1. 脏页

在 SQL 的执行过程中,无论是增删改查,都是优先在 buffer pool 中进行的,这样可以极大的保障执行效率。但是同样会有一个问题,假如我们对缓存页中的某些数据进行了修改(执行了一条update语句),就会导致 buffer pool 中的缓冲页和磁盘中的数据页【数据不一致】,那么此时的缓冲页就称为【脏页】。当然,这也就说明了,脏页的数据是要刷到磁盘上的。

2. 链表结构

在这里插入图片描述

  • flush 链表同样是一个双向链表,链表节点是被【修改过的缓冲页(脏页)】的控制块。
  • 和 free 链表一样,flush 链表也有一个基础结点,链接首尾结点,并存储了有多少个控制块。

3. 刷盘时机

后台会有专门的线程每隔一段时间就把 flush 链表中的脏页刷入磁盘中,刷新的速率取决于当前系统是否繁忙。在这样的机制下,万一系统崩溃,是会产生数据不一致的问题的,没有刷入磁盘的数据就会丢失,而MySQL通过日志系统解决了这个问题。(undo log 记录的是数据操作前的样子redo log 记录的是数据被操作后的样子;redo log 是 Innodb 存储引擎特有;bin log 记录的是整个操作记录)

LRU 链表(控制数据热度,淘汰策略)

buffer pool 的内存是有限的,缓存只是数据的中转站,当数据量很大以后,buffer pool 只能容纳一部分数据,当需要更多的空间缓存【新的数据页】的时候,我们需要将最近最少使用的【缓冲页淘汰掉】,这就是【LRU淘汰算法】。对InnoDB而言,则是通过【LRU链表】来完成此功能的,结构和上面的 free、flush 基本一致,只是负责的功能不一样而已。

在这里插入图片描述可以通过 show engine innodb status 语句来查看当前 InnoDB 的状态。

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

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

相关文章

blender 纹理材质

添加材质纹理需要哪五个节点? 映射节点:调整纹理的位置、大小、缩放; 纹理坐标:怎么映射,以什么方式去映射这张图,换句话说就是如何将 2D 的图片映射到 3D 的图像上;纹理坐标就是以什么坐标方式…

【学会动态规划】下降路径最小和(8)

目录 动态规划怎么学? 1. 题目解析 2. 算法原理 1. 状态表示 2. 状态转移方程 3. 初始化 4. 填表顺序 5. 返回值 3. 代码编写 写在最后: 动态规划怎么学? 学习一个算法没有捷径,更何况是学习动态规划, 跟我…

Rust学习01:D-day

以前自学过Python,开发了一些小程序,用于工作中提升效率。 Python的确好学易用,但用来做一个真正意义上的产品,哪怕是比较简单的产品,差点意思,特别是在移动端开发领域。 Rust看了两本书,准备动…

剑指offer61.扑克牌中的顺子

我的想法非常简单,就是先给数组排序,然后统计里面有几个0,然后遍历数组,如果是0或者比后面一个数小1就直接进入下一次循环,如果比后面一个数小2,就用掉一个0,0的数量减1,如果比后面的…

leetcode面试题 判断字符是否唯一

⭐️ 题目描述 🌟 leetcode链接:判断字符是否唯一 思路: a - z 的 ASCII 区间在 [97 , 122] 当中的每个减去 97 或者 a 都会变成 0 - 25,所以只需要一个数组,用当前元素减去 97 97 97 的下标来记录当前字母出现的次数…

微软、OpenAI用上“数据永动机” 合成数据是晨曦还是暮光?

微软、OpenAI、Cohere等公司已经开始测试使用合成数据来训练AI模型。Cohere首席执行官Aiden Gomez表示,合成数据可以适用于很多训练场景,只是目前尚未全面推广。 已有的(通用)数据资源似乎接近效能极限,开发人员认为&a…

volatile轻量级锁

一、背景 我们在写项目的时候,有时会使用多线程。为了保证一部分线程之间的通信,所以需要线程中的一些变量具有可见性。 说到线程可见性,对于Java而言,有两种方法实现:volatile和synchronized。 需要注意的是&#…

Python中TensorFlow的长短期记忆神经网络(LSTM)、指数移动平均法预测股票市场和可视化...

原文链接:http://tecdat.cn/?p23689 本文探索Python中的长短期记忆(LSTM)网络,以及如何使用它们来进行股市预测(点击文末“阅读原文”获取完整代码数据)。 相关视频 在本文中,你将看到如何使用…

BART模型和 Electra模型对比

总结 Electra模型在使用较少的计算资源的情况下能够达到跟大语言模型相近的效果。但BART模型对于传统的BERT中加入了不同种制造noise的方式,是BERT和GPT的结合体。Electra模型主要是Generator模型和Discriminator模型的结合体。 未知参数设置,两个模型…

【Spring Boot】事务的隔离级别与事务的传播特性详解:如何在 Spring 中使用事务?不同隔离级别的区别?

文章目录 1 事务1.1 事务简介与 mysql 中的事务使用1.2 Spring 编程式事务(手动操作)1.3 Spring 声明式事务(自动操作)1.4 Transactional 的工作原理 2 事务的隔离级别2.1 事务的四大特性及事务的隔离级别回顾2.2 Spring 事务的隔…

【Unity2D】相机移动以及设置相机边界

添加相机 添加相机时,首先需要在unity中添加 Cinemachine 包 第一次使用这个包时,需要在Package Manager中搜索并安装 安装Camera Mechine包后,添加2D Camera 设置跟随对象为Ruby (从Hierarchy中将Ruby拖动到Follow中&#xff0…

非线性质量弹簧阻尼器的神经网络仿真研究(Matlab代码Simulink仿真实现)

目录 💥1 概述 📚2 运行结果 🎉3 参考文献 🌈4 Matlab代码、Simulink仿真实现 💥1 概述 非线性质量弹簧阻尼器(Nonlinear Mass-Spring-Damper,NMSD)是一种常见的振动控制装置&#…

VS2017找不到QT头文件

一、我的电脑右键属性 - 》“高级系统设置” -》“环境变量” 增加环境变量Qt_INCLUDEPATH_ 值为QT的头文件目录 二、重启VS 发现波纹线不见了,证明设置环境变量后VS能识别到QT头文件了 原理是:vs导入qt项目附加包含目录继承值有Qt_INCLUDEPATH_

【视频的动态对比】

写在前面:本博客仅作记录学习之用,部分图片来自网络,如需引用请注明出处,同时如有侵犯您的权益,请联系删除! 文章目录 前言图像修复人脸与关键点检测修复图像修复视频 动态对比添加声音获取原视频音频融合声…

elementui全局给select option添加title属性

场景 有天边上的同事问了我一个问题,示例如下,有个数据特别长,导致下拉部分被横向撑大。希望在全局对所有的option进行处理,按照select的宽度,超出隐藏。 处理 方式一 第一眼看过去直接修改源码好了,修…

Mybatis基础模块-日志管理

文章目录 1. 适配器模式2. Log2.1 默认实现StdOutImpl2.2 Log4jImpl 3. LogFactory4. 解析配置和应用4.1 settings配置4.2 解析 5. jdbc日志5. 1 类图5.2 BaseJdbcLogger5.3 ConnectionLogger5.4 ConnectionLogger的具体应用 1. 适配器模式 适配器使接口不兼容的对象可以相互合…

用QFramework来重构 祖玛游戏

资料 Unity - 祖玛游戏 GitHub 说明 用QF一个场景就够了,在UIRoot下切换预制体达到面板切换。 但测试中当然要有一个直接跳到测试面板的 测试脚本,保留测试Scene(不然初学者也不知道怎么恢复测试Scene),所以全文按S…

SpringBoot整合Spring Security实现权限控制

文章目录 Spring Security介绍Spring Security案例1、快速搭建一个springboot工程2、导入SpringSecurity整合springboot工程3、认证3.1、登录流程校验3.2、入门案例的原理3.3、实现思路3.4、实现认证流程(自定义)3.5、正式实现3.5.1 实现数据库的校验3.5…

Linux 内核 ASoC 基本数据结构

Linux 内核 ASoC 框架建立了新的抽象,并通过一些中间层,将这些抽象接入 ALSA 音频框架。 Linux 内核 ASoC 设备驱动的结构如下图: Linux 内核 ASoC 设备驱动程序在 Linux 内核中扮演多个角色。 Linux 内核 ASoC 设备驱动程序在初始化阶段向…

MATLAB遗传算法求解带容量约束的物流配送选址问题实例

MATLAB遗传算法求解带容量约束的物流配送选址问题实例 作者:麦哥爱西芹 MATLAB遗传算法求解带容量约束物流配送中心选址问题代码实例 遗传算法编程问题实例: 在经度范围为(116, 118),纬度范围为(38, 40)的矩形区域内,散布着37个需…