summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTess Avitabile <tess.avitabile@mongodb.com>2017-10-25 12:07:41 -0400
committerTess Avitabile <tess.avitabile@mongodb.com>2017-10-27 16:24:18 -0400
commitba9fe259f54fe41e2694d59809be5f42911bbe4b (patch)
tree79b80b1676f2beb7cd11c22157a53f5e54132cf5
parent58da3876b02408e5c19927f1b342b8e40835bc86 (diff)
downloadmongo-ba9fe259f54fe41e2694d59809be5f42911bbe4b.tar.gz
SERVER-31633 If the featureCompatibilityVersion is 3.6, upgrading, or downgrading, respond to isMaster with minWireVersion=maxWireVersion
-rw-r--r--jstests/multiVersion/2_test_launching_cluster.js5
-rw-r--r--jstests/multiVersion/set_feature_compatibility_version.js15
-rw-r--r--jstests/noPassthroughWithMongod/isMaster_feature_compatibility_version.js55
-rw-r--r--src/mongo/db/commands/feature_compatibility_version.cpp3
-rw-r--r--src/mongo/db/repl/replication_info.cpp10
5 files changed, 69 insertions, 19 deletions
diff --git a/jstests/multiVersion/2_test_launching_cluster.js b/jstests/multiVersion/2_test_launching_cluster.js
index 47368a27331..4e81fce3602 100644
--- a/jstests/multiVersion/2_test_launching_cluster.js
+++ b/jstests/multiVersion/2_test_launching_cluster.js
@@ -15,6 +15,7 @@ load('./jstests/multiVersion/libs/verify_versions.js');
"use strict";
// Check our latest versions
var versionsToCheck = ["last-stable", "latest"];
+ var versionsToCheckConfig = ["latest"];
var versionsToCheckMongos = ["last-stable"];
jsTest.log("Testing mixed versions...");
@@ -25,7 +26,7 @@ load('./jstests/multiVersion/libs/verify_versions.js');
mongos: 2,
other: {
mongosOptions: {binVersion: versionsToCheckMongos},
- configOptions: {binVersion: versionsToCheck},
+ configOptions: {binVersion: versionsToCheckConfig},
shardOptions: {binVersion: versionsToCheck},
enableBalancer: true
}
@@ -52,7 +53,7 @@ load('./jstests/multiVersion/libs/verify_versions.js');
for (var j = 0; j < configs.length; j++)
versionsFound.push(configs[j].getBinVersion());
- assert.allBinVersions(versionsToCheck, versionsFound);
+ assert.allBinVersions(versionsToCheckConfig, versionsFound);
st.stop();
})();
diff --git a/jstests/multiVersion/set_feature_compatibility_version.js b/jstests/multiVersion/set_feature_compatibility_version.js
index d85e660cb83..2ee29b36404 100644
--- a/jstests/multiVersion/set_feature_compatibility_version.js
+++ b/jstests/multiVersion/set_feature_compatibility_version.js
@@ -367,18 +367,13 @@ TestData.skipCheckingUUIDsConsistentAcrossCluster = true;
assert.writeOK(
primaryAdminDB.getSiblingDB("test").coll.insert({awaitRepl: true}, {writeConcern: {w: 3}}));
- // Test that a 3.4 secondary crashes when syncing from a 3.6 primary and the
+ // Test that a 3.4 secondary can no longer replicate from the primary after the
// featureCompatibilityVersion is set to 3.6.
assert.commandWorked(primary.adminCommand({setFeatureCompatibilityVersion: "3.6"}));
- assert.soon(function() {
- try {
- secondaryAdminDB.runCommand({ping: 1});
- } catch (e) {
- return true;
- }
- return false;
- }, "Expected 3.4 secondary to terminate due to replicating featureCompatibilityVersion=3.6");
- rst.stop(secondary, undefined, {allowedExitCode: MongoRunner.EXIT_ABRUPT});
+ checkFCV34(secondaryAdminDB, "3.4");
+ assert.writeOK(primaryAdminDB.getSiblingDB("test").coll.insert({shouldReplicate: false}));
+ assert.eq(secondaryAdminDB.getSiblingDB("test").coll.find({shouldReplicate: false}).itcount(),
+ 0);
rst.stopSet();
// A mixed 3.4/3.6 replica set without a featureCompatibilityVersion document unfortunately
diff --git a/jstests/noPassthroughWithMongod/isMaster_feature_compatibility_version.js b/jstests/noPassthroughWithMongod/isMaster_feature_compatibility_version.js
new file mode 100644
index 00000000000..53ef53bff5b
--- /dev/null
+++ b/jstests/noPassthroughWithMongod/isMaster_feature_compatibility_version.js
@@ -0,0 +1,55 @@
+// Tests that when the featureCompatibilityVersion is not equal to the downgrade version, running
+// isMaster with internalClient returns a response with minWireVersion=maxWireVersion. This ensures
+// that an older version mongod/mongos will fail to connect to the node when it is upgraded,
+// upgrading, or downgrading.
+(function() {
+ "use strict";
+
+ const adminDB = db.getSiblingDB("admin");
+ const isMasterCommand = {
+ isMaster: 1,
+ internalClient: {minWireVersion: NumberInt(0), maxWireVersion: NumberInt(6)}
+ };
+ const upgradeVersion = "3.6";
+ const downgradeVersion = "3.4";
+
+ // When the featureCompatibilityVersion is equal to the upgrade version, running isMaster with
+ // internalClient returns minWireVersion=maxWireVersion.
+ assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: upgradeVersion}));
+ let res = adminDB.runCommand(isMasterCommand);
+ assert.commandWorked(res);
+ assert.eq(res.minWireVersion, res.maxWireVersion, tojson(res));
+
+ // When the featureCompatibilityVersion is upgrading, running isMaster with internalClient
+ // returns minWireVersion=maxWireVersion.
+ assert.writeOK(adminDB.system.version.update(
+ {_id: "featureCompatibilityVersion"},
+ {$set: {version: downgradeVersion, targetVersion: upgradeVersion}}));
+ res = adminDB.runCommand(isMasterCommand);
+ assert.commandWorked(res);
+ assert.eq(res.minWireVersion, res.maxWireVersion, tojson(res));
+
+ // When the featureCompatibilityVersion is downgrading, running isMaster with internalClient
+ // returns minWireVersion=maxWireVersion.
+ assert.writeOK(adminDB.system.version.update(
+ {_id: "featureCompatibilityVersion"},
+ {$set: {version: downgradeVersion, targetVersion: downgradeVersion}}));
+ res = adminDB.runCommand(isMasterCommand);
+ assert.commandWorked(res);
+ assert.eq(res.minWireVersion, res.maxWireVersion, tojson(res));
+
+ // When the featureCompatibilityVersion is equal to the downgrade version, running isMaster with
+ // internalClient returns minWireVersion<maxWireVersion.
+ assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: downgradeVersion}));
+ res = adminDB.runCommand(isMasterCommand);
+ assert.commandWorked(res);
+ assert.lt(res.minWireVersion, res.maxWireVersion, tojson(res));
+
+ // When the internalClient field is missing from the isMaster command, the response has
+ // minWireVersion<maxWireVersion, even if the featureCompatibilityVersion is equal to the
+ // upgrade version.
+ assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: upgradeVersion}));
+ res = adminDB.runCommand({isMaster: 1});
+ assert.commandWorked(res);
+ assert.lt(res.minWireVersion, res.maxWireVersion, tojson(res));
+})();
diff --git a/src/mongo/db/commands/feature_compatibility_version.cpp b/src/mongo/db/commands/feature_compatibility_version.cpp
index a96335aca1a..45f430a5a24 100644
--- a/src/mongo/db/commands/feature_compatibility_version.cpp
+++ b/src/mongo/db/commands/feature_compatibility_version.cpp
@@ -337,8 +337,7 @@ void FeatureCompatibilityVersion::onInsertOrUpdate(OperationContext* opCtx, cons
serverGlobalParams.featureCompatibility.setVersion(newVersion);
// Close all connections from internal clients with binary versions lower than 3.6.
- if (newVersion == ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo36 ||
- newVersion == ServerGlobalParams::FeatureCompatibility::Version::kUpgradingTo36) {
+ if (newVersion != ServerGlobalParams::FeatureCompatibility::Version::kFullyDowngradedTo34) {
opCtx->getServiceContext()->getServiceEntryPoint()->endAllSessions(
transport::Session::kLatestVersionInternalClientKeepOpen |
transport::Session::kExternalClientKeepOpen);
diff --git a/src/mongo/db/repl/replication_info.cpp b/src/mongo/db/repl/replication_info.cpp
index 3391dc3aa19..5d116d1fe2e 100644
--- a/src/mongo/db/repl/replication_info.cpp
+++ b/src/mongo/db/repl/replication_info.cpp
@@ -359,12 +359,12 @@ public:
result.append("maxWireVersion", WireSpec::instance().incoming.maxWireVersion);
result.append("logicalSessionTimeoutMinutes", localLogicalSessionTimeoutMinutes);
- // If the featureCompatibilityVersion is 3.6, respond with minWireVersion=maxWireVersion.
- // Then if the connection is from a mongod/mongos of an earlier version, it will fail to
- // connect.
+ // If the featureCompatibilityVersion is 3.6 (or upgrading or downgrading), respond with
+ // minWireVersion=maxWireVersion. Then if the connection is from a mongod/mongos of an
+ // earlier version, it will fail to connect.
if (internalClientElement &&
- serverGlobalParams.featureCompatibility.getVersion() ==
- ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo36) {
+ serverGlobalParams.featureCompatibility.getVersion() !=
+ ServerGlobalParams::FeatureCompatibility::Version::kFullyDowngradedTo34) {
result.append("minWireVersion", WireSpec::instance().incoming.maxWireVersion);
} else {
result.append("minWireVersion", WireSpec::instance().incoming.minWireVersion);