diff options
author | Vesselina Ratcheva <vesselina.ratcheva@10gen.com> | 2021-10-27 21:34:16 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-11-19 20:18:04 +0000 |
commit | 157a20b50ab984e0e7431b18dd42b0c7f0d356fa (patch) | |
tree | 38fe9c3dbe75a16b929f7cf7f1215db2566bb859 | |
parent | 755aaba320ca2a2a163f198ee7d249e95fdd77e7 (diff) | |
download | mongo-157a20b50ab984e0e7431b18dd42b0c7f0d356fa.tar.gz |
SERVER-54909 Report last durable and last applied operation wall times for all members in replSetGetStatusr4.4.11-rc0
(cherry picked from commit 0cceba6f04b95f3652de84c2f1f4ab2a644dba6e)
-rw-r--r-- | etc/backports_required_for_multiversion_tests.yml | 2 | ||||
-rw-r--r-- | jstests/replsets/replSetGetStatus_member_wall_times.js | 84 | ||||
-rw-r--r-- | src/mongo/db/repl/topology_coordinator.cpp | 5 |
3 files changed, 91 insertions, 0 deletions
diff --git a/etc/backports_required_for_multiversion_tests.yml b/etc/backports_required_for_multiversion_tests.yml index 554d06a3748..f4a30d5ff8e 100644 --- a/etc/backports_required_for_multiversion_tests.yml +++ b/etc/backports_required_for_multiversion_tests.yml @@ -177,6 +177,8 @@ all: test_file: jstests/replsets/stepdown_race_with_transaction.js - ticket: SERVER-58636 test_file: jstests/replsets/initial_sync_replicate_drop_mid_secondary_batch.js + - ticket: SERVER-54909 + test_file: jstests/replsets/replSetGetStatus_member_wall_times.js 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 1030898b642..cec008da77b 100644 --- a/src/mongo/db/repl/topology_coordinator.cpp +++ b/src/mongo/db/repl/topology_coordinator.cpp @@ -1789,6 +1789,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()) { @@ -1847,6 +1849,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()); |