summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorXueruiFa <xuerui.fa@mongodb.com>2023-03-28 13:47:51 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-03-28 15:52:51 +0000
commit126ce85a4844f7d7bf794567fc327926b47c1505 (patch)
treeadfb564608ab13e75edca5779dfc1232f9e8a721 /src
parenta1bc513d167d4238b0d88a94de74e19e84817791 (diff)
downloadmongo-126ce85a4844f7d7bf794567fc327926b47c1505.tar.gz
SERVER-73691: Require confirmation for upgrade/downgrade
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/commands/set_feature_compatibility_version.idl10
-rw-r--r--src/mongo/db/commands/set_feature_compatibility_version_command.cpp62
-rw-r--r--src/mongo/db/repl/repl_server_parameters.idl11
-rw-r--r--src/mongo/shell/replsettest.js32
-rw-r--r--src/mongo/shell/servers.js15
5 files changed, 103 insertions, 27 deletions
diff --git a/src/mongo/db/commands/set_feature_compatibility_version.idl b/src/mongo/db/commands/set_feature_compatibility_version.idl
index ecdf2e5b1c3..565f8ee180c 100644
--- a/src/mongo/db/commands/set_feature_compatibility_version.idl
+++ b/src/mongo/db/commands/set_feature_compatibility_version.idl
@@ -58,6 +58,16 @@ commands:
api_version: ""
type: fcv_string
fields:
+ confirm:
+ description: "A required parameter that ensures that the user is
+ upgrading/downgrading with support assistance. Internal setFCV
+ commands issue from the config svr will not require this parameter.
+ If this parameter is not specified from a user command, the setFCV
+ command will error out. This parameter is declared optional so that
+ we can provide the user with a custom error message if it is not
+ specified."
+ type: safeBool
+ optional: true
fromConfigServer:
description: "A boolean that indicates whether the command is being requested by a
config server. Normally FCV upgrades between last-lts and anything
diff --git a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp
index 030e8a9d389..44ad2baf745 100644
--- a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp
+++ b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp
@@ -262,26 +262,6 @@ public:
const DatabaseName&,
const BSONObj& cmdObj,
BSONObjBuilder& result) override {
- // Always wait for at least majority writeConcern to ensure all writes involved in the
- // upgrade process cannot be rolled back. There is currently no mechanism to specify a
- // default writeConcern, so we manually call waitForWriteConcern upon exiting this command.
- //
- // TODO SERVER-25778: replace this with the general mechanism for specifying a default
- // writeConcern.
- ON_BLOCK_EXIT([&] {
- WriteConcernResult res;
- auto waitForWCStatus = waitForWriteConcern(
- opCtx,
- repl::ReplClientInfo::forClient(opCtx->getClient()).getLastOp(),
- WriteConcernOptions(
- repl::ReplSetConfig::kMajorityWriteConcernModeName,
- WriteConcernOptions::SyncMode::UNSET,
- // Propagate the user's wTimeout if one was given. Default is kNoTimeout.
- opCtx->getWriteConcern().wTimeout),
- &res);
- CommandHelpers::appendCommandWCStatus(result, waitForWCStatus, res);
- });
-
// Ensure that this operation will be killed by the RstlKillOpThread during step-up or
// stepdown.
opCtx->setAlwaysInterruptAtStepDownOrUp_UNSAFE();
@@ -302,9 +282,49 @@ public:
const auto requestedVersion = request.getCommandParameter();
const auto actualVersion = serverGlobalParams.featureCompatibility.getVersion();
+ auto isConfirmed = request.getConfirm().value_or(false);
+ // TODO (SERVER-74398): Remove this flag once 7.0 is last LTS.
+ if (mongo::repl::requireConfirmInSetFcv) {
+ const auto upgradeMsg =
+ "Once you have upgraded to {}, you will not be able to downgrade FCV and binary version without support assistance. Please re-run this command with 'confirm: true' to acknowledge this and continue with the FCV upgrade."_format(
+ multiversion::toString(requestedVersion));
+ const auto downgradeMsg =
+ "Once you have downgraded the FCV, if you choose to downgrade the binary version, "
+ "it will require support assistance. Please re-run this command with 'confirm: "
+ "true' to acknowledge this and continue with the FCV downgrade.";
+ uassert(7369100,
+ (requestedVersion > actualVersion ? upgradeMsg : downgradeMsg),
+ // If the request is from a config svr, skip requiring the 'confirm: true'
+ // parameter.
+ (isFromConfigServer || isConfirmed));
+ }
+
+ // Always wait for at least majority writeConcern to ensure all writes involved in the
+ // upgrade/downgrade process cannot be rolled back. There is currently no mechanism to
+ // specify a default writeConcern, so we manually call waitForWriteConcern upon exiting this
+ // command.
+ //
+ // TODO SERVER-25778: replace this with the general mechanism for specifying a default
+ // writeConcern.
+ ON_BLOCK_EXIT([&] {
+ WriteConcernResult res;
+ auto waitForWCStatus = waitForWriteConcern(
+ opCtx,
+ repl::ReplClientInfo::forClient(opCtx->getClient()).getLastOp(),
+ WriteConcernOptions(
+ repl::ReplSetConfig::kMajorityWriteConcernModeName,
+ WriteConcernOptions::SyncMode::UNSET,
+ // Propagate the user's wTimeout if one was given. Default is kNoTimeout.
+ opCtx->getWriteConcern().wTimeout),
+ &res);
+ CommandHelpers::appendCommandWCStatus(result, waitForWCStatus, res);
+ });
+
if (requestedVersion == actualVersion) {
// Set the client's last opTime to the system last opTime so no-ops wait for
- // writeConcern.
+ // writeConcern. This will wait for any previous setFCV disk writes to be majority
+ // committed before returning to the user, if the previous setFCV command had updated
+ // the FCV but encountered failover afterwards.
repl::ReplClientInfo::forClient(opCtx->getClient()).setLastOpToSystemLastOpTime(opCtx);
// TODO SERVER-72796: Remove once gGlobalIndexesShardingCatalog is enabled.
diff --git a/src/mongo/db/repl/repl_server_parameters.idl b/src/mongo/db/repl/repl_server_parameters.idl
index a2aaabcd23d..c55580c92e9 100644
--- a/src/mongo/db/repl/repl_server_parameters.idl
+++ b/src/mongo/db/repl/repl_server_parameters.idl
@@ -611,6 +611,17 @@ server_parameters:
cpp_varname: enableReconfigRollbackCommittedWritesCheck
default: true
+ # TODO (SERVER-74398): Remove special handling of 'confirm: true' in setFCV.
+ requireConfirmInSetFcv:
+ description: >-
+ Determines if we must specify 'confirm: true' in the setFCV command. Enabled by default.
+ Test-only.
+ test_only: true
+ set_at: startup
+ cpp_vartype: bool
+ cpp_varname: requireConfirmInSetFcv
+ default: true
+
initialSyncMethod:
description: >-
Specifies which method of initial sync to use. Valid options are: fileCopyBased,
diff --git a/src/mongo/shell/replsettest.js b/src/mongo/shell/replsettest.js
index ad1c8e1c037..6667d5dba62 100644
--- a/src/mongo/shell/replsettest.js
+++ b/src/mongo/shell/replsettest.js
@@ -1437,8 +1437,17 @@ var ReplSetTest = function(opts) {
asCluster(self.nodes, function setFCV() {
let fcv = setLastLTSFCV ? lastLTSFCV : lastContinuousFCV;
print("Setting feature compatibility version for replica set to '" + fcv + "'");
- assert.commandWorked(
- self.getPrimary().adminCommand({setFeatureCompatibilityVersion: fcv}));
+ const res = self.getPrimary().adminCommand({setFeatureCompatibilityVersion: fcv});
+ // TODO (SERVER-74398): Remove the retry with 'confirm: true' once 7.0 is last LTS.
+ if (!res.ok && res.code === 7369100) {
+ // We failed due to requiring 'confirm: true' on the command. This will only
+ // occur on 7.0+ nodes that have 'enableTestCommands' set to false. Retry the
+ // setFCV command with 'confirm: true'.
+ assert.commandWorked(self.getPrimary().adminCommand(
+ {setFeatureCompatibilityVersion: fcv, confirm: true}));
+ } else {
+ assert.commandWorked(res);
+ }
checkFCV(self.getPrimary().getDB("admin"), fcv);
// The server has a practice of adding a reconfig as part of upgrade/downgrade logic
@@ -1606,8 +1615,17 @@ var ReplSetTest = function(opts) {
asCluster(self.nodes, function setFCV() {
let fcv = jsTest.options().replSetFeatureCompatibilityVersion;
print("Setting feature compatibility version for replica set to '" + fcv + "'");
- assert.commandWorked(
- self.getPrimary().adminCommand({setFeatureCompatibilityVersion: fcv}));
+ const res = self.getPrimary().adminCommand({setFeatureCompatibilityVersion: fcv});
+ // TODO (SERVER-74398): Remove the retry with 'confirm: true' once 7.0 is last LTS.
+ if (!res.ok && res.code === 7369100) {
+ // We failed due to requiring 'confirm: true' on the command. This will only
+ // occur on 7.0+ nodes that have 'enableTestCommands' set to false. Retry the
+ // setFCV command with 'confirm: true'.
+ assert.commandWorked(self.getPrimary().adminCommand(
+ {setFeatureCompatibilityVersion: fcv, confirm: true}));
+ } else {
+ assert.commandWorked(res);
+ }
// Wait for the new 'featureCompatibilityVersion' to propagate to all nodes in the
// replica set. The 'setFeatureCompatibilityVersion' command only waits for
@@ -2845,6 +2863,12 @@ var ReplSetTest = function(opts) {
// downgrading from latest to last continuous.
options.setParameter.disableTransitionFromLatestToLastContinuous =
options.setParameter.disableTransitionFromLatestToLastContinuous || false;
+
+ // TODO (SERVER-74398): Remove special handling of 'confirm: true' once we no longer run
+ // suites with v6.X. We disable this check by default now so that we can pass suites
+ // without individually handling each multiversion test running on old binaries.
+ options.setParameter.requireConfirmInSetFcv =
+ options.setParameter.requireConfirmInSetFcv || false;
}
if (tojson(options) != tojson({}))
diff --git a/src/mongo/shell/servers.js b/src/mongo/shell/servers.js
index 58808c2aaa7..2e6e5bbbb2e 100644
--- a/src/mongo/shell/servers.js
+++ b/src/mongo/shell/servers.js
@@ -710,10 +710,10 @@ MongoRunner.mongodOptions = function(opts = {}) {
opts.pathOpts = Object.merge(opts.pathOpts, {dbpath: opts.dbpath});
- // TODO (SERVER-74847): Remove this transition once we remove testing around
- // downgrading from latest to last continuous.
opts.setParameter = opts.setParameter || {};
if (jsTestOptions().enableTestCommands && typeof opts.setParameter !== "string") {
+ // TODO (SERVER-74847): Remove this transition once we remove testing around
+ // downgrading from latest to last continuous.
if (jsTestOptions().setParameters &&
jsTestOptions().setParameters.disableTransitionFromLatestToLastContinuous) {
opts.setParameter["disableTransitionFromLatestToLastContinuous"] =
@@ -721,6 +721,16 @@ MongoRunner.mongodOptions = function(opts = {}) {
} else {
opts.setParameter["disableTransitionFromLatestToLastContinuous"] = false;
}
+
+ // TODO (SERVER-74398): Remove special handling of 'confirm: true' once we no longer run
+ // suites with v6.X. We disable this check by default now so that we can pass suites
+ // without individually handling each multiversion test running on old binaries.
+ if (jsTestOptions().setParameters && jsTestOptions().setParameters.requireConfirmInSetFcv) {
+ opts.setParameter["requireConfirmInSetFcv"] =
+ jsTestOptions().setParameters.requireConfirmInSetFcv;
+ } else {
+ opts.setParameter["requireConfirmInSetFcv"] = false;
+ }
}
_removeSetParameterIfBeforeVersion(opts, "writePeriodicNoops", "3.3.12");
@@ -739,6 +749,7 @@ MongoRunner.mongodOptions = function(opts = {}) {
opts, "internalQueryDisableExclusionProjectionFastPath", "6.2.0");
_removeSetParameterIfBeforeVersion(
opts, "disableTransitionFromLatestToLastContinuous", "7.0.0");
+ _removeSetParameterIfBeforeVersion(opts, "requireConfirmInSetFcv", "7.0.0");
if (!opts.logFile && opts.useLogFiles) {
opts.logFile = opts.dbpath + "/mongod.log";