MySQL缓冲池详解

news2024/9/22 23:43:37

Buffer Pool

本文参考开源项目:小林coding在线文档;

01-缓冲池概述

​ 在MySQL查询数据的时候,是通过存储引擎去磁盘做IO来获取数据库中的数据,这样每次查询一条数据都要去做一次或者多次磁盘的IO,无疑是非常慢的。而缓冲池就能非常好的解决这个问题。

当数据从磁盘中取出后,缓存内存中,下次查询同样的数据的时候,直接从内存中读取。为此,Innodb 存储引擎设计了一个缓冲池(Buffer Pool),来提高数据库的读写性能

有了缓冲池后:

  • 当读取数据时,如果数据存在于 Buffer Pool 中,客户端就会直接读取 Buffer Pool 中的数据,否则再去磁盘中读取。
  • 当修改数据时,首先是修改 Buffer Pool 中数据所在的页,然后将其页设置为脏页,最后由后台线程将脏页写入到磁盘。

在这里插入图片描述

02-缓冲池存储的内容

2.1-数据页在缓冲池中的存储

​ InnoDB 会把存储的数据划分为若干个「页」,以页作为磁盘和内存交互的基本单位,一个页的默认大小为 16KB。因此,Buffer Pool 同样需要按「页」来划分。

​ 在 MySQL 启动的时候,InnoDB 会为 Buffer Pool 申请一片连续的内存空间,然后按照默认的16KB的大小划分出一个个的页,Buffer Pool 中的页就叫做缓存页。此时这些缓存页都是空闲的,之后随着程序的运行,才会有磁盘上的页被缓存到 Buffer Pool 中。

Buffer Pool 除了缓存「索引页」和「数据页」,还包括了 undo 页,插入缓存、自适应哈希索引、锁信息等等。

在这里插入图片描述

接下来我们讨论一下数据在缓冲池中是如何存储以及处理的:

1、既然我们要在缓冲池里存储数据页,那么数据页是怎样存储的呢?

​ 在MySQL启动的时候,会申请一段连续的内存空间,缓冲池里有着许多的缓存页,而每个缓存页有唯一对应一个控制块,实际的存储情况如下图所示:

在这里插入图片描述

2、为什么上图会有空白的地方?

​ 上图中控制块和缓存页之间灰色部分称为碎片空间。每一个控制块都对应一个缓存页,那在分配足够多的控制块和缓存页后,可能剩余的那点儿空间不够一对控制块和缓存页的大小,自然就用不到喽,这个用不到的那点儿内存空间就被称为碎片了。

​ 当然,如果你把 Buffer Pool 的大小设置的刚刚好的话,也可能不会产生碎片。

2.2-缓冲池数据页的管理

2.2.1-Free链表

​ 当我们的MySQL运行了一段时间后,缓冲池中的页有空闲的也有被使用的,当读取缓冲池中没有的数据时,我们要从磁盘去读取,磁盘读取之后,需要存到缓冲池。

​ 但是此时我们读取到的数据应该放到哪个页中呢?当然是得放在空闲页中,那么我们应该如何找到空闲页呢,在MySQL缓冲池中,MySQL建立了一个Free链表,用来管理空闲的缓存页,当我们从磁盘新读到的数据,Free链表如图所示。

在这里插入图片描述

2.2.2-Flush链表

​ 当对MySQL的数据进行修改操作后,并不需要每次都将缓冲池中的页写入磁盘,因为这样效率是比较低的,当缓存页中的数据发生改变后,MySQL会将该页标识为脏页

​ 与空闲页相同,MySQL也有一个Flush链表,记录了缓冲池中所有的脏页,Flush链表中的元素都是脏页,这样将脏页写入磁盘中就不用再去遍历所有的缓存页查看是否是脏页了,直接将Flush链表中的所有对应的缓存页写入磁盘就行,Flush链表如下图所示:

在这里插入图片描述

2.2.4-LRU链表

​ MySQL为了提高缓冲池的命中率,对于一些频繁使用的数据需要将其留在缓冲池中,在MySQL中使用了LRU(最近最少使用算法),该算法会淘汰最近最少使用的页,在MySQL缓冲池中有一个LRU链表。

下图我们可以看到LRU链表有一个头指针和尾指针,一个简单的LRU算法的实现是这样的:

  • 当访问的页在 Buffer Pool 里,就直接把该页对应的 LRU 链表节点移动到链表的头部
  • 当访问的页不在Buffer Pool里时,需要先把页放在LRU链表的头部,还要将尾部的页淘汰掉

假设现在有一个LRU链表,长度为5,目前有1、2、3、4、5五个页位于LRU链表中,也就是说有五个位于缓冲池中,如图所示:

在这里插入图片描述

现在假设我们要访问页3,那么我们就会将页3移动到head的位置,如图下图所示:

在这里插入图片描述

现在假设我们要访问页8,但是页8位于磁盘中,所以此时我们要将页8加入到LRU链表中,因此我们会淘汰掉末尾的页5,如图所示:

在这里插入图片描述

2.2.5-预读失效

对于如上所示的LRU算法会有一个预读失效的问题,我们先来解释一下预读失效是什么。

在MySQL加载数据页到缓冲池中时,由于空间局部性【访问谋个数据后,接下来很可能会访问其相邻的数据】,加载磁盘中的页到内存时,会将相邻存储的页也加载到内存中,但是如果提前加载的数据接下来不会被访问,这个就叫做预读失效

预读失效导致的问题:

​ 如果使用上述的LRU算法,那么就会导致一个问题,由于预读失效,加载了不会被访问的页放在了缓冲池中,由于加载了新的页,所以会要淘汰缓冲池中存在的页,那么就会导致缓冲池中可能会被频繁访问的页被淘汰了出去,这样就会降低缓冲池命中率。

​ MySQL对于预读问题的解决方案是将LRU链表划分成young区域和old区域,young区在LRU链表的前半部分,而old区域在LRU链表的后半部分。如下图所示。

在这里插入图片描述

​ 关于young区域和old区域在LRU链表中的占比也可以通过参数设置,可以通过innodb_old_blocks_pct参数进行设置,默认值是37,代表在缓冲池中,young区域和old区域占比是63:37。

解决预读失效产生的问题,当发生预读的时候,MySQL不会将预读的数据放到young区域,而是放在old区域的head部分,只有当预读的数据被访问的时候,才会被放在young区域的head部分,

2.2.6-Buffer Pool污染

​ 上述使用LRU链表分young区和old区虽然能够解决预读失效导致的命中率下降问题,但是还存在Buffer Pool污染问题,我们先来介绍一下什么是buffer pool污染。

当一个SQL语句扫描了大量的数据的时候,在缓冲池空间比较有限的情况下,可能会将缓冲池中所有的热点数据都替换出去,等这些热点数据被再次访问的时候,由于缓存没有命中,就会产生大量磁盘IO,导致MySQL性能急剧下降,这种情况就叫Buffer Pool污染。

​ 关于Buffer Pool污染的问题,MySQL是这样处理的,进入young区域条件增加了一个停留在old区域的时间判断。具体的处理是这样的,当访问第一次old区域的某个缓存页时,在其对应的控制块中记录当前访问的时间:

  • 如果后续访问时间与第一次访问的时间在某个时间段内,那么这个缓存页不会从old区移到young区的头部
  • 如果后续访问时间与第一次访问的时间不在某个时间段内,那么就会将这个缓存页从old区域移动到young区的头部

这个时间间隔可以通过innodb_old_blocks_time控制,默认的时间是1000ms。

​ 如果在默认的情况下,只有同时满足一次以上的访问以及在old区停留超过1s两个条件,才会被从old区移动到young区的头部,这样就解决了Buffer Pool污染的问题。

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

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

相关文章

(C++23) expected 基础使用

文章目录 ⭐前言⭐expected🎛️基础使用🎛️单子操作 (Monadic operations)🎚️and_then & or_else🎚️transform & transform_error ⭐END🌟跋🌟交流方式 ⭐前言 在 C17 中,提出了 op…

量化交易backtrader实践(二)_基础加强篇(4)_交易设置与自定义绘图

这一节我们来深入实践交易的设置以及自定义绘图。 01_交易设置 参考文档: Backtrader系列教程④:交易篇(上)_backtrader撤单操作-CSDN博客量化投资之工具篇一:Backtrader从入门到精通(8)-交易…

记软件开发者画图(UML),使用WPS应用制图

目录 前言 一、什么是UML 二、使用什么画图工具 三、示例 ​四、IntelliJ IDEA 2021快速生成UML图 前言 做软件开发的从写第一个示例程序到最后写项目程序避不开的需要设计画图,所以今天我们就来梳理一下‌UML(统一建模语言)图形需要画…

《深度学习》卷积神经网络CNN 原理及其流程解析

目录 一、CNN图像原理 1、了解图像的原理 2、举例 二、CNN图像识别 1、画面不变性 2、主要表现 1)平移不变性 2)尺度不变性 3)旋转不变性 3、传统神经网络识别 1)数据预处理 2)特征提取 3)搭建神经网…

C++基础(8.继承_多态)

目录 继承: 继承的概念: 继承的定义: 基类和派生类对象赋值转换 : 继承中的作用域: 派生类的默认成员函数: 例题: ​编辑​编辑​编辑 继承与友元: 继承与静态成员&#xff1…

图片马赛克处理(Java)

1.需求 给图片的指定区域打码给整张图片打码马赛克方格取色支持中心点取色和随机取色马赛克支持灰度处理 2.源码 package com.visy.utils;import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOE…

Rabbitmq消息队列,安装,使用,三种工作模式

产品 消息队列技术介绍 消息队列概述 消息队列中间件是分布式系统中重要的组件,主要解决应用耦合、异步消息、流量削锋等问题。实现高性能、高可用、可伸缩和最终一致性架构。是大型分布式系统不可缺少的中间件。 目前在生产环境,使用较多的消息队列有…

基于51单片机的汽车倒车防撞报警器系统

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 本课题基于微控制器控制器, 设计一款汽车倒车防撞报警器系统。 要求: 要求:1.配有距离, 用于把车和障碍物之间的距离信号送入控制器。 2.配有报警系…

2024AI做PPT软件如何重塑演示文稿的创作

现在AI技术的发展已经可以帮我们写作、绘画,最近我发现了不少ai做ppt的工具!不体验不知道,原来合理使用AI工具可以有效的帮我们进行一些办公文件的编写,提高了不少工作效率。如果你也有这方面的需求就接着往下看吧。 1.笔灵AIPPT…

内网穿透out了?黑群晖+IPv6+NAS公网助手的访问体验

科技宅最带折腾黑群晖,这不,尝试一下ipv6动态域名解析,远程访问群晖NAS的方法千千万,这个方法我早就想到了,今天终于体验了一把,把经验分享一下: 目录 黑群晖的魅力 IPv6的加入:无…

Python办公自动化教程(003):PDF的加密

【1】代码 from PyPDF2 import PdfReader, PdfWriter# 读取PDF文件 pdf_reader PdfReader(./file/Python教程_1.pdf) pdf_writer PdfWriter()# 对第1页进行加密 page pdf_reader.pages[0]pdf_writer.add_page(page) # 设置密码 pdf_writer.encrypt(3535)with open(./file/P…

上位机图像处理和嵌入式模块部署(linux小系统开发)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 和若干年前相比较,现在嵌入式linux开发要简单得多。稍微贵一点的有树莓派,国产的有各种水果派,基本上都可以按照…

苍穹外卖学习日志 -----20天项目从零到完结-----含软件下载,环境配置,框架学习,代码编写,报错处理,测试联调,每日总结,心路历程等等......

年份 2024 基础:Javase Javaweb 已完结 2024 8.25---9.14 20天 Day-01 8.25 今天开始学习已经晚了,网盘下载了一下文件,做了一些开始项目的准备工作。 本来其实打算用notepad来写学习日志的,但是那个传…

如何给bat文件替换好看的图标

最近遇到软件运行在Windows系统,通过bat文件启动,但是bat文件的图标不好看,而且作为启动快捷方式放桌面看上去跟其他软件不搭调,于是得给bat文件换个软件图标。 软件ico图标 Windows系统下使用.ico文件作为软件图标。另外favicon…

go libreoffice word 转pdf

一、main.go 关键代码 完整代码 package mainimport ("fmt""github.com/jmoiron/sqlx""github.com/tealeg/xlsx""log""os/exec""path/filepath" ) import _ "github.com/go-sql-driver/mysql"import &q…

Python练习宝典:Day 1 - 选择题 - 基础知识

目录 一、踏上Python之旅二、Python语言基础三、流程控制语句四、序列的应用 一、踏上Python之旅 1.想要输出 I Love Python,应该使用()函数。 A.printf() B.print() C.println() D.Print()2.Python安装成功的标志是在控制台(终端)输入python/python3后,命令提示符变为: A.&…

数业智能心大陆:职场倦怠的新解法

什么是职业倦怠? 在职场中,职业倦怠的表现形式丰富多样。从数业智能心大陆 AI 心理咨询平台的数据来看,职业倦怠呈现出多种状态。教师可能对教学不再满怀热情,精心备课也成为过去式;情绪上容易烦躁、易怒,在…

【d47_2】【Java】【力扣】1791.找出星型图的中心节点

思路 直接判断 edges[0][0] edges[0][1] edges[1][0] edges[1][1] 谁重复了 例如&#xff1a; [ [1,2] [2,3] ....],那么中心节点一定是2 代码 class Solution {public int findCenter(int[][] edges) {for (int i0;i<1;i){if (edges[1][0]edges[0][i]) {return edg…

车载软件调试工具系列---Trace32简介UI界面简介

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…

java项目之常规应急物资管理系统(源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的常规应急物资管理系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息。 项目简介&#xff1a; 基于SpringBootVue的…