本文为本人完成15445 2020fall(B+树版本)时的一些记录,仅作为备忘录使用。


TASK #1 - LRU REPLACEMENT POLICY

本任务为实现一个LRU页面置换策略,建立一个关于面向磁盘的数据库的基本的概念是很重要的,如下图:

从中可以看出,实际数据是持久化存储于磁盘之上的,执行引擎主要进行一些数据操作(读/写,也即对Page增删改查),而BufferPool则是介于执行引擎和磁盘之间,位于内存中,给执行引擎提供Page。由于存储器体系结构一般表现为内存容量远小于磁盘容量,因此BufferPool是无法加载整个db的所有Pages的,因此需要在合适的时机将Page写入磁盘中,LRU就决定了牺牲哪个Page(即将哪个Page写回到磁盘中),其中包含了局部性原理的思想。

在Buffer Pool中,Page是存放在frame中的,这是要注意的一个点(buffer pool就是一个能容放多个Page的vector)。

The size of the LRUReplacer is the same as buffer pool since it contains placeholders for all of the frames in the BufferPoolManager. However, not all the frames are considered as in the LRUReplacer. The LRUReplacer is initialized to have no frame in it. Then, only the newly unpinned ones will be considered in the LRUReplacer.

所要实现的接口主要是下面四个:

  • Victim(T*) : Remove the object that was accessed the least recently compared to all the elements being tracked by the Replacer, store its contents in the output parameter and return True. If the Replacer is empty return False.
  • Pin(T) : This method should be called after a page is pinned to a frame in the BufferPoolManager. It should remove the frame containing the pinned page from the LRUReplacer.
  • Unpin(T) : This method should be called when the pin_count of a page becomes 0. This method should add the frame containing the unpinned page to the LRUReplacer.
  • Size() : This method returns the number of frames that are currently in the LRUReplacer.

LRU的实现十分的简单,是经典的leetcode题,用list套一个unordered_map即可实现。

下面主要讲一下我对PinUnPin的理解:

  • Pin(T) : 将一个Page(frame)从LRU的list中剔除。即该Page(frame)被Buffer Pool所使用了,LRU不应该牺牲该页面。
  • Unpin(T) : 加入一个Page(frame)入LRU的list。即该页面Buffer Pool目前没人使用了,LRU根据策略决定该页面的去留。
  • Victim(T*) :意思很直接,LRU根据规则(最近最少使用)有选择性的牺牲一个页面(frame)。

并发的话,直接加大锁就好了。std::lock_guard是一种RAII的加锁方式,可以不用unlock(在析构的时候unlock),比较方便。给出Victim的实现方法,其他的应 Prof. Pavlo 要求就不放出来了。

bool LRUReplacer::Victim(frame_id_t *frame_id) {std::lock_guard<std::mutex> lock(latch_);if (id2iter_.empty()) {return false;}auto deleting_id = lru_list_.back();lru_list_.pop_back();id2iter_.erase(deleting_id);*frame_id = deleting_id;return true;
}

TASK #2 - BUFFER POOL MANAGER

第二个任务为构造一个Buffer Pool。

The BufferPoolManager is responsible for fetching database pages from the DiskManager and storing them in memory. The BufferPoolManager can also write dirty pages out to disk when it is either explicitly instructed to do so or when it needs to evict a page to make space for a new page.

实现以下几个接口:

  • FetchPageImpl(page_id)
  • NewPageImpl(page_id)
  • UnpinPageImpl(page_id, is_dirty)
  • FlushPageImpl(page_id)
  • DeletePageImpl(page_id)
  • FlushAllPagesImpl()

(其实可以先通过测试程序了解这几个接口怎么用的,然后再去实现会比较好!)

  • NewPageImpl(page_id):新建一个Page。
  • FetchPageImpl(page_id):获取一个Page。
  • UnpinPageImpl(page_id, is_dirty):解除对某个Page的使用(别的进程可能还在使用,pin_count为0的时候可以删除)
  • DeletePageImpl(page_id):删除一个Page。
  • FlushPageImpl(page_id):强制将某个Page写盘。
  • FlushAllPagesImpl():将所有Page写盘。

这个task其实本质上就是考验对下面两个点的理解,根据提示看看DiskManager 的API是比较好实现的:

  • Dirty Flag :当该flag为真时,该页被写过了,要写回磁盘。
  • Pin/Reference Counter:引用计数,当该计数为0时,将对应frame加入LRU中;当该计数不为0时,将对应frame从LRU中删除(即不参与LRU的替换)。

该task有几个坑需要注意一下:

  1. 重复UnpinPageImpl,但is_dirty标志不同。

    • 不是简单的赋值设置is_dirty标志,而是累计,即或一下。
    • page->is_dirty_ |= is_dirty;
  2. New完一个Page后,其pin_count为1,因此不要将这个Page放入LRU。

    • replacer_->Pin(fid);
  3. New完一个Page后,要立即刷盘。可能会有new完以后unpin(false)的情况,不刷盘这一页就丢失了

    • disk_manager_->WritePage(new_page->GetPageId(), new_page->GetData());
  4. 获取frame时,先从free list获取,再从lru中获取。

    • /*** @brief get a free page from free_list or lru_list** @return frame_id_t frame id, -1 is error*/
      frame_id_t BufferPoolManager::get_free_frame() {frame_id_t frame_id = -1;if (!free_list_.empty()) {frame_id = free_list_.front();free_list_.pop_front();} else {replacer_->Victim(&frame_id);}return frame_id;
      }
  5. 删除一个Page时,要保证free list和LRU中只存在一个fid,而不是两边都有。

    • replacer_->Pin(fid);
    • free_list_.emplace_back(fid);

由于是多线程的程序,可以多跑几次测试一下,通过日志排查出错的原因。

#!/usr/bin/env bashtrap 'exit 1' INTecho "Running test $1 for $2 iters"
for i in $(seq 1 $2); doecho -ne "\r$i / $2"LOG="$i.txt"# Failed go test return nonzero exit codes$1 &> $LOGif [[ $? -eq 0 ]]; thenrm $LOGelseecho "Failed at iter $i, saving log at $LOG"fi
done

(gradescope上测试要是失败了可以直接偷测试文件,逃

若有概念不理解的可以翻翻课件。

CMU15445 lab1 - BUFFER POOL相关推荐

  1. CMU15445 buffer pool 2021

    CMU15445 buffer pool 2021 心得体会 Gradescope测试 源代码(仅供参考) LRU Replacement Policy Buffer Pool Manager Ins ...

  2. CMU15-445 PROJECT #1 - BUFFER POOL(Fall2020实验代码,已满分)

    实验说明:https://15445.courses.cs.cmu.edu/fall2020/project1 我的完整实验代码见github:https://github.com/nefu-ljw/ ...

  3. [转]MySQL innodb buffer pool

    最近在对公司的 MySQL 服务器做性能优化, 一直对 innodb 的内存使用方式不是很清楚, 乘这机会做点总结. 在配置 MySQL 的时候, 一般都会需要设置 innodb_buffer_poo ...

  4. mysql 哈希缓存_MySQL Buffer Pool

    1.简介 buffer pool 就是一个缓存,将磁盘中的数据缓存到内存中,对数据的操作改为通过内存进行操作,然后刷盘的操作,提升性能. innodb_buffer_pool_size 控制缓存池的大 ...

  5. Innodb Buffer Pool的三种Page和链表

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | 王航威 来源 | 公众号「yangyidba」 ...

  6. MySQL · 性能优化· InnoDB buffer pool flush策略漫谈

    MySQL · 性能优化· InnoDB buffer pool flush策略漫谈 背景 我们知道InnoDB使用buffer pool来缓存从磁盘读取到内存的数据页.buffer pool通常由数 ...

  7. 缓冲多少数据_聊点深的:解析MySQL,看看InnoDB 缓冲池(buffer pool) 工作原理

    缓冲池的用处 对于使用 InnoDB 作为存储引擎的表来说,不管是用于存储用户数据的索引,还是各种系统数据,都是以页的形式存放在表空间中的,而所谓的表空间只是 InnoDB 对文件系统上一个或几个实际 ...

  8. buffer pool mysql_MySQL 5.7版本新特性(修改buffer pool,无需重启服务)

    优化online操作,例如修改buffer pool.修改索引名(非主键).修改REPLICATION FILTER.修改MASTER而无需关闭SLAVE线程等众多特性. 如果是加大buffer po ...

  9. mysql buffer pool_MySQL的查询缓存和Buffer Pool

    一.Caches - 查询缓存 下图是MySQL官网给出的:MySQL架构体系图. 人们常说的查询缓存就是下图中的Cache部分. 如果将MySQL分成 Server层和存储引擎层两大部分,那么Cac ...

最新文章

  1. Python相对导入导致SystemError的解决方案(译)
  2. c语言程序计算p q真值表,C语言程序设计第2章数据类型﹒运算符和表达式.ppt
  3. Android开发学习之路-指纹识别api
  4. 总结Java常见面试题和答案
  5. C语言游戏传递小秘密,C语言的那些小秘密之链表
  6. Linux IPC实践(7) --Posix消息队列
  7. python判别性别的代码_python如何实现性别识别 python实现性别识别代码示例
  8. 计算机普通话培训开班简报,普通话培训第四期简报.doc
  9. 集成ahci驱动的xp系统_IDE转AHCI模式 for win7+SSD
  10. pcm系统设计及matlab仿真实现,DOC:25页毕业设计PCM系统设计及MATLAB仿真实现.doc文档优秀范文...
  11. 消息中间件(消息队列)介绍
  12. TCP/IP协议(2):各层网络设备
  13. 关于瑞星杀毒软件无法完全卸载、自动重装的无奈,与相应的解决办法
  14. 电脑运行应用程序出现0xc000007b的解决方法
  15. 云计算实训之项目3-基于微信实现自动化监控报警
  16. 程序员应该怎么学数学?
  17. Python之禅——传说中的蛇宗总纲
  18. opencv心得体会_OpenCV心得
  19. 一年涌入3000家“他经济”现资本众生相
  20. 秒懂机器学习---k-近邻算法实战

热门文章

  1. Cmake Practice(二)
  2. IC芯片磨字刻字、激光烧面、编带抽真空
  3. python学习之路—自动生成唯一标识(md5加密方式)
  4. 格式检查工具eslint
  5. 将xacro格式文件转换为urdf格式并对其进行检查格式,并生成机器人模型的结构图
  6. Android 字符串中选出手机号变色并加点击事件去除下划线
  7. 社交媒体该如何实现「去中心化」?
  8. DM数据库找不到表?
  9. 博捷芯划片机:主板控制芯片组采用BGA封装技术的特点
  10. 交互细节分析——注册登录