From 4e834c53ca57910e8c44cb1edf2a780df9390556 Mon Sep 17 00:00:00 2001 From: Jay Zhuang Date: Wed, 2 Aug 2017 21:44:39 -0700 Subject: [PATCH] Fix load over calculated issue in IndexSummaryRedistribution patch by Jay Zhuang; reviewed by Marcus Eriksson for CASSANDRA-13738 --- CHANGES.txt | 1 + .../io/sstable/format/SSTableReader.java | 6 +- .../IndexSummaryRedistributionTest.java | 145 ++++++++++++++++++ 3 files changed, 149 insertions(+), 3 deletions(-) create mode 100644 test/unit/org/apache/cassandra/io/sstable/IndexSummaryRedistributionTest.java diff --git a/CHANGES.txt b/CHANGES.txt index 03a78fd2dc..1abd7de6d9 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 2.2.11 + * Fix load over calculated issue in IndexSummaryRedistribution (CASSANDRA-13738) * Fix compaction and flush exception not captured (CASSANDRA-13833) * Make BatchlogManagerMBean.forceBatchlogReplay() blocking (CASSANDRA-13809) * Uncaught exceptions in Netty pipeline (CASSANDRA-13649) diff --git a/src/java/org/apache/cassandra/io/sstable/format/SSTableReader.java b/src/java/org/apache/cassandra/io/sstable/format/SSTableReader.java index ba060d45a1..6666885519 100644 --- a/src/java/org/apache/cassandra/io/sstable/format/SSTableReader.java +++ b/src/java/org/apache/cassandra/io/sstable/format/SSTableReader.java @@ -1174,9 +1174,9 @@ public abstract class SSTableReader extends SSTable implements SelfRefCounted sstables = new ArrayList<>(cfs.getSSTables()); + for (SSTableReader sstable : sstables) + sstable.overrideReadMeter(new RestorableMeter(100.0, 100.0)); + + long oldSize = 0; + for (SSTableReader sstable : sstables) + { + assertEquals(cfs.metadata.getMinIndexInterval(), sstable.getEffectiveIndexInterval(), 0.001); + oldSize += sstable.bytesOnDisk(); + } + + load = StorageMetrics.load.getCount(); + + long others = load - oldSize; // Other SSTables size, e.g. schema and other system SSTables + + int originalMinIndexInterval = cfs.metadata.getMinIndexInterval(); + // double the min_index_interval + cfs.metadata.minIndexInterval(originalMinIndexInterval * 2); + IndexSummaryManager.instance.redistributeSummaries(); + + long newSize = 0; + for (SSTableReader sstable : cfs.getSSTables()) + { + assertEquals(cfs.metadata.getMinIndexInterval(), sstable.getEffectiveIndexInterval(), 0.001); + assertEquals(numRows / cfs.metadata.getMinIndexInterval(), sstable.getIndexSummarySize()); + newSize += sstable.bytesOnDisk(); + } + newSize += others; + load = StorageMetrics.load.getCount(); + + // new size we calculate should be almost the same as the load in metrics + assertEquals(newSize, load, newSize / 10); + } + + private void createSSTables(String ksname, String cfname, int numSSTables, int numRows) + { + Keyspace keyspace = Keyspace.open(ksname); + ColumnFamilyStore cfs = keyspace.getColumnFamilyStore(cfname); + cfs.truncateBlocking(); + cfs.disableAutoCompaction(); + + ArrayList futures = new ArrayList<>(numSSTables); + ByteBuffer value = ByteBuffer.wrap(new byte[100]); + for (int sstable = 0; sstable < numSSTables; sstable++) + { + for (int row = 0; row < numRows; row++) + { + DecoratedKey key = Util.dk(String.format("%3d", row)); + Mutation rm = new Mutation(ksname, key.getKey()); + rm.add(cfname, Util.cellname("column"), value, 0); + rm.applyUnsafe(); + } + futures.add(cfs.forceFlush()); + } + for (Future future : futures) + { + try + { + future.get(); + } + catch (InterruptedException | ExecutionException e) + { + throw new RuntimeException(e); + } + } + assertEquals(numSSTables, cfs.getSSTables().size()); + } +}