Add system_views.max_sstable_size and system_views.max_sstable_duration tables

patch by Stefan Miklosovic; reviewed by Brandon Williams for CASSANDRA-18333
This commit is contained in:
Stefan Miklosovic 2023-03-14 21:45:15 +01:00
parent 4734dfc503
commit a76286795f
No known key found for this signature in database
GPG Key ID: 32F35CB2F546D93E
6 changed files with 51 additions and 3 deletions

View File

@ -1,4 +1,5 @@
5.0
* Add system_views.max_sstable_size and system_views.max_sstable_duration tables (CASSANDRA-18333)
* Extend implicit allow-filtering for virtual tables to clustering columns (CASSANDRA-18331)
* Upgrade maven-shade-plugin to 3.4.1 to fix shaded dtest JAR build (CASSANDRA-18136)
* Upgrade to Opcodes.ASM9 (CASSANDRA-17971)

View File

@ -130,6 +130,7 @@ New features
SSTable of a table or 0 when there is not any SSTable. The latter returns the maximum duration, computed as
`maxTimestamp - minTimestamp`, effectively non-zero for SSTables produced by TimeWindowCompactionStrategy.
- Added local read/write ratio to tablestats.
- Added system_views.max_sstable_size and system_views.max_sstable_duration tables.
Upgrading
---------

View File

@ -77,7 +77,9 @@ public class TableMetricTables
new HistogramTableMetric(name, "tombstones_per_read", t -> t.tombstoneScannedHistogram.cf),
new HistogramTableMetric(name, "rows_per_read", t -> t.liveScannedHistogram.cf),
new StorageTableMetric(name, "disk_usage", (TableMetrics t) -> t.totalDiskSpaceUsed),
new StorageTableMetric(name, "max_partition_size", (TableMetrics t) -> t.maxPartitionSize));
new StorageTableMetric(name, "max_partition_size", (TableMetrics t) -> t.maxPartitionSize),
new StorageTableMetric(name, "max_sstable_size", (TableMetrics t) -> t.maxSSTableSize),
new TableMetricTable(name, "max_sstable_duration", t -> t.maxSSTableDuration, "max_sstable_duration", LongType.instance, ""));
}
/**

View File

@ -649,7 +649,7 @@ public class TableMetrics
.filter(sstable -> sstable.getMinTimestamp() != Long.MAX_VALUE && sstable.getMaxTimestamp() != Long.MAX_VALUE)
.map(ssTableReader -> ssTableReader.getMaxTimestamp() - ssTableReader.getMinTimestamp())
.max(Long::compare)
.orElse(0L);
.orElse(0L) / 1000;
}
});
maxSSTableSize = createTableGauge("MaxSSTableSize", new Gauge<Long>()

View File

@ -433,7 +433,7 @@ public class TableStatsHolder implements StatsHolder
private String millisToDuration(long millis)
{
return DurationFormatUtils.formatDurationWords(millis / 1000, true, true);
return DurationFormatUtils.formatDurationWords(millis, true, true);
}
/**

View File

@ -19,10 +19,12 @@
package org.apache.cassandra.metrics;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.google.common.util.concurrent.Uninterruptibles;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@ -36,6 +38,7 @@ import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.db.ColumnFamilyStore;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.service.EmbeddedCassandraService;
import org.apache.cassandra.service.StorageService;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@ -47,6 +50,7 @@ public class TableMetricsTest
private static final String KEYSPACE = "junit";
private static final String TABLE = "tablemetricstest";
private static final String COUNTER_TABLE = "tablemetricscountertest";
private static final String TWCS_TABLE = "tablemetricstesttwcs";
private static EmbeddedCassandraService cassandra;
private static Cluster cluster;
@ -68,6 +72,15 @@ public class TableMetricsTest
return recreateTable(TABLE);
}
private ColumnFamilyStore recreateTWCSTable()
{
session.execute(String.format("DROP TABLE IF EXISTS %s.%s", KEYSPACE, TWCS_TABLE));
session.execute(String.format("CREATE TABLE IF NOT EXISTS %s.%s (id int, val1 text, val2 text, PRIMARY KEY(id, val1)) " +
" WITH compaction = {'class': 'TimeWindowCompactionStrategy', 'compaction_window_unit': 'MINUTES', 'compaction_window_size': 1};",
KEYSPACE, TWCS_TABLE));
return ColumnFamilyStore.getIfExists(KEYSPACE, TWCS_TABLE);
}
private ColumnFamilyStore recreateTable(String table)
{
session.execute(String.format("DROP TABLE IF EXISTS %s.%s", KEYSPACE, table));
@ -129,6 +142,37 @@ public class TableMetricsTest
assertGreaterThan(cfs.metric.coordinatorWriteLatency.getMeanRate(), 0);
}
@Test
public void testMaxSSTableSize() throws Exception
{
ColumnFamilyStore cfs = recreateTable();
assertEquals(0, cfs.metric.maxSSTableSize.getValue().longValue());
for (int i = 0; i < 1000; i++)
{
session.execute(String.format("INSERT INTO %s.%s (id, val1, val2) VALUES (%d, '%s', '%s')", KEYSPACE, TABLE, i, "val" + i, "val" + i));
}
StorageService.instance.forceKeyspaceFlush(KEYSPACE);
assertGreaterThan(cfs.metric.maxSSTableSize.getValue().doubleValue(), 0);
}
@Test
public void testMaxSSTableDuration() throws Exception
{
ColumnFamilyStore cfs = recreateTWCSTable();
assertEquals(0, cfs.metric.maxSSTableDuration.getValue().longValue());
session.execute(String.format("INSERT INTO %s.%s (id, val1, val2) VALUES (%d, '%s', '%s')", KEYSPACE, TWCS_TABLE, 1, "val1", "val1"));
Uninterruptibles.sleepUninterruptibly(10, TimeUnit.SECONDS);
session.execute(String.format("INSERT INTO %s.%s (id, val1, val2) VALUES (%d, '%s', '%s')", KEYSPACE, TWCS_TABLE, 2, "val2", "val2"));
StorageService.instance.forceKeyspaceFlush(KEYSPACE);
assertGreaterThan(cfs.metric.maxSSTableDuration.getValue().doubleValue(), 0);
}
@Test
public void testPreparedStatementsExecuted()
{