diff --git a/fluss-server/src/main/java/org/apache/fluss/server/coordinator/AutoPartitionManager.java b/fluss-server/src/main/java/org/apache/fluss/server/coordinator/AutoPartitionManager.java index 695c770d45..5164a5c920 100644 --- a/fluss-server/src/main/java/org/apache/fluss/server/coordinator/AutoPartitionManager.java +++ b/fluss-server/src/main/java/org/apache/fluss/server/coordinator/AutoPartitionManager.java @@ -335,10 +335,13 @@ private void doAutoPartition(Instant now, Set tableIds, boolean forceDoAut continue; } + // Use the actual current time for drop to ensure timely cleanup. + // The random delay is only meant for spreading partition creation load, + // not for delaying retention cleanup. dropPartitions( tablePath, tableInfo.getPartitionKeys(), - createPartitionInstant, + now, tableInfo.getTableConfig().getAutoPartitionStrategy(), currentPartitions); createPartitions(tableInfo, createPartitionInstant, currentPartitions); diff --git a/fluss-server/src/test/java/org/apache/fluss/server/coordinator/AutoPartitionManagerTest.java b/fluss-server/src/test/java/org/apache/fluss/server/coordinator/AutoPartitionManagerTest.java index 5114ee1156..ba0088f17f 100644 --- a/fluss-server/src/test/java/org/apache/fluss/server/coordinator/AutoPartitionManagerTest.java +++ b/fluss-server/src/test/java/org/apache/fluss/server/coordinator/AutoPartitionManagerTest.java @@ -510,6 +510,55 @@ void testAutoCreateDayPartitionShouldJitter() throws Exception { "20250419", "20250420", "20250421", "20250422", "20250423"); } + @Test + void testDayPartitionDropShouldNotBeDelayedByJitter() throws Exception { + ZonedDateTime startTime = + LocalDateTime.parse("2025-04-19T00:00:00").atZone(ZoneId.systemDefault()); + long startMs = startTime.toInstant().toEpochMilli(); + ManualClock clock = new ManualClock(startMs); + ManuallyTriggeredScheduledExecutorService periodicExecutor = + new ManuallyTriggeredScheduledExecutorService(); + AutoPartitionManager autoPartitionManager = + new AutoPartitionManager( + new TestingServerMetadataCache(3), + metadataManager, + new Configuration(), + clock, + periodicExecutor); + autoPartitionManager.start(); + + // Create a DAY-partitioned table: numRetention=2, numPreCreate=4 + TableInfo table = createPartitionedTable(2, 4, AutoPartitionTimeUnit.DAY); + TablePath tablePath = table.getTablePath(); + autoPartitionManager.addAutoPartitionTable(table, true); + periodicExecutor.triggerNonPeriodicScheduledTasks(); + + Map partitions = + zookeeperClient.getPartitionRegistrations(tablePath); + // Initial: 20250419, 20250420, 20250421, 20250422 + assertThat(partitions.keySet()) + .containsExactlyInAnyOrder("20250419", "20250420", "20250421", "20250422"); + + Integer delayMinutes = + autoPartitionManager.getAutoCreateDayDelayMinutes(table.getTableId()); + assertThat(delayMinutes).isNotNull(); + + // Advance exactly 3 days to 2025-04-22T00:00:00. + // From 'now' perspective: current day is 20250422, retain 2 => keep 20250420, 20250421. + // So 20250419 should be dropped. + // + // With the bug (drop used delayed time): if delay > 0, delayed time would still + // be on 20250421, retain 2 => keep 20250419, 20250420 => 20250419 NOT dropped. + clock.advanceTime(Duration.ofDays(3)); + periodicExecutor.triggerPeriodicScheduledTasks(); + + partitions = zookeeperClient.getPartitionRegistrations(tablePath); + // 20250419 must be dropped regardless of jitter delay + assertThat(partitions.keySet()).doesNotContain("20250419"); + // Retained partitions should still exist + assertThat(partitions.keySet()).contains("20250420", "20250421", "20250422"); + } + /** * Test if AutoPartionManager.createPartition adheres to maxBucketLimit while adding new * parition automatically, skip if it breaches limit.