前文回顾
内容上,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_;
- comparator_:比较器的名称,这个在创建 LevelDB 的时候就确定了,以后都不能修改。
- log_number_:最小的有效 log number。小于 log_numbers_ 的 log 文件都可以删除。
prev_log_number_:已经废弃,代码保留是为了兼容旧版本的 LevelDB。- next_file_number_:下一个文件的编号 。
- last_sequence_:SSTable 中的最大的 sequence number。
- compact_pointers_:记录每一层要进行下一次 compaction 的起始 key。
- deleted_files_:可以删除的 SSTable(level-no -> file-no)。
- new_files_:新增的 SSTable。
VersionEdit 通过成员函数 EncodeTo 和 DecodeFrom 进行序列化和反序列化。一个全部字段都填上的 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
VersionApplyVersion 是 VersionEdit 进行 apply 之后得到的数据库状态——当前版本包含哪些 SSTable,并通过引用计数保证多线程并发访问的安全性。读操作要读取 SSTable 之前需要调用 Version::Ref 增加引用计数,不使用时需要调用 Version::UnRef 减少引用计数。
VersionSet
VersionSet 是一个 Version 的集合。
随着数据库状态的变化,LevelDB 内部会不停地生成 VersionEdit——进而产生新的 Version。此时,旧的 Version 可能还在被正在执行的请求使用。所以,同一时刻可能存在多个 Version。
VersionSet 用一个链表将这些 Version 维护起来,每生成一个 Version 就往这个链表尾部插入一个节点(AppendVersion)。
更多的细节会留在读操作与 Compaction 的时候介绍。
网友评论