summaryrefslogtreecommitdiff
path: root/jstests/replsets/reconfig_waits_for_config_durability.js
blob: 2ff5a25965fe3b6787e67ea8d0850b592dfaf127 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/**
 * Make sure that reconfig waits for the config document to be durable on nodes before returning.
 *
 * In this test, we disable all background checkpoints and journal flushes to eliminate those as a
 * cause for making writes durable. Then, we execute a reconfig on a replica set primary and wait
 * until the secondary has installed the new config. Finally, we SIGKILL the secondary and restart
 * it to verify that its config after restart is the same one it previously installed.
 *
 * @tags: [
 *   requires_persistence,
 * ]
 */
(function() {
"use strict";

load("jstests/libs/fail_point_util.js");

const rst = new ReplSetTest({
    nodes: [{}, {rsConfig: {priority: 0}}],
    nodeOptions: {
        // Disable background checkpoints: a zero value disables checkpointing.
        syncdelay: 0,
        setParameter: {logComponentVerbosity: tojson({storage: 2})}
    },
    useBridge: true
});
rst.startSet();
rst.initiateWithHighElectionTimeout();

// We will kill the secondary after it installs and acknowledges a config to make sure it has made
// it durable. Disable journaling on the node so we are sure that the config write is flushed
// explicitly.
const secondaryNodeId = 1;
const journalFp = configureFailPoint(rst.nodes[secondaryNodeId], "pauseJournalFlusherThread");
journalFp.wait();

// Pause the secondary applier thread so it does not cause extra journal flushes. Make sure we wait
// for the fail point to be hit before proceeding.
configureFailPoint(rst.getSecondary(), "rsSyncApplyStop").wait();

// Do a reconfig and wait for propagation to all nodes.
jsTestLog("Doing a reconfig.");
let config = rst.getReplSetConfigFromNode();
const newConfigVersion = config.version + 1;
config.version = newConfigVersion;
assert.commandWorked(rst.getPrimary().adminCommand({replSetReconfig: config}));
rst.awaitNodesAgreeOnConfigVersion();

// Verify the node has the right config.
assert.eq(rst.getReplSetConfigFromNode(secondaryNodeId).version, newConfigVersion);
jsTestLog("Finished waiting for reconfig to propagate.");

// Isolate node 1 so that it does not automatically learn of a new config via heartbeat after
// restart.
rst.nodes[1].disconnect([rst.nodes[0]]);

jsTestLog("Kill and restart the secondary node.");
rst.stop(secondaryNodeId, 9, {allowedExitCode: MongoRunner.EXIT_SIGKILL}, {forRestart: true});
rst.start(secondaryNodeId, undefined, true /* restart */);
rst.awaitSecondaryNodes();

// Make sure that node 1 still has the config it acknowledged.
assert.eq(rst.getReplSetConfigFromNode(secondaryNodeId).version, newConfigVersion);

// Re-connect the node to let the test complete.
rst.nodes[1].reconnect([rst.nodes[0]]);
rst.stopSet();
}());