Page Internals
PSQL 使用clock-sweep。
Buffer pool可以看作一个buffer slots的循环列表。
Buffer pool在启动服务时为空,一般在在结束时满。所以当新的page来的时候,我们需要evict(驱逐)一些page。---->NextVictimBuffer 存下一个被驱逐对象的索引。
当决定谁被驱逐时,如果一个page很受欢迎,则保留它。
usage_count 实现了度量popularity/recency的方法。
某个页面,当它每次被访问时,它的usage_count会加1(有一个小的上限)。如果它每次被考虑驱逐时,usage_count会减1。
不断增加NextVictimBuffer。
Buffer Pool ClockSweep Replacement Strategy
BufferDesc = (tag, usage_count, refcount, freeNext)
Init[1]的freeNext为2是因为没有需要free的,所以指向了 [2]。
当request R0时,我们通过nextVictim找到下一个要free的 index,也就是R0。
Page
Page由Tuples组成, Tuples根据TupleId被读取。
TupleId = PageID + TupleIndex
data是一系列的固定长度的pages(即blocks)。
通过PageID任意访问page。
page包含0个或多个tuple values。
Page format = 怎样组织tuples。
当delete的时,只设置tuple的entry,不改变page的结构。
当update时,设置tuple的标签tag为removed,然后加入新的tuple。
通常,page是一个bytes的数组。bytes的内容是tuple,但tuple不一定相邻。
Pages的操作:
request_page(pid) 通过pageid获取page。
get_record(rid) 通过tupleid获取record。
rid = insert_record(pid,rec) 增加新的record。
update_record(rid,rec) 更新re