【cmu db spring 2023】p1 bufferpool manager

最近在写cmu db spring 2023的project,记录一下遇到的知识点和踩过的坑

lru - k replacer

先看一下定义

The LRU-K algorithm evicts a frame whose backward k-distance is maximum of all frames in the replacer. Backward k-distance is computed as the difference in time between current timestamp and the timestamp of kth previous access. A frame with less than k historical accesses is given +inf as its backward k-distance. When multipe frames have +inf backward k-distance, the replacer evicts the frame with the earliest timestamp.

相比lru 它保存了k 次历史,避免了一些偶然访问替换掉频繁访问的page。

具体场景

  • 内部事务(Intra-Transaction) :比如一个事务先读取一个页,然后在提交之前再次访问这个页。其实就是:用于更新的事务,先读取一列,再更新这列
  • 事务重试(Transaction-Retry):一个事务访问一个页然后中止。接下来重试这个事务并且再次访问这个页。
  • 内部流程(Intra-Process): 一个事务访问一个页面,并且成功提交了。然后下一个同样流程的事务再次访问这个页。这种模式的访问通常是由进行大量更新的程序引起的,比如连续更新100条记录
  • 多事务交互(Inter-Process):一个事务访问一个页,然后另外一个不同流程的事务也访问这个页。这两个事务之前是完全独立的,目的也不一样。

上述四个例子的前三个被称作correlated reference-pair type,第四个例子是不关联的。

缓存系统不应该直接丢弃一个page,而是应该保留到下一次访问或者是保留到下一次访问的可能性变到很小的时候。
在另外一方面,我们估计两次使用page的间隔时,不应该使用关联访问对来估计。
如何判断两次访问是不是关联访问呢?一个方法是设置一个时间阈值,在阈值之下就是关联访问。
关联访问可能是一连串的访问,而不只是两次。比如一百次对同一个页上记录的更新。我们把这一连串称为关联访问时期。在估计一个页两次使用间隔时,应该时计算一次关联访问的结束和下一段关联访问开始之间的时间间隔。

实现思路

在evict 和 record access 维护两个set: less_k_time_ , k_time_ 和 一个 map 维护 frame_id 和 lruNode 之间的映射关系。

buffer pool

缓冲池,那么里面应该缓存着大量的数据,使CPU读取或者写入数据时,不直接和低速的磁盘打交道,直接和缓冲区进行交互,从而解决了因为磁盘性能慢导致的数据库性能差的问题,弥补了两者之间的速度差异。

lru链表:缓存了所有读入内存的数据页,包含三类
1)未修改的页面,可以从该列表中摘除,然后移到free列表中。
2)已修改还未刷新到磁盘的页面。
3)已修改且已经刷新到磁盘的页面,可并为第一类。

free链表:空闲内存页(块)列表,需要装载(缓存)磁盘上的数据页的时候,从此列表取内存块。

page guard

这个是最折磨人的
我在初始化pageguard 类的时候,会给page 添加读锁或者写锁,结果就是疯狂死锁

project 0 可以说使我掌握了智能指针尤其unique_ptr 的 使用

猜你喜欢

转载自blog.csdn.net/ltd0924/article/details/130055535
CMU