Return-Path: X-Original-To: apmail-cassandra-commits-archive@www.apache.org Delivered-To: apmail-cassandra-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 8806D10950 for ; Tue, 26 Nov 2013 21:19:21 +0000 (UTC) Received: (qmail 53985 invoked by uid 500); 26 Nov 2013 21:19:21 -0000 Delivered-To: apmail-cassandra-commits-archive@cassandra.apache.org Received: (qmail 53925 invoked by uid 500); 26 Nov 2013 21:19:21 -0000 Mailing-List: contact commits-help@cassandra.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cassandra.apache.org Delivered-To: mailing list commits@cassandra.apache.org Received: (qmail 53821 invoked by uid 99); 26 Nov 2013 21:19:21 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 26 Nov 2013 21:19:21 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id A416E919091; Tue, 26 Nov 2013 21:19:20 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: jbellis@apache.org To: commits@cassandra.apache.org Date: Tue, 26 Nov 2013 21:19:20 -0000 Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: [1/7] git commit: add snapshot space used to cfstats patch by Mikhail Stepura; reviewed by jbellis for CASSANDRA-6231 Updated Branches: refs/heads/cassandra-1.2 5f6261096 -> 3f66fbfc6 refs/heads/cassandra-2.0 f15681b67 -> 8e8259050 refs/heads/trunk f15d6d591 -> c1d7291c8 add snapshot space used to cfstats patch by Mikhail Stepura; reviewed by jbellis for CASSANDRA-6231 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/e178ff45 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/e178ff45 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/e178ff45 Branch: refs/heads/trunk Commit: e178ff45c0510c56257c26da2dc8d082ba301522 Parents: f15d6d5 Author: Jonathan Ellis Authored: Tue Nov 26 14:42:05 2013 -0600 Committer: Jonathan Ellis Committed: Tue Nov 26 14:49:17 2013 -0600 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../apache/cassandra/db/ColumnFamilyStore.java | 5 ++ .../cassandra/db/ColumnFamilyStoreMBean.java | 5 ++ .../org/apache/cassandra/db/Directories.java | 90 +++++++++++++++++++- .../cassandra/metrics/ColumnFamilyMetrics.java | 15 +++- .../org/apache/cassandra/tools/NodeCmd.java | 1 + .../org/apache/cassandra/tools/NodeProbe.java | 1 + 7 files changed, 114 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/e178ff45/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 7bb1fa0..00797e6 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -18,6 +18,7 @@ 2.0.4 * Fix setting last compacted key in the wrong level for LCS (CASSANDRA-6284) * Add sub-ms precision formats to the timestamp parser (CASSANDRA-6395) + * Add snapshot space used to cfstats (CASSANDRA-6231) Merged from 1.2: * Fix thundering herd on endpoint cache invalidation (CASSANDRA-6345) * cqlsh: quote single quotes in strings inside collections (CASSANDRA-6172) http://git-wip-us.apache.org/repos/asf/cassandra/blob/e178ff45/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 7037635..ccc15ab 100644 --- a/src/java/org/apache/cassandra/db/ColumnFamilyStore.java +++ b/src/java/org/apache/cassandra/db/ColumnFamilyStore.java @@ -2356,4 +2356,9 @@ public class ColumnFamilyStore implements ColumnFamilyStoreMBean Pair truncationRecord = SystemKeyspace.getTruncationRecords().get(metadata.cfId); return truncationRecord == null ? Long.MIN_VALUE : truncationRecord.right; } + + public long trueSnapshotsSize() + { + return directories.trueSnapshotsSize(); + } } http://git-wip-us.apache.org/repos/asf/cassandra/blob/e178ff45/src/java/org/apache/cassandra/db/ColumnFamilyStoreMBean.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/ColumnFamilyStoreMBean.java b/src/java/org/apache/cassandra/db/ColumnFamilyStoreMBean.java index 1ca922b..fc1a7b1 100644 --- a/src/java/org/apache/cassandra/db/ColumnFamilyStoreMBean.java +++ b/src/java/org/apache/cassandra/db/ColumnFamilyStoreMBean.java @@ -344,4 +344,9 @@ public interface ColumnFamilyStoreMBean * @return ratio */ public double getDroppableTombstoneRatio(); + + /** + * @return the size of SSTables in "snapshots" subdirectory which aren't live anymore + */ + public long trueSnapshotsSize(); } http://git-wip-us.apache.org/repos/asf/cassandra/blob/e178ff45/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 9795a27..ea5c2f4 100644 --- a/src/java/org/apache/cassandra/db/Directories.java +++ b/src/java/org/apache/cassandra/db/Directories.java @@ -17,16 +17,25 @@ */ package org.apache.cassandra.db; +import static com.google.common.collect.Sets.newHashSet; + import java.io.File; import java.io.FileFilter; import java.io.IOError; import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSet.Builder; import com.google.common.primitives.Longs; import com.google.common.util.concurrent.Uninterruptibles; @@ -35,7 +44,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.cassandra.config.*; -import org.apache.cassandra.db.compaction.LeveledManifest; import org.apache.cassandra.io.FSError; import org.apache.cassandra.io.FSWriteError; import org.apache.cassandra.io.util.FileUtils; @@ -332,7 +340,7 @@ public class Directories private FileFilter getFilter() { // Note: the prefix needs to include cfname + separator to distinguish between a cfs and it's secondary indexes - final String sstablePrefix = keyspacename + Component.separator + cfname + Component.separator; + final String sstablePrefix = getSSTablePrefix(); return new FileFilter() { // This function always return false since accepts adds to the components map @@ -401,6 +409,37 @@ public class Directories } throw new RuntimeException("Snapshot " + snapshotName + " doesn't exist"); } + + public long trueSnapshotsSize() + { + long result = 0L; + for (File dir : sstableDirectories) + result += getTrueAllocatedSizeIn(new File(dir, join(SNAPSHOT_SUBDIR))); + return result; + } + + private String getSSTablePrefix() + { + return keyspacename + Component.separator + cfname + Component.separator; + } + + public long getTrueAllocatedSizeIn(File input) + { + if (!input.isDirectory()) + return 0; + + TrueFilesSizeVisitor visitor = new TrueFilesSizeVisitor(); + try + { + Files.walkFileTree(input.toPath(), visitor); + } + catch (IOException e) + { + logger.error("Could not calculate the size of {}. {}", input, e); + } + + return visitor.getAllocatedSize(); + } private static File getOrCreate(File base, String... subdirs) { @@ -436,4 +475,51 @@ public class Directories for (int i = 0; i < locations.length; ++i) dataFileLocations[i] = new DataDirectory(new File(locations[i])); } + + private class TrueFilesSizeVisitor extends SimpleFileVisitor + { + private final AtomicLong size = new AtomicLong(0); + private final Set visited = newHashSet(); //count each file only once + private final Set alive; + private final String prefix = getSSTablePrefix(); + + public TrueFilesSizeVisitor() + { + super(); + Builder builder = ImmutableSet.builder(); + for (File file: sstableLister().listFiles()) + builder.add(file.getName()); + alive = builder.build(); + } + + private boolean isAcceptable(Path file) + { + String fileName = file.toFile().getName(); + return fileName.startsWith(prefix) + && !visited.contains(fileName) + && !alive.contains(fileName); + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException + { + if (isAcceptable(file)) + { + size.addAndGet(attrs.size()); + visited.add(file.toFile().getName()); + } + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException + { + return FileVisitResult.CONTINUE; + } + + public long getAllocatedSize() + { + return size.get(); + } + } } http://git-wip-us.apache.org/repos/asf/cassandra/blob/e178ff45/src/java/org/apache/cassandra/metrics/ColumnFamilyMetrics.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/metrics/ColumnFamilyMetrics.java b/src/java/org/apache/cassandra/metrics/ColumnFamilyMetrics.java index aabf373..038e27e 100644 --- a/src/java/org/apache/cassandra/metrics/ColumnFamilyMetrics.java +++ b/src/java/org/apache/cassandra/metrics/ColumnFamilyMetrics.java @@ -82,6 +82,8 @@ public class ColumnFamilyMetrics public final Histogram tombstoneScannedHistogram; /** Live cells scanned in queries on this CF */ public final Histogram liveScannedHistogram; + /** Disk space used by snapshot files which */ + public final Gauge trueSnapshotsSize; public final Timer coordinatorReadLatency; public final Timer coordinatorScanLatency; @@ -238,7 +240,7 @@ public class ColumnFamilyMetrics public Long value() { long count = 0L; - for (SSTableReader sstable: cfs.getSSTables()) + for (SSTableReader sstable : cfs.getSSTables()) count += sstable.getRecentBloomFilterFalsePositiveCount(); return count; } @@ -249,7 +251,7 @@ public class ColumnFamilyMetrics { long falseCount = 0L; long trueCount = 0L; - for (SSTableReader sstable: cfs.getSSTables()) + for (SSTableReader sstable : cfs.getSSTables()) { falseCount += sstable.getBloomFilterFalsePositiveCount(); trueCount += sstable.getBloomFilterTruePositiveCount(); @@ -308,6 +310,14 @@ public class ColumnFamilyMetrics liveScannedHistogram = Metrics.newHistogram(factory.createMetricName("LiveScannedHistogram"), true); coordinatorReadLatency = Metrics.newTimer(factory.createMetricName("CoordinatorReadLatency"), TimeUnit.MICROSECONDS, TimeUnit.SECONDS); coordinatorScanLatency = Metrics.newTimer(factory.createMetricName("CoordinatorScanLatency"), TimeUnit.MICROSECONDS, TimeUnit.SECONDS); + + trueSnapshotsSize = Metrics.newGauge(factory.createMetricName("SnapshotsSize"), new Gauge() + { + public Long value() + { + return cfs.trueSnapshotsSize(); + } + }); } public void updateSSTableIterated(int count) @@ -349,6 +359,7 @@ public class ColumnFamilyMetrics Metrics.defaultRegistry().removeMetric(factory.createMetricName("LiveScannedHistogram")); Metrics.defaultRegistry().removeMetric(factory.createMetricName("CoordinatorReadLatency")); Metrics.defaultRegistry().removeMetric(factory.createMetricName("CoordinatorScanLatency")); + Metrics.defaultRegistry().removeMetric(factory.createMetricName("SnapshotsSize")); } class ColumnFamilyMetricNameFactory implements MetricNameFactory http://git-wip-us.apache.org/repos/asf/cassandra/blob/e178ff45/src/java/org/apache/cassandra/tools/NodeCmd.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/NodeCmd.java b/src/java/org/apache/cassandra/tools/NodeCmd.java index d415f06..a6c0010 100644 --- a/src/java/org/apache/cassandra/tools/NodeCmd.java +++ b/src/java/org/apache/cassandra/tools/NodeCmd.java @@ -885,6 +885,7 @@ public class NodeCmd } outs.println("\t\tSpace used (live), bytes: " + probe.getColumnFamilyMetric(keyspaceName, cfName, "LiveDiskSpaceUsed")); outs.println("\t\tSpace used (total), bytes: " + probe.getColumnFamilyMetric(keyspaceName, cfName, "TotalDiskSpaceUsed")); + outs.println("\t\tSpace used by snapshots (total), bytes: " + probe.getColumnFamilyMetric(keyspaceName, cfName, "SnapshotsSize")); outs.println("\t\tSSTable Compression Ratio: " + probe.getColumnFamilyMetric(keyspaceName, cfName, "CompressionRatio")); outs.println("\t\tMemtable cell count: " + probe.getColumnFamilyMetric(keyspaceName, cfName, "MemtableColumnsCount")); outs.println("\t\tMemtable data size, bytes: " + probe.getColumnFamilyMetric(keyspaceName, cfName, "MemtableDataSize")); http://git-wip-us.apache.org/repos/asf/cassandra/blob/e178ff45/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 48d2013..2489de6 100644 --- a/src/java/org/apache/cassandra/tools/NodeProbe.java +++ b/src/java/org/apache/cassandra/tools/NodeProbe.java @@ -935,6 +935,7 @@ public class NodeProbe case "PendingTasks": case "RecentBloomFilterFalsePositives": case "RecentBloomFilterFalseRatio": + case "SnapshotsSize": return JMX.newMBeanProxy(mbeanServerConn, new ObjectName("org.apache.cassandra.metrics:type=ColumnFamily,keyspace=" + ks + ",scope=" + cf + ",name=" + metricName), JmxReporter.GaugeMBean.class).getValue();