Repository: cassandra Updated Branches: refs/heads/cassandra-3.11 858cb25a0 -> e9251e1fb
Fixed checkAvailableDiskSpace to properly recalculate expected disk usage of compaction task before reducing scope patch by Jon Haddad; reviewed by Nate McCall for CASSANDRA-12979 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/e9251e1f Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/e9251e1f Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/e9251e1f Branch: refs/heads/cassandra-3.11 Commit: e9251e1fbc8619db92ee3818eb9e8abc9a0fade5 Parents: 858cb25 Author: Jon Haddad <j...@jonhaddad.com> Authored: Wed Jan 4 11:52:54 2017 -0800 Committer: Nate McCall <zznat...@gmail.com> Committed: Tue Jan 10 16:24:37 2017 +1300 ---------------------------------------------------------------------- CHANGES.txt | 1 + NEWS.txt | 3 ++ .../cassandra/db/compaction/CompactionTask.java | 41 +++++++++++++++----- 3 files changed, 36 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/e9251e1f/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 1b74dc7..99f6613 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -110,6 +110,7 @@ * Restore resumable hints delivery (CASSANDRA-11960) * Properly report LWT contention (CASSANDRA-12626) Merged from 3.0: + * CompactionTasks now correctly drops sstables out of compaction when not enough disk space is available (CASSANDRA-12979) * Replace empty strings with null values if they cannot be converted (CASSANDRA-12794) * Fix deserialization of 2.x DeletedCells (CASSANDRA-12620) * Add parent repair session id to anticompaction log message (CASSANDRA-12186) http://git-wip-us.apache.org/repos/asf/cassandra/blob/e9251e1f/NEWS.txt ---------------------------------------------------------------------- diff --git a/NEWS.txt b/NEWS.txt index 9f376ff..7bccaae 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -24,6 +24,9 @@ Upgrading - Only Java and JavaScript are now supported UDF languages. The sandbox in 3.0 already prevented the use of script languages except Java and JavaScript. + - 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. 3.10 ==== http://git-wip-us.apache.org/repos/asf/cassandra/blob/e9251e1f/src/java/org/apache/cassandra/db/compaction/CompactionTask.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/compaction/CompactionTask.java b/src/java/org/apache/cassandra/db/compaction/CompactionTask.java index a9d6c7c..b2e9b8c 100644 --- a/src/java/org/apache/cassandra/db/compaction/CompactionTask.java +++ b/src/java/org/apache/cassandra/db/compaction/CompactionTask.java @@ -86,12 +86,15 @@ public class CompactionTask extends AbstractCompactionTask return transaction.originals().size(); } - public boolean reduceScopeForLimitedSpace() + public boolean reduceScopeForLimitedSpace(long expectedSize) { if (partialCompactionsAcceptable() && transaction.originals().size() > 1) { // Try again w/o the largest one. - logger.warn("Insufficient space to compact all requested files {}", StringUtils.join(transaction.originals(), ", ")); + logger.warn("insufficient space to compact all requested files. {}MB required, {}", + (float) expectedSize / 1024 / 1024, + StringUtils.join(transaction.originals(), ", ")); + // Note that we have removed files that are still marked as compacting. // This suboptimal but ok since the caller will unmark all the sstables at the end. SSTableReader removedSSTable = cfs.getMaxSizeFile(transaction.originals()); @@ -124,9 +127,8 @@ public class CompactionTask extends AbstractCompactionTask // note that we need to do a rough estimate early if we can fit the compaction on disk - this is pessimistic, but // since we might remove sstables from the compaction in checkAvailableDiskSpace it needs to be done here - long expectedWriteSize = cfs.getExpectedCompactedFileSize(transaction.originals(), compactionType); - long earlySSTableEstimate = Math.max(1, expectedWriteSize / strategy.getMaxSSTableBytes()); - checkAvailableDiskSpace(earlySSTableEstimate, expectedWriteSize); + + checkAvailableDiskSpace(); // sanity check: all sstables must belong to the same cfs assert !Iterables.any(transaction.originals(), new Predicate<SSTableReader>() @@ -317,7 +319,12 @@ public class CompactionTask extends AbstractCompactionTask return minRepairedAt; } - protected void checkAvailableDiskSpace(long estimatedSSTables, long expectedWriteSize) + /* + Checks if we have enough disk space to execute the compaction. Drops the largest sstable out of the Task until + there's enough space (in theory) to handle the compaction. Does not take into account space that will be taken by + other compactions. + */ + protected void checkAvailableDiskSpace() { if(!cfs.isCompactionDiskSpaceCheckEnabled() && compactionType == OperationType.COMPACTION) { @@ -325,10 +332,26 @@ public class CompactionTask extends AbstractCompactionTask return; } - while (!getDirectories().hasAvailableDiskSpace(estimatedSSTables, expectedWriteSize)) + CompactionStrategyManager strategy = cfs.getCompactionStrategyManager(); + + while(true) { - if (!reduceScopeForLimitedSpace()) - throw new RuntimeException(String.format("Not enough space for compaction, estimated sstables = %d, expected write size = %d", estimatedSSTables, expectedWriteSize)); + long expectedWriteSize = cfs.getExpectedCompactedFileSize(transaction.originals(), compactionType); + long estimatedSSTables = Math.max(1, expectedWriteSize / strategy.getMaxSSTableBytes()); + + if(cfs.getDirectories().hasAvailableDiskSpace(estimatedSSTables, expectedWriteSize)) + break; + + if (!reduceScopeForLimitedSpace(expectedWriteSize)) + { + // we end up here if we can't take any more sstables out of the compaction. + // usually means we've run out of disk space + String msg = String.format("Not enough space for compaction, estimated sstables = %d, expected write size = %d", estimatedSSTables, expectedWriteSize); + logger.warn(msg); + throw new RuntimeException(msg); + } + logger.warn("Not enough space for compaction, {}MB estimated. Reducing scope.", + (float) expectedWriteSize / 1024 / 1024); } }