diff options
author | Antonio Fuschetto <antonio.fuschetto@mongodb.com> | 2023-01-09 08:05:20 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2023-01-09 08:56:50 +0000 |
commit | 038e983c30733e1ba107acaf0c7edcd4f858ef22 (patch) | |
tree | 2cc801e798f1a98131e9529bb463d3974031e3e9 | |
parent | 4a948883cdff5003b215857244251179334c6ef7 (diff) | |
download | mongo-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.h | 2 | ||||
-rw-r--r-- | src/mongo/db/s/config/sharding_catalog_manager_database_operations.cpp | 18 |
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()); }(); |