fix bug in sstable blacklisting with LCS patch by jbellis; reviewed by yukim for CASSANDRA-4343
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/f74ed12a Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/f74ed12a Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/f74ed12a Branch: refs/heads/trunk Commit: f74ed12a70ba0e59efef20a2207ef6bf4df0ae04 Parents: 55d5c04 Author: Jonathan Ellis <[email protected]> Authored: Thu Jun 14 20:09:21 2012 -0500 Committer: Jonathan Ellis <[email protected]> Committed: Fri Jun 15 12:25:59 2012 -0500 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../cassandra/db/compaction/LeveledManifest.java | 60 +++++++++++---- 2 files changed, 46 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/f74ed12a/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index b0e667d..693b03b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 1.1.2 + * fix bug in sstable blacklisting with LCS (CASSANDRA-4343) * LCS no longer promotes tiny sstables out of L0 (CASSANDRA-4341) * skip tombstones during hint replay (CASSANDRA-4320) * fix NPE in compactionstats (CASSANDRA-4318) http://git-wip-us.apache.org/repos/asf/cassandra/blob/f74ed12a/src/java/org/apache/cassandra/db/compaction/LeveledManifest.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/compaction/LeveledManifest.java b/src/java/org/apache/cassandra/db/compaction/LeveledManifest.java index 4ed5fac..a53d519 100644 --- a/src/java/org/apache/cassandra/db/compaction/LeveledManifest.java +++ b/src/java/org/apache/cassandra/db/compaction/LeveledManifest.java @@ -277,15 +277,10 @@ public class LeveledManifest if (score > 1.001 || (i == 0 && sstables.size() > 1)) { Collection<SSTableReader> candidates = getCandidatesFor(i); - if (logger.isDebugEnabled()) logger.debug("Compaction candidates for L{} are {}", i, toString(candidates)); - - // check if have any SSTables marked as suspected, - // saves us filter time when no SSTables are suspects - return hasSuspectSSTables(candidates) - ? filterSuspectSSTables(candidates) - : candidates; + if (!candidates.isEmpty()) + return candidates; } } @@ -386,6 +381,10 @@ public class LeveledManifest // 2. At most MAX_COMPACTING_L0 sstables will be compacted at once // 3. If total candidate size is less than maxSSTableSizeInMB, we won't bother compacting with L1, // and the result of the compaction will stay in L0 instead of being promoted (see promote()) + // + // Note that we ignore suspect-ness of L1 sstables here, since if an L1 sstable is suspect we're + // basically screwed, since we expect all or most L0 sstables to overlap with each L1 sstable. + // So if an L1 sstable is suspect we can't do much besides try anyway and hope for the best. Set<SSTableReader> candidates = new HashSet<SSTableReader>(); Set<SSTableReader> remaining = new HashSet<SSTableReader>(generations[0]); List<SSTableReader> ageSortedSSTables = new ArrayList<SSTableReader>(generations[0]); @@ -395,9 +394,14 @@ public class LeveledManifest if (candidates.contains(sstable)) continue; - List<SSTableReader> newCandidates = overlapping(sstable, remaining); - candidates.addAll(newCandidates); - remaining.removeAll(newCandidates); + for (SSTableReader newCandidate : overlapping(sstable, remaining)) + { + if (!newCandidate.isMarkedSuspect()) + { + candidates.add(newCandidate); + remaining.remove(newCandidate); + } + } if (candidates.size() > MAX_COMPACTING_L0) { @@ -421,14 +425,40 @@ public class LeveledManifest // for non-L0 compactions, pick up where we left off last time Collections.sort(generations[level], SSTable.sstableComparator); - for (SSTableReader sstable : generations[level]) + int start = 0; // handles case where the prior compaction touched the very last range + for (int i = 0; i < generations[level].size(); i++) { - // the first sstable that is > than the marked + SSTableReader sstable = generations[level].get(i); if (sstable.first.compareTo(lastCompactedKeys[level]) > 0) - return overlapping(sstable, generations[(level + 1)]); + { + start = i; + break; + } } - // or if there was no last time, start with the first sstable - return overlapping(generations[level].get(0), generations[(level + 1)]); + + // look for a non-suspect table to compact with, starting with where we left off last time, + // and wrapping back to the beginning of the generation if necessary + int i = start; + outer: + while (true) + { + SSTableReader sstable = generations[level].get(i); + List<SSTableReader> candidates = overlapping(sstable, generations[(level + 1)]); + for (SSTableReader candidate : candidates) + { + if (candidate.isMarkedSuspect()) + { + i = (i + 1) % generations[level].size(); + if (i == start) + break outer; + continue outer; + } + } + return candidates; + } + + // all the sstables were suspect or overlapped with something suspect + return Collections.emptyList(); } public static File tryGetManifest(ColumnFamilyStore cfs)
