summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorJustin Seyster <justin.seyster@mongodb.com>2019-01-07 13:20:32 -0500
committerJustin Seyster <justin.seyster@mongodb.com>2019-01-08 17:44:35 -0500
commite2b8d928d796b4b6a6144bc4aa27db6fe95bfdd8 (patch)
treed8bbe57bf3aa2821aa3b3480c42754cc4d3cad2f /src/mongo
parent3b1c553162427b271266a96b0f80a9b713306788 (diff)
downloadmongo-e2b8d928d796b4b6a6144bc4aa27db6fe95bfdd8.tar.gz
SERVER-38481 No strong locks in profiling while uninterruptible
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/introspect.cpp20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/mongo/db/introspect.cpp b/src/mongo/db/introspect.cpp
index 8bda2543426..fe8405db343 100644
--- a/src/mongo/db/introspect.cpp
+++ b/src/mongo/db/introspect.cpp
@@ -117,6 +117,10 @@ void profile(OperationContext* opCtx, NetworkOp op) {
const string dbName(nsToDatabase(CurOp::get(opCtx)->getNS()));
+ // True if we need to acquire an X lock on the database in order to create the system.profile
+ // collection.
+ bool acquireDbXLock = false;
+
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
@@ -127,10 +131,12 @@ void profile(OperationContext* opCtx, NetworkOp op) {
noInterrupt.emplace(opCtx->lockState());
}
- bool acquireDbXLock = false;
while (true) {
std::unique_ptr<AutoGetDb> autoGetDb;
if (acquireDbXLock) {
+ // We should not attempt to acquire an X lock while in "noInterrupt" scope.
+ noInterrupt.reset();
+
autoGetDb.reset(new AutoGetDb(opCtx, dbName, MODE_X));
if (autoGetDb->getDb()) {
createProfileCollection(opCtx, autoGetDb->getDb()).transitional_ignore();
@@ -170,8 +176,16 @@ void profile(OperationContext* opCtx, NetworkOp op) {
}
}
} catch (const AssertionException& assertionEx) {
- warning() << "Caught Assertion while trying to profile " << networkOpToString(op)
- << " against " << CurOp::get(opCtx)->getNS() << ": " << redact(assertionEx);
+ if (acquireDbXLock && assertionEx.isA<ErrorCategory::Interruption>()) {
+ warning()
+ << "Interrupted while attempting to create profile collection in database "
+ << dbName << " to profile operation " << networkOpToString(op) << " against "
+ << CurOp::get(opCtx)->getNS()
+ << ". Manually create profile collection to ensure future operations are logged.";
+ } else {
+ warning() << "Caught Assertion while trying to profile " << networkOpToString(op)
+ << " against " << CurOp::get(opCtx)->getNS() << ": " << redact(assertionEx);
+ }
}
}