Range tombstones that are masked by row tombstones should not be written out
patch by Nachiket Patil; reviewed by Sylvain Lebresne for CASSANDRA-12030 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/98f5f77b Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/98f5f77b Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/98f5f77b Branch: refs/heads/cassandra-3.8 Commit: 98f5f77bb3c5d50e52cbb6f577a463ca8a5134ad Parents: 3c1653f Author: Nachiket Patil <nachiket_pa...@apple.com> Authored: Wed Jul 6 11:22:56 2016 +0200 Committer: Sylvain Lebresne <sylv...@datastax.com> Committed: Wed Jul 6 14:35:10 2016 +0200 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../db/compaction/LazilyCompactedRow.java | 3 +- .../apache/cassandra/db/RangeTombstoneTest.java | 40 ++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/98f5f77b/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index b1dcbe1..7fa995d 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 2.1.16 + * Don't write shadowed range tombstone (CASSANDRA-12030) * Fix filtering on clustering columns when 2i is used (CASSANDRA-11907) * Reduce contention getting instances of CompositeType (CASSANDRA-10433) * Improve digest calculation in the presence of overlapping tombstones (CASSANDRA-11349) http://git-wip-us.apache.org/repos/asf/cassandra/blob/98f5f77b/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 f912da2..dab5eeb 100644 --- a/src/java/org/apache/cassandra/db/compaction/LazilyCompactedRow.java +++ b/src/java/org/apache/cassandra/db/compaction/LazilyCompactedRow.java @@ -286,7 +286,8 @@ public class LazilyCompactedRow extends AbstractCompactedRow RangeTombstone t = tombstone; tombstone = null; - if (t.data.isGcAble(controller.gcBefore) && t.timestamp() < getMaxPurgeableTimestamp()) + if (t.data.isGcAble(controller.gcBefore) && t.timestamp() < getMaxPurgeableTimestamp() || + maxRowTombstone.markedForDeleteAt >= t.timestamp()) { indexBuilder.tombstoneTracker().update(t, true); return null; http://git-wip-us.apache.org/repos/asf/cassandra/blob/98f5f77b/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 3292422..dfd6960 100644 --- a/test/unit/org/apache/cassandra/db/RangeTombstoneTest.java +++ b/test/unit/org/apache/cassandra/db/RangeTombstoneTest.java @@ -39,6 +39,7 @@ import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.IndexType; import org.apache.cassandra.db.columniterator.OnDiskAtomIterator; import org.apache.cassandra.db.compaction.CompactionManager; +import org.apache.cassandra.db.compaction.LeveledCompactionStrategy; import org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy; import org.apache.cassandra.db.composites.CellName; import org.apache.cassandra.db.composites.CellNames; @@ -543,6 +544,45 @@ public class RangeTombstoneTest extends SchemaLoader } @Test + public void testCompactionOfRangeTombstonesCoveredByRowTombstone() throws Exception + { + long testTimeStamp = 1451606400L; // 01/01/2016 : 00:00:00 GMT + Keyspace table = Keyspace.open(KSNAME); + ColumnFamilyStore cfs = table.getColumnFamilyStore(CFNAME); + ByteBuffer key = ByteBufferUtil.bytes("k4"); + + // remove any existing sstables before starting + cfs.truncateBlocking(); + cfs.disableAutoCompaction(); + cfs.setCompactionStrategyClass(LeveledCompactionStrategy.class.getCanonicalName()); + + Mutation rm = new Mutation(KSNAME, key); + for (int i = 1; i < 11; i += 2, testTimeStamp += i * 10) + add(rm, i, testTimeStamp); + rm.apply(); + cfs.forceBlockingFlush(); + + rm = new Mutation(KSNAME, key); + ColumnFamily cf = rm.addOrGet(CFNAME); + + // Write the covering row tombstone + cf.delete(new DeletionTime(++testTimeStamp, (int) testTimeStamp)); + + // Create range tombstones covered by row tombstone above. + for (int i = 1; i < 11; i += 2, testTimeStamp -= i * 5) + delete(cf, 0, 7, testTimeStamp); + rm.apply(); + cfs.forceBlockingFlush(); + + // there should be 2 sstables + assertEquals(2, cfs.getSSTables().size()); + + // compact down to nothing + CompactionManager.instance.performMaximal(cfs); + assertEquals(0, cfs.getSSTables().size()); + } + + @Test public void testOverwritesToDeletedColumns() throws Exception { Keyspace table = Keyspace.open(KSNAME);