Innodb Buffer Pool缓存机制(三)Innodb Buffer Pool内部组成

2024-06-06 09:36

本文主要是介绍Innodb Buffer Pool缓存机制(三)Innodb Buffer Pool内部组成,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、控制块+缓存页

  Buffer Pool中默认的缓存页大小和在磁盘上默认的页大小是一样的,都是16KB。为了更好的管理这些在Buffer Pool中的缓存页,InnoDB为每一个缓存页都创建了一些所谓的控制信息,这些控制信息包括该页所属的表空间编号、页号、缓存页在Buffer Pool中的地址、链表节点信息、一些锁信息以及LSN信息,当然还有一些别的控制信息。

  每个缓存页对应的控制信息占用的内存大小是相同的,称为控制块。控制块和缓存页是一一对应的,它们都被存放到Buffer Pool 中,其中控制块被存放到Buffer Pool的前边,缓存页被存放到Buffer Pool后边,所以整个Buffer Pool对应的内存空间看起来就是这样的:
在这里插入图片描述

注:每个控制块大约占用缓存页大小的5%,而设置的innodb_buffer_pool_size并不包含这部分控制块占用的内存空间大小,也就是说InnoDB在为Buffer Pool向操作系统申请连续的内存空间时,这片连续的内存空间一般会比innodb_buffer_pool_size的值大5%左右。

二、Free链表管理

MySQL服务在刚启动的时候,需要完成对Buffer Pool的初始化,也就是向操作系统申请Buffer Pool的存储空间,然后它们划分为若干对控制块和缓存页

但此时还没有使用,所以Buffer Pool中还没有真实的页数据,随着程序运行,就会慢慢有磁盘页数据被缓存在Buffer Pool中。

对于InnoDB来说,将磁盘页读取到Buffer Pool中有几个关键问题,即哪些缓存页是空闲,哪些缓存页已经被使用了。

缓存页对应的控制块就起了大作用,可以把所有空闲的缓存页对应的控制块作为一个节点放到一个链表中,这个链表也可以被称作free链表,或者说空闲链表。

刚完成初始化的Buffer Pool中所有的缓存页都是空闲的,所以每一个缓存页对应的控制块都会被加入到free链表中,free链表的效果图就是这样的:

在这里插入图片描述
有了这个free链表之后,每当需要从磁盘中加载一个页到Buffer Pool中时,就从free链表中取一个空闲的缓存页,并且把该缓存页对应的控制块的信息填上(就是该页所在的表空间、页号之类的信息),然后把该缓存页对应的free链表节点从链表中移除,表示该缓存页已经被使用了。

三、缓存页的哈希处理

当访问某个页的数据时,如何知道该页已经在Buffer Pool中了呢

InnoDB根据表空间号 + 页号来定位一个页,所以可以用表空间号 + 页号作为key,缓存页作为value创建一个哈希表,在需要访问某个页的数据时,先从哈希表中根据表空间号 + 页号看看有没有对应的缓存页,如果有,直接使用该缓存页就好,如果没有,那就从free链表中选一个空闲的缓存页,然后把磁盘中对应的页加载到该缓存页的位置。

四、flush链表管理

如果修改了Buffer Pool中某个缓存页的数据,那它就和磁盘上的页不一致了,这样的缓存页也被称为脏页(Dirty Page)

内存的数据修改后,要保证磁盘上的数据也同步进行修改,最简单的做法就是每发生一次修改就立即同步到磁盘上对应的页上,但是频繁的往磁盘中写数据会严重的影响程序的性能。所以每次修改缓存页后,我们并不着急立即把修改同步到磁盘上,而是在未来的某个时间点进行同步。

在同步内存数据到磁盘中时,需要知道Buffer Pool中哪些缓存页的数据发生了变化,所以同样需要一个存储脏页的链表,凡是修改过的缓存页对应的控制块都会作为一个节点加入到一个链表中,因为这个链表节点对应的缓存页都是需要被刷新到磁盘上的,所以也叫flush链表。链表的构造和free链表差不多。
在这里插入图片描述

五、LRU链表管理

Buffer Pool的大小是有限的,free链表总归有用完的时候,这个时候就涉及到缓存页淘汰的问题了,把旧的缓存页移除,然后把新的缓存页放进来。

Buffer Pool的初衷就是为了减少磁盘IO的次数,缓存命中率越高越好

所以,Buffer Pool的淘汰策略使用LRU算法,淘汰最近最少使用的缓存页,留下最近使用比较频繁的缓存页。

InnoDB为了知道哪些缓存页是最近使用的,就需要再创建一个链表,该链表使用LRU算法来淘汰缓存页,所以称为LRU链表,当访问某个页时,它的工作过程如下:

  • 如果该页不在Buffer Pool中,就把该页从磁盘加载到Buffer Pool中的缓存页时,然后把该缓存页对应的控制块作为节点塞到LRU链表的头部;
  • 如果该页已经缓存在Buffer Pool中,则直接把该页对应的控制块移动到LRU链表的头部;

只要我们使用到某个缓存页,就把该缓存页调整到LRU链表的头部,这样LRU链表尾部就是最近最少使用的缓存页。所以当Buffer Pool中的空闲缓存页使用完时,到LRU链表的尾部找些缓存页淘汰就可以了。

这种简单的LRU链表其实是有一些问题,主要与InnoDB自生的一些特性和SQL语句有关。

mysql当然不会用这样的LRU链表,它对了一下优化,详情请见下一章。

这篇关于Innodb Buffer Pool缓存机制(三)Innodb Buffer Pool内部组成的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Linux系统稳定性的奥秘:探究其背后的机制与哲学

在计算机操作系统的世界里,Linux以其卓越的稳定性和可靠性著称,成为服务器、嵌入式系统乃至个人电脑用户的首选。那么,是什么造就了Linux如此之高的稳定性呢?本文将深入解析Linux系统稳定性的几个关键因素,揭示其背后的技术哲学与实践。 1. 开源协作的力量Linux是一个开源项目,意味着任何人都可以查看、修改和贡献其源代码。这种开放性吸引了全球成千上万的开发者参与到内核的维护与优化中,形成了

Spring中事务的传播机制

一、前言 首先事务传播机制解决了什么问题 Spring 事务传播机制是包含多个事务的方法在相互调用时,事务是如何在这些方法间传播的。 事务的传播级别有 7 个,支持当前事务的:REQUIRED、SUPPORTS、MANDATORY; 不支持当前事务的:REQUIRES_NEW、NOT_SUPPORTED、NEVER,以及嵌套事务 NESTED,其中 REQUIRED 是默认的事务传播级别。

计算机组成原理——RECORD

第一章 概论 1.固件  将部分操作系统固化——即把软件永恒存于只读存储器中。 2.多级层次结构的计算机系统 3.冯*诺依曼计算机的特点 4.现代计算机的组成:CPU、I/O设备、主存储器(MM) 5.细化的计算机组成框图 6.指令操作的三个阶段:取指、分析、执行 第二章 计算机的发展 1.第一台由电子管组成的电子数字积分和计算机(ENIAC) 第三章 系统总线

设置Nginx缓存策略

详细信息 Nginx服务器的缓存策略设置方法有两种:add_header或者expires。 1. add_header 1)语法:add_header name value。 2)默认值:none。 3)使用范围:http、server、location。 配置示例如下: add_header cache-control "max-age=86400";#设置缓存时间为1天。add

【计算机组成原理】部分题目汇总

计算机组成原理 部分题目汇总 一. 简答题 RISC和CICS 简要说明,比较异同 RISC(精简指令集)注重简单快速的指令执行,使用少量通用寄存器,固定长度指令,优化硬件性能,依赖软件(如编译器)来提升效率。 CISC(复杂指令集)包含多样复杂的指令,能一条指令完成多步操作,采用变长指令,减少指令数但可能增加执行时间,倾向于硬件直接支持复杂功能减轻软件负担。 两者均追求高性能,但RISC

Spring 内部类获取不到@Value配置值问题排查(附Spring代理方式)

目录 一、实例问题 1、现象 2、原因 3、解决 二、Spring的代理模式 1、静态代理(Static Proxy) 1)原理 2)优缺点 3)代码实现 2、JDK动态代理(JDK Dynamic Proxy) 1)原理 2)优缺点 3)代码实现 3、cglib 代理(Code Generation Library Proxy) 1)原理 2)优缺点 3)代码实

多头注意力机制(Multi-Head Attention)

文章目录 多头注意力机制的作用多头注意力机制的工作原理为什么使用多头注意力机制?代码示例 多头注意力机制(Multi-Head Attention)是Transformer架构中的一个核心组件。它在机器翻译、自然语言处理(NLP)等领域取得了显著的成功。多头注意力机制的引入是为了增强模型的能力,使其能够从不同的角度关注输入序列的不同部分,从而捕捉更多层次的信息。 多头注意力机

Linux-笔记 线程同步机制

目录 前言 实现 信号量(Semaphore) 计数型信号量 二值信号量  信号量的原语操作 无名信号量的操作函数 例子 互斥锁(mutex) 互斥锁的操作函数 例子 自旋锁 (Spinlock) 自旋锁与互斥锁的区别 自旋锁的操作函数 例子 前言         线程同步是为了对共享资源的访问进行保护,确保数据的一致性,由于进程中会有多个线程的存在,

Spring 集成 RabbitMQ 与其概念,消息持久化,ACK机制

目录 RabbitMQ 概念exchange交换机机制 什么是交换机binding?Direct Exchange交换机Topic Exchange交换机Fanout Exchange交换机Header Exchange交换机RabbitMQ 的 Hello - Demo(springboot实现)RabbitMQ 的 Hello Demo(spring xml实现)RabbitMQ 在生产环境

【MyBatis学习7】MyBatis中的一级缓存

缓存的作用是减轻数据库的压力,提高数据库的性能的。mybatis中提供了一级缓存和二级缓存,先来看一下两个缓存的示意图:    从图中可以看出: 一级缓存是SqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。二级缓存是mappe