Lab1缓冲池管理器
概览
实验的目标系统 BusTub 是一个面向磁盘的 DBMS,但磁盘上的数据不支持字节粒度的访问。这就需要一个管理页的中间层,但 Andy Pavlo 教授坚持不使用 mmap 将页管理权力让渡给操作系统,因此实验一 的目标便在于主动管理磁盘中的页(page)在内存中的缓存,从而,最小化磁盘访问次数(时间上)、最大化相关数据连续(空间上)。
该实验可以分解为相对独立的两个子任务:
-
维护替换策略的: LRU replacement policy
-
管理缓冲池的: buffer pool manager
两个组件都要求线程安全。
本文首先从基本概念、核心数据流总体分析下实验内容,然后分别对两个子任务进行梳理。
实验分析
刚开始写实验代码的时候,感觉细节很多,实现时很容易丢三落四。但随着实现和思考的深入,渐渐摸清了全貌,发现只要明确几个基本概念和核心数据流 ,便能够提纲挈领 。
基本概念
buffer pool 的操作的基本单位为一段逻辑连续的字节数组,在磁盘上表现为页(page) ,有唯一的标识 page_id ;在内存中表现为帧(frame) ,有唯一的标识 frame_id 。为了记下哪些 frame 存的哪些 page,需要使用一个页表(page table) 。
下边行文可能会混用 page 和 frame,因为这两个概念都是 buffer pool 管理数据的基本单位 ,一般为 4k,其区别如下:
-
page id 是这一段单位数据的全局标识,而 frame id 只是在内存池(frame 数组)中索引某个 page 下标
-
page 在文件系统中是一段逻辑连续的字节数组;在内存中,我们会给其附加一些元信息:
pin_count_
,is_dirty_
而管理帧的内存池大小一般来说是远小于磁盘的,因此在内存池满了后,再从磁盘加载新的页到内存池,需要某种替换策略(replacer)将一些不再使用的页踢出内存池以腾出空间。
CPU对内存中的数据进行操作时,传入参数为
page id
。磁盘写回脏页时,传入参数也为page id
。而frame id
只是在内存池中索引某个page的下标。