LevelDB 学习笔记5:版本控制_在线工具

2022年5月2日08:49:36

LevelDB 学习笔记5:版本控制

  • 由于压缩是在后台线程异步进行的,所以会出现新老 sstable 同时存在的状态
  • 但合并完成后,老的 sstable 并不能直接删除,必须等到没有人引用它们,才可以删除
  • 因此数据库可能同时存在多个 Version,它们的集合是 VersionSet
    • 所有的 version 组织在一个双向链表里,最新的 version 称为 current

版本变更

  • VersionEdit 是新 Version 相较于旧 Version 变动的内容
    • VersionOld + VersionEdit = VersionNew
    • VersionEdit 对应 MANIFEST 文件里的一条记录
      • EncodeTo()DecodeFrom() 方法分别用于将 VersionEdit 序列化为 manifest 记录和从 MANIFEST 记录中反序列化出 VersionEdit
  • MANIFEST 文件本质上也是日志文件,格式和 redo log 是相同的
    • 第一条记录是全量的 LevelDB 版本信息
    • 后续每一条记录都是 LevelDB 版本变更信息
    • 重启后能通过 MANIFEST 文件恢复版本信息
  • 调用 LogAndApply() 把 VersionEdit 应用到当前版本上,并新增一条记录
    • 以下几种情况下会被调用
      • 打开 DB 的时候,从 MANIFEST 文件中恢复出版本信息后,会在新的 MANIFEST 文件中提交一条全量的版本信息
      • minor compaction 完成后,提交新增的 sstable
      • major compaction 完成后,提交 sstable 变动
  • VersionSet::Builder

    • 帮助执行版本变更的工具类
    • 以某个版本为基础,不断 Apply 版本变更,得到最终的版本
    • LogAndApply() 和从 manifest 文件中恢复版本信息的时候都会用到它
      LevelDB 学习笔记5:版本控制_在线工具

从重启中恢复

从重启中恢复需要做两件事

  • 恢复版本信息
  • 重做 WAL 中记录的操作恢复 memtable 中的内容

恢复版本信息

  • 主要逻辑在 VersionSet::Recover()
  • 读取 current 文件的内容找到 MANIFEST 文件名
  • 遍历 manifest 文件,将所有记录 Apply 到 Version Builder 上
  • 从 Builder 中获得最终的 Version,将它加入 VersionSet,并作为当前版本使用
  • 检查现存的 MANIFEST 文件能否重用
    • 如果旧的 MANIFEST 文件大小不是太大就可以重用它
    • 因为重启是唯一一处 MANIFEST 文件大小缩小的地方,我们不想让 MANIFEST 文件大小无限增长
  • 如果不能重用,就会提交一条 MANIFEST 记录到新的 MANIFEST 文件里,包含了当前版本的全量信息

恢复 memtable 中的内容

  • 主要逻辑在 DBImpl::Recover() 的后半部分
  • 收集需要 redo 的日志文件
    • 做 minor compaction 后,修改记录会被写到 MANIFEST 文件中,其中包括日志文件的文件号
    • 因此 MANIFEST 中最新记录的日志文件号就是最后被写入磁盘的 memtable 的日志文件号,文件号大于它的日志文件都视为需要 redo 的
  • redo
    • 根据文件号顺序,遍历所有需要 redo 的日志文件
    • 将日志记录转换为 WriteBatch
    • redo 过程中,如果发现 memtable 大小超过阈值,直接对它做 minor compaction

Repairer

如果 MANIFEST 文件丢失,那么能否恢复出版本信息呢?

答案是可以的,LevelDB 提供了 Repairer 类用来从日志文件和 sstable 文件中恢复出版本信息

  • 所有日志文件都会被转换为 sstable 文件
  • 扫描所有 sstable 文件并计算
    • 最大最小 key
    • 最大序列号
  • 用这些信息恢复上次运行的版本信息

恢复过程遍历了整个 DB 的全部文件,所以是相当耗时的过程

  • 作者:路过的摸鱼侠
  • 原文链接:https://www.cnblogs.com/ljx-null/p/16163412.html
    更新时间:2022年5月2日08:49:36 ,共 1504 字。