diff options
author | Allison Easton <allison.easton@mongodb.com> | 2022-03-03 13:51:48 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-03-04 10:35:04 +0000 |
commit | 676a969740251e412feb14d203e55948f703e9cb (patch) | |
tree | c854e2b62cc599539d83f1464f139f1880fc7ec9 | |
parent | 2c58842f01e616ac550de578cdfa04fcd3cda02a (diff) | |
download | mongo-676a969740251e412feb14d203e55948f703e9cb.tar.gz |
SERVER-64080 ConfigsvrConfigureCollectionBalancing should not call tellShardsToRefreshCollection while holding the chunk lock
(cherry picked from commit 8f793e746623e1337cbf833d55e310374d97146e)
-rw-r--r-- | src/mongo/db/s/config/sharding_catalog_manager_collection_operations.cpp | 59 |
1 files changed, 30 insertions, 29 deletions
diff --git a/src/mongo/db/s/config/sharding_catalog_manager_collection_operations.cpp b/src/mongo/db/s/config/sharding_catalog_manager_collection_operations.cpp index 8aef3316483..944adc0ff52 100644 --- a/src/mongo/db/s/config/sharding_catalog_manager_collection_operations.cpp +++ b/src/mongo/db/s/config/sharding_catalog_manager_collection_operations.cpp @@ -610,40 +610,41 @@ void ShardingCatalogManager::configureCollectionBalancing( return; } - // Take _kChunkOpLock in exclusive mode to prevent concurrent chunk splits, merges, and - // migrations - Lock::ExclusiveLock lk(opCtx, opCtx->lockState(), _kChunkOpLock); + const auto update = updateCmd.obj(); + { + // Take _kChunkOpLock in exclusive mode to prevent concurrent chunk splits, merges, and + // migrations + Lock::ExclusiveLock lk(opCtx, opCtx->lockState(), _kChunkOpLock); + + withTransaction( + opCtx, CollectionType::ConfigNS, [&](OperationContext* opCtx, TxnNumber txnNumber) { + const auto query = BSON(CollectionType::kNssFieldName << nss.ns()); + const auto res = writeToConfigDocumentInTxn( + opCtx, + CollectionType::ConfigNS, + BatchedCommandRequest::buildUpdateOp(CollectionType::ConfigNS, + query, + update /* update */, + false /* upsert */, + false /* multi */), + txnNumber); + const auto numDocsModified = UpdateOp::parseResponse(res).getN(); + uassert(ErrorCodes::ConflictingOperationInProgress, + str::stream() << "Expected to match one doc for query " << query + << " but matched " << numDocsModified, + numDocsModified == 1); + + bumpCollectionMinorVersionInTxn(opCtx, nss, txnNumber); + }); + // Now any migrations that change the list of shards will see the results of the transaction + // during refresh, so it is safe to release the chunk lock. + } + const auto cm = uassertStatusOK( Grid::get(opCtx)->catalogCache()->getShardedCollectionRoutingInfoWithRefresh(opCtx, nss)); - const auto uuid = cm.getUUID(); - std::set<ShardId> shardsIds; cm.getAllShardIds(&shardsIds); - const auto update = updateCmd.obj(); - - withTransaction( - opCtx, CollectionType::ConfigNS, [&](OperationContext* opCtx, TxnNumber txnNumber) { - const auto query = BSON(CollectionType::kNssFieldName - << nss.ns() << CollectionType::kUuidFieldName << uuid); - const auto res = writeToConfigDocumentInTxn( - opCtx, - CollectionType::ConfigNS, - BatchedCommandRequest::buildUpdateOp(CollectionType::ConfigNS, - query, - update /* update */, - false /* upsert */, - false /* multi */), - txnNumber); - const auto numDocsModified = UpdateOp::parseResponse(res).getN(); - uassert(ErrorCodes::ConflictingOperationInProgress, - str::stream() << "Expected to match one doc for query " << query - << " but matched " << numDocsModified, - numDocsModified == 1); - - bumpCollectionMinorVersionInTxn(opCtx, nss, txnNumber); - }); - const auto executor = Grid::get(opCtx)->getExecutorPool()->getFixedExecutor(); sharding_util::tellShardsToRefreshCollection( opCtx, |