summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2014-06-05 14:44:39 -0400
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2014-06-10 13:57:23 -0400
commit936a568c59f7f0ee80f8b50fabe241e54e80e9ae (patch)
tree34bf705edf5c15dca1226ecca2467d6f79d75032
parent85461da82e7aca4285173ab7427cd468bd0f0fc2 (diff)
downloadmongo-936a568c59f7f0ee80f8b50fabe241e54e80e9ae.tar.gz
SERVER-13922 Remove dbtemprelease
-rw-r--r--src/mongo/db/db.h32
-rw-r--r--src/mongo/db/repl/oplog.cpp11
-rw-r--r--src/mongo/db/repl/rs_rollback.cpp34
3 files changed, 35 insertions, 42 deletions
diff --git a/src/mongo/db/db.h b/src/mongo/db/db.h
index 5e446bfcd4e..c9a3605c8df 100644
--- a/src/mongo/db/db.h
+++ b/src/mongo/db/db.h
@@ -38,38 +38,6 @@
namespace mongo {
- // todo: relocked is being called when there was no unlock below.
- // that is weird.
-
- /**
- * Releases the current lock for the duration of its lifetime.
- *
- * WARNING: do not put in a smart pointer or any other class. If you absolutely must, you need
- * to add the throw(DBException) annotation to it's destructor.
- */
- struct dbtemprelease {
- Client::Context * _context;
- scoped_ptr<Lock::TempRelease> tr;
- dbtemprelease(LockState* lockState) {
- const Client& c = cc();
- _context = c.getContext();
- invariant(lockState->threadState());
- if( Lock::nested() ) {
- massert(10298 , "can't temprelease nested lock", false);
- }
- if ( _context ) {
- _context->unlocked();
- }
- tr.reset(new Lock::TempRelease(lockState));
- verify( c.curop() );
- }
- ~dbtemprelease() throw(DBException) {
- tr.reset();
- if ( _context )
- _context->relocked();
- }
- };
-
extern void (*snmpInit)();
} // namespace mongo
diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp
index e1ed64a574d..3578b7acd0b 100644
--- a/src/mongo/db/repl/oplog.cpp
+++ b/src/mongo/db/repl/oplog.cpp
@@ -704,17 +704,24 @@ namespace repl {
while (!done) {
BufBuilder bb;
BSONObjBuilder ob;
+
+ // Applying commands in repl is done under Global W-lock, so it is safe to not
+ // perform the current DB checks after reacquiring the lock.
+ invariant(txn->lockState()->isW());
+
_runCommands(txn, ns, o, bb, ob, true, 0);
// _runCommands takes care of adjusting opcounters for command counting.
Status status = Command::getStatusFromCommandResult(ob.done());
switch (status.code()) {
case ErrorCodes::BackgroundOperationInProgressForDatabase: {
- dbtemprelease release(txn->lockState());
+ Lock::TempRelease release(txn->lockState());
+
BackgroundOperation::awaitNoBgOpInProgForDb(nsToDatabaseSubstring(ns));
break;
}
case ErrorCodes::BackgroundOperationInProgressForNamespace: {
- dbtemprelease release(txn->lockState());;
+ Lock::TempRelease release(txn->lockState());
+
Command* cmd = Command::findCommand(o.firstElement().fieldName());
invariant(cmd);
BackgroundOperation::awaitNoBgOpInProgForNs(cmd->parseNs(nsToDatabase(ns), o));
diff --git a/src/mongo/db/repl/rs_rollback.cpp b/src/mongo/db/repl/rs_rollback.cpp
index 5d8bc99cca5..34cfb5d9e9f 100644
--- a/src/mongo/db/repl/rs_rollback.cpp
+++ b/src/mongo/db/repl/rs_rollback.cpp
@@ -343,10 +343,10 @@ namespace repl {
}
}
- bool copyCollectionFromRemote(OperationContext* txn,
- const string& host,
- const string& ns,
- string& errmsg) {
+ static bool copyCollectionFromRemote(OperationContext* txn,
+ const string& host,
+ const string& ns,
+ string& errmsg) {
Cloner cloner;
DBClientConnection *tmpConn = new DBClientConnection();
@@ -437,11 +437,24 @@ namespace repl {
string ns = *it;
sethbmsg(str::stream() << "rollback 4.1 coll resync " << ns);
- Client::Context ctx(ns);
- ctx.db()->dropCollection(txn, ns);
+ const NamespaceString nss(ns);
+
+ bool unused;
+ Database* db = dbHolder().getOrCreate(
+ txn, nss.db().toString(), storageGlobalParams.dbpath, unused);
+ invariant(db);
+
+ db->dropCollection(txn, ns);
{
string errmsg;
- dbtemprelease release(txn->lockState());
+
+ // This comes as a GlobalWrite lock, so there is no DB to be acquired after
+ // resume, so we can skip the DB stability checks. Also
+ // copyCollectionFromRemote will acquire its own database pointer, under the
+ // appropriate locks, so just releasing and acquiring the lock is safe.
+ invariant(txn->lockState()->isW());
+ Lock::TempRelease release(txn->lockState());
+
bool ok = copyCollectionFromRemote(txn, them->getServerAddress(), ns, errmsg);
uassert(15909, str::stream() << "replSet rollback error resyncing collection "
<< ns << ' ' << errmsg, ok);
@@ -734,7 +747,12 @@ namespace repl {
}
catch (DBException& e) {
sethbmsg(string("rollback 2 exception ") + e.toString() + "; sleeping 1 min");
- dbtemprelease release(txn->lockState());
+
+ // Release the GlobalWrite lock while sleeping. We should always come here with a
+ // GlobalWrite lock
+ invariant(txn->lockState()->isW());
+ Lock::TempRelease(txn->lockState());
+
sleepsecs(60);
throw;
}