当前位置: 首页 > news >正文

MySQL缓冲池详解

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污染的问题。

相关文章:

MySQL缓冲池详解

Buffer Pool 本文参考开源项目:小林coding在线文档; 01-缓冲池概述 ​ 在MySQL查询数据的时候,是通过存储引擎去磁盘做IO来获取数据库中的数据,这样每次查询一条数据都要去做一次或者多次磁盘的IO,无疑是非常慢的。…...

【我的 PWN 学习手札】tcache stash with fastbin double free —— tcache key 绕过

参考看雪课程:PWN 探索篇 前言 tcache key 的引入使得 tcache dup 利用出现了困难。除了简单利用 UAF 覆写 key 或者House Of Karui 之外,还可以利用 ptmalloc 中的其他机制进行绕过。 一、Tcache Stash with Fastbin Double Free 之前是 double free …...

How can I stream a response from LangChain‘s OpenAI using Flask API?

题意:怎样在 Flask API 中使用 LangChain 的 OpenAI 模型流式传输响应 问题背景: I am using Python Flask app for chat over data. In the console I am getting streamable response directly from the OpenAI since I can enable streming with a f…...

什么是慢充优惠话费充值api?如何选择平台

一、话费充值api的定义 话费充值api是一种能够让开发者将话费充值功能集成到自己的平台的接口。通过接入话费充值api接口,就能够实现话费充值平台的搭建,从而为用户提供话费充值服务,这一接口主要适用于对话费充值有长期稳定需求的企业或者商…...

【MySQL 03】表的操作

目录 1.在数据库内创建表 2.表的查询 3.表的插入 往数据库中插入数据 4.表的修改 5.删除表 1.在数据库内创建表 create table 表名(字段1 字段1类型); 这样我们就创建好了一张表,我们可以进入hellosql目录下进行查看:所以在数据库内建立表&#xf…...

3、论文阅读:EnYOLO:一种基于图像增强的水下目标区域自适应实时检测框架

图像增强和目标检测的结合 前言介绍相关工作UIE 水下图像增强UOD 水下目标检测UDA 水下域自适应方法介绍训练过程推理过程网络概述多阶段训练策略Burn-In Stage(预热阶段)Mutual-Learning Stage(相互学习阶段)Domain-Adaptation Stage(领域适应阶段)多阶段训练策略算法介…...

MYSQL面试知识点手册

第一部分:MySQL 基础知识 1.1 MySQL 简介 MySQL 是世界上最流行的开源关系型数据库管理系统之一,它以性能卓越、稳定可靠和易用性而闻名。MySQL 主要应用在 Web 开发、大型互联网公司、企业级应用等场景,且广泛用于构建高并发、高可用的数据…...

排序算法的分析和应用

自己设计一个长度不小于10的乱序数组,用希尔排序,自己设定希尔排序参数 画出每一轮希尔排序的状态 自己设计一个长度不小于10的乱序数组,用堆排序,最终要生成升序数组,画出建堆后的状态 画出每一轮堆排序的状态 自…...

iptables限制网速

1、使用hashlimit来限速 #从eth0网卡进入INPUT链数据,使用模块hashlimit 限制网速为100kb/s或2mb/s,超过限制的数据包会被DROP。OUTPUT链同理,mode为srcip,有4个mode选项: srcip(默认匹配每个源地址IP,配置指定源地址…...

ALSA ubuntu 编译

1、下载tar包:alsa-lib、alsa-utils GitHub - alsa-project/alsa-lib: The Advanced Linux Sound Architecture (ALSA) - library(核心库) GitHub - alsa-project/alsa-utils: The Advanced Linux Sound Architecture (ALSA) - utilities(工具库) 2、…...

【学习笔记】SSL/TLS证书安全机制之证书透明

1、概念 CT - Certificate Transparency,证书透明 2、Trying to Solve 如果意外的 CA 为我们的域名颁发证书,我们是不可见,这就是证书透明(CT)要解决的问题 3、How CT Works 任何CA机构颁发的所有证书的公共登记处&…...

网络编程问题解答

TCP/IP是哪种模型的协议 TCP/IP 是一组通信协议的集合,它基于 TCP/IP 模型。TCP/IP 模型通常被认为是一种实用的网络通信模型,与 OSI 模型相比,TCP/IP 模型更加简洁和侧重于实际应用,被广泛应用于互联网和大多数计算机网络中。 T…...

【开源免费】基于SpringBoot+Vue.JS服装商城系统(JAVA毕业设计)

本文项目编号 T 046 ,文末自助获取源码 \color{red}{T046,文末自助获取源码} T046,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 新…...

C语言字符串学习

在C语言中,字符串(String)是字符数组(character array),并且它以空字符(\0)结束,表示字符串的结尾。我们可以通过一些常见的操作和概念来详细理解它。 1. 字符串的概念 …...

当你在Linux系统中使用MySQL命令行工具查询数据库时,如果中文显示为问号(?)或其他乱码,简单解决办法。(2)

文章目录 1、问题出现2、解决办法 1、问题出现 2、解决办法 mysql -u [username] -p --default-character-setutf8 [database_name]rootab66508d9441:/# mysql -uroot -p123456 --default-character-setutf8 tingshu_album mysql: [Warning] Using a password on the command …...

API网关之Fizz Gateway

Fizz Gateway 是一款轻量级、高性能的 API 网关,专门为服务间通信、流量控制、请求路由、鉴权与认证等需求而设计。它旨在为分布式系统和微服务架构提供高效的请求处理能力,帮助开发者构建和管理 API 服务。 核心特性 1. 请求路由 Fizz Gateway 通过强…...

pgvector docker版安装;稀疏向量使用;psycopg2 python连接使用

参看: https://cloud.tencent.com/developer/article/2359831 https://hub.docker.com/r/pgvector/pgvector/tags https://github.com/pgvector/pgvector 一、安装 拉取0.7版本 docker pull pgvector/pgvector:0.7.4-pg16运行: docker run --name pgvector -v $(pwd)/dat…...

C#命令行参数解析库System.CommandLine介绍

命令行参数 平常在日常的开发过程中,会经常用到命令行工具。如cmd下的各种命令。 以下为sc命令执行后的截图,可以看到,由于没有输入任何附带参数,所以程序并未执行任何操作,只是输出了描述和用法。 系统在创建一个新…...

CCF CSP题解:密码(key)(202409-1)

题目和思路 题目背景 西西艾弗网对用户密码有一套安全级别评定标准。 题目描述 在西西艾弗网上,用户的密码是一个由大写字母(A‐Z)、小写字母(a‐z)、数字(0‐9)和特殊字符(*和 …...

RuntimeError: Maximum Recursion Depth Exceeded - 递归深度超限的完美解决方案

RuntimeError: Maximum Recursion Depth Exceeded - 递归深度超限的完美解决方案 🛠️ RuntimeError: Maximum Recursion Depth Exceeded - 递归深度超限的完美解决方案摘要 📃引言 ✨1. 什么是递归?🔍1.1 递归的基本概念 &#x…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

逻辑回归暴力训练预测金融欺诈

简述 「使用逻辑回归暴力预测金融欺诈&#xff0c;并不断增加特征维度持续测试」的做法&#xff0c;体现了一种逐步建模与迭代验证的实验思路&#xff0c;在金融欺诈检测中非常有价值&#xff0c;本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

云原生周刊:k0s 成为 CNCF 沙箱项目

开源项目推荐 HAMi HAMi&#xff08;原名 k8s‑vGPU‑scheduler&#xff09;是一款 CNCF Sandbox 级别的开源 K8s 中间件&#xff0c;通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度&#xff0c;为容器提供统一接口&#xff0c;实现细粒度资源配额…...

VisualXML全新升级 | 新增数据库编辑功能

VisualXML是一个功能强大的网络总线设计工具&#xff0c;专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑&#xff08;如DBC、LDF、ARXML、HEX等&#xff09;&#xff0c;并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...