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

MySQL中的free链表,flush链表,LRU链表

一、free链表

1、概述

        free链表是一个双向链表数据结构,这个free链表里,每个节点就是一个空闲的缓存页的描述数据块的地址,也就是说,只要你一个缓存页是空闲的,那么他的描述数据块就会被放入这个free链表中。 刚开始数据库启动的时候,可能所有的缓存页都是空闲的,因为此时可能是一个空的数据库,一条数据都没有,所以此时所有缓存页的描述数据块,都会被放入这个free链表中,我们看下图所示 。

 

2、free链表的数据结构

        可能有的人会以为这个描述数据块,在Buffer Pool里有一份,在free链表里也有一份,好像在内存里有两个一模一样的描述数据块,是么? 其实这么想就大错特错了。 这里要给大家讲明白一点,这个free链表,他本身其实就是由Buffer Pool里的描述数据块组成的,你可以认为是每个描述数据块里都有两个指针,一个是free_pre,一个是free_next,分别指向自己的上一个free链表的节点,以及下一个free链表的节点。 通过Buffer Pool中的描述数据块的free_pre和free_next两个指针,就可以把所有的描述数据块串成一个free链表,大家可以自己去思考一下这个问题。上面为了画图需要,所以把描述数据块单独画了一份出来,表示他们之间的指针引用关系。
        对于free链表而言,只有一个基础节点是不属于Buffer Pool的,他是40字节大小的一个节点,里面就存放了free链表的头节点的地址,尾节点的地址,还有free链表里当前有多少个节点。

3、磁盘数据缓存的过程

首先,我们需要从free链表里获取一个描述数据块,然后就可以对应的获取到这个描述数据块对应的空闲缓存页,我们看下图所示。

        接着我们就可以把磁盘上的数据页读取到对应的缓存页里去,同时把相关的一些描述数据写入缓存页的描述数据块里去,比如这个数据页所属的表空间之类的信息,最后把那个描述数据块从free链表里去除就可以了,如下图所示。

 

4、怎么知道数据页有没有被缓存

        数据库还会有一个哈希表数据结构,他会用表空间号+数据页号,作为一个key,然后缓存页的地址作为value。当你要使用一个数据页的时候,通过“ 表空间号+数据页号 ”作为key去这个哈希表里查一下,如果没有就读取数据页,如果已经有了,就说明数据页已经被缓存了。 我们看下图,又引入了一个数据页缓存哈希表的结构。
        也就是说,每次你读取一个数据页到缓存之后,都会在这个哈希表中写入一个key-value对,key就是表空间号+数据页号,value就是缓存页的地址,那么下次如果你再使用这个数据页,就可以从哈希表里直接读取出来他已经被放入一个缓存页了。

 

二、flush链表

1、概述

        你在执行增删改的时候,如果发现数据页没缓存,那么必然会基于free链表找到一个空闲的缓
存页,然后读取到缓存页里去,但是如果已经缓存了,那么下一次就必然会直接使用缓存页。
反正不管怎么样,你要更新的数据页都会在Buffer Pool的缓存页里,供你在内存中直接执行增删改的操作。
        接着你肯定会去更新Buffer Pool的缓存页中的数据,此时一旦你更新了缓存页中的数据,那么缓存页里的数据和磁盘上的数据页里的数据,是不是就不一致了? 这个时候,我们就说缓存页是脏数据,脏页。

2、哪些缓存页是脏页

        其实通过之前的学习,我们都是知道一点的,最终这些在内存里更新的脏页的数据,都是要被刷新回磁盘文件的。
        但是这里就有一个问题了,不可能所有的缓存页都刷回磁盘的,因为有的缓存页可能是因为查询的时候被读取到Buffer Pool里去的,可能根本没修改过!
        所以数据库在这里引入了另外一个跟free链表类似的flush链表 ,这个flush链表本质也是通过缓存页的描述数据块中的两个指针,让被修改过的缓存页的描述数据块,组成一个双向链表。 凡是被修改过的缓存页,都会把他的描述数据块加入到flush链表中去,flush的意思就是这些都是脏页,后续都是要flush刷新到磁盘上去的。所以flush链表的结构如下图所示,跟free链表几乎是一样的。

 

三、LRU链表

1、工作原理

        简单来说,我们看下图,假设我们从磁盘加载一个数据页到缓存页的时候,就把这个缓存页的描述数据块放到LRU链表头部去,那么只要有数据的缓存页,他都会在LRU里了,而且最近被加载数据的缓存页,都会放到LRU链表的头部去。

         然后假设某个缓存页的描述数据块本来在LRU链表的尾部,后续你只要查询或者修改了这个缓存页的数据,也要把这个缓存页挪动到LRU链表的头部去,也就是说最近被访问过的缓存页,一定在LRU链表的头部,如下图。

 

        那么这样的话,当你的缓存页没有一个空闲的时候,你是不是要找出来那个最近最少被访问的缓存页去刷入磁盘?此时你就直接在LRU链表的尾部找到一个缓存页,他一定是最近最少被访问的那个缓存页!
        然后你就把LRU链表尾部的那个缓存页刷入磁盘中,然后把你需要的磁盘数据页加载到腾出来的空闲缓存页中就可以
了!

2、冷热数据分离

        真正的LRU链表,会被拆分为两个部分,一部分是热数据,一部分是冷数据,这个冷热数据的比例是由innodb_old_blocks_pct参数控制的,他默认是37,也就是说冷数据占比37%。 个时候,LRU链表实际上看起来是下面这样子的。

3、数据页第一次被加载到缓存的时候

        数据页第一次被加载到缓存的时候,这个时候缓存页会被放在LRU链表的哪个位置呢? 实际上这个时候,缓存页会被放在冷数据区域的链表头部,我们看下面的图,也就是第一次把一个数据页加载到缓存页之后,这个缓存页实际上是被放在下图箭头的位置,也就是冷数据区域的链表头部位置。

4、冷数据区域的缓存页什么时候会被放入到热数据区域

        MySQL设定了一个规则,他设计了一个innodb_old_blocks_time参数,默认值1000,也就是1000毫秒 。也就是说,必须是一个数据页被加载到缓存页之后,在1s之后,你访问这个缓存页,他才会被挪动到热数据区域的链表头部去。
        因为假设你加载了一个数据页到缓存去,然后过了1s之后你还访问了这个缓存页,说明你后续很可能会经常要访问它,这个时间限制就是1s,因此只有1s后你访问了这个缓存页,他才会给你把缓存页放到热数据区域的链表头部去。
        所以我们看下面的图,文字说明做了一点改动,是数据加载到缓存页之后过了1s,你再访问这个缓存页,他就会被放入热数据区域的链表头部,如果是你数据刚加载到缓存页,在1s内你就访问缓存页,此时他是不会把这个缓存页放入热数据区域的头部的。

5、LRU链表的淘汰机制

        接着我们看,假设此时缓存页不够了,需要淘汰一些缓存页,此时会怎么做? 那就很简单了,直接就是可以找到LRU链表中的冷数据区域的尾部的缓存页,他们肯定是之前被加载进来的,而且加载进来1s过后都没人访问过,说明这个缓存页压根儿就没人愿意去访问他!他就是冷数据!所以此时就直接淘汰冷数据区域的尾部的缓存页,刷入磁盘,就可以了,我们看下图。

 

相关文章:

MySQL中的free链表,flush链表,LRU链表

一、free链表 1、概述 free链表是一个双向链表数据结构,这个free链表里,每个节点就是一个空闲的缓存页的描述数据块的地址,也就是说,只要你一个缓存页是空闲的,那么他的描述数据块就会被放入这个free链表中。 刚开始数…...

mac使用VsCode远程连接服务器总是自动断开并要求输入密码的解决办法

在mac中使用vscode远程连接服务器,时常会出现自动断开并要求重新输入服务器密码的问题,接下来让我们来解决它: 1、首先,在本地创建公钥: ssh-keygen 这条命令执行之后,出现提示直接回车即可;直…...

Python爬虫分布式架构 - Redis/RabbitMQ工作流程介绍

在大规模数据采集和处理任务中,使用分布式架构可以提高效率和可扩展性。本文将介绍Python爬虫分布式架构中常用的消息队列工具Redis和RabbitMQ的工作流程,帮助你理解分布式爬虫的原理和应用。 为什么需要分布式架构? 在数据采集任务中&#…...

【ES】笔记-集合介绍与API

集合是一种不允许值重复的顺序数据结构。 通过集合我们可以进行并集、交集、差集等数学运算, 还会更深入的理解如何使用 ECMAScript 2015(ES2015)原生的 Set 类。 构建数据集合 集合是由一组无序且唯一(即不能重复)的项组成的。该数据结构使用了与有限集合相同的数…...

Spring Boot(Vue3+ElementPlus+Axios+MyBatisPlus+Spring Boot 前后端分离)【五】

😀前言 本篇博文是关于Spring Boot(Vue3ElementPlusAxiosMyBatisPlusSpring Boot 前后端分离)【五】,希望你能够喜欢 🏠个人主页:晨犀主页 🧑个人简介:大家好,我是晨犀,希望我的文章…...

二、Tomcat 安装集

一、Tomcat—Docker 1. 拉取镜像 # 1、拉取镜像(tomcat版本8,jre版本8)。 docker pull tomcat:8-jre82. 启动容器 # 2、启动一个tomcat容器。 docker run -id --name tomcat -p 8080:8080 镜像ID # 3、宿主机里新建/root/tomcat目录&#x…...

CentOS 上通过 NFS 挂载远程服务器硬盘

NFS(Network File System)是一种用于在不同的计算机系统之间共享文件和目录的协议。它允许一个计算机系统将其文件系统的一部分或全部内容暴露给其他计算机系统,使其能够像访问本地文件一样访问这些内容。在这篇博客中,我们将介绍…...

微信小程序中的 广播监听事件

定义 WxNotificationCenter.js 文件; /*** author: Di (微信小程序开发工程师)* organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)* 垂直微信小程序开发交流社区* * github地址: https://github.com/icindy/WxNotificationCenter…...

Quickstart: MinIO for Linux

单节点部署教程 1.安装Minio服务端 //wget下载二进制文件 wget https://dl.min.io/server/minio/release/linux-amd64/minio //赋予权限 chmod x minio //将minio可执行文件移入usr/local/bin目录下,使得minio可以全局执行 sudo mv minio /usr/local/bin/ 2.启动Mi…...

Java中word转Pdf工具类

背景: 最近做的一个项目中,对于word转Pdf用的地方很多,特此记录 搭建总图: 代码部分: 1.需要的jar包: aspose-words-15.8.0-jdk16.jar 注:下载好这个jar包后,在项目的根目录新建一…...

【conda install】网络慢导致报错CondaHTTPError: HTTP 000 CONNECTION FAILED for url

⭐⭐问题&#xff1a; 部署安装环境经常会出现由于网络慢问题&#xff0c;导致conda安装不了库&#xff0c;报错如下&#xff1a; Solving environment: failedCondaHTTPError: HTTP 000 CONNECTION FAILED for url <https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/…...

2023-8-28 图中点的层次(树与图的广度优先遍历)

题目链接&#xff1a;图中点的层次 #include <iostream> #include <cstring> #include <algorithm>using namespace std;const int N 100010;int h[N], e[N], ne[N], idx; int n, m; int q[N], d[N];void add(int a, int b) {e[idx] b, ne[idx] h[a], h…...

设计模式(一)

1、适配器模式 &#xff08;1&#xff09;概述 适配器中有一个适配器包装类Adapter&#xff0c;其包装的对象为适配者Adaptee&#xff0c;适配器作用就是将客户端请求转化为调用适配者中的接口&#xff1b;当调用适配器中的方法时&#xff0c;适配器内部会调用适配者类的方法…...

Prometheus关于微服务的监控

在微服务架构下随着服务越来越多,定位问题也变得越来越复杂,因此监控服务的运行状态以及针对异常状态及时的发出告警也成为微服务治理不可或缺的一环。服务的监控主要有日志监控、调用链路监控、指标监控等几种类型方式,其中指标监控在整个微服务监控中比重最高,也是实际生…...

CSS实现白天/夜晚模式切换

目录 功能介绍 示例 原理 代码 优化 总结 功能介绍 在网页设计和用户体验中&#xff0c;模式切换功能是一种常见的需求。模式切换可以为用户提供不同的界面外观和布局方案&#xff0c;以适应其个人偏好或特定环境。在这篇博客中&#xff0c;我们将探索如何使用纯CSS实现一…...

selenium实现输入数字字母验证码

思路 1. 登录url 2. 获取验证码坐标 3. 根据桌标截图验证码 4. 对验证码进行识别 5. 自动输入验证码 测试代码 import os import time from io import BytesIO from PIL import Image from selenium import webdriver from selenium.webdriver.common.by import By impo…...

Docker的运用

文章目录 一、 Docker介绍二、Docker常用命令三、Docker 部署微服务项目四、Docker 使用场景五、Docker模拟场景5.1 模拟部署Nacos5.2 模拟部署Mongodb5.3 模拟部署RabbitMQ 一、 Docker介绍 Docker是一种开源软件平台&#xff0c;用于在不同的操作系统&#xff08;如Windows、…...

在项目中快速搭建机器学习的流程

在软件开发领域&#xff0c;机器学习框架发挥着关键作用&#xff0c;为开发人员提供强大的人工智能工具、库和算法&#xff0c;以有效地利用机器学习的潜力。从本质上讲&#xff0c;机器学习使计算机能够从数据中学习并做出预测或决策&#xff0c;而无需明确编程。 机器学习框…...

计网-All

路由器的功能与路由表的查看_路由器路由表_傻傻小猪哈哈的博客-CSDN博客路由基础-直连路由、静态路由与动态路由的概念_MikeVane-bb的博客-CSDN博客路由器的功能与路由表的查看_路由器路由表_傻傻小猪哈哈的博客-CSDN博客 直连路由就是路由器直接连了一个网段&#xff0c;他就…...

Rabbitmq的Federation Exchange

(broker 北京 ) &#xff0c; (broker 深圳 ) 彼此之间相距甚远&#xff0c;网络延迟是一个不得不面对的问题。有一个在北京的业务(Client 北京 ) 需要连接 (broker 北京 ) &#xff0c;向其中的交换器 exchangeA 发送消息&#xff0c;此时的网络延迟很小&#xff0c;(C…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...