背景
我们知道Rocksdb的compact触发方式大概分为两种
1 系统内部整理(例如某层文件太多,某层里面某个sst的墓碑太多等等)
2 用户手动调用。
调用方法
Options dbOptions;
DB* db;
Status s = DB::Open(dbOptions, "/tmp/rocksdb", &db);
// Write some data
...
Slice begin("key1");
Slice end("key100");
CompactRangeOptions options;
s = db->CompactRange(options, &begin, &end);
假定目前L0-L6的sst数量分别是0 3 35 390 600 0 0 ,那么包含sst的最下面一层就是L4。
执行上面的逻辑后,系统就会把L4之前在key1和key100范围内的sst都一层一层合并,最终保证在key1和key100范围内的sst都处于L4层。
还有一种调用方式就是db->CompactRange(options, nullptr, nullptr);
那就是把所有的sst都合并到L4层。
个人认为手动compact里面最核心的一个参数就是 exclusive_manual_compaction
它默认是true,也就是说,如果我现在手动进行了一次compact,那么在我手动的compact执行完成之前,系统不会再进行内部的compact。也就是说即使L0的sst都满了,也不会把L0的sst往下刷,直到手动compact完成。
我已经没想明白为什么要这样,手动compact本身就是个低级别的事情,为什么要阻碍系统内部的compact呢?
阻塞的逻辑在DBImpl::HasExclusiveManualCompaction里。
那要怎么才能不阻塞内部compact呢?
把exclusive_manual_compaction改成false即可。
另外在每层进行compact的时候,max_compaction_bytes这个参数会生效。也就是一次compact源层的文件最大大小就是25倍的target_file_size_base。
这部分逻辑在 CompactionPicker::CompactRange里面。
为什么系统compact的时候,没有进行max_compaction_bytes的校验?
系统compact的时候,都是源层找一个 然后慢慢扩展,我认为是开发者觉得,源层不会有超过25个文件需要一次进行compact。
参考资料
https://wanghenshui.github.io/rocksdb-doc-cn/doc/Manual-Compaction.html