diff options
author | Tommaso Tocci <tommaso.tocci@mongodb.com> | 2022-11-12 01:20:43 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-11-12 01:54:07 +0000 |
commit | 2041a8a461f42c6fc1c257e87e88c6ae695a51a8 (patch) | |
tree | 3bfd0a72bc7e8394c558f24ec4e3316c0aa293ea | |
parent | fffe2cb03d8f3a826f7039614ee1c12d88917440 (diff) | |
download | mongo-2041a8a461f42c6fc1c257e87e88c6ae695a51a8.tar.gz |
SERVER-68888 Remove deprecated fields from config.version
19 files changed, 184 insertions, 793 deletions
diff --git a/jstests/multiVersion/genericSetFCVUsage/upgrade_downgrade_cluster.js b/jstests/multiVersion/genericSetFCVUsage/upgrade_downgrade_cluster.js index 4133e250493..fbb6a9a2687 100644 --- a/jstests/multiVersion/genericSetFCVUsage/upgrade_downgrade_cluster.js +++ b/jstests/multiVersion/genericSetFCVUsage/upgrade_downgrade_cluster.js @@ -16,9 +16,6 @@ load('./jstests/multiVersion/libs/multi_cluster.js'); // command is nondeterministic, skip the consistency check for this test. TestData.skipCheckingUUIDsConsistentAcrossCluster = true; -const kMinVersion = 5; -const kCurrentVerion = 6; - var testCRUDAndAgg = function(db) { assert.commandWorked(db.foo.insert({x: 1})); assert.commandWorked(db.foo.insert({x: -1})); @@ -52,11 +49,8 @@ for (let oldVersion of ["last-lts", "last-continuous"]) { // check that config.version document gets initialized properly var version = st.s.getCollection('config.version').findOne(); - assert.eq(version.minCompatibleVersion, kMinVersion); - assert.eq(version.currentVersion, kCurrentVerion); var clusterID = version.clusterId; assert.neq(null, clusterID); - assert.eq(version.excluding, undefined); // Setup sharded collection assert.commandWorked(st.s.adminCommand({enableSharding: 'sharded'})); @@ -114,10 +108,7 @@ for (let oldVersion of ["last-lts", "last-continuous"]) { // Check that version document is unmodified. version = st.s.getCollection('config.version').findOne(); - assert.eq(version.minCompatibleVersion, kMinVersion); - assert.eq(version.currentVersion, kCurrentVerion); assert.eq(clusterID, version.clusterId); - assert.eq(version.excluding, undefined); /////////////////////////////////////////////////////////////////////////////////////////// // Downgrade back @@ -163,10 +154,7 @@ for (let oldVersion of ["last-lts", "last-continuous"]) { // Check that version document is unmodified. version = st.s.getCollection('config.version').findOne(); - assert.eq(version.minCompatibleVersion, kMinVersion); - assert.eq(version.currentVersion, kCurrentVerion); assert.eq(clusterID, version.clusterId); - assert.eq(version.excluding, undefined); st.stop(); } diff --git a/jstests/multiVersion/genericSetFCVUsage/upgrade_downgrade_sharded_cluster.js b/jstests/multiVersion/genericSetFCVUsage/upgrade_downgrade_sharded_cluster.js index f7eeaf6578f..8463454a8c6 100644 --- a/jstests/multiVersion/genericSetFCVUsage/upgrade_downgrade_sharded_cluster.js +++ b/jstests/multiVersion/genericSetFCVUsage/upgrade_downgrade_sharded_cluster.js @@ -14,6 +14,7 @@ 'use strict'; load('jstests/multiVersion/libs/multi_cluster.js'); // For upgradeCluster +load("jstests/libs/feature_flag_util.js"); const dbName = jsTestName(); @@ -44,6 +45,35 @@ function getNodeName(node) { return info.setName + '_' + (info.secondary ? 'secondary' : 'primary'); } +function checkConfigVersionDoc() { + // TODO: SERVER-68889 remove this function once 7.0 becomes last LTS + const versionDoc = st.s.getCollection('config.version').findOne(); + + if (FeatureFlagUtil.isEnabled(st.s, "StopUsingConfigVersion")) { + // Check that the version doc doesn't contain any of the deprecatedFields + const deprecatedFields = [ + "excluding", + "upgradeId", + "upgradeState", + "currentVersion", + "minCompatibleVersion", + ]; + + deprecatedFields.forEach(deprecatedField => { + assert(!versionDoc.hasOwnProperty(deprecatedField), + `Found deprecated field '${deprecatedField}' in version document ${ + tojson(versionDoc)}`); + }); + } else { + assert.eq(versionDoc.minCompatibleVersion, + 5, + "Version doc does not contain expected value for minCompatibleVersion field"); + assert.eq(versionDoc.currentVersion, + 6, + "Version doc does not contain expected value for currentVersion field"); + } +} + function checkConfigAndShardsFCV(expectedFCV) { const configPrimary = st.configRS.getPrimary(); @@ -66,21 +96,25 @@ function checkConfigAndShardsFCV(expectedFCV) { function checkClusterBeforeUpgrade(fcv) { checkConfigAndShardsFCV(fcv); + checkConfigVersionDoc(); } function checkClusterAfterBinaryUpgrade() { - // To implement in the future, if necessary. + checkConfigVersionDoc(); } function checkClusterAfterFCVUpgrade(fcv) { checkConfigAndShardsFCV(fcv); + checkConfigVersionDoc(); } function checkClusterAfterFCVDowngrade() { + checkConfigVersionDoc(); } function checkClusterAfterBinaryDowngrade(fcv) { checkConfigAndShardsFCV(fcv); + checkConfigVersionDoc(); } for (const oldVersion of [lastLTSFCV, lastContinuousFCV]) { diff --git a/jstests/sharding/empty_cluster_init.js b/jstests/sharding/empty_cluster_init.js index c35c60191d4..bd29119cf67 100644 --- a/jstests/sharding/empty_cluster_init.js +++ b/jstests/sharding/empty_cluster_init.js @@ -82,10 +82,7 @@ for (var i = 0; i < mongoses.length; i++) { // Check version and that the version was only updated once // -assert.eq(5, version.minCompatibleVersion); -assert.eq(6, version.currentVersion); -assert(version.clusterId); -assert.eq(undefined, version.excluding); +assert.hasFields(version, ['clusterId'], "Version document does not contain cluster ID"); var oplog = configRS.getPrimary().getDB('local').oplog.rs; var updates = oplog.find({ns: "config.version"}).toArray(); 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 5e905303a35..a0672dd0d84 100644 --- a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp +++ b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp @@ -84,6 +84,7 @@ #include "mongo/idl/cluster_server_parameter_gen.h" #include "mongo/logv2/log.h" #include "mongo/rpc/get_status_from_command_result.h" +#include "mongo/s/catalog/type_config_version.h" #include "mongo/s/catalog/type_index_catalog_gen.h" #include "mongo/s/sharding_feature_flags_gen.h" #include "mongo/stdx/unordered_set.h" @@ -493,6 +494,7 @@ private: const multiversion::FeatureCompatibilityVersion requestedVersion) { if (serverGlobalParams.clusterRole == ClusterRole::ConfigServer) { _createGlobalIndexesIndexes(opCtx, requestedVersion); + _cleanupConfigVersionOnUpgrade(opCtx, requestedVersion); } else if (serverGlobalParams.clusterRole == ClusterRole::ShardServer) { _createGlobalIndexesIndexes(opCtx, requestedVersion); } else { @@ -500,6 +502,73 @@ private: } } + // TODO SERVER-68889 remove once 7.0 becomes last LTS + void _cleanupConfigVersionOnUpgrade( + OperationContext* opCtx, const multiversion::FeatureCompatibilityVersion requestedVersion) { + if (feature_flags::gStopUsingConfigVersion.isEnabledOnVersion(requestedVersion)) { + LOGV2(6888800, "Removing deprecated fields from config.version collection"); + static const std::vector<StringData> deprecatedFields{ + "excluding"_sd, + "upgradeId"_sd, + "upgradeState"_sd, + StringData{VersionType::currentVersion.name()}, + StringData{VersionType::minCompatibleVersion.name()}, + }; + + const auto updateObj = [&] { + BSONObjBuilder updateBuilder; + BSONObjBuilder unsetBuilder(updateBuilder.subobjStart("$unset")); + for (const auto deprecatedField : deprecatedFields) { + unsetBuilder.append(deprecatedField.toString(), true); + } + unsetBuilder.doneFast(); + return updateBuilder.obj(); + }(); + + DBDirectClient client(opCtx); + write_ops::UpdateCommandRequest update(VersionType::ConfigNS); + update.setUpdates({[&]() { + write_ops::UpdateOpEntry entry; + entry.setQ({}); + entry.setU(write_ops::UpdateModification::parseFromClassicUpdate(updateObj)); + entry.setMulti(true); + entry.setUpsert(false); + return entry; + }()}); + client.update(update); + } + } + + // TODO SERVER-68889 remove once 7.0 becomes last LTS + void _updateConfigVersionOnDowngrade( + OperationContext* opCtx, const multiversion::FeatureCompatibilityVersion requestedVersion) { + if (!feature_flags::gStopUsingConfigVersion.isEnabledOnVersion(requestedVersion)) { + LOGV2(6888801, "Restoring removed fields in config.version collection"); + const auto updateObj = [&] { + BSONObjBuilder updateBuilder; + BSONObjBuilder unsetBuilder(updateBuilder.subobjStart("$set")); + unsetBuilder.append(VersionType::minCompatibleVersion.name(), + VersionType::MIN_COMPATIBLE_CONFIG_VERSION); + unsetBuilder.append(VersionType::currentVersion.name(), + VersionType::CURRENT_CONFIG_VERSION); + unsetBuilder.doneFast(); + return updateBuilder.obj(); + }(); + + DBDirectClient client(opCtx); + write_ops::UpdateCommandRequest update(VersionType::ConfigNS); + update.setUpdates({[&]() { + write_ops::UpdateOpEntry entry; + entry.setQ({}); + entry.setU(write_ops::UpdateModification::parseFromClassicUpdate(updateObj)); + entry.setMulti(true); + entry.setUpsert(false); + return entry; + }()}); + client.update(update); + } + } + void _createGlobalIndexesIndexes( OperationContext* opCtx, const multiversion::FeatureCompatibilityVersion requestedVersion) { // TODO SERVER-67392: Remove once FCV 7.0 becomes last-lts. @@ -758,6 +827,7 @@ private: // run on a consistent version from start to finish. This will ensure that it will // be able to apply the oplog entries correctly. abortAllReshardCollection(opCtx); + _updateConfigVersionOnDowngrade(opCtx, requestedVersion); } else if (serverGlobalParams.clusterRole == ClusterRole::ShardServer) { // If we are downgrading to a version that doesn't support implicit translation of // Timeseries collection in sharding DDL Coordinators we need to drain all ongoing diff --git a/src/mongo/db/s/config/sharding_catalog_manager.cpp b/src/mongo/db/s/config/sharding_catalog_manager.cpp index 6b02aeb4d53..77e387a3081 100644 --- a/src/mongo/db/s/config/sharding_catalog_manager.cpp +++ b/src/mongo/db/s/config/sharding_catalog_manager.cpp @@ -46,7 +46,6 @@ #include "mongo/db/s/sharding_util.h" #include "mongo/db/vector_clock.h" #include "mongo/logv2/log.h" -#include "mongo/s/catalog/config_server_version.h" #include "mongo/s/catalog/sharding_catalog_client.h" #include "mongo/s/catalog/type_chunk.h" #include "mongo/s/catalog/type_collection.h" @@ -370,47 +369,21 @@ Status ShardingCatalogManager::_initConfigVersion(OperationContext* opCtx) { auto versionStatus = catalogClient->getConfigVersion(opCtx, repl::ReadConcernLevel::kLocalReadConcern); - if (!versionStatus.isOK()) { + if (versionStatus.isOK() || versionStatus != ErrorCodes::NoMatchingDocument) { return versionStatus.getStatus(); } - const auto& versionInfo = versionStatus.getValue(); - if (versionInfo.getMinCompatibleVersion() > CURRENT_CONFIG_VERSION) { - return {ErrorCodes::IncompatibleShardingConfigVersion, - str::stream() << "current version v" << CURRENT_CONFIG_VERSION - << " is older than the cluster min compatible v" - << versionInfo.getMinCompatibleVersion()}; - } - - if (versionInfo.getCurrentVersion() == UpgradeHistory_EmptyVersion) { - VersionType newVersion; - newVersion.setClusterId(OID::gen()); - newVersion.setMinCompatibleVersion(MIN_COMPATIBLE_CONFIG_VERSION); - newVersion.setCurrentVersion(CURRENT_CONFIG_VERSION); - - BSONObj versionObj(newVersion.toBSON()); - auto insertStatus = catalogClient->insertConfigDocument( - opCtx, VersionType::ConfigNS, versionObj, kNoWaitWriteConcern); - - return insertStatus; - } + VersionType newVersion; + newVersion.setClusterId(OID::gen()); - if (versionInfo.getCurrentVersion() == UpgradeHistory_UnreportedVersion) { - return {ErrorCodes::IncompatibleShardingConfigVersion, - "Assuming config data is old since the version document cannot be found in the " - "config server and it contains databases besides 'local' and 'admin'. " - "Please upgrade if this is the case. Otherwise, make sure that the config " - "server is clean."}; - } - - if (versionInfo.getCurrentVersion() < CURRENT_CONFIG_VERSION) { - return {ErrorCodes::IncompatibleShardingConfigVersion, - str::stream() << "need to upgrade current cluster version to v" - << CURRENT_CONFIG_VERSION << "; currently at v" - << versionInfo.getCurrentVersion()}; + if (!feature_flags::gStopUsingConfigVersion.isEnabled( + serverGlobalParams.featureCompatibility)) { + newVersion.setCurrentVersion(VersionType::CURRENT_CONFIG_VERSION); + newVersion.setMinCompatibleVersion(VersionType::MIN_COMPATIBLE_CONFIG_VERSION); } - - return Status::OK(); + auto insertStatus = catalogClient->insertConfigDocument( + opCtx, VersionType::ConfigNS, newVersion.toBSON(), kNoWaitWriteConcern); + return insertStatus; } Status ShardingCatalogManager::_initConfigIndexes(OperationContext* opCtx) { diff --git a/src/mongo/db/s/config/sharding_catalog_manager_add_shard_test.cpp b/src/mongo/db/s/config/sharding_catalog_manager_add_shard_test.cpp index 777f66995d9..5ac1e13ff2b 100644 --- a/src/mongo/db/s/config/sharding_catalog_manager_add_shard_test.cpp +++ b/src/mongo/db/s/config/sharding_catalog_manager_add_shard_test.cpp @@ -50,7 +50,6 @@ #include "mongo/idl/cluster_server_parameter_common.h" #include "mongo/idl/cluster_server_parameter_gen.h" #include "mongo/logv2/log.h" -#include "mongo/s/catalog/config_server_version.h" #include "mongo/s/catalog/type_changelog.h" #include "mongo/s/catalog/type_config_version.h" #include "mongo/s/catalog/type_database_gen.h" diff --git a/src/mongo/db/s/config/sharding_catalog_manager_config_initialization_test.cpp b/src/mongo/db/s/config/sharding_catalog_manager_config_initialization_test.cpp index 7e2a87e9869..2899632f311 100644 --- a/src/mongo/db/s/config/sharding_catalog_manager_config_initialization_test.cpp +++ b/src/mongo/db/s/config/sharding_catalog_manager_config_initialization_test.cpp @@ -42,7 +42,6 @@ #include "mongo/db/repl/replication_coordinator_mock.h" #include "mongo/db/s/config/config_server_test_fixture.h" #include "mongo/db/s/config/sharding_catalog_manager.h" -#include "mongo/s/catalog/config_server_version.h" #include "mongo/s/catalog/sharding_catalog_client.h" #include "mongo/s/catalog/type_chunk.h" #include "mongo/s/catalog/type_config_version.h" @@ -59,54 +58,9 @@ using unittest::assertGet; using ConfigInitializationTest = ConfigServerTestFixture; -TEST_F(ConfigInitializationTest, UpgradeNotNeeded) { - VersionType version; - version.setClusterId(OID::gen()); - version.setCurrentVersion(CURRENT_CONFIG_VERSION); - version.setMinCompatibleVersion(MIN_COMPATIBLE_CONFIG_VERSION); - ASSERT_OK( - insertToConfigCollection(operationContext(), VersionType::ConfigNS, version.toBSON())); - - ASSERT_OK(ShardingCatalogManager::get(operationContext()) - ->initializeConfigDatabaseIfNeeded(operationContext())); - - auto versionDoc = - assertGet(findOneOnConfigCollection(operationContext(), VersionType::ConfigNS, BSONObj())); - - VersionType foundVersion = assertGet(VersionType::fromBSON(versionDoc)); - - ASSERT_EQUALS(version.getClusterId(), foundVersion.getClusterId()); - ASSERT_EQUALS(version.getCurrentVersion(), foundVersion.getCurrentVersion()); - ASSERT_EQUALS(version.getMinCompatibleVersion(), foundVersion.getMinCompatibleVersion()); -} - -TEST_F(ConfigInitializationTest, InitIncompatibleVersion) { - VersionType version; - version.setClusterId(OID::gen()); - version.setCurrentVersion(MIN_COMPATIBLE_CONFIG_VERSION - 1); - version.setMinCompatibleVersion(MIN_COMPATIBLE_CONFIG_VERSION - 2); - ASSERT_OK( - insertToConfigCollection(operationContext(), VersionType::ConfigNS, version.toBSON())); - - ASSERT_EQ(ErrorCodes::IncompatibleShardingConfigVersion, - ShardingCatalogManager::get(operationContext()) - ->initializeConfigDatabaseIfNeeded(operationContext())); - - auto versionDoc = - assertGet(findOneOnConfigCollection(operationContext(), VersionType::ConfigNS, BSONObj())); - - VersionType foundVersion = assertGet(VersionType::fromBSON(versionDoc)); - - ASSERT_EQUALS(version.getClusterId(), foundVersion.getClusterId()); - ASSERT_EQUALS(version.getCurrentVersion(), foundVersion.getCurrentVersion()); - ASSERT_EQUALS(version.getMinCompatibleVersion(), foundVersion.getMinCompatibleVersion()); -} - TEST_F(ConfigInitializationTest, InitClusterMultipleVersionDocs) { VersionType version; version.setClusterId(OID::gen()); - version.setCurrentVersion(MIN_COMPATIBLE_CONFIG_VERSION - 2); - version.setMinCompatibleVersion(MIN_COMPATIBLE_CONFIG_VERSION - 3); ASSERT_OK( insertToConfigCollection(operationContext(), VersionType::ConfigNS, version.toBSON())); @@ -123,9 +77,7 @@ TEST_F(ConfigInitializationTest, InitClusterMultipleVersionDocs) { TEST_F(ConfigInitializationTest, InitInvalidConfigVersionDoc) { BSONObj versionDoc(fromjson(R"({ _id: 1, - minCompatibleVersion: "should be numeric", - currentVersion: 7, - clusterId: ObjectId("55919cc6dbe86ce7ac056427") + clusterId: "should be an ID" })")); ASSERT_OK(insertToConfigCollection(operationContext(), VersionType::ConfigNS, versionDoc)); @@ -149,21 +101,6 @@ TEST_F(ConfigInitializationTest, InitNoVersionDocEmptyConfig) { VersionType foundVersion = assertGet(VersionType::fromBSON(versionDoc)); ASSERT_TRUE(foundVersion.getClusterId().isSet()); - ASSERT_EQUALS(CURRENT_CONFIG_VERSION, foundVersion.getCurrentVersion()); - ASSERT_EQUALS(MIN_COMPATIBLE_CONFIG_VERSION, foundVersion.getMinCompatibleVersion()); -} - -TEST_F(ConfigInitializationTest, InitVersionTooHigh) { - VersionType version; - version.setClusterId(OID::gen()); - version.setCurrentVersion(10000); - version.setMinCompatibleVersion(10000); - ASSERT_OK( - insertToConfigCollection(operationContext(), VersionType::ConfigNS, version.toBSON())); - - ASSERT_EQ(ErrorCodes::IncompatibleShardingConfigVersion, - ShardingCatalogManager::get(operationContext()) - ->initializeConfigDatabaseIfNeeded(operationContext())); } TEST_F(ConfigInitializationTest, OnlyRunsOnce) { @@ -176,8 +113,6 @@ TEST_F(ConfigInitializationTest, OnlyRunsOnce) { VersionType foundVersion = assertGet(VersionType::fromBSON(versionDoc)); ASSERT_TRUE(foundVersion.getClusterId().isSet()); - ASSERT_EQUALS(CURRENT_CONFIG_VERSION, foundVersion.getCurrentVersion()); - ASSERT_EQUALS(MIN_COMPATIBLE_CONFIG_VERSION, foundVersion.getMinCompatibleVersion()); ASSERT_EQUALS(ErrorCodes::AlreadyInitialized, ShardingCatalogManager::get(operationContext()) @@ -194,8 +129,6 @@ TEST_F(ConfigInitializationTest, ReRunsIfDocRolledBackThenReElected) { VersionType foundVersion = assertGet(VersionType::fromBSON(versionDoc)); ASSERT_TRUE(foundVersion.getClusterId().isSet()); - ASSERT_EQUALS(CURRENT_CONFIG_VERSION, foundVersion.getCurrentVersion()); - ASSERT_EQUALS(MIN_COMPATIBLE_CONFIG_VERSION, foundVersion.getMinCompatibleVersion()); // Now remove the version document and re-run initializeConfigDatabaseIfNeeded(). { @@ -240,8 +173,6 @@ TEST_F(ConfigInitializationTest, ReRunsIfDocRolledBackThenReElected) { ASSERT_TRUE(newFoundVersion.getClusterId().isSet()); ASSERT_NOT_EQUALS(newFoundVersion.getClusterId(), foundVersion.getClusterId()); - ASSERT_EQUALS(CURRENT_CONFIG_VERSION, newFoundVersion.getCurrentVersion()); - ASSERT_EQUALS(MIN_COMPATIBLE_CONFIG_VERSION, newFoundVersion.getMinCompatibleVersion()); } TEST_F(ConfigInitializationTest, BuildsNecessaryIndexes) { diff --git a/src/mongo/db/s/config/sharding_catalog_manager_shard_operations.cpp b/src/mongo/db/s/config/sharding_catalog_manager_shard_operations.cpp index 5f51edbfe29..16d337fce6a 100644 --- a/src/mongo/db/s/config/sharding_catalog_manager_shard_operations.cpp +++ b/src/mongo/db/s/config/sharding_catalog_manager_shard_operations.cpp @@ -76,7 +76,6 @@ #include "mongo/rpc/get_status_from_command_result.h" #include "mongo/rpc/metadata/repl_set_metadata.h" #include "mongo/rpc/metadata/tracking_metadata.h" -#include "mongo/s/catalog/config_server_version.h" #include "mongo/s/catalog/sharding_catalog_client.h" #include "mongo/s/catalog/type_database_gen.h" #include "mongo/s/catalog/type_shard.h" diff --git a/src/mongo/s/SConscript b/src/mongo/s/SConscript index bd334e1a846..bf0664d9992 100644 --- a/src/mongo/s/SConscript +++ b/src/mongo/s/SConscript @@ -156,7 +156,6 @@ env.Library( source=[ 'analyze_shard_key_cmd.idl', 'cannot_implicitly_create_collection_info.cpp', - 'catalog/mongo_version_range.cpp', 'catalog/type_changelog.cpp', 'catalog/type_chunk_base.idl', 'catalog/type_chunk.cpp', diff --git a/src/mongo/s/catalog/config_server_version.h b/src/mongo/s/catalog/config_server_version.h deleted file mode 100644 index 77d782213d0..00000000000 --- a/src/mongo/s/catalog/config_server_version.h +++ /dev/null @@ -1,122 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -namespace mongo { - -/** - * UPGRADE HISTORY - * - * The enum below documents the version changes to *both* the config server data layout - * and the versioning protocol between clients (i.e. the set of calls between mongos and - * mongod). - * - * Friendly notice: - * - * EVERY CHANGE EITHER IN CONFIG LAYOUT AND IN S/D PROTOCOL MUST BE RECORDED HERE BY AN INCREASE - * IN THE VERSION AND BY TAKING THE FOLLOWING STEPS. (IF YOU DON'T UNDERSTAND THESE STEPS, YOU - * SHOULD PROBABLY NOT BE UPGRADING THE VERSIONS BY YOURSELF.) - * - * + A new entry in the UpgradeHistory enum is created - * + The CURRENT_CONFIG_VERSION below is incremented to that version - * + There should be a determination if the MIN_COMPATIBLE_CONFIG_VERSION should be increased or - * not. This means determining if, by introducing the changes to layout and/or protocol, the - * new mongos/d can co-exist in a cluster with the old ones. - * + If layout changes are involved, there should be a corresponding layout upgrade routine. See - * for instance config_upgrade_vX_to_vY.cpp. - * + Again, if a layout change occurs, the base upgrade method, config_upgrade_v0_to_vX.cpp must - * be upgraded. This means that all new clusters will start at the newest versions. - * - */ -enum UpgradeHistory { - - /** - * The empty version, reported when there is no config server data - */ - UpgradeHistory_EmptyVersion = 0, - - /** - * The unreported version older mongoses used before config.version collection existed - * - * If there is a config.shards/databases/collections collection but no config.version - * collection, version 1 is assumed - */ - UpgradeHistory_UnreportedVersion = 1, - - /** - * NOTE: We skip version 2 here since it is very old and we shouldn't see it in the wild. - * - * Do not skip upgrade versions in the future. - */ - - /** - * Base version used by pre-2.4 mongoses with no collection epochs. - */ - UpgradeHistory_NoEpochVersion = 3, - - /** - * Version upgrade which added collection epochs to all sharded collections and - * chunks. - * - * Also: - * + Version document in config.version now of the form: - * { minVersion : X, currentVersion : Y, clusterId : OID(...) } - * + Mongos pings include a "mongoVersion" field indicating the mongos version - * + Mongos pings include a "configVersion" field indicating the current config version - * + Mongos explicitly ignores any collection with a "primary" field - */ - UpgradeHistory_MandatoryEpochVersion = 4, - - /** - * Version upgrade with the following changes: - * - * + Dropping a collection from mongos now waits for the chunks to be removed from the - * config server before contacting each shard. Because of this, mongos should be - * upgraded first before mongod or never drop collections during upgrade. - */ - UpgradeHistory_DummyBumpPre2_6 = 5, - - /** - * Version upgrade with the following changes: - * - * + "_secondaryThrottle" field for config.settings now accepts write concern - * specifications. - * + config.locks { ts: 1 } index is no longer unique. - */ - UpgradeHistory_DummyBumpPre2_8 = 6, // Note: 2.8 is also known as 3.0. -}; - -// Earliest version we're compatible with -const int MIN_COMPATIBLE_CONFIG_VERSION = UpgradeHistory_DummyBumpPre2_6; - -// Latest version we know how to communicate with -const int CURRENT_CONFIG_VERSION = UpgradeHistory_DummyBumpPre2_8; - -} // namespace mongo diff --git a/src/mongo/s/catalog/mongo_version_range.cpp b/src/mongo/s/catalog/mongo_version_range.cpp deleted file mode 100644 index a0c5f505817..00000000000 --- a/src/mongo/s/catalog/mongo_version_range.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#include "mongo/platform/basic.h" - -#include "mongo/s/catalog/mongo_version_range.h" - -#include "mongo/util/str.h" - -namespace mongo { - -using std::string; -using std::vector; - -BSONArray MongoVersionRange::toBSONArray(const vector<MongoVersionRange>& ranges) { - BSONArrayBuilder barr; - - for (vector<MongoVersionRange>::const_iterator it = ranges.begin(); it != ranges.end(); ++it) { - const MongoVersionRange& range = *it; - range.toBSONElement(&barr); - } - - return barr.arr(); -} - -bool MongoVersionRange::parseBSONElement(const BSONElement& el, string* errMsg) { - string dummy; - if (!errMsg) - errMsg = &dummy; - - if (el.type() == String) { - minVersion = el.String(); - if (minVersion == "") { - *errMsg = (string) "cannot parse single empty mongo version (" + el.toString() + ")"; - return false; - } - return true; - } else if (el.type() == Array || el.type() == Object) { - BSONObj range = el.Obj(); - - if (range.nFields() != 2) { - *errMsg = (string) "not enough fields in mongo version range (" + el.toString() + ")"; - return false; - } - - BSONObjIterator it(range); - - BSONElement subElA = it.next(); - BSONElement subElB = it.next(); - - if (subElA.type() != String || subElB.type() != String) { - *errMsg = (string) "wrong field type for mongo version range (" + el.toString() + ")"; - return false; - } - - minVersion = subElA.String(); - maxVersion = subElB.String(); - - if (minVersion == "") { - *errMsg = (string) "cannot parse first empty mongo version (" + el.toString() + ")"; - return false; - } - - if (maxVersion == "") { - *errMsg = (string) "cannot parse second empty mongo version (" + el.toString() + ")"; - return false; - } - - if (str::versionCmp(minVersion, maxVersion) > 0) { - string swap = minVersion; - minVersion = maxVersion; - maxVersion = swap; - } - - return true; - } else { - *errMsg = (string) "wrong type for mongo version range " + el.toString(); - return false; - } -} - -void MongoVersionRange::toBSONElement(BSONArrayBuilder* barr) const { - if (maxVersion == "") { - barr->append(minVersion); - } else { - BSONArrayBuilder rangeB(barr->subarrayStart()); - - rangeB.append(minVersion); - rangeB.append(maxVersion); - - rangeB.done(); - } -} - -bool MongoVersionRange::isInRange(StringData version) const { - if (maxVersion == "") { - // If a prefix of the version specified is excluded, the specified version is - // excluded - if (version.find(minVersion) == 0) - return true; - } else { - // Range is inclusive, so make sure the end and beginning prefix excludes all - // prefixed versions as above - if (version.find(minVersion) == 0) - return true; - if (version.find(maxVersion) == 0) - return true; - if (str::versionCmp(minVersion, version) <= 0 && - str::versionCmp(maxVersion, version) >= 0) { - return true; - } - } - - return false; -} - -bool isInMongoVersionRanges(StringData version, const vector<MongoVersionRange>& ranges) { - for (const auto& r : ranges) { - if (r.isInRange(version)) - return true; - } - - return false; -} -} // namespace mongo diff --git a/src/mongo/s/catalog/mongo_version_range.h b/src/mongo/s/catalog/mongo_version_range.h deleted file mode 100644 index f995864a689..00000000000 --- a/src/mongo/s/catalog/mongo_version_range.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include <string> -#include <vector> - -#include "mongo/base/string_data.h" -#include "mongo/db/jsobj.h" - -namespace mongo { - -/** - * The MongoVersionRange represents a min/max of MongoDB versions, useful for - * excluding/including particular versions. - * - * The ranges may be single-version, in which case maxVersion == "", where only exact prefix - * matches are included in the range. Alternately, the range may have a min and max version - * and include any version with a prefix of the min and max version as well as all versions - * between the two. - */ -struct MongoVersionRange { - static BSONArray toBSONArray(const std::vector<MongoVersionRange>& ranges); - - bool parseBSONElement(const BSONElement& el, std::string* errMsg); - - void toBSONElement(BSONArrayBuilder* barr) const; - - bool isInRange(StringData version) const; - - std::string minVersion; - std::string maxVersion; -}; - -bool isInMongoVersionRanges(StringData version, const std::vector<MongoVersionRange>& ranges); -} // namespace mongo diff --git a/src/mongo/s/catalog/sharding_catalog_client_impl.cpp b/src/mongo/s/catalog/sharding_catalog_client_impl.cpp index 73d22f8a434..7804e14ee48 100644 --- a/src/mongo/s/catalog/sharding_catalog_client_impl.cpp +++ b/src/mongo/s/catalog/sharding_catalog_client_impl.cpp @@ -56,7 +56,6 @@ #include "mongo/logv2/log.h" #include "mongo/rpc/get_status_from_command_result.h" #include "mongo/rpc/metadata/repl_set_metadata.h" -#include "mongo/s/catalog/config_server_version.h" #include "mongo/s/catalog/type_chunk.h" #include "mongo/s/catalog/type_collection.h" #include "mongo/s/catalog/type_config_version.h" @@ -859,11 +858,8 @@ StatusWith<VersionType> ShardingCatalogClientImpl::getConfigVersion( } if (queryResults.empty()) { - VersionType versionInfo; - versionInfo.setMinCompatibleVersion(UpgradeHistory_EmptyVersion); - versionInfo.setCurrentVersion(UpgradeHistory_EmptyVersion); - versionInfo.setClusterId(OID{}); - return versionInfo; + return {ErrorCodes::NoMatchingDocument, + str::stream() << "No documents found in " << VersionType::ConfigNS.ns()}; } BSONObj versionDoc = queryResults.front(); diff --git a/src/mongo/s/catalog/type_config_version.cpp b/src/mongo/s/catalog/type_config_version.cpp index 6baf07243ca..5bbdf580734 100644 --- a/src/mongo/s/catalog/type_config_version.cpp +++ b/src/mongo/s/catalog/type_config_version.cpp @@ -33,7 +33,6 @@ #include "mongo/bson/bsonobj.h" #include "mongo/bson/bsonobjbuilder.h" #include "mongo/bson/util/bson_extract.h" -#include "mongo/s/catalog/config_server_version.h" #include "mongo/util/assert_util.h" #include "mongo/util/str.h" @@ -43,18 +42,12 @@ const NamespaceString VersionType::ConfigNS("config.version"); const BSONField<int> VersionType::minCompatibleVersion("minCompatibleVersion"); const BSONField<int> VersionType::currentVersion("currentVersion"); -const BSONField<BSONArray> VersionType::excludingMongoVersions("excluding"); const BSONField<OID> VersionType::clusterId("clusterId"); -const BSONField<OID> VersionType::upgradeId("upgradeId"); -const BSONField<BSONObj> VersionType::upgradeState("upgradeState"); void VersionType::clear() { _minCompatibleVersion.reset(); _currentVersion.reset(); - _excludingMongoVersions.reset(); - _clusterId.reset(); - _upgradeId.reset(); - _upgradeState.reset(); + _clusterId = OID{}; } void VersionType::cloneTo(VersionType* other) const { @@ -62,33 +55,10 @@ void VersionType::cloneTo(VersionType* other) const { other->_minCompatibleVersion = _minCompatibleVersion; other->_currentVersion = _currentVersion; - other->_excludingMongoVersions = _excludingMongoVersions; other->_clusterId = _clusterId; - other->_upgradeId = _upgradeId; - other->_upgradeState = _upgradeState; } Status VersionType::validate() const { - if (!_minCompatibleVersion.has_value()) { - return {ErrorCodes::NoSuchKey, - str::stream() << "missing " << minCompatibleVersion.name() << " field"}; - } - - if (!_currentVersion.has_value()) { - return {ErrorCodes::NoSuchKey, - str::stream() << "missing " << currentVersion.name() << " field"}; - } - - // UpgradeHistory::UpgradeHistory_NoEpochVersion is the last version without a cluster id - if (getCurrentVersion() > UpgradeHistory::UpgradeHistory_NoEpochVersion && - !_clusterId.has_value()) { - return {ErrorCodes::NoSuchKey, str::stream() << "missing " << clusterId.name() << " field"}; - } - - if (!_clusterId->isSet()) { - return {ErrorCodes::NotYetInitialized, "Cluster ID cannot be empty"}; - } - return Status::OK(); } @@ -96,20 +66,11 @@ BSONObj VersionType::toBSON() const { BSONObjBuilder builder; builder.append("_id", 1); + builder.append(clusterId.name(), getClusterId()); if (_minCompatibleVersion) - builder.append(minCompatibleVersion.name(), getMinCompatibleVersion()); + builder.append(minCompatibleVersion.name(), _minCompatibleVersion.get()); if (_currentVersion) - builder.append(currentVersion.name(), getCurrentVersion()); - if (_excludingMongoVersions) { - builder.append(excludingMongoVersions.name(), - MongoVersionRange::toBSONArray(getExcludingMongoVersions())); - } - if (_clusterId) - builder.append(clusterId.name(), getClusterId()); - if (_upgradeId) { - builder.append(upgradeId.name(), getUpgradeId()); - builder.append(upgradeState.name(), getUpgradeState()); - } + builder.append(currentVersion.name(), _currentVersion.get()); return builder.obj(); } @@ -121,20 +82,24 @@ StatusWith<VersionType> VersionType::fromBSON(const BSONObj& source) { long long vMinCompatibleVersion; Status status = bsonExtractIntegerField(source, minCompatibleVersion.name(), &vMinCompatibleVersion); - if (!status.isOK()) + if (status == ErrorCodes::NoSuchKey) { + // skip optional field + } else if (!status.isOK()) { return status; - version._minCompatibleVersion = vMinCompatibleVersion; + } else { + version._minCompatibleVersion = vMinCompatibleVersion; + } } { long long vCurrentVersion; Status status = bsonExtractIntegerField(source, currentVersion.name(), &vCurrentVersion); - if (status.isOK()) { - version._currentVersion = vCurrentVersion; - } else if (status == ErrorCodes::NoSuchKey) { - version._currentVersion = version._minCompatibleVersion; - } else { + if (status == ErrorCodes::NoSuchKey) { + // skip optional field + } else if (!status.isOK()) { return status; + } else { + version._currentVersion = version._currentVersion; } } @@ -142,75 +107,19 @@ StatusWith<VersionType> VersionType::fromBSON(const BSONObj& source) { BSONElement vClusterIdElem; Status status = bsonExtractTypedField(source, clusterId.name(), BSONType::jstOID, &vClusterIdElem); - if (status.isOK()) { - version._clusterId = vClusterIdElem.OID(); - } else if (status == ErrorCodes::NoSuchKey && - version.getCurrentVersion() <= UpgradeHistory::UpgradeHistory_NoEpochVersion) { - // UpgradeHistory::UpgradeHistory_NoEpochVersion is the last version - // without a cluster id - } else { - return status; - } - } - - { - BSONElement vExclMongoVersionsElem; - Status status = bsonExtractTypedField( - source, excludingMongoVersions.name(), BSONType::Array, &vExclMongoVersionsElem); - if (status.isOK()) { - version._excludingMongoVersions = std::vector<MongoVersionRange>(); - BSONObjIterator it(vExclMongoVersionsElem.Obj()); - while (it.more()) { - MongoVersionRange range; - - std::string errMsg; - if (!range.parseBSONElement(it.next(), &errMsg)) { - return {ErrorCodes::FailedToParse, errMsg}; - } - - version._excludingMongoVersions->push_back(range); - } - } else if (status == ErrorCodes::NoSuchKey) { - // 'excludingMongoVersions' field is optional - } else { - return status; - } - } - - { - BSONElement vUpgradeIdElem; - Status status = - bsonExtractTypedField(source, upgradeId.name(), BSONType::jstOID, &vUpgradeIdElem); - if (status.isOK()) { - version._upgradeId = vUpgradeIdElem.OID(); - } else if (status == ErrorCodes::NoSuchKey) { - // 'upgradeId' field is optional - } else { - return status; - } - } - - if (source.hasField(upgradeState.name())) { - BSONElement vUpgradeStateElem; - Status status = bsonExtractTypedField( - source, upgradeState.name(), BSONType::Object, &vUpgradeStateElem); - if (status.isOK()) { - version._upgradeState = vUpgradeStateElem.Obj().getOwned(); - } else if (status == ErrorCodes::NoSuchKey) { - // 'upgradeState' field is optional - } else { + if (!status.isOK()) return status; - } + version._clusterId = vClusterIdElem.OID(); } return version; } -void VersionType::setMinCompatibleVersion(const int minCompatibleVersion) { +void VersionType::setMinCompatibleVersion(boost::optional<int> minCompatibleVersion) { _minCompatibleVersion = minCompatibleVersion; } -void VersionType::setCurrentVersion(const int currentVersion) { +void VersionType::setCurrentVersion(boost::optional<int> currentVersion) { _currentVersion = currentVersion; } @@ -218,11 +127,6 @@ void VersionType::setClusterId(const OID& clusterId) { _clusterId = clusterId; } -void VersionType::setExcludingMongoVersions( - const std::vector<MongoVersionRange>& excludingMongoVersions) { - _excludingMongoVersions = excludingMongoVersions; -} - std::string VersionType::toString() const { return toBSON().toString(); } diff --git a/src/mongo/s/catalog/type_config_version.h b/src/mongo/s/catalog/type_config_version.h index 2881b34ab3c..ba649656860 100644 --- a/src/mongo/s/catalog/type_config_version.h +++ b/src/mongo/s/catalog/type_config_version.h @@ -31,11 +31,8 @@ #include <boost/optional.hpp> #include <string> -#include <vector> -#include "mongo/db/jsobj.h" #include "mongo/db/namespace_string.h" -#include "mongo/s/catalog/mongo_version_range.h" namespace mongo { @@ -46,16 +43,19 @@ namespace mongo { */ class VersionType { public: + // TODO SERVER-68889 remove once 7.0 becomes last LTS + static constexpr int MIN_COMPATIBLE_CONFIG_VERSION = 5; + static constexpr int CURRENT_CONFIG_VERSION = 6; + // Name of the version collection in the config server. static const NamespaceString ConfigNS; // Field names and types in the version collection type. + // TODO SERVER-68889 remove once 7.0 becomes last LTS static const BSONField<int> minCompatibleVersion; static const BSONField<int> currentVersion; - static const BSONField<BSONArray> excludingMongoVersions; + static const BSONField<OID> clusterId; - static const BSONField<OID> upgradeId; - static const BSONField<BSONObj> upgradeState; /** * Returns the BSON representation of the entry. @@ -89,66 +89,32 @@ public: */ std::string toString() const; - int getMinCompatibleVersion() const { - return _minCompatibleVersion.get(); + const boost::optional<int>& getMinCompatibleVersion() const { + return _minCompatibleVersion; } - void setMinCompatibleVersion(int minCompatibleVersion); + void setMinCompatibleVersion(boost::optional<int> minCompatibleVersion); - int getCurrentVersion() const { - return _currentVersion.get(); + const boost::optional<int>& getCurrentVersion() const { + return _currentVersion; } - void setCurrentVersion(int currentVersion); + + void setCurrentVersion(boost::optional<int> currentVersion); const OID& getClusterId() const { - return _clusterId.get(); - } - bool isClusterIdSet() const { - return _clusterId.is_initialized(); + return _clusterId; } void setClusterId(const OID& clusterId); - std::vector<MongoVersionRange> getExcludingMongoVersions() const { - if (!isExcludingMongoVersionsSet()) { - return std::vector<MongoVersionRange>(); - } - return _excludingMongoVersions.get(); - } - bool isExcludingMongoVersionsSet() const { - return _excludingMongoVersions.is_initialized(); - } - void setExcludingMongoVersions(const std::vector<MongoVersionRange>& excludingMongoVersions); - - const OID& getUpgradeId() const { - return _upgradeId.get(); - } - bool isUpgradeIdSet() const { - return _upgradeId.is_initialized(); - } - void setUpgradeId(const OID& upgradeId); - - const BSONObj& getUpgradeState() const { - return _upgradeState.get(); - } - bool isUpgradeStateSet() const { - return _upgradeState.is_initialized(); - } - void setUpgradeState(const BSONObj& upgradeState); - private: // Convention: (M)andatory, (O)ptional, (S)pecial rule. - // (M) minimum compatible version + // TODO SERVER-68889 remove once 7.0 becomes last LTS boost::optional<int> _minCompatibleVersion; - // (M) current version + // TODO SERVER-68889 remove once 7.0 becomes last LTS boost::optional<int> _currentVersion; - // (S) clusterId -- required if current version > UpgradeHistory::UpgradeHistory_NoEpochVersion - boost::optional<OID> _clusterId; - // (O) range of disallowed versions to upgrade to - boost::optional<std::vector<MongoVersionRange>> _excludingMongoVersions; - // (O) upgrade id of current or last upgrade - boost::optional<OID> _upgradeId; - // (O) upgrade state of current or last upgrade - boost::optional<BSONObj> _upgradeState; + + // (M) clusterId + OID _clusterId; }; } // namespace mongo diff --git a/src/mongo/s/catalog/type_config_version_test.cpp b/src/mongo/s/catalog/type_config_version_test.cpp index 6bc2d7eaac2..81e604ba8d1 100644 --- a/src/mongo/s/catalog/type_config_version_test.cpp +++ b/src/mongo/s/catalog/type_config_version_test.cpp @@ -60,8 +60,6 @@ TEST(Validity, NewVersion) { OID clusterId = OID::gen(); BSONObjBuilder bob; - bob << VersionType::minCompatibleVersion(3); - bob << VersionType::currentVersion(4); bob << VersionType::clusterId(clusterId); BSONObj versionDoc = bob.obj(); @@ -71,8 +69,6 @@ TEST(Validity, NewVersion) { VersionType& versionInfo = versionResult.getValue(); - ASSERT_EQUALS(versionInfo.getMinCompatibleVersion(), 3); - ASSERT_EQUALS(versionInfo.getCurrentVersion(), 4); ASSERT_EQUALS(versionInfo.getClusterId(), clusterId); ASSERT_OK(versionInfo.validate()); @@ -84,15 +80,9 @@ TEST(Validity, NewVersionRoundTrip) { // OID clusterId = OID::gen(); - OID upgradeId = OID::gen(); - BSONObj upgradeState = BSON("a" << 1); BSONObjBuilder bob; - bob << VersionType::minCompatibleVersion(3); - bob << VersionType::currentVersion(4); bob << VersionType::clusterId(clusterId); - bob << VersionType::upgradeId(upgradeId); - bob << VersionType::upgradeState(upgradeState); BSONObj versionDoc = bob.obj(); @@ -101,11 +91,7 @@ TEST(Validity, NewVersionRoundTrip) { VersionType& versionInfo = versionResult.getValue(); - ASSERT_EQUALS(versionInfo.getMinCompatibleVersion(), 3); - ASSERT_EQUALS(versionInfo.getCurrentVersion(), 4); ASSERT_EQUALS(versionInfo.getClusterId(), clusterId); - ASSERT_EQUALS(versionInfo.getUpgradeId(), upgradeId); - ASSERT_BSONOBJ_EQ(versionInfo.getUpgradeState(), upgradeState); ASSERT_OK(versionInfo.validate()); } @@ -116,149 +102,10 @@ TEST(Validity, NewVersionNoClusterId) { // BSONObjBuilder bob; - bob << VersionType::minCompatibleVersion(3); - bob << VersionType::currentVersion(4); - BSONObj versionDoc = bob.obj(); auto versionResult = VersionType::fromBSON(versionDoc); ASSERT_EQ(ErrorCodes::NoSuchKey, versionResult.getStatus()); } -TEST(Excludes, Empty) { - // - // Tests basic empty range - // - - VersionType versionInfo; - versionInfo.setExcludingMongoVersions({}); - - // Make sure nothing is included - ASSERT(!isInMongoVersionRanges("1.2.3", versionInfo.getExcludingMongoVersions())); - ASSERT(!isInMongoVersionRanges("1.2.3-pre", versionInfo.getExcludingMongoVersions())); - ASSERT(!isInMongoVersionRanges("1.2.3-rc0", versionInfo.getExcludingMongoVersions())); -} - -TEST(Excludes, SinglePointRange) { - // - // Tests single string range - // - - VersionType versionInfo; - MongoVersionRange vr; - vr.minVersion = "1.2.3"; - versionInfo.setExcludingMongoVersions({vr}); - - ASSERT(isInMongoVersionRanges("1.2.3", versionInfo.getExcludingMongoVersions())); - - ASSERT(!isInMongoVersionRanges("1.2.2-rc0", versionInfo.getExcludingMongoVersions())); - ASSERT(!isInMongoVersionRanges("1.2.2", versionInfo.getExcludingMongoVersions())); - - ASSERT(isInMongoVersionRanges("1.2.3-pre", versionInfo.getExcludingMongoVersions())); - ASSERT(isInMongoVersionRanges("1.2.3-rc0", versionInfo.getExcludingMongoVersions())); - - ASSERT(!isInMongoVersionRanges("1.2.4-rc0", versionInfo.getExcludingMongoVersions())); - ASSERT(!isInMongoVersionRanges("1.2.4", versionInfo.getExcludingMongoVersions())); -} - -TEST(Excludes, BetweenRange) { - // - // Tests range with two endpoints - // - - VersionType versionInfo; - MongoVersionRange vr; - vr.minVersion = "7.8.9"; - vr.maxVersion = "10.11.12"; - versionInfo.setExcludingMongoVersions({vr}); - - ASSERT(isInMongoVersionRanges("7.8.9", versionInfo.getExcludingMongoVersions())); - ASSERT(isInMongoVersionRanges("10.11.12", versionInfo.getExcludingMongoVersions())); - - // Before - ASSERT(!isInMongoVersionRanges("7.8.8-rc0", versionInfo.getExcludingMongoVersions())); - ASSERT(!isInMongoVersionRanges("7.8.8", versionInfo.getExcludingMongoVersions())); - - // Boundary - ASSERT(isInMongoVersionRanges("7.8.9-pre", versionInfo.getExcludingMongoVersions())); - ASSERT(isInMongoVersionRanges("7.8.9-rc0", versionInfo.getExcludingMongoVersions())); - - ASSERT(isInMongoVersionRanges("7.8.10-rc0", versionInfo.getExcludingMongoVersions())); - ASSERT(isInMongoVersionRanges("7.8.10", versionInfo.getExcludingMongoVersions())); - - // Between - ASSERT(isInMongoVersionRanges("8.9.10", versionInfo.getExcludingMongoVersions())); - ASSERT(isInMongoVersionRanges("9.10.11", versionInfo.getExcludingMongoVersions())); - - // Boundary - ASSERT(isInMongoVersionRanges("10.11.11-rc0", versionInfo.getExcludingMongoVersions())); - ASSERT(isInMongoVersionRanges("10.11.11", versionInfo.getExcludingMongoVersions())); - - ASSERT(isInMongoVersionRanges("10.11.12-pre", versionInfo.getExcludingMongoVersions())); - ASSERT(isInMongoVersionRanges("10.11.12-rc0", versionInfo.getExcludingMongoVersions())); - - // After - ASSERT(!isInMongoVersionRanges("10.11.13-rc0", versionInfo.getExcludingMongoVersions())); - ASSERT(!isInMongoVersionRanges("10.11.13", versionInfo.getExcludingMongoVersions())); -} - -TEST(Excludes, WeirdRange) { - // - // Tests range with rc/pre endpoints - // - - VersionType versionInfo; - MongoVersionRange vr; - vr.minVersion = "7.8.9-rc0"; - vr.maxVersion = "10.11.12-pre"; - versionInfo.setExcludingMongoVersions({vr}); - - // Near endpoints - ASSERT(isInMongoVersionRanges("7.8.9", versionInfo.getExcludingMongoVersions())); - ASSERT(!isInMongoVersionRanges("10.11.12", versionInfo.getExcludingMongoVersions())); - - // Before - ASSERT(!isInMongoVersionRanges("7.8.8-rc0", versionInfo.getExcludingMongoVersions())); - ASSERT(!isInMongoVersionRanges("7.8.8", versionInfo.getExcludingMongoVersions())); - - // Boundary - ASSERT(!isInMongoVersionRanges("7.8.9-pre", versionInfo.getExcludingMongoVersions())); - ASSERT(isInMongoVersionRanges("7.8.9-rc0", versionInfo.getExcludingMongoVersions())); - - ASSERT(isInMongoVersionRanges("7.8.10-rc0", versionInfo.getExcludingMongoVersions())); - ASSERT(isInMongoVersionRanges("7.8.10", versionInfo.getExcludingMongoVersions())); - - // Between - ASSERT(isInMongoVersionRanges("8.9.10", versionInfo.getExcludingMongoVersions())); - ASSERT(isInMongoVersionRanges("9.10.11", versionInfo.getExcludingMongoVersions())); - - // Boundary - ASSERT(isInMongoVersionRanges("10.11.11-rc0", versionInfo.getExcludingMongoVersions())); - ASSERT(isInMongoVersionRanges("10.11.11", versionInfo.getExcludingMongoVersions())); - - ASSERT(isInMongoVersionRanges("10.11.12-pre", versionInfo.getExcludingMongoVersions())); - ASSERT(!isInMongoVersionRanges("10.11.12-rc0", versionInfo.getExcludingMongoVersions())); - - // After - ASSERT(!isInMongoVersionRanges("10.11.13-rc0", versionInfo.getExcludingMongoVersions())); - ASSERT(!isInMongoVersionRanges("10.11.13", versionInfo.getExcludingMongoVersions())); -} - -TEST(Excludes, BadRangeArray) { - // - // Tests range with bad array - // - - BSONArrayBuilder bab; - bab << BSON_ARRAY("" - << "1.2.3"); // empty bound - BSONArray includeArr = bab.arr(); - - auto versionInfoResult = VersionType::fromBSON( - BSON(VersionType::minCompatibleVersion(3) - << VersionType::currentVersion(4) << VersionType::clusterId(OID::gen()) - << VersionType::excludingMongoVersions(includeArr))); - ASSERT_EQ(ErrorCodes::FailedToParse, versionInfoResult.getStatus()); -} - } // unnamed namespace diff --git a/src/mongo/s/cluster_identity_loader.cpp b/src/mongo/s/cluster_identity_loader.cpp index b51d0854b90..bb54a644f92 100644 --- a/src/mongo/s/cluster_identity_loader.cpp +++ b/src/mongo/s/cluster_identity_loader.cpp @@ -100,6 +100,12 @@ StatusWith<OID> ClusterIdentityLoader::_fetchClusterIdFromConfig( OperationContext* opCtx, const repl::ReadConcernLevel& readConcernLevel) { auto catalogClient = Grid::get(opCtx)->catalogClient(); auto loadResult = catalogClient->getConfigVersion(opCtx, readConcernLevel); + + if (loadResult == ErrorCodes::NoMatchingDocument) { + // if no version document was found on config server return a zero filled ID + return OID{}; + } + if (!loadResult.isOK()) { return loadResult.getStatus().withContext("Error loading clusterID"); } diff --git a/src/mongo/s/cluster_identity_loader_test.cpp b/src/mongo/s/cluster_identity_loader_test.cpp index 046e67bd5fd..d9cbae13151 100644 --- a/src/mongo/s/cluster_identity_loader_test.cpp +++ b/src/mongo/s/cluster_identity_loader_test.cpp @@ -39,7 +39,6 @@ #include "mongo/executor/task_executor.h" #include "mongo/rpc/metadata/repl_set_metadata.h" #include "mongo/rpc/metadata/tracking_metadata.h" -#include "mongo/s/catalog/config_server_version.h" #include "mongo/s/catalog/type_config_version.h" #include "mongo/s/client/shard_registry.h" #include "mongo/s/cluster_identity_loader.h" @@ -87,8 +86,6 @@ public: if (result.isOK()) { VersionType version; - version.setCurrentVersion(CURRENT_CONFIG_VERSION); - version.setMinCompatibleVersion(MIN_COMPATIBLE_CONFIG_VERSION); version.setClusterId(result.getValue()); return StatusWith<std::vector<BSONObj>>{{version.toBSON()}}; @@ -125,6 +122,21 @@ TEST_F(ClusterIdentityTest, BasicLoadSuccess) { ->loadClusterId(operationContext(), repl::ReadConcernLevel::kMajorityReadConcern)); } +TEST_F(ClusterIdentityTest, NoConfigVersionDocument) { + // If no version document is found on config server loadClusterId will return a newly generated + // clusterId + auto future = launchAsync([&] { + ASSERT_OK( + ClusterIdentityLoader::get(operationContext()) + ->loadClusterId(operationContext(), repl::ReadConcernLevel::kMajorityReadConcern)); + }); + + expectConfigVersionLoad( + Status(ErrorCodes::NoMatchingDocument, "No config version document found")); + + future.default_timed_get(); +} + TEST_F(ClusterIdentityTest, MultipleThreadsLoadingSuccess) { // Check that multiple threads calling getClusterId at once still results in only one network // operation. diff --git a/src/mongo/s/sharding_feature_flags.idl b/src/mongo/s/sharding_feature_flags.idl index d8901c8affa..cbd558771a7 100644 --- a/src/mongo/s/sharding_feature_flags.idl +++ b/src/mongo/s/sharding_feature_flags.idl @@ -87,6 +87,12 @@ feature_flags: description: "Feature flag for enabling concurrency within a chunk migration" cpp_varname: feature_flags::gConcurrencyInChunkMigration default: false + featureFlagStopUsingConfigVersion: + # TODO SERVER-68889 remove once 7.0 becomes last LTS + description: "Stop using deprecated config version fields to check metadata compatibility between different version" + cpp_varname: feature_flags::gStopUsingConfigVersion + default: true + version: 6.2 featureFlagResilientMovePrimary: description: "Enable the resilient coordinator for the movePrimary command in order to improve the tolerance in case of a failure on donor and recipient nodes" |