专栏首页linjinhe的专栏LevelDB 完全解析(4):Manifest

LevelDB 完全解析(4):Manifest

前文回顾

  • LevelDB 完全解析(0):基本原理和整体架构
  • LevelDB 完全解析(1):MemTable
  • LevelDB 完全解析(2):Log
  • LevelDB 完全解析(3):SSTable

内容上,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 的时候介绍。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • LevelDB 完全解析(3):SSTable

    SSTable 全称 Sorted String Table,顾名思义,里面的 key-value 都是有序保存的。除了两个 MemTable,LevelDB ...

    linjinhe
  • LevelDB:读操作

    前面写了两篇文章介绍 LevelDB 的整体架构和接口使用。这篇文章,我们从代码的角度看看 LevelDB 的设计与实现,先从读操作开始。

    linjinhe
  • Linux动态链接

    曾经不止一次遇到过这样的情况:从机器A拷贝一个二进制文件到另一台机器B,两台机器的操作系统版本一样,可是在机器A能正常运行,在机器B却提示错误。最常见的就是提示...

    linjinhe
  • 索引

    最简单的索引策略就是:将key值的offset存入在内存,使用hash表进行管理,在搜索时,会先根据key值找到offset,进而由offset找到对应的v...

    哒呵呵
  • Spring Boot核心配置

    启动类 在包根目录下添加启动类,必须包含main方法,再添加Spring Boot启动方法: SpringApplication.run(SampleContr...

    Java技术栈
  • 你买不到的酒,黄牛都有

    某白酒品牌的"黑市成交价"又双叒叕涨了。 几个月前还能用2000块钱拿下的一瓶酒,如今已经涨破了2400元大关。一方面,官方渠道上明码标价1000多元的价格常...

    腾讯大讲堂
  • 你买不到的酒,黄牛都有

    某白酒品牌的"黑市成交价"又双叒叕涨了。 几个月前还能用2000块钱拿下的一瓶酒,如今已经涨破了2400元大关。一方面,官方渠道上明码标价1000多元的价格常...

    腾讯防水墙
  • 谈谈身份与访问管理(IAM)的12大趋势

    你可能已经注意到,在刚结束不久的RSA大会上大量讨论围绕“身份”展开,而且很多公司也开始将自己的产品贴上“身份与访问管理(IAM)”的标签,大谈“身份治理”、“...

    FB客服
  • 喜大普奔!Django官方文档终于出中文版了

    之前对于 Django 的学习我一直推荐看官方文档,但不得不加上一句“如果你英语水平允许的话……”。现在总算是等来好日子了。各位想向网站/服务器开发方向进阶的同...

    Crossin先生
  • Android中AsyncTask的入门使用学习指南

    我们都知道,Android UI线程中不能执行耗时的任务,否则就会出现ANR。对于耗时的操作就需要放到子线程中操作,操作完成后需要通知UI线程进行更新等操作,这...

    砸漏

扫码关注云+社区

领取腾讯云代金券