CMU15445 Lecture 5 Buffer Pools
本节主要介绍DBMS是如何管理memory与disk之间的数据来回移动的
为什么需要Buffer Pools
由于系统不能直接处理磁盘中的数据,DBMS需要为了系统将数据从磁盘放入内存中,又由于内存容量有限,DBMS需要进行内存数据与磁盘数据的交换;这其中的权衡是,需要系统看起来好像所有的数据都以及在内存之中,这需要DBMS考量空间的控制与时间的控制
- 空间控制
目标是使得常常需要被使用的page尽可能保存在内存中 - 时间控制
目标是,使得在磁盘与内存中交换数据的停顿最小化
锁与闩(locks & latches)
- 锁(lock)
锁是一个高层面,逻辑原语,用来在事务之间,保护数据库的内容(诸如tuple,table,database);事务会全程维护一个lock;在查询执行时,database系统可以告诉用户现在持有了什么锁;lock可以回滚,也就是rollback changes - 闩(latch)
闩是一个低层面的保护原语,用来保护DBMS的关键区域的内部数据结构(hash table, region of memory);一个区别是latch只有在操作(比如query)执行的时候才会持有,另外一个区别是latch不能够回滚,也就是不能rollback changes
Buffer Pool能够做什么
buffer bool 开辟于内存里,可以看作是磁盘页在内存中的对于database的缓存,buffer pool的单位容量被称为frame
Buffer Pool的元数据
- page table
page table 是buffer pool维护在内存中的元数据,它保存着page_id与frame_id(也就是buffer pool中frame的位置)的映射;这个间接层(indirection layer)使得buffer pool中页可以不按顺序存储;这里需要区别page directory与page table,前者是保存这page_id与数据库文件位置的映射 - dirty flag与pin/reference counter
如果一个page在内存中被修改,page table中会对page置位dirty标志,这样在将该page换出时,就需要将该页写入磁盘
对于某个page,可以用pin/reference Counter追踪有多少线程在访问该页,只要其不为0,那么storage manager不能够将该page驱逐出内存
内存分配策略
需要分配多少内存给buffer pool又两种考量
- global policies
DBMS需要考虑全局负载,也就是需要考虑所有的当前正在执行的事务,以此来找到一个最优的分配给buffer pool的大小 - local policies
只考虑一个query或transaction,为了使得它运行的更快,即使其不是全局最优
Buffer Pool的优化
多缓冲池(Multiple Buffer Pools)
DBMS可以基于不同的目的维持多个缓冲池(比如每个数据库一个缓冲池,每种页类型一个缓冲池),这样一来,每个buffer pool可以采用定制化的local police,一个最大的好处时可以减少latch的竞争与提高局部性
如果又多个buffer pool,如何区分pages,并放到给定的buffer pool中呢,有两种方案:
- Object IDs
给每个page添加一个新的属性,Object id - hashing
对于page_id进行hash,以决定buffer pool
预取
DBMS可以基于query方案进行pre-fetching优化;这个策略常用于线性访问
scan sharing
区别与result caching,result caching是指第一个query查完数据,那么将其缓存下来;而scan sharing是指,当两个查询query的数据需要扫描同一个个page序列,那么它们的cursor合并为一个
但是对于LIMIT子句的出现,可能会导致错误
buffer pool旁路
buffer pool bypass,对于某些需要线性读取大量数据的query,可以不将数据缓存在buffer pool,这样就可以随意丢弃,减少开销;另外对于诸如(sorting, joins)中间数据,可以不放在buffer pool
OS Page Cache
磁盘操作也会通过OS API被缓存,除非OS被告知不要去维护缓存。但是一般DBMS会绕过OS取进行磁盘操作,这样一来可以减少缓存的冗余,并且DBMS可以执行自己的evict policies
但是也有例外,Postgres就不绕过OS
buffer pool replacement policies
替换策略需要考量正确,精准,速度与元数据开销
- LRU(Least Recently Used)
基于时间戳的LRU - CLOCK(LRU的近似算法但更简洁)
- 其他
对于sequential flooding,前两者都无济于事,有三种解决方案:LRU-K
,以前k次的page的访问来推测出之后该page被访问的概率有多大locllization
, 基于每个query与transaction做evictionpriority hints
,对于每个page添加优先级属性,基于每个query的上下文
脏页驱逐
对于未置位dirty bit的page,在evict时,可以直接丢弃;但是置位了dirty bit 的page,为了保持一致性,需要将其写回disk,这里存在着一种权衡,立马驱逐还是说保存在内存中,以防止未来它还需要被读
- background writing
周期性集中异步刷脏,据说可以解决the problem of having to write out pages unnecessarily
OTHER MEMORY POOLS
参考
note5
b站视频