From ba9fe259f54fe41e2694d59809be5f42911bbe4b Mon Sep 17 00:00:00 2001 From: Tess Avitabile Date: Wed, 25 Oct 2017 12:07:41 -0400 Subject: SERVER-31633 If the featureCompatibilityVersion is 3.6, upgrading, or downgrading, respond to isMaster with minWireVersion=maxWireVersion --- jstests/multiVersion/2_test_launching_cluster.js | 5 +- .../set_feature_compatibility_version.js | 15 ++---- .../isMaster_feature_compatibility_version.js | 55 ++++++++++++++++++++++ .../db/commands/feature_compatibility_version.cpp | 3 +- src/mongo/db/repl/replication_info.cpp | 10 ++-- 5 files changed, 69 insertions(+), 19 deletions(-) create mode 100644 jstests/noPassthroughWithMongod/isMaster_feature_compatibility_version.js 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 minWireVersiongetServiceContext()->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); -- cgit v1.2.1