summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/s/config/sharding_catalog_manager_database_operations.cpp74
-rw-r--r--src/mongo/db/s/create_collection_coordinator.cpp39
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()