From ce7a6107010447dbabac8b80d01f5ce9f41f1918 Mon Sep 17 00:00:00 2001 From: Jonathan Ellis Date: Fri, 2 Oct 2009 19:31:05 +0000 Subject: [PATCH] merge from 0.4 branch git-svn-id: https://svn.apache.org/repos/asf/incubator/cassandra/trunk@821137 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES.txt | 1 + .../cassandra/config/DatabaseDescriptor.java | 30 +++++++++++++++---- .../cassandra/db/ColumnFamilyStore.java | 20 +++++++++---- .../cassandra/service/ThriftValidation.java | 2 +- 4 files changed, 42 insertions(+), 11 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 57c0667730..7ccfba251f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -5,6 +5,7 @@ * Fix for serializing a row that only contains tombstones (CASSANDRA-458) * Fix for discarding unneeded commitlog segments (CASSANDRA-459) + * Add SnapshotBeforeCompaction configuration option (CASSANDRA-426) 0.4.0 diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java index f10a198d82..28bee84682 100644 --- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java +++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java @@ -128,6 +128,8 @@ public class DatabaseDescriptor private static double commitLogSyncBatchMS_; private static int commitLogSyncPeriodMS_; + private static boolean snapshotBeforeCompaction_; + static { try @@ -305,18 +307,31 @@ public class DatabaseDescriptor String framedRaw = xmlUtils.getNodeValue("/Storage/ThriftFramedTransport"); if (framedRaw != null) { - if (framedRaw.compareToIgnoreCase("true") == 0 || - framedRaw.compareToIgnoreCase("false") == 0) + if (framedRaw.equalsIgnoreCase("true") || framedRaw.equalsIgnoreCase("false")) { thriftFramed_ = Boolean.valueOf(framedRaw); } else { - throw new ConfigurationException("Unrecognized value " + - "for ThriftFramedTransport. Use 'true' or 'false'."); + throw new ConfigurationException("Unrecognized value for ThriftFramedTransport. Use 'true' or 'false'."); + } + } + + /* snapshot-before-compaction. defaults to false */ + String sbc = xmlUtils.getNodeValue("/Storage/SnapshotBeforeCompaction"); + if (sbc != null) + { + if (sbc.equalsIgnoreCase("true") || sbc.equalsIgnoreCase("false")) + { + if (logger_.isDebugEnabled()) + logger_.debug("setting snapshotBeforeCompaction to " + sbc); + snapshotBeforeCompaction_ = Boolean.valueOf(sbc); + } + else + { + throw new ConfigurationException("Unrecognized value for SnapshotBeforeCompaction. Use 'true' or 'false'."); } } - /* Number of days to keep the memtable around w/o flushing */ String lifetime = xmlUtils.getNodeValue("/Storage/MemtableFlushAfterMinutes"); @@ -973,4 +988,9 @@ public class DatabaseDescriptor { return bmtThreshold_; } + + public static boolean isSnapshotBeforeCompaction() + { + return snapshotBeforeCompaction_; + } } diff --git a/src/java/org/apache/cassandra/db/ColumnFamilyStore.java b/src/java/org/apache/cassandra/db/ColumnFamilyStore.java index 2291235c1e..0ce9ee6cc0 100644 --- a/src/java/org/apache/cassandra/db/ColumnFamilyStore.java +++ b/src/java/org/apache/cassandra/db/ColumnFamilyStore.java @@ -417,14 +417,9 @@ public final class ColumnFamilyStore implements ColumnFamilyStoreMBean void forceBlockingFlush() throws IOException, ExecutionException, InterruptedException { - Memtable oldMemtable = getMemtableThreadSafe(); Future future = forceFlush(); if (future != null) future.get(); - /* this assert is not threadsafe -- the memtable could have been clean when forceFlush - checked it, but dirty now thanks to another thread. But as long as we are only - calling this from single-threaded test code it is useful to have as a sanity check. */ - assert oldMemtable.isFlushed() || oldMemtable.isClean(); } public void forceFlushBinary() @@ -833,6 +828,8 @@ public final class ColumnFamilyStore implements ColumnFamilyStoreMBean */ private int doFileCompaction(Collection sstables) throws IOException { + if (DatabaseDescriptor.isSnapshotBeforeCompaction()) + Table.open(table_).snapshot("compact-" + columnFamily_); logger_.info("Compacting [" + StringUtils.join(sstables, ",") + "]"); String compactionFileLocation = DatabaseDescriptor.getDataFileLocationForTable(table_, getExpectedCompactedFileSize(sstables)); // If the compaction file path is null that means we have no space left for this compaction. @@ -1285,6 +1282,19 @@ public final class ColumnFamilyStore implements ColumnFamilyStoreMBean */ public void snapshot(String snapshotName) throws IOException { + try + { + forceBlockingFlush(); + } + catch (ExecutionException e) + { + throw new RuntimeException(e); + } + catch (InterruptedException e) + { + throw new AssertionError(e); + } + for (SSTableReader ssTable : ssTables_) { // mkdir diff --git a/src/java/org/apache/cassandra/service/ThriftValidation.java b/src/java/org/apache/cassandra/service/ThriftValidation.java index 545def289a..f1fb2792db 100644 --- a/src/java/org/apache/cassandra/service/ThriftValidation.java +++ b/src/java/org/apache/cassandra/service/ThriftValidation.java @@ -95,7 +95,7 @@ public class ThriftValidation else { if (column_path.super_column == null) - throw new InvalidRequestException("column parameter is not optional for super CF " + column_path.column_family); + throw new InvalidRequestException("supercolumn parameter is not optional for super CF " + column_path.column_family); } if (column_path.column != null) {