summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVesselina Ratcheva <vesselina.ratcheva@10gen.com>2021-10-27 21:34:16 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-10-27 22:19:58 +0000
commit0cceba6f04b95f3652de84c2f1f4ab2a644dba6e (patch)
tree6671a328a415819f63b55be0d86390853eba0ac5
parent637b7ad320dc66908b2e468bb8f862ab81b328c5 (diff)
downloadmongo-0cceba6f04b95f3652de84c2f1f4ab2a644dba6e.tar.gz
SERVER-54909 Report last durable and last applied operation wall times for all members in replSetGetStatus
-rw-r--r--etc/backports_required_for_multiversion_tests.yml4
-rw-r--r--jstests/replsets/replSetGetStatus_member_wall_times.js84
-rw-r--r--src/mongo/db/repl/topology_coordinator.cpp5
3 files changed, 93 insertions, 0 deletions
diff --git a/etc/backports_required_for_multiversion_tests.yml b/etc/backports_required_for_multiversion_tests.yml
index c4bea5b638b..3fdbbcf2692 100644
--- a/etc/backports_required_for_multiversion_tests.yml
+++ b/etc/backports_required_for_multiversion_tests.yml
@@ -106,6 +106,8 @@ last-continuous:
test_file: jstests/core/sbe/sbe_cmd.js
- ticket: SERVER-56127
test_file: jstests/sharding/retryable_writes_nested_shard_key.js
+ - ticket: SERVER-54909
+ test_file: jstests/replsets/replSetGetStatus_member_wall_times.js
# Tests that should only be excluded from particular suites should be listed under that suite.
suites:
@@ -372,6 +374,8 @@ last-lts:
test_file: jstests/core/sbe/sbe_cmd.js
- ticket: SERVER-56127
test_file: jstests/sharding/retryable_writes_nested_shard_key.js
+ - ticket: SERVER-54909
+ test_file: jstests/replsets/replSetGetStatus_member_wall_times.js
# Tests that should only be excluded from particular suites should be listed under that suite.
suites:
diff --git a/jstests/replsets/replSetGetStatus_member_wall_times.js b/jstests/replsets/replSetGetStatus_member_wall_times.js
new file mode 100644
index 00000000000..4cd976a752b
--- /dev/null
+++ b/jstests/replsets/replSetGetStatus_member_wall_times.js
@@ -0,0 +1,84 @@
+/**
+ * Tests that replSetGetStatus responses include the last applied and durable wall times for other
+ * members.
+ *
+ * @tags: [multiversion_incompatible]
+ */
+
+(function() {
+"use strict";
+load("jstests/libs/write_concern_util.js");
+load("jstests/replsets/rslib.js");
+
+// We use GTE to account for the possibility of other writes in the system (e.g. HMAC).
+// Comparison is GTE by default, GT if 'strict' is specified.
+function checkWallTimes(primary, greaterMemberIndex, lesserMemberIndex, strict = false) {
+ let res = assert.commandWorked(primary.adminCommand({replSetGetStatus: 1}));
+ assert(res.members, () => tojson(res));
+
+ const greater = res.members[greaterMemberIndex];
+ assert(greater, () => tojson(res));
+ const greaterApplied = greater.lastAppliedWallTime;
+ const greaterDurable = greater.lastAppliedWallTime;
+ assert(greaterApplied, () => tojson(res));
+ assert(greaterDurable, () => tojson(res));
+
+ const lesser = res.members[lesserMemberIndex];
+ assert(lesser, () => tojson(res));
+ const lesserApplied = lesser.lastAppliedWallTime;
+ const lesserDurable = lesser.lastDurableWallTime;
+ assert(lesser.lastAppliedWallTime, () => tojson(res));
+ assert(lesser.lastDurableWallTime, () => tojson(res));
+
+ if (!strict) {
+ assert.gte(greaterApplied, lesserApplied, () => tojson(res));
+ assert.gte(greaterDurable, lesserDurable, () => tojson(res));
+ } else {
+ assert.gt(greaterApplied, lesserApplied, () => tojson(res));
+ assert.gt(greaterDurable, lesserDurable, () => tojson(res));
+ }
+}
+
+const name = jsTestName();
+const rst = new ReplSetTest({name: name, nodes: 3, settings: {chainingAllowed: false}});
+
+rst.startSet();
+rst.initiateWithHighElectionTimeout();
+rst.awaitReplication();
+
+const primary = rst.getPrimary(); // node 0
+const [caughtUpSecondary, laggedSecondary] = rst.getSecondaries(); // nodes 1 and 2
+
+const dbName = "testdb";
+const collName = "testcoll";
+const primaryDB = primary.getDB(dbName);
+const primaryColl = primaryDB.getCollection(collName);
+
+jsTestLog("Creating test collection");
+assert.commandWorked(primaryColl.insert({"one": 1}));
+rst.awaitReplication();
+
+checkWallTimes(primary, 0 /* greater */, 1 /* lesser */);
+checkWallTimes(primary, 0 /* greater */, 2 /* lesser */);
+
+jsTestLog("Stopping replication on secondary: " + laggedSecondary.host);
+stopServerReplication(laggedSecondary);
+
+jsTestLog("Adding more documents to collection");
+assert.commandWorked(primaryColl.insert({"two": 2}, {writeConcern: {w: 1}}));
+rst.awaitReplication(
+ undefined /* timeout */, undefined /* secondaryOpTimeType */, [caughtUpSecondary]);
+
+// Wall times of the lagged secondary should be strictly lesser.
+checkWallTimes(primary, 0 /* greater */, 2 /* lesser */, true /* strict */);
+checkWallTimes(primary, 1 /* greater */, 2 /* lesser */, true /* strict */);
+
+jsTestLog("Letting lagged secondary catch up");
+restartServerReplication(laggedSecondary);
+rst.awaitReplication();
+
+checkWallTimes(primary, 0 /* greater */, 1 /* lesser */);
+checkWallTimes(primary, 0 /* greater */, 2 /* lesser */);
+
+rst.stopSet();
+})();
diff --git a/src/mongo/db/repl/topology_coordinator.cpp b/src/mongo/db/repl/topology_coordinator.cpp
index a3df552f4df..68791c08a5d 100644
--- a/src/mongo/db/repl/topology_coordinator.cpp
+++ b/src/mongo/db/repl/topology_coordinator.cpp
@@ -1888,6 +1888,8 @@ void TopologyCoordinator::prepareStatusResponse(const ReplSetStatusArgs& rsStatu
appendOpTime(&bb, "optime", lastOpApplied);
bb.appendDate("optimeDate",
Date_t::fromDurationSinceEpoch(Seconds(lastOpApplied.getSecs())));
+ bb.appendDate("lastAppliedWallTime", it->getLastAppliedWallTime());
+ bb.appendDate("lastDurableWallTime", it->getLastDurableWallTime());
}
if (!_syncSource.empty() && !_iAmPrimary()) {
@@ -1946,6 +1948,9 @@ void TopologyCoordinator::prepareStatusResponse(const ReplSetStatusArgs& rsStatu
bb.appendDate("optimeDurableDate",
Date_t::fromDurationSinceEpoch(
Seconds(it->getHeartbeatDurableOpTime().getSecs())));
+
+ bb.appendDate("lastAppliedWallTime", it->getLastAppliedWallTime());
+ bb.appendDate("lastDurableWallTime", it->getLastDurableWallTime());
}
bb.appendDate("lastHeartbeat", it->getLastHeartbeat());
bb.appendDate("lastHeartbeatRecv", it->getLastHeartbeatRecv());