mysql内核源代码深度解析 缓冲池 LRU模块 全面分析(bufferpool部分二)

本文深入探讨MySQL内核的缓冲池LRU模块,包括LRU链表结构、基础算法、功能分类及核心函数调用主线。通过对LRU组件的分析,揭示了LRU在缓存管理、页面淘汰、分配与释放中的作用,为进一步理解MySQL缓冲池工作原理打下基础。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

老刘原创文章,优快云首发!转载请注明出处。

LRU模块组件

(1)LRU整体运行机制

       完整了解bufpool子系统,必须要分模块逐个击破,以笔者目前的经验看是LRU -> flush -> buf read -> buddy allocator ->buf pool,这个顺序为宜。

首先是五模块关系图,从整体来看LRU在本系统内不仅仅是一种算法,也是一个链表,更是一个重要的组件模块。作者的这句“These statistics are not 'of' LRU but 'for' LRU.”是最好的诠释。


       buf pool实例管理部分调用LRU的函数接口调用最多,读缓存、flush、伙伴系统也都有重要调用。

       除此之外,存储子系统的文件表空间管理部分fil0fil.c文件也引用了LRU的其中一个函数接口。

(2)LRU链表结构和基础算法


LRU链表结构简单直接,分为old部分和头部分,这涉及到一个策略:

buf_pool_struct结构体有一个LRU_old对象,它是一个指向LRU链表“old部分”的buf_page_struct类型指针。

buf_page_t*       LRU_old;

另一个对象,

ulint             LRU_old_ratio;

配合宏BUF_LRU_OLD_RATIO_DIV定义buf pool的LRU链表OLD端指针的设置、old端长度,也是一个很重要的对象。

当LRU链表长度超过一定阀值后,就初始化该结构体的LRU_old对象,也就是下面这个逻辑:

UT_LIST_GET_LEN(buf_pool->LRU)== BUF_LRU_OLD_MIN_LEN

       关于LRU链表的OLD部分涉及到4个宏定义:

第一个代表LRU长度达到多少个节点之后,触发LRU_old的初始化操作,长度是512;

#define BUF_LRU_OLD_MIN_LEN      512 /* 8 megabytes of 16k pages */

       第二个代表buf_pool_struct结构体对象LRU_old_ratio的分母,作为决定LRU_old指针位置的一个重要定义。

#define BUF_LRU_OLD_RATIO_DIV  1024

old下限

#define BUF_LRU_OLD_RATIO_MIN  51

old上限

#define BUF_LRU_OLD_RATIO_MAX       BUF_LRU_OLD_RATIO_DIV

现在把上面的信息进行合并整理,当LRU链表节点数低于BUF_LRU_OLD_MIN_LEN个数时候,LRU链表的old端不需要初始化,buf_pool_t->LRU_old=NULL;

同时buf_page_struct结构体的old对象值也是false。

上面几个宏都是在最初就完成了定义,而LRU_old_ratio是在buf pool初始化过程中完成的,由buf_pool_init()函数内发起调用:

buf_LRU_old_ratio_update(100 * 3/ 8, FALSE);

十分明确,(LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV)的预设值=3/8。

函数buf_LRU_old_ratio_update根据BUF_LRU_OLD_RATIO_DIV 和3/8的预设值计算LRU_old_ratio。相关代码:

。。。。。。

       if (ratio < BUF_LRU_OLD_RATIO_MIN) {

              ratio = BUF_LRU_OLD_RATIO_MIN;

       } else if (ratio > BUF_LRU_OLD_RATIO_MAX) {

              ratio = BUF_LRU_OLD_RATIO_MAX;

       }

。。。。。。

以3/8比例计算如果大过上限值BUF_LRU_OLD_RATIO_MAX就按照上限赋值LRU_old_ratio,若小于下限值BUF_LRU_OLD_RATIO_MIN就设为下限值,使得old端长度灵活可变(也就是不一定每次调整完链表长度后old端长度都保持3/8的样子),最终可用于flush或者remove。

(3)函数分类详解

源代码的主体是43个函数,从功能角度对函数接口进行分类并综合调用关系进行梳理,基本上围绕着三方面进行,开篇曾经进行过概述:

15个重要的主函数:基本功能围绕分配块、释放块、LRU链表删除块、LRU链表添加块进行,但因为牵涉到flush机制、free空闲链表、LRU链表的old端控制、bufpool的虚拟内存磁盘置换就衍生出了多达15个供外部模块调用的主要函数接口。另外,所谓‘主函数’的称呼其实并不准确,只是按照被调用次数以及功能重要性做的一种模糊的定位,辅助函数中有很多虽然没有被外部调用,但从某种意义上来说重要性甚至更高!

14个与主函数关联密切的辅助函数:这14个函数很多都包含了上面第一类主函数的一些实现细节,是血肉的精华。

其它函数接口:43个函数中减去15个主函数和14个辅助接口之外的其余函数,归类此处暂不一一列举。

表格一栏如下,排名不分先后:

类型

功能

名称

主函数

删除给定表空间的全部页(上层接口)

buf_LRU_flush_or_remove_pages

 </

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值