diff options
author | Louis Williams <louis.williams@mongodb.com> | 2017-09-28 16:40:49 -0400 |
---|---|---|
committer | Louis Williams <louis.williams@mongodb.com> | 2017-09-28 16:40:49 -0400 |
commit | 0309fa8091bdf7d6663a02fefd5d61ae0965e7b1 (patch) | |
tree | 685732dc627d5a2ea75f69a3c965388f82137a6a /src/mongo/db/commands | |
parent | 20a128d3922a3f83f3769ee80ebb4fd607251888 (diff) | |
download | mongo-0309fa8091bdf7d6663a02fefd5d61ae0965e7b1.tar.gz |
Revert "SERVER-31209 Persist targetVersion in FCV document to indicate an upgrade/downgrade in progress."
This reverts commit b0b99866781302ba8b16de033ff2681f20483c14.
Diffstat (limited to 'src/mongo/db/commands')
6 files changed, 110 insertions, 223 deletions
diff --git a/src/mongo/db/commands/feature_compatibility_version.cpp b/src/mongo/db/commands/feature_compatibility_version.cpp index c35d1eb993f..f6515bc0cd1 100644 --- a/src/mongo/db/commands/feature_compatibility_version.cpp +++ b/src/mongo/db/commands/feature_compatibility_version.cpp @@ -55,21 +55,51 @@ constexpr StringData FeatureCompatibilityVersion::kCommandName; constexpr StringData FeatureCompatibilityVersion::kDatabase; constexpr StringData FeatureCompatibilityVersion::kParameterName; constexpr StringData FeatureCompatibilityVersion::kVersionField; -constexpr StringData FeatureCompatibilityVersion::kTargetVersionField; -StatusWith<FeatureCompatibilityVersionInfo> FeatureCompatibilityVersion::parse( - const BSONObj& featureCompatibilityVersionInfo) { - FeatureCompatibilityVersionInfo versionInfo; +namespace { +BSONObj makeUpdateCommand(StringData newVersion, BSONObj writeConcern) { + BSONObjBuilder updateCmd; - for (auto&& elem : featureCompatibilityVersionInfo) { + NamespaceString nss(FeatureCompatibilityVersion::kCollection); + updateCmd.append("update", nss.coll()); + { + BSONArrayBuilder updates(updateCmd.subarrayStart("updates")); + { + BSONObjBuilder updateSpec(updates.subobjStart()); + { + BSONObjBuilder queryFilter(updateSpec.subobjStart("q")); + queryFilter.append("_id", FeatureCompatibilityVersion::kParameterName); + } + { + BSONObjBuilder updateMods(updateSpec.subobjStart("u")); + updateMods.append(FeatureCompatibilityVersion::kVersionField, newVersion); + } + updateSpec.appendBool("upsert", true); + } + } + + if (!writeConcern.isEmpty()) { + updateCmd.append(WriteConcernOptions::kWriteConcernField, writeConcern); + } + + return updateCmd.obj(); +} +} // namespace + +StatusWith<ServerGlobalParams::FeatureCompatibility::Version> FeatureCompatibilityVersion::parse( + const BSONObj& featureCompatibilityVersionDoc) { + bool foundVersionField = false; + ServerGlobalParams::FeatureCompatibility::Version version; + + for (auto&& elem : featureCompatibilityVersionDoc) { auto fieldName = elem.fieldNameStringData(); if (fieldName == "_id") { continue; - } else if (fieldName == FeatureCompatibilityVersion::kVersionField || - fieldName == FeatureCompatibilityVersion::kTargetVersionField) { + } else if (fieldName == FeatureCompatibilityVersion::kVersionField) { + foundVersionField = true; if (elem.type() != BSONType::String) { return Status(ErrorCodes::TypeMismatch, - str::stream() << fieldName + str::stream() << FeatureCompatibilityVersion::kVersionField << " must be of type String, but was of type " << typeName(elem.type()) << ". Contents of " @@ -77,20 +107,20 @@ StatusWith<FeatureCompatibilityVersionInfo> FeatureCompatibilityVersion::parse( << " document in " << FeatureCompatibilityVersion::kCollection << ": " - << featureCompatibilityVersionInfo + << featureCompatibilityVersionDoc << ". See " << feature_compatibility_version::kDochubLink << "."); } - - ServerGlobalParams::FeatureCompatibility::Version version; if (elem.String() == FeatureCompatibilityVersionCommandParser::kVersion36) { version = ServerGlobalParams::FeatureCompatibility::Version::k36; } else if (elem.String() == FeatureCompatibilityVersionCommandParser::kVersion34) { version = ServerGlobalParams::FeatureCompatibility::Version::k34; } else { return Status(ErrorCodes::BadValue, - str::stream() << "Invalid value for " << fieldName << ", found " + str::stream() << "Invalid value for " + << FeatureCompatibilityVersion::kVersionField + << ", found " << elem.String() << ", expected '" << FeatureCompatibilityVersionCommandParser::kVersion36 @@ -101,32 +131,27 @@ StatusWith<FeatureCompatibilityVersionInfo> FeatureCompatibilityVersion::parse( << " document in " << FeatureCompatibilityVersion::kCollection << ": " - << featureCompatibilityVersionInfo + << featureCompatibilityVersionDoc << ". See " << feature_compatibility_version::kDochubLink << "."); } - - if (fieldName == FeatureCompatibilityVersion::kVersionField) { - versionInfo.version = version; - } else if (fieldName == FeatureCompatibilityVersion::kTargetVersionField) { - versionInfo.targetVersion = version; - } } else { return Status(ErrorCodes::BadValue, - str::stream() << "Unrecognized field '" << fieldName << "'. Contents of " + str::stream() << "Unrecognized field '" << elem.fieldName() + << "''. Contents of " << FeatureCompatibilityVersion::kParameterName << " document in " << FeatureCompatibilityVersion::kCollection << ": " - << featureCompatibilityVersionInfo + << featureCompatibilityVersionDoc << ". See " << feature_compatibility_version::kDochubLink << "."); } } - if (versionInfo.version == ServerGlobalParams::FeatureCompatibility::Version::kUnset) { + if (!foundVersionField) { return Status(ErrorCodes::BadValue, str::stream() << "Missing required field '" << FeatureCompatibilityVersion::kVersionField @@ -135,45 +160,45 @@ StatusWith<FeatureCompatibilityVersionInfo> FeatureCompatibilityVersion::parse( << " document in " << FeatureCompatibilityVersion::kCollection << ": " - << featureCompatibilityVersionInfo + << featureCompatibilityVersionDoc << ". See " << feature_compatibility_version::kDochubLink << "."); } - return versionInfo; + return version; } void FeatureCompatibilityVersion::set(OperationContext* opCtx, StringData version) { - // Upgrades to a version, which sets the 'version' field only. - _runUpdateCommand(opCtx, version, [version](auto updateMods) { - BSONObjBuilder setOp(updateMods.subobjStart("$set")); - setOp.append(FeatureCompatibilityVersion::kVersionField, version); - }); -} + uassert(40284, + str::stream() << "featureCompatibilityVersion must be '" + << FeatureCompatibilityVersionCommandParser::kVersion36 + << "' or '" + << FeatureCompatibilityVersionCommandParser::kVersion34 + << "'. See " + << feature_compatibility_version::kDochubLink + << ".", + version == FeatureCompatibilityVersionCommandParser::kVersion36 || + version == FeatureCompatibilityVersionCommandParser::kVersion34); -void FeatureCompatibilityVersion::setTargetUpgrade(OperationContext* opCtx, StringData version) { - // Only set 'targetVersion' field. - _runUpdateCommand(opCtx, version, [version](auto updateMods) { - BSONObjBuilder setOp(updateMods.subobjStart("$set")); - setOp.append(FeatureCompatibilityVersion::kTargetVersionField, version); - }); -} + DBDirectClient client(opCtx); + NamespaceString nss(FeatureCompatibilityVersion::kCollection); -void FeatureCompatibilityVersion::setTargetDowngrade(OperationContext* opCtx, StringData version) { - // Set both 'version' and 'targetVersion' fields. - _runUpdateCommand(opCtx, version, [version](auto updateMods) { - updateMods.append(FeatureCompatibilityVersion::kVersionField, version); - updateMods.append(FeatureCompatibilityVersion::kTargetVersionField, version); - }); -} + // Update the featureCompatibilityVersion document stored in the "admin.system.version" + // collection. + BSONObj updateResult; + client.runCommand(nss.db().toString(), + makeUpdateCommand(version, WriteConcernOptions::Majority), + updateResult); + uassertStatusOK(getStatusFromCommandResult(updateResult)); + uassertStatusOK(getWriteConcernStatusFromCommandResult(updateResult)); -void FeatureCompatibilityVersion::unsetTargetUpgradeOrDowngrade(OperationContext* opCtx, - StringData version) { - // Updates 'version' field, while also unsetting the 'targetVersion' field. - _runUpdateCommand(opCtx, version, [version](auto updateMods) { - updateMods.append(FeatureCompatibilityVersion::kVersionField, version); - }); + // Close all internal connections to versions lower than 3.6. + if (version == FeatureCompatibilityVersionCommandParser::kVersion36) { + opCtx->getServiceContext()->getServiceEntryPoint()->endAllSessions( + transport::Session::kLatestVersionInternalClientKeepOpen | + transport::Session::kExternalClientKeepOpen); + } } void FeatureCompatibilityVersion::setIfCleanStartup(OperationContext* opCtx, @@ -200,10 +225,9 @@ void FeatureCompatibilityVersion::setIfCleanStartup(OperationContext* opCtx, // the "admin.system.version" collection. invariant(autoDB.justCreated()); - // We update the value of the version server parameter so that the admin.system.version - // collection gets a UUID. - serverGlobalParams.featureCompatibility.version.store( - ServerGlobalParams::FeatureCompatibility::Version::k36); + // We update the value of the isSchemaVersion36 server parameter so the + // admin.system.version collection gets a UUID. + serverGlobalParams.featureCompatibility.isSchemaVersion36.store(true); uassertStatusOK(storageInterface->createCollection(opCtx, nss, {})); } @@ -229,27 +253,13 @@ void FeatureCompatibilityVersion::onInsertOrUpdate(OperationContext* opCtx, cons idElement.String() != FeatureCompatibilityVersion::kParameterName) { return; } - auto versionInfo = uassertStatusOK(FeatureCompatibilityVersion::parse(doc)); - - // Indicate if an upgrade or downgrade is in progress. - if (versionInfo.targetVersion != ServerGlobalParams::FeatureCompatibility::Version::kUnset) { - log() << "targeting featureCompatibilityVersion " << toString(versionInfo.targetVersion); - } - - // To avoid extra log messages when the targetVersion is set/unset, only log when the version - // changes. - auto oldVersion = serverGlobalParams.featureCompatibility.version.load(); - auto newVersion = versionInfo.version; - if (oldVersion != newVersion) { - log() << "setting featureCompatibilityVersion to " << toString(newVersion); - } - - // On commit, update the server parameters, and close any incoming connections with a wire - // version that is below the minimum. - opCtx->recoveryUnit()->onCommit([opCtx, versionInfo]() { - serverGlobalParams.featureCompatibility.version.store(versionInfo.version); - serverGlobalParams.featureCompatibility.targetVersion.store(versionInfo.targetVersion); - _closeConnectionsBelowVersion(opCtx, versionInfo); + auto newVersion = uassertStatusOK(FeatureCompatibilityVersion::parse(doc)); + log() << "setting featureCompatibilityVersion to " << toString(newVersion); + opCtx->recoveryUnit()->onCommit([newVersion]() { + serverGlobalParams.featureCompatibility.version.store(newVersion); + serverGlobalParams.featureCompatibility.isSchemaVersion36.store( + serverGlobalParams.featureCompatibility.version.load() == + ServerGlobalParams::FeatureCompatibility::Version::k36); }); } @@ -264,8 +274,7 @@ void FeatureCompatibilityVersion::onDelete(OperationContext* opCtx, const BSONOb opCtx->recoveryUnit()->onCommit([]() { serverGlobalParams.featureCompatibility.version.store( ServerGlobalParams::FeatureCompatibility::Version::k34); - serverGlobalParams.featureCompatibility.targetVersion.store( - ServerGlobalParams::FeatureCompatibility::Version::kUnset); + serverGlobalParams.featureCompatibility.isSchemaVersion36.store(false); }); } @@ -275,70 +284,10 @@ void FeatureCompatibilityVersion::onDropCollection(OperationContext* opCtx) { opCtx->recoveryUnit()->onCommit([]() { serverGlobalParams.featureCompatibility.version.store( ServerGlobalParams::FeatureCompatibility::Version::k34); - serverGlobalParams.featureCompatibility.targetVersion.store( - ServerGlobalParams::FeatureCompatibility::Version::kUnset); + serverGlobalParams.featureCompatibility.isSchemaVersion36.store(false); }); } -void FeatureCompatibilityVersion::_validateVersion(StringData version) { - uassert(40284, - str::stream() << "featureCompatibilityVersion must be '" - << FeatureCompatibilityVersionCommandParser::kVersion36 - << "' or '" - << FeatureCompatibilityVersionCommandParser::kVersion34 - << "'. See " - << feature_compatibility_version::kDochubLink - << ".", - version == FeatureCompatibilityVersionCommandParser::kVersion36 || - version == FeatureCompatibilityVersionCommandParser::kVersion34); -} - -void FeatureCompatibilityVersion::_closeConnectionsBelowVersion( - OperationContext* opCtx, FeatureCompatibilityVersionInfo versionInfo) { - - // Close all internal connections to versions lower than 3.6. - if (versionInfo.version == ServerGlobalParams::FeatureCompatibility::Version::k36 || - versionInfo.targetVersion == ServerGlobalParams::FeatureCompatibility::Version::k36) { - opCtx->getServiceContext()->getServiceEntryPoint()->endAllSessions( - transport::Session::kLatestVersionInternalClientKeepOpen | - transport::Session::kExternalClientKeepOpen); - } -} - -void FeatureCompatibilityVersion::_runUpdateCommand(OperationContext* opCtx, - StringData version, - UpdateBuilder builder) { - _validateVersion(version); - - DBDirectClient client(opCtx); - NamespaceString nss(FeatureCompatibilityVersion::kCollection); - - BSONObjBuilder updateCmd; - updateCmd.append("update", nss.coll()); - { - BSONArrayBuilder updates(updateCmd.subarrayStart("updates")); - { - BSONObjBuilder updateSpec(updates.subobjStart()); - { - BSONObjBuilder queryFilter(updateSpec.subobjStart("q")); - queryFilter.append("_id", FeatureCompatibilityVersion::kParameterName); - } - { - BSONObjBuilder updateMods(updateSpec.subobjStart("u")); - builder(std::move(updateMods)); - } - updateSpec.appendBool("upsert", true); - } - } - updateCmd.append(WriteConcernOptions::kWriteConcernField, WriteConcernOptions::Majority); - - // Update the featureCompatibilityVersion document stored in the "admin.system.version" - // collection. - BSONObj updateResult; - client.runCommand(nss.db().toString(), updateCmd.obj(), updateResult); - uassertStatusOK(getStatusFromCommandResult(updateResult)); - uassertStatusOK(getWriteConcernStatusFromCommandResult(updateResult)); -} /** * Read-only server parameter for featureCompatibilityVersion. */ diff --git a/src/mongo/db/commands/feature_compatibility_version.h b/src/mongo/db/commands/feature_compatibility_version.h index abb48b82101..d89b2e996d5 100644 --- a/src/mongo/db/commands/feature_compatibility_version.h +++ b/src/mongo/db/commands/feature_compatibility_version.h @@ -41,18 +41,6 @@ class BSONObj; class OperationContext; /** - * Store state of featureCompatibilityVersion document. - **/ -struct FeatureCompatibilityVersionInfo { - ServerGlobalParams::FeatureCompatibility::Version version; - ServerGlobalParams::FeatureCompatibility::Version targetVersion; - - FeatureCompatibilityVersionInfo() - : version(ServerGlobalParams::FeatureCompatibility::Version::kUnset), - targetVersion(ServerGlobalParams::FeatureCompatibility::Version::kUnset) {} -}; - -/** * Startup parameter to ignore featureCompatibilityVersion checks. This parameter cannot be set if * the node is started with --replSet, --master, or --slave. This should never be set by end users. */ @@ -65,13 +53,12 @@ public: static constexpr StringData kDatabase = "admin"_sd; static constexpr StringData kParameterName = "featureCompatibilityVersion"_sd; static constexpr StringData kVersionField = "version"_sd; - static constexpr StringData kTargetVersionField = "targetVersion"_sd; /** * Parses the featureCompatibilityVersion document from admin.system.version, and returns the * version. */ - static StatusWith<FeatureCompatibilityVersionInfo> parse( + static StatusWith<ServerGlobalParams::FeatureCompatibility::Version> parse( const BSONObj& featureCompatibilityVersionDoc); static StringData toString(ServerGlobalParams::FeatureCompatibility::Version version) { @@ -80,8 +67,6 @@ public: return FeatureCompatibilityVersionCommandParser::kVersion36; case ServerGlobalParams::FeatureCompatibility::Version::k34: return FeatureCompatibilityVersionCommandParser::kVersion34; - case ServerGlobalParams::FeatureCompatibility::Version::kUnset: - return FeatureCompatibilityVersionCommandParser::kVersionUnset; default: MONGO_UNREACHABLE; } @@ -95,27 +80,6 @@ public: static void set(OperationContext* opCtx, StringData version); /** - * Indicate intent to perform an upgrade. Should be set before schemas are modified. - * This sets the 'targetVersion' field only. - * Use unsetTargetUpgradeOrDowngrade to indicate that the schemas have completed the upgrading. - */ - static void setTargetUpgrade(OperationContext* opCtx, StringData version); - - /** - * Indicate intent to perform a downgrade. Should be set before schemas are modified. - * This atomically updates both the 'version' and 'targetVersion' fields. - * Use unsetTargetUpgradeOrDowngrade to indicate that the schemas have completed downgrading. - */ - static void setTargetDowngrade(OperationContext* opCtx, StringData version); - - /** - * Indicate the completion of an upgrade or downgrade. Should be set only when schemas are - * done being upgraded or modified. - * Unsets the 'targetVersion' field and updates the 'version' field. - */ - static void unsetTargetUpgradeOrDowngrade(OperationContext* opCtx, StringData version); - - /** * If there are no non-local databases and we are not running with --shardsvr, set * featureCompatibilityVersion to the latest value. */ @@ -140,28 +104,6 @@ public: * Resets the server parameter to its default value on commit. */ static void onDropCollection(OperationContext* opCtx); - -private: - /** - * Validate version. Uasserts if invalid. - */ - static void _validateVersion(StringData version); - - /** - * Close incoming connections from interal clients who cannot speak our highest wire protocol - * version. - */ - static void _closeConnectionsBelowVersion(OperationContext* opCtx, - FeatureCompatibilityVersionInfo versionInfo); - - /** - * Build update command. - */ - typedef stdx::function<void(BSONObjBuilder)> UpdateBuilder; - static void _runUpdateCommand(OperationContext* opCtx, - StringData version, - UpdateBuilder callback); }; - } // namespace mongo diff --git a/src/mongo/db/commands/feature_compatibility_version_command_parser.cpp b/src/mongo/db/commands/feature_compatibility_version_command_parser.cpp index 1859bc13f9e..ae781c8137f 100644 --- a/src/mongo/db/commands/feature_compatibility_version_command_parser.cpp +++ b/src/mongo/db/commands/feature_compatibility_version_command_parser.cpp @@ -43,7 +43,6 @@ constexpr StringData kVersion32 = "3.2"_sd; constexpr StringData FeatureCompatibilityVersionCommandParser::kVersion34; constexpr StringData FeatureCompatibilityVersionCommandParser::kVersion36; -constexpr StringData FeatureCompatibilityVersionCommandParser::kVersionUnset; StatusWith<std::string> FeatureCompatibilityVersionCommandParser::extractVersionFromCommand( StringData commandName, const BSONObj& cmdObj) { diff --git a/src/mongo/db/commands/feature_compatibility_version_command_parser.h b/src/mongo/db/commands/feature_compatibility_version_command_parser.h index 498c9c8261d..c4544fdbff1 100644 --- a/src/mongo/db/commands/feature_compatibility_version_command_parser.h +++ b/src/mongo/db/commands/feature_compatibility_version_command_parser.h @@ -49,7 +49,6 @@ public: */ static constexpr StringData kVersion34 = "3.4"_sd; static constexpr StringData kVersion36 = "3.6"_sd; - static constexpr StringData kVersionUnset = "Unset"_sd; /** * Interprets the specified BSON as a command and extracts the desired compatibility version diff --git a/src/mongo/db/commands/mr.cpp b/src/mongo/db/commands/mr.cpp index b9ecf5b4006..84ebb935f39 100644 --- a/src/mongo/db/commands/mr.cpp +++ b/src/mongo/db/commands/mr.cpp @@ -421,7 +421,7 @@ void State::prepTempCollection() { options.setNoIdIndex(); options.temp = true; if (enableCollectionUUIDs && - serverGlobalParams.featureCompatibility.isSchemaVersion36()) { + serverGlobalParams.featureCompatibility.isSchemaVersion36.load() == true) { options.uuid.emplace(UUID::gen()); } incColl = incCtx.db()->createCollection(_opCtx, _config.incLong.ns(), options); @@ -505,7 +505,8 @@ void State::prepTempCollection() { CollectionOptions options = finalOptions; options.temp = true; - if (enableCollectionUUIDs && serverGlobalParams.featureCompatibility.isSchemaVersion36()) { + if (enableCollectionUUIDs && + serverGlobalParams.featureCompatibility.isSchemaVersion36.load() == true) { // If a UUID for the final output collection was sent by mongos (i.e., the final output // collection is sharded), use the UUID mongos sent when creating the temp collection. // When the temp collection is renamed to the final output collection, the UUID will be 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 92d8ce3e0e3..77bfd2bb8d9 100644 --- a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp +++ b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp @@ -128,33 +128,30 @@ public: opCtx, writeConcern); } - // Perform an upgrade if (version != existingVersion && isFCVUpgrade(version)) { - // Set targetVersion to indicate that an upgrade is in progress, then unset when done. - FeatureCompatibilityVersion::setTargetUpgrade(opCtx, version); + serverGlobalParams.featureCompatibility.isSchemaVersion36.store(true); updateUUIDSchemaVersion(opCtx, /*upgrade*/ true); + existingVersion = version; + } + + // For reproducing failure after adding UUIDs and before upgrade FCV document. + if (MONGO_FAIL_POINT(featureCompatibilityUpgrade)) { + exitCleanly(EXIT_CLEAN); + } - // For reproducing failure after adding UUIDs and before upgrade FCV document. - if (MONGO_FAIL_POINT(featureCompatibilityUpgrade)) { - exitCleanly(EXIT_CLEAN); - } - // Unsets 'targetVersion' and sets 'version' to new version. - FeatureCompatibilityVersion::unsetTargetUpgradeOrDowngrade(opCtx, version); - - // Always perform a downgrade when setting the FCV to 3.4, in case of a crash after - // writing the document and before completing the upgrade. - } else if (version == FeatureCompatibilityVersionCommandParser::kVersion34) { - // Set targetVersion to indicate that a downgrade is in progress, then unset when - // complete. - FeatureCompatibilityVersion::setTargetDowngrade(opCtx, version); - - // For reproducing failure after downgrading FCV document, and before removing UUIDs. - if (MONGO_FAIL_POINT(featureCompatibilityDowngrade)) { - exitCleanly(EXIT_CLEAN); - } + FeatureCompatibilityVersion::set(opCtx, version); + + // For reproducing failure after downgrading FCV document, and before removing UUIDs. + if (MONGO_FAIL_POINT(featureCompatibilityDowngrade)) { + serverGlobalParams.featureCompatibility.isSchemaVersion36.store(false); + exitCleanly(EXIT_CLEAN); + } + // Always perform a downgrade when setting the FCV to 3.4, in case of a crash after writing + // the document and before completing the upgrade. + if (version == FeatureCompatibilityVersionCommandParser::kVersion34) { + serverGlobalParams.featureCompatibility.isSchemaVersion36.store(false); updateUUIDSchemaVersion(opCtx, /*upgrade*/ false); - FeatureCompatibilityVersion::unsetTargetUpgradeOrDowngrade(opCtx, version); } // Ensure we try reading the keys for signing clusterTime immediately on upgrade to 3.6. |