diff options
author | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2014-06-05 14:44:39 -0400 |
---|---|---|
committer | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2014-06-10 13:57:23 -0400 |
commit | 936a568c59f7f0ee80f8b50fabe241e54e80e9ae (patch) | |
tree | 34bf705edf5c15dca1226ecca2467d6f79d75032 | |
parent | 85461da82e7aca4285173ab7427cd468bd0f0fc2 (diff) | |
download | mongo-936a568c59f7f0ee80f8b50fabe241e54e80e9ae.tar.gz |
SERVER-13922 Remove dbtemprelease
-rw-r--r-- | src/mongo/db/db.h | 32 | ||||
-rw-r--r-- | src/mongo/db/repl/oplog.cpp | 11 | ||||
-rw-r--r-- | src/mongo/db/repl/rs_rollback.cpp | 34 |
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; } |