1 /*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2002, 2014 Oracle and/or its affiliates. All rights reserved. 5 * 6 */ 7 8 package com.sleepycat.je.rep; 9 10 import static com.sleepycat.je.rep.impl.node.FeederManagerStatDefinition.N_FEEDERS_CREATED; 11 import static com.sleepycat.je.rep.impl.node.FeederManagerStatDefinition.N_FEEDERS_SHUTDOWN; 12 import static com.sleepycat.je.rep.impl.node.FeederManagerStatDefinition.N_MAX_REPLICA_LAG; 13 import static com.sleepycat.je.rep.impl.node.FeederManagerStatDefinition.N_MAX_REPLICA_LAG_NAME; 14 import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.LATEST_COMMIT_LAG_MS; 15 import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.MAX_COMMIT_PROCESSING_NANOS; 16 import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.MIN_COMMIT_PROCESSING_NANOS; 17 import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_ABORTS; 18 import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_COMMITS; 19 import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_COMMIT_ACKS; 20 import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_COMMIT_NO_SYNCS; 21 import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_COMMIT_SYNCS; 22 import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_COMMIT_WRITE_NO_SYNCS; 23 import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_ELAPSED_TXN_TIME; 24 import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_GROUP_COMMITS; 25 import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_GROUP_COMMIT_MAX_EXCEEDED; 26 import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_GROUP_COMMIT_TIMEOUTS; 27 import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_GROUP_COMMIT_TXNS; 28 import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_LNS; 29 import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.N_NAME_LNS; 30 import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.TOTAL_COMMIT_LAG_MS; 31 import static com.sleepycat.je.rep.impl.node.ReplayStatDefinition.TOTAL_COMMIT_PROCESSING_NANOS; 32 import static com.sleepycat.je.rep.impl.node.ReplicaStatDefinition.N_LAG_CONSISTENCY_WAITS; 33 import static com.sleepycat.je.rep.impl.node.ReplicaStatDefinition.N_LAG_CONSISTENCY_WAIT_MS; 34 import static com.sleepycat.je.rep.impl.node.ReplicaStatDefinition.N_VLSN_CONSISTENCY_WAITS; 35 import static com.sleepycat.je.rep.impl.node.ReplicaStatDefinition.N_VLSN_CONSISTENCY_WAIT_MS; 36 import static com.sleepycat.je.rep.stream.FeederTxnStatDefinition.ACK_WAIT_MS; 37 import static com.sleepycat.je.rep.stream.FeederTxnStatDefinition.TOTAL_TXN_MS; 38 import static com.sleepycat.je.rep.stream.FeederTxnStatDefinition.TXNS_ACKED; 39 import static com.sleepycat.je.rep.stream.FeederTxnStatDefinition.TXNS_NOT_ACKED; 40 import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.BYTES_READ_RATE; 41 import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.BYTES_WRITE_RATE; 42 import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.MESSAGE_READ_RATE; 43 import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.MESSAGE_WRITE_RATE; 44 import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.N_BYTES_READ; 45 import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.N_BYTES_WRITTEN; 46 import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.N_ENTRIES_WRITTEN_OLD_VERSION; 47 import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.N_MESSAGES_BATCHED; 48 import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.N_MESSAGES_READ; 49 import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.N_MESSAGES_WRITTEN; 50 import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.N_MESSAGE_BATCHES; 51 import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.N_READ_NANOS; 52 import static com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition.N_WRITE_NANOS; 53 54 import java.io.Serializable; 55 import java.util.Arrays; 56 import java.util.Collection; 57 import java.util.HashMap; 58 import java.util.Map; 59 60 import com.sleepycat.je.Durability.ReplicaAckPolicy; 61 import com.sleepycat.je.Environment; 62 import com.sleepycat.je.EnvironmentFailureException; 63 import com.sleepycat.je.StatsConfig; 64 import com.sleepycat.je.Transaction; 65 import com.sleepycat.je.TransactionConfig; 66 import com.sleepycat.je.rep.impl.RepImpl; 67 import com.sleepycat.je.rep.impl.node.FeederManager; 68 import com.sleepycat.je.rep.impl.node.FeederManagerStatDefinition; 69 import com.sleepycat.je.rep.impl.node.RepNode; 70 import com.sleepycat.je.rep.impl.node.ReplayStatDefinition; 71 import com.sleepycat.je.rep.impl.node.Replica; 72 import com.sleepycat.je.rep.impl.node.ReplicaStatDefinition; 73 import com.sleepycat.je.rep.stream.FeederTxnStatDefinition; 74 import com.sleepycat.je.rep.utilint.BinaryProtocolStatDefinition; 75 import com.sleepycat.je.rep.vlsn.VLSNIndexStatDefinition; 76 import com.sleepycat.je.utilint.IntegralLongAvgStat; 77 import com.sleepycat.je.utilint.StatDefinition; 78 import com.sleepycat.je.utilint.StatGroup; 79 80 /** 81 * Statistics for a replicated environment. 82 * <p> 83 * The statistics are logically grouped into four categories. Viewing the 84 * statistics through {@link ReplicatedEnvironmentStats#toString()} displays 85 * the values in these categories, as does viewing the stats through the {@link 86 * <a href="{@docRoot}/../jconsole/JConsole-plugin.html">RepJEMonitor 87 * mbean</a>}. Viewing the stats with {@link 88 * ReplicatedEnvironmentStats#toStringVerbose()} will provide more detailed 89 * descriptions of the stats and stat categories. 90 * <p> 91 * The current categories are: 92 * <ul> 93 * <li><b>FeederManager</b>: A feed is the {@link <a 94 * href="{@docRoot}/../ReplicationGuide/introduction.html#replicationstreams">replication 95 * stream</a>} between a master and replica. The current number of feeders 96 * gives a sense of the connectivity of the replication group. 97 * </li> 98 * <li><b>BinaryProtocol</b>: These statistics center on the network traffic 99 * engendered by the replication stream, and provide a sense of the network 100 * bandwidth seen by the replication group. 101 * </li> 102 * <li><b>Replay</b>: The act of receiving and applying the replication stream 103 * at the Replica node is called Replay. These stats give a sense of how much 104 * load the replica node is experiencing when processing the traffic from the 105 * replication group. 106 * </li> 107 * <li><b>ConsistencyTracker</b>: The tracker is invoked when consistency 108 * policies are used at a replica node. This provides a measure of delays 109 * experienced by read requests at a replica, in order to conform with the 110 * consistency specified by the application. 111 * </li> 112 * </ul> 113 * 114 * @see <a href="{@docRoot}/../jconsole/JConsole-plugin.html">Viewing 115 * Statistics with JConsole</a> 116 */ 117 public class ReplicatedEnvironmentStats implements Serializable { 118 private static final long serialVersionUID = 1L; 119 120 /** 121 * The "impossible" return value used by stats accessors to indicate the 122 * statistic is not available in this instance of 123 * ReplicatedEnvironmentStats, because it represents an earlier 124 * de-serialized instance in which this statistic was unavailable. 125 */ 126 private static final int VALUE_UNAVAILABLE = -1; 127 128 private StatGroup feederManagerStats; 129 private StatGroup feederTxnStats; 130 private StatGroup replayStats; 131 private StatGroup trackerStats; 132 private StatGroup protocolStats; 133 private StatGroup vlsnIndexStats; 134 135 private final Map<String, String> tipsMap = new HashMap<String, String>(); 136 ReplicatedEnvironmentStats(RepImpl repImpl, StatsConfig config)137 ReplicatedEnvironmentStats(RepImpl repImpl, StatsConfig config) { 138 final RepNode repNode = repImpl.getRepNode(); 139 final FeederManager feederManager = repNode.feederManager(); 140 141 feederManagerStats = feederManager.getFeederManagerStats(config); 142 feederTxnStats = repNode.getFeederTxns().getStats(config); 143 144 final Replica replica = repNode.getReplica(); 145 replayStats = replica.getReplayStats(config); 146 trackerStats = replica.getTrackerStats(config); 147 protocolStats = feederManager.getProtocolStats(config); 148 vlsnIndexStats = repImpl.getVLSNIndex().getStats(config); 149 150 protocolStats.addAll(replica.getProtocolStats(config)); 151 addMessageRateStats(); 152 addBytesRateStats(); 153 } 154 155 /** 156 * @hidden 157 * Internal use only. 158 */ ReplicatedEnvironmentStats()159 public ReplicatedEnvironmentStats() { 160 } 161 162 /** 163 * @hidden 164 * Internal use only. 165 */ getStatGroups()166 public Collection<StatGroup> getStatGroups() { 167 return (feederTxnStats != null) ? 168 Arrays.asList(feederManagerStats, 169 feederTxnStats, 170 replayStats, 171 trackerStats, 172 protocolStats, 173 vlsnIndexStats) : 174 Arrays.asList(feederManagerStats, 175 replayStats, 176 trackerStats, 177 protocolStats, 178 vlsnIndexStats); 179 } 180 181 /** 182 * @hidden 183 * Internal use only. 184 */ getStatGroupsMap()185 public Map<String, StatGroup> getStatGroupsMap() { 186 HashMap<String, StatGroup> statmap = new HashMap<String, StatGroup>(); 187 statmap.put(feederManagerStats.getName(), feederManagerStats); 188 statmap.put(replayStats.getName(), replayStats); 189 statmap.put(trackerStats.getName(), trackerStats); 190 statmap.put(protocolStats.getName(), protocolStats); 191 statmap.put(vlsnIndexStats.getName(), vlsnIndexStats); 192 if (feederTxnStats != null) { 193 statmap.put(feederTxnStats.getName(), feederTxnStats); 194 } 195 return statmap; 196 } 197 198 /** 199 * @hidden 200 * Internal use only. 201 */ setStatGroup(StatGroup sg)202 public void setStatGroup(StatGroup sg) { 203 204 if (sg.getName().equals(FeederManagerStatDefinition.GROUP_NAME)) { 205 feederManagerStats = sg; 206 } else if (sg.getName().equals(ReplayStatDefinition.GROUP_NAME)) { 207 replayStats = sg; 208 } else if (sg.getName().equals(ReplicaStatDefinition.GROUP_NAME)) { 209 trackerStats = sg; 210 } else if (sg.getName().equals 211 (BinaryProtocolStatDefinition.GROUP_NAME)) { 212 protocolStats = sg; 213 } else if (sg.getName().equals(VLSNIndexStatDefinition.GROUP_NAME)) { 214 vlsnIndexStats = sg; 215 } else if (sg.getName().equals(FeederTxnStatDefinition.GROUP_NAME)) { 216 feederTxnStats = sg; 217 } else { 218 throw EnvironmentFailureException.unexpectedState 219 ("Internal error stat context is not registered"); 220 } 221 } 222 223 /** 224 * @hidden 225 * Internal use only 226 * 227 * For JConsole plugin support. 228 */ getStatGroupTitles()229 public static String[] getStatGroupTitles() { 230 return new String[] { 231 FeederManagerStatDefinition.GROUP_NAME, 232 FeederTxnStatDefinition.GROUP_NAME, 233 BinaryProtocolStatDefinition.GROUP_NAME, 234 ReplayStatDefinition.GROUP_NAME, 235 ReplicaStatDefinition.GROUP_NAME, 236 VLSNIndexStatDefinition.GROUP_NAME}; 237 } 238 addMessageRateStats()239 private void addMessageRateStats() { 240 long numerator; 241 long denominator; 242 243 numerator = (protocolStats.getLongStat(N_MESSAGES_READ) == null) ? 244 0 : protocolStats.getLongStat(N_MESSAGES_READ).get(); 245 denominator = (protocolStats.getLongStat(N_READ_NANOS) == null) ? 246 0 : protocolStats.getLongStat(N_READ_NANOS).get(); 247 @SuppressWarnings("unused") 248 IntegralLongAvgStat msgReadRate = 249 new IntegralLongAvgStat 250 (protocolStats, 251 MESSAGE_READ_RATE, 252 numerator, 253 denominator, 254 1000000000); 255 256 numerator = (protocolStats.getLongStat(N_MESSAGES_WRITTEN) == null) ? 257 0 : protocolStats.getLongStat(N_MESSAGES_WRITTEN).get(); 258 denominator = (protocolStats.getLongStat(N_WRITE_NANOS) == null) ? 259 0 : protocolStats.getLongStat(N_WRITE_NANOS).get(); 260 @SuppressWarnings("unused") 261 IntegralLongAvgStat msgWriteRate = 262 new IntegralLongAvgStat 263 (protocolStats, 264 MESSAGE_WRITE_RATE, 265 numerator, 266 denominator, 267 1000000000); 268 } 269 addBytesRateStats()270 private void addBytesRateStats() { 271 long numerator; 272 long denominator; 273 274 numerator = (protocolStats.getLongStat(N_BYTES_READ) == null) ? 275 0 : protocolStats.getLongStat(N_BYTES_READ).get(); 276 denominator = (protocolStats.getLongStat(N_READ_NANOS) == null) ? 277 0 : protocolStats.getLongStat(N_READ_NANOS).get(); 278 @SuppressWarnings("unused") 279 IntegralLongAvgStat bytesReadRate = 280 new IntegralLongAvgStat 281 (protocolStats, 282 BYTES_READ_RATE, 283 numerator, 284 denominator, 285 1000000000); 286 287 numerator = (protocolStats.getLongStat(N_BYTES_WRITTEN) == null) ? 288 0 : protocolStats.getLongStat(N_BYTES_WRITTEN).get(); 289 denominator = (protocolStats.getLongStat(N_WRITE_NANOS) == null) ? 290 0 : protocolStats.getLongStat(N_WRITE_NANOS).get(); 291 @SuppressWarnings("unused") 292 IntegralLongAvgStat bytesWriteRate = 293 new IntegralLongAvgStat 294 (protocolStats, 295 BYTES_WRITE_RATE, 296 numerator, 297 denominator, 298 1000000000); 299 } 300 301 /* Feeder Stats. */ 302 303 /** 304 * The number of Feeder threads since this node was started. A Master 305 * supplies the Replication Stream to a Replica via a Feeder thread. The 306 * Feeder thread is created when a Replica connects to the node and is 307 * shutdown when the connection is terminated. 308 */ getNFeedersCreated()309 public int getNFeedersCreated() { 310 return feederManagerStats.getInt(N_FEEDERS_CREATED); 311 } 312 313 /** 314 * The number of Feeder threads that were shut down, either because this 315 * node, or the Replica terminated the connection. 316 * 317 * @see #getNFeedersCreated() 318 */ getNFeedersShutdown()319 public int getNFeedersShutdown() { 320 return feederManagerStats.getInt(N_FEEDERS_SHUTDOWN); 321 } 322 323 /** 324 * The lag (in VLSNs) associated with the replica that's farthest behind in 325 * replaying the replication stream. 326 */ getNMaxReplicaLag()327 public long getNMaxReplicaLag() { 328 return feederManagerStats.getLong(N_MAX_REPLICA_LAG); 329 } 330 331 /** 332 * The name of the replica that's farthest behind in replaying the 333 * replication stream. 334 */ getNMaxReplicaLagName()335 public String getNMaxReplicaLagName() { 336 return feederManagerStats.getString(N_MAX_REPLICA_LAG_NAME); 337 } 338 339 /* Master transaction commit acknowledgment statistics. */ 340 341 /** 342 * The number of transactions that were successfully acknowledged based 343 * upon the {@link ReplicaAckPolicy} policy associated with the 344 * transaction commit. 345 */ getNTxnsAcked()346 public long getNTxnsAcked() { 347 return (feederTxnStats == null) ? 348 VALUE_UNAVAILABLE : 349 feederTxnStats.getAtomicLong(TXNS_ACKED); 350 } 351 352 /** 353 * The number of transactions that were not acknowledged as required by the 354 * {@link ReplicaAckPolicy} policy associated with the transaction commit. 355 * These transactions resulted in {@link InsufficientReplicasException} or 356 * {@link InsufficientAcksException}. 357 */ getNTxnsNotAcked()358 public long getNTxnsNotAcked() { 359 return (feederTxnStats == null) ? 360 VALUE_UNAVAILABLE : 361 feederTxnStats.getAtomicLong(TXNS_NOT_ACKED); 362 } 363 364 /** 365 * The total time in milliseconds spent in replicated transactions. This 366 * represents the time from the start of the transaction until its 367 * successful commit and acknowledgment. It includes the time spent 368 * waiting for transaction commit acknowledgments, as determined by 369 * {@link #getAckWaitMs()}. 370 */ getTotalTxnMs()371 public long getTotalTxnMs() { 372 return (feederTxnStats == null) ? 373 VALUE_UNAVAILABLE : 374 feederTxnStats.getAtomicLong(TOTAL_TXN_MS); 375 } 376 377 /** 378 * The total time in milliseconds that the master spent waiting for the 379 * {@link ReplicaAckPolicy} to be satisfied during successful transaction 380 * commits. 381 * 382 * @see #getTotalTxnMs() 383 */ getAckWaitMs()384 public long getAckWaitMs() { 385 return (feederTxnStats == null) ? 386 VALUE_UNAVAILABLE : 387 feederTxnStats.getAtomicLong(ACK_WAIT_MS); 388 } 389 390 /* Replay Stats. */ 391 392 /** 393 * The number of commit log records that were replayed by this node when 394 * it was a Replica. There is one commit record record for each actual 395 * commit on the Master. 396 */ getNReplayCommits()397 public long getNReplayCommits() { 398 return replayStats.getLong(N_COMMITS); 399 } 400 401 /** 402 * The number of commit log records that needed to be acknowledged to the 403 * Master by this node when it was a Replica. The rate of change of this 404 * statistic, will show a strong correlation with that of 405 * <code>NReplayCommits</code> statistic, if the <code>Durability</code> 406 * policy used by transactions on the master calls for transaction commit 407 * acknowledgments and the Replica is current with respect to the Master. 408 */ getNReplayCommitAcks()409 public long getNReplayCommitAcks() { 410 return replayStats.getLong(N_COMMIT_ACKS); 411 } 412 413 /** 414 * The number of commitSync() calls executed when satisfying transaction 415 * commit acknowledgment requests from the Master. 416 */ getNReplayCommitSyncs()417 public long getNReplayCommitSyncs() { 418 return replayStats.getLong(N_COMMIT_SYNCS); 419 } 420 421 /** 422 * The number of commitNoSync() calls executed when satisfying transaction 423 * commit acknowledgment requests from the Master. 424 */ getNReplayCommitNoSyncs()425 public long getNReplayCommitNoSyncs() { 426 return replayStats.getLong(N_COMMIT_NO_SYNCS); 427 } 428 429 /** 430 * The number of commitNoSync() calls executed when satisfying transaction 431 * commit acknowledgment requests from the Master. 432 */ getNReplayCommitWriteNoSyncs()433 public long getNReplayCommitWriteNoSyncs() { 434 return replayStats.getLong(N_COMMIT_WRITE_NO_SYNCS); 435 } 436 437 /** 438 * The number of abort records which were replayed while the node was in 439 * the Replica state. 440 */ getNReplayAborts()441 public long getNReplayAborts() { 442 return replayStats.getLong(N_ABORTS); 443 } 444 445 /** 446 * The number of NameLN records which were replayed while the node was in 447 * the Replica state. 448 */ getNReplayNameLNs()449 public long getNReplayNameLNs() { 450 return replayStats.getLong(N_NAME_LNS); 451 } 452 453 /** 454 * The number of data records (creation, update, deletion) which were 455 * replayed while the node was in the Replica state. 456 */ getNReplayLNs()457 public long getNReplayLNs() { 458 return replayStats.getLong(N_LNS); 459 } 460 461 /** 462 * The total elapsed time in milliseconds spent replaying committed and 463 * aborted transactions. 464 */ getReplayElapsedTxnTime()465 public long getReplayElapsedTxnTime() { 466 return replayStats.getLong(N_ELAPSED_TXN_TIME); 467 } 468 469 /** 470 * The number of group commits that were initiated due to the 471 * {@link ReplicationConfig#REPLICA_GROUP_COMMIT_INTERVAL group timeout 472 * interval} being exceeded. 473 * 474 * @since 5.0.76 475 */ getNReplayGroupCommitTimeouts()476 public long getNReplayGroupCommitTimeouts() { 477 return replayStats.getLong(N_GROUP_COMMIT_TIMEOUTS); 478 } 479 480 /** 481 * The number of group commits that were initiated due the 482 * {@link ReplicationConfig#REPLICA_MAX_GROUP_COMMIT max group size} being 483 * exceeded. 484 * 485 * @since 5.0.76 486 */ getNReplayGroupCommitMaxExceeded()487 public long getNReplayGroupCommitMaxExceeded() { 488 return replayStats.getLong(N_GROUP_COMMIT_MAX_EXCEEDED); 489 } 490 491 /** 492 * The number of replay transaction commits that were part of a group 493 * commit operation. 494 * 495 * @since 5.0.76 496 */ getNReplayGroupCommitTxns()497 public long getNReplayGroupCommitTxns() { 498 return replayStats.getLong(N_GROUP_COMMIT_TXNS); 499 } 500 501 /** 502 * The number of group commit operations. 503 * 504 * @since 5.0.76 505 */ getNReplayGroupCommits()506 public long getNReplayGroupCommits() { 507 return replayStats.getLong(N_GROUP_COMMITS); 508 } 509 510 /** 511 * The minimum time taken to replay a transaction commit operation. 512 */ getReplayMinCommitProcessingNanos()513 public long getReplayMinCommitProcessingNanos() { 514 return replayStats.getLong(MIN_COMMIT_PROCESSING_NANOS); 515 } 516 517 /** 518 * The maximum time taken to replay a transaction commit operation. 519 */ getReplayMaxCommitProcessingNanos()520 public long getReplayMaxCommitProcessingNanos() { 521 return replayStats.getLong(MAX_COMMIT_PROCESSING_NANOS); 522 } 523 524 /** 525 * The total time spent to replay all commit operations. 526 */ getReplayTotalCommitProcessingNanos()527 public long getReplayTotalCommitProcessingNanos() { 528 return replayStats.getLong(TOTAL_COMMIT_PROCESSING_NANOS); 529 } 530 531 /** 532 * @hidden 533 * TODO: Make visible after experimenting with this new stat 534 * 535 * The sum of time periods, measured in milliseconds, between when update 536 * operations commit on the master and then subsequently commit on the 537 * replica. Divide this value by the total number of commit operations, 538 * available by calling {@link #getNReplayCommits}, to find the average 539 * commit lag for a single operation. 540 * 541 * <p>Note that each lag is computed on the replica by comparing the time 542 * of the master commit, as measured by the master, and time on the replica 543 * when it commits locally. As a result, the return value will be affected 544 * by any clock skew between the master and the replica. 545 */ getReplayTotalCommitLagMs()546 public long getReplayTotalCommitLagMs() { 547 return replayStats.getLong(TOTAL_COMMIT_LAG_MS); 548 } 549 550 /** 551 * @hidden 552 * TODO: Make visible after experimenting with this new stat 553 * 554 * The time in milliseconds between when the latest update operation 555 * committed on the master and then subsequently committed on the replica. 556 * 557 * <p>Note that the lag is computed on the replica by comparing the time of 558 * the master commit, as measured by the master, and time on the replica 559 * when it commits locally. As a result, the return value will be affected 560 * by any clock skew between the master and the replica. 561 */ getReplayLatestCommitLagMs()562 public long getReplayLatestCommitLagMs() { 563 return replayStats.getLong(LATEST_COMMIT_LAG_MS); 564 } 565 566 /* Protocol Stats. */ 567 568 /** 569 * The number of bytes of Replication Stream read over the network. It does 570 * not include the TCP/IP overhead. 571 * <p> 572 * If the node has served as both a Replica and Master since it was first 573 * started, the number represents the sum total of all Feeder related 574 * network activity, as well as Replica network activity. 575 */ getNProtocolBytesRead()576 public long getNProtocolBytesRead() { 577 return protocolStats.getLong(N_BYTES_READ); 578 } 579 580 /** 581 * The number of Replication Stream messages read over the network. 582 * <p> 583 * If the node has served as both a Replica and Master since it was first 584 * started, the number represents the sum total of all Feeder related 585 * network activity, as well as Replica network activity. 586 */ getNProtocolMessagesRead()587 public long getNProtocolMessagesRead() { 588 return protocolStats.getLong(N_MESSAGES_READ); 589 } 590 591 /** 592 * The number of Replication Stream bytes written over the network. 593 * <p> 594 * If the node has served as both a Replica and Master since it was first 595 * started, the number represents the sum total of all Feeder related 596 * network activity, as well as Replica network activity. 597 */ getNProtocolBytesWritten()598 public long getNProtocolBytesWritten() { 599 return protocolStats.getLong(N_BYTES_WRITTEN); 600 } 601 602 /** 603 * The number of Replication Stream messages that were written as part 604 * of a message batch instead of being written individually. 605 * 606 * It represents a subset of the messages returned by 607 * {@link #getNProtocolMessagesWritten()} 608 * 609 * @see #getNProtocolMessageBatches 610 * 611 * @since 6.2.7 612 */ getNProtocolMessagesBatched()613 public long getNProtocolMessagesBatched() { 614 return protocolStats.getLong(N_MESSAGES_BATCHED); 615 } 616 617 /** 618 * The number of Replication Stream message batches written to the network. 619 * 620 * @see #getNProtocolMessagesBatched 621 * 622 * @since 6.2.7 623 */ getNProtocolMessageBatches()624 public long getNProtocolMessageBatches() { 625 return protocolStats.getLong(N_MESSAGE_BATCHES); 626 } 627 628 /** 629 * The total number of Replication Stream messages written over the 630 * network. 631 * <p> 632 * If the node has served as both a Replica and Master since it was first 633 * started, the number represents the sum total of all Feeder related 634 * network activity, as well as Replica network activity. 635 */ getNProtocolMessagesWritten()636 public long getNProtocolMessagesWritten() { 637 return protocolStats.getLong(N_MESSAGES_WRITTEN); 638 } 639 640 /** 641 * The number of nanoseconds spent reading from the network channel. 642 * <p> 643 * If the node has served as both a Replica and Master since it was first 644 * started, the number represents the sum total of all Feeder related 645 * network activity, as well as Replica network activity. 646 */ getProtocolReadNanos()647 public long getProtocolReadNanos() { 648 return protocolStats.getLong(N_READ_NANOS); 649 } 650 651 /** 652 * The number of nanoseconds spent writing to the network channel. 653 * <p> 654 * If the node has served as both a Replica and Master since it was first 655 * started, the number represents the sum total of all Feeder related 656 * network activity, as well as Replica network activity. 657 */ getProtocolWriteNanos()658 public long getProtocolWriteNanos() { 659 return protocolStats.getLong(N_WRITE_NANOS); 660 } 661 662 /** 663 * Incoming replication message throughput, in terms of messages received 664 * from the replication network channels per second. 665 * <p> If the node has served as both a Replica and Master since 666 * it was first started, the number represents the message reading rate 667 * over all Feeder related network activity, as well as Replica network 668 * activity. 669 */ getProtocolMessageReadRate()670 public long getProtocolMessageReadRate() { 671 IntegralLongAvgStat rstat = 672 protocolStats.getIntegralLongAvgStat(MESSAGE_READ_RATE); 673 return (rstat != null) ? rstat.get().longValue() : 0; 674 } 675 676 /** 677 * Outgoing message throughput, in terms of message written to the 678 * replication network channels per second. 679 * <p> 680 * If the node has served as both a Replica and Master since it was first 681 * started, the number represents the message writing rate over all Feeder 682 * related network activity, as well as Replica network activity. 683 */ getProtocolMessageWriteRate()684 public long getProtocolMessageWriteRate() { 685 IntegralLongAvgStat rstat = 686 protocolStats.getIntegralLongAvgStat(MESSAGE_WRITE_RATE); 687 return (rstat != null) ? rstat.get().longValue() : 0; 688 } 689 690 /** 691 * Bytes read throughput, in terms of bytes received from the replication 692 * network channels per second. 693 * <p> 694 * If the node has served as both a Replica and Master since it was first 695 * started, the number represents the bytes reading rate over all Feeder 696 * related network activity, as well as Replica network activity. 697 */ getProtocolBytesReadRate()698 public long getProtocolBytesReadRate() { 699 IntegralLongAvgStat rstat = 700 protocolStats.getIntegralLongAvgStat(BYTES_READ_RATE); 701 return (rstat != null) ? rstat.get().longValue() : 0; 702 } 703 704 /** 705 * Bytes written throughput, in terms of bytes written to the replication 706 * network channels per second. 707 * <p> 708 * If the node has served as both a Replica and Master since it was first 709 * started, the number represents the bytes writing rate over all Feeder 710 * related network activity, as well as Replica network activity. 711 */ getProtocolBytesWriteRate()712 public long getProtocolBytesWriteRate() { 713 IntegralLongAvgStat rstat = 714 protocolStats.getIntegralLongAvgStat(BYTES_WRITE_RATE); 715 return (rstat != null) ? rstat.get().longValue() : 0; 716 } 717 718 /** 719 * Returns the number of messages containing log entries that were written 720 * to the replication stream using the previous log format to support 721 * replication to a replica running an earlier version during an upgrade. 722 */ getNProtocolEntriesWrittenOldVersion()723 public long getNProtocolEntriesWrittenOldVersion() { 724 return protocolStats.getLong(N_ENTRIES_WRITTEN_OLD_VERSION); 725 } 726 727 /* ConsistencyTracker Stats. */ 728 729 /** 730 * The number of times a Replica held back a 731 * {@link Environment#beginTransaction(Transaction,TransactionConfig)} 732 * operation to satisfy the {@link TimeConsistencyPolicy}. 733 */ getTrackerLagConsistencyWaits()734 public long getTrackerLagConsistencyWaits() { 735 return trackerStats.getLong(N_LAG_CONSISTENCY_WAITS); 736 } 737 738 /** 739 * The total time (in msec) for which a Replica held back a 740 * {@link Environment#beginTransaction(Transaction,TransactionConfig)} 741 * operation to satisfy the {@link TimeConsistencyPolicy}. 742 */ getTrackerLagConsistencyWaitMs()743 public long getTrackerLagConsistencyWaitMs() { 744 return trackerStats.getLong(N_LAG_CONSISTENCY_WAIT_MS); 745 } 746 747 /** 748 * The number of times a Replica held back a 749 * {@link Environment#beginTransaction(Transaction,TransactionConfig)} 750 * operation to satisfy the {@link CommitPointConsistencyPolicy}. 751 */ getTrackerVLSNConsistencyWaits()752 public long getTrackerVLSNConsistencyWaits() { 753 return trackerStats.getLong(N_VLSN_CONSISTENCY_WAITS); 754 } 755 756 /** 757 * The total time (in msec) for which a Replica held back a 758 * {@link Environment#beginTransaction(Transaction,TransactionConfig)} 759 * operation to satisfy the {@link CommitPointConsistencyPolicy}. 760 */ getTrackerVLSNConsistencyWaitMs()761 public long getTrackerVLSNConsistencyWaitMs() { 762 return trackerStats.getLong(N_VLSN_CONSISTENCY_WAIT_MS); 763 } 764 765 /** 766 * Returns a string representation of the statistics. 767 */ 768 @Override toString()769 public String toString() { 770 StringBuilder sb = new StringBuilder(); 771 772 for (StatGroup group : getStatGroups()) { 773 sb.append(group.toString()); 774 } 775 776 return sb.toString(); 777 } 778 toStringVerbose()779 public String toStringVerbose() { 780 StringBuilder sb = new StringBuilder(); 781 782 for (StatGroup group : getStatGroups()) { 783 sb.append(group.toStringVerbose()); 784 } 785 786 return sb.toString(); 787 } 788 getTips()789 public Map<String, String> getTips() { 790 /* Add FeederManager stats definition. */ 791 792 for (StatGroup group : getStatGroups()) { 793 tipsMap.put(group.getName(), group.getDescription()); 794 for (StatDefinition def : group.getStats().keySet()) { 795 tipsMap.put(def.getName(), def.getDescription()); 796 } 797 } 798 799 return tipsMap; 800 } 801 } 802