LevelDB 完全解析(4):Manifest

前文回顾

内容上,Manifest 文件保存了整个 LevelDB 实例的元数据,比如:每一层有哪些 SSTable。

格式上,Manifest 文件其实就是一个 log 文件,一个 log record 就是一个 VersionEdit

VersionEdit

LevelDB 用 VersionEdit 来表示一次元数据的变更。Manifest 文件保存 VersionEdit 序列化后的数据。LevelDB 的元数据变更包括:

std::string comparator_;
uint64_t log_number_;
uint64_t prev_log_number_;
uint64_t next_file_number_;
SequenceNumber last_sequence_;

std::vector<std::pair<int, InternalKey> > compact_pointers_;
DeletedFileSet deleted_files_;
std::vector<std::pair<int, FileMetaData> > new_files_;
复制代码
  1. comparator_:比较器的名称,这个在创建 LevelDB 的时候就确定了,以后都不能修改。
  2. log_number_:最小的有效 log number。小于 log_numbers_ 的 log 文件都可以删除。
  3. prev_log_number_:已经废弃,代码保留是为了兼容旧版本的 LevelDB。
  4. next_file_number_:下一个文件的编号 。
  5. last_sequence_:SSTable 中的最大的 sequence number。
  6. compact_pointers_:记录每一层要进行下一次 compaction 的起始 key。
  7. deleted_files_:可以删除的 SSTable(level-no -> file-no)。
  8. new_files_:新增的 SSTable。

VersionEdit 通过成员函数 EncodeToDecodeFrom 进行序列化和反序列化。一个全部字段都填上的 VersionEdit 序列化后的内容格式如下(注意,并不是每个 VersionEdit 都会由下面所有字段的内容,一般只有一部分):

kComparator comparator_
kLogNumber log_number_
kPrevLogNumber prev_log_number_
kNextFileNumber next_file_number_
kLastSequence last_sequence_
kCompactPointer level internal_key kCompactPointer level internal_key ...
kDeletedFile level fileno kDeletedFile level fileno ...
kNewFile level fileno file-size smallest largest kNewFile level fileno file-size smallest largest ...
复制代码

Version

VersionApply

Version 是 VersionEdit 进行 apply 之后得到的数据库状态——当前版本包含哪些 SSTable,并通过引用计数保证多线程并发访问的安全性。读操作要读取 SSTable 之前需要调用 Version::Ref 增加引用计数,不使用时需要调用 Version::UnRef 减少引用计数。

VersionSet

VersionSet 是一个 Version 的集合。

随着数据库状态的变化,LevelDB 内部会不停地生成 VersionEdit——进而产生新的 Version。此时,旧的 Version 可能还在被正在执行的请求使用。所以,同一时刻可能存在多个 Version。

VersionSet 用一个链表将这些 Version 维护起来,每生成一个 Version 就往这个链表尾部插入一个节点(AppendVersion)。

更多的细节会留在读操作与 Compaction 的时候介绍。

猜你喜欢

转载自juejin.im/post/5ea9cc0b5188256d6c59466b