You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by sl...@apache.org on 2011/06/21 14:51:35 UTC

svn commit: r1137984 - in /cassandra/branches/cassandra-0.8: CHANGES.txt src/java/org/apache/cassandra/db/compaction/PrecompactedRow.java test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java

Author: slebresne
Date: Tue Jun 21 12:51:34 2011
New Revision: 1137984

URL: http://svn.apache.org/viewvc?rev=1137984&view=rev
Log:
Fix wrong purge of deleted cf during compaction
patch by slebresne; reviewed by jbellis for CASSANDRA-2786

Modified:
    cassandra/branches/cassandra-0.8/CHANGES.txt
    cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/db/compaction/PrecompactedRow.java
    cassandra/branches/cassandra-0.8/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java

Modified: cassandra/branches/cassandra-0.8/CHANGES.txt
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/CHANGES.txt?rev=1137984&r1=1137983&r2=1137984&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/CHANGES.txt (original)
+++ cassandra/branches/cassandra-0.8/CHANGES.txt Tue Jun 21 12:51:34 2011
@@ -69,6 +69,7 @@
  * add jamm agent to cassandra.bat (CASSANDRA-2787)
  * fix repair hanging if a neighbor has nothing to send (CASSANDRA-2797)
  * purge tombstone even if row is in only one sstable (CASSANDRA-2801)
+ * Fix wrong purge of deleted cf during compaction (CASSANDRA-2786)
 
 
 0.8.0-final

Modified: cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/db/compaction/PrecompactedRow.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/db/compaction/PrecompactedRow.java?rev=1137984&r1=1137983&r2=1137984&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/db/compaction/PrecompactedRow.java (original)
+++ cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/db/compaction/PrecompactedRow.java Tue Jun 21 12:51:34 2011
@@ -45,16 +45,20 @@ public class PrecompactedRow extends Abs
     private static Logger logger = LoggerFactory.getLogger(PrecompactedRow.class);
 
     private final ColumnFamily compactedCf;
+    private final int gcBefore;
 
+    // For testing purposes
     public PrecompactedRow(DecoratedKey key, ColumnFamily compacted)
     {
         super(key);
         this.compactedCf = compacted;
+        this.gcBefore = Integer.MAX_VALUE;
     }
 
     public PrecompactedRow(CompactionController controller, List<SSTableIdentityIterator> rows)
     {
         super(rows.get(0).getKey());
+        this.gcBefore = controller.gcBefore;
 
         ColumnFamily cf = null;
         for (SSTableIdentityIterator row : rows)
@@ -120,7 +124,7 @@ public class PrecompactedRow extends Abs
 
     public boolean isEmpty()
     {
-        return compactedCf == null || compactedCf.getColumnCount() == 0;
+        return compactedCf == null || ColumnFamilyStore.removeDeletedCF(compactedCf, gcBefore) == null;
     }
 
     public int columnCount()

Modified: cassandra/branches/cassandra-0.8/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java?rev=1137984&r1=1137983&r2=1137984&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java (original)
+++ cassandra/branches/cassandra-0.8/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java Tue Jun 21 12:51:34 2011
@@ -23,6 +23,7 @@ import java.net.InetAddress;
 import java.nio.ByteBuffer;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
+import java.util.Collection;
 import java.util.List;
 import java.util.ArrayList;
 import java.util.Set;
@@ -34,11 +35,10 @@ import org.junit.Test;
 
 import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.CleanupHelper;
-import org.apache.cassandra.db.Table;
-import org.apache.cassandra.db.ColumnFamilyStore;
-import org.apache.cassandra.db.DecoratedKey;
-import org.apache.cassandra.db.RowMutation;
+import org.apache.cassandra.db.*;
+import org.apache.cassandra.db.filter.QueryFilter;
 import org.apache.cassandra.db.filter.QueryPath;
+import org.apache.cassandra.io.sstable.*;
 import org.apache.cassandra.utils.ByteBufferUtil;
 import org.apache.cassandra.utils.FBUtilities;
 import org.apache.cassandra.utils.Pair;
@@ -157,6 +157,7 @@ public class CompactionsTest extends Cle
         buckets = CompactionManager.getBuckets(pairs, 10); // notice the min is 10
         assertEquals(1, buckets.size());
     }
+
     @Test
     public void testEchoedRow() throws IOException, ExecutionException, InterruptedException
     {
@@ -187,4 +188,51 @@ public class CompactionsTest extends Cle
         // Now assert we do have the two keys
         assertEquals(4, Util.getRangeSlice(store).size());
     }
+
+    @Test
+    public void testDontPurgeAccidentaly() throws IOException, ExecutionException, InterruptedException
+    {
+        // This test catches the regression of CASSANDRA-2786
+        Table table = Table.open(TABLE1);
+        String cfname = "Super5";
+        ColumnFamilyStore store = table.getColumnFamilyStore(cfname);
+
+        // disable compaction while flushing
+        store.disableAutoCompaction();
+
+        // Add test row
+        DecoratedKey key = Util.dk("test");
+        RowMutation rm = new RowMutation(TABLE1, key.key);
+        rm.add(new QueryPath(cfname, ByteBufferUtil.bytes("sc"), ByteBufferUtil.bytes("c")), ByteBufferUtil.EMPTY_BYTE_BUFFER, 0);
+        rm.apply();
+
+        store.forceBlockingFlush();
+
+        Collection<SSTableReader> sstablesBefore = store.getSSTables();
+
+        QueryFilter filter = QueryFilter.getIdentityFilter(Util.dk("test"), new QueryPath(cfname, null, null));
+        assert !store.getColumnFamily(filter).isEmpty();
+
+        // Remove key
+        key = Util.dk("test");
+        rm = new RowMutation(TABLE1, key.key);
+        rm.delete(new QueryPath(cfname, null, null), 2);
+        rm.apply();
+
+        ColumnFamily cf = store.getColumnFamily(filter);
+        assert cf.isEmpty() : "should be empty: " + cf;
+
+        store.forceBlockingFlush();
+
+        Collection<SSTableReader> sstablesAfter = store.getSSTables();
+        Collection<Descriptor> toCompact = new ArrayList<Descriptor>();
+        for (SSTableReader sstable : sstablesAfter)
+            if (!sstablesBefore.contains(sstable))
+                toCompact.add(sstable.descriptor);
+
+        CompactionManager.instance.submitUserDefined(store, toCompact, (int) (System.currentTimeMillis() / 1000) - store.metadata.getGcGraceSeconds()).get();
+
+        cf = store.getColumnFamily(filter);
+        assert cf.isEmpty() : "should be empty: " + cf;
+    }
 }