一起写个数据库 —— 3. 数据页的缓存与管理

本文介绍了数据库管理模块DM如何将文件系统抽象为页面,实现页面缓存,包括默认页大小、缓存结构与操作。重点讲解了第一页的特殊用途、元数据存储以及普通页的管理,如数据插入和空闲空间管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文原载于我的博客:https://ziyang.moe/article/mydb3.html

本章涉及代码都在 https://github.com/CN-GuoZiyang/MYDB/tree/master/src/main/java/top/guoziyang/mydb/backend/dm/pageCachehttps://github.com/CN-GuoZiyang/MYDB/tree/master/src/main/java/top/guoziyang/mydb/backend/dm/page 中。

前言

本节主要内容就是 DM 模块向下对文件系统的抽象部分。DM 将文件系统抽象成页面,每次对文件系统的读写都是以页面为单位的。同样,从文件系统读进来的数据也是以页面为单位进行缓存的。

页面缓存

这里参考大部分数据库的设计,将默认数据页大小定为 8K。如果想要提升向数据库写入大量数据情况下的性能的话,也可以适当增大这个值。

上一节我们已经实现了一个通用的缓存框架,那么这一节我们需要缓存页面,就可以直接借用那个缓存的框架了。但是首先,需要定义出页面的结构。注意这个页面是存储在内存中的,与已经持久化到磁盘的抽象页面有区别。

定义一个页面如下:

public class PageImpl implements Page {
   
    private int pageNumber;
    private byte[] data;
    private boolean dirty;
    private Lock lock;
    
    private PageCache pc;
}

其中,pageNumber 是这个页面的页号,该页号从 1 开始。data 就是这个页实际包含的字节数据。dirty 标志着这个页面是否是脏页面,在缓存驱逐的时候,脏页面需要被写回磁盘。这里保存了一个 PageCache(还未定义)的引用,用来方便在拿到 Page 的引用时可以快速对这个页面的缓存进行释放操作。

定义页面缓存的接口如下:

public interface PageCache {
   
    int newPage(byte[] initData);
    Page getPage(int pgno) throws Exception;
    void close();
    void release(Page page);

    void truncateByBgno(int maxPgno);
    int getPageNumber();
    void flushPage(Page pg);
}

页面缓存的具体实现类,需要继承抽象缓存框架,并且实现 getForCache()releaseForCache() 两个抽象方法。由于数据源就是文件系统,getForCache() 直接从文件中读取,并包裹成 Page 即可:

@Override
protected Page getForCache(long key) throws Exception {
   
    int pgno = (int)key;
    long offset = PageCacheImpl.pageOffset(pgno);

    ByteBuffer buf 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值