summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Fuschetto <antonio.fuschetto@mongodb.com>2023-01-09 08:05:20 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-01-09 08:56:50 +0000
commit038e983c30733e1ba107acaf0c7edcd4f858ef22 (patch)
tree2cc801e798f1a98131e9529bb463d3974031e3e9
parent4a948883cdff5003b215857244251179334c6ef7 (diff)
downloadmongo-038e983c30733e1ba107acaf0c7edcd4f858ef22.tar.gz
SERVER-69890 Concurrent movePrimary and removeShard can move database to a no-longer existent shard
-rw-r--r--src/mongo/db/s/config/sharding_catalog_manager.h2
-rw-r--r--src/mongo/db/s/config/sharding_catalog_manager_database_operations.cpp18
2 files changed, 17 insertions, 3 deletions
diff --git a/src/mongo/db/s/config/sharding_catalog_manager.h b/src/mongo/db/s/config/sharding_catalog_manager.h
index e6102f8b533..54cc6bf23ae 100644
--- a/src/mongo/db/s/config/sharding_catalog_manager.h
+++ b/src/mongo/db/s/config/sharding_catalog_manager.h
@@ -403,7 +403,7 @@ public:
void commitMovePrimary(OperationContext* opCtx,
const StringData& dbName,
const DatabaseVersion& expectedDbVersion,
- const ShardId& toShard);
+ const ShardId& toShardId);
//
// Collection Operations
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 fadb1299d45..c2489780880 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
@@ -272,10 +272,24 @@ DatabaseType ShardingCatalogManager::createDatabase(OperationContext* opCtx,
void ShardingCatalogManager::commitMovePrimary(OperationContext* opCtx,
const StringData& dbName,
const DatabaseVersion& expectedDbVersion,
- const ShardId& toShard) {
+ const ShardId& toShardId) {
// Hold the shard lock until the entire commit finishes to serialize with removeShard.
Lock::SharedLock shardLock(opCtx->lockState(), _kShardMembershipLock);
+ const auto toShardDoc = [&] {
+ DBDirectClient dbClient(opCtx);
+ return dbClient.findOne(NamespaceString::kConfigsvrShardsNamespace,
+ BSON(ShardType::name << toShardId));
+ }();
+ uassert(ErrorCodes::ShardNotFound,
+ "Requested primary shard {} does not exist"_format(toShardId.toString()),
+ !toShardDoc.isEmpty());
+
+ const auto toShardEntry = uassertStatusOK(ShardType::fromBSON(toShardDoc));
+ uassert(ErrorCodes::ShardNotFound,
+ "Requested primary shard {} is draining"_format(toShardId.toString()),
+ !toShardEntry.getDraining());
+
const auto updateOp = [&] {
const auto query = [&] {
BSONObjBuilder bsonBuilder;
@@ -293,7 +307,7 @@ void ShardingCatalogManager::commitMovePrimary(OperationContext* opCtx,
const auto newDbVersion = expectedDbVersion.makeUpdated();
BSONObjBuilder bsonBuilder;
- bsonBuilder.append(DatabaseType::kPrimaryFieldName, toShard);
+ bsonBuilder.append(DatabaseType::kPrimaryFieldName, toShardId);
bsonBuilder.append(DatabaseType::kVersionFieldName, newDbVersion.toBSON());
return BSON("$set" << bsonBuilder.obj());
}();