13

LevelDB 完全解析(四):Manifest

 4 years ago
source link: https://mp.weixin.qq.com/s/LX_l5SQq7Bb7Cxv__67t3w
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

前文回顾

文中“蓝色字体”部分均有跳转,大部分是引用了 Github 上的源码链接,可以点击【阅读原文】查看。

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

格式上,Manifest 文件其实就是一个 log 文件 [1] 。

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 通过成员函数 EncodeTo [2] 和 DecodeFrom [3] 进行序列化和反序列化。一个全部字段都填上的 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

J7VvUfR.png!web VersionApply

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

VersionSet

VersionSet [10] 是一个 Version 的集合。

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

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

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

mYFrMzr.jpg!web

参考资料

[1]

log 文件: https://mp.weixin.qq.com/s/Ry7FRClFz8XRut_fSYlX2g

[2]

EncodeTo: https://github.com/google/leveldb/blob/1.22/db/version_edit.cc#L41

[3]

DecodeFrom: https://github.com/google/leveldb/blob/1.22/db/version_edit.cc#L107

[4]

Version: https://github.com/google/leveldb/blob/1.22/db/version_set.h#L60

[5]

apply: https://github.com/google/leveldb/blob/1.22/db/version_set.cc#L801

[6]

包含哪些 SSTable: https://github.com/google/leveldb/blob/1.22/db/version_set.h#L154

[7]

引用计数: https://github.com/google/leveldb/blob/1.22/db/version_set.h#L151

[8]

Version::Ref: https://github.com/google/leveldb/blob/1.22/db/version_set.cc#L474

[9]

Version::UnRef: https://github.com/google/leveldb/blob/1.22/db/version_set.cc#L476

[10]

VersionSet: https://github.com/google/leveldb/blob/1.22/db/version_set.h#L167

[11]

链表: https://github.com/google/leveldb/blob/1.22/db/version_set.h#L310

[12]

AppendVersion: https://github.com/google/leveldb/blob/1.22/db/version_set.cc#L784


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK