diff options
author | Antonio Fuschetto <antonio.fuschetto@mongodb.com> | 2021-08-26 21:04:10 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-08-26 21:26:26 +0000 |
commit | 7f1ec52be8e1a04af3fa542d3de245d83adddd01 (patch) | |
tree | 20ffdf20b8b4460a3e3c1afecd9b4d8befcd237b /src/mongo/db/s | |
parent | f40810c7c8706754b647992fbde1dc2745616b7c (diff) | |
download | mongo-7f1ec52be8e1a04af3fa542d3de245d83adddd01.tar.gz |
SERVER-58574 Modify the setFCV command to set/unset the long names flag
Diffstat (limited to 'src/mongo/db/s')
-rw-r--r-- | src/mongo/db/s/config/sharding_catalog_manager.cpp | 165 | ||||
-rw-r--r-- | src/mongo/db/s/config/sharding_catalog_manager.h | 38 | ||||
-rw-r--r-- | src/mongo/db/s/create_collection_coordinator.cpp | 10 |
3 files changed, 212 insertions, 1 deletions
diff --git a/src/mongo/db/s/config/sharding_catalog_manager.cpp b/src/mongo/db/s/config/sharding_catalog_manager.cpp index 35758decf8e..1a9d49d33b3 100644 --- a/src/mongo/db/s/config/sharding_catalog_manager.cpp +++ b/src/mongo/db/s/config/sharding_catalog_manager.cpp @@ -477,6 +477,171 @@ Status ShardingCatalogManager::setFeatureCompatibilityVersionOnShards(OperationC return Status::OK(); } +void _updateConfigDocument(OperationContext* opCtx, + const mongo::NamespaceString& nss, + const BSONObj& query, + const BSONObj& update, + bool upsert, + bool multi) { + invariant(nss.db() == "config"); + + write_ops::UpdateCommandRequest commandRequest(nss, [&] { + write_ops::UpdateOpEntry updateOp; + updateOp.setQ(query); + updateOp.setU(write_ops::UpdateModification::parseFromClassicUpdate(update)); + updateOp.setMulti(multi); + updateOp.setUpsert(upsert); + return std::vector{updateOp}; + }()); + commandRequest.setWriteCommandRequestBase([] { + write_ops::WriteCommandRequestBase commandRequestBase; + commandRequestBase.setOrdered(false); + return commandRequestBase; + }()); + + DBDirectClient dbClient(opCtx); + const auto commandResponse = + dbClient.runCommand(OpMsgRequest::fromDBAndBody(nss.db(), commandRequest.toBSON({}))); + + const auto commandReply = commandResponse->getCommandReply(); + uassertStatusOK([&] { + BatchedCommandResponse response; + std::string unusedErrMsg; + response.parseBSON(commandReply, &unusedErrMsg); + return response.toStatus(); + }()); + uassertStatusOK(getWriteConcernStatusFromCommandResult(commandReply)); +} + +void ShardingCatalogManager::_enableSupportForLongCollectionName(OperationContext* opCtx) { + // List all collections for which the long name support is disabled. + const auto configShard = Grid::get(opCtx)->shardRegistry()->getConfigShard(); + const auto collectionDocs = + uassertStatusOK( + configShard->exhaustiveFindOnConfig( + opCtx, + ReadPreferenceSetting{ReadPreference::PrimaryOnly}, + repl::ReadConcernLevel::kLocalReadConcern, + CollectionType::ConfigNS, + BSON(CollectionType::kSupportingLongNameFieldName << BSON("$exists" << false)), + BSONObj(), + boost::none)) + .docs; + + // Implicitly enable the long name support on all collections for which it is disabled. + _updateConfigDocument( + opCtx, + CollectionType::ConfigNS, + BSON(CollectionType::kSupportingLongNameFieldName << BSON("$exists" << false)), + BSON("$set" << BSON(CollectionType::kSupportingLongNameFieldName + << SupportingLongNameStatus_serializer( + SupportingLongNameStatusEnum::kImplicitlyEnabled))), + false /* upsert */, + true /* multi */); + + // Wait until the last operation is majority-committed. + WriteConcernResult ignoreResult; + const auto latestOpTime = repl::ReplClientInfo::forClient(opCtx->getClient()).getLastOp(); + uassertStatusOK(waitForWriteConcern( + opCtx, latestOpTime, ShardingCatalogClient::kMajorityWriteConcern, &ignoreResult)); + + // Force the catalog cache refresh of updated collections on each shard. + const auto shardIds = Grid::get(opCtx)->shardRegistry()->getAllShardIds(opCtx); + const auto fixedExecutor = Grid::get(_serviceContext)->getExecutorPool()->getFixedExecutor(); + for (const auto& doc : collectionDocs) { + const CollectionType coll(doc); + const auto collNss = coll.getNss(); + + try { + sharding_util::tellShardsToRefreshCollection(opCtx, shardIds, collNss, fixedExecutor); + } catch (const ExceptionFor<ErrorCodes::ConflictingOperationInProgress>& e) { + LOGV2_ERROR(5857400, + "Failed to refresh collection on shards after enabling long name support", + "nss"_attr = collNss.ns(), + "error"_attr = redact(e)); + } + } +} + +void ShardingCatalogManager::_disableSupportForLongCollectionName(OperationContext* opCtx) { + // List all collections for which the long name support is implicitly enabled. + const auto configShard = Grid::get(opCtx)->shardRegistry()->getConfigShard(); + const auto collectionDocs = + uassertStatusOK(configShard->exhaustiveFindOnConfig( + opCtx, + ReadPreferenceSetting{ReadPreference::PrimaryOnly}, + repl::ReadConcernLevel::kLocalReadConcern, + CollectionType::ConfigNS, + BSON(CollectionType::kSupportingLongNameFieldName + << SupportingLongNameStatus_serializer( + SupportingLongNameStatusEnum::kImplicitlyEnabled)), + BSONObj(), + boost::none)) + .docs; + + // Disable the long name support on all collections for which it is implicitly enabled. + _updateConfigDocument( + opCtx, + CollectionType::ConfigNS, + BSON(CollectionType::kSupportingLongNameFieldName << SupportingLongNameStatus_serializer( + SupportingLongNameStatusEnum::kImplicitlyEnabled)), + BSON("$unset" << BSON(CollectionType::kSupportingLongNameFieldName << 1)), + false /* upsert */, + true /* multi */); + + // Wait until the last operation is majority-committed. + WriteConcernResult ignoreResult; + const auto latestOpTime = repl::ReplClientInfo::forClient(opCtx->getClient()).getLastOp(); + uassertStatusOK(waitForWriteConcern( + opCtx, latestOpTime, ShardingCatalogClient::kMajorityWriteConcern, &ignoreResult)); + + // Force the catalog cache refresh of updated collections on each shard. + const auto shardIds = Grid::get(opCtx)->shardRegistry()->getAllShardIds(opCtx); + const auto fixedExecutor = Grid::get(_serviceContext)->getExecutorPool()->getFixedExecutor(); + for (const auto& doc : collectionDocs) { + const CollectionType coll(doc); + const auto collNss = coll.getNss(); + + try { + sharding_util::tellShardsToRefreshCollection(opCtx, shardIds, collNss, fixedExecutor); + } catch (const ExceptionFor<ErrorCodes::ConflictingOperationInProgress>& e) { + LOGV2_ERROR(5857401, + "Failed to refresh collection on shards after disabling long name support", + "nss"_attr = collNss.ns(), + "error"_attr = redact(e)); + } + } +} + +void ShardingCatalogManager::upgradeMetadataTo51Phase2(OperationContext* opCtx) { + LOGV2(5857402, "Starting metadata upgrade to FCV 5.1 (phase 2)"); + + try { + _enableSupportForLongCollectionName(opCtx); + } catch (const DBException& e) { + LOGV2_ERROR( + 5857403, "Failed to upgrade metadata to FCV 5.1 (phase 2)", "error"_attr = redact(e)); + throw; + } + + LOGV2(5857404, "Successfully upgraded metadata to FCV 5.1 (phase 2)"); +} + +void ShardingCatalogManager::downgradeMetadataToPre51Phase2(OperationContext* opCtx) { + LOGV2(5857405, "Starting metadata downgrade to pre FCV 5.1 (phase 2)"); + + try { + _disableSupportForLongCollectionName(opCtx); + } catch (const DBException& e) { + LOGV2_ERROR(5857406, + "Failed to downgrade metadata to pre FCV 5.1 (phase 2)", + "error"_attr = redact(e)); + throw; + } + + LOGV2(5857407, "Successfully downgraded metadata to pre FCV 5.1 (phase 2)"); +} + StatusWith<bool> ShardingCatalogManager::_isShardRequiredByZoneStillInUse( OperationContext* opCtx, const ReadPreferenceSetting& readPref, diff --git a/src/mongo/db/s/config/sharding_catalog_manager.h b/src/mongo/db/s/config/sharding_catalog_manager.h index 8eef2b7191c..391db3a5c8b 100644 --- a/src/mongo/db/s/config/sharding_catalog_manager.h +++ b/src/mongo/db/s/config/sharding_catalog_manager.h @@ -437,6 +437,20 @@ public: */ Status setFeatureCompatibilityVersionOnShards(OperationContext* opCtx, const BSONObj& cmdObj); + /** + * Upgrade the persistent metadata to FCV 5.1 (phase 2). + * + * TODO: Remove once FCV 6.0 becomes last-lts + */ + void upgradeMetadataTo51Phase2(OperationContext* opCtx); + + /** + * Upgrade the persistent metadata from FCV 5.1 (phase 2). + * + * TODO: Remove once FCV 6.0 becomes last-lts + */ + void downgradeMetadataToPre51Phase2(OperationContext* opCtx); + /* * Rename collection metadata as part of a renameCollection operation. * @@ -572,6 +586,30 @@ private: const std::string& shardName, const std::string& zoneName); + /** + * Enable the support for long collection name for each entity in 'config.collections' for + * which the support is unset, then force the catalog cache refresh of updated collections on + * each shard. + * + * This metadata change is not bound to any specific setFCV phase, so it could be safely run in + * phase 1 or 2. + * + * TODO: Remove once FCV 6.0 becomes last-lts + */ + void _enableSupportForLongCollectionName(OperationContext* opCtx); + + /** + * Disable the support for long collection name for each entity in 'config.collections' for + * which the support is implicitely enabled, then force the catalog cache refresh of updated + * collections on each shard. + * + * This metadata change is not bound to any specific setFCV phase, so it could be safely run in + * phase 1 or 2. + * + * TODO: Remove once FCV 6.0 becomes last-lts + */ + void _disableSupportForLongCollectionName(OperationContext* opCtx); + // The owning service context ServiceContext* const _serviceContext; diff --git a/src/mongo/db/s/create_collection_coordinator.cpp b/src/mongo/db/s/create_collection_coordinator.cpp index bd9b4819a6f..5eeb7f09c60 100644 --- a/src/mongo/db/s/create_collection_coordinator.cpp +++ b/src/mongo/db/s/create_collection_coordinator.cpp @@ -758,9 +758,17 @@ void CreateCollectionCoordinator::_commit(OperationContext* opCtx) { coll.setKeyPattern(_shardKeyPattern->getKeyPattern()); + // Prevent the FCV from changing before committing the new collection to the config server. This + // ensures that the 'supportingLongName' field is properly set (and committed) based on the + // current shard's FCV. + // + // TODO: Remove once FCV 6.0 becomes last-lts + FixedFCVRegion fixedFCVRegion(opCtx); + + // TODO: Remove condition once FCV 6.0 becomes last-lts const auto& currentFCV = serverGlobalParams.featureCompatibility; if (currentFCV.isGreaterThanOrEqualTo( - ServerGlobalParams::FeatureCompatibility::Version::kVersion51)) { + ServerGlobalParams::FeatureCompatibility::Version::kUpgradingFrom50To51)) { coll.setSupportingLongName(SupportingLongNameStatusEnum::kImplicitlyEnabled); } |