From af7b20bd0ea0d1e80553c519510c9ad9f29af64a Mon Sep 17 00:00:00 2001 From: Chris Lohfink Date: Thu, 26 Jan 2017 09:43:47 -0600 Subject: [PATCH 1/2] Use keyspace replication settings on system.size_estimates table Patch by Chris Lohfink; Reviewed by Paulo Motta for CASSANDRA-9639 --- CHANGES.txt | 1 + NEWS.txt | 2 + .../cassandra/db/SizeEstimatesRecorder.java | 54 +++++++++---------- 3 files changed, 30 insertions(+), 27 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index b19550a712..732e14bd4c 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 3.0.11 + * Use keyspace replication settings on system.size_estimates table (CASSANDRA-9639) * Add vm.max_map_count StartupCheck (CASSANDRA-13008) * Hint related logging should include the IP address of the destination in addition to host ID (CASSANDRA-13205) diff --git a/NEWS.txt b/NEWS.txt index 4248a6e529..a5ee496809 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -30,6 +30,8 @@ Upgrading - Compaction now correctly drops sstables out of CompactionTask when there isn't enough disk space to perform the full compaction. This should reduce pending compaction tasks on systems with little remaining disk space. + - 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.0.10 ===== diff --git a/src/java/org/apache/cassandra/db/SizeEstimatesRecorder.java b/src/java/org/apache/cassandra/db/SizeEstimatesRecorder.java index 0b31b872f2..ebe3f9a208 100644 --- a/src/java/org/apache/cassandra/db/SizeEstimatesRecorder.java +++ b/src/java/org/apache/cassandra/db/SizeEstimatesRecorder.java @@ -69,12 +69,10 @@ public class SizeEstimatesRecorder extends MigrationListener implements Runnable 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(); @@ -91,37 +89,39 @@ public class SizeEstimatesRecorder extends MigrationListener implements Runnable @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. From f02f154e47be13dd481fe7afe18183c615f39c71 Mon Sep 17 00:00:00 2001 From: Paulo Motta Date: Wed, 15 Feb 2017 10:15:43 -0200 Subject: [PATCH 2/2] ninja: improve subrange repair error message --- .../org/apache/cassandra/service/ActiveRepairService.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/java/org/apache/cassandra/service/ActiveRepairService.java b/src/java/org/apache/cassandra/service/ActiveRepairService.java index 97c5c0a000..11d4617a11 100644 --- a/src/java/org/apache/cassandra/service/ActiveRepairService.java +++ b/src/java/org/apache/cassandra/service/ActiveRepairService.java @@ -220,7 +220,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))