Description
Repro
Start with an empty database and assuming L0-L6 configured. Set one kv pair and run CompactRange
on everything. With level_compaction_dynamic_level_bytes
set, we'll end up with 1 file in L6 and nothing else. But if CompactRangeOptions.change_level
is set, we'll end up with 1 file in L1, which is not the ideal behavior under level_compaction_dynamic_level_bytes
.
Root cause
The problem is with change_level
set, CompactRange
will first generate 1 file in L6, then it will call DBImpl::ReFitLevel
, which will try to move the file in L6 to the minimum level that could hold the data set. It calls FindMinimumEmptyLevelFitting
to find such level, but note it finds the minimum level, not taking into account the base level restriction as calculated by level_compaction_dynamic_level_bytes
. Even more concretely, DBImpl::FindMinimumEmptyLevelFitting
should take into account VersionStorageInfo.lowest_unnecessary_level_
and stop there, instead of trying find an even lower number.
This is related to apache/kvrocks#2601