FIFO compaction 適用于低負載數(shù)據的存儲(如日志)乍桂,所有的文件都位于 L0冲杀。當文件總大小超過配置值 CompactionOptionsFIFO::max_table_files_size (默認值為 1GB) 時效床,最早的 SST 文件將會被刪除。
Compaction* FIFOCompactionPicker::PickSizeCompaction(
...
std::vector<CompactionInputFiles> inputs;
inputs.emplace_back();
inputs[0].level = 0;
for (auto ritr = level_files.rbegin(); ritr != level_files.rend(); ++ritr) {
auto f = *ritr;
total_size -= f->compensated_file_size;
inputs[0].files.push_back(f);
char tmp_fsize[16];
AppendHumanBytes(f->fd.GetFileSize(), tmp_fsize, sizeof(tmp_fsize));
ROCKS_LOG_BUFFER(log_buffer,
"[%s] FIFO compaction: picking file %" PRIu64
" with size %s for deletion",
cf_name.c_str(), f->fd.GetNumber(), tmp_fsize);
// 選擇文件進行 compaction 直到文件總大小小于閾值
if (total_size <=
mutable_cf_options.compaction_options_fifo.max_table_files_size) {
break;
}
}
...
}
L0 IntraCompaction
僅僅如此簡單的 compaction 策略可能會因為 L0 保存了大量的 SST 文件導致查詢性能急劇下降权谁。即使有 bloom filter 的幫助剩檀,甚至可能嚴重到 bloom filter 的開銷大到不可接受的地步。開啟 CompactionOptionsFIFO.allow_compaction 參數(shù)旺芽,可以觸發(fā) L0 IntraCompaction沪猴,每次至少選取 level0_file_num_compaction_trigger 個 SST 文件進行合并,從而減少文件數(shù)量采章。
以 level0_file_num_compaction_trigger = 2运嗜,每個 flush 文件大小為 100MB 為例,其 compaction 過程如下:
100MB
100MB 100MB -> 200MB
100MB 200MB
100MB 100MB 200MB -> 200MB 200MB
100MB 200MB 200MB
TTL Compaction
TTL compaction 在 FIFO compaction 的基礎之上悯舟,提供 SST 文件級別的過期刪除功能担租。當 SST 的最新的 key 存在時間超過 mutable_cf_options.ttl,則該 SST 文件將會在 TTL compaction 中被刪除抵怎。
Compaction* FIFOCompactionPicker::PickTTLCompaction(
const std::string& cf_name, const MutableCFOptions& mutable_cf_options,
const MutableDBOptions& mutable_db_options, VersionStorageInfo* vstorage,
LogBuffer* log_buffer) {
...
std::vector<CompactionInputFiles> inputs;
inputs.emplace_back();
inputs[0].level = 0;
// avoid underflow
if (current_time > mutable_cf_options.ttl) {
for (auto ritr = level_files.rbegin(); ritr != level_files.rend(); ++ritr) {
FileMetaData* f = *ritr;
assert(f);
if (f->fd.table_reader && f->fd.table_reader->GetTableProperties()) {
uint64_t creation_time =
f->fd.table_reader->GetTableProperties()->creation_time;
// 判斷文件是否過期
if (creation_time == 0 ||
creation_time >= (current_time - mutable_cf_options.ttl)) {
break;
}
}
total_size -= f->compensated_file_size;
inputs[0].files.push_back(f);
}
}
...