MiniOB 1
MiniOB is one mini database, helping developers to learn how database works.
|
页帧 更多...
#include <frame.h>
Public 成员函数 | |
void | reinit () |
reinit 和 reset 在 MemPoolSimple 中使用 更多... | |
void | reset () |
void | clear_page () |
int | buffer_pool_id () const |
void | set_buffer_pool_id (int id) |
Page & | page () |
在磁盘和内存中内容完全一致的数据页 更多... | |
PageNum | page_num () const |
每个页面都有一个编号 更多... | |
void | set_page_num (PageNum page_num) |
FrameId | frame_id () const |
LSN | lsn () const |
为了实现持久化,需要将页面的修改记录记录到日志中,这里记录了日志序列号 更多... | |
void | set_lsn (LSN lsn) |
CheckSum | check_sum () const |
页面校验和 更多... | |
void | set_check_sum (CheckSum check_sum) |
void | access () |
刷新当前内存页面的访问时间 更多... | |
void | mark_dirty () |
标记指定页面为“脏”页。 更多... | |
void | clear_dirty () |
重置“脏”标记 更多... | |
bool | dirty () const |
char * | data () |
bool | can_purge () |
void | pin () |
给当前页帧增加引用计数 pin通常都会加着frame manager锁来访问。 当我们访问某个页面时,我们不期望此页面被淘汰,所以我们会增加引用计数。 | |
int | unpin () |
释放一个当前页帧的引用计数 与pin对应,但是通常不会加着frame manager的锁来访问 | |
int | pin_count () const |
void | write_latch () |
void | write_latch (intptr_t xid) |
void | write_unlatch () |
void | write_unlatch (intptr_t xid) |
void | read_latch () |
void | read_latch (intptr_t xid) |
bool | try_read_latch () |
void | read_unlatch () |
void | read_unlatch (intptr_t xid) |
string | to_string () const |
Private 属性 | |
bool | dirty_ = false |
atomic< int > | pin_count_ {0} |
unsigned long | acc_time_ = 0 |
FrameId | frame_id_ |
Page | page_ |
common::RecursiveSharedMutex | lock_ |
在非并发编译时,加锁解锁动作将什么都不做 | |
common::DebugMutex | debug_lock_ |
使用一些手段来做测试,提前检测出头疼的死锁问题 如果编译时没有增加调试选项,这些代码什么都不做 | |
intptr_t | write_locker_ = 0 |
int | write_recursive_count_ = 0 |
unordered_map< intptr_t, int > | read_lockers_ |
友元 | |
class | BufferPool |
页帧
页帧是磁盘文件在内存中的表示。磁盘文件按照页面来操作,操作之前先映射到内存中, 将磁盘数据读取到内存中,也就是页帧。
当某个页面被淘汰时,如果有些内容曾经变更过,那么就需要将这些内容刷新到磁盘上。这里有 一个dirty标识,用来标识页面是否被修改过。
为了防止在使用过程中页面被淘汰,这里使用了pin count,当页面被使用时,pin count会增加, 当页面不再使用时,pin count会减少。当pin count为0时,页面可以被淘汰。
void Frame::access | ( | ) |
刷新当前内存页面的访问时间
由于内存是有限的,比磁盘要小很多。那当我们访问某些文件页面时,可能由于内存不足 而要淘汰一些页面。我们选择淘汰哪些页面呢?这里使用了LRU算法,即最近最少使用的页面被淘汰。 最近最少使用,采用的依据就是访问时间。所以每次访问某个页面时,我们都要刷新一下访问时间。
|
inline |
页面校验和
用于校验页面完整性。如果页面写入一半时出现异常,可以通过校验和检测出来。
|
inline |
重置“脏”标记
如果页面已经被写入磁盘文件,则应调用此函数。
|
inline |
为了实现持久化,需要将页面的修改记录记录到日志中,这里记录了日志序列号
如果当前页面从磁盘中加载出来时,它的日志序列号比当前WAL(Write-Ahead-Logging)中的一些 序列号要小,那就可以从日志中读取这些更大序列号的日志,做重做操作,将页面恢复到最新状态,也就是redo。
|
inline |
标记指定页面为“脏”页。
如果修改了页面的内容,则应调用此函数, 以便该页面被淘汰出缓冲区时系统将新的页面数据写入磁盘文件
|
inline |
在磁盘和内存中内容完全一致的数据页
磁盘文件划分为一个个页面,每次从磁盘加载到内存中,也是一个页面,就是 Page。 frame 是为了管理这些页面而维护的一个数据结构。
|
inline |
每个页面都有一个编号
当前页面编号记录在了页面数据中,其实可以不记录,从磁盘中加载时记录在Frame信息中即可。
|
inline |
reinit 和 reset 在 MemPoolSimple 中使用
在 MemPoolSimple 分配和释放一个Frame对象时,不会调用构造函数和析构函数, 而是调用reinit和reset。