diff --git a/test/unit/org/apache/cassandra/cql3/MemtableSizeTest.java b/test/unit/org/apache/cassandra/cql3/MemtableSizeTest.java index dbe0498654..7d6c6dd304 100644 --- a/test/unit/org/apache/cassandra/cql3/MemtableSizeTest.java +++ b/test/unit/org/apache/cassandra/cql3/MemtableSizeTest.java @@ -18,10 +18,12 @@ package org.apache.cassandra.cql3; +import com.google.common.base.Throwables; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; +import org.apache.cassandra.Util; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.db.ColumnFamilyStore; import org.apache.cassandra.db.Keyspace; @@ -54,71 +56,82 @@ public class MemtableSizeTest extends CQLTester } @Test - public void testSize() throws Throwable + public void testTruncationReleasesLogSpace() { - keyspace = createKeyspace("CREATE KEYSPACE %s with replication = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 } and durable_writes = false"); - table = createTable(keyspace, "CREATE TABLE %s ( userid bigint, picid bigint, commentid bigint, PRIMARY KEY(userid, picid)) with compression = {'enabled': false}"); - execute("use " + keyspace + ';'); - - String writeStatement = "INSERT INTO "+table+"(userid,picid,commentid)VALUES(?,?,?)"; - - cfs = Keyspace.open(keyspace).getColumnFamilyStore(table); - cfs.disableAutoCompaction(); - cfs.forceBlockingFlush(); - - long deepSizeBefore = ObjectSizes.measureDeep(cfs.getTracker().getView().getCurrentMemtable()); - System.out.printf("Memtable deep size before %s\n%n", - FBUtilities.prettyPrintMemory(deepSizeBefore)); - long i; - long limit = partitions; - System.out.println("Writing " + partitions + " partitions of " + rowsPerPartition + " rows"); - for (i = 0; i < limit; ++i) - { - for (long j = 0; j < rowsPerPartition; ++j) - execute(writeStatement, i, j, i + j); - } - - System.out.println("Deleting " + deletedPartitions + " partitions"); - limit += deletedPartitions; - for (; i < limit; ++i) - { - // no partition exists, but we will create a tombstone - execute("DELETE FROM " + table + " WHERE userid = ?", i); - } - - System.out.println("Deleting " + deletedRows + " rows"); - limit += deletedRows; - for (; i < limit; ++i) - { - // no row exists, but we will create a tombstone (and partition) - execute("DELETE FROM " + table + " WHERE userid = ? AND picid = ?", i, 0L); - } - - - if (!cfs.getLiveSSTables().isEmpty()) - System.out.println("Warning: " + cfs.getLiveSSTables().size() + " sstables created."); - - Memtable memtable = cfs.getTracker().getView().getCurrentMemtable(); - long actualHeap = memtable.getAllocator().onHeap().owns(); - System.out.printf("Memtable in %s mode: %d ops, %s serialized bytes, %s (%.0f%%) on heap, %s (%.0f%%) off-heap%n", - DatabaseDescriptor.getMemtableAllocationType(), - memtable.getOperations(), - FBUtilities.prettyPrintMemory(memtable.getLiveDataSize()), - FBUtilities.prettyPrintMemory(actualHeap), - 100 * memtable.getAllocator().onHeap().ownershipRatio(), - FBUtilities.prettyPrintMemory(memtable.getAllocator().offHeap().owns()), - 100 * memtable.getAllocator().offHeap().ownershipRatio()); - - long deepSizeAfter = ObjectSizes.measureDeep(memtable); - System.out.printf("Memtable deep size %s\n%n", - FBUtilities.prettyPrintMemory(deepSizeAfter)); - - long expectedHeap = deepSizeAfter - deepSizeBefore; - String message = String.format("Expected heap usage close to %s, got %s.\n", - FBUtilities.prettyPrintMemory(expectedHeap), - FBUtilities.prettyPrintMemory(actualHeap)); - System.out.println(message); - Assert.assertTrue(message, Math.abs(actualHeap - expectedHeap) <= MAX_DIFFERENCE); + Util.flakyTest(this::testSize, 2, "Fails occasionally, see CASSANDRA-16684"); } + private void testSize() + { + try + { + keyspace = createKeyspace("CREATE KEYSPACE %s with replication = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 } and durable_writes = false"); + table = createTable(keyspace, "CREATE TABLE %s ( userid bigint, picid bigint, commentid bigint, PRIMARY KEY(userid, picid)) with compression = {'enabled': false}"); + execute("use " + keyspace + ';'); + + String writeStatement = "INSERT INTO " + table + "(userid,picid,commentid)VALUES(?,?,?)"; + + cfs = Keyspace.open(keyspace).getColumnFamilyStore(table); + cfs.disableAutoCompaction(); + cfs.forceBlockingFlush(); + + long deepSizeBefore = ObjectSizes.measureDeep(cfs.getTracker().getView().getCurrentMemtable()); + System.out.printf("Memtable deep size before %s\n%n", + FBUtilities.prettyPrintMemory(deepSizeBefore)); + long i; + long limit = partitions; + System.out.println("Writing " + partitions + " partitions of " + rowsPerPartition + " rows"); + for (i = 0; i < limit; ++i) + { + for (long j = 0; j < rowsPerPartition; ++j) + execute(writeStatement, i, j, i + j); + } + + System.out.println("Deleting " + deletedPartitions + " partitions"); + limit += deletedPartitions; + for (; i < limit; ++i) + { + // no partition exists, but we will create a tombstone + execute("DELETE FROM " + table + " WHERE userid = ?", i); + } + + System.out.println("Deleting " + deletedRows + " rows"); + limit += deletedRows; + for (; i < limit; ++i) + { + // no row exists, but we will create a tombstone (and partition) + execute("DELETE FROM " + table + " WHERE userid = ? AND picid = ?", i, 0L); + } + + + if (!cfs.getLiveSSTables().isEmpty()) + System.out.println("Warning: " + cfs.getLiveSSTables().size() + " sstables created."); + + Memtable memtable = cfs.getTracker().getView().getCurrentMemtable(); + long actualHeap = memtable.getAllocator().onHeap().owns(); + System.out.printf("Memtable in %s mode: %d ops, %s serialized bytes, %s (%.0f%%) on heap, %s (%.0f%%) off-heap%n", + DatabaseDescriptor.getMemtableAllocationType(), + memtable.getOperations(), + FBUtilities.prettyPrintMemory(memtable.getLiveDataSize()), + FBUtilities.prettyPrintMemory(actualHeap), + 100 * memtable.getAllocator().onHeap().ownershipRatio(), + FBUtilities.prettyPrintMemory(memtable.getAllocator().offHeap().owns()), + 100 * memtable.getAllocator().offHeap().ownershipRatio()); + + long deepSizeAfter = ObjectSizes.measureDeep(memtable); + System.out.printf("Memtable deep size %s\n%n", + FBUtilities.prettyPrintMemory(deepSizeAfter)); + + long expectedHeap = deepSizeAfter - deepSizeBefore; + String message = String.format("Expected heap usage close to %s, got %s.\n", + FBUtilities.prettyPrintMemory(expectedHeap), + FBUtilities.prettyPrintMemory(actualHeap)); + System.out.println(message); + Assert.assertTrue(message, Math.abs(actualHeap - expectedHeap) <= MAX_DIFFERENCE); + } + catch (Throwable throwable) + { + Throwables.propagate(throwable); + } + } } \ No newline at end of file