Leveldb: Compaction
July 14, 2019
Database Leveldb[TOC]
LevelDb通过周期性地利用归并排序对磁盘文件执行合并操作 (compaction):移除已删除和冗余数据,减少文件个数,保证读操作性能。
LevelDB中,Compaction分成两种,就如同Linux操作系统中的page fault分成minor和major一样:
- minor compaction:在合适的时机,将Immutable MemTable dump到磁盘,形成SSTable
- major compaction:文件数目过多或者某个level的文件总大小过大,引起compacction
compaction 整体流程
Compaction操作入口实际由DBImpl::MaybeScheduleCompaction控制。追踪该函数的调用场景,就可以知道触发Compaction的时机。 整体流程如下所示:
void DBImpl::MaybeScheduleCompaction() {
mutex_.AssertHeld();
if (bg_compaction_scheduled_) {
// Already scheduled
} else if (shutting_down_.Acquire_Load()) {
// DB is being deleted; no more background compactions
} else if (!bg_error_.ok()) {
// Already got an error; no more changes
} else if (imm_ == NULL &&
manual_compaction_ == NULL &&
!versions_->NeedsCompaction()) {
/*防止无限递归,会判断需不需要再次Compaction,如果不需要就返回了*/
// No work to be done
} else {
bg_compaction_scheduled_ = true;
env_->Schedule(&DBImpl::BGWork, this);
}
}
从这段代码可以看出发起Compction需要的条件,三个条件满足一个即可发起Compaction:
imm_ != NULL
表示需要将Memtable dump成SSTable,发起Minor Compactionmanual_compaction_ != NULL
表示手动发起Compactionversions_->NeedsCompaction
函数返回True
Minor Compaction
leveldb之Compaction (1) –从MemTable到SSTable文件
Major Compaction
leveldb之Compaction (2)–何时需要Compaction