diff --git a/CHANGES.txt b/CHANGES.txt index 5705453ea2..489a76d14a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -11,6 +11,7 @@ * Deprecate Pig support (CASSANDRA-10542) * Reduce contention getting instances of CompositeType (CASSANDRA-10433) Merged from 2.1: + * Reject incremental repair with subrange repair (CASSANDRA-10422) * Add a nodetool command to refresh size_estimates (CASSANDRA-9579) * Shutdown compaction in drain to prevent leak (CASSANDRA-10079) * Invalidate cache after stream receive task is completed (CASSANDRA-10341) diff --git a/src/java/org/apache/cassandra/repair/messages/RepairOption.java b/src/java/org/apache/cassandra/repair/messages/RepairOption.java index f3e452c06f..1780b6b922 100644 --- a/src/java/org/apache/cassandra/repair/messages/RepairOption.java +++ b/src/java/org/apache/cassandra/repair/messages/RepairOption.java @@ -144,6 +144,9 @@ public class RepairOption Set> ranges = new HashSet<>(); if (rangesStr != null) { + if (incremental) + throw new IllegalArgumentException("Incremental repair can't be requested with subrange repair " + + "because each subrange repair would generate an anti-compacted table"); StringTokenizer tokenizer = new StringTokenizer(rangesStr, ","); while (tokenizer.hasMoreTokens()) { diff --git a/src/java/org/apache/cassandra/service/StorageService.java b/src/java/org/apache/cassandra/service/StorageService.java index 74b3c73f73..b5ce38b379 100644 --- a/src/java/org/apache/cassandra/service/StorageService.java +++ b/src/java/org/apache/cassandra/service/StorageService.java @@ -2964,6 +2964,10 @@ public class StorageService extends NotificationBroadcasterSupport implements IE logger.warn("Snapshot-based repair is not yet supported on Windows. Reverting to parallel repair."); parallelism = RepairParallelism.PARALLEL; } + + if (!fullRepair) + throw new IllegalArgumentException("Incremental repair can't be requested with subrange repair " + + "because each subrange repair would generate an anti-compacted table"); Collection> repairingRange = createRepairRangeFrom(beginToken, endToken); RepairOption options = new RepairOption(parallelism, false, !fullRepair, false, 1, repairingRange); diff --git a/test/unit/org/apache/cassandra/repair/messages/RepairOptionTest.java b/test/unit/org/apache/cassandra/repair/messages/RepairOptionTest.java index 11ae69f815..3257a10ce3 100644 --- a/test/unit/org/apache/cassandra/repair/messages/RepairOptionTest.java +++ b/test/unit/org/apache/cassandra/repair/messages/RepairOptionTest.java @@ -24,6 +24,8 @@ import java.util.Set; import org.junit.Test; +import com.google.common.collect.ImmutableMap; + import org.apache.cassandra.config.Config; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.dht.IPartitioner; @@ -58,7 +60,7 @@ public class RepairOptionTest Map options = new HashMap<>(); options.put(RepairOption.PARALLELISM_KEY, "parallel"); options.put(RepairOption.PRIMARY_RANGE_KEY, "false"); - options.put(RepairOption.INCREMENTAL_KEY, "true"); + options.put(RepairOption.INCREMENTAL_KEY, "false"); options.put(RepairOption.RANGES_KEY, "0:10,11:20,21:30"); options.put(RepairOption.COLUMNFAMILIES_KEY, "cf1,cf2,cf3"); options.put(RepairOption.DATACENTERS_KEY, "dc1,dc2,dc3"); @@ -67,7 +69,7 @@ public class RepairOptionTest option = RepairOption.parse(options, partitioner); assertTrue(option.getParallelism() == RepairParallelism.PARALLEL); assertFalse(option.isPrimaryRange()); - assertTrue(option.isIncremental()); + assertFalse(option.isIncremental()); Set> expectedRanges = new HashSet<>(3); expectedRanges.add(new Range<>(tokenFactory.fromString("0"), tokenFactory.fromString("10"))); @@ -93,4 +95,11 @@ public class RepairOptionTest expectedHosts.add("127.0.0.3"); assertEquals(expectedHosts, option.getHosts()); } + + @Test(expected=IllegalArgumentException.class) + public void testIncrementalRepairWithSubrangesThrows() throws Exception + { + RepairOption.parse(ImmutableMap.of(RepairOption.INCREMENTAL_KEY, "true", RepairOption.RANGES_KEY, ""), + Murmur3Partitioner.instance); + } }