This is an automated email from the ASF dual-hosted git repository.
cecemei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/master by this push:
new 86b6ae95aaf feat: add `skipIntervals` to `DataSourceCompactionConfig`
(#19792)
86b6ae95aaf is described below
commit 86b6ae95aaff250d8db1312473031a4bfea2f786
Author: Cece Mei <[email protected]>
AuthorDate: Fri Jul 31 10:06:52 2026 -0700
feat: add `skipIntervals` to `DataSourceCompactionConfig` (#19792)
* skip
* format
* test
* fix
* fix: correct compaction config test after MetadataCatalog constructor
change
Pass null for the MetadataCatalog arg in AutoCompactionUpgradeTest since
it's only used to serialize a JSON config, and fix a stale comment in
DataSourceCompactibleSegmentIteratorTest that didn't match the assertion.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
* fix: honor configured skipIntervals in coordinator compaction duty
DataSourceCompactibleSegmentIterator now reads config.getSkipIntervals()
directly in findInitialSearchInterval, the same way it already reads
config.getSkipOffsetFromLatest(), instead of relying on callers to merge
it into the skipIntervals parameter. Previously only the supervisor job
template did this merge, so the legacy Coordinator duty path silently
ignored configured skipIntervals. Also simplifies
CompactionConfigBasedJobTemplate to use Intervals.complementOf() instead
of hand-rolled boundary construction.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
* address review feedback on skipIntervals PR
- Add javadoc to DataSourceCompactionConfig.getSkipIntervals()
- Use Configs.valueOrDefault() in Inline/CatalogDataSourceCompactionConfig
- Rename testSerdeWithSkip -> testSerdeWithSkipIntervals
- Condense assertions and comments in
DataSourceCompactibleSegmentIteratorTest
- Fold test intent into method name in NewestSegmentFirstPolicyTest
- Document skipIntervals and its backfill/failing-compaction use case in
automatic-compaction.md and configuration/index.md
Co-Authored-By: Claude Sonnet 5 <[email protected]>
---------
Co-authored-by: Claude Sonnet 5 <[email protected]>
---
docs/configuration/index.md | 1 +
docs/data-management/automatic-compaction.md | 13 +++
.../compact/AutoCompactionUpgradeTest.java | 2 +-
.../catalog/compact/CatalogCompactionTest.java | 4 +-
.../compact/CascadingReindexingTemplate.java | 6 ++
.../apache/druid/java/util/common/JodaUtils.java | 4 +-
.../DataSourceCompactibleSegmentIterator.java | 55 +++--------
.../CatalogDataSourceCompactionConfig.java | 15 ++-
.../coordinator/DataSourceCompactionConfig.java | 6 ++
.../InlineSchemaDataSourceCompactionConfig.java | 23 +++++
.../DataSourceCompactibleSegmentIteratorTest.java | 101 ++++++++++++++++++---
.../compaction/NewestSegmentFirstPolicyTest.java | 33 +++++++
.../CatalogDataSourceCompactionConfigTest.java | 38 ++++++++
...InlineSchemaDataSourceCompactionConfigTest.java | 17 ++++
.../coordinator/duty/CompactSegmentsTest.java | 1 +
15 files changed, 254 insertions(+), 65 deletions(-)
diff --git a/docs/configuration/index.md b/docs/configuration/index.md
index f4c40ba15b7..d4898222664 100644
--- a/docs/configuration/index.md
+++ b/docs/configuration/index.md
@@ -856,6 +856,7 @@ You can configure automatic compaction through the
following properties:
|`taskPriority`|[Priority](../ingestion/tasks.md#lock-priority) of compaction
task.|no (default = 25)|
|`inputSegmentSizeBytes`|Maximum number of total segment bytes processed per
compaction task. Since a time chunk must be processed in its entirety, if the
segments for a particular time chunk have a total size in bytes greater than
this parameter, compaction will not run for that time chunk.|no (default =
100,000,000,000,000 i.e. 100TB)|
|`skipOffsetFromLatest`|The offset for searching segments to be compacted in
[ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) duration format. Strongly
recommended to set for realtime datasources. See [Data handling with
compaction](../data-management/compaction.md#data-handling-with-compaction).|no
(default = "P1D")|
+|`skipIntervals`|A list of intervals to exclude from compaction. Any candidate
compaction interval that overlaps one of these intervals is skipped. See [Skip
compaction for specific
intervals](../data-management/automatic-compaction.md#skip-compaction-for-specific-intervals).|no|
|`tuningConfig`|Tuning config for compaction tasks. See below [Automatic
compaction tuningConfig](#automatic-compaction-tuningconfig).|no|
|`taskContext`|[Task context](../ingestion/tasks.md#context-parameters) for
compaction tasks.|no|
|`granularitySpec`|Custom `granularitySpec`. See [Automatic compaction
granularitySpec](#automatic-compaction-granularityspec).|no|
diff --git a/docs/data-management/automatic-compaction.md
b/docs/data-management/automatic-compaction.md
index 221888e3ba8..0d84a81bcdc 100644
--- a/docs/data-management/automatic-compaction.md
+++ b/docs/data-management/automatic-compaction.md
@@ -52,6 +52,7 @@ The automatic compaction system uses the following syntax:
"tuningConfig": <parallel indexing task tuningConfig>,
"granularitySpec": <compaction task granularitySpec>,
"skipOffsetFromLatest": <time period to avoid compaction>,
+ "skipIntervals": <list of time intervals to avoid compaction>,
"taskPriority": <compaction task priority>,
"taskContext": <task context>
}
@@ -60,6 +61,7 @@ The automatic compaction system uses the following syntax:
Most fields in the auto-compaction configuration correlate to a typical [Druid
ingestion spec](../ingestion/ingestion-spec.md).
The following properties only apply to auto-compaction:
* `skipOffsetFromLatest`
+* `skipIntervals`
* `taskPriority`
* `taskContext`
@@ -293,6 +295,7 @@ Compaction tasks may be interrupted when they interfere
with ingestion. For exam
* Enable [concurrent append and replace
tasks](#enable-concurrent-append-and-replace) on your datasource and on the
ingestion tasks.
* Set `skipOffsetFromLatest` to reduce the chance of conflicts between
ingestion and compaction. See more details in [Skip compaction for latest
segments](#skip-compaction-for-latest-segments).
+* Set `skipIntervals` to exclude a specific interval from compaction, for
example, while a backfill job is actively writing to that interval or if the
interval keeps failing compaction. See more details in [Skip compaction for
specific intervals](#skip-compaction-for-specific-intervals).
* Increase the priority value of compaction tasks relative to ingestion tasks.
Only recommended for advanced users. This approach can cause ingestion jobs to
fail or lag. To change the priority of compaction tasks, set `taskPriority` to
the desired priority value in the auto-compaction configuration. For details on
the priority values of different task types, see [Lock
priority](../ingestion/tasks.md#lock-priority).
### Enable concurrent append and replace
@@ -314,6 +317,16 @@ The Coordinator compacts segments from newest to oldest.
In the auto-compaction
To set `skipOffsetFromLatest`, consider how frequently you expect the stream
to receive late arriving data. If your stream only occasionally receives late
arriving data, the auto-compaction system robustly compacts your data even
though data is ingested outside the `skipOffsetFromLatest` window. For most
realtime streaming ingestion use cases, it is reasonable to set
`skipOffsetFromLatest` to a few hours or a day.
+### Skip compaction for specific intervals
+
+In addition to `skipOffsetFromLatest`, you can set `skipIntervals` to a list
of time intervals to exclude from compaction. Any candidate compaction interval
that overlaps one of these intervals is skipped.
+
+This is useful, for example, when a backfill job is actively writing to a
specific interval and you don't want to compact it until the backfill finishes,
or when a specific interval consistently fails compaction and you want to
exclude it while you investigate:
+
+```json
+"skipIntervals": ["2015-04-01/2015-04-02"]
+```
+
## Examples
The following examples demonstrate potential use cases in which
auto-compaction may improve your Druid performance. See more details in
[Compaction
strategies](../data-management/compaction.md#compaction-guidelines). The
examples in this section do not change the underlying data.
diff --git
a/embedded-tests/src/test/java/org/apache/druid/testing/embedded/compact/AutoCompactionUpgradeTest.java
b/embedded-tests/src/test/java/org/apache/druid/testing/embedded/compact/AutoCompactionUpgradeTest.java
index 9aca257f663..c8b8c33b393 100644
---
a/embedded-tests/src/test/java/org/apache/druid/testing/embedded/compact/AutoCompactionUpgradeTest.java
+++
b/embedded-tests/src/test/java/org/apache/druid/testing/embedded/compact/AutoCompactionUpgradeTest.java
@@ -135,7 +135,7 @@ public class AutoCompactionUpgradeTest extends
EmbeddedClusterTestBase
private void insertMinimalCompactionConfig(TestDerbyConnector sqlConnector)
{
DataSourceCompactionConfig dataSourceCompactionConfig =
- new CatalogDataSourceCompactionConfig(dataSource, null, Period.ZERO,
null, null, null, null);
+ new CatalogDataSourceCompactionConfig(dataSource, null, Period.ZERO,
null, null, null, null, null);
DruidCompactionConfig config =
DruidCompactionConfig.legacy().withDatasourceConfig(dataSourceCompactionConfig);
sqlConnector.retryWithHandle(
handle -> handle.insert(
diff --git
a/extensions-core/druid-catalog/src/test/java/org/apache/druid/catalog/compact/CatalogCompactionTest.java
b/extensions-core/druid-catalog/src/test/java/org/apache/druid/catalog/compact/CatalogCompactionTest.java
index 13793def20d..da4b565dd6f 100644
---
a/extensions-core/druid-catalog/src/test/java/org/apache/druid/catalog/compact/CatalogCompactionTest.java
+++
b/extensions-core/druid-catalog/src/test/java/org/apache/druid/catalog/compact/CatalogCompactionTest.java
@@ -26,7 +26,6 @@ import org.apache.druid.catalog.model.TableMetadata;
import org.apache.druid.catalog.model.table.TableBuilder;
import org.apache.druid.catalog.sync.CatalogClient;
import org.apache.druid.common.utils.IdUtils;
-import org.apache.druid.indexer.CompactionEngine;
import org.apache.druid.indexing.common.task.IndexTask;
import org.apache.druid.indexing.common.task.TaskBuilder;
import org.apache.druid.indexing.compact.CompactionSupervisorSpec;
@@ -113,7 +112,7 @@ public class CatalogCompactionTest extends
EmbeddedClusterTestBase
// Create a catalog compaction config
CatalogDataSourceCompactionConfig compactionConfig =
- new CatalogDataSourceCompactionConfig(dataSource,
CompactionEngine.NATIVE, Period.ZERO, null, null, null, null);
+ new CatalogDataSourceCompactionConfig(dataSource, null, Period.ZERO,
null, null, null, null, null);
final CompactionSupervisorSpec compactionSupervisor
= new CompactionSupervisorSpec(compactionConfig, false, null);
@@ -124,7 +123,6 @@ public class CatalogCompactionTest extends
EmbeddedClusterTestBase
event -> event.hasMetricName("task/run/time")
.hasDimension(DruidMetrics.TASK_TYPE, "compact")
.hasDimension(DruidMetrics.DATASOURCE, dataSource)
- .hasDimension(DruidMetrics.TASK_STATUS, "SUCCESS")
);
// Verify that segments are now compacted to MONTH granularity
diff --git
a/indexing-service/src/main/java/org/apache/druid/indexing/compact/CascadingReindexingTemplate.java
b/indexing-service/src/main/java/org/apache/druid/indexing/compact/CascadingReindexingTemplate.java
index 2f22f20af13..455fced0b9d 100644
---
a/indexing-service/src/main/java/org/apache/druid/indexing/compact/CascadingReindexingTemplate.java
+++
b/indexing-service/src/main/java/org/apache/druid/indexing/compact/CascadingReindexingTemplate.java
@@ -220,6 +220,12 @@ public class CascadingReindexingTemplate implements
CompactionJobTemplate, DataS
return skipOffsetFromLatest;
}
+ @Override
+ public List<Interval> getSkipIntervals()
+ {
+ return List.of();
+ }
+
@JsonProperty
@Nullable
private Period getSkipOffsetFromNow()
diff --git
a/processing/src/main/java/org/apache/druid/java/util/common/JodaUtils.java
b/processing/src/main/java/org/apache/druid/java/util/common/JodaUtils.java
index ad83f5d983b..b19c3e83341 100644
--- a/processing/src/main/java/org/apache/druid/java/util/common/JodaUtils.java
+++ b/processing/src/main/java/org/apache/druid/java/util/common/JodaUtils.java
@@ -52,7 +52,7 @@ public class JodaUtils
* {@link Comparators#intervalsByStartThenEnd()}.
*
* @param intervals The Iterable object containing the intervals to condense
- * @return The condensed intervals
+ * @return The condensed intervals, sorted by {@link
Comparators#intervalsByStartThenEnd()}
*/
public static List<Interval> condenseIntervals(Iterable<Interval> intervals)
{
@@ -85,7 +85,7 @@ public class JodaUtils
* @param sortedIntervals The iterator object containing the intervals to
condense
*
* @return An iterator for the condensed intervals. By construction the
condensed intervals are sorted
- * in ascending order and contain no repeated elements. The iterator can
contain nulls,
+ * by {@link Comparators#intervalsByStartThenEnd()} and contain no repeated
elements. The iterator can contain nulls,
* they will be skipped if it does.
*
* @throws IAE if an element is null or if sortedIntervals is not sorted in
ascending order
diff --git
a/server/src/main/java/org/apache/druid/server/compaction/DataSourceCompactibleSegmentIterator.java
b/server/src/main/java/org/apache/druid/server/compaction/DataSourceCompactibleSegmentIterator.java
index f818d6ca97a..8e37b978bee 100644
---
a/server/src/main/java/org/apache/druid/server/compaction/DataSourceCompactibleSegmentIterator.java
+++
b/server/src/main/java/org/apache/druid/server/compaction/DataSourceCompactibleSegmentIterator.java
@@ -22,6 +22,7 @@ package org.apache.druid.server.compaction;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import org.apache.druid.java.util.common.DateTimes;
@@ -350,12 +351,12 @@ public class DataSourceCompactibleSegmentIterator
implements CompactionSegmentIt
}
/**
- * Returns the initial searchInterval which is {@code
(timeline.first().start, timeline.last().end - skipOffset)}.
+ * Returns the initial search intervals for compaction, excluding the
provided skipIntervals,
+ * {@code config.getSkipIntervals()} and the computed skip interval from
+ * {@code config.getSkipOffsetFromLatest()}.
*/
- private List<Interval> findInitialSearchInterval(
- SegmentTimeline timeline,
- @Nullable List<Interval> skipIntervals
- )
+ @VisibleForTesting
+ List<Interval> findInitialSearchInterval(SegmentTimeline timeline,
List<Interval> skipIntervals)
{
final Period skipOffset = config.getSkipOffsetFromLatest();
Preconditions.checkArgument(timeline != null && !timeline.isEmpty(),
"timeline should not be null or empty");
@@ -368,8 +369,11 @@ public class DataSourceCompactibleSegmentIterator
implements CompactionSegmentIt
last.getInterval().getEnd(),
skipOffset
);
- final List<Interval> allSkipIntervals
- = sortAndAddSkipIntervalFromLatest(latestSkipInterval, skipIntervals);
+ final List<Interval> allSkipIntervals =
JodaUtils.condenseIntervals(Iterables.concat(
+ skipIntervals,
+ config.getSkipIntervals(),
+ List.of(latestSkipInterval)
+ ));
// Collect stats for all skipped segments
for (Interval skipInterval : allSkipIntervals) {
@@ -454,43 +458,6 @@ public class DataSourceCompactibleSegmentIterator
implements CompactionSegmentIt
}
}
- @VisibleForTesting
- static List<Interval> sortAndAddSkipIntervalFromLatest(
- Interval skipFromLatest,
- @Nullable List<Interval> skipIntervals
- )
- {
- final List<Interval> nonNullSkipIntervals = skipIntervals == null
- ? new ArrayList<>(1)
- : new
ArrayList<>(skipIntervals.size());
-
- if (skipIntervals != null) {
- final List<Interval> sortedSkipIntervals = new
ArrayList<>(skipIntervals);
- sortedSkipIntervals.sort(Comparators.intervalsByStartThenEnd());
-
- final List<Interval> overlapIntervals = new ArrayList<>();
-
- for (Interval interval : sortedSkipIntervals) {
- if (interval.overlaps(skipFromLatest)) {
- overlapIntervals.add(interval);
- } else {
- nonNullSkipIntervals.add(interval);
- }
- }
-
- if (!overlapIntervals.isEmpty()) {
- overlapIntervals.add(skipFromLatest);
- nonNullSkipIntervals.add(JodaUtils.umbrellaInterval(overlapIntervals));
- } else {
- nonNullSkipIntervals.add(skipFromLatest);
- }
- } else {
- nonNullSkipIntervals.add(skipFromLatest);
- }
-
- return nonNullSkipIntervals;
- }
-
/**
* Returns a list of intervals which are contained by totalInterval but
don't ovarlap with skipIntervals.
*
diff --git
a/server/src/main/java/org/apache/druid/server/coordinator/CatalogDataSourceCompactionConfig.java
b/server/src/main/java/org/apache/druid/server/coordinator/CatalogDataSourceCompactionConfig.java
index 37de2a17947..a080ae01acd 100644
---
a/server/src/main/java/org/apache/druid/server/coordinator/CatalogDataSourceCompactionConfig.java
+++
b/server/src/main/java/org/apache/druid/server/coordinator/CatalogDataSourceCompactionConfig.java
@@ -31,12 +31,14 @@ import org.apache.druid.catalog.model.ResolvedTable;
import org.apache.druid.catalog.model.TableId;
import org.apache.druid.catalog.model.table.DatasourceDefn;
import org.apache.druid.client.indexing.ClientCompactionRunnerInfo;
+import org.apache.druid.common.config.Configs;
import org.apache.druid.data.input.impl.AggregateProjectionSpec;
import org.apache.druid.data.input.impl.BaseTableProjectionSpec;
import org.apache.druid.indexer.CompactionEngine;
import org.apache.druid.java.util.common.granularity.Granularity;
import org.apache.druid.query.aggregation.AggregatorFactory;
import org.apache.druid.segment.transform.CompactionTransformSpec;
+import org.joda.time.Interval;
import org.joda.time.Period;
import javax.annotation.Nullable;
@@ -51,6 +53,7 @@ public class CatalogDataSourceCompactionConfig implements
DataSourceCompactionCo
@Nullable
private final CompactionEngine engine;
private final Period skipOffsetFromLatest;
+ private final List<Interval> skipIntervals;
private final int taskPriority;
@Nullable
private final Map<String, Object> taskContext;
@@ -63,6 +66,7 @@ public class CatalogDataSourceCompactionConfig implements
DataSourceCompactionCo
@JsonProperty("dataSource") String dataSource,
@JsonProperty("engine") @Nullable CompactionEngine engine,
@JsonProperty("skipOffsetFromLatest") @Nullable Period
skipOffsetFromLatest,
+ @JsonProperty("skipIntervals") @Nullable List<Interval> skipIntervals,
@JsonProperty("taskPriority") @Nullable Integer taskPriority,
@JsonProperty("taskContext") @Nullable Map<String, Object> taskContext,
@JsonProperty("inputSegmentSizeBytes") @Nullable Long
inputSegmentSizeBytes,
@@ -72,6 +76,7 @@ public class CatalogDataSourceCompactionConfig implements
DataSourceCompactionCo
this.dataSource = Preconditions.checkNotNull(dataSource, "dataSource");
this.engine = engine;
this.skipOffsetFromLatest = skipOffsetFromLatest == null ?
DEFAULT_SKIP_OFFSET_FROM_LATEST : skipOffsetFromLatest;
+ this.skipIntervals = Configs.valueOrDefault(skipIntervals, List.of());
this.inputSegmentSizeBytes = inputSegmentSizeBytes == null
? DEFAULT_INPUT_SEGMENT_SIZE_BYTES
: inputSegmentSizeBytes;
@@ -103,6 +108,13 @@ public class CatalogDataSourceCompactionConfig implements
DataSourceCompactionCo
return skipOffsetFromLatest;
}
+ @JsonProperty
+ @Override
+ public List<Interval> getSkipIntervals()
+ {
+ return skipIntervals;
+ }
+
@JsonProperty
@Override
public int getTaskPriority()
@@ -241,12 +253,13 @@ public class CatalogDataSourceCompactionConfig implements
DataSourceCompactionCo
&& Objects.equals(dataSource, that.dataSource)
&& engine == that.engine
&& Objects.equals(skipOffsetFromLatest, that.skipOffsetFromLatest)
+ && Objects.equals(skipIntervals, that.skipIntervals)
&& Objects.equals(taskContext, that.taskContext);
}
@Override
public int hashCode()
{
- return Objects.hash(dataSource, engine, skipOffsetFromLatest,
taskPriority, taskContext, inputSegmentSizeBytes);
+ return Objects.hash(dataSource, engine, skipOffsetFromLatest,
skipIntervals, taskPriority, taskContext, inputSegmentSizeBytes);
}
}
diff --git
a/server/src/main/java/org/apache/druid/server/coordinator/DataSourceCompactionConfig.java
b/server/src/main/java/org/apache/druid/server/coordinator/DataSourceCompactionConfig.java
index 4b8550ee598..1cad30913da 100644
---
a/server/src/main/java/org/apache/druid/server/coordinator/DataSourceCompactionConfig.java
+++
b/server/src/main/java/org/apache/druid/server/coordinator/DataSourceCompactionConfig.java
@@ -36,6 +36,7 @@ import org.apache.druid.segment.IndexSpec;
import org.apache.druid.segment.transform.CompactionTransformSpec;
import org.apache.druid.server.compaction.CompactionStatus;
import org.apache.druid.timeline.CompactionState;
+import org.joda.time.Interval;
import org.joda.time.Period;
import javax.annotation.Nullable;
@@ -80,6 +81,11 @@ public interface DataSourceCompactionConfig
Period getSkipOffsetFromLatest();
+ /**
+ * Intervals to skip from compaction. A compaction interval overlapping any
of these will be skipped.
+ */
+ List<Interval> getSkipIntervals();
+
@Nullable
UserCompactionTaskQueryTuningConfig getTuningConfig();
diff --git
a/server/src/main/java/org/apache/druid/server/coordinator/InlineSchemaDataSourceCompactionConfig.java
b/server/src/main/java/org/apache/druid/server/coordinator/InlineSchemaDataSourceCompactionConfig.java
index f99739d85df..0ac0276d078 100644
---
a/server/src/main/java/org/apache/druid/server/coordinator/InlineSchemaDataSourceCompactionConfig.java
+++
b/server/src/main/java/org/apache/druid/server/coordinator/InlineSchemaDataSourceCompactionConfig.java
@@ -24,12 +24,14 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Preconditions;
import org.apache.druid.client.indexing.ClientCompactionRunnerInfo;
+import org.apache.druid.common.config.Configs;
import org.apache.druid.data.input.impl.AggregateProjectionSpec;
import org.apache.druid.data.input.impl.BaseTableProjectionSpec;
import org.apache.druid.indexer.CompactionEngine;
import org.apache.druid.java.util.common.granularity.Granularity;
import org.apache.druid.query.aggregation.AggregatorFactory;
import org.apache.druid.segment.transform.CompactionTransformSpec;
+import org.joda.time.Interval;
import org.joda.time.Period;
import javax.annotation.Nullable;
@@ -56,6 +58,7 @@ public class InlineSchemaDataSourceCompactionConfig
implements DataSourceCompact
@Nullable
private final Integer maxRowsPerSegment;
private final Period skipOffsetFromLatest;
+ private final List<Interval> skipIntervals;
@Nullable
private final UserCompactionTaskQueryTuningConfig tuningConfig;
@Nullable
@@ -84,6 +87,7 @@ public class InlineSchemaDataSourceCompactionConfig
implements DataSourceCompact
@JsonProperty("inputSegmentSizeBytes") @Nullable Long
inputSegmentSizeBytes,
@JsonProperty("maxRowsPerSegment") @Deprecated @Nullable Integer
maxRowsPerSegment,
@JsonProperty("skipOffsetFromLatest") @Nullable Period
skipOffsetFromLatest,
+ @JsonProperty("skipIntervals") @Nullable List<Interval> skipIntervals,
@JsonProperty("tuningConfig") @Nullable
UserCompactionTaskQueryTuningConfig tuningConfig,
@JsonProperty("granularitySpec") @Nullable
UserCompactionTaskGranularityConfig granularitySpec,
@JsonProperty("dimensionsSpec") @Nullable
UserCompactionTaskDimensionsConfig dimensionsSpec,
@@ -105,6 +109,7 @@ public class InlineSchemaDataSourceCompactionConfig
implements DataSourceCompact
: inputSegmentSizeBytes;
this.maxRowsPerSegment = maxRowsPerSegment;
this.skipOffsetFromLatest = skipOffsetFromLatest == null ?
DEFAULT_SKIP_OFFSET_FROM_LATEST : skipOffsetFromLatest;
+ this.skipIntervals = Configs.valueOrDefault(skipIntervals, List.of());
this.tuningConfig = tuningConfig;
this.ioConfig = ioConfig;
this.granularitySpec = granularitySpec;
@@ -154,6 +159,13 @@ public class InlineSchemaDataSourceCompactionConfig
implements DataSourceCompact
return skipOffsetFromLatest;
}
+ @JsonProperty
+ @Override
+ public List<Interval> getSkipIntervals()
+ {
+ return skipIntervals;
+ }
+
@JsonProperty
@Nullable
@Override
@@ -263,6 +275,7 @@ public class InlineSchemaDataSourceCompactionConfig
implements DataSourceCompact
Objects.equals(dataSource, that.dataSource) &&
Objects.equals(maxRowsPerSegment, that.maxRowsPerSegment) &&
Objects.equals(skipOffsetFromLatest, that.skipOffsetFromLatest) &&
+ Objects.equals(skipIntervals, that.skipIntervals) &&
Objects.equals(tuningConfig, that.tuningConfig) &&
Objects.equals(granularitySpec, that.granularitySpec) &&
Objects.equals(dimensionsSpec, that.dimensionsSpec) &&
@@ -284,6 +297,7 @@ public class InlineSchemaDataSourceCompactionConfig
implements DataSourceCompact
inputSegmentSizeBytes,
maxRowsPerSegment,
skipOffsetFromLatest,
+ skipIntervals,
tuningConfig,
granularitySpec,
dimensionsSpec,
@@ -310,6 +324,7 @@ public class InlineSchemaDataSourceCompactionConfig
implements DataSourceCompact
.withInputSegmentSizeBytes(this.inputSegmentSizeBytes)
.withMaxRowsPerSegment(this.maxRowsPerSegment)
.withSkipOffsetFromLatest(this.skipOffsetFromLatest)
+ .withSkipIntervals(this.skipIntervals)
.withTuningConfig(this.tuningConfig)
.withGranularitySpec(this.granularitySpec)
.withDimensionsSpec(this.dimensionsSpec)
@@ -329,6 +344,7 @@ public class InlineSchemaDataSourceCompactionConfig
implements DataSourceCompact
private Long inputSegmentSizeBytes;
private Integer maxRowsPerSegment;
private Period skipOffsetFromLatest;
+ private List<Interval> skipIntervals;
private UserCompactionTaskQueryTuningConfig tuningConfig;
private UserCompactionTaskGranularityConfig granularitySpec;
private UserCompactionTaskDimensionsConfig dimensionsSpec;
@@ -348,6 +364,7 @@ public class InlineSchemaDataSourceCompactionConfig
implements DataSourceCompact
inputSegmentSizeBytes,
maxRowsPerSegment,
skipOffsetFromLatest,
+ skipIntervals,
tuningConfig,
granularitySpec,
dimensionsSpec,
@@ -392,6 +409,12 @@ public class InlineSchemaDataSourceCompactionConfig
implements DataSourceCompact
return this;
}
+ public Builder withSkipIntervals(List<Interval> skipIntervals)
+ {
+ this.skipIntervals = skipIntervals;
+ return this;
+ }
+
public Builder withTuningConfig(
UserCompactionTaskQueryTuningConfig tuningConfig
)
diff --git
a/server/src/test/java/org/apache/druid/server/compaction/DataSourceCompactibleSegmentIteratorTest.java
b/server/src/test/java/org/apache/druid/server/compaction/DataSourceCompactibleSegmentIteratorTest.java
index eea081b9f51..b923af3f290 100644
---
a/server/src/test/java/org/apache/druid/server/compaction/DataSourceCompactibleSegmentIteratorTest.java
+++
b/server/src/test/java/org/apache/druid/server/compaction/DataSourceCompactibleSegmentIteratorTest.java
@@ -19,17 +19,35 @@
package org.apache.druid.server.compaction;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
+import org.apache.druid.jackson.DefaultObjectMapper;
import org.apache.druid.java.util.common.Intervals;
+import org.apache.druid.java.util.common.granularity.Granularities;
+import org.apache.druid.segment.metadata.DefaultIndexingStateFingerprintMapper;
+import org.apache.druid.segment.metadata.IndexingStateFingerprintMapper;
+import org.apache.druid.segment.metadata.NoopIndexingStateCache;
+import org.apache.druid.server.coordinator.CreateDataSegments;
+import org.apache.druid.server.coordinator.DataSourceCompactionConfig;
+import
org.apache.druid.server.coordinator.InlineSchemaDataSourceCompactionConfig;
+import org.apache.druid.timeline.DataSegment;
+import org.apache.druid.timeline.SegmentTimeline;
import org.joda.time.Interval;
+import org.joda.time.Period;
import org.junit.Assert;
import org.junit.Test;
+import java.util.Iterator;
import java.util.List;
public class DataSourceCompactibleSegmentIteratorTest
{
+ private static final ObjectMapper MAPPER = new DefaultObjectMapper();
+ private static final CompactionCandidateSearchPolicy POLICY = new
NewestSegmentFirstPolicy(null);
+ private static final IndexingStateFingerprintMapper FINGERPRINT_MAPPER =
+ new DefaultIndexingStateFingerprintMapper(new NoopIndexingStateCache(),
MAPPER);
+
@Test
public void testFilterSkipIntervals()
{
@@ -54,22 +72,77 @@ public class DataSourceCompactibleSegmentIteratorTest
}
@Test
- public void testAddSkipIntervalFromLatestAndSort()
+ public void testFindInitialSearchInterval()
{
- final List<Interval> expectedIntervals = ImmutableList.of(
- Intervals.of("2018-12-24/2018-12-25"),
- Intervals.of("2018-12-29/2019-01-01")
+ final Iterator<DataSegment> segments =
CreateDataSegments.ofDatasource("test_datasource")
+ .forIntervals(12,
Granularities.HOUR)
+
.startingAt("2018-01-01")
+
.withNumPartitions(1)
+
.eachOfSizeInMb(100)
+ .iterator();
+ final SegmentTimeline timeline = SegmentTimeline.forSegments(segments);
+ final DataSourceCompactionConfig config =
+ InlineSchemaDataSourceCompactionConfig.builder()
+ .forDataSource("test_datasource")
+ .withSkipOffsetFromLatest(new
Period("PT4H"))
+ .build();
+ final DataSourceCompactibleSegmentIterator iterator = new
DataSourceCompactibleSegmentIterator(
+ config,
+ timeline,
+ List.of(),
+ POLICY,
+ FINGERPRINT_MAPPER
);
- /*final List<Interval> fullSkipIntervals =
DataSourceCompactibleSegmentIterator.sortAndAddSkipIntervalFromLatest(
- DateTimes.of("2019-01-01"),
- new Period(72, 0, 0, 0),
- null,
- ImmutableList.of(
- Intervals.of("2018-12-30/2018-12-31"),
- Intervals.of("2018-12-24/2018-12-25")
- )
- );*/
- //Assert.assertEquals(expectedIntervals, fullSkipIntervals);
+ final List<Interval> searchIntervals =
iterator.findInitialSearchInterval(timeline, List.of());
+
+ // Expected: Total interval is 2018-01-01T00:00:00/2018-01-01T12:00:00
+ // Skip interval: 2018-01-01T08:00:00/2018-01-01T12:00:00 (computed from
4h offset)
+ // Search interval should be: [2018-01-01T00:00:00/2018-01-01T08:00:00]
+ Assert.assertEquals(1, searchIntervals.size());
+
Assert.assertEquals(Intervals.of("2018-01-01T00:00:00/2018-01-01T08:00:00"),
searchIntervals.get(0));
+ }
+
+ @Test
+ public void testFindInitialSearchIntervalWithMultipleSkipIntervals()
+ {
+ final Iterator<DataSegment> segments =
CreateDataSegments.ofDatasource("test_datasource")
+ .forIntervals(24,
Granularities.HOUR)
+
.startingAt("2018-01-01")
+
.withNumPartitions(1)
+
.eachOfSizeInMb(100)
+ .iterator();
+ final SegmentTimeline timeline = SegmentTimeline.forSegments(segments);
+ final DataSourceCompactionConfig config =
+ InlineSchemaDataSourceCompactionConfig.builder()
+ .forDataSource("test_datasource")
+ .withSkipOffsetFromLatest(new
Period("PT4H"))
+ .withSkipIntervals(List.of(
+
Intervals.of("2018-01-01T06:00:00/2018-01-01T08:00:00"),
+
Intervals.of("2018-01-01T12:00:00/2018-01-01T14:00:00"),
+
Intervals.of("2018-01-01T18:30:00/2018-01-01T21:00:00")
+ ))
+ .build();
+ final DataSourceCompactibleSegmentIterator iterator = new
DataSourceCompactibleSegmentIterator(
+ config,
+ timeline,
+ List.of(),
+ POLICY,
+ FINGERPRINT_MAPPER
+ );
+
+ final List<Interval> searchIntervals =
iterator.findInitialSearchInterval(timeline, List.of());
+
+ // The three configured skip intervals and the 4h-offset skip interval
(18:30-21:00 and
+ // 20:00-00:00 merge) leave three search windows. The last window is
clipped to 18:00
+ // since segments are hourly and the 18:00-19:00 segment overlaps the
18:30 skip start.
+ Assert.assertEquals(
+ List.of(
+ Intervals.of("2018-01-01T00:00:00/PT6H"),
+ Intervals.of("2018-01-01T08:00:00/PT4H"),
+ Intervals.of("2018-01-01T14:00:00/PT4H")
+ ),
+ searchIntervals
+ );
}
}
diff --git
a/server/src/test/java/org/apache/druid/server/compaction/NewestSegmentFirstPolicyTest.java
b/server/src/test/java/org/apache/druid/server/compaction/NewestSegmentFirstPolicyTest.java
index 0b69f87e755..9d4ef4534d9 100644
---
a/server/src/test/java/org/apache/druid/server/compaction/NewestSegmentFirstPolicyTest.java
+++
b/server/src/test/java/org/apache/druid/server/compaction/NewestSegmentFirstPolicyTest.java
@@ -534,6 +534,39 @@ public class NewestSegmentFirstPolicyTest
);
}
+ @Test
+ public void
testConfiguredSkipIntervalsAreHonoredWithNoExternalSkipIntervals()
+ {
+ final SegmentTimeline timeline = createTimeline(
+ createSegments().forIntervals(4, Granularities.DAY)
+ .startingAt("2017-12-01")
+ .withNumPartitions(1)
+ );
+
+ final CompactionSegmentIterator iterator = createIterator(
+ configBuilder()
+ .withSkipIntervals(List.of(Intervals.of("2017-12-02/2017-12-03")))
+ .build(),
+ timeline
+ );
+
+ final List<DataSegment> expectedSegmentsToCompact = new ArrayList<>(
+
timeline.findNonOvershadowedObjectsInInterval(Intervals.of("2017-12-01/2017-12-02"),
Partitions.ONLY_COMPLETE)
+ );
+ expectedSegmentsToCompact.addAll(
+
timeline.findNonOvershadowedObjectsInInterval(Intervals.of("2017-12-03/2017-12-05"),
Partitions.ONLY_COMPLETE)
+ );
+
+ Assert.assertTrue(iterator.hasNext());
+ final Set<DataSegment> observedSegmentsToCompact =
Streams.sequentialStreamFrom(iterator)
+ .flatMap(s ->
s.getSegments().stream())
+
.collect(Collectors.toSet());
+ Assert.assertEquals(
+ ImmutableSet.copyOf(expectedSegmentsToCompact),
+ observedSegmentsToCompact
+ );
+ }
+
@Test
public void testHoleInSearchInterval()
{
diff --git
a/server/src/test/java/org/apache/druid/server/coordinator/CatalogDataSourceCompactionConfigTest.java
b/server/src/test/java/org/apache/druid/server/coordinator/CatalogDataSourceCompactionConfigTest.java
index e7ed9a7d038..af779a7b840 100644
---
a/server/src/test/java/org/apache/druid/server/coordinator/CatalogDataSourceCompactionConfigTest.java
+++
b/server/src/test/java/org/apache/druid/server/coordinator/CatalogDataSourceCompactionConfigTest.java
@@ -34,15 +34,20 @@ import org.apache.druid.catalog.model.table.TableBuilder;
import org.apache.druid.data.input.impl.AggregateProjectionSpec;
import org.apache.druid.data.input.impl.StringDimensionSchema;
import org.apache.druid.jackson.DefaultObjectMapper;
+import org.apache.druid.java.util.common.Intervals;
import org.apache.druid.java.util.common.granularity.Granularities;
import org.apache.druid.math.expr.ExprMacroTable;
import org.apache.druid.query.aggregation.LongSumAggregatorFactory;
import org.apache.druid.query.expression.TestExprMacroTable;
import org.apache.druid.segment.column.ColumnHolder;
import org.apache.druid.segment.column.ColumnType;
+import org.joda.time.Interval;
+import org.joda.time.Period;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import java.util.List;
+
public class CatalogDataSourceCompactionConfigTest
{
private static final String TEST_DS = "test";
@@ -116,6 +121,7 @@ public class CatalogDataSourceCompactionConfigTest
null,
null,
null,
+ null,
METADATA_CATALOG
);
@@ -135,6 +141,7 @@ public class CatalogDataSourceCompactionConfigTest
null,
null,
null,
+ null,
METADATA_CATALOG
);
@@ -144,6 +151,37 @@ public class CatalogDataSourceCompactionConfigTest
);
}
+ @Test
+ public void testSerdeWithSkipIntervals() throws JsonProcessingException
+ {
+ final Period skipOffsetFromLatest = new Period("PT1H");
+ final List<Interval> skipIntervals = List.of(
+ Intervals.of("2024-01-01/2024-01-02"),
+ Intervals.of("2024-02-15/2024-02-16")
+ );
+
+ final CatalogDataSourceCompactionConfig config = new
CatalogDataSourceCompactionConfig(
+ "foo",
+ null,
+ skipOffsetFromLatest,
+ skipIntervals,
+ null,
+ null,
+ null,
+ METADATA_CATALOG
+ );
+
+ final CatalogDataSourceCompactionConfig deserialized =
+ (CatalogDataSourceCompactionConfig) MAPPER.readValue(
+ MAPPER.writeValueAsString(config),
+ DataSourceCompactionConfig.class
+ );
+
+ Assertions.assertEquals(config, deserialized);
+ Assertions.assertEquals(skipOffsetFromLatest,
deserialized.getSkipOffsetFromLatest());
+ Assertions.assertEquals(skipIntervals, deserialized.getSkipIntervals());
+ }
+
@Test
public void testEqualsAndHashcode()
{
diff --git
a/server/src/test/java/org/apache/druid/server/coordinator/InlineSchemaDataSourceCompactionConfigTest.java
b/server/src/test/java/org/apache/druid/server/coordinator/InlineSchemaDataSourceCompactionConfigTest.java
index 00f3ce0813c..eb8111f8291 100644
---
a/server/src/test/java/org/apache/druid/server/coordinator/InlineSchemaDataSourceCompactionConfigTest.java
+++
b/server/src/test/java/org/apache/druid/server/coordinator/InlineSchemaDataSourceCompactionConfigTest.java
@@ -32,6 +32,7 @@ import org.apache.druid.indexer.CompactionEngine;
import org.apache.druid.indexer.partitions.DynamicPartitionsSpec;
import org.apache.druid.jackson.DefaultObjectMapper;
import org.apache.druid.java.util.common.HumanReadableBytes;
+import org.apache.druid.java.util.common.Intervals;
import org.apache.druid.java.util.common.granularity.Granularities;
import org.apache.druid.math.expr.ExprMacroTable;
import org.apache.druid.query.aggregation.AggregatorFactory;
@@ -54,6 +55,7 @@ import org.junit.Assert;
import org.junit.Test;
import java.io.IOException;
+import java.util.List;
public class InlineSchemaDataSourceCompactionConfigTest extends
InitializedNullHandlingTest
{
@@ -74,6 +76,7 @@ public class InlineSchemaDataSourceCompactionConfigTest
extends InitializedNullH
.builder()
.forDataSource("dataSource")
.withSkipOffsetFromLatest(new Period(3600))
+ .withSkipIntervals(List.of(Intervals.of("2024-02-15/2024-02-16")))
.withTaskContext(ImmutableMap.of("key", "val"))
.build();
final String json = OBJECT_MAPPER.writeValueAsString(config);
@@ -84,6 +87,7 @@ public class InlineSchemaDataSourceCompactionConfigTest
extends InitializedNullH
Assert.assertEquals(100_000_000_000_000L,
fromJson.getInputSegmentSizeBytes());
Assert.assertEquals(config.getMaxRowsPerSegment(),
fromJson.getMaxRowsPerSegment());
Assert.assertEquals(config.getSkipOffsetFromLatest(),
fromJson.getSkipOffsetFromLatest());
+ Assert.assertEquals(config.getSkipIntervals(),
fromJson.getSkipIntervals());
Assert.assertEquals(config.getTuningConfig(), fromJson.getTuningConfig());
Assert.assertEquals(config.getTaskContext(), fromJson.getTaskContext());
Assert.assertEquals(config.getGranularitySpec(),
fromJson.getGranularitySpec());
@@ -99,6 +103,7 @@ public class InlineSchemaDataSourceCompactionConfigTest
extends InitializedNullH
.withInputSegmentSizeBytes(500L)
.withMaxRowsPerSegment(30)
.withSkipOffsetFromLatest(new Period(3600))
+ .withSkipIntervals(List.of(Intervals.of("2024-01-01/2024-01-02")))
.withEngine(CompactionEngine.MSQ)
.withTaskContext(ImmutableMap.of("key", "val"))
.build();
@@ -123,6 +128,7 @@ public class InlineSchemaDataSourceCompactionConfigTest
extends InitializedNullH
.forDataSource("dataSource")
.withInputSegmentSizeBytes(500L)
.withSkipOffsetFromLatest(new Period(3600))
+ .withSkipIntervals(List.of(Intervals.of("2024-03-01/2024-03-02")))
.withEngine(CompactionEngine.NATIVE)
.withTaskContext(ImmutableMap.of("key", "val"))
.build();
@@ -148,6 +154,7 @@ public class InlineSchemaDataSourceCompactionConfigTest
extends InitializedNullH
.withInputSegmentSizeBytes(500L)
.withMaxRowsPerSegment(10000)
.withSkipOffsetFromLatest(new Period(3600))
+ .withSkipIntervals(List.of(Intervals.of("2024-04-01/2024-04-02")))
.withTaskContext(ImmutableMap.of("key", "val"))
.build();
final String json = OBJECT_MAPPER.writeValueAsString(config);
@@ -248,6 +255,7 @@ public class InlineSchemaDataSourceCompactionConfigTest
extends InitializedNullH
.forDataSource("dataSource")
.withInputSegmentSizeBytes(500L)
.withSkipOffsetFromLatest(new Period(3600))
+ .withSkipIntervals(List.of(Intervals.of("2024-01-15/2024-01-16")))
.withGranularitySpec(new
UserCompactionTaskGranularityConfig(Granularities.HOUR, null, null))
.withTaskContext(ImmutableMap.of("key", "val"))
.build();
@@ -272,6 +280,7 @@ public class InlineSchemaDataSourceCompactionConfigTest
extends InitializedNullH
.forDataSource("dataSource")
.withInputSegmentSizeBytes(500L)
.withSkipOffsetFromLatest(new Period(3600))
+ .withSkipIntervals(List.of(Intervals.of("2024-01-15/2024-01-16")))
.withGranularitySpec(new UserCompactionTaskGranularityConfig(null,
Granularities.YEAR, null))
.withTaskContext(ImmutableMap.of("key", "val"))
.build();
@@ -299,6 +308,7 @@ public class InlineSchemaDataSourceCompactionConfigTest
extends InitializedNullH
.forDataSource("dataSource")
.withInputSegmentSizeBytes(500L)
.withSkipOffsetFromLatest(new Period(3600))
+ .withSkipIntervals(List.of(Intervals.of("2024-01-15/2024-01-16")))
.withTaskContext(ImmutableMap.of("key", "val"))
.build();
final String json = OBJECT_MAPPER.writeValueAsString(config);
@@ -322,6 +332,7 @@ public class InlineSchemaDataSourceCompactionConfigTest
extends InitializedNullH
.forDataSource("dataSource")
.withInputSegmentSizeBytes(500L)
.withSkipOffsetFromLatest(new Period(3600))
+ .withSkipIntervals(List.of(Intervals.of("2024-01-15/2024-01-16")))
.withGranularitySpec(new UserCompactionTaskGranularityConfig(null,
null, null))
.withTaskContext(ImmutableMap.of("key", "val"))
.build();
@@ -346,6 +357,7 @@ public class InlineSchemaDataSourceCompactionConfigTest
extends InitializedNullH
.forDataSource("dataSource")
.withInputSegmentSizeBytes(500L)
.withSkipOffsetFromLatest(new Period(3600))
+ .withSkipIntervals(List.of(Intervals.of("2024-01-15/2024-01-16")))
.withGranularitySpec(new UserCompactionTaskGranularityConfig(null,
null, true))
.withTaskContext(ImmutableMap.of("key", "val"))
.build();
@@ -373,6 +385,7 @@ public class InlineSchemaDataSourceCompactionConfigTest
extends InitializedNullH
.forDataSource("dataSource")
.withInputSegmentSizeBytes(500L)
.withSkipOffsetFromLatest(new Period(3600))
+ .withSkipIntervals(List.of(Intervals.of("2024-01-15/2024-01-16")))
.withGranularitySpec(new
UserCompactionTaskGranularityConfig(Granularities.HOUR, null, null))
.withIoConfig(new UserCompactionTaskIOConfig(true))
.withTaskContext(ImmutableMap.of("key", "val"))
@@ -399,6 +412,7 @@ public class InlineSchemaDataSourceCompactionConfigTest
extends InitializedNullH
.forDataSource("dataSource")
.withInputSegmentSizeBytes(500L)
.withSkipOffsetFromLatest(new Period(3600))
+ .withSkipIntervals(List.of(Intervals.of("2024-01-15/2024-01-16")))
.withGranularitySpec(new
UserCompactionTaskGranularityConfig(Granularities.HOUR, null, null))
.withIoConfig(new UserCompactionTaskIOConfig(null))
.withTaskContext(ImmutableMap.of("key", "val"))
@@ -425,6 +439,7 @@ public class InlineSchemaDataSourceCompactionConfigTest
extends InitializedNullH
.forDataSource("dataSource")
.withInputSegmentSizeBytes(500L)
.withSkipOffsetFromLatest(new Period(3600))
+ .withSkipIntervals(List.of(Intervals.of("2024-01-15/2024-01-16")))
.withDimensionsSpec(
new UserCompactionTaskDimensionsConfig(
DimensionsSpec.getDefaultSchemas(ImmutableList.of("foo"))
@@ -453,6 +468,7 @@ public class InlineSchemaDataSourceCompactionConfigTest
extends InitializedNullH
.forDataSource("dataSource")
.withInputSegmentSizeBytes(500L)
.withSkipOffsetFromLatest(new Period(3600))
+ .withSkipIntervals(List.of(Intervals.of("2024-01-15/2024-01-16")))
.withTransformSpec(
new CompactionTransformSpec(
new SelectorDimFilter("dim1", "foo", null),
@@ -489,6 +505,7 @@ public class InlineSchemaDataSourceCompactionConfigTest
extends InitializedNullH
.forDataSource("dataSource")
.withInputSegmentSizeBytes(500L)
.withSkipOffsetFromLatest(new Period(3600))
+ .withSkipIntervals(List.of(Intervals.of("2024-01-15/2024-01-16")))
.withMetricsSpec(new AggregatorFactory[]{new
CountAggregatorFactory("cnt")})
.withTaskContext(ImmutableMap.of("key", "val"))
.build();
diff --git
a/server/src/test/java/org/apache/druid/server/coordinator/duty/CompactSegmentsTest.java
b/server/src/test/java/org/apache/druid/server/coordinator/duty/CompactSegmentsTest.java
index f1ea4e553de..b4b070e77d0 100644
---
a/server/src/test/java/org/apache/druid/server/coordinator/duty/CompactSegmentsTest.java
+++
b/server/src/test/java/org/apache/druid/server/coordinator/duty/CompactSegmentsTest.java
@@ -1053,6 +1053,7 @@ public class CompactSegmentsTest
dataSource,
engine,
new Period("PT0H"),
+ null,
0,
null,
500L,
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]