首页 > 其他分享 >15445第一阶段笔记+Buffer Pool(2019)

15445第一阶段笔记+Buffer Pool(2019)

时间:2022-09-07 11:03:06浏览次数:71  
标签:15445 Buffer frame replacer page 2019 victim 磁盘 id

15445第一阶段笔记+Buffer Pool(2019)

概念

page与frame

​ 块,页,是对同一概念的不同叫法,取决于场景不同。其表述的都是磁盘上某一柱面上的连续扇区(固定数目)。数据在磁盘和缓冲区(内存)之间传输,传输的单位就是块(页)。

​ 内存区是以定长的页数组的形式组织的,其中每一个数组条目,被称为一个帧(frame)。当DBMS请求一个页时,被请求页的一份拷贝就被读取进其中一个帧中。

​ 所以,page和frame实际是指的是同一个概念,buffer pool中的叫做帧,磁盘与内存之间的传输单位的叫做page或者block。

page table

​ 是一个Page ID到Frame ID的映射。Page ID是磁盘页的属性,不同的磁盘页的Page ID不同,当磁盘页被读取进缓冲区时,该磁盘页会在缓冲区中有一个位置,即Frame ID。缓冲区是Frame的定长数组,一共只有buffer_pool_size大小的frame,所以,当磁盘页读进写出,会存在不同的磁盘页先后出现在同一个帧位置的情况,那么这个Page Table,就是保存当前页ID到帧ID的映射。

page directory

​ Page Directory中的每⼀个小格中包含有对应page所在位置,也包含它剩余空间信息。通过Page Directory可以将page映射到内存或者磁盘上的某个位置

存储结构

​ 总的来说,数据库内部的存储结构可以总结为,Page Directory负责映射内存或者磁盘中的page,Page Table负责将page映射到buffer pool中的frame中。

​ 而page内部的header和slot array来组织tuple存放。以下是page中的结构

​ tuple内部的结构也是header+data。

项目

一些注意的地方

clock_replacer

  • replacer是一个定长数组,但是clock_size不是定长,而是可以被victim的frame的总数,所以replacer实际上存放的是可以被替换的帧。clock_size初始为0。

  • clock_hand是遍历replacer的指针,只有Victim()函数可以修改clock_hand指针。

buffer_pool_manager

  • pages_是buffer pool的帧数组。

函数

clock_replacer

bool Victim(frame_id_t *frame_id)

1.进行循环遍历,扫描所有实际存在replacer中的帧,如果没有可替换帧,则返回false。

2.只查看实际在replacer中的帧,如果ref为1,则将ref修改为0,clock_hand++。如果ref为0,则将其标记为不在replacer中,clock_size--,并令*frame_id = clock_hand++,将该帧的frame_id传出去,返回true。


void Pin(frame_id_t frame_id)

将目标帧标记为不在replacer中,clock_size--。


void Unpin(frame_id_t frame_id)

将目标帧标记为在replacer中,clock_size++,同时将ref标记为true(clock_replacer中新添加帧的ref需标记为true)。


buffer_pool_manager

FetchPageImpl(page_id_t page_id)

0.首先用latch上锁

1.page_table_中是否存在page_id所对应的帧。如果存在,则直接返回所对应的帧,并需要进行pin操作;若没有则需要将磁盘中的page读取到buffer pool中,即读取到pages_中的一个帧的位置。

2.首先从free_list中寻找空闲帧,如果可以找到空闲帧,则go to 4;如果free_list为空,则调用replacer.Victim()获得可替换帧的victim_frame_id。若没有可替换帧,则返回nullptr

3.检查victim_frame的脏读位,如果脏读位有效,则需要调用disk_manager_->WritePage()写回到磁盘中。

4.进行victim_frame数据的读取以及元数据的更新操作:

(1)清除victim_frame的页表中的记录。

(2)添加victim_frame的page_id到victim_frame_id的新映射。

(3)更新victim_frame(在pages_数组中)的page_id。

(4)进行victim_frame的pin操作,pin_count++,调用者加1,并调用replacer_->pin()方法。

(5)victim_frame的脏读位记为false。

(6)调用disk_manager_->ReadPage(page_id, pages_[victim_frame_id].data_),将page的数据读取到victim_frame中。

5.返回pages_中victim_frame的地址。


Page* NewPageImpl(page_id_t *page_id)

0.首先用latch上锁

1.首先从free_list中寻找空闲帧,如果可以找到空闲帧,则go to 3;如果free_list为空,则调用replacer.Victim()获得可用帧的victim_frame_id。若没有可用帧,则返回nullptr

2.检查victim_frame的脏读位,如果脏读位有效,则需要调用disk_manager_->WritePage()写回到磁盘中。

3.调用disk_manager_->AllocatePage()分配一个新的页,记页ID为page_id,然后进行victim_frame数据的清除以及元数据的更新操作:

(1)清除victim_frame的页表中的记录。

(2)添加victim_frame的page_id到victim_frame_id的新映射。

(3)更新pages_数组中的victim_frame的page_id.

(4)记victim_frame的脏读位为false

(5)清空victim_frame中的数据

(6)设置victim_frame的pin_count=1

4.返回pages_中victim_frame的地址


bool DeletePageImpl(page_id_t page_id)

0.首先用latch上锁

1.在page_table_中查找page_id是否存在对应的frame_id,如果不存在,则直接go to 4。

2.若page_table_[frame_id].pin_count不为0,则返回false。

3.若目标帧的脏读位为true,则调用disk_manager_->WritePage()将其写回磁盘。

4.进行目标帧的重置操作:

(1)该目标帧不再进行replacer_->Victim()操作,所以调用replacer_->Pin(frame_id)

(2)从page_table_中删除page_id的映射

(3)设置目标帧的pin_count=0,is_dirty_=false,data_清空,page_id=INVALID_PAGE_ID。

(4)加入free_list_中。

4.调用disk_manager_->DeallocatePage(page_id),返回true。

标签:15445,Buffer,frame,replacer,page,2019,victim,磁盘,id
From: https://www.cnblogs.com/oneOmega/p/16664540.html

相关文章

  • 关于buffer
    创建Buffer实例alloc:创建指定字节大小的bufferallocUnsafe:创建指定大小的buffer(不安全)from:接收数据,创建bufferBuffer实例方法fill:使用数据填充bufferwrite:向bu......
  • 代码笔记24 windows+opencv4.5.5安装中出现的IPPICV: Download: ippicv_2020_win_inte
    1环境介绍:windows10,visualstudio2019,CMake,OPENCV4.5.5出现问题IPPICV:Download:ippicv_2020_win_intel64_20191018_general.zipTry1failedCMakeWarninga......
  • [极客大挑战 2019]Upload 1
    进入可以看到,这时一道文件上传题目直接上传test.php提示Notimage不是图片,可能是MIME绕过,尝试抓包修改Content-Type提示Notphp,猜测可能是检测后缀名不能是php,将te......
  • P5664[CSP-S2019] Emiya 家今天的饭 (dp + 计数)
     P5664[CSP-S2019]Emiya家今天的饭(dp+计数)题目传送门题目大意:给定一个大小为\(n*m\)的表格,其中\(a_{i,j}\)表示用第\(i\)种烹饪方式并且有第\(j\)......
  • [极客大挑战 2019]LoveSQL 1
    很明显这时一道SQL注入的题目这题很简单的SQL注入题目,使用union(联合查询注入),但是缠了我很久为什么呢?因为我们学校的waf,很多可以注入成功的语句,他都会连接被重置,或者被b......
  • vs2019编辑代码闪退解决方法
    错误应用程序名称:devenv.exe,版本:16.11.32802.440,时间戳:0x62e9f741错误模块名称:KERNELBASE.dll,版本:10.0.19041.1949,时间戳:0xa599bd99异常代码:0xe0434352错......
  • [GXYCTF2019]Ping Ping Ping 1
    进入页面发现提示应该是命令执行可以使用|&;等方法绕过尝试查看当前目录下的文件?ip=127.0.0.1|ls发现拥有flag.php和index.php两个文件尝试使用cat查看flag.php......
  • ArrayBuffer、Float32Array、Uint8Array 详解
    ArrayBufferArrayBuffer()是一个普通的JavaScript构造函数,可用于在内存中分配特定数量的字节空间。constbuf=newArrayBuffer(16);//在内存中分配16字节alert(......
  • [SUCTF 2019]EasySQL 1
    这个题目搞了我好久,由于本人基础不扎实,试了好多方法,只发现有三种情况Nonono、无返回结果和有返回然后使用了新学习的堆叠注入,得到了数据库名和表名想要查看Flag表的字......
  • buffer poll 缓存页
    free链表:指向未使用的控制块与缓存页hash表:key:表空间号+页号value:缓存页脏页:修改过的缓存页flush链表:指向脏页lru:缓存不够时,先删除最近最少使用的。LRU链表:只要用到......