diff options
author | Benjamin Murphy <benjamin_murphy@me.com> | 2016-01-25 16:36:23 -0500 |
---|---|---|
committer | Charlie Swanson <charlie.swanson@mongodb.com> | 2016-01-27 09:28:14 -0500 |
commit | 58f2842252bc833b3b051d46117d3f243ac2548f (patch) | |
tree | 6b3116a8e1ec51d0c46b7dda51e11c715e264330 | |
parent | cb89e4f26016974febe5c5d3656103733a768e86 (diff) | |
download | mongo-58f2842252bc833b3b051d46117d3f243ac2548f.tar.gz |
SERVER-21409 Read-only profile command takes only shared lock.
Closes #1063
Signed-off-by: Charlie Swanson <charlie.swanson@mongodb.com>
-rw-r--r-- | src/mongo/db/dbcommands.cpp | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp index 4d1959c2b66..97f5d852530 100644 --- a/src/mongo/db/dbcommands.cpp +++ b/src/mongo/db/dbcommands.cpp @@ -341,26 +341,32 @@ public: int options, string& errmsg, BSONObjBuilder& result) { - // Needs to be locked exclusively, because creates the system.profile collection - // in the local database. - ScopedTransaction transaction(txn, MODE_IX); - AutoGetDb ctx(txn, dbname, MODE_X); + BSONElement firstElement = cmdObj.firstElement(); + int profilingLevel = firstElement.numberInt(); + + // If profilingLevel is 0, 1, or 2, needs to be locked exclusively, + // because creates the system.profile collection in the local database. + + const bool readOnly = (profilingLevel < 0 || profilingLevel > 2); + const LockMode dbMode = readOnly ? MODE_S : MODE_X; + const LockMode transactionMode = readOnly ? MODE_IS : MODE_IX; + + Status status = Status::OK(); + + ScopedTransaction transaction(txn, transactionMode); + AutoGetDb ctx(txn, dbname, dbMode); Database* db = ctx.getDb(); - BSONElement e = cmdObj.firstElement(); result.append("was", db ? db->getProfilingLevel() : serverGlobalParams.defaultProfile); result.append("slowms", serverGlobalParams.slowMS); - int p = (int)e.number(); - Status status = Status::OK(); - - if (p >= 0 && p <= 2) { + if (!readOnly) { if (!db) { // When setting the profiling level, create the database if it didn't already exist. // When just reading the profiling level, we do not create the database. db = dbHolder().openDb(txn, dbname); } - status = db->setProfilingLevel(txn, p); + status = db->setProfilingLevel(txn, profilingLevel); } const BSONElement slow = cmdObj["slowms"]; |