高级数据库课程实验记录 - 实现Storage and Buffer Manager

简介: USTC计算机院高级数据库课程实验1 - 实现Storage and Buffer Manager. 源代码在我的Github上advance_db_exp1,欢迎star(issue)。

功能需求描述

数据管理模块 DataStorageManager

提供记录的增改查操作,作为DBMS的底层模块,为上层缓冲区管理模块提供接口。

  • 下层: 调用操作系统提供的文件系统,实现目录式的记录管理
  • 上层: 提供读取读取/更新某个页,写入新页等功能
  • 外部接口
    • 初始化相关文件信息
    • 读取page
    • 写入新page
    • 更新page
    • 获取页数、IO总数
  • 内部接口
    • 打开、关闭文件
    • 读取、更新目录
    • 读取某个目录
  • 实现方式优缺点
    • 优点: 扩展性更好,可以存储变长记录
    • 缺点: 读取目录会增加IO次数,实现更复杂
    • 权衡: 重用内存内部的目录,不需要每次从0号目录开始读取

缓冲区管理 BufferManager

提供基于LRU的缓存管理功能,提高记录读取/更新的效率。为上层SQL执行模块提供接口,下层调用数据管理模块的接口执行数据更新。

  • 上层为记录查询提供增删改查功能
  • 下层调用数据管理接口的功能
  • 外部接口
    • 读取某个page内容
    • 更新某个page内容
    • 增加一个新page
    • 获取某个frame
    • 获取命中率
    • 获取IO总数
    • 获取LRU头、尾信息
    • 将所有脏页写入磁盘
    • 获取可用frame数目
  • 内部接口
    • 根据淘汰算法选择受害者
    • 设置/取消设置一个页为脏页
    • 将所有脏页写入磁盘
    • 打印一个frame的内容
    • 根据LRU算法更新一个缓冲块
    • 根据LRU算法插入一个新的缓冲块

数据结构设计

DataStorageManager

页大小为8KB,使用一页作为目录,存储N=(8*1024/4)=2*1024个页地址和下一个目录表的地址。其中页地址与目录表地址为偏移量,使用长整数(4Byte)表示。目录表信息用于重用目录。

  • 文件指针: FILE* fp
  • 页数: numpages
  • 目录表: contents -> int[], 在堆上分配
  • 目录表信息: 目录的偏移量与序号
    • 当前目录在文件中的偏移量: cur_content_offset
    • 当前目录的序号: cur_content_id

BufferManager

  • 缓冲区: buffer[]
  • 缓冲区大小: size
  • 链表首/尾: head_frame_id, tail_frame_id
  • frame->page: frame2page[] 数组
  • page->frame: page2frame[] 哈希表
  • 缓冲块信息(链表节点): bcb[] -> { frame_id, page_id, dirty, count, prev_frame_id, next_frame_id }
    • 链表结构与哈希表结合使用,使用缓冲块信息保存

运行结果

每次执行freadfwrite时增加一次IO,总IO数为1383506,IO曲线与命中率曲线如下:
命中率曲线
IO计数曲线

问题与解决

  • fread莫名遇到eof,fseek、ftell都没问题: 打开文件时指定b,即以二进制方式打开,如下为fseek相关信息

    For streams open in binary mode, the new position is defined by adding offset to a reference position specified by origin. For streams open in text mode, offset shall either be zero or a value returned by a previous call to ftell, and origin shall necessarily be SEEK_SET.

  • 目录读取IO过多: 重用内存中的目录

  • vscode莫名抛出 无法打开…cygwin.s: 由于栈内数组开的过大,造成了调试器启动失败!!!

  • 文件太大,偏移量无法使用int存下?: 并不是文件太大,int作偏移量时文件理论最大值为2GB,所以是因为输入数据中有不正常的数据(50000).另外gcc的 -D_FILE_OFFSET_BITS=64 能够将off_t定义为64位的,因此使用off_t作为偏移量的类型之后使用该选项编译运行即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值