CMU 15-445 lec6

这是一篇关于 CMU 15-445 数据库导论 lecture6 的笔记,主要讲了DBMS是如何从硬盘中读取内容到内存中的,Buffer Pool的概念,以及其优化策略。

lecture 6

主要讲了从Disk到Memory之间,采用了Buffer Pool的机制,缓冲池(往往有多个)会装Disk上的子集,然后由Page Table作为中间层来进行映射以便Memory访问。而为了防止竞态的发生,DB一般会采用latch机制来保证并发访问的安全性。

Buffer Pool

缓冲池是从磁盘中读取的页面中的内存缓存。它本质上是数据库内部分配的大型内存区域,用于存储从磁盘获取的页面。

缓冲池的内存区域组织为固定大小页面的数组。每个entry都称为一个frame。

Buffer Pool的职能类似与Cache。当要求访问某个Page时,数据库系统首先搜索缓冲池。只有在找不到页面的情况下,系统才会从磁盘中获取页面的副本。Dirty Page被被Buffer Pool缓冲,不会立即写回Disk当中。

不同的Buffer Pool不会存取同一个Page,而是一对一映射。一般某个Page on Disk被放在Buffer Pool之后,便不会再被其他Buffer Pool使用。

  • 页表(Page Table)是一个内存中的哈希表,用于跟踪当前在内存中的Page。它将Page_ID映射到Buffer Pool中的某个frame。由于缓冲池中页面的顺序不一定反映磁盘上的顺序,因此这个额外的间接层允许标识缓冲池中的页面位置。

  • Page Directory是从页面ID到数据库文件中页面位置的映射,对页面目录的所有更改都必须记录在磁盘上。

处理Dirty Page

这个类似于Cache Coherency。当Buffer Pool中的页面被修改时,它必须被标记为Dirty。pin/reference计数器跟踪当前正在访问该页面(读取或修改该页面)的线程数。线程在访问页面之前必须递增计数器。如果页面的引脚数大于零,则不允许存储管理器从内存中收回该页面。固定不会阻止其他事务同时访问该页面。直到Dirty Page被写回磁盘后,才会被清除,从而允许其他线程对这个Page进行访问。

Buffer Pool 的优化策略

  1. 使用多个Buffer Pool: 一般desired Page和Buffer Pool的映射方式采用ObjectID或者Hashing
  2. Pre-fetching: 根据某些特定的算法,预测接下来你可能会读取的Page,预先从磁盘中读取一些页面到Buffer Pool中,以便在需要时立即使用。
  3. Scan Sharing(Synchronized Scans): 一次遍历,多个目的。比如我们需要查询某个东西,且需要对另外一个东西进行计数。若操作对象处于同一个Page当中,我们可以在同一次对Page的遍历中,同时进行这二者。
  4. Buffer Pool Bypass: 缓冲池旁路。顺序扫描运算符不会将提取的页面存储在缓冲池中以避免开销。

Buffer Pool 的替换策略

  1. LRU: 经典LRU
  2. CLOCK: 基于时间的淘汰策略,将最近最少使用的页面淘汰。
  3. Dirty Page: 有两种方法可以处理带有脏位的页面。最快的选择是删除缓冲池中未脏的任何页面。较慢的方法是将脏页写回磁盘,以确保其更改被持久化。
  4. Alternatives: 因为LRU和CLOCK对于顺序读取很有问题,比如总共有100个Page,而一个Pool总共就10个Page大,每次读取就是不同的10个这样Cache的机制根本就无效了。

Latch

latch是更底层的lock,可以将它理解为一种互斥锁(mutex),用来保护共享资源的访问。在DBMS中,latch的作用主要是为了防止多个事务同时对同一资源进行访问,从而导致数据不一致的问题。