summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2014-12-17 18:10:39 -0500
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2014-12-17 18:10:39 -0500
commit8d90ce21ffb7fac21fd9f287ce3d66a4c6b576b8 (patch)
treec7e199fe9f15094efd7f45234b432a2d40a02308 /src/mongo/db
parentf46ff140de92e43c34bace43be971fd903ac11d9 (diff)
downloadmongo-8d90ce21ffb7fac21fd9f287ce3d66a4c6b576b8.tar.gz
Revert "SERVER-16431 Simplify DB profile code"
This reverts commit c5ebc6be8e3a865655acbc5ecd1cb3b96fdf44ff.
Diffstat (limited to 'src/mongo/db')
-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, 225 insertions, 197 deletions
diff --git a/src/mongo/db/catalog/database.cpp b/src/mongo/db/catalog/database.cpp
index 4d873eca3e2..24c0ea01821 100644
--- a/src/mongo/db/catalog/database.cpp
+++ b/src/mongo/db/catalog/database.cpp
@@ -249,28 +249,25 @@ namespace mongo {
}
}
- Status Database::setProfilingLevel(OperationContext* txn, int newLevel) {
- if (_profile == newLevel) {
- return Status::OK();
+ 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;
}
- if (newLevel == 0) {
+ if ( newLevel == 0 ) {
_profile = 0;
- return Status::OK();
+ return true;
}
- 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;
- }
+ if (!getOrCreateProfileCollection(txn, this, true, &errmsg))
+ return false;
_profile = newLevel;
-
- return Status::OK();
+ return true;
}
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 ea4c2e80724..23354d3e307 100644
--- a/src/mongo/db/catalog/database.h
+++ b/src/mongo/db/catalog/database.h
@@ -69,12 +69,9 @@ namespace mongo {
void clearTmpCollections(OperationContext* txn);
/**
- * 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.
+ * @return true if success. false if bad level or error creating profile ns
*/
- Status setProfilingLevel(OperationContext* txn, int newLevel);
+ bool setProfilingLevel( OperationContext* txn, int newLevel , std::string& errmsg );
/**
* @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 dc7bd5106c5..c924375ef0a 100644
--- a/src/mongo/db/catalog/database_holder.cpp
+++ b/src/mongo/db/catalog/database_holder.cpp
@@ -30,15 +30,13 @@
#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"
@@ -46,9 +44,11 @@
#include "mongo/util/log.h"
namespace mongo {
-namespace {
- StringData _todb(const StringData& ns) {
+ static DatabaseHolder _dbHolder;
+
+namespace {
+ static 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,18 +62,12 @@ 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 6ad69c5bef2..dd3afdf2470 100644
--- a/src/mongo/db/catalog/database_holder.h
+++ b/src/mongo/db/catalog/database_holder.h
@@ -28,17 +28,13 @@
#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 2296fd58c9b..3703d555ff2 100644
--- a/src/mongo/db/client.h
+++ b/src/mongo/db/client.h
@@ -55,6 +55,7 @@ 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 31a5923ef3a..956f17a9c0b 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->getCurOp()->getOp());
+ if ( currentOp->shouldDBProfile( executionTime ) ) {
+ profile( txn, *txn->getClient(), currentOp->getOp(), *currentOp );
}
}
diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp
index 90d38d20e00..19958e19d21 100644
--- a/src/mongo/db/dbcommands.cpp
+++ b/src/mongo/db/dbcommands.cpp
@@ -341,16 +341,10 @@ namespace mongo {
}
- bool run(OperationContext* txn,
- const string& dbname,
- BSONObj& cmdObj,
- int options,
- string& errmsg,
- BSONObjBuilder& result,
- bool fromRepl) {
-
+ bool run(OperationContext* txn, const string& dbname, BSONObj& cmdObj, int, 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);
@@ -360,26 +354,21 @@ namespace mongo {
result.append("slowms", serverGlobalParams.slowMS);
int p = (int) e.number();
- Status status = Status::OK();
+ bool ok = false;
- if (p == -1)
- status = Status::OK();
+ if ( p == -1 )
+ ok = true;
else if ( p >= 0 && p <= 2 ) {
- status = ctx.db()->setProfilingLevel(txn, p);
+ ok = ctx.db()->setProfilingLevel( txn, p , errmsg );
}
- const BSONElement slow = cmdObj["slowms"];
+ BSONElement slow = cmdObj["slowms"];
if (slow.isNumber()) {
serverGlobalParams.slowMS = slow.numberInt();
}
- if (!status.isOK()) {
- errmsg = status.reason();
- }
-
- return status.isOK();
+ return ok;
}
-
} cmdProfile;
class CmdDiagLogging : public Command {
diff --git a/src/mongo/db/dbeval.cpp b/src/mongo/db/dbeval.cpp
index b873b64b760..72d7ebcd977 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,7 +153,6 @@ 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 ccc949ed6f0..aad9da30096 100644
--- a/src/mongo/db/instance.cpp
+++ b/src/mongo/db/instance.cpp
@@ -489,12 +489,17 @@ namespace {
}
if ( currentOp.shouldDBProfile( debug.executionTime ) ) {
- if (lockedForWriting()) {
+ // 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() ) {
MONGO_LOG_COMPONENT(1, logComponentForOp(op))
<< "note: not profiling because doing fsync+lock" << endl;
}
else {
- profile(txn, op);
+ profile(txn, c, op, currentOp);
}
}
diff --git a/src/mongo/db/introspect.cpp b/src/mongo/db/introspect.cpp
index 65a5bee8c86..6dd6c323a99 100644
--- a/src/mongo/db/introspect.cpp
+++ b/src/mongo/db/introspect.cpp
@@ -1,49 +1,53 @@
+// introspect.cpp
+
/**
- * 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.
- */
+* 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.
+*/
#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kDefault
-#include "mongo/platform/basic.h"
-
-#include "mongo/db/introspect.h"
+#include "mongo/pch.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 {
+namespace {
void _appendUserInfo(const CurOp& c,
BSONObjBuilder& builder,
AuthorizationSession* authSession) {
@@ -71,110 +75,141 @@ namespace {
builder.append("user", bestUser.getUser().empty() ? "" : bestUser.getFullName());
}
-
} // namespace
-
- void profile(OperationContext* txn, int op) {
- // initialize with 1kb to start, to avoid realloc later
- BufBuilder profileBufBuilder(1024);
-
+ /**
+ * @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
BSONObjBuilder b(profileBufBuilder);
- txn->getCurOp()->debug().append(*txn->getCurOp(), b);
+ currentOp.debug().append(currentOp, b);
b.appendDate("ts", jsTime());
- b.append("client", txn->getClient()->clientAddress());
+ b.append("client", c.clientAddress());
- AuthorizationSession * authSession = txn->getClient()->getAuthorizationSession();
- _appendUserInfo(*txn->getCurOp(), b, authSession);
+ AuthorizationSession * authSession = c.getAuthorizationSession();
+ _appendUserInfo(currentOp, b, authSession);
BSONObj p = b.done();
- const string dbName(nsToDatabase(txn->getCurOp()->getNS()));
-
- try {
- bool acquireDbXLock = false;
- while (true) {
- ScopedTransaction scopedXact(txn, MODE_IX);
-
- boost::scoped_ptr<AutoGetDb> autoGetDb;
- if (acquireDbXLock) {
- autoGetDb.reset(new AutoGetDb(txn, dbName, MODE_X));
- if (autoGetDb->getDb()) {
- createProfileCollection(txn, autoGetDb->getDb());
- }
- }
- else {
- 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);
+ WriteUnitOfWork wunit(txn);
- Collection* const coll = db->getCollection(txn, db->getProfilingNS());
- if (coll) {
- WriteUnitOfWork wuow(txn);
- coll->insertDocument(txn, p, false);
- wuow.commit();
+ // 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;
+ }
- break;
+ 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) );
}
- 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;
+ 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;
+ }
}
else {
- // Cannot write the profile information
- break;
+ mongo::log() << "note: not profiling because db went away - "
+ << "probably a close on: " << currentOp.getNS();
}
+ 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;
+ }
- Status createProfileCollection(OperationContext* txn, Database *db) {
- invariant(txn->lockState()->isDbLockedForMode(db->name(), MODE_X));
-
- const std::string dbProfilingNS(db->getProfilingNS());
+ // does not exist!
- Collection* const collection = db->getCollection(txn, dbProfilingNS);
- if (collection) {
- if (!collection->isCapped()) {
- return Status(ErrorCodes::NamespaceExists,
- str::stream() << dbProfilingNS << " exists but isn't capped");
+ 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);
}
+ return NULL;
+ }
- return Status::OK();
+ if ( !txn->lockState()->isDbLockedForMode( db->name(), MODE_X ) ) {
+ // can't create here
+ return NULL;
}
// system.profile namespace doesn't exist; create it
- log() << "Creating profile collection: " << dbProfilingNS << endl;
+ log() << "creating profile collection: " << profileName << endl;
CollectionOptions collectionOptions;
collectionOptions.capped = true;
collectionOptions.cappedSize = 1024 * 1024;
WriteUnitOfWork wunit(txn);
- invariant(db->createCollection(txn, dbProfilingNS, collectionOptions));
+ collection = db->createCollection( txn, profileName, collectionOptions );
+ invariant( collection );
wunit.commit();
- return Status::OK();
+ return collection;
}
} // namespace mongo
diff --git a/src/mongo/db/introspect.h b/src/mongo/db/introspect.h
index 2a6ec2a477f..07af4ba6653 100644
--- a/src/mongo/db/introspect.h
+++ b/src/mongo/db/introspect.h
@@ -1,48 +1,63 @@
+// introspect.h
+// system management stuff.
+
/**
- * 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.
- */
+* 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.
+*/
#pragma once
-#include "mongo/base/status.h"
+#include <string>
+
+#include "mongo/db/curop.h"
+#include "mongo/db/jsobj.h"
namespace mongo {
+ class Collection;
class Database;
class OperationContext;
- /**
- * Invoked when database profile is enabled.
- */
- void profile(OperationContext* txn, int op);
+ /* --- profiling --------------------------------------------
+ do when database->profile is set
+ */
+
+ void profile(OperationContext* txn, const Client& c, int op, CurOp& currentOp);
/**
- * Pre-creates the profile collection for the specified database.
- */
- Status createProfileCollection(OperationContext* txn, Database *db);
+ * 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);
} // namespace mongo
diff --git a/src/mongo/db/operation_context.h b/src/mongo/db/operation_context.h
index 036e2be83b9..59c190733f8 100644
--- a/src/mongo/db/operation_context.h
+++ b/src/mongo/db/operation_context.h
@@ -30,6 +30,7 @@
#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"
@@ -39,7 +40,6 @@ namespace mongo {
class Client;
class CurOp;
class ProgressMeter;
- class StringData;
/**
* This class encompasses the state required by an operation.