老刘原创文章,优快云首发!转载请注明出处。
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 |
</ |