You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by jw...@apache.org on 2022/12/03 20:57:19 UTC
[cassandra] branch trunk updated: Add option to print level with getsstables output
This is an automated email from the ASF dual-hosted git repository.
jwest pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra.git
The following commit(s) were added to refs/heads/trunk by this push:
new 279f284da5 Add option to print level with getsstables output
279f284da5 is described below
commit 279f284da5cfe8b4766921d3b1b4d6e299dbe66d
Author: Jordan West <jo...@netflix.com>
AuthorDate: Wed Nov 9 12:59:34 2022 -0800
Add option to print level with getsstables output
Patch by Jordan West; reviewed by Brandon Williams and Cheng Wang for CASSANDRA-18023
---
CHANGES.txt | 1 +
.../org/apache/cassandra/db/ColumnFamilyStore.java | 30 +++++++++++++++++++---
.../cassandra/db/ColumnFamilyStoreMBean.java | 14 ++++++++++
.../db/compaction/CompactionStrategyManager.java | 12 +++++++++
src/java/org/apache/cassandra/tools/NodeProbe.java | 13 ++++++++++
.../cassandra/tools/nodetool/GetSSTables.java | 20 ++++++++++++---
6 files changed, 84 insertions(+), 6 deletions(-)
diff --git a/CHANGES.txt b/CHANGES.txt
index 34754e59d0..98a63a6aa8 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
4.2
+ * Add option to print level in nodetool getsstables output (CASSANDRA-18023)
* Implement a guardrail for not having zero default_time_to_live on tables with TWCS (CASSANDRA-18042)
* Add CQL scalar functions for collection aggregation (CASSANDRA-18060)
* Make cassandra.replayList property for CommitLogReplayer possible to react on keyspaces only (CASSANDRA-18044)
diff --git a/src/java/org/apache/cassandra/db/ColumnFamilyStore.java b/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
index e7bad897ba..cb164a030f 100644
--- a/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
+++ b/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
@@ -64,10 +64,12 @@ import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
+import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.RateLimiter;
import org.slf4j.Logger;
@@ -167,6 +169,7 @@ import org.apache.cassandra.utils.FBUtilities;
import org.apache.cassandra.utils.JVMStabilityInspector;
import org.apache.cassandra.utils.MBeanWrapper;
import org.apache.cassandra.utils.NoSpamLogger;
+import org.apache.cassandra.utils.Pair;
import org.apache.cassandra.utils.TimeUUID;
import org.apache.cassandra.utils.WrappedRunnable;
import org.apache.cassandra.utils.concurrent.CountDownLatch;
@@ -1939,19 +1942,34 @@ public class ColumnFamilyStore implements ColumnFamilyStoreMBean, Memtable.Owner
}
public List<String> getSSTablesForKey(String key, boolean hexFormat)
+ {
+ return withSSTablesForKey(key, hexFormat, SSTableReader::getFilename);
+ }
+
+ public Map<Integer, Collection<String>> getSSTablesForKeyWithLevel(String key, boolean hexFormat)
+ {
+ List<Pair<Integer, String>> ssts = withSSTablesForKey(key, hexFormat, sstr -> Pair.create(sstr.getSSTableLevel(), sstr.getFilename()));
+ Multimap<Integer, String> result = HashMultimap.create();
+ for (Pair<Integer, String> sst : ssts)
+ result.put(sst.left, sst.right);
+
+ return result.asMap();
+ }
+
+ public <T> List<T> withSSTablesForKey(String key, boolean hexFormat, Function<SSTableReader, T> mapper)
{
ByteBuffer keyBuffer = hexFormat ? ByteBufferUtil.hexToBytes(key) : metadata().partitionKeyType.fromString(key);
DecoratedKey dk = decorateKey(keyBuffer);
try (OpOrder.Group op = readOrdering.start())
{
- List<String> files = new ArrayList<>();
+ List<T> mapped = new ArrayList<>();
for (SSTableReader sstr : select(View.select(SSTableSet.LIVE, dk)).sstables)
{
// check if the key actually exists in this sstable, without updating cache and stats
if (sstr.getPosition(dk, SSTableReader.Operator.EQ, false) != null)
- files.add(sstr.getFilename());
+ mapped.add(mapper.apply(sstr));
}
- return files;
+ return mapped;
}
}
@@ -3061,6 +3079,12 @@ public class ColumnFamilyStore implements ColumnFamilyStoreMBean, Memtable.Owner
return compactionStrategyManager.getPerLevelSizeBytes();
}
+ @Override
+ public boolean isLeveledCompaction()
+ {
+ return compactionStrategyManager.isLeveledCompaction();
+ }
+
@Override
public int[] getSSTableCountPerTWCSBucket()
{
diff --git a/src/java/org/apache/cassandra/db/ColumnFamilyStoreMBean.java b/src/java/org/apache/cassandra/db/ColumnFamilyStoreMBean.java
index 4f06192bf4..629f431547 100644
--- a/src/java/org/apache/cassandra/db/ColumnFamilyStoreMBean.java
+++ b/src/java/org/apache/cassandra/db/ColumnFamilyStoreMBean.java
@@ -161,6 +161,15 @@ public interface ColumnFamilyStoreMBean
*/
public List<String> getSSTablesForKey(String key, boolean hexFormat);
+ /**
+ * Returns a list of filenames that contain the given key and which level they belong to.
+ * Requires table to be compacted with {@link org.apache.cassandra.db.compaction.LeveledCompactionStrategy}
+ * @param key
+ * @param hexFormat
+ * @return list of filenames and levels containing the key
+ */
+ public Map<Integer, Collection<String>> getSSTablesForKeyWithLevel(String key, boolean hexFormat);
+
/**
* Load new sstables from the given directory
*
@@ -225,6 +234,11 @@ public interface ColumnFamilyStoreMBean
*/
public long[] getPerLevelSizeBytes();
+ /**
+ * @return true if the table is using LeveledCompactionStrategy. false otherwise.
+ */
+ public boolean isLeveledCompaction();
+
/**
* @return sstable count for each bucket in TWCS. null unless time window compaction is used.
* array index corresponds to bucket(int[0] is for most recent, ...).
diff --git a/src/java/org/apache/cassandra/db/compaction/CompactionStrategyManager.java b/src/java/org/apache/cassandra/db/compaction/CompactionStrategyManager.java
index 06ff15abbb..08ab2c22fe 100644
--- a/src/java/org/apache/cassandra/db/compaction/CompactionStrategyManager.java
+++ b/src/java/org/apache/cassandra/db/compaction/CompactionStrategyManager.java
@@ -617,6 +617,18 @@ public class CompactionStrategyManager implements INotificationConsumer
}
}
+ public boolean isLeveledCompaction()
+ {
+ readLock.lock();
+ try
+ {
+ return repaired.first() instanceof LeveledCompactionStrategy;
+ } finally
+ {
+ readLock.unlock();
+ }
+ }
+
public int[] getSSTableCountPerTWCSBucket()
{
readLock.lock();
diff --git a/src/java/org/apache/cassandra/tools/NodeProbe.java b/src/java/org/apache/cassandra/tools/NodeProbe.java
index 22ec00b5df..687ab0a0ab 100644
--- a/src/java/org/apache/cassandra/tools/NodeProbe.java
+++ b/src/java/org/apache/cassandra/tools/NodeProbe.java
@@ -30,6 +30,7 @@ import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMISocketFactory;
import java.util.AbstractMap;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@@ -1044,6 +1045,18 @@ public class NodeProbe implements AutoCloseable
return cfsProxy.getSSTablesForKey(key, hexFormat);
}
+ public Map<Integer, Collection<String>> getSSTablesWithLevel(String keyspace, String cf, String key, boolean hexFormat)
+ {
+ ColumnFamilyStoreMBean cfsProxy = getCfsProxy(keyspace, cf);
+ return cfsProxy.getSSTablesForKeyWithLevel(key, hexFormat);
+ }
+
+ public boolean isLeveledCompaction(String keyspace, String cf)
+ {
+ ColumnFamilyStoreMBean cfsProxy = getCfsProxy(keyspace, cf);
+ return cfsProxy.isLeveledCompaction();
+ }
+
public Set<StreamState> getStreamStatus()
{
return Sets.newHashSet(Iterables.transform(streamProxy.getCurrentStreams(), new Function<CompositeData, StreamState>()
diff --git a/src/java/org/apache/cassandra/tools/nodetool/GetSSTables.java b/src/java/org/apache/cassandra/tools/nodetool/GetSSTables.java
index f1e2117ebf..e321e31f20 100644
--- a/src/java/org/apache/cassandra/tools/nodetool/GetSSTables.java
+++ b/src/java/org/apache/cassandra/tools/nodetool/GetSSTables.java
@@ -22,7 +22,9 @@ import io.airlift.airline.Arguments;
import io.airlift.airline.Command;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
+import java.util.Map;
import io.airlift.airline.Option;
import org.apache.cassandra.tools.NodeProbe;
@@ -36,6 +38,9 @@ public class GetSSTables extends NodeToolCmd
description = "Specify the key in hexadecimal string format")
private boolean hexFormat = false;
+ @Option(name={"-l", "--show-levels"}, description="If the table is using leveled compaction the level of each sstable will be included in the output (Default: false)")
+ private boolean showLevels = false;
+
@Arguments(usage = "<keyspace> <cfname> <key>", description = "The keyspace, the column family, and the key")
private List<String> args = new ArrayList<>();
@@ -47,10 +52,19 @@ public class GetSSTables extends NodeToolCmd
String cf = args.get(1);
String key = args.get(2);
- List<String> sstables = probe.getSSTables(ks, cf, key, hexFormat);
- for (String sstable : sstables)
+ if (showLevels && probe.isLeveledCompaction(ks, cf))
+ {
+ Map<Integer, Collection<String>> sstables = probe.getSSTablesWithLevel(ks, cf, key, hexFormat);
+ for (Integer level : sstables.keySet())
+ for (String sstable : sstables.get(level))
+ probe.output().out.println(level + ": " + sstable);
+ } else
{
- probe.output().out.println(sstable);
+ List<String> sstables = probe.getSSTables(ks, cf, key, hexFormat);
+ for (String sstable : sstables)
+ {
+ probe.output().out.println(sstable);
+ }
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org