Return-Path: X-Original-To: apmail-cassandra-commits-archive@www.apache.org Delivered-To: apmail-cassandra-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id E5F8C1143F for ; Tue, 26 Aug 2014 14:20:26 +0000 (UTC) Received: (qmail 6105 invoked by uid 500); 26 Aug 2014 14:20:26 -0000 Delivered-To: apmail-cassandra-commits-archive@cassandra.apache.org Received: (qmail 6077 invoked by uid 500); 26 Aug 2014 14:20:26 -0000 Mailing-List: contact commits-help@cassandra.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cassandra.apache.org Delivered-To: mailing list commits@cassandra.apache.org Received: (qmail 6053 invoked by uid 99); 26 Aug 2014 14:20:26 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 26 Aug 2014 14:20:26 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 1CA77A009F1; Tue, 26 Aug 2014 14:20:25 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: marcuse@apache.org To: commits@cassandra.apache.org Date: Tue, 26 Aug 2014 14:20:28 -0000 Message-Id: <9c81cd8409d84f5ea02a2aa14809e4a1@git.apache.org> In-Reply-To: <0655da97e7564931b6368bc4a92ddc6f@git.apache.org> References: <0655da97e7564931b6368bc4a92ddc6f@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [4/8] git commit: Don't clear out range tombstones during compaction. Don't clear out range tombstones during compaction. Patch by rlow; reviewed by marcuse for CASSANDRA-7808 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/1cf98630 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/1cf98630 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/1cf98630 Branch: refs/heads/trunk Commit: 1cf986301b6109b5744b52b80dcdb1640be2b247 Parents: 62642fa Author: Marcus Eriksson Authored: Tue Aug 26 11:33:24 2014 +0200 Committer: Marcus Eriksson Committed: Tue Aug 26 15:23:43 2014 +0200 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../db/compaction/LazilyCompactedRow.java | 8 ++- .../apache/cassandra/db/RangeTombstoneTest.java | 60 ++++++++++++++++++++ 3 files changed, 66 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/1cf98630/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 7fb6de9..badb45e 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -11,6 +11,7 @@ are thrown while handling native protocol messages (CASSANDRA-7470) * Fix row size miscalculation in LazilyCompactedRow (CASSANDRA-7543) * Fix race in background compaction check (CASSANDRA-7745) + * Don't clear out range tombstones during compaction (CASSANDRA-7808) 1.2.18 http://git-wip-us.apache.org/repos/asf/cassandra/blob/1cf98630/src/java/org/apache/cassandra/db/compaction/LazilyCompactedRow.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/compaction/LazilyCompactedRow.java b/src/java/org/apache/cassandra/db/compaction/LazilyCompactedRow.java index d9f753c..4360b0b 100644 --- a/src/java/org/apache/cassandra/db/compaction/LazilyCompactedRow.java +++ b/src/java/org/apache/cassandra/db/compaction/LazilyCompactedRow.java @@ -167,8 +167,9 @@ public class LazilyCompactedRow extends AbstractCompactedRow implements Iterable public boolean isEmpty() { + // need to clone emptyColumnFamily to avoid resetting the deletion time. See CASSANDRA-7808. boolean cfIrrelevant = shouldPurge - ? ColumnFamilyStore.removeDeletedCF(emptyColumnFamily, controller.gcBefore) == null + ? ColumnFamilyStore.removeDeletedCF(emptyColumnFamily.cloneMeShallow(), controller.gcBefore) == null : !emptyColumnFamily.isMarkedForDelete(); // tombstones are relevant return cfIrrelevant && columnStats.columnCount == 0; } @@ -285,11 +286,12 @@ public class LazilyCompactedRow extends AbstractCompactedRow implements Iterable ColumnFamily purged = PrecompactedRow.removeDeletedAndOldShards(key, shouldPurge, controller, container); if (purged == null || !purged.iterator().hasNext()) { - container.clear(); + // don't call clear() because that resets the deletion time. See CASSANDRA-7808. + container = emptyColumnFamily.cloneMeShallow(); return null; } IColumn reduced = purged.iterator().next(); - container.clear(); + container = emptyColumnFamily.cloneMeShallow(); // PrecompactedRow.removeDeletedAndOldShards have only checked the top-level CF deletion times, // not the range tombstone. For that we use the columnIndexer tombstone tracker. http://git-wip-us.apache.org/repos/asf/cassandra/blob/1cf98630/test/unit/org/apache/cassandra/db/RangeTombstoneTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/db/RangeTombstoneTest.java b/test/unit/org/apache/cassandra/db/RangeTombstoneTest.java index c2f8b83..59be938 100644 --- a/test/unit/org/apache/cassandra/db/RangeTombstoneTest.java +++ b/test/unit/org/apache/cassandra/db/RangeTombstoneTest.java @@ -18,17 +18,22 @@ */ package org.apache.cassandra.db; +import java.io.IOException; import java.nio.ByteBuffer; import java.util.*; +import java.util.concurrent.ExecutionException; import org.junit.Test; import org.apache.cassandra.SchemaLoader; +import org.apache.cassandra.Util; +import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.db.compaction.CompactionManager; import org.apache.cassandra.db.filter.*; import org.apache.cassandra.utils.ByteBufferUtil; import static org.apache.cassandra.Util.dk; +import static org.junit.Assert.assertEquals; public class RangeTombstoneTest extends SchemaLoader { @@ -97,6 +102,61 @@ public class RangeTombstoneTest extends SchemaLoader } @Test + public void test7808_1() throws ExecutionException, InterruptedException + { + DatabaseDescriptor.setInMemoryCompactionLimit(0); + Table table = Table.open(KSNAME); + ColumnFamilyStore cfs = table.getColumnFamilyStore(CFNAME); + cfs.metadata.gcGraceSeconds(2); + + String key = "7808_1"; + RowMutation rm; + rm = new RowMutation(KSNAME, ByteBufferUtil.bytes(key)); + for (int i = 0; i < 40; i += 2) + add(rm, i, 0); + rm.apply(); + cfs.forceBlockingFlush(); + rm = new RowMutation(KSNAME, ByteBufferUtil.bytes(key)); + ColumnFamily cf = rm.addOrGet(CFNAME); + cf.delete(new DeletionInfo(1, 1)); + rm.apply(); + cfs.forceBlockingFlush(); + Thread.sleep(5); + cfs.forceMajorCompaction(); + } + + @Test + public void test7808_2() throws ExecutionException, InterruptedException, IOException + { + DatabaseDescriptor.setInMemoryCompactionLimit(0); + Table table = Table.open(KSNAME); + ColumnFamilyStore cfs = table.getColumnFamilyStore(CFNAME); + cfs.metadata.gcGraceSeconds(2); + + String key = "7808_2"; + RowMutation rm; + rm = new RowMutation(KSNAME, ByteBufferUtil.bytes(key)); + for (int i = 10; i < 20; i++) + add(rm, i, 0); + rm.apply(); + cfs.forceBlockingFlush(); + + rm = new RowMutation(KSNAME, ByteBufferUtil.bytes(key)); + ColumnFamily cf = rm.addOrGet(CFNAME); + cf.delete(new DeletionInfo(0,0)); + rm.apply(); + + rm = new RowMutation(KSNAME, ByteBufferUtil.bytes(key)); + add(rm, 5, 1); + rm.apply(); + + cfs.forceBlockingFlush(); + Thread.sleep(5); + cfs.forceMajorCompaction(); + assertEquals(1, Util.getColumnFamily(table, Util.dk(key), CFNAME).getColumnCount()); + } + + @Test public void overlappingRangeTest() throws Exception { CompactionManager.instance.disableAutoCompaction();