高級數據庫課程實驗記錄 - 實現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作爲偏移量的類型之後使用該選項編譯運行即可

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章