This is an automated email from the ASF dual-hosted git repository.

maedhroz pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra.git

commit cc86fc8865e2794a83078db5629ba5096498045e
Merge: a397a53891 79630fb42a
Author: Caleb Rackliffe <[email protected]>
AuthorDate: Fri Jan 17 12:30:30 2025 -0600

    Merge branch 'cassandra-5.0' into trunk
    
    * cassandra-5.0:
      Add selected SAI index state and query performance metrics to nodetool 
tablestats

 CHANGES.txt                                        |  1 +
 .../index/sai/metrics/IndexGroupMetrics.java       |  3 +-
 .../index/sai/metrics/TableQueryMetrics.java       |  4 +-
 src/java/org/apache/cassandra/tools/NodeProbe.java | 73 +++++++++++++++-
 .../cassandra/tools/nodetool/TableStats.java       |  6 +-
 .../cassandra/tools/nodetool/stats/StatsTable.java | 10 +++
 .../tools/nodetool/stats/StatsTableComparator.java | 46 ++++++++++-
 .../tools/nodetool/stats/TableStatsHolder.java     | 58 +++++++++++++
 .../tools/nodetool/stats/TableStatsPrinter.java    | 14 ++++
 .../cassandra/tools/nodetool/TableStatsTest.java   |  6 +-
 .../nodetool/stats/TableStatsPrinterTest.java      | 96 ++++++++++++++--------
 .../tools/nodetool/stats/TableStatsTestBase.java   | 24 ++++++
 12 files changed, 302 insertions(+), 39 deletions(-)

diff --cc CHANGES.txt
index 0b12096ef1,85c50621d1..517b7b6958
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,126 -1,5 +1,127 @@@
 -5.0.3
 +5.1
 + * Make JsonUtils serialize Instant always with the same format 
(CASSANDRA-20209)
 + * Port Harry v2 to trunk (CASSANDRA-20200)
 + * Enable filtering of snapshots on keyspace, table and snapshot name in 
nodetool listsnapshots (CASSANDRA-20151)
 + * Create manifest upon loading where it does not exist or enrich it 
(CASSANDRA-20150)
 + * Propagate true size of snapshot in SnapshotDetailsTabularData to not call 
JMX twice in nodetool listsnapshots (CASSANDRA-20149)
 + * Implementation of CEP-43 - copying a table via CQL by CREATE TABLE LIKE 
(CASSANDRA-19964)
 + * Periodically disconnect roles that are revoked or have LOGIN=FALSE set 
(CASSANDRA-19385)
 + * AST library for CQL-based fuzz tests (CASSANDRA-20198)
 + * Support audit logging for JMX operations (CASSANDRA-20128)
 + * Enable sorting of nodetool status output (CASSANDRA-20104)
 + * Support downgrading after CMS is initialized (CASSANDRA-20145)
 + * Deprecate IEndpointSnitch (CASSANDRA-19488)
 + * Check presence of a snapshot in a case-insensitive manner on macOS 
platform to prevent hardlinking failures (CASSANDRA-20146)
 + * Enable JMX server configuration to be in cassandra.yaml (CASSANDRA-11695)
 + * Parallelized UCS compactions (CASSANDRA-18802)
 + * Avoid prepared statement invalidation race when committing schema changes 
(CASSANDRA-20116)
 + * Restore optimization in MultiCBuilder around building one clustering 
(CASSANDRA-20129)
 + * Consolidate all snapshot management to SnapshotManager and introduce 
SnapshotManagerMBean (CASSANDRA-18111)
 + * Fix RequestFailureReason constants codes (CASSANDRA-20126)
 + * Introduce SSTableSimpleScanner for compaction (CASSANDRA-20092)
 + * Include column drop timestamp in alter table transformation 
(CASSANDRA-18961)
 + * Make JMX SSL configurable in cassandra.yaml (CASSANDRA-18508)
 + * Fix cqlsh CAPTURE command to save query results without trace details when 
TRACING is ON (CASSANDRA-19105)
 + * Optionally prevent tombstone purging during repair (CASSANDRA-20071)
 + * Add post-filtering support for the IN operator in SAI queries 
(CASSANDRA-20025)
 + * Don’t finish ongoing decommission and move operations during startup 
(CASSANDRA-20040)
 + * Nodetool reconfigure cms has correct return code when streaming fails 
(CASSANDRA-19972)
 + * Reintroduce RestrictionSet#iterator() optimization around multi-column 
restrictions (CASSANDRA-20034)
 + * Explicitly localize strings to Locale.US for internal implementation 
(CASSANDRA-19953)
 + * Add -H option for human-friendly output in nodetool compactionhistory 
(CASSANDRA-20015)
 + * Fix type check for referenced duration type for nested types 
(CASSANDRA-19890)
 + * In simulation tests, correctly set the tokens of replacement nodes 
(CASSANDRA-19997)
 + * During TCM upgrade, retain all properties of existing system tables 
(CASSANDRA-19992)
 + * Properly cancel in-flight futures and reject requests in 
EpochAwareDebounce during shutdown (CASSANDRA-19848)
 + * Provide clearer exception message on failing commitlog_disk_access_mode 
combinations (CASSANDRA-19812)
 + * Add total space used for a keyspace to nodetool tablestats 
(CASSANDRA-19671)
 + * Ensure Relation#toRestriction() handles ReversedType properly 
(CASSANDRA-19950)
 + * Add JSON and YAML output option to nodetool gcstats (CASSANDRA-19771)
 + * Introduce metadata serialization version V4 (CASSANDRA-19970)
 + * Allow CMS reconfiguration to work around DOWN nodes (CASSANDRA-19943)
 + * Make TableParams.Serializer set allowAutoSnapshots and incrementalBackups 
(CASSANDRA-19954)
 + * Make sstabledump possible to show tombstones only (CASSANDRA-19939)
 + * Ensure that RFP queries potentially stale replicas even with only key 
columns in the row filter (CASSANDRA-19938)
 + * Allow nodes to change IP address while upgrading to TCM (CASSANDRA-19921)
 + * Retain existing keyspace params on system tables after upgrade 
(CASSANDRA-19916)
 + * Deprecate use of gossip state for paxos electorate verification 
(CASSANDRA-19904)
 + * Update dtest-api to 0.0.17 to fix jvm17 crash in jvm-dtests 
(CASSANDRA-19239)
 + * Add resource leak test and Update Netty to 4.1.113.Final to fix leak 
(CASSANDRA-19783)
 + * Fix incorrect nodetool suggestion when gossip mode is running 
(CASSANDRA-19905)
 + * SAI support for BETWEEN operator (CASSANDRA-19688)
 + * Fix BETWEEN filtering for reversed clustering columns (CASSANDRA-19878)
 + * Retry if node leaves CMS while committing a transformation 
(CASSANDRA-19872)
 + * Add support for NOT operators in WHERE clauses. Fixed Three Valued Logic 
(CASSANDRA-18584)
 + * Allow getendpoints for system tables and make sure getNaturalReplicas work 
for MetaStrategy (CASSANDRA-19846)
 + * On upgrade, handle pre-existing tables with unexpected table ids 
(CASSANDRA-19845)
 + * Reconfigure CMS before assassinate (CASSANDRA-19768)
 + * Warn about unqualified prepared statement only if it is select or 
modification statement (CASSANDRA-18322)
 + * Update legacy peers tables during node replacement (CASSANDRA-19782)
 + * Refactor ColumnCondition (CASSANDRA-19620)
 + * Allow configuring log format for Audit Logs (CASSANDRA-19792)
 + * Support for noboolean rpm (centos7 compatible) packages removed 
(CASSANDRA-19787)
 + * Allow threads waiting for the metadata log follower to be interrupted 
(CASSANDRA-19761)
 + * Support dictionary lookup for CassandraPasswordValidator (CASSANDRA-19762)
 + * Disallow denylisting keys in system_cluster_metadata (CASSANDRA-19713)
 + * Fix gossip status after replacement (CASSANDRA-19712)
 + * Ignore repair requests for system_cluster_metadata (CASSANDRA-19711)
 + * Avoid ClassCastException when verifying tables with reversed partitioner 
(CASSANDRA-19710)
 + * Always repair the full range when repairing system_cluster_metadata 
(CASSANDRA-19709)
 + * Use table-specific partitioners during Paxos repair (CASSANDRA-19714)
 + * Expose current compaction throughput in nodetool (CASSANDRA-13890)
 + * CEP-24 Password validation / generation (CASSANDRA-17457)
 + * Reconfigure CMS after replacement, bootstrap and move operations 
(CASSANDRA-19705)
 + * Support querying LocalStrategy tables with any partitioner 
(CASSANDRA-19692)
 + * Relax slow_query_log_timeout for MultiNodeSAITest (CASSANDRA-19693)
 + * Audit Log entries are missing identity for mTLS connections 
(CASSANDRA-19669)
 + * Add support for the BETWEEN operator in WHERE clauses (CASSANDRA-19604)
 + * Replace Stream iteration with for-loop for 
SimpleRestriction::bindAndGetClusteringElements (CASSANDRA-19679)
 + * Consolidate logging on trace level (CASSANDRA-19632)
 + * Expand DDL statements on coordinator before submission to the CMS 
(CASSANDRA-19592)
 + * Fix number of arguments of String.format() in various classes 
(CASSANDRA-19645)
 + * Remove unused fields from config (CASSANDRA-19599)
 + * Refactor Relation and Restriction hierarchies (CASSANDRA-19341)
 + * Raise priority of TCM internode messages during critical operations 
(CASSANDRA-19517)
 + * Add nodetool command to unregister LEFT nodes (CASSANDRA-19581)
 + * Add cluster metadata id to gossip syn messages (CASSANDRA-19613)
 + * Reduce heap usage occupied by the metrics (CASSANDRA-19567)
 + * Improve handling of transient replicas during range movements 
(CASSANDRA-19344)
 + * Enable debounced internode log requests to be cancelled at shutdown 
(CASSANDRA-19514)
 + * Correctly set last modified epoch when combining multistep operations into 
a single step (CASSANDRA-19538)
 + * Add new TriggersPolicy configuration to allow operators to disable 
triggers (CASSANDRA-19532)
 + * Use Transformation.Kind.id in local and distributed log tables 
(CASSANDRA-19516)
 + * Remove period field from ClusterMetadata and metadata log tables 
(CASSANDRA-19482)
 + * Enrich system_views.pending_hints vtable with hints sizes (CASSANDRA-19486)
 + * Expose all dropwizard metrics in virtual tables (CASSANDRA-14572)
 + * Ensured that PropertyFileSnitchTest do not overwrite 
cassandra-toploogy.properties (CASSANDRA-19502)
 + * Add option for MutualTlsAuthenticator to restrict the certificate validity 
period (CASSANDRA-18951)
 + * Fix StorageService::constructRangeToEndpointMap for non-distributed 
keyspaces (CASSANDRA-19255)
 + * Group nodetool cms commands into single command group (CASSANDRA-19393)
 + * Register the measurements of the bootstrap process as Dropwizard metrics 
(CASSANDRA-19447)
 + * Add LIST SUPERUSERS CQL statement (CASSANDRA-19417)
 + * Modernize CQLSH datetime conversions (CASSANDRA-18879)
 + * Harry model and in-JVM tests for partition-restricted 2i queries 
(CASSANDRA-18275)
 + * Refactor cqlshmain global constants (CASSANDRA-19201)
 + * Remove native_transport_port_ssl (CASSANDRA-19397)
 + * Make nodetool reconfigurecms sync by default and add --cancel to be able 
to cancel ongoing reconfigurations (CASSANDRA-19216)
 + * Expose auth mode in system_views.clients, nodetool clientstats, metrics 
(CASSANDRA-19366)
 + * Remove sealed_periods and last_sealed_period tables (CASSANDRA-19189)
 + * Improve setup and initialisation of LocalLog/LogSpec (CASSANDRA-19271)
 + * Refactor structure of caching metrics and expose auth cache metrics via 
JMX (CASSANDRA-17062)
 + * Allow CQL client certificate authentication to work without sending an 
AUTHENTICATE request (CASSANDRA-18857)
 + * Extend nodetool tpstats and system_views.thread_pools with detailed pool 
parameters (CASSANDRA-19289)
 + * Remove dependency on Sigar in favor of OSHI (CASSANDRA-16565)
 + * Simplify the bind marker and Term logic (CASSANDRA-18813)
 + * Limit cassandra startup to supported JDKs, allow higher JDKs by setting 
CASSANDRA_JDK_UNSUPPORTED (CASSANDRA-18688)
 + * Standardize nodetool tablestats formatting of data units (CASSANDRA-19104)
 + * Make nodetool tablestats use number of significant digits for time and 
average values consistently (CASSANDRA-19015)
 + * Upgrade jackson to 2.15.3 and snakeyaml to 2.1 (CASSANDRA-18875)
 + * Transactional Cluster Metadata [CEP-21] (CASSANDRA-18330)
 + * Add ELAPSED command to cqlsh (CASSANDRA-18861)
 + * Add the ability to disable bulk loading of SSTables (CASSANDRA-18781)
 + * Clean up obsolete functions and simplify cql_version handling in cqlsh 
(CASSANDRA-18787)
 +Merged from 5.0:
+  * Add selected SAI index state and query performance metrics to nodetool 
tablestats (CASSANDRA-20026)
   * Remove v30 and v3X from 5.x in-JVM upgrade tests (CASSANDRA-20103)
   * Avoid memory allocation in offheap_object's NativeCell.valueSize() and 
NativeClustering.dataSize() (CASSANDRA-20162)
   * Add flag to avoid invalidating key cache on sstable deletions 
(CASSANDRA-20068)
diff --cc src/java/org/apache/cassandra/tools/NodeProbe.java
index d0ba27ad51,a917793ecc..f7ac9eff3b
--- a/src/java/org/apache/cassandra/tools/NodeProbe.java
+++ b/src/java/org/apache/cassandra/tools/NodeProbe.java
@@@ -90,9 -90,11 +90,12 @@@ import org.apache.cassandra.gms.Gossipe
  import org.apache.cassandra.gms.GossiperMBean;
  import org.apache.cassandra.hints.HintsService;
  import org.apache.cassandra.hints.HintsServiceMBean;
+ import org.apache.cassandra.index.sai.metrics.IndexGroupMetrics;
+ import org.apache.cassandra.index.sai.metrics.TableQueryMetrics;
+ import org.apache.cassandra.index.sai.metrics.TableStateMetrics;
  import org.apache.cassandra.locator.DynamicEndpointSnitchMBean;
  import org.apache.cassandra.locator.EndpointSnitchInfoMBean;
 +import org.apache.cassandra.locator.LocationInfoMBean;
  import org.apache.cassandra.metrics.CIDRAuthorizerMetrics;
  import org.apache.cassandra.metrics.CassandraMetricsRegistry;
  import org.apache.cassandra.metrics.StorageMetrics;
@@@ -1922,7 -1870,75 +1925,75 @@@ public class NodeProbe implements AutoC
        }
      }
  
-     /**
+     public Object getSaiMetric(String ks, String cf, String metricName)
+     {
+         try
+         {
+             String scope = getSaiMetricScope(metricName);
+             String objectNameStr = 
String.format("org.apache.cassandra.metrics:type=StorageAttachedIndex,keyspace=%s,table=%s,scope=%s,name=%s",ks,
 cf, scope, metricName);
+             ObjectName oName = new ObjectName(objectNameStr);
+ 
+             Set<ObjectName> matchingMBeans = 
mbeanServerConn.queryNames(oName, null);
+             if (matchingMBeans.isEmpty())
+                 return null;
+ 
+             return getSaiMetricValue(metricName, oName);
+         }
+         catch (MalformedObjectNameException e)
+         {
+             throw new RuntimeException("Invalid ObjectName format: " + 
e.getMessage(), e);
+         }
+         catch (IOException e)
+         {
+             throw new RuntimeException("Error accessing MBean server: " + 
e.getMessage(), e);
+         }
+     }
+ 
+     private Object getSaiMetricValue(String metricName, ObjectName oName) 
throws IOException
+     {
+         switch (metricName)
+         {
+             case "QueryLatency":
+                 return JMX.newMBeanProxy(mbeanServerConn, oName, 
CassandraMetricsRegistry.JmxTimerMBean.class);
+             case "PostFilteringReadLatency":
+             case "SSTableIndexesHit":
+             case "IndexSegmentsHit":
+             case "RowsFiltered":
+                 return JMX.newMBeanProxy(mbeanServerConn, oName, 
CassandraMetricsRegistry.JmxHistogramMBean.class);
+             case "DiskUsedBytes":
+             case "TotalIndexCount":
+             case "TotalQueryableIndexCount":
+                 return JMX.newMBeanProxy(mbeanServerConn, oName, 
CassandraMetricsRegistry.JmxGaugeMBean.class).getValue();
+             case "TotalQueryTimeouts":
+                 return JMX.newMBeanProxy(mbeanServerConn, oName, 
CassandraMetricsRegistry.JmxCounterMBean.class).getCount();
+             default:
+                 throw new IllegalArgumentException("Unknown metric name: " + 
metricName);
+         }
+     }
+ 
+     private String getSaiMetricScope(String metricName)
+     {
+         switch (metricName)
+         {
+             case "QueryLatency":
+             case "SSTableIndexesHit":
+             case "IndexSegmentsHit":
+             case "RowsFiltered":
+                 return 
TableQueryMetrics.PerQueryMetrics.PER_QUERY_METRICS_TYPE;
+             case "PostFilteringReadLatency":
+             case "TotalQueryTimeouts":
+                 return TableQueryMetrics.TABLE_QUERY_METRIC_TYPE;
+             case "DiskUsedBytes":
+                 return IndexGroupMetrics.INDEX_GROUP_METRICS_TYPE;
+             case "TotalIndexCount":
+             case "TotalQueryableIndexCount":
+                 return TableStateMetrics.TABLE_STATE_METRIC_TYPE;
+             default:
+                 throw new IllegalArgumentException("Unknown metric name: " + 
metricName);
+         }
+     }
+ 
 -    /**
++        /**
       * Retrieve threadpool paths and names for threadpools with metrics.
       * @return Multimap from path (internal, request, etc.) to name
       */
diff --cc src/java/org/apache/cassandra/tools/nodetool/TableStats.java
index fc641e7891,a347fd5f7d..0faaa32aa0
--- a/src/java/org/apache/cassandra/tools/nodetool/TableStats.java
+++ b/src/java/org/apache/cassandra/tools/nodetool/TableStats.java
@@@ -60,8 -60,10 +60,10 @@@ public class TableStats extends NodeToo
                          + "memtable_off_heap_memory_used, 
memtable_switch_count, number_of_partitions_estimate, "
                          + "off_heap_memory_used_total, pending_flushes, 
percent_repaired, read_latency, reads, "
                          + "space_used_by_snapshots_total, space_used_live, 
space_used_total, "
-                         + "sstable_compression_ratio, sstable_count, 
table_name, write_latency, writes, " +
-                           "max_sstable_size, local_read_write_ratio, 
twcs_max_duration)")
+                         + "sstable_compression_ratio, sstable_count, 
table_name, write_latency, writes, "
 -                        + "max_sstable_size, local_read_write_ratio, 
twcs_max_duration, sai_local_query_latency_ms,"
++                        + "max_sstable_size, local_read_write_ratio, 
twcs_max_duration, sai_local_query_latency_ms, "
+                         + "sai_post_filtering_read_latency, 
sai_disk_used_bytes, sai_sstable_indexes_hit, sai_index_segments_hit "
+                         + "sai_rows_filtered, sai_total_query_timeouts, 
sai_total_queryable_index_ratio)")
      private String sortKey = "";
  
      @Option(title = "top",
diff --cc 
src/java/org/apache/cassandra/tools/nodetool/stats/TableStatsHolder.java
index 338151a0d8,a225ccb88c..a2005f4b32
--- a/src/java/org/apache/cassandra/tools/nodetool/stats/TableStatsHolder.java
+++ b/src/java/org/apache/cassandra/tools/nodetool/stats/TableStatsHolder.java
@@@ -393,6 -396,44 +404,43 @@@ public class TableStatsHolder implement
                  if (table.getTopTombstonePartitionsLastUpdate() != null)
                      statsTable.topTombstonePartitionsLastUpdate = 
millisToDateString(table.getTopTombstonePartitionsLastUpdate());
  
+                 if (!SchemaConstants.isSystemKeyspace(keyspaceName))
+                 {
+                     Object totalIndexCount = probe.getSaiMetric(keyspaceName, 
tableName, "TotalIndexCount");
+                     statsTable.saiTotalIndexCount = (totalIndexCount != null) 
? (int) totalIndexCount : 0;
+ 
+                     if (statsTable.saiTotalIndexCount > 0)
+                     {
+                         Object queryLatencyMetric = 
probe.getSaiMetric(keyspaceName, tableName, "QueryLatency");
+                         double queryLatency = 
getMetricMean(queryLatencyMetric);
+                         statsTable.saiQueryLatencyMs = queryLatency > 0 ? 
queryLatency : Double.NaN;
+ 
+                         Object PostFilteringReadLatency = 
probe.getSaiMetric(keyspaceName, tableName, "PostFilteringReadLatency");
+                         double postfilteringreadlatency = 
getMetricMean(PostFilteringReadLatency);
+                         statsTable.saiPostFilteringReadLatencyMs = 
postfilteringreadlatency > 0 ? postfilteringreadlatency : Double.NaN;
+ 
+                         Object diskUsedBytes = 
probe.getSaiMetric(keyspaceName, tableName, "DiskUsedBytes");
+                         long saidiskusedbytes = (diskUsedBytes != null) ? 
(long) diskUsedBytes : 0L;
 -                        statsTable.saiDiskUsedBytes = 
format(saidiskusedbytes, humanReadable);
++                        statsTable.saiDiskUsedBytes = 
FileUtils.stringifyFileSize(saidiskusedbytes, humanReadable);
+ 
+                         Object SSTableIndexesHit = 
probe.getSaiMetric(keyspaceName, tableName, "SSTableIndexesHit");
+                         statsTable.saiSSTableIndexesHit = 
getMetricMean(SSTableIndexesHit);
+ 
+                         Object IndexSegmentsHit = 
probe.getSaiMetric(keyspaceName, tableName, "IndexSegmentsHit");
+                         statsTable.saiIndexSegmentsHit = 
getMetricMean(IndexSegmentsHit);
+ 
+                         Object RowsFiltered = 
probe.getSaiMetric(keyspaceName, tableName, "RowsFiltered");
+                         statsTable.saiRowsFiltered = 
getMetricMean(RowsFiltered);
+ 
+                         Object totalQueryTimeouts = 
probe.getSaiMetric(keyspaceName, tableName, "TotalQueryTimeouts");
+                         statsTable.saiTotalQueryTimeouts = 
(totalQueryTimeouts != null) ? (Long) totalQueryTimeouts : 0L;
+ 
+                         Object totalQueryableIndexCount = 
probe.getSaiMetric(keyspaceName, tableName, "TotalQueryableIndexCount");
+                         int saiTotalQueryableIndexCount = 
(totalQueryableIndexCount != null) ? (int) totalQueryableIndexCount : 0;
+ 
+                         statsTable.saiTotalQueryableIndexRatio = 
String.format("%d/%d", saiTotalQueryableIndexCount, 
statsTable.saiTotalIndexCount);
+                     }
+                 }
 -
                  statsKeyspace.tables.add(statsTable);
              }
              keyspaces.add(statsKeyspace);
diff --cc 
src/java/org/apache/cassandra/tools/nodetool/stats/TableStatsPrinter.java
index bd979039cb,eb272d38dc..187ca05b8e
--- a/src/java/org/apache/cassandra/tools/nodetool/stats/TableStatsPrinter.java
+++ b/src/java/org/apache/cassandra/tools/nodetool/stats/TableStatsPrinter.java
@@@ -22,7 -22,7 +22,8 @@@ import java.io.PrintStream
  import java.util.List;
  import java.util.Map;
  
 +import org.apache.cassandra.io.util.FileUtils;
+ import org.apache.cassandra.schema.SchemaConstants;
  import org.apache.cassandra.utils.FBUtilities;
  
  public class TableStatsPrinter<T extends StatsHolder>
@@@ -168,13 -164,21 +169,26 @@@
                  for (Map.Entry<String, Long> tombstonecnt : 
table.topTombstonePartitions.entrySet())
                      out.printf(indent + "  %-" + maxWidth + "s %s%n", 
tombstonecnt.getKey(), tombstonecnt.getValue());
              }
+ 
+             if (!SchemaConstants.isSystemKeyspace(table.keyspaceName) && 
table.saiTotalIndexCount > 0)
+             {
 -                out.println(indent + "SAI local query latency (mean): " + 
String.format("%.3f ms", table.saiQueryLatencyMs));
 -                out.println(indent + "SAI post-filtering latency (mean): " + 
String.format("%.3f ms",table.saiPostFilteringReadLatencyMs));
++                out.println(indent + "SAI local query latency (mean): " + 
FBUtilities.prettyPrintLatency(table.saiQueryLatencyMs));
++                out.println(indent + "SAI post-filtering latency (mean): " + 
FBUtilities.prettyPrintLatency(table.saiPostFilteringReadLatencyMs));
+                 out.println(indent + "SAI space used (bytes): " + 
table.saiDiskUsedBytes);
+                 out.println(indent + "SAI sstable indexes hit per query 
(mean): " + table.saiSSTableIndexesHit);
+                 out.println(indent + "SAI index segments hit per query 
(mean): " + table.saiIndexSegmentsHit);
+                 out.println(indent + "SAI rows filtered per query (mean): " + 
table.saiRowsFiltered);
+                 out.println(indent + "SAI local query timeouts: " + 
table.saiTotalQueryTimeouts);
+                 out.println(indent + "SAI queryable/total indexes: " + 
table.saiTotalQueryableIndexRatio);
+             }
+ 
              out.println("");
          }
 +
 +        private String formatDataSize(long bytes, boolean humanReadable)
 +        {
 +            return humanReadable ? FileUtils.stringifyFileSize(bytes) : 
Long.toString(bytes);
 +        }
      }
  
      /**
diff --cc test/unit/org/apache/cassandra/tools/nodetool/TableStatsTest.java
index 11e5e1f569,bfd7b8bee4..c4487d64e4
--- a/test/unit/org/apache/cassandra/tools/nodetool/TableStatsTest.java
+++ b/test/unit/org/apache/cassandra/tools/nodetool/TableStatsTest.java
@@@ -112,7 -112,11 +112,11 @@@ public class TableStatsTest extends CQL
                          "            read_latency, reads, 
space_used_by_snapshots_total, space_used_live,\n" + 
                          "            space_used_total, 
sstable_compression_ratio, sstable_count,\n" + 
                          "            table_name, write_latency, writes, 
max_sstable_size,\n" +
-                         "            local_read_write_ratio, 
twcs_max_duration)\n" +
+                         "            local_read_write_ratio, 
twcs_max_duration,\n" +
 -                        "            
sai_local_query_latency_ms,sai_post_filtering_read_latency,\n" +
++                        "            sai_local_query_latency_ms, 
sai_post_filtering_read_latency,\n" +
+                         "            sai_disk_used_bytes, 
sai_sstable_indexes_hit, sai_index_segments_hit\n" +
+                         "            sai_rows_filtered, 
sai_total_query_timeouts,\n" +
+                         "            sai_total_queryable_index_ratio)\n" +
                          "\n" + 
                          "        -t <top>, --top <top>\n" + 
                          "            Show only the top K tables for the sort 
key (specify the number K of\n" + 
diff --cc 
test/unit/org/apache/cassandra/tools/nodetool/stats/TableStatsPrinterTest.java
index 3d666db946,427c5e2a40..07a56d11ac
--- 
a/test/unit/org/apache/cassandra/tools/nodetool/stats/TableStatsPrinterTest.java
+++ 
b/test/unit/org/apache/cassandra/tools/nodetool/stats/TableStatsPrinterTest.java
@@@ -385,44 -227,15 +385,60 @@@ public class TableStatsPrinterTest exte
          "\tMaximum live cells per slice (last five minutes): 3\n" +
          "\tAverage tombstones per slice (last five minutes): 4.01\n" +
          "\tMaximum tombstones per slice (last five minutes): 5\n" +
 -        "\tDroppable tombstone ratio: 0.55556\n" +
 +        "\tDroppable tombstone ratio: 0.556\n" +
++        "\tSAI local query latency (mean): 10.000 ms\n" +
++        "\tSAI post-filtering latency (mean): 1.000 ms\n" +
++        "\tSAI space used (bytes): 40 bytes\n" +
++        "\tSAI sstable indexes hit per query (mean): 3.5\n" +
++        "\tSAI index segments hit per query (mean): 4.0\n" +
++        "\tSAI rows filtered per query (mean): 55.0\n" +
++        "\tSAI local query timeouts: 4\n" +
++        "\tSAI queryable/total indexes: 5/5\n" +
 +        "\n";
 +
 +    public static final String expectedDefaultHumanReadableTable5Output =
 +        "\tTable: %s\n" +
 +        "\tSSTable count: 40000\n" +
 +        "\tOld SSTable count: 0\n" +
 +        "\tMax SSTable size: 0 bytes\n" +
 +        "\tSpace used (live): 55555\n" +
 +        "\tSpace used (total): 64\n" +
 +        "\tSpace used by snapshots (total): 55555\n" +
 +        "\tSSTable Compression Ratio: 0.990\n" +
 +        "\tNumber of partitions (estimate): 55\n" +
 +        "\tMemtable cell count: 55555\n" +
 +        "\tMemtable data size: 20000\n" +
 +        "\tMemtable switch count: 5\n" +
 +        "\tSpeculative retries: 0\n" +
 +        "\tLocal read count: 4\n" +
 +        "\tLocal read latency: 0.000 ms\n" +
 +        "\tLocal write count: 1\n" +
 +        "\tLocal write latency: 1.000 ms\n" +
 +        "\tLocal read/write ratio: 0.000\n" +
 +        "\tPending flushes: 5\n" +
 +        "\tPercent repaired: 93.0\n" +
 +        "\tBytes repaired: 0 bytes\n" +
 +        "\tBytes unrepaired: 0 bytes\n" +
 +        "\tBytes pending repair: 0 bytes\n" +
 +        "\tBloom filter false positives: 10\n" +
 +        "\tBloom filter false ratio: 0.600\n" +
 +        "\tBloom filter space used: 123\n" +
 +        "\tCompacted partition minimum bytes: 3 bytes\n" +
 +        "\tCompacted partition maximum bytes: 40 bytes\n" +
 +        "\tCompacted partition mean bytes: 4 bytes\n" +
 +        "\tAverage live cells per slice (last five minutes): 4.00\n" +
 +        "\tMaximum live cells per slice (last five minutes): 3\n" +
 +        "\tAverage tombstones per slice (last five minutes): 4.01\n" +
 +        "\tMaximum tombstones per slice (last five minutes): 5\n" +
 +        "\tDroppable tombstone ratio: 0.556\n" +
+         "\tSAI local query latency (mean): 10.000 ms\n" +
+         "\tSAI post-filtering latency (mean): 1.000 ms\n" +
+         "\tSAI space used (bytes): 40 bytes\n" +
+         "\tSAI sstable indexes hit per query (mean): 3.5\n" +
+         "\tSAI index segments hit per query (mean): 4.0\n" +
+         "\tSAI rows filtered per query (mean): 55.0\n" +
+         "\tSAI local query timeouts: 4\n" +
+         "\tSAI queryable/total indexes: 5/5\n" +
          "\n";
  
      public static final String expectedDefaultTable6Output =
@@@ -821,13 -545,10 +855,11 @@@
                                   "      
maximum_live_cells_per_slice_last_five_minutes: 2\n" +
                                   "      space_used_live: '666666'\n" +
                                   "      compacted_partition_mean_bytes: 3\n" +
-                                  "      bloom_filter_false_ratio: 
'0.03000'\n" +
                                   "      old_sstable_count: 0\n" +
                                   "      bytes_unrepaired: 0\n" +
-                                  "      percent_repaired: 0.0\n" +
                                   "      space_used_by_snapshots_total: '0'\n" 
+
                                   "  read_latency_ms: 0.0\n" +
 +                                 "  space_used_live: '0'\n" +
                                   "  pending_flushes: 66\n" +
                                   "  write_count: 0\n" +
                                   "  read_latency: 0.0\n" +


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to