diff options
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/s/config/sharding_catalog_manager_database_operations.cpp | 74 | ||||
-rw-r--r-- | src/mongo/db/s/create_collection_coordinator.cpp | 39 |
2 files changed, 67 insertions, 46 deletions
diff --git a/src/mongo/db/s/config/sharding_catalog_manager_database_operations.cpp b/src/mongo/db/s/config/sharding_catalog_manager_database_operations.cpp index 4d6ee0347e2..212e598bb67 100644 --- a/src/mongo/db/s/config/sharding_catalog_manager_database_operations.cpp +++ b/src/mongo/db/s/config/sharding_catalog_manager_database_operations.cpp @@ -48,6 +48,7 @@ #include "mongo/s/client/shard.h" #include "mongo/s/grid.h" #include "mongo/s/shard_util.h" +#include "mongo/s/sharding_feature_flags_gen.h" namespace mongo { namespace { @@ -93,7 +94,7 @@ DatabaseType ShardingCatalogManager::createDatabase(OperationContext* opCtx, } uassert(ErrorCodes::InvalidOptions, - str::stream() << "Cannot manually create or shard database '" << dbName << "'", + str::stream() << "Cannot manually create database'" << dbName << "'", dbName != NamespaceString::kAdminDb && dbName != NamespaceString::kLocalDb); uassert(ErrorCodes::InvalidNamespace, @@ -103,39 +104,55 @@ DatabaseType ShardingCatalogManager::createDatabase(OperationContext* opCtx, // Make sure to force update of any stale metadata ON_BLOCK_EXIT([&] { Grid::get(opCtx)->catalogCache()->purgeDatabase(dbName); }); + auto& replClient = repl::ReplClientInfo::forClient(opCtx->getClient()); + DBDirectClient client(opCtx); boost::optional<DistLockManager::ScopedLock> dbLock; - // First perform an optimistic attempt to write the 'sharded' field to the database entry, in - // case this is the only thing, which is missing. If that doesn't succeed, go through the + const auto enableShardingOptional = + feature_flags::gEnableShardingOptional.isEnabled(serverGlobalParams.featureCompatibility); + + const auto dbMatchFilter = [&] { + BSONObjBuilder filterBuilder; + filterBuilder.append(DatabaseType::kNameFieldName, dbName); + if (optPrimaryShard) { + uassert(ErrorCodes::BadValue, + str::stream() << "invalid shard name: " << *optPrimaryShard, + optPrimaryShard->isValid()); + filterBuilder.append(DatabaseType::kPrimaryFieldName, optPrimaryShard->toString()); + } + return filterBuilder.obj(); + }(); + + + // First perform an optimistic attempt to write the 'sharded' field to the database entry, + // in case this is the only thing, which is missing. If that doesn't succeed, go through the // expensive createDatabase flow. while (true) { - auto response = client.findAndModify([&] { - write_ops::FindAndModifyCommandRequest findAndModify( - NamespaceString::kConfigDatabasesNamespace); - findAndModify.setQuery([&] { - BSONObjBuilder queryFilterBuilder; - queryFilterBuilder.append(DatabaseType::kNameFieldName, dbName); - if (optPrimaryShard) { - uassert(ErrorCodes::BadValue, - str::stream() << "invalid shard name: " << *optPrimaryShard, - optPrimaryShard->isValid()); - queryFilterBuilder.append(DatabaseType::kPrimaryFieldName, - optPrimaryShard->toString()); - } - return queryFilterBuilder.obj(); + if (!enableShardingOptional) { + auto response = client.findAndModify([&] { + write_ops::FindAndModifyCommandRequest findAndModify( + NamespaceString::kConfigDatabasesNamespace); + findAndModify.setQuery(dbMatchFilter); + findAndModify.setUpdate(write_ops::UpdateModification::parseFromClassicUpdate( + BSON("$set" << BSON(DatabaseType::kShardedFieldName << enableSharding)))); + findAndModify.setUpsert(false); + findAndModify.setNew(true); + return findAndModify; }()); - findAndModify.setUpdate(write_ops::UpdateModification::parseFromClassicUpdate( - BSON("$set" << BSON(DatabaseType::kShardedFieldName << enableSharding)))); - findAndModify.setUpsert(false); - findAndModify.setNew(true); - return findAndModify; - }()); - - if (response.getLastErrorObject().getNumDocs()) { - uassert(528120, "Missing value in the response", response.getValue()); - return DatabaseType::parse(IDLParserErrorContext("DatabaseType"), *response.getValue()); + + if (response.getLastErrorObject().getNumDocs()) { + uassert(528120, "Missing value in the response", response.getValue()); + return DatabaseType::parse(IDLParserErrorContext("DatabaseType"), + *response.getValue()); + } + } else { + auto dbObj = client.findOne(NamespaceString::kConfigDatabasesNamespace, dbMatchFilter); + if (!dbObj.isEmpty()) { + replClient.setLastOpToSystemLastOpTime(opCtx); + return DatabaseType::parse(IDLParserErrorContext("DatabaseType"), std::move(dbObj)); + } } if (dbLock) { @@ -151,7 +168,6 @@ DatabaseType ShardingCatalogManager::createDatabase(OperationContext* opCtx, // Expensive createDatabase code path const auto catalogClient = Grid::get(opCtx)->catalogClient(); const auto shardRegistry = Grid::get(opCtx)->shardRegistry(); - auto& replClient = repl::ReplClientInfo::forClient(opCtx->getClient()); // Check if a database already exists with the same name (case sensitive), and if so, return the // existing entry. @@ -200,7 +216,7 @@ DatabaseType ShardingCatalogManager::createDatabase(OperationContext* opCtx, // Pick a primary shard for the new database. DatabaseType db(dbName.toString(), shardPtr->getId(), - enableSharding, + enableShardingOptional ? false : enableSharding, DatabaseVersion(UUID::gen(), clusterTime)); LOGV2(21938, diff --git a/src/mongo/db/s/create_collection_coordinator.cpp b/src/mongo/db/s/create_collection_coordinator.cpp index 4016982d6c1..72766e99945 100644 --- a/src/mongo/db/s/create_collection_coordinator.cpp +++ b/src/mongo/db/s/create_collection_coordinator.cpp @@ -57,6 +57,7 @@ #include "mongo/s/cluster_commands_helpers.h" #include "mongo/s/cluster_write.h" #include "mongo/s/grid.h" +#include "mongo/s/sharding_feature_flags_gen.h" namespace mongo { namespace { @@ -630,25 +631,29 @@ ExecutorFuture<void> CreateCollectionCoordinator::_runImpl( void CreateCollectionCoordinator::_checkCommandArguments(OperationContext* opCtx) { LOGV2_DEBUG(5277902, 2, "Create collection _checkCommandArguments", "namespace"_attr = nss()); - const auto dbEnabledForSharding = [&, this] { - // The modification of the 'sharded' flag for the db does not imply a database version - // change so we can't use the DatabaseShardingState to look it up. Instead we will do a - // first attempt through the catalog cache and if it is unset we will attempt another time - // after a forced catalog cache refresh. - auto catalogCache = Grid::get(opCtx)->catalogCache(); - - auto dbInfo = uassertStatusOK(catalogCache->getDatabase(opCtx, nss().db())); - if (!dbInfo.shardingEnabled()) { - sharding_ddl_util::linearizeCSRSReads(opCtx); - dbInfo = uassertStatusOK(catalogCache->getDatabaseWithRefresh(opCtx, nss().db())); - } + if (!feature_flags::gEnableShardingOptional.isEnabled( + serverGlobalParams.featureCompatibility)) { - return dbInfo.shardingEnabled(); - }(); + const auto dbEnabledForSharding = [&, this] { + // The modification of the 'sharded' flag for the db does not imply a database version + // change so we can't use the DatabaseShardingState to look it up. Instead we will do a + // first attempt through the catalog cache and if it is unset we will attempt another + // time after a forced catalog cache refresh. + auto catalogCache = Grid::get(opCtx)->catalogCache(); - uassert(ErrorCodes::IllegalOperation, - str::stream() << "sharding not enabled for db " << nss().db(), - dbEnabledForSharding); + auto dbInfo = uassertStatusOK(catalogCache->getDatabase(opCtx, nss().db())); + if (!dbInfo.shardingEnabled()) { + sharding_ddl_util::linearizeCSRSReads(opCtx); + dbInfo = uassertStatusOK(catalogCache->getDatabaseWithRefresh(opCtx, nss().db())); + } + + return dbInfo.shardingEnabled(); + }(); + + uassert(ErrorCodes::IllegalOperation, + str::stream() << "sharding not enabled for db " << nss().db(), + dbEnabledForSharding); + } uassert(ErrorCodes::InvalidNamespace, str::stream() << "Namespace too long. Namespace: " << nss() |