diff --git a/CHANGES.txt b/CHANGES.txt index 601667457b..6efcaa3874 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -37,6 +37,7 @@ * More fixes to the TokenAllocator (CASSANDRA-12990) * NoReplicationTokenAllocator should work with zero replication factor (CASSANDRA-12983) Merged from 3.0: + * Use keyspace replication settings on system.size_estimates table (CASSANDRA-9639) * Add vm.max_map_count StartupCheck (CASSANDRA-13008) * Obfuscate password in stress-graphs (CASSANDRA-12233) * Hint related logging should include the IP address of the destination in addition to diff --git a/NEWS.txt b/NEWS.txt index 9c183f601b..d936dbe73e 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -22,9 +22,6 @@ New features See CASSANDRA-11936 - Support for arithmetic operations on number has been added. See CASSANDRA-11935 -3.11 -==== - Upgrading --------- - Cassandra 4.0 removed support for the deprecated Thrift interface. Amongst @@ -47,6 +44,14 @@ Upgrading repaired. For incremental repairs, anticompaction is run at the beginning of the repair, instead of at the end. +3.11.0 +====== + +Upgrading +--------- + - Primary ranges in the system.size_estimates table are now based on the keyspace + replication settings and adjacent ranges are no longer merged (CASSANDRA-9639). + 3.10 ==== diff --git a/src/java/org/apache/cassandra/db/SizeEstimatesRecorder.java b/src/java/org/apache/cassandra/db/SizeEstimatesRecorder.java index f70e45e63a..066b2fe178 100644 --- a/src/java/org/apache/cassandra/db/SizeEstimatesRecorder.java +++ b/src/java/org/apache/cassandra/db/SizeEstimatesRecorder.java @@ -68,12 +68,10 @@ public class SizeEstimatesRecorder extends SchemaChangeListener implements Runna logger.trace("Recording size estimates"); - // find primary token ranges for the local node. - Collection localTokens = StorageService.instance.getLocalTokens(); - Collection> localRanges = metadata.getPrimaryRangesFor(localTokens); - for (Keyspace keyspace : Keyspace.nonLocalStrategy()) { + Collection> localRanges = StorageService.instance.getPrimaryRangesForEndpoint(keyspace.getName(), + FBUtilities.getBroadcastAddress()); for (ColumnFamilyStore table : keyspace.getColumnFamilyStores()) { long start = System.nanoTime(); @@ -90,37 +88,39 @@ public class SizeEstimatesRecorder extends SchemaChangeListener implements Runna @SuppressWarnings("resource") private void recordSizeEstimates(ColumnFamilyStore table, Collection> localRanges) { - List> unwrappedRanges = Range.normalize(localRanges); // for each local primary range, estimate (crudely) mean partition size and partitions count. Map, Pair> estimates = new HashMap<>(localRanges.size()); - for (Range range : unwrappedRanges) + for (Range localRange : localRanges) { - // filter sstables that have partitions in this range. - Refs refs = null; - long partitionsCount, meanPartitionSize; - - try + for (Range unwrappedRange : localRange.unwrap()) { - while (refs == null) + // filter sstables that have partitions in this range. + Refs refs = null; + long partitionsCount, meanPartitionSize; + + try { - Iterable sstables = table.getTracker().getView().select(SSTableSet.CANONICAL); - SSTableIntervalTree tree = SSTableIntervalTree.build(sstables); - Range r = Range.makeRowRange(range); - Iterable canonicalSSTables = View.sstablesInBounds(r.left, r.right, tree); - refs = Refs.tryRef(canonicalSSTables); + while (refs == null) + { + Iterable sstables = table.getTracker().getView().select(SSTableSet.CANONICAL); + SSTableIntervalTree tree = SSTableIntervalTree.build(sstables); + Range r = Range.makeRowRange(unwrappedRange); + Iterable canonicalSSTables = View.sstablesInBounds(r.left, r.right, tree); + refs = Refs.tryRef(canonicalSSTables); + } + + // calculate the estimates. + partitionsCount = estimatePartitionsCount(refs, unwrappedRange); + meanPartitionSize = estimateMeanPartitionSize(refs); + } + finally + { + if (refs != null) + refs.release(); } - // calculate the estimates. - partitionsCount = estimatePartitionsCount(refs, range); - meanPartitionSize = estimateMeanPartitionSize(refs); + estimates.put(unwrappedRange, Pair.create(partitionsCount, meanPartitionSize)); } - finally - { - if (refs != null) - refs.release(); - } - - estimates.put(range, Pair.create(partitionsCount, meanPartitionSize)); } // atomically update the estimates. diff --git a/src/java/org/apache/cassandra/service/ActiveRepairService.java b/src/java/org/apache/cassandra/service/ActiveRepairService.java index 89e1954a4a..c4979070d7 100644 --- a/src/java/org/apache/cassandra/service/ActiveRepairService.java +++ b/src/java/org/apache/cassandra/service/ActiveRepairService.java @@ -266,7 +266,10 @@ public class ActiveRepairService implements IEndpointStateChangeSubscriber, IFai } else if (range.intersects(toRepair)) { - throw new IllegalArgumentException("Requested range intersects a local range but is not fully contained in one; this would lead to imprecise repair"); + throw new IllegalArgumentException(String.format("Requested range %s intersects a local range (%s) " + + "but is not fully contained in one; this would lead to " + + "imprecise repair. keyspace: %s", toRepair.toString(), + range.toString(), keyspaceName)); } } if (rangeSuperSet == null || !replicaSets.containsKey(rangeSuperSet))