summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Polato <paolo.polato@mongodb.com>2022-04-04 13:35:54 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-04-04 14:08:01 +0000
commite44576384c3ed73e60f5e40b128df38ddb6ac981 (patch)
tree6f8b0bc66a4ce6f8e9d9c13cdfadeb7c5897d1d9
parente2accb7dc1f8d1b465f5628fbbfec18e5f3fa713 (diff)
downloadmongo-e44576384c3ed73e60f5e40b128df38ddb6ac981.tar.gz
SERVER-65169 fix deadlock in BalancerCommandsScheduler while stepping down
-rw-r--r--src/mongo/db/s/balancer/balancer_commands_scheduler_impl.cpp6
-rw-r--r--src/mongo/db/s/balancer/balancer_commands_scheduler_impl.h6
2 files changed, 10 insertions, 2 deletions
diff --git a/src/mongo/db/s/balancer/balancer_commands_scheduler_impl.cpp b/src/mongo/db/s/balancer/balancer_commands_scheduler_impl.cpp
index 338734c905e..db6ab8093a4 100644
--- a/src/mongo/db/s/balancer/balancer_commands_scheduler_impl.cpp
+++ b/src/mongo/db/s/balancer/balancer_commands_scheduler_impl.cpp
@@ -561,15 +561,17 @@ void BalancerCommandsSchedulerImpl::_workerThread() {
}
}
// Wait for each outstanding command to complete, clean out its resources and leave.
+ stdx::unordered_map<UUID, RequestData, UUID::Hash> requestsToClean;
{
stdx::unique_lock<Latch> ul(_mutex);
_stateUpdatedCV.wait(
ul, [this] { return (_requests.size() == _recentlyCompletedRequestIds.size()); });
- auto opCtxHolder = cc().makeOperationContext();
- _performDeferredCleanup(opCtxHolder.get(), _requests);
+ requestsToClean.swap(_requests);
_requests.clear();
_recentlyCompletedRequestIds.clear();
}
+ auto opCtxHolder = cc().makeOperationContext();
+ _performDeferredCleanup(opCtxHolder.get(), requestsToClean);
}
diff --git a/src/mongo/db/s/balancer/balancer_commands_scheduler_impl.h b/src/mongo/db/s/balancer/balancer_commands_scheduler_impl.h
index 7f57527367e..3cb23e4e565 100644
--- a/src/mongo/db/s/balancer/balancer_commands_scheduler_impl.h
+++ b/src/mongo/db/s/balancer/balancer_commands_scheduler_impl.h
@@ -635,6 +635,12 @@ private:
void _enqueueRequest(WithLock, RequestData&& request);
+ /**
+ * Clears any persisted state and releases any distributed lock associated to the list of
+ * requests specified.
+ * This method must not be called while holding any mutex (this could cause deadlocks if a
+ * stepdown request is also being served).
+ */
void _performDeferredCleanup(
OperationContext* opCtx,
const stdx::unordered_map<UUID, RequestData, UUID::Hash>& requestsHoldingResources);