diff options
author | Tess Avitabile <tess.avitabile@mongodb.com> | 2017-10-25 12:07:41 -0400 |
---|---|---|
committer | Tess Avitabile <tess.avitabile@mongodb.com> | 2017-10-27 16:24:18 -0400 |
commit | ba9fe259f54fe41e2694d59809be5f42911bbe4b (patch) | |
tree | 79b80b1676f2beb7cd11c22157a53f5e54132cf5 | |
parent | 58da3876b02408e5c19927f1b342b8e40835bc86 (diff) | |
download | mongo-ba9fe259f54fe41e2694d59809be5f42911bbe4b.tar.gz |
SERVER-31633 If the featureCompatibilityVersion is 3.6, upgrading, or downgrading, respond to isMaster with minWireVersion=maxWireVersion
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); |