mirror of https://github.com/mongodb/mongo
125 lines
5.0 KiB
JavaScript
125 lines
5.0 KiB
JavaScript
import {ReplSetTest} from "jstests/libs/replsettest.js";
|
|
|
|
function nodeWithHighestPriorityStepsUp() {
|
|
// Test replica set with different priorities.
|
|
const replTest = new ReplSetTest({
|
|
name: "NodesWithDifferentPriorities",
|
|
nodes: [{rsConfig: {priority: 5}}, {}, {rsConfig: {priority: 0}}],
|
|
});
|
|
|
|
replTest.startSet();
|
|
replTest.initiate(null, null, {initiateWithDefaultElectionTimeout: true});
|
|
|
|
// Make sure that node[0] is the primary because it has the highest priority.
|
|
replTest.waitForState(replTest.nodes[0], ReplSetTest.State.PRIMARY);
|
|
|
|
// Stop the primary and wait for another node to become primary. Node 1 will become primary
|
|
// because the third node has priority 0 so it cannot become primary and cannot trigger
|
|
// elections.
|
|
const primary = replTest.getPrimary();
|
|
replTest.stop(primary, undefined /* signal */, {} /* options */, {forRestart: true});
|
|
replTest.waitForState(replTest.nodes[1], ReplSetTest.State.PRIMARY);
|
|
|
|
// Start the old primary again and make sure it becomes primary again due to priority takeover.
|
|
// Calling `stop()` and `start()` with `restart=true` will skip clearing the data directory
|
|
// before the server starts.
|
|
replTest.start(primary, {} /* options */, true /* restart */);
|
|
replTest.waitForState(primary, ReplSetTest.State.PRIMARY);
|
|
|
|
// Shut down the set and finish the test.
|
|
replTest.stopSet();
|
|
}
|
|
|
|
function manuallyStepUpNodeWhenHighElectionTimeoutSet() {
|
|
const replTest = new ReplSetTest({name: "highElectionTimeoutAndStepUp", nodes: 3});
|
|
|
|
replTest.startSet();
|
|
|
|
// Call `initiate` without `initiateWithDefaultElectionTimeout: true` when not testing election
|
|
// behavior. This initiates the replica set with high election timeout, which prevents unplanned
|
|
// elections from happening during the test, so we can maintain the same primary throughout the
|
|
// test.
|
|
replTest.initiate();
|
|
|
|
// Test some behavior.
|
|
const primary = replTest.getPrimary();
|
|
const primaryDB = primary.getDB("db");
|
|
assert.commandWorked(
|
|
primaryDB["collection"].insertMany(
|
|
[...Array(100).keys()].map((x) => ({a: x.toString()})),
|
|
{ordered: false},
|
|
),
|
|
);
|
|
|
|
// Call `stepUp()` to make another node the primary. This waits for all nodes to reach the same
|
|
// optime before sending the replSetStepUp command to the node, so that the stepup command will
|
|
// not fail because the candidate is too stale. It also waits for the new primary to become a
|
|
// writable primary.
|
|
const newPrimary = replTest.getSecondary();
|
|
replTest.stepUp(newPrimary);
|
|
replTest.waitForState(newPrimary, ReplSetTest.State.PRIMARY);
|
|
|
|
// Shut down the set and finish the test.
|
|
replTest.stopSet();
|
|
}
|
|
|
|
function frozenNodesDontTriggerElections() {
|
|
const replTest = new ReplSetTest({
|
|
name: "freezeNode",
|
|
nodes: [{rsConfig: {priority: 5}}, {rsConfig: {priority: 3}}, {rsConfig: {priority: 0}}],
|
|
});
|
|
replTest.startSet();
|
|
replTest.initiate(null, null, {initiateWithDefaultElectionTimeout: true});
|
|
|
|
// Step down the primary and freeze it for 30 seconds. Freezing a node prevents it from
|
|
// attempting to become primary.
|
|
const primary = replTest.getPrimary();
|
|
replTest.awaitReplication();
|
|
assert.commandWorked(primary.getDB("admin").runCommand({replSetStepDown: 10, force: true}));
|
|
assert.commandWorked(primary.getDB("admin").runCommand({replSetFreeze: 30}));
|
|
sleep(1000);
|
|
|
|
// Node 1 will then step up to become a primary after the election timeout because node 0 is
|
|
// frozen and node 2 has priority 0 so neither of them can start elections.
|
|
replTest.waitForState(replTest.nodes[1], ReplSetTest.State.PRIMARY);
|
|
|
|
// Unfreeze the primary before 30 seconds are up. The old primary will step up again now that it
|
|
// can start elections again.
|
|
assert.commandWorked(primary.getDB("admin").runCommand({replSetFreeze: 0}));
|
|
replTest.waitForState(primary, ReplSetTest.State.PRIMARY);
|
|
|
|
replTest.stopSet();
|
|
}
|
|
|
|
function dumpOplogEntries() {
|
|
const replTest = new ReplSetTest({name: "dumpOplogEntries", nodes: 3});
|
|
replTest.startSet();
|
|
|
|
// Call `initiate` without `initiateWithDefaultElectionTimeout: true` when not testing election
|
|
// behavior. This initiates the replica set with high election timeout, which prevents unplanned
|
|
// elections from happening during the test, so we can maintain the same primary throughout the
|
|
// test.
|
|
replTest.initiate();
|
|
|
|
// Insert some documents.
|
|
const primary = replTest.getPrimary();
|
|
const primaryDB = primary.getDB("db");
|
|
assert.commandWorked(
|
|
primaryDB["collection"].insertMany(
|
|
[...Array(5).keys()].map((x) => ({a: x.toString()})),
|
|
{ordered: false},
|
|
),
|
|
);
|
|
|
|
// Use `dumpOplog()` to print out oplog entries to help with debugging.
|
|
replTest.dumpOplog(primary);
|
|
|
|
// Shut down the set and finish the test.
|
|
replTest.stopSet();
|
|
}
|
|
|
|
nodeWithHighestPriorityStepsUp();
|
|
manuallyStepUpNodeWhenHighElectionTimeoutSet();
|
|
frozenNodesDontTriggerElections();
|
|
dumpOplogEntries();
|