mirror of https://github.com/mongodb/mongo
69 lines
2.4 KiB
JavaScript
69 lines
2.4 KiB
JavaScript
/**
|
|
* Tests that step-up to become a primary during rollback won't crash the server with
|
|
* OplogOutOfOrder error after becoming a secondary again.
|
|
* Exercises the fix for SERVER-61977.
|
|
* @tags: [uses_transactions]
|
|
*/
|
|
|
|
import {configureFailPoint} from "jstests/libs/fail_point_util.js";
|
|
import {ReplSetTest} from "jstests/libs/replsettest.js";
|
|
import {restartServerReplication, stopServerReplication} from "jstests/libs/write_concern_util.js";
|
|
|
|
const rst = new ReplSetTest({
|
|
name: jsTestName(),
|
|
nodes: 3,
|
|
settings: {chainingAllowed: false, catchUpTimeoutMillis: 0},
|
|
useBridge: true,
|
|
});
|
|
|
|
rst.startSet();
|
|
rst.initiate();
|
|
const node0 = rst.getPrimary();
|
|
const node1 = rst.getSecondaries()[0];
|
|
const node2 = rst.getSecondaries()[1];
|
|
const testDB = node0.getDB("test");
|
|
const collName = jsTestName();
|
|
const coll = testDB[collName];
|
|
|
|
assert.commandWorked(testDB.createCollection(coll.getName()));
|
|
rst.awaitReplication();
|
|
|
|
stopServerReplication([node1, node2]);
|
|
|
|
// Add a non replicated write to the node0 to be rolled back later.
|
|
assert.commandWorked(coll.insert({_id: "write 1"}, {writeConcern: {w: 1}}));
|
|
|
|
let rollbackFp = configureFailPoint(node0, "rollbackHangBeforeTransitioningToRollback");
|
|
rst.stepUp(node2, {awaitReplicationBeforeStepUp: false});
|
|
|
|
// When node0 starts syncing from the node2, it will rollback the write that didn't get replicated.
|
|
rollbackFp.wait();
|
|
|
|
// Step-up node0 while it is hung at rollback.
|
|
rst.stepUp(node0, {awaitReplicationBeforeStepUp: false});
|
|
|
|
// Rollback will fail because we do not allow transitioning to follower mode from node0.
|
|
rollbackFp.off();
|
|
|
|
// Wait for node0 to step-up to avoid InterrupetedDueToReplStateChange errors in the inserts below.
|
|
restartServerReplication([node1, node2]);
|
|
rst.awaitNodesAgreeOnPrimary(rst.timeoutMS, rst.nodes, node0);
|
|
rst.awaitReplication();
|
|
|
|
// Advance the lastApplied on node0.
|
|
assert.commandWorked(coll.insert({_id: "write 2"}));
|
|
assert.commandWorked(coll.insert({_id: "write 3"}));
|
|
rst.awaitReplication();
|
|
|
|
// When node0 stepped down it will start syncing again from node2, and it shouldn't crash trying to
|
|
// apply entries older than the lastApplied.
|
|
rst.stepUp(node2);
|
|
rst.awaitNodesAgreeOnPrimary(rst.timeoutMS, rst.nodes, node2);
|
|
rst.awaitReplication();
|
|
|
|
// Verify node0 can replicate new writes.
|
|
assert.commandWorked(node2.getDB("test")[collName].insert({_id: "write 4"}));
|
|
rst.awaitReplication();
|
|
|
|
rst.stopSet();
|