summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2014-12-15 15:38:44 -0500
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2014-12-17 11:27:15 -0500
commitc5ebc6be8e3a865655acbc5ecd1cb3b96fdf44ff (patch)
treea8f5a606481a6f1d29deaf445da1a844366b409f
parentf312681a62f15196d0638da50350dd6a9c693e36 (diff)
downloadmongo-c5ebc6be8e3a865655acbc5ecd1cb3b96fdf44ff.tar.gz
SERVER-16431 Simplify DB profile code
-rw-r--r--src/mongo/db/catalog/database.cpp27
-rw-r--r--src/mongo/db/catalog/database.h7
-rw-r--r--src/mongo/db/catalog/database_holder.cpp18
-rw-r--r--src/mongo/db/catalog/database_holder.h6
-rw-r--r--src/mongo/db/client.h1
-rw-r--r--src/mongo/db/commands/write_commands/batch_executor.cpp4
-rw-r--r--src/mongo/db/dbcommands.cpp27
-rw-r--r--src/mongo/db/dbeval.cpp5
-rw-r--r--src/mongo/db/instance.cpp9
-rw-r--r--src/mongo/db/introspect.cpp233
-rw-r--r--src/mongo/db/introspect.h83
-rw-r--r--src/mongo/db/operation_context.h2
12 files changed, 197 insertions, 225 deletions
diff --git a/src/mongo/db/catalog/database.cpp b/src/mongo/db/catalog/database.cpp
index 24c0ea01821..4d873eca3e2 100644
--- a/src/mongo/db/catalog/database.cpp
+++ b/src/mongo/db/catalog/database.cpp
@@ -249,25 +249,28 @@ namespace mongo {
}
}
- bool Database::setProfilingLevel( OperationContext* txn, int newLevel , string& errmsg ) {
- if ( _profile == newLevel )
- return true;
-
- if ( newLevel < 0 || newLevel > 2 ) {
- errmsg = "profiling level has to be >=0 and <= 2";
- return false;
+ Status Database::setProfilingLevel(OperationContext* txn, int newLevel) {
+ if (_profile == newLevel) {
+ return Status::OK();
}
- if ( newLevel == 0 ) {
+ if (newLevel == 0) {
_profile = 0;
- return true;
+ return Status::OK();
}
- if (!getOrCreateProfileCollection(txn, this, true, &errmsg))
- return false;
+ if (newLevel < 0 || newLevel > 2) {
+ return Status(ErrorCodes::BadValue, "profiling level has to be >=0 and <= 2");
+ }
+
+ Status status = createProfileCollection(txn, this);
+ if (!status.isOK()) {
+ return status;
+ }
_profile = newLevel;
- return true;
+
+ return Status::OK();
}
void Database::getStats( OperationContext* opCtx, BSONObjBuilder* output, double scale ) {
diff --git a/src/mongo/db/catalog/database.h b/src/mongo/db/catalog/database.h
index 23354d3e307..ea4c2e80724 100644
--- a/src/mongo/db/catalog/database.h
+++ b/src/mongo/db/catalog/database.h
@@ -69,9 +69,12 @@ namespace mongo {
void clearTmpCollections(OperationContext* txn);
/**
- * @return true if success. false if bad level or error creating profile ns
+ * Sets a new profiling level for the database and returns the outcome.
+ *
+ * @param txn Operation context which to use for creating the profiling collection.
+ * @param newLevel New profiling level to use.
*/
- bool setProfilingLevel( OperationContext* txn, int newLevel , std::string& errmsg );
+ Status setProfilingLevel(OperationContext* txn, int newLevel);
/**
* @return true if ns is part of the database
diff --git a/src/mongo/db/catalog/database_holder.cpp b/src/mongo/db/catalog/database_holder.cpp
index c924375ef0a..dc7bd5106c5 100644
--- a/src/mongo/db/catalog/database_holder.cpp
+++ b/src/mongo/db/catalog/database_holder.cpp
@@ -30,13 +30,15 @@
#include "mongo/platform/basic.h"
+#include "mongo/db/catalog/database_holder.h"
+
#include "mongo/db/audit.h"
#include "mongo/db/auth/auth_index_d.h"
#include "mongo/db/background.h"
#include "mongo/db/client.h"
#include "mongo/db/clientcursor.h"
+#include "mongo/db/catalog/database.h"
#include "mongo/db/catalog/database_catalog_entry.h"
-#include "mongo/db/catalog/database_holder.h"
#include "mongo/db/global_environment_experiment.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/storage/storage_engine.h"
@@ -44,11 +46,9 @@
#include "mongo/util/log.h"
namespace mongo {
-
- static DatabaseHolder _dbHolder;
-
namespace {
- static StringData _todb(const StringData& ns) {
+
+ StringData _todb(const StringData& ns) {
size_t i = ns.find('.');
if (i == std::string::npos) {
uassert(13074, "db name can't be empty", ns.size());
@@ -62,12 +62,18 @@ namespace {
return d;
}
-}
+
+
+ DatabaseHolder _dbHolder;
+
+} // namespace
+
DatabaseHolder& dbHolder() {
return _dbHolder;
}
+
Database* DatabaseHolder::get(OperationContext* txn,
const StringData& ns) const {
diff --git a/src/mongo/db/catalog/database_holder.h b/src/mongo/db/catalog/database_holder.h
index dd3afdf2470..6ad69c5bef2 100644
--- a/src/mongo/db/catalog/database_holder.h
+++ b/src/mongo/db/catalog/database_holder.h
@@ -28,13 +28,17 @@
#pragma once
+#include <set>
+
#include "mongo/base/string_data.h"
-#include "mongo/db/catalog/database.h"
#include "mongo/db/namespace_string.h"
+#include "mongo/util/concurrency/mutex.h"
#include "mongo/util/string_map.h"
namespace mongo {
+ class Database;
+
/**
* Registry of opened databases.
*/
diff --git a/src/mongo/db/client.h b/src/mongo/db/client.h
index 3703d555ff2..2296fd58c9b 100644
--- a/src/mongo/db/client.h
+++ b/src/mongo/db/client.h
@@ -55,7 +55,6 @@ namespace mongo {
class AuthenticationInfo;
class Database;
class CurOp;
- class Client;
class Collection;
class AbstractMessagingPort;
class Locker;
diff --git a/src/mongo/db/commands/write_commands/batch_executor.cpp b/src/mongo/db/commands/write_commands/batch_executor.cpp
index 956f17a9c0b..31a5923ef3a 100644
--- a/src/mongo/db/commands/write_commands/batch_executor.cpp
+++ b/src/mongo/db/commands/write_commands/batch_executor.cpp
@@ -638,8 +638,8 @@ namespace mongo {
LOG(0) << currentOp->debug().report( *currentOp ) << endl;
}
- if ( currentOp->shouldDBProfile( executionTime ) ) {
- profile( txn, *txn->getClient(), currentOp->getOp(), *currentOp );
+ if (currentOp->shouldDBProfile(executionTime)) {
+ profile(txn, txn->getCurOp()->getOp());
}
}
diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp
index 19958e19d21..90d38d20e00 100644
--- a/src/mongo/db/dbcommands.cpp
+++ b/src/mongo/db/dbcommands.cpp
@@ -341,10 +341,16 @@ namespace mongo {
}
- bool run(OperationContext* txn, const string& dbname, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
+ bool run(OperationContext* txn,
+ const string& dbname,
+ BSONObj& cmdObj,
+ int options,
+ string& errmsg,
+ BSONObjBuilder& result,
+ bool fromRepl) {
+
// Needs to be locked exclusively, because creates the system.profile collection
// in the local database.
- //
ScopedTransaction transaction(txn, MODE_IX);
Lock::DBLock dbXLock(txn->lockState(), dbname, MODE_X);
Client::Context ctx(txn, dbname);
@@ -354,21 +360,26 @@ namespace mongo {
result.append("slowms", serverGlobalParams.slowMS);
int p = (int) e.number();
- bool ok = false;
+ Status status = Status::OK();
- if ( p == -1 )
- ok = true;
+ if (p == -1)
+ status = Status::OK();
else if ( p >= 0 && p <= 2 ) {
- ok = ctx.db()->setProfilingLevel( txn, p , errmsg );
+ status = ctx.db()->setProfilingLevel(txn, p);
}
- BSONElement slow = cmdObj["slowms"];
+ const BSONElement slow = cmdObj["slowms"];
if (slow.isNumber()) {
serverGlobalParams.slowMS = slow.numberInt();
}
- return ok;
+ if (!status.isOK()) {
+ errmsg = status.reason();
+ }
+
+ return status.isOK();
}
+
} cmdProfile;
class CmdDiagLogging : public Command {
diff --git a/src/mongo/db/dbeval.cpp b/src/mongo/db/dbeval.cpp
index 72d7ebcd977..b873b64b760 100644
--- a/src/mongo/db/dbeval.cpp
+++ b/src/mongo/db/dbeval.cpp
@@ -32,16 +32,16 @@
#include "mongo/platform/basic.h"
-#include <time.h>
-
#include "mongo/bson/util/builder.h"
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/authorization_manager_global.h"
#include "mongo/db/auth/authorization_session.h"
+#include "mongo/db/client.h"
#include "mongo/db/commands.h"
#include "mongo/db/introspect.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/json.h"
+#include "mongo/db/operation_context.h"
#include "mongo/scripting/engine.h"
#include "mongo/util/log.h"
@@ -153,6 +153,7 @@ namespace mongo {
ScopedTransaction transaction(txn, MODE_X);
Lock::GlobalWrite lk(txn->lockState());
+
// No WriteUnitOfWork necessary, as dbEval will create its own, see "nolock" case above
Client::Context ctx(txn, dbname );
diff --git a/src/mongo/db/instance.cpp b/src/mongo/db/instance.cpp
index aad9da30096..ccc949ed6f0 100644
--- a/src/mongo/db/instance.cpp
+++ b/src/mongo/db/instance.cpp
@@ -489,17 +489,12 @@ namespace {
}
if ( currentOp.shouldDBProfile( debug.executionTime ) ) {
- // performance profiling is on
- if (txn->lockState()->isReadLocked()) {
- MONGO_LOG_COMPONENT(1, logComponentForOp(op))
- << "note: not profiling because recursive read lock" << endl;
- }
- else if ( lockedForWriting() ) {
+ if (lockedForWriting()) {
MONGO_LOG_COMPONENT(1, logComponentForOp(op))
<< "note: not profiling because doing fsync+lock" << endl;
}
else {
- profile(txn, c, op, currentOp);
+ profile(txn, op);
}
}
diff --git a/src/mongo/db/introspect.cpp b/src/mongo/db/introspect.cpp
index 6dd6c323a99..65a5bee8c86 100644
--- a/src/mongo/db/introspect.cpp
+++ b/src/mongo/db/introspect.cpp
@@ -1,53 +1,49 @@
-// introspect.cpp
-
/**
-* Copyright (C) 2008 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*
-* As a special exception, the copyright holders give permission to link the
-* code of portions of this program with the OpenSSL library under certain
-* conditions as described in each individual source file and distribute
-* linked combinations including the program with the OpenSSL library. You
-* must comply with the GNU Affero General Public License in all respects for
-* all of the code used other than as permitted herein. If you modify file(s)
-* with this exception, you may extend this exception to your version of the
-* file(s), but you are not obligated to do so. If you do not wish to do so,
-* delete this exception statement from your version. If you delete this
-* exception statement from all source files in the program, then also delete
-* it in the license file.
-*/
+ * Copyright (C) 2008 MongoDB Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kDefault
-#include "mongo/pch.h"
+#include "mongo/platform/basic.h"
+
+#include "mongo/db/introspect.h"
#include "mongo/bson/util/builder.h"
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/auth/user_set.h"
#include "mongo/db/curop.h"
-#include "mongo/db/catalog/database_holder.h"
-#include "mongo/db/introspect.h"
#include "mongo/db/jsobj.h"
-#include "mongo/db/storage_options.h"
#include "mongo/db/catalog/collection.h"
-#include "mongo/util/goodies.h"
#include "mongo/util/log.h"
namespace mongo {
-
namespace {
+
void _appendUserInfo(const CurOp& c,
BSONObjBuilder& builder,
AuthorizationSession* authSession) {
@@ -75,141 +71,110 @@ namespace {
builder.append("user", bestUser.getUser().empty() ? "" : bestUser.getFullName());
}
+
} // namespace
- /**
- * @return if collection existed or was created
- */
- static bool _profile(OperationContext* txn,
- const Client& c,
- Database* db,
- CurOp& currentOp,
- BufBuilder& profileBufBuilder) {
- dassert( db );
-
- // build object
+
+ void profile(OperationContext* txn, int op) {
+ // initialize with 1kb to start, to avoid realloc later
+ BufBuilder profileBufBuilder(1024);
+
BSONObjBuilder b(profileBufBuilder);
- currentOp.debug().append(currentOp, b);
+ txn->getCurOp()->debug().append(*txn->getCurOp(), b);
b.appendDate("ts", jsTime());
- b.append("client", c.clientAddress());
+ b.append("client", txn->getClient()->clientAddress());
- AuthorizationSession * authSession = c.getAuthorizationSession();
- _appendUserInfo(currentOp, b, authSession);
+ AuthorizationSession * authSession = txn->getClient()->getAuthorizationSession();
+ _appendUserInfo(*txn->getCurOp(), b, authSession);
BSONObj p = b.done();
- WriteUnitOfWork wunit(txn);
+ const string dbName(nsToDatabase(txn->getCurOp()->getNS()));
- // write: not replicated
- // get or create the profiling collection
- Collection* profileCollection = getOrCreateProfileCollection(txn, db);
- if ( !profileCollection ) {
- return false;
- }
- profileCollection->insertDocument( txn, p, false );
- wunit.commit();
- return true;
- }
+ try {
+ bool acquireDbXLock = false;
+ while (true) {
+ ScopedTransaction scopedXact(txn, MODE_IX);
- void profile(OperationContext* txn, const Client& c, int op, CurOp& currentOp) {
- bool tryAgain = false;
- while ( 1 ) {
- try {
- // initialize with 1kb to start, to avoid realloc later
- // doing this outside the dblock to improve performance
- BufBuilder profileBufBuilder(1024);
-
- // NOTE: It's kind of weird that we lock the op's namespace, but have to for now
- // since we're sometimes inside the lock already
- const string dbname(nsToDatabase(currentOp.getNS()));
- scoped_ptr<Lock::DBLock> lk;
-
- // todo: this can be slow, perhaps can re-work
- if ( !txn->lockState()->isDbLockedForMode( dbname, MODE_IX ) ) {
- lk.reset( new Lock::DBLock( txn->lockState(),
- dbname,
- tryAgain ? MODE_X : MODE_IX) );
- }
- Database* db = dbHolder().get(txn, dbname);
- if (db != NULL) {
- Lock::CollectionLock clk(txn->lockState(), db->getProfilingNS(), MODE_X);
- Client::Context cx(txn, currentOp.getNS(), false);
- if ( !_profile(txn, c, cx.db(), currentOp, profileBufBuilder ) && lk.get() ) {
- if ( tryAgain ) {
- // we couldn't profile, but that's ok, we should have logged already
- break;
- }
- // we took an IX lock, so now we try again with an X lock
- tryAgain = true;
- continue;
+ boost::scoped_ptr<AutoGetDb> autoGetDb;
+ if (acquireDbXLock) {
+ autoGetDb.reset(new AutoGetDb(txn, dbName, MODE_X));
+ if (autoGetDb->getDb()) {
+ createProfileCollection(txn, autoGetDb->getDb());
}
}
else {
- mongo::log() << "note: not profiling because db went away - "
- << "probably a close on: " << currentOp.getNS();
+ autoGetDb.reset(new AutoGetDb(txn, dbName, MODE_IX));
+ }
+
+ Database* const db = autoGetDb->getDb();
+ if (!db) {
+ // Database disappeared
+ log() << "note: not profiling because db went away for "
+ << txn->getCurOp()->getNS();
+ break;
+ }
+
+ Lock::CollectionLock collLock(txn->lockState(), db->getProfilingNS(), MODE_IX);
+
+ Collection* const coll = db->getCollection(txn, db->getProfilingNS());
+ if (coll) {
+ WriteUnitOfWork wuow(txn);
+ coll->insertDocument(txn, p, false);
+ wuow.commit();
+
+ break;
+ }
+ else if (!acquireDbXLock && !txn->lockState()->isLocked()) {
+ // Try to create the collection only if we are not under lock, in order to
+ // avoid deadlocks due to lock conversion. This would only be hit if someone
+ // deletes the profiler collection after setting profile level.
+ acquireDbXLock = true;
+ }
+ else {
+ // Cannot write the profile information
+ break;
}
- return;
- }
- catch (const AssertionException& assertionEx) {
- warning() << "Caught Assertion while trying to profile " << opToString(op)
- << " against " << currentOp.getNS()
- << ": " << assertionEx.toString() << endl;
- return;
}
}
+ catch (const AssertionException& assertionEx) {
+ warning() << "Caught Assertion while trying to profile "
+ << opToString(op)
+ << " against " << txn->getCurOp()->getNS()
+ << ": " << assertionEx.toString() << endl;
+ }
}
- Collection* getOrCreateProfileCollection(OperationContext* txn,
- Database *db,
- bool force,
- string* errmsg ) {
- fassert(16372, db);
- const char* profileName = db->getProfilingNS();
- Collection* collection = db->getCollection( txn, profileName );
-
- if ( collection ) {
- if ( !collection->isCapped() ) {
- string myerrmsg = str::stream() << profileName << " exists but isn't capped";
- log() << myerrmsg << endl;
- if ( errmsg )
- *errmsg = myerrmsg;
- return NULL;
- }
- return collection;
- }
- // does not exist!
+ Status createProfileCollection(OperationContext* txn, Database *db) {
+ invariant(txn->lockState()->isDbLockedForMode(db->name(), MODE_X));
+
+ const std::string dbProfilingNS(db->getProfilingNS());
- if ( force == false && serverGlobalParams.defaultProfile == false ) {
- // we don't want it, so why are we here?
- static time_t last = time(0) - 10; // warn the first time
- if( time(0) > last+10 ) {
- log() << "profile: warning ns " << profileName << " does not exist" << endl;
- last = time(0);
+ Collection* const collection = db->getCollection(txn, dbProfilingNS);
+ if (collection) {
+ if (!collection->isCapped()) {
+ return Status(ErrorCodes::NamespaceExists,
+ str::stream() << dbProfilingNS << " exists but isn't capped");
}
- return NULL;
- }
- if ( !txn->lockState()->isDbLockedForMode( db->name(), MODE_X ) ) {
- // can't create here
- return NULL;
+ return Status::OK();
}
// system.profile namespace doesn't exist; create it
- log() << "creating profile collection: " << profileName << endl;
+ log() << "Creating profile collection: " << dbProfilingNS << endl;
CollectionOptions collectionOptions;
collectionOptions.capped = true;
collectionOptions.cappedSize = 1024 * 1024;
WriteUnitOfWork wunit(txn);
- collection = db->createCollection( txn, profileName, collectionOptions );
- invariant( collection );
+ invariant(db->createCollection(txn, dbProfilingNS, collectionOptions));
wunit.commit();
- return collection;
+ return Status::OK();
}
} // namespace mongo
diff --git a/src/mongo/db/introspect.h b/src/mongo/db/introspect.h
index 07af4ba6653..2a6ec2a477f 100644
--- a/src/mongo/db/introspect.h
+++ b/src/mongo/db/introspect.h
@@ -1,63 +1,48 @@
-// introspect.h
-// system management stuff.
-
/**
-* Copyright (C) 2008 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*
-* As a special exception, the copyright holders give permission to link the
-* code of portions of this program with the OpenSSL library under certain
-* conditions as described in each individual source file and distribute
-* linked combinations including the program with the OpenSSL library. You
-* must comply with the GNU Affero General Public License in all respects for
-* all of the code used other than as permitted herein. If you modify file(s)
-* with this exception, you may extend this exception to your version of the
-* file(s), but you are not obligated to do so. If you do not wish to do so,
-* delete this exception statement from your version. If you delete this
-* exception statement from all source files in the program, then also delete
-* it in the license file.
-*/
+ * Copyright (C) 2008 MongoDB Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
#pragma once
-#include <string>
-
-#include "mongo/db/curop.h"
-#include "mongo/db/jsobj.h"
+#include "mongo/base/status.h"
namespace mongo {
- class Collection;
class Database;
class OperationContext;
- /* --- profiling --------------------------------------------
- do when database->profile is set
- */
-
- void profile(OperationContext* txn, const Client& c, int op, CurOp& currentOp);
+ /**
+ * Invoked when database profile is enabled.
+ */
+ void profile(OperationContext* txn, int op);
/**
- * Get (or create) the profile collection
- *
- * @param db Database in which to create the profile collection
- * @param force Always create the collection if it does not exist
- * @return Collection for the newly created collection, or NULL on error
- **/
- Collection* getOrCreateProfileCollection(OperationContext* txn,
- Database *db,
- bool force = false,
- std::string* errmsg = NULL);
+ * Pre-creates the profile collection for the specified database.
+ */
+ Status createProfileCollection(OperationContext* txn, Database *db);
} // namespace mongo
diff --git a/src/mongo/db/operation_context.h b/src/mongo/db/operation_context.h
index 59c190733f8..036e2be83b9 100644
--- a/src/mongo/db/operation_context.h
+++ b/src/mongo/db/operation_context.h
@@ -30,7 +30,6 @@
#include "mongo/base/disallow_copying.h"
#include "mongo/base/status.h"
-#include "mongo/base/string_data.h"
#include "mongo/db/storage/recovery_unit.h"
#include "mongo/db/concurrency/locker.h"
#include "mongo/db/concurrency/d_concurrency.h"
@@ -40,6 +39,7 @@ namespace mongo {
class Client;
class CurOp;
class ProgressMeter;
+ class StringData;
/**
* This class encompasses the state required by an operation.