2016-02-03 01:37:01 +01:00
|
|
|
/**
|
2019-07-27 00:20:35 +02:00
|
|
|
* This file defines a class, CSRSUpgradeCoordinator, which contains logic for spinning up a
|
|
|
|
* sharded cluster using SCCC config servers and for upgrading that cluster to CSRS.
|
|
|
|
* Include this file and use the CSRSUpgradeCoordinator class in any targetted jstests of csrs
|
|
|
|
* upgrade behavior.
|
|
|
|
*/
|
2016-02-03 01:37:01 +01:00
|
|
|
|
|
|
|
load("jstests/replsets/rslib.js");
|
|
|
|
|
|
|
|
var CSRSUpgradeCoordinator = function() {
|
2016-03-09 18:17:50 +01:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
var testDBName = jsTestName();
|
|
|
|
var dataCollectionName = testDBName + ".data";
|
|
|
|
var csrsName = jsTestName() + "-csrs";
|
|
|
|
var numCsrsMembers;
|
|
|
|
var st;
|
|
|
|
var shardConfigs;
|
|
|
|
var csrsConfig;
|
|
|
|
var csrs;
|
|
|
|
var csrs0Opts;
|
|
|
|
|
|
|
|
this.getTestDBName = function() {
|
|
|
|
return testDBName;
|
|
|
|
};
|
2016-02-03 01:37:01 +01:00
|
|
|
|
2016-03-09 18:17:50 +01:00
|
|
|
this.getDataCollectionName = function() {
|
|
|
|
return dataCollectionName;
|
|
|
|
};
|
2016-02-03 01:37:01 +01:00
|
|
|
|
2016-03-09 18:17:50 +01:00
|
|
|
/**
|
|
|
|
* Returns an array of connections to the CSRS nodes.
|
|
|
|
*/
|
|
|
|
this.getCSRSNodes = function() {
|
|
|
|
return csrs;
|
|
|
|
};
|
2016-02-03 01:37:01 +01:00
|
|
|
|
2016-03-09 18:17:50 +01:00
|
|
|
/**
|
|
|
|
* Returns the replica set name of the config server replica set.
|
|
|
|
*/
|
|
|
|
this.getCSRSName = function() {
|
|
|
|
return csrsName;
|
|
|
|
};
|
2016-02-03 01:37:01 +01:00
|
|
|
|
2016-03-09 18:17:50 +01:00
|
|
|
/**
|
|
|
|
* Returns a copy of the options used for starting a mongos in the coordinator's cluster.
|
|
|
|
*/
|
|
|
|
this.getMongosConfig = function() {
|
|
|
|
var sconfig = Object.extend({}, st.s0.fullOptions, /* deep */ true);
|
|
|
|
delete sconfig.port;
|
|
|
|
return sconfig;
|
|
|
|
};
|
2016-02-03 01:37:01 +01:00
|
|
|
|
2016-03-09 18:17:50 +01:00
|
|
|
this.getMongos = function(n) {
|
|
|
|
return st._mongos[n];
|
|
|
|
};
|
2016-02-03 01:37:01 +01:00
|
|
|
|
2016-03-09 18:17:50 +01:00
|
|
|
this.getShardName = function(n) {
|
|
|
|
return shardConfigs[n]._id;
|
|
|
|
};
|
2016-02-03 01:37:01 +01:00
|
|
|
|
2016-03-09 18:17:50 +01:00
|
|
|
/**
|
|
|
|
* Returns the ShardingTest fixture backing this CSRSUpgradeCoordinator.
|
|
|
|
*/
|
|
|
|
this.getShardingTestFixture = function() {
|
|
|
|
return st;
|
|
|
|
};
|
2016-02-03 01:37:01 +01:00
|
|
|
|
2016-03-09 18:17:50 +01:00
|
|
|
/**
|
|
|
|
* Private helper method for waiting for a given node to return ismaster:true in its ismaster
|
|
|
|
* command response.
|
|
|
|
*/
|
|
|
|
var _waitUntilMaster = function(dnode) {
|
|
|
|
var isMasterReply;
|
|
|
|
assert.soon(
|
|
|
|
function() {
|
|
|
|
isMasterReply = dnode.adminCommand({ismaster: 1});
|
|
|
|
return isMasterReply.ismaster;
|
|
|
|
},
|
|
|
|
function() {
|
|
|
|
return "Expected " + dnode.name + " to respond ismaster:true, but got " +
|
|
|
|
tojson(isMasterReply);
|
|
|
|
});
|
|
|
|
};
|
2016-02-03 01:37:01 +01:00
|
|
|
|
2016-03-09 18:17:50 +01:00
|
|
|
/**
|
|
|
|
* Restarts the first config server as a single node replica set, while still leaving the
|
|
|
|
* cluster
|
|
|
|
* operating in SCCC mode.
|
|
|
|
*/
|
|
|
|
this.restartFirstConfigAsReplSet = function() {
|
|
|
|
jsTest.log("Restarting " + st.c0.name + " as a standalone replica set");
|
2016-05-28 23:55:12 +02:00
|
|
|
csrsConfig =
|
|
|
|
{_id: csrsName, version: 1, configsvr: true, members: [{_id: 0, host: st.c0.name}]};
|
2016-03-09 18:17:50 +01:00
|
|
|
assert.commandWorked(st.c0.adminCommand({replSetInitiate: csrsConfig}));
|
|
|
|
csrs = [];
|
|
|
|
csrs0Opts = Object.extend({}, st.c0.fullOptions, /* deep */ true);
|
|
|
|
csrs0Opts.restart = true; // Don't clean the data files from the old c0.
|
|
|
|
csrs0Opts.replSet = csrsName;
|
|
|
|
csrs0Opts.configsvrMode = "sccc";
|
|
|
|
MongoRunner.stopMongod(st.c0);
|
|
|
|
csrs.push(MongoRunner.runMongod(csrs0Opts));
|
|
|
|
_waitUntilMaster(csrs[0]);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Starts up the new members of the config server replica set as non-voting, priority zero
|
|
|
|
* nodes.
|
|
|
|
*/
|
|
|
|
this.startNewCSRSNodes = function() {
|
|
|
|
jsTest.log("Starting new CSRS nodes");
|
|
|
|
for (var i = 1; i < numCsrsMembers; ++i) {
|
|
|
|
csrs.push(MongoRunner.runMongod(
|
|
|
|
{replSet: csrsName, configsvr: "", storageEngine: "wiredTiger"}));
|
|
|
|
csrsConfig.members.push({_id: i, host: csrs[i].name, votes: 0, priority: 0});
|
2016-02-03 01:37:01 +01:00
|
|
|
}
|
2016-03-09 18:17:50 +01:00
|
|
|
csrsConfig.version = 2;
|
|
|
|
jsTest.log("Adding non-voting members to csrs set: " + tojson(csrsConfig));
|
|
|
|
assert.commandWorked(csrs[0].adminCommand({replSetReconfig: csrsConfig}));
|
|
|
|
};
|
2016-02-03 01:37:01 +01:00
|
|
|
|
2016-03-09 18:17:50 +01:00
|
|
|
this.waitUntilConfigsCaughtUp = function() {
|
|
|
|
waitUntilAllNodesCaughtUp(csrs, 60000);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Stops one of the SCCC config servers, thus disabling changes to cluster metadata and
|
|
|
|
* preventing
|
|
|
|
* any further writes to the config servers until the upgrade to CSRS is completed.
|
|
|
|
*/
|
|
|
|
this.shutdownOneSCCCNode = function() {
|
|
|
|
// Only shut down one of the SCCC config servers to avoid any period without any config
|
|
|
|
// servers
|
|
|
|
// online.
|
|
|
|
jsTest.log("Shutting down third SCCC config server node");
|
|
|
|
MongoRunner.stopMongod(st.c2);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Allows all CSRS members to vote, in preparation for switching fully to CSRS mode.
|
|
|
|
*/
|
|
|
|
this.allowAllCSRSNodesToVote = function() {
|
|
|
|
csrsConfig.members.forEach(function(member) {
|
|
|
|
member.votes = 1;
|
|
|
|
member.priority = 1;
|
|
|
|
});
|
|
|
|
csrsConfig.version = 3;
|
|
|
|
jsTest.log("Allowing all csrs members to vote: " + tojson(csrsConfig));
|
|
|
|
assert.commandWorked(csrs[0].adminCommand({replSetReconfig: csrsConfig}));
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Restarts the first member of the config server replica set without the --configsvrMode flag,
|
|
|
|
* marking the official switchover from SCCC to CSRS mode. If the first config server doesn't
|
|
|
|
* support readCommitted, waits for it to automatically go into the REMOVED state. Finally,
|
|
|
|
* it shuts down the one remaining SCCC config server node now that it is no longer needed.
|
|
|
|
*/
|
|
|
|
this.switchToCSRSMode = function() {
|
|
|
|
jsTest.log("Restarting " + csrs[0].name + " in csrs mode");
|
|
|
|
delete csrs0Opts.configsvrMode;
|
2019-02-07 21:52:06 +01:00
|
|
|
assert.commandWorked(csrs[0].adminCommand({replSetStepDown: 60}));
|
2016-03-09 18:17:50 +01:00
|
|
|
MongoRunner.stopMongod(csrs[0]);
|
|
|
|
csrs[0] = MongoRunner.runMongod(csrs0Opts);
|
|
|
|
var csrsStatus;
|
|
|
|
assert.soon(
|
|
|
|
function() {
|
|
|
|
csrsStatus = csrs[0].adminCommand({replSetGetStatus: 1});
|
|
|
|
if (csrsStatus.members[0].stateStr == "STARTUP" ||
|
|
|
|
csrsStatus.members[0].stateStr == "STARTUP2" ||
|
|
|
|
csrsStatus.members[0].stateStr == "RECOVERING") {
|
|
|
|
// Make sure first node is fully online or else mongoses still in SCCC mode
|
|
|
|
// might not
|
|
|
|
// find any node online to talk to.
|
2016-02-03 01:37:01 +01:00
|
|
|
return false;
|
|
|
|
}
|
2016-03-09 18:17:50 +01:00
|
|
|
|
|
|
|
var i;
|
|
|
|
for (i = 0; i < csrsStatus.members.length; ++i) {
|
|
|
|
if (csrsStatus.members[i].name == csrs[0].name) {
|
|
|
|
var supportsCommitted = csrs[0]
|
|
|
|
.getDB("admin")
|
|
|
|
.serverStatus()
|
|
|
|
.storageEngine.supportsCommittedReads;
|
|
|
|
var stateIsRemoved = csrsStatus.members[i].stateStr == "REMOVED";
|
|
|
|
// If the storage engine supports committed reads, it shouldn't go into
|
|
|
|
// REMOVED
|
|
|
|
// state, but if it does not then it should.
|
|
|
|
if (supportsCommitted) {
|
|
|
|
assert(!stateIsRemoved);
|
|
|
|
} else if (!stateIsRemoved) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (csrsStatus.members[i].stateStr == "PRIMARY") {
|
|
|
|
return csrs[i].adminCommand({ismaster: 1}).ismaster;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
function() {
|
|
|
|
return "No primary or non-WT engine not removed in " + tojson(csrsStatus);
|
|
|
|
});
|
|
|
|
|
|
|
|
jsTest.log("Shutting down final SCCC config server now that upgrade is complete");
|
|
|
|
MongoRunner.stopMongod(st.c1);
|
|
|
|
};
|
2019-02-07 21:52:06 +01:00
|
|
|
};
|