db_impl.cc Memtable落盘分析和SST文件合并

一、db_impl.cc分析

  1. 调用WriteLevel0Table把Memtable落盘,在VersionEdit存储新增文件信息
    1. 遍历Memtable,调用TableBuilder::Add把key_value写入文件
    2. 调用Finish
    3. 调用sync把缓冲区强制写入磁盘
    4. 生成SST文件
    5. 为新的SST文件挑选level,并且修改VersionEdit,添加一个文件记录,更新level层的统计信息
  2. 调用LogAndApply把VersionEdit更新应用到leveldb的版本库
  3. 调用RemoveObsoleteFiles删除废弃文件

二、SST文件合并

功能:把底层的文件合并到高层去

默认的分层size表:

l1 l2 l3 l4 l5 l6
1M 10M 100M 1000M 10000M 100000M

L0是通过文件数量来限制的,合并发生在相邻两层之间,比如le和le+1层;首先在le层查找选中文件有key,然后去le+1选择重叠的文件,被合并的文件删除

函数功能:

  • background_compaction()
  1. 有Immutable Memtable,完成immu的落盘,把imm转为SST文件放入l0~l2层
  2. 选择要合并(PickCompaction)的level,以及le和le+1层合并的文件,结果放在compaction中
  3. c!=null:判断是否可以把le层文件移动到le+1层,能(31),不能(32)
    1. 31:选择le层文件为1,le+1层文件为0,且唯一的文件和le+2层有key范围重叠的文件总size<阈值,才为true,然后直接移走文件
    2. 32:正常合并,调用DoCompactionWork完成合并
  • PickCompaction()
    • 选择level和level层的文件:size_compaction/seek_compaction
    • 选择leve+1层的文件,存在input[1]中
    • SetupOtherInputs
      • 检查input_[0]中的文件input_file和level层的文件levelfile
      • 检查是否能不在增加level+1层要合并的文件数量的同时增加level层选中的文件数量
  • DoCompactionWork()
    • 获取最旧的仍然在被使用的快照(版本号sequece)
    • 合并这些SST文件就是合并多个有序列表.MakeInputIterator对这个逻辑封装,返回的iterator
    • 把Iterator指向第一个key,然后初始化些字段
    • 结束当前文件,所有输出文件已完成
    • 更新统计信息和版本信息

三、compaction

  1. Minor Compaction: 一次内存教据的特久化这程,产出是一个0层的sstable文件
    1. 每次compaction结束后,会生成新的sstable文件,leveldb的版本状态发生了变化,1的优先级高于2
  2. Major Conpactior: 将0层中的文件合并 为若干个没有数据重叠的1层文件,对不同的版本的教据项进行合并
    1. 触发2的条件:当0层文件数超过预定的上限(4个)、当leveli层文件的总大小超过(10^i)M、当某个文件无效读取的次数过多

整个compaction可以分为以下几步:

  • 寻找合适的输入文件---->根据key的重叠情况扩大输入文件集合----->多路合并------>积分计算

 

posted @ 2022-03-02 09:44  Z9Y1J5  阅读(72)  评论(0编辑  收藏  举报