Author: jbellis
Date: Fri Nov 19 19:10:48 2010
New Revision: 1036984
URL: http://svn.apache.org/viewvc?rev=1036984&view=rev
Log:
fix race between snapshot andcompaction
patch by jbellis; reviewed by gdusbabek for CASSANDRA-1736
Modified:
cassandra/branches/cassandra-0.7/CHANGES.txt
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/sstable/SSTable.java
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/sstable/SSTableDeletingReference.java
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/sstable/SSTableReader.java
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/sstable/SSTableWriter.java
Modified: cassandra/branches/cassandra-0.7/CHANGES.txt
URL:
http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/CHANGES.txt?rev=1036984&r1=1036983&r2=1036984&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/CHANGES.txt (original)
+++ cassandra/branches/cassandra-0.7/CHANGES.txt Fri Nov 19 19:10:48 2010
@@ -44,6 +44,7 @@ dev
* handle replica unavailability in index scan (CASSANDRA-1755)
* fix service initialization order deadlock (CASSANDRA-1756)
* multi-line cli commands (CASSANDRA-1742)
+ * fix race between snapshot and compaction (CASSANDRA-1736)
0.7.0-beta3
Modified:
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
URL:
http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamilyStore.java?rev=1036984&r1=1036983&r2=1036984&view=diff
==============================================================================
---
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
(original)
+++
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
Fri Nov 19 19:10:48 2010
@@ -461,9 +461,8 @@ public class ColumnFamilyStore implement
Descriptor desc = sstableFiles.getKey();
Set<Component> components = sstableFiles.getValue();
- if (SSTable.conditionalDelete(desc, components))
- // was compacted or temporary: deleted.
- continue;
+ if (components.contains(Component.COMPACTED_MARKER) ||
desc.temporary)
+ SSTable.delete(desc, components);
File dataFile = new File(desc.filenameFor(Component.DATA));
if (components.contains(Component.DATA) && dataFile.length() > 0)
@@ -1559,12 +1558,7 @@ public class ColumnFamilyStore implement
FileUtils.createDirectory(snapshotDirectoryPath);
// hard links
- for (Component component : ssTable.components)
- {
- File sourceFile = new
File(ssTable.descriptor.filenameFor(component));
- File targetLink = new File(snapshotDirectoryPath,
sourceFile.getName());
- CLibrary.createHardLink(sourceFile, targetLink);
- }
+ ssTable.createLinks(snapshotDirectoryPath);
if (logger.isDebugEnabled())
logger.debug("Snapshot for " + table + " keyspace data
file " + ssTable.getFilename() +
" created in " + snapshotDirectoryPath);
Modified:
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/sstable/SSTable.java
URL:
http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/sstable/SSTable.java?rev=1036984&r1=1036983&r2=1036984&view=diff
==============================================================================
---
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/sstable/SSTable.java
(original)
+++
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/sstable/SSTable.java
Fri Nov 19 19:10:48 2010
@@ -23,6 +23,7 @@ import java.io.File;
import java.io.FilenameFilter;
import java.io.IOError;
import java.io.IOException;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -59,12 +60,10 @@ public abstract class SSTable
public static final String COMPONENT_FILTER = Component.Type.FILTER.repr;
public static final String COMPONENT_STATS = Component.Type.STATS.repr;
- public static final String COMPONENT_COMPACTED =
Component.Type.COMPACTED_MARKER.repr;
-
public static final String TEMPFILE_MARKER = "tmp";
public final Descriptor descriptor;
- public final Set<Component> components;
+ protected final Set<Component> components;
public final CFMetaData metadata;
public final IPartitioner partitioner;
@@ -94,7 +93,10 @@ public abstract class SSTable
protected SSTable(Descriptor descriptor, Set<Component> components,
CFMetaData metadata, IPartitioner partitioner, EstimatedHistogram rowSizes,
EstimatedHistogram columnCounts)
{
this.descriptor = descriptor;
- this.components = components;
+ Set<Component> dataComponents = new HashSet<Component>(components);
+ for (Component component : components)
+ assert component.type != Component.Type.COMPACTED_MARKER;
+ this.components = Collections.unmodifiableSet(dataComponents);
this.metadata = metadata;
this.partitioner = partitioner;
estimatedRowSize = rowSizes;
@@ -122,11 +124,8 @@ public abstract class SSTable
*
* @return true if the file was deleted
*/
- public static boolean conditionalDelete(Descriptor desc, Set<Component>
components)
+ public static boolean delete(Descriptor desc, Set<Component> components)
{
- if (!components.contains(Component.COMPACTED_MARKER) &&
!desc.temporary)
- // not compacted or temporary
- return false;
try
{
// remove the DATA component first if it exists
@@ -139,8 +138,7 @@ public abstract class SSTable
FileUtils.deleteWithConfirm(desc.filenameFor(component));
}
// remove the COMPACTED_MARKER component last if it exists
- if (components.contains(Component.COMPACTED_MARKER))
-
FileUtils.deleteWithConfirm(desc.filenameFor(Component.COMPACTED_MARKER));
+ FileUtils.delete(desc.filenameFor(Component.COMPACTED_MARKER));
}
catch (IOException e)
{
Modified:
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/sstable/SSTableDeletingReference.java
URL:
http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/sstable/SSTableDeletingReference.java?rev=1036984&r1=1036983&r2=1036984&view=diff
==============================================================================
---
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/sstable/SSTableDeletingReference.java
(original)
+++
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/sstable/SSTableDeletingReference.java
Fri Nov 19 19:10:48 2010
@@ -90,9 +90,9 @@ public class SSTableDeletingReference ex
return;
}
}
- // let the remainder be cleaned up by conditionalDelete
+ // let the remainder be cleaned up by delete
components.remove(Component.DATA);
- SSTable.conditionalDelete(desc, components);
+ SSTable.delete(desc, components);
tracker.spaceReclaimed(size);
}
}
Modified:
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/sstable/SSTableReader.java
URL:
http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/sstable/SSTableReader.java?rev=1036984&r1=1036983&r2=1036984&view=diff
==============================================================================
---
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/sstable/SSTableReader.java
(original)
+++
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/sstable/SSTableReader.java
Fri Nov 19 19:10:48 2010
@@ -55,10 +55,8 @@ import org.apache.cassandra.io.util.Buff
import org.apache.cassandra.io.util.FileDataInput;
import org.apache.cassandra.io.util.SegmentedFile;
import org.apache.cassandra.service.StorageService;
-import org.apache.cassandra.utils.BloomFilter;
-import org.apache.cassandra.utils.EstimatedHistogram;
-import org.apache.cassandra.utils.FBUtilities;
-import org.apache.cassandra.utils.Pair;
+import org.apache.cassandra.utils.*;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -524,7 +522,6 @@ public class SSTableReader extends SSTab
{
throw new IOError(e);
}
- components.add(Component.COMPACTED_MARKER);
phantomReference.deleteOnCleanup();
}
@@ -597,6 +594,16 @@ public class SSTableReader extends SSTab
return in.readLong();
}
+ public void createLinks(String snapshotDirectoryPath) throws IOException
+ {
+ for (Component component : components)
+ {
+ File sourceFile = new File(descriptor.filenameFor(component));
+ File targetLink = new File(snapshotDirectoryPath,
sourceFile.getName());
+ CLibrary.createHardLink(sourceFile, targetLink);
+ }
+ }
+
/**
* Conditionally use the deprecated 'IPartitioner.convertFromDiskFormat'
method.
*/
Modified:
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/sstable/SSTableWriter.java
URL:
http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/sstable/SSTableWriter.java?rev=1036984&r1=1036983&r2=1036984&view=diff
==============================================================================
---
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/sstable/SSTableWriter.java
(original)
+++
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/io/sstable/SSTableWriter.java
Fri Nov 19 19:10:48 2010
@@ -25,6 +25,7 @@ import java.io.FileOutputStream;
import java.io.IOError;
import java.io.IOException;
import java.nio.ByteBuffer;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
@@ -65,16 +66,15 @@ public class SSTableWriter extends SSTab
public SSTableWriter(String filename, long keyCount, CFMetaData metadata,
IPartitioner partitioner) throws IOException
{
- super(Descriptor.fromFilename(filename), new HashSet<Component>(),
metadata, partitioner, SSTable.defaultRowHistogram(),
SSTable.defaultColumnHistogram());
+ super(Descriptor.fromFilename(filename),
+ new HashSet<Component>(Arrays.asList(Component.DATA,
Component.FILTER, Component.PRIMARY_INDEX, Component.STATS)),
+ metadata,
+ partitioner,
+ SSTable.defaultRowHistogram(),
+ SSTable.defaultColumnHistogram());
iwriter = new IndexWriter(descriptor, partitioner, keyCount);
dbuilder =
SegmentedFile.getBuilder(DatabaseDescriptor.getDiskAccessMode());
dataFile = new BufferedRandomAccessFile(getFilename(), "rw",
DatabaseDescriptor.getInMemoryCompactionLimit());
-
- // the set of required components
- components.add(Component.DATA);
- components.add(Component.FILTER);
- components.add(Component.PRIMARY_INDEX);
- components.add(Component.STATS);
}
public void mark()