当前位置: 首页 > news >正文

Innodb内存结构

缓冲池Buffer Pool:

缓冲池是innodb内存结构缓冲区中的核心部分,在服务启动的时候服务器会向操作系统申请一块大小为128MB的内存空间,所有对数据库中数据的增删查改操作均在缓冲池bufferPool中完成,并且缓冲区中其他组件的描述信息也都存储在缓冲池中

Buffer Pool结构

缓冲池管理的最小单位是页,多个页通过一个chunk块管理,多个chunk块通过一个instance管理,呈现层级结构,如图所示
在这里插入图片描述
内存中对页的组织:
页从磁盘被加载到内存中,也需要对页进行管理,此时不能再使用页中的next_record管理内存页了,因为next_record是磁盘地址并且被加载到内存的页可能是不连续的
在不修改页的前提下innodb引入了控制块的概念用来管理内存页,简单得说就是每一个控制块有唯一对应得内存页,并且所有控制块被一个带头双向链表关联,通过遍历控制块链表就能遍历所有内存页 如图所示
在这里插入图片描述

chunk块作用

chunk 是一块连续的大内存区域,InnoDB 可以更灵活地管理不同大小的内存块,避免内存碎片。而直接管理 page 的地址,可能会导致更多的内存碎片

chunk类似于一个内存池的机制,以固定大块的空间为单位分配与释放内存空间,可以有效的降低空间申请和释放的次数,如果instance直接管理page,那么就需要page大小的堆空间频繁申请与释放,时间成本就上去了,不妨一次申请一个chunk块大小的空间(一般大小为页空间的整数倍),一段时间内就不需要申请释放了,一定程度上提高了性能

通过 chunk 管理内存,减少了对大量 page 的直接操作,简化了整体的内存管理流程。内存管理模块可以专注于管理少量的 chunk,而不是成千上万个 page
缓冲池中对页的申请和释放都是以chunk块为单位的

chunk块初始化

当缓冲区完成初始化后会把每个数据页所占用的内存空间和对应的控制块提前分配到,只不过此时控制块和数据页都是空的(未使用)
chunk块中左半部分为控制块信息,右半部分为页信息
控制块信息从左至右初始化
页信息从右至左初始化
在这里插入图片描述
第一个控制块管理第一个页,第二个控制块管理第二个页,依次类推

页管理

缓冲池中采用三个链表管理不同状态的页,三个链表分别是Free List,LRU List,Flush List
页状态分为空闲页Free,干净页Clean,脏页Dirty
顾名思义,空闲页是还没有被使用的页空间,干净页是已经有真实数据但数据未发生修改的页空间,脏页即已经发生数据修改的页空间

当读取指定页的数据时,会从Free List中取出一个空闲页,将目标页的数据拷贝到所获得的空闲页中,并把该页标记为干净页挂入LRU List,如果之后该页的数据发生了修改操作,会把该页标记为脏页挂入Flush List中,但不一定会从LRU中马上删除
LRU List采用了LRU算法对干净页和脏页进行统一管理,当达到阈值大小时,会率先淘汰掉长时间未使用的页

对于Flush List,服务器会在合适的时机对链表中的页进行统一的刷盘操作,刷盘结束后将对应的页空间归置,放入Free List中
在这里插入图片描述

变更缓冲区Change Buffer:

普通情况下对一个文件中的数据修改分为3步:
1、从磁盘中找到目标位置
2、将文件加载到内存中进行修改
3、将最新数据刷新到磁盘
作为一个数据库,修改操作肯定是比较频繁的,如果每一次修改都进行一次上述操作,那么势必会严重降低性能,因为IO的次数太多了,有效的解决办法就是将修改操作先保存到一个缓冲区中,等达到阈值时再IO,一次性批量修改,大幅度降低IO次数,这就是Change Buffer的作用

触发刷新的时机:

读取对应的数据页
系统空闲时
系统正常关闭
change buffer写满
redo log写满

修改操作存入变更缓冲区是由条件的
必须是针对二级索引数据的修改,否则不会进入变更缓冲区,因此建议为每一张表建立二级索引,并且修改时筛选条件为二级索引行
不能是主键索引的原因:主键是不可重复的,如果同一时刻新增2条主键值都为1的数据,在真正修改的时候就会发生主键冲突

自适应哈希Adaptive Hash:

根据InnoDB内部的监控机制,如果监控到某些查询通过建⽴哈希索引可以提⾼性能,则⾃动对这个⻚创建哈希索引,这个过程称为⾃适应,所以叫⾃适应哈希索引。
如果表完全放在内存中,则哈希索引可以通过直接查找任何元素来加快查询速度,为频繁使⽤的查询条件和对应的数据⻚建⽴映射关系,从⽽提升内存级别的查询效率

InnoDB存储引擎的数据存储于B+树中,B+树通常只有3到5层,但从根节点到叶节点的寻路涉及到
多层⻚⾯内记录的⽐较,即使所有路径上的⻚⾯都在内存中,也⾮常消耗CPU的资源
InnoDB对寻路的开销进⾏了优化,⽐如寻路结束后将cursor缓存起来⽅便下次查询复⽤;尽可能
的避免单词寻路开销,Adaptive hash index(AHI)便是为此⽽设计

日志缓冲区Log Buffer:

MySQL在运行过程中会产生大量需要落盘的日志,产生一条写一条肯定是不合理的,通过日志缓冲区将批量的日志统一落盘减少IO次数提高性能


http://www.mrgr.cn/news/31862.html

相关文章:

  • git撤销、回退某个commit的修改
  • 用pandoc工具实现ipynb,md,word,pdf之间的转化
  • 生成式GPT商品推荐:精准满足用户需求
  • 【软考】系统架构设计师-计算机系统基础(3):嵌入式系统
  • jenkins用户在执行scp的时候如何做免密登录
  • 学习rust语言宏之macro_rules!
  • mysql性能优化- 数据库配置优化
  • 【C++】模拟实现list
  • MySQL 中如何处理大型事务
  • 超实用线程调度方法!
  • 【算法】2022年第十三届蓝桥杯大赛软件类省赛Java大学C组真题
  • SQL优化之深度分页优化
  • linux安装nginx+前端部署vue项目(实际测试react项目也可以)
  • 模板初阶
  • 自闭症能上寄宿学校吗?了解解答与选择
  • PLC中几个电机控制电路
  • IDA Pro基本使用
  • 【Linux】简易日志系统
  • 剑指offer JZ54 二叉搜索树的第k个节点
  • python+selenium实现自动联网认证,并实现断网重连
  • 读取ply文件中的点云属性
  • vue3 TagInput 实现
  • 如何把python(.py或.ipynb)文件打包成可运行的.exe文件?
  • 毕业季,论文的开题报告对大学生来说意味着什么?
  • ESP32调用本地部署的ChatTTS
  • C++第1课——输出、变量和输入(含视频讲解)