You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by jb...@apache.org on 2014/01/22 07:27:48 UTC
git commit: add listsnapshots command to nodetool patch by Sankalp
Kohli and Lyuben Todorov for CASSANDRA-5742
Updated Branches:
refs/heads/trunk 0b6f03f12 -> 719103b64
add listsnapshots command to nodetool
patch by Sankalp Kohli and Lyuben Todorov for CASSANDRA-5742
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/719103b6
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/719103b6
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/719103b6
Branch: refs/heads/trunk
Commit: 719103b649c1c5459683a8ffd1c013664f1ffbb6
Parents: 0b6f03f
Author: Jonathan Ellis <jb...@apache.org>
Authored: Tue Jan 21 22:27:24 2014 -0800
Committer: Jonathan Ellis <jb...@apache.org>
Committed: Tue Jan 21 22:27:24 2014 -0800
----------------------------------------------------------------------
CHANGES.txt | 1 +
.../apache/cassandra/db/ColumnFamilyStore.java | 9 ++++
.../org/apache/cassandra/db/Directories.java | 36 ++++++++++++++++
.../org/apache/cassandra/io/util/FileUtils.java | 18 ++++++++
.../cassandra/service/StorageService.java | 45 ++++++++++++++++++++
.../cassandra/service/StorageServiceMBean.java | 13 ++++++
.../org/apache/cassandra/tools/NodeProbe.java | 10 +++++
.../org/apache/cassandra/tools/NodeTool.java | 44 +++++++++++++++++++
8 files changed, 176 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/719103b6/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 6eeb819..5c9b64f 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
2.1
+ * add listsnapshots command to nodetool (CASSANDRA-5742)
* Introduce AtomicBTreeColumns (CASSANDRA-6271)
* Multithreaded commitlog (CASSANDRA-3578)
* allocate fixed index summary memory pool and resample cold index summaries
http://git-wip-us.apache.org/repos/asf/cassandra/blob/719103b6/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/ColumnFamilyStore.java b/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
index 892e881..fe77d09 100644
--- a/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
+++ b/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
@@ -1839,6 +1839,15 @@ public class ColumnFamilyStore implements ColumnFamilyStoreMBean
List<File> snapshotDirs = directories.getCFDirectories();
Directories.clearSnapshot(snapshotName, snapshotDirs);
}
+ /**
+ *
+ * @return Return a map of all snapshots to space being used
+ * The pair for a snapshot has true size and size on disk.
+ */
+ public Map<String, Pair<Long,Long>> getSnapshotDetails()
+ {
+ return directories.getSnapshotDetails();
+ }
public boolean hasUnreclaimedSpace()
{
http://git-wip-us.apache.org/repos/asf/cassandra/blob/719103b6/src/java/org/apache/cassandra/db/Directories.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/Directories.java b/src/java/org/apache/cassandra/db/Directories.java
index a124d67..b3723b3 100644
--- a/src/java/org/apache/cassandra/db/Directories.java
+++ b/src/java/org/apache/cassandra/db/Directories.java
@@ -485,6 +485,42 @@ public class Directories
}
}
+ /**
+ *
+ * @return Return a map of all snapshots to space being used
+ * The pair for a snapshot has size on disk and true size.
+ */
+ public Map<String, Pair<Long, Long>> getSnapshotDetails()
+ {
+ final Map<String, Pair<Long, Long>> snapshotSpaceMap = new HashMap<>();
+ for (final File dir : sstableDirectories)
+ {
+ final File snapshotDir = new File(dir,SNAPSHOT_SUBDIR);
+ if (snapshotDir.exists() && snapshotDir.isDirectory())
+ {
+ final File[] snapshots = snapshotDir.listFiles();
+ if (snapshots != null)
+ {
+ for (final File snapshot : snapshots)
+ {
+ if (snapshot.isDirectory())
+ {
+ final long sizeOnDisk = FileUtils.folderSize(snapshot);
+ final long trueSize = getTrueAllocatedSizeIn(snapshot);
+ Pair<Long,Long> spaceUsed = snapshotSpaceMap.get(snapshot.getName());
+ if (spaceUsed == null)
+ spaceUsed = Pair.create(sizeOnDisk,trueSize);
+ else
+ spaceUsed = Pair.create(spaceUsed.left + sizeOnDisk, spaceUsed.right + trueSize);
+ snapshotSpaceMap.put(snapshot.getName(), spaceUsed);
+ }
+ }
+ }
+ }
+ }
+
+ return snapshotSpaceMap;
+ }
public boolean snapshotExists(String snapshotName)
{
for (File dir : sstableDirectories)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/719103b6/src/java/org/apache/cassandra/io/util/FileUtils.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/io/util/FileUtils.java b/src/java/org/apache/cassandra/io/util/FileUtils.java
index 3c84cc3..cbed4f8 100644
--- a/src/java/org/apache/cassandra/io/util/FileUtils.java
+++ b/src/java/org/apache/cassandra/io/util/FileUtils.java
@@ -447,4 +447,22 @@ public class FileUtils
throw new IllegalStateException();
}
}
+
+ /**
+ * Get the size of a directory in bytes
+ * @param The directory for which we need size.
+ * @return The size of the directory
+ */
+ public static long folderSize(File directory)
+ {
+ long length = 0;
+ for (File file : directory.listFiles())
+ {
+ if (file.isFile())
+ length += file.length();
+ else
+ length += folderSize(file);
+ }
+ return length;
+ }
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/719103b6/src/java/org/apache/cassandra/service/StorageService.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/StorageService.java b/src/java/org/apache/cassandra/service/StorageService.java
index 6f4788f..43fead0 100644
--- a/src/java/org/apache/cassandra/service/StorageService.java
+++ b/src/java/org/apache/cassandra/service/StorageService.java
@@ -34,6 +34,8 @@ import javax.management.MBeanServer;
import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;
import javax.management.ObjectName;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
import static java.nio.charset.StandardCharsets.ISO_8859_1;
@@ -2229,6 +2231,49 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
logger.debug("Cleared out snapshot directories");
}
+ public Map<String, TabularData> getSnapshotDetails()
+ {
+ final Map<String, TabularData> snapshotMap = new HashMap<>();
+ for (final Keyspace keyspace : Keyspace.all())
+ {
+ if (Keyspace.SYSTEM_KS.equals(keyspace.getName()))
+ continue;
+
+ for (final ColumnFamilyStore cfStore : keyspace.getColumnFamilyStores())
+ {
+ for (final Map.Entry<String, Pair<Long,Long>> snapshotDetail : cfStore.getSnapshotDetails().entrySet())
+ {
+ TabularDataSupport data = (TabularDataSupport)snapshotMap.get(snapshotDetail.getKey());
+ if (data == null)
+ {
+ data = new TabularDataSupport(SnapshotDetailsTabularData.TABULAR_TYPE);
+ snapshotMap.put(snapshotDetail.getKey(), data);
+ }
+
+ SnapshotDetailsTabularData.from(snapshotDetail.getKey(), keyspace.getName(), cfStore.getColumnFamilyName(), snapshotDetail, data);
+ }
+ }
+ }
+ return snapshotMap;
+ }
+
+ public long trueSnapshotsSize()
+ {
+ long total = 0;
+ for (final Keyspace keyspace : Keyspace.all())
+ {
+ if (Keyspace.SYSTEM_KS.equals(keyspace.getName()))
+ continue;
+
+ for (final ColumnFamilyStore cfStore : keyspace.getColumnFamilyStores())
+ {
+ total += cfStore.trueSnapshotsSize();
+ }
+ }
+
+ return total;
+ }
+
/**
* @param allowIndexes Allow index CF names to be passed in
* @param autoAddIndexes Automatically add secondary indexes if a CF has them
http://git-wip-us.apache.org/repos/asf/cassandra/blob/719103b6/src/java/org/apache/cassandra/service/StorageServiceMBean.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/StorageServiceMBean.java b/src/java/org/apache/cassandra/service/StorageServiceMBean.java
index e0bca26..390795e 100644
--- a/src/java/org/apache/cassandra/service/StorageServiceMBean.java
+++ b/src/java/org/apache/cassandra/service/StorageServiceMBean.java
@@ -28,6 +28,7 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import javax.management.NotificationEmitter;
+import javax.management.openmbean.TabularData;
public interface StorageServiceMBean extends NotificationEmitter
{
@@ -216,6 +217,18 @@ public interface StorageServiceMBean extends NotificationEmitter
public void clearSnapshot(String tag, String... keyspaceNames) throws IOException;
/**
+ * Get the details of all the snapshot
+ * @return A map of snapshotName to all its details in Tabular form.
+ */
+ public Map<String, TabularData> getSnapshotDetails();
+
+ /**
+ * Get the true size taken by all snapshots across all keyspaces.
+ * @return True size taken by all the snapshots.
+ */
+ public long trueSnapshotsSize();
+
+ /**
* Forces major compaction of a single keyspace
*/
public void forceKeyspaceCompaction(String keyspaceName, String... columnFamilies) throws IOException, ExecutionException, InterruptedException;
http://git-wip-us.apache.org/repos/asf/cassandra/blob/719103b6/src/java/org/apache/cassandra/tools/NodeProbe.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/NodeProbe.java b/src/java/org/apache/cassandra/tools/NodeProbe.java
index 7727401..cbd43e9 100644
--- a/src/java/org/apache/cassandra/tools/NodeProbe.java
+++ b/src/java/org/apache/cassandra/tools/NodeProbe.java
@@ -452,6 +452,16 @@ public class NodeProbe implements AutoCloseable
ssProxy.clearSnapshot(tag, keyspaces);
}
+ public Map<String, TabularData> getSnapshotDetails()
+ {
+ return ssProxy.getSnapshotDetails();
+ }
+
+ public long trueSnapshotsSize()
+ {
+ return ssProxy.trueSnapshotsSize();
+ }
+
public boolean isJoined()
{
return ssProxy.isJoined();
http://git-wip-us.apache.org/repos/asf/cassandra/blob/719103b6/src/java/org/apache/cassandra/tools/NodeTool.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/NodeTool.java b/src/java/org/apache/cassandra/tools/NodeTool.java
index c9ddf4f..70580f2 100644
--- a/src/java/org/apache/cassandra/tools/NodeTool.java
+++ b/src/java/org/apache/cassandra/tools/NodeTool.java
@@ -42,6 +42,7 @@ import org.apache.cassandra.db.ColumnFamilyStoreMBean;
import org.apache.cassandra.db.Keyspace;
import org.apache.cassandra.db.compaction.CompactionManagerMBean;
import org.apache.cassandra.db.compaction.OperationType;
+import org.apache.cassandra.io.util.FileUtils;
import org.apache.cassandra.locator.EndpointSnitchInfoMBean;
import org.apache.cassandra.net.MessagingServiceMBean;
import org.apache.cassandra.service.CacheServiceMBean;
@@ -117,6 +118,7 @@ public class NodeTool
SetStreamThroughput.class,
SetTraceProbability.class,
Snapshot.class,
+ ListSnapshots.class,
Status.class,
StatusBinary.class,
StatusThrift.class,
@@ -1645,6 +1647,48 @@ public class NodeTool
}
}
+ @Command(name = "listsnapshots", description = "Lists all the snapshots along with the size on disk and true size.")
+ public static class ListSnapshots extends NodeToolCmd
+ {
+ @Override
+ public void execute(NodeProbe probe)
+ {
+ try
+ {
+ System.out.println("Snapshot Details: ");
+
+ final Map<String,TabularData> snapshotDetails = probe.getSnapshotDetails();
+ if (snapshotDetails.isEmpty())
+ {
+ System.out.printf("There are no snapshots");
+ return;
+ }
+
+ final long trueSnapshotsSize = probe.trueSnapshotsSize();
+ final String format = "%-20s%-29s%-29s%-19s%-19s%n";
+ // display column names only once
+ final List<String> indexNames = snapshotDetails.entrySet().iterator().next().getValue().getTabularType().getIndexNames();
+ System.out.printf(format, (Object[]) indexNames.toArray(new String[indexNames.size()]));
+
+ for (final Map.Entry<String, TabularData> snapshotDetail : snapshotDetails.entrySet())
+ {
+ Set<?> values = snapshotDetail.getValue().keySet();
+ for (Object eachValue : values)
+ {
+ final List<?> value = (List<?>) eachValue;
+ System.out.printf(format, value.toArray(new Object[value.size()]));
+ }
+ }
+
+ System.out.println("\nTotal TrueDiskSpaceUsed: " + FileUtils.stringifyFileSize(trueSnapshotsSize) + "\n");
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Error during list snapshot", e);
+ }
+ }
+ }
+
@Command(name = "status", description = "Print cluster information (state, load, IDs, ...)")
public static class Status extends NodeToolCmd
{