summaryrefslogtreecommitdiff
path: root/src/mongo/db/s
diff options
context:
space:
mode:
authorAntonio Fuschetto <antonio.fuschetto@mongodb.com>2021-08-26 21:04:10 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-08-26 21:26:26 +0000
commit7f1ec52be8e1a04af3fa542d3de245d83adddd01 (patch)
tree20ffdf20b8b4460a3e3c1afecd9b4d8befcd237b /src/mongo/db/s
parentf40810c7c8706754b647992fbde1dc2745616b7c (diff)
downloadmongo-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.cpp165
-rw-r--r--src/mongo/db/s/config/sharding_catalog_manager.h38
-rw-r--r--src/mongo/db/s/create_collection_coordinator.cpp10
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);
}