diff options
Diffstat (limited to 'src/mongo/db/introspect.cpp')
-rw-r--r-- | src/mongo/db/introspect.cpp | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/src/mongo/db/introspect.cpp b/src/mongo/db/introspect.cpp index bc3232f31a2..f63cffbd86c 100644 --- a/src/mongo/db/introspect.cpp +++ b/src/mongo/db/introspect.cpp @@ -89,21 +89,25 @@ void profile(OperationContext* opCtx, NetworkOp op) { // replication lag. As such, they should be excluded from Flow Control. opCtx->setShouldParticipateInFlowControl(false); + // Set the opCtx to be only interruptible for replication state changes. This is needed + // because for some operations that are already marked as killed due to errors such as + // operation time exceeding maxTimeMS, we still want to output the profiler entry. Thus + // in these cases we do not interrupt lock acquisition even though the opCtx has already + // been killed. In the meantime we need to make sure replication state changes can still + // interrupt lock acquisition, otherwise there could be deadlocks when the state change + // thread is waiting for the session checked out by this opCtx while holding RSTL lock. + // However when maxLockTimeout is set, we want it to be always interruptible. + if (!opCtx->lockState()->hasMaxLockTimeout()) { + opCtx->setIgnoreInterruptsExceptForReplStateChange(true); + } + // IX lock acquisitions beyond this block will not be related to writes to system.profile. - ON_BLOCK_EXIT( - [opCtx, origFlowControl] { opCtx->setShouldParticipateInFlowControl(origFlowControl); }); + ON_BLOCK_EXIT([opCtx, origFlowControl] { + opCtx->setIgnoreInterruptsExceptForReplStateChange(false); + opCtx->setShouldParticipateInFlowControl(origFlowControl); + }); try { - - // Even if the operation we are profiling was interrupted, we still want to output the - // profiler entry. This lock guard will prevent lock acquisitions from throwing exceptions - // before we finish writing the entry. However, our maximum lock timeout overrides - // uninterruptibility. - boost::optional<UninterruptibleLockGuard> noInterrupt; - if (!opCtx->lockState()->hasMaxLockTimeout()) { - noInterrupt.emplace(opCtx->lockState()); - } - const auto dbProfilingNS = NamespaceString(dbName, "system.profile"); AutoGetCollection autoColl(opCtx, dbProfilingNS, MODE_IX); Database* const db = autoColl.getDb(); |