diff --git a/src/meta/src/hummock/compaction/level_selector.rs b/src/meta/src/hummock/compaction/level_selector.rs index e5a2c61e27d6c..ede6f572a48fd 100644 --- a/src/meta/src/hummock/compaction/level_selector.rs +++ b/src/meta/src/hummock/compaction/level_selector.rs @@ -397,7 +397,6 @@ impl DynamicLevelSelectorCore { max_size * SCORE_BASE * (level.vnode_partition_count as u64) / ctx.level_max_bytes[level_idx], ); - // Reduce the level num of l0 non-overlapping sub_level ctx.score_levels.push(PickerInfo { score, select_level: level_idx, @@ -405,7 +404,6 @@ impl DynamicLevelSelectorCore { picker_type: PickerType::BaseLevelCompaction(ctx.target_partitions.clone()), }); } else { - // Reduce the level num of l0 non-overlapping sub_level ctx.score_levels.push(PickerInfo { score, select_level: level_idx, diff --git a/src/meta/src/hummock/compaction/mod.rs b/src/meta/src/hummock/compaction/mod.rs index 825e247e2702d..a52daf3b3bfdd 100644 --- a/src/meta/src/hummock/compaction/mod.rs +++ b/src/meta/src/hummock/compaction/mod.rs @@ -185,6 +185,7 @@ impl CompactStatus { &task.input_ssts[0].table_infos, ) { + // If this level can not be partitioned, we must compact it at least once. return false; } if task.input_ssts.len() == 1 { diff --git a/src/meta/src/hummock/compaction/picker/partition_intral_sub_level_picker.rs b/src/meta/src/hummock/compaction/picker/partition_intral_sub_level_picker.rs index 79a9be98d9abc..8560644c5d3a3 100644 --- a/src/meta/src/hummock/compaction/picker/partition_intral_sub_level_picker.rs +++ b/src/meta/src/hummock/compaction/picker/partition_intral_sub_level_picker.rs @@ -130,16 +130,12 @@ impl PartitionIntraSubLevelPicker { } None } -} -impl CompactionPicker for PartitionIntraSubLevelPicker { - fn pick_compaction( - &mut self, + fn pick_whole_level( + &self, levels: &Levels, level_handlers: &[LevelHandler], - stats: &mut LocalPickerStatistic, ) -> Option { - assert!(levels.can_partition_by_vnode()); let l0 = levels.l0.as_ref().unwrap(); let max_sub_level_id = self .partitions @@ -162,7 +158,7 @@ impl CompactionPicker for PartitionIntraSubLevelPicker { } if levels.vnode_partition_count == 0 - && level.total_file_size > self.config.sub_level_max_compaction_bytes / 2 + && level.total_file_size > self.config.sub_level_max_compaction_bytes { continue; } @@ -236,9 +232,17 @@ impl CompactionPicker for PartitionIntraSubLevelPicker { vnode_partition_count, }); } + None + } + fn pick_partition( + &mut self, + levels: &Levels, + level_handlers: &[LevelHandler], + stats: &mut LocalPickerStatistic, + ) -> Option { let mut skip_pending_compact = false; - + let l0 = levels.l0.as_ref().unwrap(); for part in &self.partitions { for (idx, info) in part.sub_levels.iter().enumerate() { if info.total_file_size > self.config.sub_level_max_compaction_bytes / 2 { @@ -309,6 +313,26 @@ impl CompactionPicker for PartitionIntraSubLevelPicker { } else { stats.skip_by_count_limit += 1; } + None + } +} + +impl CompactionPicker for PartitionIntraSubLevelPicker { + fn pick_compaction( + &mut self, + levels: &Levels, + level_handlers: &[LevelHandler], + stats: &mut LocalPickerStatistic, + ) -> Option { + assert!(levels.can_partition_by_vnode()); + if let Some(input) = self.pick_whole_level(levels, level_handlers) { + return Some(input); + } + + if let Some(input) = self.pick_partition(levels, level_handlers, stats) { + return Some(input); + } + self.pick_l0_trivial_move_file(levels.l0.as_ref().unwrap(), level_handlers, stats) } }