blob: 75a35205828881a373a732cbea3603aa6a59cb67 [file] [log] [blame]
/*-
* Copyright (C) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This file was distributed by Oracle as part of a version of Oracle Berkeley
* DB Java Edition made available at:
*
* http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html
*
* Please see the LICENSE file included in the top-level directory of the
* appropriate version of Oracle Berkeley DB Java Edition for a copy of the
* license and additional information.
*/
package com.sleepycat.je.rep;
import static com.sleepycat.je.rep.impl.node.FeederManagerStatDefinition.N_FEEDERS_CREATED;
import static com.sleepycat.je.rep.impl.node.FeederManagerStatDefinition.N_FEEDERS_SHUTDOWN;
import static com.sleepycat.je.rep.impl.node.FeederManagerStatDefinition.REPLICA_95_DELAY_MS_MAP;
import static com.sleepycat.je.rep.impl.node.FeederManagerStatDefinition.REPLICA_99_DELAY_MS_MAP;
import static com.sleepycat.je.rep.impl.node.FeederManagerStatDefinition.REPLICA_AVG_DELAY_MS_MAP;
import static com.sleepycat.je.rep.impl.node.FeederManagerStatDefinition.REPLICA_DELAY_MAP;
import static com.sleepycat.je.rep.impl.node.FeederManagerStatDefinition.REPLICA_LAST_COMMIT_TIMESTAMP_MAP;
import static com.sleepycat.je.rep.impl.node.FeederManagerStatDefinition.REPLICA_LAST_COMMIT_VLSN_MAP;
import static com.sleepycat.je.rep.impl.node.FeederManagerStatDefinition.REPLICA_MAX_DELAY_MS_MAP;
import static com.sleepycat.je.rep.impl.node.FeederManagerStatDefinition.REPLICA_VLSN_LAG_MAP;
import static com.sleepycat.je.rep.impl.node.FeederManagerStatDefinition.REPLICA_VLSN_RATE_MAP;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.ELAPSED_TXN_95_MS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.ELAPSED_TXN_99_MS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.ELAPSED_TXN_AVG_MS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.ELAPSED_TXN_MAX_MS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.LATEST_COMMIT_LAG_MS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.MAX_COMMIT_PROCESSING_NANOS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.MIN_COMMIT_PROCESSING_NANOS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_ABORTS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_COMMITS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_COMMIT_ACKS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_COMMIT_NO_SYNCS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_COMMIT_SYNCS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_COMMIT_WRITE_NO_SYNCS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_GROUP_COMMITS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_GROUP_COMMIT_MAX_EXCEEDED;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_GROUP_COMMIT_TIMEOUTS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_GROUP_COMMIT_TXNS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_LNS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_NAME_LNS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.OUTPUT_QUEUE_95_DELAY_MS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.OUTPUT_QUEUE_99_DELAY_MS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.OUTPUT_QUEUE_AVG_DELAY_MS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.OUTPUT_QUEUE_MAX_DELAY_MS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.REPLAY_QUEUE_95_DELAY_MS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.REPLAY_QUEUE_99_DELAY_MS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.REPLAY_QUEUE_AVG_DELAY_MS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.REPLAY_QUEUE_MAX_DELAY_MS;
import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.TOTAL_COMMIT_PROCESSING_NANOS;
import static com.sleepycat.je.rep.impl.node.ReplicaStatDefinition.N_LAG_CONSISTENCY_WAITS;
import static com.sleepycat.je.rep.impl.node.ReplicaStatDefinition.N_LAG_CONSISTENCY_WAIT_MS;
import static com.sleepycat.je.rep.impl.node.ReplicaStatDefinition.N_VLSN_CONSISTENCY_WAITS;
import static com.sleepycat.je.rep.impl.node.ReplicaStatDefinition.N_VLSN_CONSISTENCY_WAIT_MS;
import static com.sleepycat.je.rep.stream.FeederTxnStatDefinition.ACK_WAIT_MS;
import static com.sleepycat.je.rep.stream.FeederTxnStatDefinition.LAST_COMMIT_TIMESTAMP;
import static com.sleepycat.je.rep.stream.FeederTxnStatDefinition.LAST_COMMIT_VLSN;
import static com.sleepycat.je.rep.stream.FeederTxnStatDefinition.TOTAL_TXN_MS;
import static com.sleepycat.je.rep.stream.FeederTxnStatDefinition.TXNS_ACKED;
import static com.sleepycat.je.rep.stream.FeederTxnStatDefinition.TXNS_NOT_ACKED;
import static com.sleepycat.je.rep.stream.FeederTxnStatDefinition.VLSN_RATE;
import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.BYTES_READ_RATE;
import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.BYTES_WRITE_RATE;
import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.MESSAGE_READ_RATE;
import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.MESSAGE_WRITE_RATE;
import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.N_BYTES_READ;
import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.N_BYTES_WRITTEN;
import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.N_ENTRIES_WRITTEN_OLD_VERSION;
import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.N_MESSAGES_BATCHED;
import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.N_MESSAGES_READ;
import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.N_MESSAGES_WRITTEN;
import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.N_MESSAGE_BATCHES;
import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.N_READ_NANOS;
import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.N_WRITE_NANOS;
import static com.sleepycat.je.utilint.CollectionUtils.emptySortedMap;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import com.sleepycat.je.Durability.ReplicaAckPolicy;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentFailureException;
import com.sleepycat.je.StatsConfig;
import com.sleepycat.je.Transaction;
import com.sleepycat.je.TransactionConfig;
import com.sleepycat.je.rep.impl.RepImpl;
import com.sleepycat.je.rep.impl.node.FeederManager;
import com.sleepycat.je.rep.impl.node.FeederManagerStatDefinition;
import com.sleepycat.je.rep.impl.node.RepNode;
import com.sleepycat.je.rep.impl.node.ReplayStatDefinition;
import com.sleepycat.je.rep.impl.node.Replica;
import com.sleepycat.je.rep.impl.node.ReplicaStatDefinition;
import com.sleepycat.je.rep.stream.FeederTxnStatDefinition;
import com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition;
import com.sleepycat.je.rep.vlsn.VLSNIndexStatDefinition;
import com.sleepycat.je.utilint.AtomicLongMapStat;
import com.sleepycat.je.utilint.IntegralLongAvgStat;
import com.sleepycat.je.utilint.LatencyPercentileMapStat;
import com.sleepycat.je.utilint.LongAvgMapStat;
import com.sleepycat.je.utilint.LongAvgRateMapStat;
import com.sleepycat.je.utilint.LongAvgRateStat;
import com.sleepycat.je.utilint.LongDiffMapStat;
import com.sleepycat.je.utilint.LongMaxMapStat;
import com.sleepycat.je.utilint.StatDefinition;
import com.sleepycat.je.utilint.StatGroup;
/**
* Statistics for a replicated environment.
* <p>
* The statistics are logically grouped into four categories. Viewing the
* statistics through {@link ReplicatedEnvironmentStats#toString()} displays
* the values in these categories, as does viewing the stats through the
* <a href="{@docRoot}/../jconsole/JConsole-plugin.html">RepJEMonitor
* mbean</a>. Viewing the stats with {@link
* ReplicatedEnvironmentStats#toStringVerbose()} will provide more detailed
* descriptions of the stats and stat categories.
* <p>
* The current categories are:
* <ul>
* <li><b>FeederManager</b>: A feed is the <a
* href="{@docRoot}/../ReplicationGuide/introduction.html#replicationstreams">replication
* stream</a> between a master and replica. The current number of feeders
* gives a sense of the connectivity of the replication group.
* </li>
* <li><b>BinaryProtocol</b>: These statistics center on the network traffic
* engendered by the replication stream, and provide a sense of the network
* bandwidth seen by the replication group.
* </li>
* <li><b>Replay</b>: The act of receiving and applying the replication stream
* at the Replica node is called Replay. These stats give a sense of how much
* load the replica node is experiencing when processing the traffic from the
* replication group.
* </li>
* <li><b>ConsistencyTracker</b>: The tracker is invoked when consistency
* policies are used at a replica node. This provides a measure of delays
* experienced by read requests at a replica, in order to conform with the
* consistency specified by the application.
* </li>
* </ul>
*
* @see <a href="{@docRoot}/../jconsole/JConsole-plugin.html">Viewing
* Statistics with JConsole</a>
*/
public class ReplicatedEnvironmentStats implements Serializable {
private static final long serialVersionUID = 1L;
/**
* The "impossible" return value used by stats accessors to indicate the
* statistic is not available in this instance of
* ReplicatedEnvironmentStats, because it represents an earlier
* de-serialized instance in which this statistic was unavailable.
*/
private static final int VALUE_UNAVAILABLE = -1;
private StatGroup feederManagerStats;
private StatGroup feederTxnStats;
private StatGroup replayStats;
private StatGroup trackerStats;
private StatGroup protocolStats;
private StatGroup vlsnIndexStats;
private final Map<String, String> tipsMap = new HashMap<String, String>();
ReplicatedEnvironmentStats(RepImpl repImpl, StatsConfig config) {
final RepNode repNode = repImpl.getRepNode();
final FeederManager feederManager = repNode.feederManager();
feederManagerStats = feederManager.getFeederManagerStats(config);
feederTxnStats = repNode.getFeederTxns().getStats(config);
final Replica replica = repNode.getReplica();
replayStats = replica.getReplayStats(config);
trackerStats = replica.getTrackerStats(config);
protocolStats = feederManager.getProtocolStats(config);
vlsnIndexStats = repImpl.getVLSNIndex().getStats(config);
protocolStats.addAll(replica.getProtocolStats(config));
addMessageRateStats();
addBytesRateStats();
}
/**
* @hidden
* Internal use only.
*/
public ReplicatedEnvironmentStats() {
}
/**
* @hidden
* Internal use only.
*/
public Collection<StatGroup> getStatGroups() {
return (feederTxnStats != null) ?
Arrays.asList(feederManagerStats,
feederTxnStats,
replayStats,
trackerStats,
protocolStats,
vlsnIndexStats) :
Arrays.asList(feederManagerStats,
replayStats,
trackerStats,
protocolStats,
vlsnIndexStats);
}
/**
* @hidden
* Internal use only.
*/
public Map<String, StatGroup> getStatGroupsMap() {
HashMap<String, StatGroup> statmap = new HashMap<String, StatGroup>();
statmap.put(feederManagerStats.getName(), feederManagerStats);
statmap.put(replayStats.getName(), replayStats);
statmap.put(trackerStats.getName(), trackerStats);
statmap.put(protocolStats.getName(), protocolStats);
statmap.put(vlsnIndexStats.getName(), vlsnIndexStats);
if (feederTxnStats != null) {
statmap.put(feederTxnStats.getName(), feederTxnStats);
}
return statmap;
}
/**
* @hidden
* Internal use only.
*/
public void setStatGroup(StatGroup sg) {
if (FeederManagerStatDefinition.GROUP_NAME.equals(sg.getName())) {
feederManagerStats = sg;
} else if (ReplayStatDefinition.GROUP_NAME.equals(sg.getName())) {
replayStats = sg;
} else if (ReplicaStatDefinition.GROUP_NAME.equals(sg.getName())) {
trackerStats = sg;
} else if (BinaryProtocolStatDefinition.GROUP_NAME.equals(
sg.getName())) {
protocolStats = sg;
} else if (VLSNIndexStatDefinition.GROUP_NAME.equals(sg.getName())) {
vlsnIndexStats = sg;
} else if (FeederTxnStatDefinition.GROUP_NAME.equals(sg.getName())) {
feederTxnStats = sg;
} else {
throw EnvironmentFailureException.unexpectedState(
"Internal error stat context is not registered");
}
}
/**
* @hidden
* Internal use only
*
* For JConsole plugin support.
*/
public static String[] getStatGroupTitles() {
return new String[] {
FeederManagerStatDefinition.GROUP_NAME,
FeederTxnStatDefinition.GROUP_NAME,
BinaryProtocolStatDefinition.GROUP_NAME,
ReplayStatDefinition.GROUP_NAME,
ReplicaStatDefinition.GROUP_NAME,
VLSNIndexStatDefinition.GROUP_NAME};
}
private void addMessageRateStats() {
long numerator;
long denominator;
numerator = (protocolStats.getLongStat(N_MESSAGES_READ) == null) ?
0 : protocolStats.getLongStat(N_MESSAGES_READ).get();
denominator = (protocolStats.getLongStat(N_READ_NANOS) == null) ?
0 : protocolStats.getLongStat(N_READ_NANOS).get();
@SuppressWarnings("unused")
IntegralLongAvgStat msgReadRate =
new IntegralLongAvgStat
(protocolStats,
MESSAGE_READ_RATE,
numerator,
denominator,
1000000000);
numerator = (protocolStats.getLongStat(N_MESSAGES_WRITTEN) == null) ?
0 : protocolStats.getLongStat(N_MESSAGES_WRITTEN).get();
denominator = (protocolStats.getLongStat(N_WRITE_NANOS) == null) ?
0 : protocolStats.getLongStat(N_WRITE_NANOS).get();
@SuppressWarnings("unused")
IntegralLongAvgStat msgWriteRate =
new IntegralLongAvgStat
(protocolStats,
MESSAGE_WRITE_RATE,
numerator,
denominator,
1000000000);
}
private void addBytesRateStats() {
long numerator;
long denominator;
numerator = (protocolStats.getLongStat(N_BYTES_READ) == null) ?
0 : protocolStats.getLongStat(N_BYTES_READ).get();
denominator = (protocolStats.getLongStat(N_READ_NANOS) == null) ?
0 : protocolStats.getLongStat(N_READ_NANOS).get();
@SuppressWarnings("unused")
IntegralLongAvgStat bytesReadRate =
new IntegralLongAvgStat
(protocolStats,
BYTES_READ_RATE,
numerator,
denominator,
1000000000);
numerator = (protocolStats.getLongStat(N_BYTES_WRITTEN) == null) ?
0 : protocolStats.getLongStat(N_BYTES_WRITTEN).get();
denominator = (protocolStats.getLongStat(N_WRITE_NANOS) == null) ?
0 : protocolStats.getLongStat(N_WRITE_NANOS).get();
@SuppressWarnings("unused")
IntegralLongAvgStat bytesWriteRate =
new IntegralLongAvgStat
(protocolStats,
BYTES_WRITE_RATE,
numerator,
denominator,
1000000000);
}
/* Feeder Stats. */
/**
* The number of Feeder threads since this node was started. A Master
* supplies the Replication Stream to a Replica via a Feeder thread. The
* Feeder thread is created when a Replica connects to the node and is
* shutdown when the connection is terminated.
*/
public int getNFeedersCreated() {
return feederManagerStats.getInt(N_FEEDERS_CREATED);
}
/**
* The number of Feeder threads that were shut down, either because this
* node, or the Replica terminated the connection.
*
* @see #getNFeedersCreated()
*/
public int getNFeedersShutdown() {
return feederManagerStats.getInt(N_FEEDERS_SHUTDOWN);
}
/**
* @deprecated in 18.3, always returns 0. Use {@link
* #getReplicaVLSNLagMap} to compute the maximum VLSN lag for all replicas.
*/
public long getNMaxReplicaLag() {
return 0;
}
/**
* @deprecated in 18.3, always returns null. Use {@link
* #getReplicaVLSNLagMap} to compute the maximum VLSN lag for all replicas.
*/
public String getNMaxReplicaLagName() {
return null;
}
/**
* Returns a map from replica node name to the most recently known value of
* the delay, in milliseconds, between when a transaction was committed on
* the master and when the master learned that the transaction was
* processed on the replica, if any. Returns an empty map if this node is
* not the master. The delay represents the time that would be needed to
* receive a transaction acknowledgement if the response is received
* quickly enough to be used.
*
* @since 6.3.0
*/
public SortedMap<String, Long> getReplicaDelayMap() {
final LongDiffMapStat stat =
(LongDiffMapStat) feederManagerStats.getStat(REPLICA_DELAY_MAP);
if (stat == null) {
return emptySortedMap();
}
return stat.getMap();
}
/**
* Returns a map from replica node name to average for the current period
* of the delay, in milliseconds, between when a transaction was committed
* on the master and when the master learned that the transaction was
* processed on the replica, if known. Returns an empty map if this node
* is not the master. The delay represents the time that would be needed
* to receive a transaction acknowledgement if the response is received
* quickly enough to be used.
*
* @since 18.3
*/
public SortedMap<String, Long> getReplicaAvgDelayMsMap() {
final LongAvgMapStat stat = (LongAvgMapStat)
feederManagerStats.getStat(REPLICA_AVG_DELAY_MS_MAP);
if (stat == null) {
return emptySortedMap();
}
return stat.getMap();
}
/**
* Returns a map from replica node name to the 95th percentile value for
* the current period of the delay, in milliseconds, between when a
* transaction was committed on the master and when the master learned that
* the transaction was processed on the replica, if known. Returns an
* empty map if this node is not the master. The delay represents the time
* that would be needed to receive a transaction acknowledgement if the
* response is received quickly enough to be used.
*
* @since 18.3
*/
public SortedMap<String, Long> getReplica95DelayMsMap() {
final LatencyPercentileMapStat stat = (LatencyPercentileMapStat)
feederManagerStats.getStat(REPLICA_95_DELAY_MS_MAP);
if (stat == null) {
return emptySortedMap();
}
return stat.getMap();
}
/**
* Returns a map from replica node name to the 99th percentile value for
* the current period of the delay, in milliseconds, between when a
* transaction was committed on the master and when the master learned that
* the transaction was processed on the replica, if known. Returns an
* empty map if this node is not the master. The delay represents the time
* that would be needed to receive a transaction acknowledgement if the
* response is received quickly enough to be used.
*
* @since 18.3
*/
public SortedMap<String, Long> getReplica99DelayMsMap() {
final LatencyPercentileMapStat stat = (LatencyPercentileMapStat)
feederManagerStats.getStat(REPLICA_99_DELAY_MS_MAP);
if (stat == null) {
return emptySortedMap();
}
return stat.getMap();
}
/**
* Returns a map from replica node name to the maximum value for the
* current period of the delay, in milliseconds, between when a transaction
* was committed on the master and when the master learned that the
* transaction was processed on the replica, if known. Returns an empty
* map if this node is not the master. The delay represents the time that
* would be needed to receive a transaction acknowledgement if the response
* is received quickly enough to be used.
*
* @since 18.3
*/
public SortedMap<String, Long> getReplicaMaxDelayMsMap() {
final LongMaxMapStat stat = (LongMaxMapStat)
feederManagerStats.getStat(REPLICA_MAX_DELAY_MS_MAP);
if (stat == null) {
return emptySortedMap();
}
return stat.getMap();
}
/**
* Returns a map from replica node name to the commit timestamp of the last
* committed transaction that was processed on the replica, if known.
* Returns an empty map if this node is not the master.
*
* @since 6.3.0
*/
public SortedMap<String, Long> getReplicaLastCommitTimestampMap() {
final AtomicLongMapStat stat = (AtomicLongMapStat)
feederManagerStats.getStat(REPLICA_LAST_COMMIT_TIMESTAMP_MAP);
if (stat == null) {
return emptySortedMap();
}
return stat.getMap();
}
/**
* Returns a map from replica node name to the VLSN of the last committed
* transaction that was processed on the replica, if known. Returns an
* empty map if this node is not the master.
*
* @since 6.3.0
*/
public SortedMap<String, Long> getReplicaLastCommitVLSNMap() {
final AtomicLongMapStat stat = (AtomicLongMapStat)
feederManagerStats.getStat(REPLICA_LAST_COMMIT_VLSN_MAP);
if (stat == null) {
return emptySortedMap();
}
return stat.getMap();
}
/**
* Returns a map from replica node name to the lag, in VLSNs, between the
* replication state of the replica and the master, if known. Returns an
* empty map if this node is not the master.
*
* @since 6.3.0
*/
public SortedMap<String, Long> getReplicaVLSNLagMap() {
final LongDiffMapStat stat =
(LongDiffMapStat) feederManagerStats.getStat(REPLICA_VLSN_LAG_MAP);
if (stat == null) {
return emptySortedMap();
}
return stat.getMap();
}
/**
* Returns a map from replica node name to a moving average of the rate, in
* VLSNs per minute, that the replica is processing replication data, if
* known. Returns an empty map if this node is not the master.
*
* @since 6.3.0
*/
public SortedMap<String, Long> getReplicaVLSNRateMap() {
final LongAvgRateMapStat stat = (LongAvgRateMapStat)
feederManagerStats.getStat(REPLICA_VLSN_RATE_MAP);
if (stat == null) {
return emptySortedMap();
}
return stat.getMap();
}
/* Master transaction commit acknowledgment statistics. */
/**
* The number of transactions that were successfully acknowledged based
* upon the {@link ReplicaAckPolicy} policy associated with the
* transaction commit.
*/
public long getNTxnsAcked() {
return (feederTxnStats == null) ?
VALUE_UNAVAILABLE :
feederTxnStats.getAtomicLong(TXNS_ACKED);
}
/**
* The number of transactions that were not acknowledged as required by the
* {@link ReplicaAckPolicy} policy associated with the transaction commit.
* These transactions resulted in {@link InsufficientReplicasException} or
* {@link InsufficientAcksException}.
*/
public long getNTxnsNotAcked() {
return (feederTxnStats == null) ?
VALUE_UNAVAILABLE :
feederTxnStats.getAtomicLong(TXNS_NOT_ACKED);
}
/**
* The total time in milliseconds spent in replicated transactions. This
* represents the time from the start of the transaction until its
* successful commit and acknowledgment. It includes the time spent
* waiting for transaction commit acknowledgments, as determined by
* {@link #getAckWaitMs()}.
*/
public long getTotalTxnMs() {
return (feederTxnStats == null) ?
VALUE_UNAVAILABLE :
feederTxnStats.getAtomicLong(TOTAL_TXN_MS);
}
/**
* The total time in milliseconds that the master spent waiting for the
* {@link ReplicaAckPolicy} to be satisfied during successful transaction
* commits.
*
* @see #getTotalTxnMs()
*/
public long getAckWaitMs() {
return (feederTxnStats == null) ?
VALUE_UNAVAILABLE :
feederTxnStats.getAtomicLong(ACK_WAIT_MS);
}
/**
* The VLSN of the last committed transaction on the master, or 0 if not
* known or this node is not the master.
*
* @since 6.3.0
*/
public long getLastCommitVLSN() {
return (feederTxnStats == null) ?
VALUE_UNAVAILABLE :
feederTxnStats.getAtomicLong(LAST_COMMIT_VLSN);
}
/**
* The commit timestamp of the last committed transaction on the master, or
* 0 if not known or this node is not the master.
*
* @since 6.3.0
*/
public long getLastCommitTimestamp() {
return (feederTxnStats == null) ?
VALUE_UNAVAILABLE :
feederTxnStats.getAtomicLong(LAST_COMMIT_TIMESTAMP);
}
/**
* A moving average of the rate replication data is being generated by the
* master, in VLSNs per minute, or 0 if not known or this node is not the
* master.
*
* @since 6.3.0
*/
public long getVLSNRate() {
if (feederTxnStats == null) {
return VALUE_UNAVAILABLE;
}
final LongAvgRateStat stat =
(LongAvgRateStat) feederTxnStats.getStat(VLSN_RATE);
return (stat != null) ? stat.get() : 0;
}
/* Replay Stats. */
/**
* The number of commit log records that were replayed by this node when
* it was a Replica. There is one commit record record for each actual
* commit on the Master.
*/
public long getNReplayCommits() {
return replayStats.getLong(N_COMMITS);
}
/**
* The number of commit log records that needed to be acknowledged to the
* Master by this node when it was a Replica. The rate of change of this
* statistic, will show a strong correlation with that of
* <code>NReplayCommits</code> statistic, if the <code>Durability</code>
* policy used by transactions on the master calls for transaction commit
* acknowledgments and the Replica is current with respect to the Master.
*/
public long getNReplayCommitAcks() {
return replayStats.getLong(N_COMMIT_ACKS);
}
/**
* The number of commitSync() calls executed when satisfying transaction
* commit acknowledgment requests from the Master.
*/
public long getNReplayCommitSyncs() {
return replayStats.getLong(N_COMMIT_SYNCS);
}
/**
* The number of commitNoSync() calls executed when satisfying transaction
* commit acknowledgment requests from the Master.
*/
public long getNReplayCommitNoSyncs() {
return replayStats.getLong(N_COMMIT_NO_SYNCS);
}
/**
* The number of commitNoSync() calls executed when satisfying transaction
* commit acknowledgment requests from the Master.
*/
public long getNReplayCommitWriteNoSyncs() {
return replayStats.getLong(N_COMMIT_WRITE_NO_SYNCS);
}
/**
* The number of abort records which were replayed while the node was in
* the Replica state.
*/
public long getNReplayAborts() {
return replayStats.getLong(N_ABORTS);
}
/**
* The number of NameLN records which were replayed while the node was in
* the Replica state.
*/
public long getNReplayNameLNs() {
return replayStats.getLong(N_NAME_LNS);
}
/**
* The number of data records (creation, update, deletion) which were
* replayed while the node was in the Replica state.
*/
public long getNReplayLNs() {
return replayStats.getLong(N_LNS);
}
/**
* @deprecated in 18.3, always returns zero. Use {@link
* #getElapsedTxnAvgMs} to return the average elapsed transaction time.
*/
public long getReplayElapsedTxnTime() {
return 0;
}
/**
* The number of group commits that were initiated due to the
* {@link ReplicationConfig#REPLICA_GROUP_COMMIT_INTERVAL group timeout
* interval} being exceeded.
*
* @since 5.0.76
*/
public long getNReplayGroupCommitTimeouts() {
return replayStats.getLong(N_GROUP_COMMIT_TIMEOUTS);
}
/**
* The number of group commits that were initiated due the
* {@link ReplicationConfig#REPLICA_MAX_GROUP_COMMIT max group size} being
* exceeded.
*
* @since 5.0.76
*/
public long getNReplayGroupCommitMaxExceeded() {
return replayStats.getLong(N_GROUP_COMMIT_MAX_EXCEEDED);
}
/**
* The number of replay transaction commits that were part of a group
* commit operation.
*
* @since 5.0.76
*/
public long getNReplayGroupCommitTxns() {
return replayStats.getLong(N_GROUP_COMMIT_TXNS);
}
/**
* The number of group commit operations.
*
* @since 5.0.76
*/
public long getNReplayGroupCommits() {
return replayStats.getLong(N_GROUP_COMMITS);
}
/**
* The minimum time taken to replay a transaction commit operation.
*/
public long getReplayMinCommitProcessingNanos() {
return replayStats.getLong(MIN_COMMIT_PROCESSING_NANOS);
}
/**
* The maximum time taken to replay a transaction commit operation.
*/
public long getReplayMaxCommitProcessingNanos() {
return replayStats.getLong(MAX_COMMIT_PROCESSING_NANOS);
}
/**
* The total time spent to replay all commit operations.
*/
public long getReplayTotalCommitProcessingNanos() {
return replayStats.getLong(TOTAL_COMMIT_PROCESSING_NANOS);
}
/**
* @hidden
* TODO: Make visible after experimenting with this new stat
*
* The time in milliseconds between when the latest update operation
* committed on the master and then subsequently committed on the replica.
*
* <p>Note that the lag is computed on the replica by comparing the time of
* the master commit, as measured by the master, and time on the replica
* when it commits locally. As a result, the return value will be affected
* by any clock skew between the master and the replica.
*/
public long getReplayLatestCommitLagMs() {
return replayStats.getLong(LATEST_COMMIT_LAG_MS);
}
/**
* The average time in milliseconds between when the replica receives a
* replication entry and when the entry is read from the replay queue by
* the replay thread.
*
* @since 18.3
*/
public long getReplayQueueAvgDelayMs() {
return replayStats.getLong(REPLAY_QUEUE_AVG_DELAY_MS);
}
/**
* The 95th percentile value of the time in milliseconds between when the
* replica receives a replication entry and when the entry is read from the
* replay queue by the replay thread.
*
* @since 18.3
*/
public long getReplayQueue95DelayMs() {
return replayStats.getLong(REPLAY_QUEUE_95_DELAY_MS);
}
/**
* The 99th percentile value of the time in milliseconds between when the
* replica receives a replication entry and when the entry is read from the
* replay queue by the replay thread.
*
* @since 18.3
*/
public long getReplayQueue99DelayMs() {
return replayStats.getLong(REPLAY_QUEUE_99_DELAY_MS);
}
/**
* The maximum time in milliseconds between when the replica receives a
* replication entry and when the entry is read from the replay queue by
* the replay thread.
*
* @since 18.3
*/
public long getReplayQueueMaxDelayMs() {
return replayStats.getLong(REPLAY_QUEUE_MAX_DELAY_MS);
}
/**
* The average time in milliseconds between when the replay thread places a
* response in the output queue and when the entry is read from the queue
* in preparation for sending it to the feeder by the output thread.
*
* @since 18.3
*/
public long getOutputQueueAvgDelayMs() {
return replayStats.getLong(OUTPUT_QUEUE_AVG_DELAY_MS);
}
/**
* The 95th percentile value of the time in milliseconds between when the
* replay thread places a response in the output queue and when the entry
* is read from the queue in preparation for sending it to the feeder by
* the output thread.
*
* @since 18.3
*/
public long getOutputQueue95DelayMs() {
return replayStats.getLong(OUTPUT_QUEUE_95_DELAY_MS);
}
/**
* The 99th percentile value of the time in milliseconds between when the
* replay thread places a response in the output queue and when the entry
* is read from the queue in preparation for sending it to the feeder by
* the output thread.
*
* @since 18.3
*/
public long getOutputQueue99DelayMs() {
return replayStats.getLong(OUTPUT_QUEUE_99_DELAY_MS);
}
/**
* The maximum time in milliseconds between when the replay thread places a
* response in the output queue and when the entry is read from the queue
* in preparation for sending it to the feeder by the output thread.
*
* @since 18.3
*/
public long getOutputQueueMaxDelayMs() {
return replayStats.getLong(OUTPUT_QUEUE_MAX_DELAY_MS);
}
/**
* The average time in milliseconds spent replaying a committed or aborted
* transaction.
*
* @since 18.3
*/
public long getElapsedTxnAvgMs() {
return replayStats.getLong(ELAPSED_TXN_AVG_MS);
}
/**
* The 95th percentile value of the time in milliseconds spent replaying a
* committed or aborted transaction.
*
* @since 18.3
*/
public long getElapsedTxn95Ms() {
return replayStats.getLong(ELAPSED_TXN_95_MS);
}
/**
* The 99th percentile value of the time in milliseconds spent replaying a
* committed or aborted transaction.
*
* @since 18.3
*/
public long getElapsedTxn99Ms() {
return replayStats.getLong(ELAPSED_TXN_99_MS);
}
/**
* The maximum time in milliseconds spent replaying a committed or aborted
* transaction.
*
* @since 18.3
*/
public long getElapsedTxnMaxMs() {
return replayStats.getLong(ELAPSED_TXN_MAX_MS);
}
/* Protocol Stats. */
/**
* The number of bytes of Replication Stream read over the network. It does
* not include the TCP/IP overhead.
* <p>
* If the node has served as both a Replica and Master since it was first
* started, the number represents the sum total of all Feeder related
* network activity, as well as Replica network activity.
*/
public long getNProtocolBytesRead() {
return protocolStats.getLong(N_BYTES_READ);
}
/**
* The number of Replication Stream messages read over the network.
* <p>
* If the node has served as both a Replica and Master since it was first
* started, the number represents the sum total of all Feeder related
* network activity, as well as Replica network activity.
*/
public long getNProtocolMessagesRead() {
return protocolStats.getLong(N_MESSAGES_READ);
}
/**
* The number of Replication Stream bytes written over the network.
* <p>
* If the node has served as both a Replica and Master since it was first
* started, the number represents the sum total of all Feeder related
* network activity, as well as Replica network activity.
*/
public long getNProtocolBytesWritten() {
return protocolStats.getLong(N_BYTES_WRITTEN);
}
/**
* The number of Replication Stream messages that were written as part
* of a message batch instead of being written individually.
*
* It represents a subset of the messages returned by
* {@link #getNProtocolMessagesWritten()}
*
* @see #getNProtocolMessageBatches
*
* @since 6.2.7
*/
public long getNProtocolMessagesBatched() {
return protocolStats.getLong(N_MESSAGES_BATCHED);
}
/**
* The number of Replication Stream message batches written to the network.
*
* @see #getNProtocolMessagesBatched
*
* @since 6.2.7
*/
public long getNProtocolMessageBatches() {
return protocolStats.getLong(N_MESSAGE_BATCHES);
}
/**
* The total number of Replication Stream messages written over the
* network.
* <p>
* If the node has served as both a Replica and Master since it was first
* started, the number represents the sum total of all Feeder related
* network activity, as well as Replica network activity.
*/
public long getNProtocolMessagesWritten() {
return protocolStats.getLong(N_MESSAGES_WRITTEN);
}
/**
* The number of nanoseconds spent reading from the network channel.
* <p>
* If the node has served as both a Replica and Master since it was first
* started, the number represents the sum total of all Feeder related
* network activity, as well as Replica network activity.
*/
public long getProtocolReadNanos() {
return protocolStats.getLong(N_READ_NANOS);
}
/**
* The number of nanoseconds spent writing to the network channel.
* <p>
* If the node has served as both a Replica and Master since it was first
* started, the number represents the sum total of all Feeder related
* network activity, as well as Replica network activity.
*/
public long getProtocolWriteNanos() {
return protocolStats.getLong(N_WRITE_NANOS);
}
/**
* Incoming replication message throughput, in terms of messages received
* from the replication network channels per second.
* <p> If the node has served as both a Replica and Master since
* it was first started, the number represents the message reading rate
* over all Feeder related network activity, as well as Replica network
* activity.
*/
public long getProtocolMessageReadRate() {
IntegralLongAvgStat rstat =
protocolStats.getIntegralLongAvgStat(MESSAGE_READ_RATE);
return (rstat != null) ? rstat.get().longValue() : 0;
}
/**
* Outgoing message throughput, in terms of message written to the
* replication network channels per second.
* <p>
* If the node has served as both a Replica and Master since it was first
* started, the number represents the message writing rate over all Feeder
* related network activity, as well as Replica network activity.
*/
public long getProtocolMessageWriteRate() {
IntegralLongAvgStat rstat =
protocolStats.getIntegralLongAvgStat(MESSAGE_WRITE_RATE);
return (rstat != null) ? rstat.get().longValue() : 0;
}
/**
* Bytes read throughput, in terms of bytes received from the replication
* network channels per second.
* <p>
* If the node has served as both a Replica and Master since it was first
* started, the number represents the bytes reading rate over all Feeder
* related network activity, as well as Replica network activity.
*/
public long getProtocolBytesReadRate() {
IntegralLongAvgStat rstat =
protocolStats.getIntegralLongAvgStat(BYTES_READ_RATE);
return (rstat != null) ? rstat.get().longValue() : 0;
}
/**
* Bytes written throughput, in terms of bytes written to the replication
* network channels per second.
* <p>
* If the node has served as both a Replica and Master since it was first
* started, the number represents the bytes writing rate over all Feeder
* related network activity, as well as Replica network activity.
*/
public long getProtocolBytesWriteRate() {
IntegralLongAvgStat rstat =
protocolStats.getIntegralLongAvgStat(BYTES_WRITE_RATE);
return (rstat != null) ? rstat.get().longValue() : 0;
}
/**
* Returns the number of messages containing log entries that were written
* to the replication stream using the previous log format to support
* replication to a replica running an earlier version during an upgrade.
*/
public long getNProtocolEntriesWrittenOldVersion() {
return protocolStats.getLong(N_ENTRIES_WRITTEN_OLD_VERSION);
}
/* ConsistencyTracker Stats. */
/**
* The number of times a Replica held back a
* {@link Environment#beginTransaction(Transaction,TransactionConfig)}
* operation to satisfy the {@link TimeConsistencyPolicy}.
*/
public long getTrackerLagConsistencyWaits() {
return trackerStats.getLong(N_LAG_CONSISTENCY_WAITS);
}
/**
* The total time (in msec) for which a Replica held back a
* {@link Environment#beginTransaction(Transaction,TransactionConfig)}
* operation to satisfy the {@link TimeConsistencyPolicy}.
*/
public long getTrackerLagConsistencyWaitMs() {
return trackerStats.getLong(N_LAG_CONSISTENCY_WAIT_MS);
}
/**
* The number of times a Replica held back a
* {@link Environment#beginTransaction(Transaction,TransactionConfig)}
* operation to satisfy the {@link CommitPointConsistencyPolicy}.
*/
public long getTrackerVLSNConsistencyWaits() {
return trackerStats.getLong(N_VLSN_CONSISTENCY_WAITS);
}
/**
* The total time (in msec) for which a Replica held back a
* {@link Environment#beginTransaction(Transaction,TransactionConfig)}
* operation to satisfy the {@link CommitPointConsistencyPolicy}.
*/
public long getTrackerVLSNConsistencyWaitMs() {
return trackerStats.getLong(N_VLSN_CONSISTENCY_WAIT_MS);
}
/**
* Returns a String representation of the stats in the form of
* &lt;stat&gt;=&lt;value&gt;
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (StatGroup group : getStatGroups()) {
sb.append(group.toString());
}
return sb.toString();
}
/**
* Returns a String representation of the stats which includes stats
* descriptions in addition to &lt;stat&gt;=&lt;value&gt;
*/
public String toStringVerbose() {
StringBuilder sb = new StringBuilder();
for (StatGroup group : getStatGroups()) {
sb.append(group.toStringVerbose());
}
return sb.toString();
}
public Map<String, String> getTips() {
/* Add FeederManager stats definition. */
for (StatGroup group : getStatGroups()) {
tipsMap.put(group.getName(), group.getDescription());
for (StatDefinition def : group.getStats().keySet()) {
tipsMap.put(def.getName(), def.getDescription());
}
}
return tipsMap;
}
}