MySQL--Buffer Pool

虽然说 MySQL 的数据是存储在磁盘里的,但是也不能每次都从磁盘里面读取数据,这样性能是极差的。为此,Innodb 存储引擎设计了一个缓冲池(Buffer Pool,来提高数据库的读写性能。

有了缓冲池后:

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

一、Buffer Pool 有多大?

Buffer Pool 是在 MySQL 启动的时候,向操作系统申请的一片连续的内存空间,默认配置下 Buffer Pool 只有 128MB 。

可以通过调整 innodb_buffer_pool_size 参数来设置 Buffer Pool 的大小,一般建议设置成可用物理内存的 60%~80%。


二、Buffer Pool 缓存什么?

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

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

为了更好的管理这些在 Buffer Pool 中的缓存页,InnoDB 为每一个缓存页都创建了一个控制块,控制块信息包括「缓存页的表空间、页号、缓存页地址、链表节点」等等。

控制块也是占有内存空间的,它是放在 Buffer Pool 的最前面,接着才是缓存页,如下图:

上图中控制块和缓存页之间灰色部分称为碎片空间。

查询一条记录,就只需要缓冲一条记录吗?

不是的。

当我们查询一条记录时,InnoDB 是会把整个页的数据加载到 Buffer Pool 中,因为,通过索引只能定位到磁盘中的页,而不能定位到页中的一条记录。将页加载到 Buffer Pool 后,再通过页里的页目录去定位到某条具体的记录。


三、如何管理 Buffer Pool?

Innodb 通过三种链表来管理缓页:

  • Free List (空闲页链表),管理空闲页;
  • Flush List (脏页链表),管理脏页;
  • LRU List,管理脏页+干净页,将最近且经常查询的数据缓存在其中,而不常查询的数据就淘汰出去。

InnoDB 对 LRU 做了一些优化,我们熟悉的 LRU 算法通常是将最近查询的数据放到 LRU 链表的头部,而 InnoDB 做 2 点优化:

  • 将 LRU 链表 分为young 和 old 两个区域,加入缓冲池的页,优先插入 old 区域;页被访问时,才进入 young 区域,目的是为了解决预读失效的问题。
  • 当**「页被访问」且「 old 区域停留时间超过 innodb_old_blocks_time 阈值(默认为1秒)」**时,才会将页插入到 young 区域,否则还是插入到 old 区域,目的是为了解决批量数据访问,大量热数据淘汰的问题。

可以通过调整 innodb_old_blocks_pct 参数,设置 young 区域和 old 区域比例。


四、脏页什么时候会被刷入磁盘?

引入了 Buffer Pool 后,当修改数据时,首先是修改 Buffer Pool 中数据所在的页,然后将其页设置为脏页,但是磁盘中还是原数据。

因此,脏页需要被刷入磁盘,保证缓存和磁盘数据一致,但是若每次修改数据都刷入磁盘,则性能会很差,因此一般都会在一定时机进行批量刷盘。

可能大家担心,如果在脏页还没有来得及刷入到磁盘时,MySQL 宕机了,不就丢失数据了吗?

这个不用担心,InnoDB 的更新操作采用的是 Write Ahead Log 策略,即先写日志,再写入磁盘,通过 redo log 日志让 MySQL 拥有了崩溃恢复能力。

下面几种情况会触发脏页的刷新:

  • 当 redo log 日志满了的情况下,会主动触发脏页刷新到磁盘;
  • Buffer Pool 空间不足时,需要将一部分数据页淘汰掉,如果淘汰的是脏页,需要先将脏页同步到磁盘;
  • MySQL 认为空闲时,后台线程会定期将适量的脏页刷入到磁盘;
  • MySQL 正常关闭之前,会把所有的脏页刷入到磁盘;

在我们开启了慢 SQL 监控后,如果你发现**「偶尔」会出现一些用时稍长的 SQL**,这可能是因为脏页在刷新到磁盘时可能会给数据库带来性能开销,导致数据库操作抖动。

如果间断出现这种现象,就需要调大 Buffer Pool 空间或 redo log 日志的大小。


五、参考

小林 coding

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Go微服务实战——metrics指标监控(Prometheus框架与Grafana可视化)

安装Prometheus 参考官网 安装完后访问http://IP:9090如下所示: 这是Prometheus自带的UI。 该地址是数据监控地址http://localhost:9090/metrics所有输出的监控项。 可以正常浏览上述信息是表示安装完成。 Promethus简介 promethus中文网 Prometheus中文文档 …

分享5款能让电脑更高效的软件

​ 你想让你的电脑更好用吗?这里有五款电脑软件可以帮你,它们可以让你的电脑更高效、美观、安全,快来看看吧! 1.远程协助——TeamViewer ​ TeamViewer是一款功能强大的远程桌面连接软件,支持跨平台操作,…

基于SSM+Jsp+Mysql的毕业生就业信息管理系统

开发语言:Java框架:ssm技术:JSPJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包…

牛客网BC-33 统计成绩(数组排序思想)

题目如下 --------------------------------------------------------------------------------------------------------------------------------- 思路:以数组形式输入,并将数组顺序(或者逆序)排序,最后输出最大值最…

静态代理与动态代理

静态代理与动态代理 静态代理 某个对象提供一个代理,代理角色固定,以控制对这个对象的访问。 代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理对象替代。代理类负责请求的预处理、过滤、将请求分派给委托类…

在项目中数据库如何优化?【MySQL主从复制(创建一个从节点复制备份数据)】【数据库读写分离ShardingJDBC(主库写,从库读)】

MySQL主从复制 MySQL主从复制介绍MySQL复制过程分成三步:1). MySQL master 将数据变更写入二进制日志( binary log)2). slave将master的binary log拷贝到它的中继日志(relay log)3). slave重做中继日志中的事件,将数据变更反映它自…

基于GA优化的CNN-LSTM-Attention的时间序列回归预测matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1卷积神经网络(CNN)在时间序列中的应用 4.2 长短时记忆网络(LSTM)处理序列依赖关系 4.3 注意力机制(Attention) 5…

JetBrains GoLand 2023---高效Go语言开发环境的首选工具【Mac/Windows】

JetBrains GoLand 2023是一款专为Go语言开发者设计的强大集成开发环境(IDE)。它提供了智能代码提示、自动补全和强大的调试工具,帮助开发者快速编写和调试Go语言代码。JetBrains GoLand 2023的功能特色主要表现在以下几个方面: 强…

万象奥科携手RT-Thread,线下体验RK3568混合部署!

3月21日,万象奥科联合RT-Thread在上海张江举办RK3568OpenAMP混合部署线下workshop,体验在一个SOC上的同时运行RT-Thread和Linux,为电力、医疗、工业控制、机器人、新能源等行业应用提供新思路。 万象奥科为伙伴们提供RK3568全功能开发板&…

flutter使用Command库调用cmd命令或者shell命令,并支持多个参数和指定文件夹目录

想要在不同的平台上运行flutter doctor命令,就需要知道对应的平台是windows还是linux,如果是windows就需要调用cmd命令,如果是linux平台,就需要调用sh命令,所以可以通过cfg!实现不同平台的判断,然后调用不同…

私人健身与教练预约管理系统设计与实现|SpringBoot+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)

本项目包含可运行源码数据库LW,文末可获取本项目的所有资料。 推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java,…

Java基础面试复习

一、java基础 1、jdk、jre、jvm的区别 jdk:Java程序开发工具包。 jre:Java程序运行环境。 jvm:Java虚拟机。 2、一个Java源文件中是否可以包含多个类有什么限制 解:可以包含多个类但是只有一个类生命成public并且要和文件名一致 …

开源鸿蒙系统调试模式屏幕截图功能如何实现

开源鸿蒙系统调试模式屏幕截图功能如何实现,适用于需要获取软件app运行界面的场景。 使用工具:鸿蒙官方hdc_std.exe jietu.bat里面内容为: set filepath/data/%date:~0,4%%date:~5,2%%date:~8,2%%time:~1,1%%time:~3,2%%time:~6,2%.jpeg ec…

[Linux]知识整理(持续更新)

前言 Linux的目录结构 Linux的目录结构是一个树型结构 Windows 系统可以拥有多个盘符, 如 C盘、D盘、E盘 Linux没有盘符这个概念, 只有一个根目录 /, 所有文件都在它下面 Linux路径的描述方式 第一章 基本命令 命令格式 例:ls –la /etc 说明: 1)个别命令使用不遵循…

力扣---最长公共子序列---二维动态规划

思想: 定义g[i][j]:text1的前i位和text2的前j位的最长公共子序列长度。递推公式:如果text[i]text[j],那么只需要看g[i-1][j-1]即可,此时g[i][j]g[i-1][j-1]1。如果text[i]!text[j],那么g[i][j]max(g[i-1][j…

Gif动图怎么快速制作?两招教你在线做

Gif动图作为一种实用的图片格式,因为其体积小,画面丰富,所以在各大聊天软件中非常的受欢迎。小伙伴们是不是很好奇这种gif动态图片是如何制作的吧!下面,小编就给大家分享两个快速制作gif动画的小技巧!不用下…

【Python机器学习系列】sklearn机器学习模型的保存---pickle法

这是我的第246篇原创文章。 一、引言 pickle是Python 的标准库,用于序列化对象。可以使用 pickle.dump()将模型保存到文件,然后使用 pickle.load()从文件中加载模型。 序列化:指将一个对象转换为字节流,能够存储在文件或网络上&…

OpenCV4.9关于矩阵上的掩码操作

返回:OpenCV系列文章目录(持续更新中......) 上一篇:如何使用OpenCV扫描图像、查找表和时间测量 下一篇:OpenCV4.9的是如何进行图像操作 引言: 矩阵上的掩码操作非常简单。这个想法是,我们根据掩码矩阵&#xff08…

PTA题解 --- 浪漫侧影(思路题解)

今天是PTA题库解法讲解的第九天,今天我们要讲解浪漫侧影,题目如下: 题解思路: 要解决这个问题,首先需要根据给定的中序遍历和后序遍历序列重建二叉树。然后,通过分别进行层序遍历的方式,记录每…

阿里CICD流水线Docker部署,将阿里镜像私仓中的镜像部署到服务器中

文章目录 阿里CICD流水线Docker部署,将阿里镜像私仓中的镜像部署到服务器中一、CICD流水线的初步使用可以看我之前的两篇文章二、添加部署任务,进行Docker部署,创建一个阿里的试用主机1、选择主机部署,并添加服务主机2、创建免费体…