MySQL的缓冲池(buffer pool)及 LRU算法

news2025/1/17 21:53:50

1.什么是缓冲池(buffer pool)

buffer pool 是数据库的一个内存组件,里面缓存了磁盘上的真实数据,Java系统对数据库的增删改操作,主要是这个内存数据结构中的缓存数据执行的。
在这里插入图片描述
控制块

  1. 存的是 数据页所属的表 空间号,数据页编号,数据页地址等信息
  2. 是放在缓存页的前面
  3. 控制块占缓冲页百分之5左右的内存大小

缓存页

1.buffer pool中存放的数据页我们叫缓存页,和磁盘上的数据页是一一对应的,都是16KB
2.缓存页的数据,是从磁盘上加载到buffer pool当中的

2. 缓冲池有什么作用

MySQL的InnoDB能使用内存会尽量的使用内存。这样是为了加速数据访问,把查询数据放在MySQL作为一个存储系统,使用缓冲池(buffer pool)机制,以避免每次查询数据都进行磁盘IO。

它的默认大小是128M。在实际的生产环境中可以通过参数innodb_buffer_pool_size对 buffer pool进行调整,一般建议设置成可用物理内存的 60%~80%。

那么在一条update语句中,缓冲池是什么作用呢?’

执行SQL语句

 update  user set name=’李四‘ where id=3

在这里插入图片描述

这条SQL语句执行流程是这样的:

  1. 在主键id这颗树上上找到id=3这一行数据
  2. 判断这一行数据页是否在内存(缓冲池)中
  3. 如果在缓冲池中,直接返回数据。不在缓冲池中,就从磁盘读入数据页。并通过LRU算法存入缓冲池
  4. 在数据页找到这一行数据,并把name改成李四
  5. 将此行数据更新到内存中。
  6. 进行两阶段提交。

在这条SQL语句中,我们可以知道MySQL它是会先从内存中读取我们的数据页,如果内存中没有数据页,我们就会在去读磁盘。

怎么知道数据页是否被缓存?

因为buffer pool内部存储它是一个hash结构。优化器会通过这张表所对应的表空间+页号计算为key,然后通过value对应的缓冲页的控制块。这样就可以通过表空间+页号找到控制块,然后通过控制块找到缓冲页了

而我们缓冲池(buffer pool)它是有固定大小的,虽然我们一页是数据是16KB。但是数据页多了,难免会把缓冲池(buffer pool)撑满,这个时候缓冲池(buffer pool)是怎么进行淘汰的呢?这个就是我们接下来要讲的MySQL的LRU算法。

3. 什么是LRU算法

LRU是Least Recently Used的缩写,即最近最少使用,选择最近最久未使用的页面予以淘汰。在InnoDB 管理 Buffer Pool 的 LRU 算法,它巧妙的使用了链表,把刚访问的数据放在链表头部,链表尾部的就是最近未被访问过的数据,予以淘汰。

在这里插入图片描述
链表头部是 P1,表示 P1 是最近刚刚被访问过的数据页;PN表示的是链表的尾部;先假设内存里只能放下这么多数据页;
在这里插入图片描述

这时候有一个读请求访问 P4,因此变成状态 2,P4 被移到最前面;
在这里插入图片描述

这次访问的数据页是p0,它不存在于链表中的,所以需要在 Buffer Pool 中新申请一个数据页 P0,加到链表头部。但是由于内存已经满了,不能申请新的内存。于是,会清空链表末尾 PN 这个数据页的内存。在存入 P0 的内容,然后放到链表头部。

这个算法有什么问题???
从算法的角度来看,这似乎没什么问题。但我们需要考虑到使用场景,为什么需要使用LRU 呢,为什么需要淘汰呢?

现在假如我们业务访问一个内存特别大、数据很多的表,这个表的内容也不是热点数据(假如是日志,或者历史数据),我们平时访问也很少。并且进行全表扫描

那么,按照这个算法扫描的话,就会把当前的 Buffer Pool 里的数据全部淘汰掉,存入扫描过程中访问到的数据页的内容。也就是说 Buffer Pool 里面主要放的是这个(日志、历史数据)表的数据。

对于一个正在做业务服务的库,这可不妙。你会看到,Buffer Pool 的内存命中率急剧下降,磁盘压力增加,SQL 语句响应变慢。

4. MySQL的LRU算法

在这里插入图片描述
在 InnoDB 实现上,按照 5:3 的比例把整个 LRU 链表分成了 young 区域和 old 区域。图中p6就是 old 区域的第一个位置,是整个链表的 5/8 处。也就是说,靠近链表头部的 5/8 是 young 区域,靠近链表尾部的 3/8 是 old 区域。

在这里插入图片描述
当我们在young区域访问数据时,假如要访问数据页 P4,由于 P4 在 young 区域,因此和优化前的 LRU 算法一样,将其移到链表头部。
在这里插入图片描述
之后要访问一个新的不存在于当前链表的数据页,这时候依然是淘汰掉数据页 P8尾部数据,但是新插入的数据页 P0,是放在old区域的头部。

处于 old 区域的数据页,每次被访问的时候都要做下面这个判断:

1.若这个数据页在 LRU 链表中存在的时间超过了 1 秒,就把它移动到链表头部;

2.如果这个数据页在 LRU 链表中存在的时间短于 1 秒,位置保持不变。1 秒这个时间,是由参数 innodb_old_blocks_time 控制的。其默认值是 1000,单位毫秒。

这个策略,就是为了处理类似全表扫描的操作量身定制的。还是以刚刚例子。现在假如我们业务访问一个内存特别大、数据很多的表,这个表的内容也不是热点数据(假如是日志,或者历史数据),我们平时访问也很少。并且进行全表扫描

1.扫描过程中,需要新插入的数据页,都被放到 old 区域 ;

2.一个数据页里面有多条记录,这个数据页会被多次访问到,但由于是顺序扫描,这个数据页第一次被访问和最后一次被访问的时间间隔不会超过 1 秒,因此还是会被保留在 old 区域;

3.再继续扫描后续的数据,之前的这个数据页之后也不会再被访问到,于是始终没有机会移到链表头部(也就是 young 区域),很快就会被淘汰出去。

5.被淘汰的页怎么处理?

什么是脏页

当内存数据页跟磁盘数据页内容不一致的时候,我们称这个内存页为“脏页”。

什么是干净页

内存数据写入到磁盘后,内存和磁盘上的数据页的内容就一致了,称为“干净页”

MySQL什么时候会刷脏页
(1)redo log满了
因为我们redo log日志是有固定空间的,如果它满了的话,就会进行刷脏页 (flush 脏页)。MySQL会先把内存数据更新到磁盘上,并把redo log进行清空。这种情况是 InnoDB所有更新会为0,因为出现这种情况的时候,整个系统就不能再接受更新了,所有的更新都必须堵住。
(2)内存满了
因为我们MySQL的缓冲池是有固定内存大小的,当我们缓冲池满了的时候,这时候也会进行刷脏页。而这时在内存中的数据会有三种类型数据页

第一种是,还没有使用的; 第二种是,使用了并且是干净页;第三种是,使用了并且是脏页。

而当要读入的数据页没有在内存的时候,就必须到缓冲池中申请一个数据页。这时候只能把最久不使用的数据页从内存中淘汰掉:如果要淘汰的是一个干净页,就直接释放出来复用;但如果是脏页呢,就必须将脏页先刷到磁盘,变成干净页后才能复用。

(3)mysql空闲的时候
这个时候就是我们MySQL比较空闲,没有请求的时候。这个时候redo log会flush 脏页,会把内存中的脏页更新到我们的磁盘里。
(4)mysql正常关闭的时候
因为我们MySQL正常关闭,肯定是要把内存脏页更新到磁盘中的。

会影响性能的刷脏页操作

1.比如我们一个查询要淘汰的脏页个数太多,如果MySQL刷脏页速度很慢,则会导致查询的响应时间明显变长;

2.redo log 写满了,导致这个系统更新为0;

6.刷脏页控制策略

1.设置系统刷脏页的速度和能力

show global variables like ‘innodb_io_capacity’; 查看当前系统刷脏页的能力

set global innodb_io_capacity=200; 进行设置刷脏页速度

2.设置脏页比例
如果我们系统一直全力去刷盘的话,那其他业务必定会受到影响。所以我们需求设置脏页比例,去执行刷盘。脏页比例默认75%,一定不要让其接近75%**
查看当前脏页比例

参数innodb_max_dirty_pages_pct是脏页比例上限,默认值是75%

select VARIABLE_VALUE into @a from performance_schema.global_status where VARIABLE_NAME = ‘Innodb_buffer_pool_pages_dirty’; select VARIABLE_VALUE into @b from performance_schema.global_status where VARIABLE_NAME = ‘Innodb_buffer_pool_pages_total’; select @a/@b;

3. 刷脏页速度 nnodb_io_capacity定义的能力乘以R%(redolog)来控制刷脏页的速度

InnoDB每次写入的日志都有一个序号,当前写入的序号跟checkpoint对应的序号之间的差值,InnoDB会将这两个值经过一定的计算得出一个数,这个结果数就是用来控制刷脏页的速度。

4. innodb_flush_neighbors=0(不开启脏页相邻淘汰) (对于机械硬盘顺序读写会有提升,ssd无提升。iops普通机械硬盘只有几百,ssd有上千,可以不开启)

在MySQL 8.0中,innodb_flush_neighbors参数的默认值已经是0了。

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

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

相关文章

MATLAB break语句

MATLAB中 break 语句用于终止 for 或 while 循环的执行,当在循环体内执行到该语句的时候,程序将会跳出循环,继续执行循环语句的下一语句。 注意:在嵌套循环中,break 退出只能在循环发生,后通过的声明控制循…

git关于创建/删除分支常用命令

主要用来介绍git中如何操作分支的命令&#xff1a; 1.git查看所有的分支: git branch -a 2.创建本地分支&#xff1a; git checkout -b <name> 3.有了本地分支之后推送到远程分支; git push origin <name> 4.切换分支&#xff1a; git checkout <name> 5.删除…

黑*头条_第5章_文章发布粉丝管理成形记

黑*头条_第5章_文章发布&粉丝管理成形记 文章目录黑*头条_第5章_文章发布&粉丝管理成形记文章发布&粉丝管理1 需求分析1.1 功能需求1.2 前端需求1.2.1 图文数据需求1.2.2 素材管理需求1.2.3 发布文章需求1.2.4 内容列表需求1.2.5 粉丝概况需求2 定义2.1 后端定义2.…

MacBook磁盘内存空间清理软件CleanMyMac2023

Mac电脑用的时间久了&#xff0c;Mac用户尤其是MacBook用户会经常收到“磁盘几乎已满”的提示&#xff0c;如何解决这个问题&#xff0c;当我们使用苹果MAC一段时间后&#xff0c;就会有大量的垃圾文件占用磁盘空间&#xff0c;例如系统缓存文件、应用程序缓存文件、备份和重复…

2022/11/18[指针] 关于指针的初步理解

先看一段利用指针交换a和b值得代码&#xff1a; #include<stdio.h> void swap(int* p1, int* p2); int main() {int a, b;int* pa, * pb;printf("enter:");scanf_s("%d%d", &a, &b);pa &a;pb &b;printf("%d,%d\n", pa,…

面试:线程池核心线程如何保持一直运行的

对于Java中 Thread 对象&#xff0c;同一个线程对象调用 start 方法后&#xff0c;会在执行完run 后走向终止&#xff08;TERMINATED&#xff09;状态&#xff0c;也就是说一个线程对象是不可以通过多次调用 start 方法重复执行 run 方法内容的。Java的线程是不允许启动两次的&…

frp内网穿透服务

参考博客&#xff1a; https://www.jianshu.com/p/19ea81efffc4 https://blog.csdn.net/yj222333/article/details/124752420 依赖于&#xff1a;Github开源软件FRP 下载地址&#xff1a;https://github.com/fatedier/frp/releases frp 主要由 客户端(frpc) 和 服务端(frps…

基于JAVA景区售票系统设计与实现 开题报告

本科生毕业论文 基于java框架springboot旅游景区景点购票系统 开题报告 学 院&#xff1a; 专 业&#xff1a; 计算机科学与技术 年 级&#xff1a; 学生姓名&#xff1a; 指导教师…

三维模型文件以及obj、ply格式文件生成pcd点云文件

方法一、三维模型文件生成obj文件 要想生成点云文件&#xff0c;要先将三维模型文件保存为obj文件格式&#xff0c;步骤如下&#xff1a; 通过SolidWorks将模型保存为stl文件格式打开SolidWorks的插件选择&#xff0c;在ScanTo3D前面打勾 在solidworks中以网格文件的形式打开…

通信算法之九十六:电力通信系统-HRF多载波通信系统-物理层收发信道开发

目录1.HRF通信系统-物理层收发信道开发1.1 SIG发射机算法功能模块1.2 SIG接收机算法功能模块1.3 PHR发射机算法功能模块1.4 PHR接收机算法功能模块1.5 PSDU发射接收机处理流程1.6前导LTF/STF序列发射接收处理流程1.7PPDU帧&#xff08;前导SIGPHRPSDU&#xff09;发射接收处理流…

阿里云服务器(Ubuntu)配置nextcloud个人网盘

tags: Ubuntu Server Linux 写在前面 最近迷恋上了云服务器的配置, 感觉云服务器能做的事情太多了, 不管是docker还是直接部署, 都是相当方便快捷的, 下面来看看在阿里云服务器配置nextcloud网盘的基本配置方法, 这里参考了一篇文章1, 写的相当详细了, 我这里只是做一些补充.…

【5G MAC】Msg1 TX开环功控介绍

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

使用python编写mqtt客户端向EMQX服务器发送数据

摘要&#xff1a;本文介绍如何用python编写一个mqtt客户端向EMQX服务器发送数据&#xff0c;实现一个简易的本地物联网服务器。 上一篇文章讲到使用mqtt.fx软件来发布消息。 (1条消息) 使用mqtt.fx向EMQX服务器发送消息_TMS320VC5257H的博客-CSDN博客https://blog.csdn.net/yo…

【树莓派不吃灰】命令篇⑦ 学习awk命令

目录awk 命令1. 基本语法2. 工作原理3. 基础实例操作3.1 把用户名和Shell打印出来3.2 找到以ssh关键字开头的所有行&#xff0c;并输出用户名和shell&#xff0c;中间以“-”分割3.3 给用户 ID加上一个常量3.4 输出第一个字段为sshd所在的行4. BEGIN END 操作4.1 基于3.2&#…

智慧仓储解决方案-最新全套文件

智慧仓储解决方案-最新全套文件一、建设背景二、思路架构三、建设方案四、获取 - 智慧仓储全套最新解决方案合集一、建设背景 仓储行业目前存在的问题 仓管员需要手动录单&#xff0c;工作量大&#xff0c;易出错&#xff0c;无法保证数据的准确率和及时性。 批次属性复杂、保…

计算机里的刻度:时钟和步进器

计算机的底层逻辑很简单&#xff0c;它们被定义为完成一些简单的事情。计算机是一个复杂系统&#xff0c;复杂的是如何规划好处理这些简单的事情的时间和步骤。本节就可以了解到计算机的时间刻度和步进器的构成&#xff0c;帮助我们进一步理解计算机的底层工作原理。 时钟是什…

redis三(3-1)

分布式缓存 基于Redis集群解决单机Redis存在的问题 单机的Redis存在四大问题 一、redis持久化 - RDB持久化 - AOF持久化1.1RDB持久化 RDB全称Redis Database Backup file&#xff08;Redis数据备份文件&#xff09;&#xff0c;也被叫做Redis数据快照。简单来说就是把内存中的…

java项目-第150期ssm网络视频播放器-java毕业设计_计算机毕业设计

java项目-第150期ssm网络视频播放器-java毕业设计_计算机毕业设计 【源码请到资源专栏下载】 今天分享的项目是《ssm网络视频播放器》 该项目分为2个角色&#xff0c;管理员、用户。 用户可以浏览前台查看视频信息、系统公告、论坛信息。 并且可以进入到个人中心查看视频信息、…

计算机毕业设计java基于javaweb+ssm+vue婚纱摄影网站

本站不同于其它摄影网站&#xff0c;本网站不但可以展示本店的摄影作品&#xff0c;更可以列出众多摄影套餐供用户选择预约&#xff0c;用户看中哪款套餐了&#xff0c;可以预约时间进行拍摄&#xff0c;即增加了店内本身的业务量&#xff0c;也方便了客户直接在线订套餐。 对于…

[附源码]计算机毕业设计JAVA基于JAVAWEB的高校实训管理系统

[附源码]计算机毕业设计JAVA基于JAVAWEB的高校实训管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a;…