InnoDB的Buffer Pool

前置概念:一个数据页16KB,一个数据页可能有多个记录,即使我们只需要访问一条记录,需要把整个数据页加载到内存中,加载到内存后不是直接释放,而是缓存到内存当中(当然对于buffer pool的缓存是在存储引擎层的发生在优化器之后,而mysql的查询缓存和buffer pool不是一个东西,查询缓存发生在最开始的时候)。

buffer pool的概念

提出buffer pool是为了缓存磁盘中的页,在mysql服务器启动的时候就向操作系统申请一片连续的内存,这一片的内存就是buffer pool,也就缓冲池。

默认情况下 buffer pooll只有128M大小,我们可以在启动服务器的时候配置innodb_buffer_pool_size参数的值。

buffer pool内部组成

buffer pool中的缓存页大小和磁盘中数据页相同16KB。

1)每个缓存页对应一个控制块,控制块是什么呢,描述缓存页的表空间编号,页号,存储也在buffer pool中的地址,一些所信息等。

2)每个缓存页对应的控制信息占用的内存大小是相同的。在mysql5.7中控制块占用808字节。

3)控制块和缓存页都存放到buffer pool中,控制块放在buffer pool的前边,缓存也放在buffer pool的后面。

free链表和flush链表

1、free链表

首先mysql服务器初始化,向操作系统申请一段连续的内存空间,然后把他划分成若干对控制块和缓存页,此刻缓存页都还没有用到。随着程序的运行会不断地有磁盘的页 被缓存到buffer pool中,那么往哪个缓存页中放呢?换句话说mysql是怎么知道哪个缓存页是空闲的呢?

链表!在存储数据的磁盘中,也就是文件系统的表空间中,管理数据页、区都是用的链表。

管理缓存页也是用链表,两个链表,一个是free链表,一个是flush链表。

顾名思义free链表中全是空闲的缓存页。另外我们呢要注意一点链表管理的是控制块,也就是说控制块作为一个节点放到链表中,控制块管理缓存页。

注意:基节点占用的不是buffer pool而是单独申请的一块内存空间。

流程:当需要从磁盘加载一个页到buffer pool中就从free链表中去一个空闲的缓存页,并且把该缓存也的控制块信息天上。之后把缓存页对应的控制块的free链表节点从链表中移除表示该缓存页已经使用了。

缓存页的哈希处理

前面说了,当我们要访问某个也的数据时,就会把该页从磁盘加载到 buffer pool,如果该页已经在buffer pool中的话就直接使用就可以了。那mysql怎么知道该页在不在buffer pool中呢?难道是遍历一遍链表,no遍历太慢。

hasn结构,我们是根据表空间号+页号定位一个页的。相当于表空间号+页号是一个key,缓存页就是对应的value。

2、flush链表

当修改了某个缓存页中的数据,那他就和磁盘的数据页不一致了,这时候的缓存页就叫脏页。

如果每一次有脏页产生就立刻同步到磁盘上对应的页上,那性能非常低。所以我们呢不着急立刻修改同步磁盘上。而是存起来,到未来的某个时间点进行同步。这个管理脏页的数据结构还是链表,flush链表中放的就是被修改的脏页。

LRU链表的管理

众所周知,buffer pool对应的内存大小是有限的,可定会满,满了就清,那怎么进行清理呢?

我们要留存的数据,必定是热点数据,或者说必须缓存命中率必须越高越好。

参考微信聊天列表,排在前面的都是频繁使用到的。排在后面的都是很久不联系的。用什么样的数据结构来维护这个“微信列表”链表呢?LRU链表

简单LRU链表介绍

最近最少使用的原则去淘汰缓存页。当我们需要访问某个页的时候,LRU链表发生了这个情况:

1)如果该页不在buffer pool,在把该页从磁盘加载到buffer pool中的缓存页时,就把该缓存页对应的控制块作为节点塞到LRU链表的头部。

2)如果该页已经在buffer pool中,直接把控制块移动到头部。

划分区域的LRU链表

上面介绍的简单LRU链表mysql并没有应用,而是使用的划分区域的LRU链表。

为什么不使用简单的LRU链表呢?简单的LRU链表有什么问题呢?两种情况不适用。

情况一:预读(还没用使用到就从磁盘读到buffer pool)

        线性预读

        如果顺序访问某个区的页面超过了innodb_read_ahead_threshold(默认为56,一个区64个页,超过54就预读下一个区的全部页面)系统变量的值,就会触发一次异步读取下一个区中全部的页面到buffer pool的请求。

        随机预读

        如果buffer pool已经缓存了某个区的13个连续的页面,不论这些页是否时顺序读取的,都会出发一次一部读取本区全部页面的buffer pool请求。

        预读的问题

        预读的页面放到了链表的头部,有很多页面可能会用不到 ,降低了缓存命中率。

情况二:全表扫描

        很好理解,全表扫描会大量读取页面,但是全表扫描发生的概率不大,所以简单LRU缓存的页没有大用,降低了缓存命中率。

总结

上面的两种情况反映出了两个问题:

1)加载到buffer pool的页不一定被用到

2)用的少的页面把热点页面挤掉。

划分LRU链表的结构

为了解决这两种情况,InnoDB把LRU量表分为两段,分别是热数据段和冷数据段。

注意:InnoDB时按照某个比例将LRU链表分为两半的,也就是说随着程序运行,某个节点的区域会发生变化。

复杂LRU链表的优化

        针对预读的优化

                其实并没有对预读进行优化,只是InnoDB规定当磁盘上的某个页面初次加载到buffer pool中的某个缓存页时,该缓存页对应的控制块会被放到old区域的头部,如果后续不进行访问,就会从old区域逐出。从而不会影响到young区域中的缓存页。

        针对全表扫描的优化

                在mysql中规定每次区页面中读取一条记录时,都算时访问一次页面,而一个页面可能 会包含很多条记录,也就是说读取完某个页面的记录就像当于访问这个页面好多次。这样按理来说young区域会被挤出很多热点数据。

                InnoDB为了解决上面的问题是这么规定的:在对某个在old区域的缓存页进行第一次访问的时候就在他对应的控制块中记录下这个访问时间,如果后续的访问时间于第一次的访问时间在某个时间间隔内,就那么该页面就不会被从old区域移动到young区域的头部,否则就会被移动到young区域的头部。

复杂LRU链表的进一步优化

        这次优化时针对young区域的缓存页进行优化的。

        young区域有一个问题,因为被经常访问,那么他会经常移动到头节点,这样的开销太大了。

        针对这个问题进行优化:

                只有被访问的缓存页位于young区域的1/4后面,才会被移动到LRU链表头部,这样能降低调整LRU链表的牝鹿,从而提升性能。换句话说,某个缓存页对应的节点在young区域的1/4中,访问也不会移动到LRU链表头部。

刷新脏页到磁盘

后台有专门的线程每隔一段时间就会把脏页刷新到磁盘,这样就可以不影响用户线程处理正常的请求。两种刷新方法:

        从LRU的冷数据中刷新一部分页面到磁盘。

                后台线程会定时从LRU链表尾部开始扫描页面,发现脏页就会刷新到磁盘。

        从flush链表中刷新一部分页面到磁盘

                后台线程也会定时从flush链表中刷新一部分页面到磁盘。刷新的速率取决于当时系统是不是很繁忙。

        思考:

        有两个线程,后台线程和用户线程。用户线程在准备加载一个磁盘也到buffer pool时没有可用的缓存页,这时候就会从LRU链表尾部直接释放掉为修改的页面,如果没有未修改的页面,就不得不将LRU链表尾部的一个脏页同步刷新到磁盘。

总结

1)InnoDB想操作系统申请一段连续的内存空间作为缓存

2)innodb_buffer_pool_size参数可以调整buffer pool的大小

3)buffer pool有两个部分,控制块和缓存页。每个控制块和缓存页都是一一对应的。

4)innodb使用了使用链表来管理buffer pool。free链表、frush链表、LRU链表。

5)链表中的节点都是控制块。

6)为了快速定位某个也是否被加载到buffer pool,使用了hash算法,使用空间号+页号作为key,缓存页作为value,建立hash表。

7)在buffer pool中修改的页面叫脏页,脏页不是立刻刷新到磁盘,而是加入到flush列表中,之后某一时刻同步刷新到磁盘

8)LRU链表分为young和old两个区域,首次加载到buffer pool的页会被放到old区域的头部,在某个时间间隔内访问该页不会移动到young区域头部,在没有可用的缓存页的时候首先会淘汰掉old区域的一些页,如果是脏页会刷新到磁盘再淘汰。

                

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

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

相关文章

若依管理系统搭建教程,ruoyi-vue环境搭建

环境部署 准备工作 JDK > 1.8 (推荐1.8版本) Mysql > 5.7.0 (推荐5.7版本) Maven > 3.0 运行系统 1、前往Gitee下载页面([https://gitee.com/y_project/RuoYi (opens new window)](https://gitee.com/y_project/RuoYi))下载解压到工作目录 2、导入到Eclipse&#…

ESP32-TCP服务端(Arduino)

将ESP32设置为TCP服务器 介绍 TCP(Transmission Control Protocol)传输控制协议,是一种面向连接的(一个客户端对应一个服务端)、可靠的传输层协议。在TCP的工作原理中,它会将消息或文件分解为更小的片段&a…

Day16 linuxC高级(存储类型 linux命令 shell命令)

文章目录 C补充标识常量存储类型1.auto // 自动型2.static:修饰变量和函数 // 静态型3.extern:外部引用4.register:寄存器类型 LinuxC高级简介:嵌入式系统(将软件嵌入到硬件里面)Linux起源查看操作系统版本内核系统架构系统关机或…

CSDN COC西安城市开发者社区2023年度线下聚会

1. 活动背景 CSDN始终致力于促进城市区域内尖端新型技术开发者交流,提供开放自由的切磋平台。在这个充满挑战和机遇的一年即将结束之际,通过本次聚会,汇聚西安本地各行各业的开发者朋友,回顾过去一年城市社区的成就和收获&#x…

Spring5系列学习文章分享---第一篇(概述+特点+IOC原理+IOC并操作之bean的XML管理操作)

目录 Spring(概述特点IOC原理IOC并操作之bean的XML管理操作)概述Spring是轻量级的开源的JavaEE框架Spring可以解决企业应用开发的复杂性Spring有两个核心部分ioc,aopSpring特点 loc(概念和原理)什么是 IOCIOC 底层原理IOC 过程图 IOC(接口&am…

MySQL的一些综合运用

一些基本的语句: USE dept_emp; CREATE TABLE dept ( deptno INT(2) NOT NULL COMMENT 部门编号, dname VARCHAR (15) COMMENT 部门名称, loc VARCHAR (20) COMMENT 地理位置 ); -- 添加主键 ALTER TABLE dept ADD PRIMARY KEY (deptno); -- 添加数据 INSE…

前端转鸿蒙的就业前景如何?有必要学鸿蒙么?

学习鸿蒙开发是否有必要,取决于多个因素: 一、个人兴趣与职业规划: 如果你对华为鸿蒙操作系统(HarmonyOS)感兴趣,并且希望将这个平台作为你的职业发展的方向,那么学习鸿蒙开发是非常有意义的。…

MSG3D

论文在stgcn与sta-lstm基础上做的。下面讲一下里面的方法: 1.准备工作 符号。这里是对符号进行解释。 一个人体骨骼图被记为G(v,E) 图卷积: 图卷积定义 考虑一种常用于处理图像的标准卷积神经网络 (CNN)。输入是像素网格。每个像素都有一个数据值向…

x-cmd pkg | speedtest-cli - 网络速度测试工具

目录 简介首次用户功能特点竞品和相关作品进一步探索 简介 speedtest-cli 是一个网络速度测试工具,用于测试计算机或服务器与速度测试服务器之间的网络连接速度。 它使用 speedtest.net 测试互联网带宽,可以帮助用户获取网络的上传和下载速度、延迟等参…

【复现】SpringBlade SQL 注入漏洞_22

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一: 四.修复建议: 五. 搜索语法: 六.免责声明 一.概述 SpringBlade 是由一个商业级项目升级优化而来的SpringCloud微服务架构,采用Java8 API重构了业务代码,完全…

【C++初阶】第二站:类与对象(上) -- 下部分

前言: 本章知识点: 类对象模型、 this 指针 专栏: C初阶 目录 类对象模型 如何计算类对象的大小 类对象的存储方式猜测 结构体内存对齐规则 this指针 this指针的引出 this指针的特性 C语言和C实现Stack的对比 C语言实现 C实现 类对象模型 …

动态规划——炮兵回城【集训笔记】

题目描述 游戏盘面是一个m行n列的方格矩阵,将每个方格用坐标表示,行坐标从下到上依次递增,列坐标从左至右依次递增,左下角方格的坐标为(1,1),则右上角方格的坐标为(m,n)。 游戏结束盘上只剩下一枚炮兵没有回到城池中&a…

ERP系统哪个好用?用友,金蝶,ORACLE,SAP综合测评

ERP系统哪个好用?用友,金蝶,ORACLE,SAP综合测评 ERP领域SAP、ORACLE相对于国内厂商如用友、金蝶优势在哪? SAP,ORACLE操作习惯一般国人用不惯;相对于国产软件,界面也很难看&#x…

AlmaLinux 9.3 安装图解

风险告知 本人及本篇博文不为任何人及任何行为的任何风险承担责任,图解仅供参考,请悉知!本次安装图解是在一个全新的演示环境下进行的,演示环境中没有任何有价值的数据,但这并不代表摆在你面前的环境也是如此。生产环境…

Android学习之路(22) 从模块化到组件化

从模块化到组件化 一、从模块化到组件化 Android 应用项目 , 都存在一个应用模块 ( Application Module ) , 在 build.gradle 构建脚本中 , 第一个插件配置 com.android.application , 表明 该 Module 编译打包后的输出是 APK 安装包 ; 该项目可以直接运行 ; plugins {id co…

React进阶 - 11( 说一说 PropTypes 和 DefaultProps )

本章内容 目录 PropTypesDefaultProps 截止到上一节的内容,我们使用了一个 TodoList的案例,大概了解了 React的一些入门知识。从本节内容开始,我们将进入React进阶知识的学习 PropTypes 在组件拆分时,我们知道每个组件都有自己的…

AI快速构建中文文本蕴含深度学习模型-NeuronBlocks(一)

案例介绍 随着自然语言处理(NLP)领域研究的不断深入,如何让机器能够真正地理解自然语言,而不是仅简单地处理语句的表层信息,渐渐成为了许多学者面临的问题。实现对文本深层次理解,是自然语言处理研究最主要也是最重要的目的之一。…

2017-2021年中国城市数字经济指数

2017-2021年中国城市数字经济指数 1、时间:2017-2021年 2、指标:年份、城市名称、城市代码、城市分级、发展阶段、总得分、总排名、总排名变更、数据及信息化基础设施得分、数据及信息化基础设施排名、数据及信息化基础设施排名变更、城市服务得分、城…

c++:string相关的oj题(把字符串转换成整数、344.反转字符串、387. 字符串中的第一个唯一字符、917. 仅仅反转字母)

文章目录 1.把字符串转换成整数题目详情代码思路 2. 344.反转字符串题目详情代码1思路1代码2思路 3. 387. 字符串中的第一个唯一字符题目详情代码思路 4. 917. 仅仅反转字母题目详情代码思路 1.把字符串转换成整数 传送门 题目详情 代码 class Solution { public:int StrToI…

详解SpringCloud微服务技术栈:一文速通RabbitMQ,入门到实践

👨‍🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习 🌌上期文章:详解SpringCloud微服务技术栈:DockerCompose部署微服务集群 📚订阅专栏:微服务技术全家桶 希…