前文回顧
- LevelDB 完全解析(0):基本原理和整體架構
- LevelDB 完全解析(1):MemTable
- LevelDB 完全解析(2):Log
- LevelDB 完全解析(3):SSTable
- LevelDB 完全解析(4):Manifest
- LevelDB 完全解析(5):Cache
- LevelDB 完全解析(6):Filter
一個 LevelDB 實例初始化的主要任務包括:
- 從 Manifest 文件恢復各個 level 的 SSTable 的元數據。
- 根據 log 文件恢復 MemTable。
- 恢復 last_sequence_、next_file_numbe_等元信息。
DB::Open
一個 LevelDB 實例的初始化是從 DB::Open 這個函數開始的:
Status DB::Open(const Options& options, const std::string& dbname, DB** dbptr);
options - 打開/創建 LevelDB 實例的配置參數。
dbname - 保存數據的目錄名。
dbptr - 初始化成功的 LevelDB 實例保存在 *dbptr。
DB::Open 的執行邏輯:
- 創建 DBImpl 對象:DBImpl 的構造函數會做一些簡單的初始化工作。
- 調用 DBImpl::Recover。
- 根據條件決定是否需要創建新的 MemTable。
- 根據條件決定是否需要保存 Manifest。
- 刪除過期文件,調度后臺的 compaction 任務。
重點是第 2 步。
DBImpl::Recover
DBImpl::Recover 是 LevelDB 初始化的主要邏輯:
- 根據參數判斷是否要創建新的數據庫。
- 從 Manifest 文件恢復各個 level 的 SSTable 的元數據:調用 VersionSet::Recover 讀取 Manifest 的內容。
- 文件檢查:1)外存上的文件是否和 Manifest 的內容一致;2)收集需要恢復的 log 文件。
- 根據 log 文件恢復 MemTable:針對每個 log 文件調用 RecoverLogFile,同時更新 next_file_numbe_。
- 更新 last_sequence_。