summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Murphy <benjamin_murphy@me.com>2016-01-25 16:36:23 -0500
committerCharlie Swanson <charlie.swanson@mongodb.com>2016-01-27 09:28:14 -0500
commit58f2842252bc833b3b051d46117d3f243ac2548f (patch)
tree6b3116a8e1ec51d0c46b7dda51e11c715e264330
parentcb89e4f26016974febe5c5d3656103733a768e86 (diff)
downloadmongo-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.cpp26
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"];