【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 的 使用

优化

为了保持数据的 一致性,对每一个执行模块直接一把互斥锁,确保数据的安全性。但是这会对性能造成较大的困扰,在实现bufferpool 内存申请时会有一些对于容器的操作

  • table :frame id 与 page id 映射
  • free_list 空闲的内存空间
  • 对于指定page 页基本信息的赋值

我进行了优化但是感觉还没有达到最优,参考一下大佬的思路

get类线程总数与scan类相同,每个线程zipfian distribution地点查共同的区间,执行fetch page、加读锁、校验数据、放读锁、Unpin操作。QPS的计算方式如下,可以看出get_qps_1ms是我们的优化目标。scan_qps_0ms / 10000 + get_qps_0ms / 10000 + scan_qps_1ms + get_qps_1ms * 10在进行优化前,可以disable掉所有的scan线程,单独看get线程在没有scan线程扰乱buffer pool以及脏页刷盘的情况下性能表现符不符合预期,这里的符不符合预期指的是buffer pool成员变量加锁区间、page元数据加锁区间、page数据加锁区间、lru_k replacer加锁区间是否足够小,是否能满足多线程并发时性能尽可能线性提升的需求。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值