You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2017/06/07 09:30:13 UTC
[2/2] ignite git commit: IGNITE-5375 - Persistence metrics introduced
IGNITE-5375 - Persistence metrics introduced
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/fffad68f
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/fffad68f
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/fffad68f
Branch: refs/heads/ignite-5267
Commit: fffad68f6c23c36cf28e61bd7465082d71569665
Parents: a2e1730
Author: Alexey Goncharuk <al...@gmail.com>
Authored: Wed Jun 7 12:28:29 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Wed Jun 7 12:28:29 2017 +0300
----------------------------------------------------------------------
.../src/main/java/org/apache/ignite/Ignite.java | 6 +
.../java/org/apache/ignite/MemoryMetrics.java | 29 +-
.../org/apache/ignite/PersistenceMetrics.java | 114 +++++++
.../PersistentStoreConfiguration.java | 95 +++++-
.../apache/ignite/internal/IgniteKernal.java | 13 +
.../pagemem/wal/IgniteWriteAheadLogManager.java | 5 +
.../IgniteCacheDatabaseSharedManager.java | 10 +
.../cache/database/MemoryMetricsImpl.java | 203 ++++++-------
.../cache/database/MemoryMetricsMXBeanImpl.java | 15 +
.../cache/database/MemoryMetricsSnapshot.java | 27 ++
.../database/PersistenceMetricsSnapshot.java | 144 +++++++++
.../cache/database/tree/io/PageIO.java | 8 +
.../ignite/mxbean/MemoryMetricsMXBean.java | 12 +
.../ignite/mxbean/PersistenceMetricsMXBean.java | 121 ++++++++
.../database/MemoryMetricsSelfTest.java | 10 +-
.../processors/igfs/IgfsIgniteMock.java | 8 +
.../ignite/testframework/junits/IgniteMock.java | 6 +
.../junits/multijvm/IgniteProcessProxy.java | 6 +
.../GridCacheDatabaseSharedManager.java | 189 ++++++++----
.../cache/database/PersistenceMetricsImpl.java | 297 +++++++++++++++++++
.../pagemem/CheckpointMetricsTracker.java | 183 ++++++++++++
.../cache/database/pagemem/PageMemoryEx.java | 3 +-
.../cache/database/pagemem/PageMemoryImpl.java | 38 ++-
.../database/wal/FileWriteAheadLogManager.java | 138 +++++++--
.../IgnitePersistenceMetricsSelfTest.java | 236 +++++++++++++++
...entStoreRecoveryAfterFileCorruptionTest.java | 2 +-
.../PageStoreCheckpointSimulationSelfTest.java | 4 +-
...PlusTreeReuseListPageMemoryImplSelfTest.java | 6 +-
...BPlusTreeSelfTestPageMemoryImplSelfTest.java | 5 +-
.../MetadataStoragePageMemoryImplSelfTest.java | 5 +-
.../cache/database/pagemem/NoOpWALManager.java | 5 +
.../pagemem/PageMemoryImplNoLoadSelfTest.java | 5 +-
.../database/pagemem/PageMemoryImplTest.java | 5 +-
.../ignite/testsuites/IgnitePdsTestSuite2.java | 7 +-
.../org/apache/ignite/IgniteSpringBean.java | 7 +
35 files changed, 1745 insertions(+), 222 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/fffad68f/modules/core/src/main/java/org/apache/ignite/Ignite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/Ignite.java b/modules/core/src/main/java/org/apache/ignite/Ignite.java
index 8d5e967..f32782a 100644
--- a/modules/core/src/main/java/org/apache/ignite/Ignite.java
+++ b/modules/core/src/main/java/org/apache/ignite/Ignite.java
@@ -638,4 +638,10 @@ public interface Ignite extends AutoCloseable {
* @return {@link MemoryMetrics} snapshot or {@code null} if no memory region is configured under specified name.
*/
@Nullable public MemoryMetrics memoryMetrics(String memPlcName);
+
+ /**
+ *
+ * @return {@link PersistenceMetrics} snapshot.
+ */
+ public PersistenceMetrics persistentStoreMetrics();
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/fffad68f/modules/core/src/main/java/org/apache/ignite/MemoryMetrics.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/MemoryMetrics.java b/modules/core/src/main/java/org/apache/ignite/MemoryMetrics.java
index 81f8309..c709777 100644
--- a/modules/core/src/main/java/org/apache/ignite/MemoryMetrics.java
+++ b/modules/core/src/main/java/org/apache/ignite/MemoryMetrics.java
@@ -55,7 +55,9 @@ public interface MemoryMetrics {
public String getName();
/**
- * Gets a total number of allocated pages in a memory region.
+ * Gets a total number of allocated pages related to the memory policy. When persistence is disabled, this
+ * metric shows the total number of pages in memory. When persistence is enabled, this metric shows the
+ * total number of pages in memory and on disk.
*
* @return Total number of allocated pages.
*/
@@ -89,4 +91,29 @@ public interface MemoryMetrics {
* @return The percentage of space that is still free and can be filled in.
*/
public float getPagesFillFactor();
+
+ /**
+ * Gets the number of dirty pages (pages which contents is different from the current persistent storage state).
+ * This metric is enabled only for Ignite nodes with enabled persistence.
+ *
+ * @return Current number of dirty pages.
+ */
+ public long getDirtyPages();
+
+ /**
+ * Gets rate (pages per second) at which pages get replaced with other pages from persistent storage.
+ * The rate effectively represents the rate at which pages get 'evicted' in favor of newly needed pages.
+ * This metric is enabled only for Ignite nodes with enabled persistence.
+ *
+ * @return Pages per second replace rate.
+ */
+ public float getPagesReplaceRate();
+
+ /**
+ * Gets total number of pages currently loaded to the RAM. When persistence is disabled, this metric is equal
+ * to {@link #getTotalAllocatedPages()}.
+ *
+ * @return Total number of pages loaded to RAM.
+ */
+ public long getPhysicalMemoryPages();
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/fffad68f/modules/core/src/main/java/org/apache/ignite/PersistenceMetrics.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/PersistenceMetrics.java b/modules/core/src/main/java/org/apache/ignite/PersistenceMetrics.java
new file mode 100644
index 0000000..3f00b01
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/PersistenceMetrics.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ignite;
+
+import org.apache.ignite.configuration.PersistentStoreConfiguration;
+
+/**
+ *
+ */
+public interface PersistenceMetrics {
+ /**
+ * Gets the average number of WAL records per second written during the last time interval.
+ * <p>
+ * The length of time interval is configured via {@link PersistentStoreConfiguration#setRateTimeInterval(long)}
+ * configurartion property.
+ * The number of subintervals is configured via {@link PersistentStoreConfiguration#setSubIntervals(int)}
+ * configuration property.
+ */
+ public float getWalLoggingRate();
+
+ /**
+ * Gets the average number of bytes per second written during the last time interval.
+ * The length of time interval is configured via {@link PersistentStoreConfiguration#setRateTimeInterval(long)}
+ * configurartion property.
+ * The number of subintervals is configured via {@link PersistentStoreConfiguration#setSubIntervals(int)}
+ * configuration property.
+ */
+ public float getWalWritingRate();
+
+ /**
+ * Gets the current number of WAL segments in the WAL archive.
+ */
+ public int getWalArchiveSegments();
+
+ /**
+ * Gets the average WAL fsync duration in microseconds over the last time interval.
+ * <p>
+ * The length of time interval is configured via {@link PersistentStoreConfiguration#setRateTimeInterval(long)}
+ * configurartion property.
+ * The number of subintervals is configured via {@link PersistentStoreConfiguration#setSubIntervals(int)}
+ * configuration property.
+ */
+ public float getWalFsyncTimeAverage();
+
+ /**
+ * Gets the duration of the last checkpoint in milliseconds.
+ *
+ * @return Total checkpoint duration in milliseconds.
+ */
+ public long getLastCheckpointingDuration();
+
+ /**
+ * Gets the duration of last checkpoint lock wait in milliseconds.
+ *
+ * @return Checkpoint lock wait time in milliseconds.
+ */
+ public long getLastCheckpointLockWaitDuration();
+
+ /**
+ * Gets the duration of last checkpoint mark phase in milliseconds.
+ *
+ * @return Checkpoint mark duration in milliseconds.
+ */
+ public long getLastCheckpointMarkDuration();
+
+ /**
+ * Gets the duration of last checkpoint pages write phase in milliseconds.
+ *
+ * @return Checkpoint pages write phase in milliseconds.
+ */
+ public long getLastCheckpointPagesWriteDuration();
+
+ /**
+ * Gets the duration of the sync phase of the last checkpoint in milliseconds.
+ *
+ * @return Checkpoint fsync time in milliseconds.
+ */
+ public long getLastCheckpointFsyncDuration();
+
+ /**
+ * Gets the total number of pages written during the last checkpoint.
+ *
+ * @return Total number of pages written during the last checkpoint.
+ */
+ public long getLastCheckpointTotalPagesNumber();
+
+ /**
+ * Gets the number of data pages written during the last checkpoint.
+ *
+ * @return Total number of data pages written during the last checkpoint.
+ */
+ public long getLastCheckpointDataPagesNumber();
+
+ /**
+ * Gets the number of pages copied to a temporary checkpoint buffer during the last checkpoint.
+ *
+ * @return Total number of pages copied to a temporary checkpoint buffer during the last checkpoint.
+ */
+ public long getLastCheckpointCopiedOnWritePagesNumber();
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/fffad68f/modules/core/src/main/java/org/apache/ignite/configuration/PersistentStoreConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/PersistentStoreConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/PersistentStoreConfiguration.java
index 14e3a73..362dcdf 100644
--- a/modules/core/src/main/java/org/apache/ignite/configuration/PersistentStoreConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/PersistentStoreConfiguration.java
@@ -32,6 +32,15 @@ public class PersistentStoreConfiguration implements Serializable {
public static final int DFLT_LOCK_WAIT_TIME = 10 * 1000;
/** */
+ public static final boolean DFLT_METRICS_ENABLED = false;
+
+ /** Default amount of sub intervals to calculate rate-based metric. */
+ public static final int DFLT_SUB_INTERVALS = 5;
+
+ /** Default length of interval over which rate-based metric is calculated. */
+ public static final int DFLT_RATE_TIME_INTERVAL_MILLIS = 60_000;
+
+ /** */
@SuppressWarnings("UnnecessaryBoxing")
public static final Long DFLT_CHECKPOINTING_PAGE_BUFFER_SIZE = new Long(256L * 1024 * 1024);
@@ -48,7 +57,7 @@ public class PersistentStoreConfiguration implements Serializable {
private static final int DFLT_WAL_SEGMENT_SIZE = 64 * 1024 * 1024;
/** */
- private String persistenteStorePath;
+ private String persistenceStorePath;
/** Checkpointing frequency. */
private long checkpointingFreq = DFLT_CHECKPOINTING_FREQ;
@@ -77,11 +86,27 @@ public class PersistentStoreConfiguration implements Serializable {
/** WAL archive path. */
private String walArchivePath;
+ /** Metrics enabled flag. */
+ private boolean metricsEnabled = DFLT_METRICS_ENABLED;
+
+ /**
+ * Number of sub-intervals the whole {@link #setRateTimeInterval(long)} will be split into to calculate
+ * rate-based metrics.
+ * <p>
+ * Setting it to a bigger value will result in more precise calculation and smaller drops of
+ * rate-based metrics when next sub-interval has to be recycled but introduces bigger
+ * calculation overhead.
+ */
+ private int subIntervals = DFLT_SUB_INTERVALS;
+
+ /** Time interval (in milliseconds) for rate-based metrics. */
+ private long rateTimeInterval = DFLT_RATE_TIME_INTERVAL_MILLIS;
+
/**
* Returns a path the root directory where the Persistent Store will persist data and indexes.
*/
public String getPersistentStorePath() {
- return persistenteStorePath;
+ return persistenceStorePath;
}
/**
@@ -91,7 +116,7 @@ public class PersistentStoreConfiguration implements Serializable {
* @param persistenceStorePath Persistence store path.
*/
public PersistentStoreConfiguration setPersistentStorePath(String persistenceStorePath) {
- this.persistenteStorePath = persistenceStorePath;
+ this.persistenceStorePath = persistenceStorePath;
return this;
}
@@ -291,4 +316,68 @@ public class PersistentStoreConfiguration implements Serializable {
return this;
}
+
+ /**
+ * Gets flag indicating whether persistence metrics collection is enabled.
+ * Default value is {@link #DFLT_METRICS_ENABLED}.
+ *
+ * @return Metrics enabled flag.
+ */
+ public boolean isMetricsEnabled() {
+ return metricsEnabled;
+ }
+
+ /**
+ * Sets flag indicating whether persistence metrics collection is enabled.
+ *
+ * @param metricsEnabled Metrics enabled flag.
+ */
+ public PersistentStoreConfiguration setMetricsEnabled(boolean metricsEnabled) {
+ this.metricsEnabled = metricsEnabled;
+
+ return this;
+ }
+
+ /**
+ * Gets the length of the time interval for rate-based metrics. This interval defines a window over which
+ * hits will be tracked. Default value is {@link #DFLT_RATE_TIME_INTERVAL_MILLIS}.
+ *
+ * @return Time interval in milliseconds.
+ */
+ public long getRateTimeInterval() {
+ return rateTimeInterval;
+ }
+
+ /**
+ * Sets the length of the time interval for rate-based metrics. This interval defines a window over which
+ * hits will be tracked.
+ *
+ * @param rateTimeInterval Time interval in milliseconds.
+ */
+ public PersistentStoreConfiguration setRateTimeInterval(long rateTimeInterval) {
+ this.rateTimeInterval = rateTimeInterval;
+
+ return this;
+ }
+
+ /**
+ * Gets the number of sub-intervals to split the {@link #getRateTimeInterval()} into to track the update history.
+ * Default value is {@link #DFLT_SUB_INTERVALS}.
+ *
+ * @return The number of sub-intervals for history tracking.
+ */
+ public int getSubIntervals() {
+ return subIntervals;
+ }
+
+ /**
+ * Sets the number of sub-intervals to split the {@link #getRateTimeInterval()} into to track the update history.
+ *
+ * @param subIntervals The number of sub-intervals for history tracking.
+ */
+ public PersistentStoreConfiguration setSubIntervals(int subIntervals) {
+ this.subIntervals = subIntervals;
+
+ return this;
+ }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/fffad68f/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
index b04a969..bce3032 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
@@ -75,6 +75,7 @@ import org.apache.ignite.IgniteSystemProperties;
import org.apache.ignite.IgniteTransactions;
import org.apache.ignite.Ignition;
import org.apache.ignite.MemoryMetrics;
+import org.apache.ignite.PersistenceMetrics;
import org.apache.ignite.cache.affinity.Affinity;
import org.apache.ignite.cluster.ClusterGroup;
import org.apache.ignite.cluster.ClusterMetrics;
@@ -3441,6 +3442,18 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
}
/** {@inheritDoc} */
+ @Override public PersistenceMetrics persistentStoreMetrics() {
+ guard();
+
+ try {
+ return ctx.cache().context().database().persistentStoreMetrics();
+ }
+ finally {
+ unguard();
+ }
+ }
+
+ /** {@inheritDoc} */
@Nullable @Override public IgniteAtomicSequence atomicSequence(String name, long initVal, boolean create) {
guard();
http://git-wip-us.apache.org/repos/asf/ignite/blob/fffad68f/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/IgniteWriteAheadLogManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/IgniteWriteAheadLogManager.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/IgniteWriteAheadLogManager.java
index ac785b6..187df8d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/IgniteWriteAheadLogManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/IgniteWriteAheadLogManager.java
@@ -102,6 +102,11 @@ public interface IgniteWriteAheadLogManager extends GridCacheSharedManager, Igni
public int truncate(WALPointer ptr);
/**
+ * @return Total number of segments in the WAL archive.
+ */
+ public int walArchiveSegments();
+
+ /**
* @param ptr Pointer.
* @return True if given pointer is located in reserved segment.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/fffad68f/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
index 19c25aa..f13532d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
@@ -28,6 +28,7 @@ import javax.management.JMException;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.MemoryMetrics;
+import org.apache.ignite.PersistenceMetrics;
import org.apache.ignite.configuration.DataPageEvictionMode;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.configuration.MemoryConfiguration;
@@ -583,6 +584,13 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap
}
/**
+ * @return PersistenceMetrics if persistence is enabled or {@code null} otherwise.
+ */
+ public PersistenceMetrics persistentStoreMetrics() {
+ return null;
+ }
+
+ /**
* @param memPlcName Name of {@link MemoryPolicy} to obtain {@link MemoryMetrics} for.
* @return {@link MemoryMetrics} snapshot for specified {@link MemoryPolicy} or {@code null} if
* no {@link MemoryPolicy} is configured for specified name.
@@ -904,6 +912,8 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap
MemoryPolicyConfiguration memPlcCfg,
MemoryMetricsImpl memMetrics
) {
+ memMetrics.persistenceEnabled(false);
+
return new PageMemoryNoStoreImpl(
log,
memProvider,
http://git-wip-us.apache.org/repos/asf/ignite/blob/fffad68f/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/MemoryMetricsImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/MemoryMetricsImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/MemoryMetricsImpl.java
index 2bd96e7..2e5a78c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/MemoryMetricsImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/MemoryMetricsImpl.java
@@ -16,12 +16,11 @@
*/
package org.apache.ignite.internal.processors.cache.database;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
import org.apache.ignite.MemoryMetrics;
import org.apache.ignite.configuration.MemoryPolicyConfiguration;
+import org.apache.ignite.internal.pagemem.PageMemory;
import org.apache.ignite.internal.processors.cache.database.freelist.FreeListImpl;
-import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.internal.processors.cache.ratemetrics.HitRateMetrics;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.jsr166.LongAdder8;
@@ -40,24 +39,30 @@ public class MemoryMetricsImpl implements MemoryMetrics {
*/
private final LongAdder8 largeEntriesPages = new LongAdder8();
+ /** Counter for number of dirty pages. */
+ private LongAdder8 dirtyPages = new LongAdder8();
+
/** */
private volatile boolean metricsEnabled;
/** */
- private volatile int subInts;
+ private boolean persistenceEnabled;
/** */
- private volatile LongAdder8[] allocRateCounters;
+ private volatile int subInts;
- /** */
- private final AtomicInteger counterIdx = new AtomicInteger(0);
+ /** Allocation rate calculator. */
+ private volatile HitRateMetrics allocRate = new HitRateMetrics(60_000, 5);
/** */
- private final AtomicLong lastUpdTime = new AtomicLong(0);
+ private volatile HitRateMetrics pageReplaceRate = new HitRateMetrics(60_000, 5);
/** */
private final MemoryPolicyConfiguration memPlcCfg;
+ /** */
+ private PageMemory pageMem;
+
/** Time interval (in milliseconds) when allocations/evictions are counted to calculate rate. */
private volatile long rateTimeInterval;
@@ -72,11 +77,6 @@ public class MemoryMetricsImpl implements MemoryMetrics {
rateTimeInterval = memPlcCfg.getRateTimeInterval();
subInts = memPlcCfg.getSubIntervals();
-
- allocRateCounters = new LongAdder8[subInts];
-
- for (int i = 0; i < subInts; i++)
- allocRateCounters[i] = new LongAdder8();
}
/** {@inheritDoc} */
@@ -94,12 +94,7 @@ public class MemoryMetricsImpl implements MemoryMetrics {
if (!metricsEnabled)
return 0;
- float res = 0;
-
- for (int i = 0; i < subInts; i++)
- res += allocRateCounters[i].floatValue();
-
- return res * 1000 / rateTimeInterval;
+ return ((float) allocRate.getRate()) / rateTimeInterval;
}
/** {@inheritDoc} */
@@ -125,125 +120,87 @@ public class MemoryMetricsImpl implements MemoryMetrics {
return freeList.fillFactor();
}
- /**
- * Increments totalAllocatedPages counter.
- */
- public void incrementTotalAllocatedPages() {
- if (metricsEnabled) {
- totalAllocatedPages.increment();
+ /** {@inheritDoc} */
+ @Override public long getDirtyPages() {
+ if (!metricsEnabled || !persistenceEnabled)
+ return 0;
- try {
- updateAllocationRateMetrics();
- }
- catch (ArrayIndexOutOfBoundsException | NullPointerException ignored) {
- // No-op.
- }
- }
+ return dirtyPages.longValue();
}
- /**
- *
- */
- private void updateAllocationRateMetrics() {
- long lastUpdT = lastUpdTime.get();
- long currT = IgniteUtils.currentTimeMillis();
-
- int currIdx = counterIdx.get();
-
- long deltaT = currT - lastUpdT;
-
- int subInts = this.subInts;
-
- LongAdder8[] rateCntrs = allocRateCounters;
-
- if (subInts != rateCntrs.length)
- return;
-
- int cntrIdx = counterIdx.get();
-
- for (int i = 1; i <= subInts; i++) {
- if (deltaT < subInt(i)) {
- if (i > 1) {
- if (!lastUpdTime.compareAndSet(lastUpdT, currT)) {
- rateCntrs[cntrIdx].increment();
-
- break;
- }
- }
-
- if (rotateIndex(currIdx, i - 1)) {
- currIdx = counterIdx.get();
-
- resetCounters(currIdx, i - 1);
-
- rateCntrs[currIdx].increment();
+ /** {@inheritDoc} */
+ @Override public float getPagesReplaceRate() {
+ if (!metricsEnabled || !persistenceEnabled)
+ return 0;
- break;
- }
- else {
- rateCntrs[cntrIdx].increment();
+ return ((float) pageReplaceRate.getRate()) / rateTimeInterval;
+ }
- break;
- }
- }
- else if (i == subInts && lastUpdTime.compareAndSet(lastUpdT, currT))
- resetAll();
+ /** {@inheritDoc} */
+ @Override public long getPhysicalMemoryPages() {
+ if (!metricsEnabled || !persistenceEnabled)
+ return 0;
- if (currIdx != cntrIdx) {
- rateCntrs[cntrIdx].increment();
+ assert pageMem != null;
- break;
- }
- }
+ return pageMem.loadedPages();
}
/**
- * @param intervalNum Interval number.
+ * Updates pageReplaceRate metric.
*/
- private long subInt(int intervalNum) {
- return (rateTimeInterval * intervalNum) / subInts;
+ public void updatePageReplaceRate() {
+ if (metricsEnabled)
+ pageReplaceRate.onHit();
}
/**
- * @param idx Index.
- * @param rotateStep Rotate step.
+ * Increments dirtyPages counter.
*/
- private boolean rotateIndex(int idx, int rotateStep) {
- if (rotateStep == 0)
- return true;
+ public void incrementDirtyPages() {
+ if (metricsEnabled)
+ dirtyPages.increment();
+ }
- int subInts = this.subInts;
+ /**
+ * Decrements dirtyPages counter.
+ */
+ public void decrementDirtyPages() {
+ if (metricsEnabled)
+ dirtyPages.decrement();
+ }
- assert rotateStep < subInts;
+ /**
+ * Resets dirtyPages counter to zero.
+ */
+ public void resetDirtyPages() {
+ if (metricsEnabled)
+ dirtyPages.reset();
+ }
- int nextIdx = (idx + rotateStep) % subInts;
+ /**
+ * Increments totalAllocatedPages counter.
+ */
+ public void incrementTotalAllocatedPages() {
+ if (metricsEnabled) {
+ totalAllocatedPages.increment();
- return counterIdx.compareAndSet(idx, nextIdx);
+ updateAllocationRateMetrics();
+ }
}
/**
*
*/
- private void resetAll() {
- LongAdder8[] cntrs = allocRateCounters;
-
- for (LongAdder8 cntr : cntrs)
- cntr.reset();
+ private void updateAllocationRateMetrics() {
+ allocRate.onHit();
}
/**
- * @param currIdx Current index.
- * @param resettingCntrs Resetting allocRateCounters.
+ * @param intervalNum Interval number.
*/
- private void resetCounters(int currIdx, int resettingCntrs) {
- if (resettingCntrs == 0)
- return;
-
- for (int j = 0; j < resettingCntrs; j++) {
- int cleanIdx = currIdx - j >= 0 ? currIdx - j : currIdx - j + subInts;
-
- allocRateCounters[cleanIdx].reset();
- }
+ private long subInt(int intervalNum) {
+ return (rateTimeInterval * intervalNum) / subInts;
}
/**
@@ -277,10 +234,27 @@ public class MemoryMetricsImpl implements MemoryMetrics {
}
/**
+ * @param persistenceEnabled Persistence enabled.
+ */
+ public void persistenceEnabled(boolean persistenceEnabled) {
+ this.persistenceEnabled = persistenceEnabled;
+ }
+
+ /**
+ * @param pageMem Page mem.
+ */
+ public void pageMemory(PageMemory pageMem) {
+ this.pageMem = pageMem;
+ }
+
+ /**
* @param rateTimeInterval Time interval (in milliseconds) used to calculate allocation/eviction rate.
*/
public void rateTimeInterval(long rateTimeInterval) {
this.rateTimeInterval = rateTimeInterval;
+
+ allocRate = new HitRateMetrics((int) rateTimeInterval, subInts);
+ pageReplaceRate = new HitRateMetrics((int) rateTimeInterval, subInts);
}
/**
@@ -297,13 +271,8 @@ public class MemoryMetricsImpl implements MemoryMetrics {
if (rateTimeInterval / subInts < 10)
subInts = (int) rateTimeInterval / 10;
- LongAdder8[] newCounters = new LongAdder8[subInts];
-
- for (int i = 0; i < subInts; i++)
- newCounters[i] = new LongAdder8();
-
- this.subInts = subInts;
- allocRateCounters = newCounters;
+ allocRate = new HitRateMetrics((int) rateTimeInterval, subInts);
+ pageReplaceRate = new HitRateMetrics((int) rateTimeInterval, subInts);
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/fffad68f/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/MemoryMetricsMXBeanImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/MemoryMetricsMXBeanImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/MemoryMetricsMXBeanImpl.java
index d3ae378..b53db4b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/MemoryMetricsMXBeanImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/MemoryMetricsMXBeanImpl.java
@@ -67,6 +67,21 @@ class MemoryMetricsMXBeanImpl implements MemoryMetricsMXBean {
}
/** {@inheritDoc} */
+ @Override public long getDirtyPages() {
+ return memMetrics.getDirtyPages();
+ }
+
+ /** {@inheritDoc} */
+ @Override public float getPagesReplaceRate() {
+ return memMetrics.getPagesReplaceRate();
+ }
+
+ /** {@inheritDoc} */
+ @Override public long getPhysicalMemoryPages() {
+ return memMetrics.getPhysicalMemoryPages();
+ }
+
+ /** {@inheritDoc} */
@Override public void rateTimeInterval(long rateTimeInterval) {
if (rateTimeInterval < 1000)
throw new IllegalArgumentException("rateTimeInterval property must be positive " +
http://git-wip-us.apache.org/repos/asf/ignite/blob/fffad68f/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/MemoryMetricsSnapshot.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/MemoryMetricsSnapshot.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/MemoryMetricsSnapshot.java
index 5f337bd..f4874eb 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/MemoryMetricsSnapshot.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/MemoryMetricsSnapshot.java
@@ -41,6 +41,15 @@ public class MemoryMetricsSnapshot implements MemoryMetrics {
/** */
private float pagesFillFactor;
+ /** */
+ private long dirtyPages;
+
+ /** */
+ private float pageReplaceRate;
+
+ /** */
+ private long physicalMemoryPages;
+
/**
* @param metrics Metrics instance to take a copy.
*/
@@ -51,6 +60,9 @@ public class MemoryMetricsSnapshot implements MemoryMetrics {
evictionRate = metrics.getEvictionRate();
largeEntriesPagesPercentage = metrics.getLargeEntriesPagesPercentage();
pagesFillFactor = metrics.getPagesFillFactor();
+ dirtyPages = metrics.getDirtyPages();
+ pageReplaceRate = metrics.getPagesReplaceRate();
+ physicalMemoryPages = metrics.getPhysicalMemoryPages();
}
/** {@inheritDoc} */
@@ -82,4 +94,19 @@ public class MemoryMetricsSnapshot implements MemoryMetrics {
@Override public float getPagesFillFactor() {
return pagesFillFactor;
}
+
+ /** {@inheritDoc} */
+ @Override public long getDirtyPages() {
+ return dirtyPages;
+ }
+
+ /** {@inheritDoc} */
+ @Override public float getPagesReplaceRate() {
+ return pageReplaceRate;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long getPhysicalMemoryPages() {
+ return physicalMemoryPages;
+ }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/fffad68f/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/PersistenceMetricsSnapshot.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/PersistenceMetricsSnapshot.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/PersistenceMetricsSnapshot.java
new file mode 100644
index 0000000..c939710
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/PersistenceMetricsSnapshot.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ignite.internal.processors.cache.database;
+
+import org.apache.ignite.PersistenceMetrics;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ *
+ */
+public class PersistenceMetricsSnapshot implements PersistenceMetrics {
+ /** */
+ private float walLoggingRate;
+
+ /** */
+ private float walWritingRate;
+
+ /** */
+ private int walArchiveSegments;
+
+ /** */
+ private float walFsyncTimeAvg;
+
+ /** */
+ private long lastCpDuration;
+
+ /** */
+ private long lastCpLockWaitDuration;
+
+ /** */
+ private long lastCpMmarkDuration;
+
+ /** */
+ private long lastCpPagesWriteDuration;
+
+ /** */
+ private long lastCpFsyncDuration;
+
+ /** */
+ private long lastCpTotalPages;
+
+ /** */
+ private long lastCpDataPages;
+
+ /** */
+ private long lastCpCowPages;
+
+ /**
+ * @param metrics Metrics.
+ */
+ public PersistenceMetricsSnapshot(PersistenceMetrics metrics) {
+ walLoggingRate = metrics.getWalLoggingRate();
+ walWritingRate = metrics.getWalWritingRate();
+ walArchiveSegments = metrics.getWalArchiveSegments();
+ walFsyncTimeAvg = metrics.getWalFsyncTimeAverage();
+ lastCpDuration = metrics.getLastCheckpointingDuration();
+ lastCpLockWaitDuration = metrics.getLastCheckpointLockWaitDuration();
+ lastCpMmarkDuration = metrics.getLastCheckpointMarkDuration();
+ lastCpPagesWriteDuration = metrics.getLastCheckpointPagesWriteDuration();
+ lastCpFsyncDuration = metrics.getLastCheckpointFsyncDuration();
+ lastCpTotalPages = metrics.getLastCheckpointTotalPagesNumber();
+ lastCpDataPages = metrics.getLastCheckpointDataPagesNumber();
+ lastCpCowPages = metrics.getLastCheckpointCopiedOnWritePagesNumber();
+ }
+
+ /** {@inheritDoc} */
+ @Override public float getWalLoggingRate() {
+ return walLoggingRate;
+ }
+
+ /** {@inheritDoc} */
+ @Override public float getWalWritingRate() {
+ return walWritingRate;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int getWalArchiveSegments() {
+ return walArchiveSegments;
+ }
+
+ /** {@inheritDoc} */
+ @Override public float getWalFsyncTimeAverage() {
+ return walFsyncTimeAvg;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long getLastCheckpointingDuration() {
+ return lastCpDuration;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long getLastCheckpointLockWaitDuration() {
+ return lastCpLockWaitDuration;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long getLastCheckpointMarkDuration() {
+ return lastCpMmarkDuration;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long getLastCheckpointPagesWriteDuration() {
+ return lastCpPagesWriteDuration;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long getLastCheckpointFsyncDuration() {
+ return lastCpFsyncDuration;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long getLastCheckpointTotalPagesNumber() {
+ return lastCpTotalPages;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long getLastCheckpointDataPagesNumber() {
+ return lastCpDataPages;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long getLastCheckpointCopiedOnWritePagesNumber() {
+ return lastCpCowPages;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(PersistenceMetricsSnapshot.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/fffad68f/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/PageIO.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/PageIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/PageIO.java
index e40ed11..dd6a503 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/PageIO.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/PageIO.java
@@ -537,4 +537,12 @@ public abstract class PageIO {
throw new IgniteCheckedException("Unknown page IO type: " + type);
}
+
+ /**
+ * @param type Type to test.
+ * @return {@code True} if data page.
+ */
+ public static boolean isDataPageType(int type) {
+ return type == T_DATA;
+ }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/fffad68f/modules/core/src/main/java/org/apache/ignite/mxbean/MemoryMetricsMXBean.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/mxbean/MemoryMetricsMXBean.java b/modules/core/src/main/java/org/apache/ignite/mxbean/MemoryMetricsMXBean.java
index d0900f6..4d6c96a 100644
--- a/modules/core/src/main/java/org/apache/ignite/mxbean/MemoryMetricsMXBean.java
+++ b/modules/core/src/main/java/org/apache/ignite/mxbean/MemoryMetricsMXBean.java
@@ -73,6 +73,18 @@ public interface MemoryMetricsMXBean extends MemoryMetrics {
@MXBeanDescription("Percentage of space that is still free and can be filled in.")
@Override public float getPagesFillFactor();
+ /** {@inheritDoc} */
+ @MXBeanDescription("Number of pages in memory not yet synchronized with persistent storage.")
+ @Override public long getDirtyPages();
+
+ /** {@inheritDoc} */
+ @MXBeanDescription("Rate at which pages in memory are replaced with pages from persistent storage (pages per second).")
+ @Override public float getPagesReplaceRate();
+
+ /** {@inheritDoc} */
+ @MXBeanDescription("Number of pages residing in physical RAM.")
+ @Override public long getPhysicalMemoryPages();
+
/**
* Enables memory metrics collection on an Apache Ignite node.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/fffad68f/modules/core/src/main/java/org/apache/ignite/mxbean/PersistenceMetricsMXBean.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/mxbean/PersistenceMetricsMXBean.java b/modules/core/src/main/java/org/apache/ignite/mxbean/PersistenceMetricsMXBean.java
new file mode 100644
index 0000000..30ccab4
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/mxbean/PersistenceMetricsMXBean.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.mxbean;
+
+import org.apache.ignite.PersistenceMetrics;
+import org.apache.ignite.configuration.PersistentStoreConfiguration;
+
+/**
+ *
+ */
+public interface PersistenceMetricsMXBean extends PersistenceMetrics {
+ /** {@inheritDoc} */
+ @MXBeanDescription("Average number of WAL records per second written during the last time interval.")
+ @Override float getWalLoggingRate();
+
+ /** {@inheritDoc} */
+ @MXBeanDescription("Average number of bytes per second written during the last time interval.")
+ @Override float getWalWritingRate();
+
+ /** {@inheritDoc} */
+ @MXBeanDescription("Current number of WAL segments in the WAL archive.")
+ @Override int getWalArchiveSegments();
+
+ /** {@inheritDoc} */
+ @MXBeanDescription("Average WAL fsync duration in microseconds over the last time interval.")
+ @Override float getWalFsyncTimeAverage();
+
+ /** {@inheritDoc} */
+ @MXBeanDescription("Duration of the last checkpoint in milliseconds.")
+ @Override long getLastCheckpointingDuration();
+
+ /** {@inheritDoc} */
+ @MXBeanDescription("Duration of the checkpoint lock wait in milliseconds.")
+ @Override long getLastCheckpointLockWaitDuration();
+
+ /** {@inheritDoc} */
+ @MXBeanDescription("Duration of the checkpoint mark in milliseconds.")
+ @Override long getLastCheckpointMarkDuration();
+
+ /** {@inheritDoc} */
+ @MXBeanDescription("Duration of the checkpoint pages write in milliseconds.")
+ @Override long getLastCheckpointPagesWriteDuration();
+
+ /** {@inheritDoc} */
+ @MXBeanDescription("Duration of the sync phase of the last checkpoint in milliseconds.")
+ @Override long getLastCheckpointFsyncDuration();
+
+ /** {@inheritDoc} */
+ @MXBeanDescription("Total number of pages written during the last checkpoint.")
+ @Override long getLastCheckpointTotalPagesNumber();
+
+ /** {@inheritDoc} */
+ @MXBeanDescription("Total number of data pages written during the last checkpoint.")
+ @Override long getLastCheckpointDataPagesNumber();
+
+ /** {@inheritDoc} */
+ @MXBeanDescription("Number of pages copied to a temporary checkpoint buffer during the last checkpoint.")
+ @Override long getLastCheckpointCopiedOnWritePagesNumber();
+
+ /**
+ * Enables persistence metrics collection on an Apache Ignite node.
+ */
+ @MXBeanDescription("Enables persistence metrics collection on an Apache Ignite node.")
+ public void enableMetrics();
+
+ /**
+ * Disables persistence metrics collection on an Apache Ignite node.
+ */
+ @MXBeanDescription("Disables persistence metrics collection on an Apache Ignite node.")
+ public void disableMetrics();
+
+ /**
+ * Sets time interval for rate-based metrics. Identical to setting
+ * {@link PersistentStoreConfiguration#setRateTimeInterval(long)} configuration property.
+ *
+ * @param rateTimeInterval Time interval (in milliseconds) used for allocation and eviction rates calculations.
+ */
+ @MXBeanDescription(
+ "Sets time interval for pages allocation and eviction monitoring purposes."
+ )
+ @MXBeanParametersNames(
+ "rateTimeInterval"
+ )
+ @MXBeanParametersDescriptions(
+ "Time interval (in milliseconds) to set."
+ )
+ public void rateTimeInterval(long rateTimeInterval);
+
+ /**
+ * Sets a number of sub-intervals the whole {@link #rateTimeInterval(long)} will be split into to calculate
+ * rate-based metrics. Identical to setting {@link PersistentStoreConfiguration#setSubIntervals(int)} configuration
+ * property.
+ *
+ * @param subInts A number of sub-intervals.
+ */
+ @MXBeanDescription(
+ "Sets a number of sub-intervals to calculate allocation and eviction rates metrics."
+ )
+ @MXBeanParametersNames(
+ "subInts"
+ )
+ @MXBeanParametersDescriptions(
+ "Number of subintervals to set."
+ )
+ public void subIntervals(int subInts);
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/fffad68f/modules/core/src/test/java/org/apache/ignite/internal/processors/database/MemoryMetricsSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/MemoryMetricsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/MemoryMetricsSelfTest.java
index 706e717..3a99cb2 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/MemoryMetricsSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/MemoryMetricsSelfTest.java
@@ -66,7 +66,9 @@ public class MemoryMetricsSelfTest extends GridCommonAbstractTest {
joinAllThreads();
- assertEquals(4, watcher.rateDropsCntr);
+ assertTrue(watcher.rateDropsCntr > 3);
+
+ assertTrue(watcher.rateDropsCntr < 6);
}
/**
@@ -87,7 +89,9 @@ public class MemoryMetricsSelfTest extends GridCommonAbstractTest {
joinAllocationThreads();
- assertEquals(4, watcher.rateDropsCntr);
+ assertTrue(watcher.rateDropsCntr > 3);
+
+ assertTrue(watcher.rateDropsCntr < 6);
sleep(3);
@@ -150,7 +154,7 @@ public class MemoryMetricsSelfTest extends GridCommonAbstractTest {
for (int i = 0; i < 10; i++) {
Thread.sleep(25);
- memMetrics.subIntervals((2 + i * 5) % 3 + 1);
+ memMetrics.subIntervals((2 + i * 5) % 3 + 2);
}
joinAllThreads();
http://git-wip-us.apache.org/repos/asf/ignite/blob/fffad68f/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsIgniteMock.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsIgniteMock.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsIgniteMock.java
index b4fcc70..2f3a878 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsIgniteMock.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsIgniteMock.java
@@ -39,6 +39,7 @@ import org.apache.ignite.IgniteServices;
import org.apache.ignite.IgniteSet;
import org.apache.ignite.IgniteTransactions;
import org.apache.ignite.MemoryMetrics;
+import org.apache.ignite.PersistenceMetrics;
import org.apache.ignite.cache.affinity.Affinity;
import org.apache.ignite.cluster.ClusterGroup;
import org.apache.ignite.cluster.ClusterNode;
@@ -553,6 +554,13 @@ public class IgfsIgniteMock implements IgniteEx {
return null;
}
+ /** {@inheritDoc} */
+ @Override public PersistenceMetrics persistentStoreMetrics() {
+ throwUnsupported();
+
+ return null;
+ }
+
/**
* Throw {@link UnsupportedOperationException}.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/fffad68f/modules/core/src/test/java/org/apache/ignite/testframework/junits/IgniteMock.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/IgniteMock.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/IgniteMock.java
index 97157a8..709639e 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/IgniteMock.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/IgniteMock.java
@@ -46,6 +46,7 @@ import org.apache.ignite.IgniteServices;
import org.apache.ignite.IgniteSet;
import org.apache.ignite.IgniteTransactions;
import org.apache.ignite.MemoryMetrics;
+import org.apache.ignite.PersistenceMetrics;
import org.apache.ignite.binary.BinaryObjectBuilder;
import org.apache.ignite.binary.BinaryObjectException;
import org.apache.ignite.cache.affinity.Affinity;
@@ -452,6 +453,11 @@ public class IgniteMock implements Ignite {
return null;
}
+ /** {@inheritDoc} */
+ @Override public PersistenceMetrics persistentStoreMetrics() {
+ return null;
+ }
+
/**
* @param staticCfg Configuration.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/fffad68f/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/IgniteProcessProxy.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/IgniteProcessProxy.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/IgniteProcessProxy.java
index f4dc491..4fea480 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/IgniteProcessProxy.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/IgniteProcessProxy.java
@@ -50,6 +50,7 @@ import org.apache.ignite.IgniteServices;
import org.apache.ignite.IgniteSet;
import org.apache.ignite.IgniteTransactions;
import org.apache.ignite.MemoryMetrics;
+import org.apache.ignite.PersistenceMetrics;
import org.apache.ignite.cache.affinity.Affinity;
import org.apache.ignite.cluster.ClusterGroup;
import org.apache.ignite.cluster.ClusterNode;
@@ -670,6 +671,11 @@ public class IgniteProcessProxy implements IgniteEx {
}
/** {@inheritDoc} */
+ @Override public PersistenceMetrics persistentStoreMetrics() {
+ throw new UnsupportedOperationException("Operation isn't supported yet.");
+ }
+
+ /** {@inheritDoc} */
@Override public void close() throws IgniteException {
if (locJvmGrid != null) {
final CountDownLatch rmtNodeStoppedLatch = new CountDownLatch(1);
http://git-wip-us.apache.org/repos/asf/ignite/blob/fffad68f/modules/pds/src/main/java/org/apache/ignite/internal/processors/cache/database/GridCacheDatabaseSharedManager.java
----------------------------------------------------------------------
diff --git a/modules/pds/src/main/java/org/apache/ignite/internal/processors/cache/database/GridCacheDatabaseSharedManager.java b/modules/pds/src/main/java/org/apache/ignite/internal/processors/cache/database/GridCacheDatabaseSharedManager.java
index 9f51750..ff5dfa9 100755
--- a/modules/pds/src/main/java/org/apache/ignite/internal/processors/cache/database/GridCacheDatabaseSharedManager.java
+++ b/modules/pds/src/main/java/org/apache/ignite/internal/processors/cache/database/GridCacheDatabaseSharedManager.java
@@ -57,10 +57,15 @@ import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import javax.management.InstanceNotFoundException;
+import javax.management.JMException;
+import javax.management.MBeanRegistrationException;
+import javax.management.ObjectName;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteException;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.IgniteSystemProperties;
+import org.apache.ignite.PersistenceMetrics;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.DataPageEvictionMode;
import org.apache.ignite.configuration.IgniteConfiguration;
@@ -101,6 +106,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
import org.apache.ignite.internal.processors.cache.StoredCacheData;
import org.apache.ignite.internal.processors.cache.database.file.FilePageStoreManager;
+import org.apache.ignite.internal.processors.cache.database.pagemem.CheckpointMetricsTracker;
import org.apache.ignite.internal.processors.cache.database.pagemem.PageMemoryEx;
import org.apache.ignite.internal.processors.cache.database.pagemem.PageMemoryImpl;
import org.apache.ignite.internal.processors.cache.database.tree.io.PageIO;
@@ -127,6 +133,7 @@ import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.internal.util.worker.GridWorker;
import org.apache.ignite.lang.IgniteBiTuple;
import org.apache.ignite.lang.IgniteInClosure;
+import org.apache.ignite.mxbean.PersistenceMetricsMXBean;
import org.apache.ignite.thread.IgniteThread;
import org.jetbrains.annotations.Nullable;
@@ -235,7 +242,7 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
private volatile boolean printCheckpointStats = true;
/** Database configuration. */
- private final PersistentStoreConfiguration dbCfg;
+ private final PersistentStoreConfiguration persistenceCfg;
/** */
private final Collection<DbCheckpointListener> lsnrs = new CopyOnWriteArrayList<>();
@@ -270,19 +277,25 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
/** Snapshot manager. */
private IgniteCacheSnapshotManager snapshotMgr;
+ /** */
+ private PersistenceMetricsImpl persStoreMetrics;
+
+ /** */
+ private ObjectName persistenceMetricsMbeanName;
+
/**
* @param ctx Kernal context.
*/
public GridCacheDatabaseSharedManager(GridKernalContext ctx) {
IgniteConfiguration cfg = ctx.config();
- dbCfg = cfg.getPersistentStoreConfiguration();
+ persistenceCfg = cfg.getPersistentStoreConfiguration();
- assert dbCfg != null : "PageStore should not be created if persistence is disabled.";
+ assert persistenceCfg != null : "PageStore should not be created if persistence is disabled.";
- checkpointFreq = dbCfg.getCheckpointingFrequency();
+ checkpointFreq = persistenceCfg.getCheckpointingFrequency();
- lockWaitTime = dbCfg.getLockWaitTime();
+ lockWaitTime = persistenceCfg.getLockWaitTime();
final int pageSize = cfg.getMemoryConfiguration().getPageSize();
@@ -296,6 +309,12 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
return tmpWriteBuf;
}
};
+
+ persStoreMetrics = new PersistenceMetricsImpl(
+ persistenceCfg.isMetricsEnabled(),
+ persistenceCfg.getRateTimeInterval(),
+ persistenceCfg.getSubIntervals()
+ );
}
/**
@@ -339,6 +358,21 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
throw new IgniteCheckedException("Could not create directory for checkpoint metadata: " + cpDir);
fileLockHolder = new FileLockHolder(storeMgr.workDir().getPath(), cctx.kernalContext(), log);
+
+ persStoreMetrics.wal(cctx.wal());
+
+ try {
+ persistenceMetricsMbeanName = U.registerMBean(
+ cctx.kernalContext().config().getMBeanServer(),
+ cctx.kernalContext().igniteInstanceName(),
+ "Persistent Store",
+ "PersistenceMetrics",
+ persStoreMetrics,
+ PersistenceMetricsMXBean.class);
+ }
+ catch (JMException e) {
+ throw new IgniteCheckedException("Failed to register persistence metrics MBean", e);
+ }
}
}
@@ -346,19 +380,19 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
*
*/
@Override public void initDataBase() throws IgniteCheckedException {
- Long cpBufSize = dbCfg.getCheckpointingPageBufferSize();
+ Long cpBufSize = persistenceCfg.getCheckpointingPageBufferSize();
- if (dbCfg.getCheckpointingThreads() > 1)
+ if (persistenceCfg.getCheckpointingThreads() > 1)
asyncRunner = new ThreadPoolExecutor(
- dbCfg.getCheckpointingThreads(),
- dbCfg.getCheckpointingThreads(),
+ persistenceCfg.getCheckpointingThreads(),
+ persistenceCfg.getCheckpointingThreads(),
30L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>()
);
// Intentionally use identity comparison to check if configuration default has changed.
- // Noinspection NumberEquality.
+ //noinspection NumberEquality
if (cpBufSize == PersistentStoreConfiguration.DFLT_CHECKPOINTING_PAGE_BUFFER_SIZE) {
MemoryConfiguration memCfg = cctx.kernalContext().config().getMemoryConfiguration();
@@ -544,6 +578,18 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
fileLockHolder.close();
}
+
+ if (persistenceMetricsMbeanName != null) {
+ try {
+ cctx.kernalContext().config().getMBeanServer().unregisterMBean(persistenceMetricsMbeanName);
+ }
+ catch (InstanceNotFoundException ignore) {
+ // No-op, nothing to unregister.
+ }
+ catch (MBeanRegistrationException e) {
+ U.error(log, "Failed to unregister persistence metrics MBean (will continue stop routine)", e);
+ }
+ }
}
/** {@inheritDoc} */
@@ -580,7 +626,9 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
MemoryPolicyConfiguration plcCfg,
MemoryMetricsImpl memMetrics
) {
- return new PageMemoryImpl(
+ memMetrics.persistenceEnabled(true);
+
+ PageMemoryImpl pageMem = new PageMemoryImpl(
memProvider,
calculateFragmentSizes(
memCfg.getConcurrencyLevel(),
@@ -599,17 +647,22 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
snapshotMgr.flushDirtyPageHandler(fullId, pageBuf, tag);
}
},
- new GridInClosure3X<Long,FullPageId, PageMemoryEx>() {
+ new GridInClosure3X<Long, FullPageId, PageMemoryEx>() {
@Override public void applyx(
Long page,
FullPageId fullId,
PageMemoryEx pageMem
) throws IgniteCheckedException {
- snapshotMgr.onChangeTrackerPage(page, fullId, pageMem);
+ snapshotMgr.onChangeTrackerPage(page, fullId, pageMem);
}
},
- this
+ this,
+ memMetrics
);
+
+ memMetrics.pageMemory(pageMem);
+
+ return pageMem;
}
/** {@inheritDoc} */
@@ -1074,8 +1127,6 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
cp.cancelOrWaitPartitionDestroy(grpId, partId);
}
-
-
/**
* Tries to search for a WAL pointer for the given partition counter start.
*
@@ -1656,7 +1707,7 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
for (FullPageId fullId : cpPages) {
tmpWriteBuf.rewind();
- Integer tag = pageMem.getForCheckpoint(fullId, tmpWriteBuf);
+ Integer tag = pageMem.getForCheckpoint(fullId, tmpWriteBuf, null);
if (tag != null) {
tmpWriteBuf.rewind();
@@ -1969,14 +2020,12 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
*/
private void doCheckpoint() {
try {
- long start = U.currentTimeMillis();
+ CheckpointMetricsTracker tracker = new CheckpointMetricsTracker();
- Checkpoint chp = markCheckpointBegin();
+ Checkpoint chp = markCheckpointBegin(tracker);
snapshotMgr.onCheckPointBegin();
- long written, fsync, marked = U.currentTimeMillis();
-
int pages = chp.cpPages.size();
boolean interrupted = true;
@@ -1988,9 +2037,12 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
CountDownFuture doneWriteFut = new CountDownFuture(
asyncRunner == null ? 1 : chp.cpPages.collectionsSize());
+ tracker.onPagesWriteStart();
+
if (asyncRunner != null) {
for (int i = 0; i < chp.cpPages.collectionsSize(); i++) {
Runnable write = new WriteCheckpointPages(
+ tracker,
chp.cpPages.innerCollection(i),
updStores,
doneWriteFut
@@ -2007,7 +2059,7 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
}
else {
// Single-threaded checkpoint.
- Runnable write = new WriteCheckpointPages(chp.cpPages, updStores, doneWriteFut);
+ Runnable write = new WriteCheckpointPages(tracker, chp.cpPages, updStores, doneWriteFut);
write.run();
}
@@ -2022,7 +2074,7 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
snapshotMgr.afterCheckpointPageWritten();
- written = U.currentTimeMillis();
+ tracker.onFsyncStart();
if (!skipSync) {
for (PageStore updStore : updStores) {
@@ -2033,8 +2085,6 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
}
}
- fsync = U.currentTimeMillis();
-
// Must mark successful checkpoint only if there are no exceptions or interrupts.
interrupted = false;
}
@@ -2043,7 +2093,7 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
markCheckpointEnd(chp);
}
- long fsyncEnd = U.currentTimeMillis();
+ tracker.onEnd();
// We finished this checkpoint, now it's time to clean up partitions.
PartitionDestroyQueue destroyQueue = chp.progress.destroyQueue;
@@ -2073,19 +2123,30 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
finishDestroyPartitionsAsync(reqs);
}
- if (printCheckpointStats)
- log.info(String.format("Checkpoint finished [cpId=%s, pages=%d, markPos=%s, " +
- "walSegmentsCleared=%d, markBegin=%dms, pagesWrite=%dms, fsync=%dms, markEnd=%dms, " +
- "total=%dms]",
- chp.cpEntry.checkpointId(),
- pages,
- chp.cpEntry.checkpointMark(),
- chp.walFilesDeleted,
- marked - start,
- written - marked,
- fsync - written,
- fsyncEnd - fsync,
- fsyncEnd - start));
+ if (printCheckpointStats) {
+ if (log.isInfoEnabled())
+ log.info(String.format("Checkpoint finished [cpId=%s, pages=%d, markPos=%s, " +
+ "walSegmentsCleared=%d, markDuration=%dms, pagesWrite=%dms, fsync=%dms, " +
+ "total=%dms]",
+ chp.cpEntry.checkpointId(),
+ pages,
+ chp.cpEntry.checkpointMark(),
+ chp.walFilesDeleted,
+ tracker.markDuration(),
+ tracker.pagesWriteDuration(),
+ tracker.fsyncDuration(),
+ tracker.totalDuration()));
+ }
+
+ persStoreMetrics.onCheckpoint(
+ tracker.lockWaitDuration(),
+ tracker.markDuration(),
+ tracker.pagesWriteDuration(),
+ tracker.fsyncDuration(),
+ tracker.totalDuration(),
+ pages,
+ tracker.dataPagesWritten(),
+ tracker.cowPagesWritten());
}
catch (IgniteCheckedException e) {
// TODO-ignite-db how to handle exception?
@@ -2127,21 +2188,21 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
*
*/
@SuppressWarnings("TooBroadScope")
- private Checkpoint markCheckpointBegin() throws IgniteCheckedException {
+ private Checkpoint markCheckpointBegin(CheckpointMetricsTracker tracker) throws IgniteCheckedException {
CheckpointRecord cpRec = new CheckpointRecord(null, false);
WALPointer cpPtr;
GridMultiCollectionWrapper<FullPageId> cpPages;
- long lockAcquired, lockReleased, lockStart = U.currentTimeMillis();
-
final CheckpointProgress curr;
+ tracker.onLockWaitStart();
+
checkpointLock.writeLock().lock();
try {
- lockAcquired = U.currentTimeMillis();
+ tracker.onMarkStart();
synchronized (this) {
curr = scheduledCp;
@@ -2210,7 +2271,7 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
finally {
checkpointLock.writeLock().unlock();
- lockReleased = U.currentTimeMillis();
+ tracker.onLockRelease();
}
curr.cpBeginFut.onDone();
@@ -2236,8 +2297,8 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
"checkpointLockHoldTime=%dms, pages=%d, reason='%s']",
cpRec.checkpointId(),
cpPtr,
- lockAcquired - lockStart,
- lockReleased - lockAcquired,
+ tracker.lockWaitDuration(),
+ tracker.lockHoldDuration(),
cpPages.size(),
curr.reason)
);
@@ -2315,6 +2376,9 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
*/
private class WriteCheckpointPages implements Runnable {
/** */
+ private CheckpointMetricsTracker tracker;
+
+ /** */
private Collection<FullPageId> writePageIds;
/** */
@@ -2327,10 +2391,12 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
* @param writePageIds Write page IDs.
*/
private WriteCheckpointPages(
+ CheckpointMetricsTracker tracker,
Collection<FullPageId> writePageIds,
GridConcurrentHashSet<PageStore> updStores,
CountDownFuture doneFut
) {
+ this.tracker = tracker;
this.writePageIds = writePageIds;
this.updStores = updStores;
this.doneFut = doneFut;
@@ -2362,11 +2428,18 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
PageMemoryEx pageMem = (PageMemoryEx)grp.memoryPolicy().pageMemory();
- Integer tag = pageMem.getForCheckpoint(fullId, tmpWriteBuf);
+ Integer tag = pageMem.getForCheckpoint(fullId, tmpWriteBuf, persStoreMetrics.metricsEnabled() ? tracker : null);
if (tag != null) {
tmpWriteBuf.rewind();
+ if (persStoreMetrics.metricsEnabled()) {
+ int pageType = PageIO.getType(tmpWriteBuf);
+
+ if (PageIO.isDataPageType(pageType))
+ tracker.onDataPageWritten();
+ }
+
if (!skipCrc) {
PageIO.setCrc(writeAddr, PureJavaCrc32.calcCrc32(tmpWriteBuf, pageSize()));
@@ -2488,7 +2561,7 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
/**
*
*/
- public static class CheckpointProgress {
+ private static class CheckpointProgress {
/** */
private volatile long nextCpTs;
@@ -2499,13 +2572,13 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
private GridFutureAdapter cpFinishFut = new GridFutureAdapter<>();
/** */
- public volatile boolean nextSnapshot;
+ private volatile boolean nextSnapshot;
/** */
private volatile boolean started;
/** */
- public volatile SnapshotOperation snapshotOperation;
+ private volatile SnapshotOperation snapshotOperation;
/** Wakeup reason. */
private String reason;
@@ -2629,7 +2702,7 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
private int onCheckpointFinished() {
int deleted = 0;
- while (histMap.size() > dbCfg.getWalHistorySize()) {
+ while (histMap.size() > persistenceCfg.getWalHistorySize()) {
Map.Entry<Long, CheckpointEntry> entry = histMap.firstEntry();
CheckpointEntry cpEntry = entry.getValue();
@@ -2649,7 +2722,7 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
U.warn(log, "Failed to remove stale checkpoint files [startFile=" + startFile.getAbsolutePath() +
", endFile=" + endFile.getAbsolutePath() + ']');
- if (histMap.size() > 2 * dbCfg.getWalHistorySize()) {
+ if (histMap.size() > 2 * persistenceCfg.getWalHistorySize()) {
U.error(log, "Too many stale checkpoint entries in the map, will truncate WAL archive anyway.");
fail = false;
@@ -3178,4 +3251,16 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
return file.getAbsolutePath();
}
}
+
+ /** {@inheritDoc} */
+ @Override public PersistenceMetrics persistentStoreMetrics() {
+ return new PersistenceMetricsSnapshot(persStoreMetrics);
+ }
+
+ /**
+ *
+ */
+ public PersistenceMetricsImpl persistentStoreMetricsImpl() {
+ return persStoreMetrics;
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/fffad68f/modules/pds/src/main/java/org/apache/ignite/internal/processors/cache/database/PersistenceMetricsImpl.java
----------------------------------------------------------------------
diff --git a/modules/pds/src/main/java/org/apache/ignite/internal/processors/cache/database/PersistenceMetricsImpl.java b/modules/pds/src/main/java/org/apache/ignite/internal/processors/cache/database/PersistenceMetricsImpl.java
new file mode 100644
index 0000000..25d95ae
--- /dev/null
+++ b/modules/pds/src/main/java/org/apache/ignite/internal/processors/cache/database/PersistenceMetricsImpl.java
@@ -0,0 +1,297 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ignite.internal.processors.cache.database;
+
+import org.apache.ignite.internal.pagemem.wal.IgniteWriteAheadLogManager;
+import org.apache.ignite.internal.processors.cache.ratemetrics.HitRateMetrics;
+import org.apache.ignite.mxbean.PersistenceMetricsMXBean;
+
+/**
+ *
+ */
+public class PersistenceMetricsImpl implements PersistenceMetricsMXBean {
+ /** */
+ private volatile HitRateMetrics walLoggingRate;
+
+ /** */
+ private volatile HitRateMetrics walWritingRate;
+
+ /** */
+ private volatile HitRateMetrics walFsyncTimeDuration;
+
+ /** */
+ private volatile HitRateMetrics walFsyncTimeNumber;
+
+ /** */
+ private volatile long lastCpLockWaitDuration;
+
+ /** */
+ private volatile long lastCpMarkDuration;
+
+ /** */
+ private volatile long lastCpPagesWriteDuration;
+
+ /** */
+ private volatile long lastCpDuration;
+
+ /** */
+ private volatile long lastCpFsyncDuration;
+
+ /** */
+ private volatile long lastCpTotalPages;
+
+ /** */
+ private volatile long lastCpDataPages;
+
+ /** */
+ private volatile long lastCpCowPages;
+
+ /** */
+ private volatile long rateTimeInterval;
+
+ /** */
+ private volatile int subInts;
+
+ /** */
+ private volatile boolean metricsEnabled;
+
+ /** */
+ private IgniteWriteAheadLogManager wal;
+
+ /**
+ * @param metricsEnabled Metrics enabled flag.
+ * @param rateTimeInterval Rate time interval.
+ * @param subInts Number of sub-intervals.
+ */
+ public PersistenceMetricsImpl(
+ boolean metricsEnabled,
+ long rateTimeInterval,
+ int subInts
+ ) {
+ this.metricsEnabled = metricsEnabled;
+ this.rateTimeInterval = rateTimeInterval;
+ this.subInts = subInts;
+
+ resetRates();
+ }
+
+ /** {@inheritDoc} */
+ @Override public float getWalLoggingRate() {
+ if (!metricsEnabled)
+ return 0;
+
+ return ((float)walLoggingRate.getRate()) / rateTimeInterval;
+ }
+
+ /** {@inheritDoc} */
+ @Override public float getWalWritingRate() {
+ if (!metricsEnabled)
+ return 0;
+
+ return ((float)walWritingRate.getRate()) / rateTimeInterval;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int getWalArchiveSegments() {
+ if (!metricsEnabled)
+ return 0;
+
+ return wal.walArchiveSegments();
+ }
+
+ /** {@inheritDoc} */
+ @Override public float getWalFsyncTimeAverage() {
+ if (!metricsEnabled)
+ return 0;
+
+ long numRate = walFsyncTimeNumber.getRate();
+
+ if (numRate == 0)
+ return 0;
+
+ return (float)walFsyncTimeDuration.getRate() / numRate;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long getLastCheckpointingDuration() {
+ if (!metricsEnabled)
+ return 0;
+
+ return lastCpDuration;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long getLastCheckpointLockWaitDuration() {
+ if (!metricsEnabled)
+ return 0;
+
+ return lastCpLockWaitDuration;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long getLastCheckpointMarkDuration() {
+ if (!metricsEnabled)
+ return 0;
+
+ return lastCpMarkDuration;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long getLastCheckpointPagesWriteDuration() {
+ if (!metricsEnabled)
+ return 0;
+
+ return lastCpPagesWriteDuration;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long getLastCheckpointFsyncDuration() {
+ if (!metricsEnabled)
+ return 0;
+
+ return lastCpFsyncDuration;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long getLastCheckpointTotalPagesNumber() {
+ if (!metricsEnabled)
+ return 0;
+
+ return lastCpTotalPages;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long getLastCheckpointDataPagesNumber() {
+ if (!metricsEnabled)
+ return 0;
+
+ return lastCpDataPages;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long getLastCheckpointCopiedOnWritePagesNumber() {
+ if (!metricsEnabled)
+ return 0;
+
+ return lastCpCowPages;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void enableMetrics() {
+ metricsEnabled = true;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void disableMetrics() {
+ metricsEnabled = false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void rateTimeInterval(long rateTimeInterval) {
+ this.rateTimeInterval = rateTimeInterval;
+
+ resetRates();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void subIntervals(int subInts) {
+ this.subInts = subInts;
+
+ resetRates();
+ }
+
+ /**
+ * @param wal Write-ahead log manager.
+ */
+ public void wal(IgniteWriteAheadLogManager wal) {
+ this.wal = wal;
+ }
+
+ /**
+ * @return Metrics enabled flag.
+ */
+ public boolean metricsEnabled() {
+ return metricsEnabled;
+ }
+
+ /**
+ * @param lockWaitDuration Lock wait duration.
+ * @param markDuration Mark duration.
+ * @param pagesWriteDuration Pages write duration.
+ * @param fsyncDuration Total checkpoint fsync duration.
+ * @param duration Total checkpoint duration.
+ * @param totalPages Total number of all pages in checkpoint.
+ * @param dataPages Total number of data pages in checkpoint.
+ * @param cowPages Total number of COW-ed pages in checkpoint.
+ */
+ public void onCheckpoint(
+ long lockWaitDuration,
+ long markDuration,
+ long pagesWriteDuration,
+ long fsyncDuration,
+ long duration,
+ long totalPages,
+ long dataPages,
+ long cowPages
+ ) {
+ if (metricsEnabled) {
+ lastCpLockWaitDuration = lockWaitDuration;
+ lastCpMarkDuration = markDuration;
+ lastCpPagesWriteDuration = pagesWriteDuration;
+ lastCpFsyncDuration = fsyncDuration;
+ lastCpDuration = duration;
+ lastCpTotalPages = totalPages;
+ lastCpDataPages = dataPages;
+ lastCpCowPages = cowPages;
+ }
+ }
+
+ /**
+ *
+ */
+ public void onWalRecordLogged() {
+ walLoggingRate.onHit();
+ }
+
+ /**
+ * @param size Size written.
+ */
+ public void onWalBytesWritten(int size) {
+ walWritingRate.onHits(size);
+ }
+
+ /**
+ * @param nanoTime Fsync nano time.
+ */
+ public void onFsync(long nanoTime) {
+ long microseconds = nanoTime / 1_000;
+
+ walFsyncTimeDuration.onHits(microseconds);
+ walFsyncTimeNumber.onHit();
+ }
+
+ /**
+ *
+ */
+ private void resetRates() {
+ walLoggingRate = new HitRateMetrics((int)rateTimeInterval, subInts);
+ walWritingRate = new HitRateMetrics((int)rateTimeInterval, subInts);
+
+ walFsyncTimeDuration = new HitRateMetrics((int)rateTimeInterval, subInts);
+ walFsyncTimeNumber = new HitRateMetrics((int)rateTimeInterval, subInts);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/fffad68f/modules/pds/src/main/java/org/apache/ignite/internal/processors/cache/database/pagemem/CheckpointMetricsTracker.java
----------------------------------------------------------------------
diff --git a/modules/pds/src/main/java/org/apache/ignite/internal/processors/cache/database/pagemem/CheckpointMetricsTracker.java b/modules/pds/src/main/java/org/apache/ignite/internal/processors/cache/database/pagemem/CheckpointMetricsTracker.java
new file mode 100644
index 0000000..e6b88d3
--- /dev/null
+++ b/modules/pds/src/main/java/org/apache/ignite/internal/processors/cache/database/pagemem/CheckpointMetricsTracker.java
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.database.pagemem;
+
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+
+/**
+ * Tracks various checkpoint phases and stats.
+ *
+ * Assumed sequence of events:
+ * <ol>
+ * <li>Checkpoint start</li>
+ * <li>CP Lock wait start</li>
+ * <li>CP mark start</li>
+ * <li>CP Lock release</li>
+ * <li>Pages write start</li>
+ * <li>fsync start</li>
+ * <li>Checkpoint end</li>
+ * </ol>
+ */
+public class CheckpointMetricsTracker {
+ /** */
+ private static final AtomicIntegerFieldUpdater<CheckpointMetricsTracker> DATA_PAGES_UPDATER =
+ AtomicIntegerFieldUpdater.newUpdater(CheckpointMetricsTracker.class, "dataPages");
+
+ /** */
+ private static final AtomicIntegerFieldUpdater<CheckpointMetricsTracker> COW_PAGES_UPDATER =
+ AtomicIntegerFieldUpdater.newUpdater(CheckpointMetricsTracker.class, "cowPages");
+
+ /** */
+ private volatile int dataPages;
+
+ /** */
+ private volatile int cowPages;
+
+ /** */
+ private long cpStart = System.currentTimeMillis();
+
+ /** */
+ private long cpLockWaitStart;
+
+ /** */
+ private long cpMarkStart;
+
+ /** */
+ private long cpLockRelease;
+
+ /** */
+ private long cpPagesWriteStart;
+
+ /** */
+ private long cpFsyncStart;
+
+ /** */
+ private long cpEnd;
+
+ /**
+ *
+ */
+ public void onCowPageWritten() {
+ COW_PAGES_UPDATER.incrementAndGet(this);
+ }
+
+ /**
+ *
+ */
+ public void onDataPageWritten() {
+ DATA_PAGES_UPDATER.incrementAndGet(this);
+ }
+
+ /**
+ * @return COW pages.
+ */
+ public int cowPagesWritten() {
+ return cowPages;
+ }
+
+ /**
+ * @return Data pages written.
+ */
+ public int dataPagesWritten() {
+ return dataPages;
+ }
+
+ /**
+ *
+ */
+ public void onLockWaitStart() {
+ cpLockWaitStart = System.currentTimeMillis();
+ }
+
+ /**
+ *
+ */
+ public void onMarkStart() {
+ cpMarkStart = System.currentTimeMillis();
+ }
+
+ /**
+ *
+ */
+ public void onLockRelease() {
+ cpLockRelease = System.currentTimeMillis();
+ }
+
+ /**
+ *
+ */
+ public void onPagesWriteStart() {
+ cpPagesWriteStart = System.currentTimeMillis();
+ }
+
+ /**
+ *
+ */
+ public void onFsyncStart() {
+ cpFsyncStart = System.currentTimeMillis();
+ }
+
+ /**
+ *
+ */
+ public void onEnd() {
+ cpEnd = System.currentTimeMillis();
+ }
+
+ /**
+ * @return Total checkpoint duration.
+ */
+ public long totalDuration() {
+ return cpEnd - cpStart;
+ }
+
+ /**
+ * @return Checkpoint lock wait duration.
+ */
+ public long lockWaitDuration() {
+ return cpMarkStart - cpLockWaitStart;
+ }
+
+ /**
+ * @return Checkpoint mark duration.
+ */
+ public long markDuration() {
+ return cpPagesWriteStart - cpMarkStart;
+ }
+
+ /**
+ * @return Checkpoint lock hold duration.
+ */
+ public long lockHoldDuration() {
+ return cpLockRelease - cpMarkStart;
+ }
+
+ /**
+ * @return Pages write duration.
+ */
+ public long pagesWriteDuration() {
+ return cpFsyncStart - cpPagesWriteStart;
+ }
+
+ /**
+ * @return Checkpoint fsync duration.
+ */
+ public long fsyncDuration() {
+ return cpEnd - cpFsyncStart;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/fffad68f/modules/pds/src/main/java/org/apache/ignite/internal/processors/cache/database/pagemem/PageMemoryEx.java
----------------------------------------------------------------------
diff --git a/modules/pds/src/main/java/org/apache/ignite/internal/processors/cache/database/pagemem/PageMemoryEx.java b/modules/pds/src/main/java/org/apache/ignite/internal/processors/cache/database/pagemem/PageMemoryEx.java
index ef84d83..56d1be9 100644
--- a/modules/pds/src/main/java/org/apache/ignite/internal/processors/cache/database/pagemem/PageMemoryEx.java
+++ b/modules/pds/src/main/java/org/apache/ignite/internal/processors/cache/database/pagemem/PageMemoryEx.java
@@ -116,10 +116,11 @@ public interface PageMemoryEx extends PageMemory {
* @param pageId Page ID to get byte buffer for. The page ID must be present in the collection returned by
* the {@link #beginCheckpoint()} method call.
* @param tmpBuf Temporary buffer to write changes into.
+ * @param tracker Checkpoint metrics tracker.
* @return {@code True} if data were read, {@code false} otherwise (data already saved to storage).
* @throws IgniteException If failed to obtain page data.
*/
- @Nullable public Integer getForCheckpoint(FullPageId pageId, ByteBuffer tmpBuf);
+ @Nullable public Integer getForCheckpoint(FullPageId pageId, ByteBuffer tmpBuf, CheckpointMetricsTracker tracker);
/**
* Marks partition as invalid / outdated.