Fix AE when SSTable is closed without releasing reference patch by yukim and benedict; reviewed by thobbs and Ben Chan for CASSANDRA-7000
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/930905bb Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/930905bb Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/930905bb Branch: refs/heads/trunk Commit: 930905bbebfbfc923d71c34fb35fbdb4e7bc8ccc Parents: 66a6990 Author: Yuki Morishita <yu...@apache.org> Authored: Fri Apr 11 10:55:57 2014 -0500 Committer: Yuki Morishita <yu...@apache.org> Committed: Fri Apr 11 10:55:57 2014 -0500 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../apache/cassandra/db/ColumnFamilyStore.java | 35 ++++++++++++++------ .../db/compaction/CompactionManager.java | 7 +--- .../cassandra/io/sstable/SSTableReader.java | 10 ++++-- 4 files changed, 35 insertions(+), 18 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/930905bb/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 94dd7c3..4c2d77e 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -43,6 +43,7 @@ * Track presence of legacy counter shards in sstables (CASSANDRA-6888) * Ensure safe resource cleanup when replacing sstables (CASSANDRA-6912) * Add failure handler to async callback (CASSANDRA-6747) + * Fix AE when closing SSTable without releasing reference (CASSANDRA-7000) Merged from 2.0: * Put nodes in hibernate when join_ring is false (CASSANDRA-6961) * Allow compaction of system tables during startup (CASSANDRA-6913) http://git-wip-us.apache.org/repos/asf/cassandra/blob/930905bb/src/java/org/apache/cassandra/db/ColumnFamilyStore.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/ColumnFamilyStore.java b/src/java/org/apache/cassandra/db/ColumnFamilyStore.java index 43ecdc1..ffea243 100644 --- a/src/java/org/apache/cassandra/db/ColumnFamilyStore.java +++ b/src/java/org/apache/cassandra/db/ColumnFamilyStore.java @@ -2326,22 +2326,37 @@ public class ColumnFamilyStore implements ColumnFamilyStoreMBean public Iterable<DecoratedKey> keySamples(Range<Token> range) { - Collection<SSTableReader> sstables = getSSTables(); - Iterable<DecoratedKey>[] samples = new Iterable[sstables.size()]; - int i = 0; - for (SSTableReader sstable: sstables) + Collection<SSTableReader> sstables = markCurrentSSTablesReferenced(); + try + { + Iterable<DecoratedKey>[] samples = new Iterable[sstables.size()]; + int i = 0; + for (SSTableReader sstable: sstables) + { + samples[i++] = sstable.getKeySamples(range); + } + return Iterables.concat(samples); + } + finally { - samples[i++] = sstable.getKeySamples(range); + SSTableReader.releaseReferences(sstables); } - return Iterables.concat(samples); } public long estimatedKeysForRange(Range<Token> range) { - long count = 0; - for (SSTableReader sstable : getSSTables()) - count += sstable.estimatedKeysForRanges(Collections.singleton(range)); - return count; + Collection<SSTableReader> sstables = markCurrentSSTablesReferenced(); + try + { + long count = 0; + for (SSTableReader sstable : sstables) + count += sstable.estimatedKeysForRanges(Collections.singleton(range)); + return count; + } + finally + { + SSTableReader.releaseReferences(sstables); + } } /** http://git-wip-us.apache.org/repos/asf/cassandra/blob/930905bb/src/java/org/apache/cassandra/db/compaction/CompactionManager.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/compaction/CompactionManager.java b/src/java/org/apache/cassandra/db/compaction/CompactionManager.java index 5cebf73..b1f0c2a 100644 --- a/src/java/org/apache/cassandra/db/compaction/CompactionManager.java +++ b/src/java/org/apache/cassandra/db/compaction/CompactionManager.java @@ -950,16 +950,11 @@ public class CompactionManager implements CompactionManagerMBean finally { iter.close(); + SSTableReader.releaseReferences(sstables); if (isSnapshotValidation) { - for (SSTableReader sstable : sstables) - FileUtils.closeQuietly(sstable); cfs.clearSnapshot(snapshotName); } - else - { - SSTableReader.releaseReferences(sstables); - } metrics.finishCompaction(ci); } http://git-wip-us.apache.org/repos/asf/cassandra/blob/930905bb/src/java/org/apache/cassandra/io/sstable/SSTableReader.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/io/sstable/SSTableReader.java b/src/java/org/apache/cassandra/io/sstable/SSTableReader.java index d29d5ac..bc5002f 100644 --- a/src/java/org/apache/cassandra/io/sstable/SSTableReader.java +++ b/src/java/org/apache/cassandra/io/sstable/SSTableReader.java @@ -546,7 +546,10 @@ public class SSTableReader extends SSTable implements Closeable if (readMeterSyncFuture != null) readMeterSyncFuture.cancel(false); - assert references.get() == 0; + if (references.get() != 0) + { + throw new IllegalStateException("SSTable is not fully released (" + references.get() + " references)"); + } synchronized (replaceLock) { @@ -589,7 +592,10 @@ public class SSTableReader extends SSTable implements Closeable replacedBy.replaces = replaces; } - assert references.get() == 0; + if (references.get() != 0) + { + throw new IllegalStateException("SSTable is not fully released (" + references.get() + " references)"); + } if (closeBf) bf.close(); if (closeSummary)