Author: jbellis
Date: Fri Oct 2 19:22:58 2009
New Revision: 821136
URL: http://svn.apache.org/viewvc?rev=821136&view=rev
Log:
option (default to false) to snapshot sstables before each compaction. this
provides a "safety net" in case anything goes wrong during compaction. patch
by jbellis; tested by molinaro for CASSANDRA-426
Modified:
incubator/cassandra/branches/cassandra-0.4/CHANGES.txt
incubator/cassandra/branches/cassandra-0.4/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
incubator/cassandra/branches/cassandra-0.4/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
Modified: incubator/cassandra/branches/cassandra-0.4/CHANGES.txt
URL:
http://svn.apache.org/viewvc/incubator/cassandra/branches/cassandra-0.4/CHANGES.txt?rev=821136&r1=821135&r2=821136&view=diff
==============================================================================
--- incubator/cassandra/branches/cassandra-0.4/CHANGES.txt (original)
+++ incubator/cassandra/branches/cassandra-0.4/CHANGES.txt Fri Oct 2 19:22:58
2009
@@ -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
Modified:
incubator/cassandra/branches/cassandra-0.4/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
URL:
http://svn.apache.org/viewvc/incubator/cassandra/branches/cassandra-0.4/src/java/org/apache/cassandra/config/DatabaseDescriptor.java?rev=821136&r1=821135&r2=821136&view=diff
==============================================================================
---
incubator/cassandra/branches/cassandra-0.4/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
(original)
+++
incubator/cassandra/branches/cassandra-0.4/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
Fri Oct 2 19:22:58 2009
@@ -131,6 +131,8 @@
private static double commitLogSyncBatchMS_;
private static int commitLogSyncPeriodMS_;
+ private static boolean snapshotBeforeCompaction_;
+
static
{
try
@@ -320,18 +322,31 @@
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/MemtableLifetimeInDays");
@@ -1018,4 +1033,9 @@
{
return bmtThreshold_;
}
+
+ public static boolean isSnapshotBeforeCompaction()
+ {
+ return snapshotBeforeCompaction_;
+ }
}
Modified:
incubator/cassandra/branches/cassandra-0.4/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
URL:
http://svn.apache.org/viewvc/incubator/cassandra/branches/cassandra-0.4/src/java/org/apache/cassandra/db/ColumnFamilyStore.java?rev=821136&r1=821135&r2=821136&view=diff
==============================================================================
---
incubator/cassandra/branches/cassandra-0.4/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
(original)
+++
incubator/cassandra/branches/cassandra-0.4/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
Fri Oct 2 19:22:58 2009
@@ -409,7 +409,6 @@
void forceBlockingFlush() throws IOException, ExecutionException,
InterruptedException
{
- Memtable oldMemtable = getMemtableThreadSafe();
forceFlush();
// block for flush to finish by adding a no-op action to the flush
executorservice
// and waiting for that to finish. (this works since flush ES is
single-threaded.)
@@ -420,10 +419,6 @@
}
});
f.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()
@@ -1012,6 +1007,8 @@
*/
private int doFileCompaction(List<String> files, int minBufferSize) throws
IOException
{
+ if (DatabaseDescriptor.isSnapshotBeforeCompaction())
+ Table.open(table_).snapshot("compact-" + columnFamily_);
logger_.info("Compacting [" + StringUtils.join(files, ",") + "]");
String compactionFileLocation =
DatabaseDescriptor.getDataFileLocationForTable(table_,
getExpectedCompactedFileSize(files));
// If the compaction file path is null that means we have no space
left for this compaction.
@@ -1549,6 +1546,19 @@
*/
public void snapshot(String snapshotName) throws IOException
{
+ try
+ {
+ forceBlockingFlush();
+ }
+ catch (ExecutionException e)
+ {
+ throw new RuntimeException(e);
+ }
+ catch (InterruptedException e)
+ {
+ throw new AssertionError(e);
+ }
+
sstableLock_.readLock().lock();
try
{