mirror of https://github.com/apache/cassandra
Enhance nodetool compactionstats with additional metrics
patch by Manish Ghildiyal; reviewed by Stefan Miklosovic, Brandon Williams for CASSANDRA-18305 Co-authored-by: Stefan Miklosovic <smiklosovic@apache.org>
This commit is contained in:
parent
ae537abc64
commit
7998e22127
|
|
@ -1,4 +1,5 @@
|
|||
5.0
|
||||
* Enhance nodetool compactionstats with additional metrics (CASSANDRA-18305)
|
||||
* Added support for type VECTOR<type, dimension> (CASSANDRA-18504)
|
||||
* Expose bootstrap and decommission state to nodetool info (CASSANDRA-18555)
|
||||
* Fix SSTabledump errors when dumping data from index (CASSANDRA-17698)
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ public class CompactionIterator extends CompactionInfo.Holder implements Unfilte
|
|||
private long totalSourceCQLRows;
|
||||
|
||||
// Keep targetDirectory for compactions, needed for `nodetool compactionstats`
|
||||
private String targetDirectory;
|
||||
private volatile String targetDirectory;
|
||||
|
||||
/*
|
||||
* counters for merged rows.
|
||||
|
|
|
|||
|
|
@ -1918,7 +1918,9 @@ public class NodeProbe implements AutoCloseable
|
|||
|
||||
/**
|
||||
* Retrieve Proxy metrics
|
||||
* @param metricName CompletedTasks, PendingTasks, BytesCompacted or TotalCompactionsCompleted.
|
||||
* @param metricName BytesCompacted, CompactionsAborted, CompactionsReduced,
|
||||
* SSTablesDroppedFromCompaction, CompletedTasks, PendingTasks, PendingTasksByTableName
|
||||
* or TotalCompactionsCompleted.
|
||||
*/
|
||||
public Object getCompactionMetric(String metricName)
|
||||
{
|
||||
|
|
@ -1927,6 +1929,9 @@ public class NodeProbe implements AutoCloseable
|
|||
switch(metricName)
|
||||
{
|
||||
case "BytesCompacted":
|
||||
case "CompactionsAborted":
|
||||
case "CompactionsReduced":
|
||||
case "SSTablesDroppedFromCompaction":
|
||||
return JMX.newMBeanProxy(mbeanServerConn,
|
||||
new ObjectName("org.apache.cassandra.metrics:type=Compaction,name=" + metricName),
|
||||
CassandraMetricsRegistry.JmxCounterMBean.class);
|
||||
|
|
@ -1941,7 +1946,7 @@ public class NodeProbe implements AutoCloseable
|
|||
new ObjectName("org.apache.cassandra.metrics:type=Compaction,name=" + metricName),
|
||||
CassandraMetricsRegistry.JmxMeterMBean.class);
|
||||
default:
|
||||
throw new RuntimeException("Unknown compaction metric.");
|
||||
throw new RuntimeException("Unknown compaction metric " + metricName);
|
||||
}
|
||||
}
|
||||
catch (MalformedObjectNameException e)
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package org.apache.cassandra.tools.nodetool;
|
|||
|
||||
import java.io.PrintStream;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
|
@ -28,8 +29,8 @@ import io.airlift.airline.Option;
|
|||
|
||||
import org.apache.cassandra.db.compaction.CompactionInfo;
|
||||
import org.apache.cassandra.db.compaction.CompactionInfo.Unit;
|
||||
import org.apache.cassandra.db.compaction.CompactionManagerMBean;
|
||||
import org.apache.cassandra.io.util.FileUtils;
|
||||
import org.apache.cassandra.metrics.CassandraMetricsRegistry;
|
||||
import org.apache.cassandra.tools.NodeProbe;
|
||||
import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
|
||||
import org.apache.cassandra.tools.nodetool.formatter.TableBuilder;
|
||||
|
|
@ -53,82 +54,119 @@ public class CompactionStats extends NodeToolCmd
|
|||
public void execute(NodeProbe probe)
|
||||
{
|
||||
PrintStream out = probe.output().out;
|
||||
CompactionManagerMBean cm = probe.getCompactionManagerProxy();
|
||||
TableBuilder tableBuilder = new TableBuilder();
|
||||
pendingTasksAndConcurrentCompactorsStats(probe, tableBuilder);
|
||||
compactionsStats(probe, tableBuilder);
|
||||
reportCompactionTable(probe.getCompactionManagerProxy().getCompactions(), probe.getCompactionThroughputBytes(), humanReadable, vtableOutput, out, tableBuilder);
|
||||
}
|
||||
|
||||
private void pendingTasksAndConcurrentCompactorsStats(NodeProbe probe, TableBuilder tableBuilder)
|
||||
{
|
||||
Map<String, Map<String, Integer>> pendingTaskNumberByTable =
|
||||
(Map<String, Map<String, Integer>>) probe.getCompactionMetric("PendingTasksByTableName");
|
||||
int numTotalPendingTask = 0;
|
||||
for (Entry<String, Map<String, Integer>> ksEntry : pendingTaskNumberByTable.entrySet())
|
||||
{
|
||||
for (Entry<String, Integer> tableEntry : ksEntry.getValue().entrySet())
|
||||
numTotalPendingTask += tableEntry.getValue();
|
||||
}
|
||||
out.println("pending tasks: " + numTotalPendingTask);
|
||||
for (Entry<String, Map<String, Integer>> ksEntry : pendingTaskNumberByTable.entrySet())
|
||||
{
|
||||
String ksName = ksEntry.getKey();
|
||||
for (Entry<String, Integer> tableEntry : ksEntry.getValue().entrySet())
|
||||
{
|
||||
String tableName = tableEntry.getKey();
|
||||
int pendingTaskCount = tableEntry.getValue();
|
||||
(Map<String, Map<String, Integer>>) probe.getCompactionMetric("PendingTasksByTableName");
|
||||
|
||||
out.println("- " + ksName + '.' + tableName + ": " + pendingTaskCount);
|
||||
}
|
||||
}
|
||||
out.println();
|
||||
reportCompactionTable(cm.getCompactions(), probe.getCompactionThroughputBytes(), humanReadable, vtableOutput, out);
|
||||
tableBuilder.add("concurrent compactors", Integer.toString(probe.getConcurrentCompactors()));
|
||||
tableBuilder.add("pending tasks", Integer.toString(numPendingTasks(pendingTaskNumberByTable)));
|
||||
|
||||
for (Entry<String, Map<String, Integer>> ksEntry : pendingTaskNumberByTable.entrySet())
|
||||
for (Entry<String, Integer> tableEntry : ksEntry.getValue().entrySet())
|
||||
tableBuilder.add(ksEntry.getKey(), tableEntry.getKey(), tableEntry.getValue().toString());
|
||||
}
|
||||
|
||||
public static void reportCompactionTable(List<Map<String,String>> compactions, long compactionThroughputInBytes, boolean humanReadable, PrintStream out)
|
||||
private int numPendingTasks(Map<String, Map<String, Integer>> pendingTaskNumberByTable)
|
||||
{
|
||||
reportCompactionTable(compactions, compactionThroughputInBytes, humanReadable, false, out);
|
||||
int numTotalPendingTasks = 0;
|
||||
for (Entry<String, Map<String, Integer>> ksEntry : pendingTaskNumberByTable.entrySet())
|
||||
for (Entry<String, Integer> tableEntry : ksEntry.getValue().entrySet())
|
||||
numTotalPendingTasks += tableEntry.getValue();
|
||||
|
||||
return numTotalPendingTasks;
|
||||
}
|
||||
|
||||
public static void reportCompactionTable(List<Map<String,String>> compactions, long compactionThroughputInBytes, boolean humanReadable, boolean vtableOutput, PrintStream out)
|
||||
private void compactionsStats(NodeProbe probe, TableBuilder tableBuilder)
|
||||
{
|
||||
if (!compactions.isEmpty())
|
||||
CassandraMetricsRegistry.JmxMeterMBean totalCompactionsCompletedMetrics =
|
||||
(CassandraMetricsRegistry.JmxMeterMBean) probe.getCompactionMetric("TotalCompactionsCompleted");
|
||||
tableBuilder.add("compactions completed", String.valueOf(totalCompactionsCompletedMetrics.getCount()));
|
||||
|
||||
CassandraMetricsRegistry.JmxCounterMBean bytesCompacted = (CassandraMetricsRegistry.JmxCounterMBean) probe.getCompactionMetric("BytesCompacted");
|
||||
if (humanReadable)
|
||||
tableBuilder.add("data compacted", FileUtils.stringifyFileSize(Double.parseDouble(Long.toString(bytesCompacted.getCount()))));
|
||||
else
|
||||
tableBuilder.add("data compacted", Long.toString(bytesCompacted.getCount()));
|
||||
|
||||
CassandraMetricsRegistry.JmxCounterMBean compactionsAborted = (CassandraMetricsRegistry.JmxCounterMBean) probe.getCompactionMetric("CompactionsAborted");
|
||||
tableBuilder.add("compactions aborted", Long.toString(compactionsAborted.getCount()));
|
||||
|
||||
CassandraMetricsRegistry.JmxCounterMBean compactionsReduced = (CassandraMetricsRegistry.JmxCounterMBean) probe.getCompactionMetric("CompactionsReduced");
|
||||
tableBuilder.add("compactions reduced", Long.toString(compactionsReduced.getCount()));
|
||||
|
||||
CassandraMetricsRegistry.JmxCounterMBean sstablesDroppedFromCompaction = (CassandraMetricsRegistry.JmxCounterMBean) probe.getCompactionMetric("SSTablesDroppedFromCompaction");
|
||||
tableBuilder.add("sstables dropped from compaction", Long.toString(sstablesDroppedFromCompaction.getCount()));
|
||||
|
||||
NumberFormat formatter = new DecimalFormat("0.00");
|
||||
|
||||
tableBuilder.add("15 minute rate", String.format("%s/minute", formatter.format(totalCompactionsCompletedMetrics.getFifteenMinuteRate() * 60)));
|
||||
tableBuilder.add("mean rate", String.format("%s/hour", formatter.format(totalCompactionsCompletedMetrics.getMeanRate() * 60 * 60)));
|
||||
|
||||
double configured = probe.getStorageService().getCompactionThroughtputMibPerSecAsDouble();
|
||||
tableBuilder.add("compaction throughput (MiB/s)", configured == 0 ? "throttling disabled (0)" : Double.toString(configured));
|
||||
}
|
||||
|
||||
public static void reportCompactionTable(List<Map<String,String>> compactions, long compactionThroughputInBytes, boolean humanReadable, PrintStream out, TableBuilder table)
|
||||
{
|
||||
reportCompactionTable(compactions, compactionThroughputInBytes, humanReadable, false, out, table);
|
||||
}
|
||||
|
||||
public static void reportCompactionTable(List<Map<String,String>> compactions, long compactionThroughputInBytes, boolean humanReadable, boolean vtableOutput, PrintStream out, TableBuilder table)
|
||||
{
|
||||
if (compactions.isEmpty())
|
||||
{
|
||||
long remainingBytes = 0;
|
||||
TableBuilder table = new TableBuilder();
|
||||
|
||||
if (vtableOutput)
|
||||
table.add("keyspace", "table", "task id", "completion ratio", "kind", "progress", "sstables", "total", "unit", "target directory");
|
||||
else
|
||||
table.add("id", "compaction type", "keyspace", "table", "completed", "total", "unit", "progress");
|
||||
|
||||
for (Map<String, String> c : compactions)
|
||||
{
|
||||
long total = Long.parseLong(c.get(CompactionInfo.TOTAL));
|
||||
long completed = Long.parseLong(c.get(CompactionInfo.COMPLETED));
|
||||
String taskType = c.get(CompactionInfo.TASK_TYPE);
|
||||
String keyspace = c.get(CompactionInfo.KEYSPACE);
|
||||
String columnFamily = c.get(CompactionInfo.COLUMNFAMILY);
|
||||
String unit = c.get(CompactionInfo.UNIT);
|
||||
boolean toFileSize = humanReadable && Unit.isFileSize(unit);
|
||||
String[] tables = c.get(CompactionInfo.SSTABLES).split(",");
|
||||
String progressStr = toFileSize ? FileUtils.stringifyFileSize(completed) : Long.toString(completed);
|
||||
String totalStr = toFileSize ? FileUtils.stringifyFileSize(total) : Long.toString(total);
|
||||
String percentComplete = total == 0 ? "n/a" : new DecimalFormat("0.00").format((double) completed / total * 100) + "%";
|
||||
String id = c.get(CompactionInfo.COMPACTION_ID);
|
||||
if (vtableOutput)
|
||||
{
|
||||
String targetDirectory = c.get(CompactionInfo.TARGET_DIRECTORY);
|
||||
table.add(keyspace, columnFamily, id, percentComplete, taskType, progressStr, String.valueOf(tables.length), totalStr, unit, targetDirectory);
|
||||
}
|
||||
else
|
||||
table.add(id, taskType, keyspace, columnFamily, progressStr, totalStr, unit, percentComplete);
|
||||
|
||||
remainingBytes += total - completed;
|
||||
}
|
||||
table.printTo(out);
|
||||
|
||||
String remainingTime = "n/a";
|
||||
if (compactionThroughputInBytes != 0)
|
||||
{
|
||||
long remainingTimeInSecs = remainingBytes / compactionThroughputInBytes;
|
||||
remainingTime = format("%dh%02dm%02ds", remainingTimeInSecs / 3600, (remainingTimeInSecs % 3600) / 60, (remainingTimeInSecs % 60));
|
||||
}
|
||||
out.printf("%25s%10s%n", "Active compaction remaining time : ", remainingTime);
|
||||
return;
|
||||
}
|
||||
|
||||
long remainingBytes = 0;
|
||||
|
||||
if (vtableOutput)
|
||||
table.add("keyspace", "table", "task id", "completion ratio", "kind", "progress", "sstables", "total", "unit", "target directory");
|
||||
else
|
||||
table.add("id", "compaction type", "keyspace", "table", "completed", "total", "unit", "progress");
|
||||
|
||||
for (Map<String, String> c : compactions)
|
||||
{
|
||||
long total = Long.parseLong(c.get(CompactionInfo.TOTAL));
|
||||
long completed = Long.parseLong(c.get(CompactionInfo.COMPLETED));
|
||||
String taskType = c.get(CompactionInfo.TASK_TYPE);
|
||||
String keyspace = c.get(CompactionInfo.KEYSPACE);
|
||||
String columnFamily = c.get(CompactionInfo.COLUMNFAMILY);
|
||||
String unit = c.get(CompactionInfo.UNIT);
|
||||
boolean toFileSize = humanReadable && Unit.isFileSize(unit);
|
||||
String[] tables = c.get(CompactionInfo.SSTABLES).split(",");
|
||||
String progressStr = toFileSize ? FileUtils.stringifyFileSize(completed) : Long.toString(completed);
|
||||
String totalStr = toFileSize ? FileUtils.stringifyFileSize(total) : Long.toString(total);
|
||||
String percentComplete = total == 0 ? "n/a" : new DecimalFormat("0.00").format((double) completed / total * 100) + '%';
|
||||
String id = c.get(CompactionInfo.COMPACTION_ID);
|
||||
if (vtableOutput)
|
||||
{
|
||||
String targetDirectory = c.get(CompactionInfo.TARGET_DIRECTORY);
|
||||
table.add(keyspace, columnFamily, id, percentComplete, taskType, progressStr, String.valueOf(tables.length), totalStr, unit, targetDirectory);
|
||||
}
|
||||
else
|
||||
table.add(id, taskType, keyspace, columnFamily, progressStr, totalStr, unit, percentComplete);
|
||||
|
||||
remainingBytes += total - completed;
|
||||
}
|
||||
|
||||
String remainingTime = "n/a";
|
||||
if (compactionThroughputInBytes != 0)
|
||||
{
|
||||
long remainingTimeInSecs = remainingBytes / compactionThroughputInBytes;
|
||||
remainingTime = format("%dh%02dm%02ds", remainingTimeInSecs / 3600, (remainingTimeInSecs % 3600) / 60, (remainingTimeInSecs % 60));
|
||||
}
|
||||
|
||||
table.add("active compaction remaining time", remainingTime);
|
||||
table.printTo(out);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -35,11 +35,10 @@ import org.apache.cassandra.io.sstable.format.SSTableReader;
|
|||
import org.apache.cassandra.schema.MockSchema;
|
||||
import org.apache.cassandra.tools.ToolRunner;
|
||||
import org.apache.cassandra.utils.TimeUUID;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.awaitility.Awaitility;
|
||||
|
||||
import static org.apache.cassandra.utils.TimeUUID.Generator.nextTimeUUID;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.awaitility.Awaitility.await;
|
||||
|
||||
public class CompactionStatsTest extends CQLTester
|
||||
{
|
||||
|
|
@ -58,42 +57,42 @@ public class CompactionStatsTest extends CQLTester
|
|||
ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("help", "compactionstats");
|
||||
tool.assertOnCleanExit();
|
||||
|
||||
String help = "NAME\n" +
|
||||
" nodetool compactionstats - Print statistics on compactions\n" +
|
||||
"\n" +
|
||||
"SYNOPSIS\n" +
|
||||
" nodetool [(-h <host> | --host <host>)] [(-p <port> | --port <port>)]\n" +
|
||||
" [(-pp | --print-port)] [(-pw <password> | --password <password>)]\n" +
|
||||
" [(-pwf <passwordFilePath> | --password-file <passwordFilePath>)]\n" +
|
||||
" [(-u <username> | --username <username>)] compactionstats\n" +
|
||||
" [(-H | --human-readable)] [(-V | --vtable)]\n" +
|
||||
"\n" +
|
||||
"OPTIONS\n" +
|
||||
" -h <host>, --host <host>\n" +
|
||||
" Node hostname or ip address\n" +
|
||||
"\n" +
|
||||
" -H, --human-readable\n" +
|
||||
" Display bytes in human readable form, i.e. KiB, MiB, GiB, TiB\n" +
|
||||
"\n" +
|
||||
" -p <port>, --port <port>\n" +
|
||||
" Remote jmx agent port number\n" +
|
||||
"\n" +
|
||||
" -pp, --print-port\n" +
|
||||
" Operate in 4.0 mode with hosts disambiguated by port number\n" +
|
||||
"\n" +
|
||||
" -pw <password>, --password <password>\n" +
|
||||
" Remote jmx agent password\n" +
|
||||
"\n" +
|
||||
" -pwf <passwordFilePath>, --password-file <passwordFilePath>\n" +
|
||||
" Path to the JMX password file\n" +
|
||||
"\n" +
|
||||
" -u <username>, --username <username>\n" +
|
||||
" Remote jmx agent username\n" +
|
||||
"\n" +
|
||||
" -V, --vtable\n" +
|
||||
" Display fields matching vtable output\n" +
|
||||
"\n" +
|
||||
"\n";
|
||||
String help = "NAME\n" +
|
||||
" nodetool compactionstats - Print statistics on compactions\n" +
|
||||
"\n" +
|
||||
"SYNOPSIS\n" +
|
||||
" nodetool [(-h <host> | --host <host>)] [(-p <port> | --port <port>)]\n" +
|
||||
" [(-pp | --print-port)] [(-pw <password> | --password <password>)]\n" +
|
||||
" [(-pwf <passwordFilePath> | --password-file <passwordFilePath>)]\n" +
|
||||
" [(-u <username> | --username <username>)] compactionstats\n" +
|
||||
" [(-H | --human-readable)] [(-V | --vtable)]\n" +
|
||||
"\n" +
|
||||
"OPTIONS\n" +
|
||||
" -h <host>, --host <host>\n" +
|
||||
" Node hostname or ip address\n" +
|
||||
"\n" +
|
||||
" -H, --human-readable\n" +
|
||||
" Display bytes in human readable form, i.e. KiB, MiB, GiB, TiB\n" +
|
||||
"\n" +
|
||||
" -p <port>, --port <port>\n" +
|
||||
" Remote jmx agent port number\n" +
|
||||
"\n" +
|
||||
" -pp, --print-port\n" +
|
||||
" Operate in 4.0 mode with hosts disambiguated by port number\n" +
|
||||
"\n" +
|
||||
" -pw <password>, --password <password>\n" +
|
||||
" Remote jmx agent password\n" +
|
||||
"\n" +
|
||||
" -pwf <passwordFilePath>, --password-file <passwordFilePath>\n" +
|
||||
" Path to the JMX password file\n" +
|
||||
"\n" +
|
||||
" -u <username>, --username <username>\n" +
|
||||
" Remote jmx agent username\n" +
|
||||
"\n" +
|
||||
" -V, --vtable\n" +
|
||||
" Display fields matching vtable output\n" +
|
||||
"\n" +
|
||||
"\n";
|
||||
assertThat(tool.getStdout()).isEqualTo(help);
|
||||
}
|
||||
|
||||
|
|
@ -124,11 +123,23 @@ public class CompactionStatsTest extends CQLTester
|
|||
|
||||
CompactionManager.instance.active.beginCompaction(compactionHolder);
|
||||
String stdout = waitForNumberOfPendingTasks(1, "compactionstats");
|
||||
Assertions.assertThat(stdout).containsPattern("id\\s+compaction type\\s+keyspace\\s+table\\s+completed\\s+total\\s+unit\\s+progress");
|
||||
assertThat(stdout).containsPattern("id\\s+compaction type\\s+keyspace\\s+table\\s+completed\\s+total\\s+unit\\s+progress");
|
||||
String expectedStatsPattern = String.format("%s\\s+%s\\s+%s\\s+%s\\s+%s\\s+%s\\s+%s\\s+%.2f%%",
|
||||
compactionId, OperationType.COMPACTION, CQLTester.KEYSPACE, currentTable(), bytesCompacted, bytesTotal,
|
||||
CompactionInfo.Unit.BYTES, (double) bytesCompacted / bytesTotal * 100);
|
||||
Assertions.assertThat(stdout).containsPattern(expectedStatsPattern);
|
||||
assertThat(stdout).containsPattern(expectedStatsPattern);
|
||||
|
||||
assertThat(stdout).containsPattern(expectedStatsPattern);
|
||||
assertThat(stdout).containsPattern("concurrent compactors\\s+[0-9]*");
|
||||
assertThat(stdout).containsPattern("pending tasks\\s+[0-9]*");
|
||||
assertThat(stdout).containsPattern("compactions completed\\s+[0-9]*");
|
||||
assertThat(stdout).containsPattern("data compacted\\s+[0-9]*");
|
||||
assertThat(stdout).containsPattern("compactions aborted\\s+[0-9]*");
|
||||
assertThat(stdout).containsPattern("compactions reduced\\s+[0-9]*");
|
||||
assertThat(stdout).containsPattern("sstables dropped from compaction\\s+[0-9]*");
|
||||
assertThat(stdout).containsPattern("15 minute rate\\s+[0-9]*.[0-9]*[0-9]*/minute");
|
||||
assertThat(stdout).containsPattern("mean rate\\s+[0-9]*.[0-9]*[0-9]*/hour");
|
||||
assertThat(stdout).containsPattern("compaction throughput \\(MiB/s\\)\\s+throttling disabled \\(0\\)");
|
||||
|
||||
CompactionManager.instance.active.finishCompaction(compactionHolder);
|
||||
waitForNumberOfPendingTasks(0, "compactionstats");
|
||||
|
|
@ -176,17 +187,17 @@ public class CompactionStatsTest extends CQLTester
|
|||
CompactionManager.instance.active.beginCompaction(compactionHolder);
|
||||
CompactionManager.instance.active.beginCompaction(nonCompactionHolder);
|
||||
String stdout = waitForNumberOfPendingTasks(2, "compactionstats", "-V");
|
||||
Assertions.assertThat(stdout).containsPattern("keyspace\\s+table\\s+task id\\s+completion ratio\\s+kind\\s+progress\\s+sstables\\s+total\\s+unit\\s+target directory");
|
||||
assertThat(stdout).containsPattern("keyspace\\s+table\\s+task id\\s+completion ratio\\s+kind\\s+progress\\s+sstables\\s+total\\s+unit\\s+target directory");
|
||||
String expectedStatsPattern = String.format("%s\\s+%s\\s+%s\\s+%.2f%%\\s+%s\\s+%s\\s+%s\\s+%s\\s+%s\\s+%s",
|
||||
CQLTester.KEYSPACE, currentTable(), compactionId, (double) bytesCompacted / bytesTotal * 100,
|
||||
OperationType.COMPACTION, bytesCompacted, sstables.size(), bytesTotal, CompactionInfo.Unit.BYTES,
|
||||
targetDirectory);
|
||||
Assertions.assertThat(stdout).containsPattern(expectedStatsPattern);
|
||||
assertThat(stdout).containsPattern(expectedStatsPattern);
|
||||
|
||||
String expectedStatsPatternForNonCompaction = String.format("%s\\s+%s\\s+%s\\s+%.2f%%\\s+%s\\s+%s\\s+%s\\s+%s\\s+%s",
|
||||
CQLTester.KEYSPACE, currentTable(), compactionId, (double) bytesCompacted / bytesTotal * 100,
|
||||
OperationType.COMPACTION, bytesCompacted, sstables.size(), bytesTotal, CompactionInfo.Unit.BYTES);
|
||||
Assertions.assertThat(stdout).containsPattern(expectedStatsPatternForNonCompaction);
|
||||
assertThat(stdout).containsPattern(expectedStatsPatternForNonCompaction);
|
||||
|
||||
CompactionManager.instance.active.finishCompaction(compactionHolder);
|
||||
CompactionManager.instance.active.finishCompaction(nonCompactionHolder);
|
||||
|
|
@ -220,11 +231,11 @@ public class CompactionStatsTest extends CQLTester
|
|||
|
||||
CompactionManager.instance.active.beginCompaction(compactionHolder);
|
||||
String stdout = waitForNumberOfPendingTasks(1, "compactionstats", "--human-readable");
|
||||
Assertions.assertThat(stdout).containsPattern("id\\s+compaction type\\s+keyspace\\s+table\\s+completed\\s+total\\s+unit\\s+progress");
|
||||
assertThat(stdout).containsPattern("id\\s+compaction type\\s+keyspace\\s+table\\s+completed\\s+total\\s+unit\\s+progress");
|
||||
String expectedStatsPattern = String.format("%s\\s+%s\\s+%s\\s+%s\\s+%s\\s+%s\\s+%s\\s+%.2f%%",
|
||||
compactionId, OperationType.COMPACTION, CQLTester.KEYSPACE, currentTable(), "123 bytes", "120.56 KiB",
|
||||
CompactionInfo.Unit.BYTES, (double) bytesCompacted / bytesTotal * 100);
|
||||
Assertions.assertThat(stdout).containsPattern(expectedStatsPattern);
|
||||
assertThat(stdout).containsPattern(expectedStatsPattern);
|
||||
|
||||
CompactionManager.instance.active.finishCompaction(compactionHolder);
|
||||
waitForNumberOfPendingTasks(0, "compactionstats", "--human-readable");
|
||||
|
|
@ -272,16 +283,16 @@ public class CompactionStatsTest extends CQLTester
|
|||
CompactionManager.instance.active.beginCompaction(compactionHolder);
|
||||
CompactionManager.instance.active.beginCompaction(nonCompactionHolder);
|
||||
String stdout = waitForNumberOfPendingTasks(2, "compactionstats", "--vtable", "--human-readable");
|
||||
Assertions.assertThat(stdout).containsPattern("keyspace\\s+table\\s+task id\\s+completion ratio\\s+kind\\s+progress\\s+sstables\\s+total\\s+unit\\s+target directory");
|
||||
assertThat(stdout).containsPattern("keyspace\\s+table\\s+task id\\s+completion ratio\\s+kind\\s+progress\\s+sstables\\s+total\\s+unit\\s+target directory");
|
||||
String expectedStatsPattern = String.format("%s\\s+%s\\s+%s\\s+%.2f%%\\s+%s\\s+%s\\s+%s\\s+%s\\s+%s\\s+%s",
|
||||
CQLTester.KEYSPACE, currentTable(), compactionId, (double) bytesCompacted / bytesTotal * 100,
|
||||
OperationType.COMPACTION, "123 bytes", sstables.size(), "120.56 KiB", CompactionInfo.Unit.BYTES,
|
||||
targetDirectory);
|
||||
Assertions.assertThat(stdout).containsPattern(expectedStatsPattern);
|
||||
assertThat(stdout).containsPattern(expectedStatsPattern);
|
||||
String expectedStatsPatternForNonCompaction = String.format("%s\\s+%s\\s+%s\\s+%.2f%%\\s+%s\\s+%s\\s+%s\\s+%s\\s+%s",
|
||||
CQLTester.KEYSPACE, currentTable(), compactionId, (double) bytesCompacted / bytesTotal * 100,
|
||||
OperationType.CLEANUP, "123 bytes", sstables.size(), "120.56 KiB", CompactionInfo.Unit.BYTES);
|
||||
Assertions.assertThat(stdout).containsPattern(expectedStatsPatternForNonCompaction);
|
||||
assertThat(stdout).containsPattern(expectedStatsPatternForNonCompaction);
|
||||
|
||||
CompactionManager.instance.active.finishCompaction(compactionHolder);
|
||||
CompactionManager.instance.active.finishCompaction(nonCompactionHolder);
|
||||
|
|
@ -291,12 +302,21 @@ public class CompactionStatsTest extends CQLTester
|
|||
private String waitForNumberOfPendingTasks(int pendingTasksToWaitFor, String... args)
|
||||
{
|
||||
AtomicReference<String> stdout = new AtomicReference<>();
|
||||
Awaitility.await().until(() -> {
|
||||
await().until(() -> {
|
||||
ToolRunner.ToolResult tool = ToolRunner.invokeNodetool(args);
|
||||
tool.assertOnCleanExit();
|
||||
String output = tool.getStdout();
|
||||
stdout.set(output);
|
||||
return output.contains("pending tasks: " + pendingTasksToWaitFor);
|
||||
|
||||
try
|
||||
{
|
||||
assertThat(output).containsPattern("pending tasks\\s+" + pendingTasksToWaitFor);
|
||||
return true;
|
||||
}
|
||||
catch (AssertionError e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
return stdout.get();
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ import org.apache.cassandra.stress.generate.SeedManager;
|
|||
import org.apache.cassandra.stress.operations.userdefined.SchemaInsert;
|
||||
import org.apache.cassandra.stress.settings.StressSettings;
|
||||
import org.apache.cassandra.tools.nodetool.CompactionStats;
|
||||
import org.apache.cassandra.tools.nodetool.formatter.TableBuilder;
|
||||
import org.apache.cassandra.utils.FBUtilities;
|
||||
import org.apache.cassandra.utils.JVMStabilityInspector;
|
||||
import org.apache.cassandra.utils.concurrent.Future;
|
||||
|
|
@ -274,7 +275,7 @@ public abstract class CompactionStress implements Runnable
|
|||
{
|
||||
System.out.println("========");
|
||||
System.out.println(String.format("Pending compactions: %d\n", CompactionManager.instance.getPendingTasks()));
|
||||
CompactionStats.reportCompactionTable(CompactionManager.instance.getCompactions(), 0, true, System.out);
|
||||
CompactionStats.reportCompactionTable(CompactionManager.instance.getCompactions(), 0, true, System.out, new TableBuilder());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue