summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/db/auth/auth_index_d.cpp1
-rw-r--r--src/mongo/db/catalog/database.cpp2
-rw-r--r--src/mongo/db/client.cpp9
-rw-r--r--src/mongo/db/client.h5
-rw-r--r--src/mongo/db/cloner.cpp6
-rw-r--r--src/mongo/db/commands/apply_ops.cpp8
-rw-r--r--src/mongo/db/commands/clone.cpp3
-rw-r--r--src/mongo/db/commands/collection_to_capped.cpp15
-rw-r--r--src/mongo/db/commands/compact.cpp3
-rw-r--r--src/mongo/db/commands/copydb.cpp8
-rw-r--r--src/mongo/db/commands/cpuprofile.cpp3
-rw-r--r--src/mongo/db/commands/create_indexes.cpp1
-rw-r--r--src/mongo/db/commands/drop_indexes.cpp12
-rw-r--r--src/mongo/db/commands/find_and_modify.cpp7
-rw-r--r--src/mongo/db/commands/fsync.cpp3
-rw-r--r--src/mongo/db/commands/mr.cpp11
-rw-r--r--src/mongo/db/commands/rename_collection.cpp11
-rw-r--r--src/mongo/db/commands/test_commands.cpp7
-rw-r--r--src/mongo/db/commands/write_commands/batch_executor.cpp12
-rw-r--r--src/mongo/db/db.cpp3
-rw-r--r--src/mongo/db/dbcommands.cpp41
-rw-r--r--src/mongo/db/dbeval.cpp3
-rw-r--r--src/mongo/db/dbhelpers.cpp1
-rw-r--r--src/mongo/db/index_builder.cpp1
-rw-r--r--src/mongo/db/index_rebuilder.cpp1
-rw-r--r--src/mongo/db/instance.cpp6
-rw-r--r--src/mongo/db/introspect.cpp3
-rw-r--r--src/mongo/db/repl/master_slave.cpp1
-rw-r--r--src/mongo/db/repl/oplog.cpp10
-rw-r--r--src/mongo/db/repl/repl_set_impl.cpp6
-rw-r--r--src/mongo/db/repl/resync.cpp2
-rw-r--r--src/mongo/db/repl/rs_config.cpp1
-rw-r--r--src/mongo/db/repl/rs_initialsync.cpp4
-rw-r--r--src/mongo/db/repl/sync.cpp2
-rw-r--r--src/mongo/db/repl/sync_source_feedback.cpp1
-rw-r--r--src/mongo/db/repl/sync_tail.cpp4
-rw-r--r--src/mongo/db/ttl.cpp1
-rw-r--r--src/mongo/dbtests/basictests.cpp2
-rw-r--r--src/mongo/dbtests/clienttests.cpp1
-rw-r--r--src/mongo/dbtests/counttests.cpp4
-rw-r--r--src/mongo/dbtests/dbhelper_tests.cpp2
-rw-r--r--src/mongo/dbtests/indexcatalogtests.cpp3
-rw-r--r--src/mongo/dbtests/indexupdatetests.cpp3
-rw-r--r--src/mongo/dbtests/oplogstarttests.cpp3
-rw-r--r--src/mongo/dbtests/pdfiletests.cpp5
-rw-r--r--src/mongo/dbtests/plan_ranking.cpp3
-rw-r--r--src/mongo/dbtests/query_multi_plan_runner.cpp1
-rw-r--r--src/mongo/dbtests/query_single_solution_runner.cpp7
-rw-r--r--src/mongo/dbtests/query_stage_and.cpp16
-rw-r--r--src/mongo/dbtests/query_stage_collscan.cpp6
-rw-r--r--src/mongo/dbtests/query_stage_count.cpp14
-rw-r--r--src/mongo/dbtests/query_stage_distinct.cpp3
-rw-r--r--src/mongo/dbtests/query_stage_fetch.cpp2
-rw-r--r--src/mongo/dbtests/query_stage_keep.cpp1
-rw-r--r--src/mongo/dbtests/query_stage_merge_sort.cpp8
-rw-r--r--src/mongo/dbtests/query_stage_sort.cpp5
-rw-r--r--src/mongo/dbtests/query_stage_tests.cpp4
-rw-r--r--src/mongo/dbtests/querytests.cpp26
-rw-r--r--src/mongo/dbtests/replsettests.cpp18
-rw-r--r--src/mongo/dbtests/repltests.cpp17
-rw-r--r--src/mongo/dbtests/runner_registry.cpp10
-rw-r--r--src/mongo/dbtests/threadedtests.cpp1
-rw-r--r--src/mongo/s/d_migrate.cpp5
-rw-r--r--src/mongo/tools/dump.cpp1
64 files changed, 352 insertions, 37 deletions
diff --git a/src/mongo/db/auth/auth_index_d.cpp b/src/mongo/db/auth/auth_index_d.cpp
index 07f692149fe..694530f535b 100644
--- a/src/mongo/db/auth/auth_index_d.cpp
+++ b/src/mongo/db/auth/auth_index_d.cpp
@@ -95,6 +95,7 @@ namespace {
while ((oldIndex = indexCatalog->findIndexByKeyPattern(v1SystemUsersKeyPattern))) {
indexCatalog->dropIndex(txn, oldIndex);
}
+ wctx.commit();
}
}
diff --git a/src/mongo/db/catalog/database.cpp b/src/mongo/db/catalog/database.cpp
index 8c6dd84cf67..d1fbc8c8bd9 100644
--- a/src/mongo/db/catalog/database.cpp
+++ b/src/mongo/db/catalog/database.cpp
@@ -503,8 +503,10 @@ namespace mongo {
log() << "dropAllDatabasesExceptLocal " << n.size() << endl;
for( vector<string>::iterator i = n.begin(); i != n.end(); i++ ) {
if( *i != "local" ) {
+ WriteUnitOfWork wunit(txn->recoveryUnit());
Client::Context ctx(txn, *i);
dropDatabase(txn, ctx.db());
+ wunit.commit();
}
}
}
diff --git a/src/mongo/db/client.cpp b/src/mongo/db/client.cpp
index 6cfefce96a6..8bfe80850a7 100644
--- a/src/mongo/db/client.cpp
+++ b/src/mongo/db/client.cpp
@@ -205,14 +205,18 @@ namespace mongo {
DEV log() << "_DEBUG ReadContext db wasn't open, will try to open " << ns << endl;
if (txn->lockState()->isW()) {
// write locked already
+ WriteUnitOfWork wunit(txn->recoveryUnit());
DEV RARELY log() << "write locked on ReadContext construction " << ns << endl;
_c.reset(new Context(txn, ns, doVersion));
+ wunit.commit();
}
else if (!txn->lockState()->isRecursive()) {
_lk.reset(0);
{
Lock::GlobalWrite w(txn->lockState());
+ WriteUnitOfWork wunit(txn->recoveryUnit());
Context c(txn, ns, doVersion);
+ wunit.commit();
}
// db could be closed at this interim point -- that is ok, we will throw, and don't mind throwing.
@@ -232,10 +236,13 @@ namespace mongo {
Client::WriteContext::WriteContext(
OperationContext* opCtx, const std::string& ns, bool doVersion)
: _lk(opCtx->lockState(), ns),
+ _wunit(opCtx->recoveryUnit()),
_c(opCtx, ns, doVersion) {
-
}
+ void Client::WriteContext::commit() {
+ _wunit.commit();
+ }
void Client::Context::checkNotStale() const {
switch ( _client->_curOp->getOp() ) {
diff --git a/src/mongo/db/client.h b/src/mongo/db/client.h
index cf5c9f38964..570807c6ccb 100644
--- a/src/mongo/db/client.h
+++ b/src/mongo/db/client.h
@@ -207,10 +207,15 @@ namespace mongo {
class WriteContext : boost::noncopyable {
public:
WriteContext(OperationContext* opCtx, const std::string& ns, bool doVersion = true);
+
+ /** Commit any writes done so far in this context. */
+ void commit();
+
Context& ctx() { return _c; }
private:
Lock::DBWrite _lk;
+ WriteUnitOfWork _wunit;
Context _c;
};
diff --git a/src/mongo/db/cloner.cpp b/src/mongo/db/cloner.cpp
index 6888c82eb46..368c986d908 100644
--- a/src/mongo/db/cloner.cpp
+++ b/src/mongo/db/cloner.cpp
@@ -119,9 +119,11 @@ namespace mongo {
<< "collection dropped during clone ["
<< to_collection << "]",
!createdCollection );
+ WriteUnitOfWork wunit(txn->recoveryUnit());
createdCollection = true;
collection = db->createCollection( txn, to_collection );
verify( collection );
+ wunit.commit();
}
}
@@ -147,6 +149,7 @@ namespace mongo {
}
++numSeen;
+ WriteUnitOfWork wunit(txn->recoveryUnit());
BSONObj js = tmp;
if ( isindex ) {
@@ -167,6 +170,7 @@ namespace mongo {
if (logForRepl)
repl::logOp(txn, "i", to_collection, js);
+ wunit.commit();
txn->recoveryUnit()->commitIfNeeded();
RARELY if ( time( 0 ) - saveLast > 60 ) {
@@ -300,6 +304,7 @@ namespace mongo {
const NamespaceString nss(ns);
Lock::DBWrite dbWrite(txn->lockState(), nss.db());
+ WriteUnitOfWork wunit(txn->recoveryUnit());
const string dbName = nss.db().toString();
@@ -332,6 +337,7 @@ namespace mongo {
copy(txn, dbName, temp.c_str(), temp.c_str(), true, logForRepl, false, true, mayYield,
mayBeInterrupted, BSON( "ns" << ns ));
+ wunit.commit();
txn->recoveryUnit()->commitIfNeeded();
return true;
}
diff --git a/src/mongo/db/commands/apply_ops.cpp b/src/mongo/db/commands/apply_ops.cpp
index b3fa1b6ce2e..bd69352c350 100644
--- a/src/mongo/db/commands/apply_ops.cpp
+++ b/src/mongo/db/commands/apply_ops.cpp
@@ -84,6 +84,7 @@ namespace mongo {
// SERVER-4328 todo : is global ok or does this take a long time? i believe multiple
// ns used so locking individually requires more analysis
Lock::GlobalWrite globalWriteLock(txn->lockState());
+ WriteUnitOfWork wunit(txn->recoveryUnit());
DBDirectClient db(txn);
@@ -172,7 +173,12 @@ namespace mongo {
repl::logOp(txn, "c", tempNS.c_str(), cmdBuilder.done());
}
- return errors == 0;
+ if (errors != 0) {
+ return false;
+ }
+
+ wunit.commit();
+ return true;
}
} applyOpsCmd;
diff --git a/src/mongo/db/commands/clone.cpp b/src/mongo/db/commands/clone.cpp
index 29a0dbd0dd5..cefe28ba570 100644
--- a/src/mongo/db/commands/clone.cpp
+++ b/src/mongo/db/commands/clone.cpp
@@ -117,6 +117,8 @@ namespace mongo {
set<string> clonedColls;
Lock::DBWrite dbXLock(txn->lockState(), dbname);
+ // SERVER-14085: This unit of work should go away and be put in the individual ops
+ WriteUnitOfWork wunit(txn->recoveryUnit());
Cloner cloner;
bool rval = cloner.go(txn, dbname, from, opts, &clonedColls, errmsg);
@@ -125,6 +127,7 @@ namespace mongo {
barr.append( clonedColls );
result.append( "clonedColls", barr.arr() );
+ wunit.commit();
return rval;
diff --git a/src/mongo/db/commands/collection_to_capped.cpp b/src/mongo/db/commands/collection_to_capped.cpp
index 476d80edf08..3a26bbdc852 100644
--- a/src/mongo/db/commands/collection_to_capped.cpp
+++ b/src/mongo/db/commands/collection_to_capped.cpp
@@ -153,9 +153,13 @@ namespace mongo {
}
Lock::DBWrite dbXLock(txn->lockState(), dbname);
+ WriteUnitOfWork wunit(txn->recoveryUnit());
Client::Context ctx(txn, dbname);
Status status = cloneCollectionAsCapped( txn, ctx.db(), from, to, size, temp, true );
+ if (status.isOK()) {
+ wunit.commit();
+ }
return appendCommandStatus( result, status );
}
} cmdCloneCollectionAsCapped;
@@ -196,10 +200,17 @@ namespace mongo {
return std::vector<BSONObj>();
}
- bool run(OperationContext* txn, const string& dbname, BSONObj& jsobj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl ) {
+ bool run(OperationContext* txn,
+ const string& dbname,
+ BSONObj& jsobj,
+ int,
+ string& errmsg,
+ BSONObjBuilder& result,
+ bool fromRepl ) {
// calls renamecollection which does a global lock, so we must too:
//
Lock::GlobalWrite globalWriteLock(txn->lockState());
+ WriteUnitOfWork wunit(txn->recoveryUnit());
Client::Context ctx(txn, dbname);
Database* db = ctx.db();
@@ -242,6 +253,8 @@ namespace mongo {
if (!fromRepl)
repl::logOp(txn, "c",(dbname + ".$cmd").c_str(), jsobj);
+
+ wunit.commit();
return true;
}
} cmdConvertToCapped;
diff --git a/src/mongo/db/commands/compact.cpp b/src/mongo/db/commands/compact.cpp
index c0df090d29a..0400321d239 100644
--- a/src/mongo/db/commands/compact.cpp
+++ b/src/mongo/db/commands/compact.cpp
@@ -141,6 +141,8 @@ namespace mongo {
Lock::DBWrite lk(txn->lockState(), ns.ns());
+ // SERVER-14085: The following will have to go as we push down WOUW
+ WriteUnitOfWork wunit(txn->recoveryUnit());
BackgroundOperation::assertNoBgOpInProgForNs(ns.ns());
Client::Context ctx(txn, ns);
@@ -169,6 +171,7 @@ namespace mongo {
log() << "compact " << ns << " end";
IndexBuilder::restoreIndexes(indexesInProg);
+ wunit.commit();
return true;
}
diff --git a/src/mongo/db/commands/copydb.cpp b/src/mongo/db/commands/copydb.cpp
index 6582c1172eb..597cbf62d93 100644
--- a/src/mongo/db/commands/copydb.cpp
+++ b/src/mongo/db/commands/copydb.cpp
@@ -188,8 +188,12 @@ namespace mongo {
scoped_ptr<Lock::ScopedLock> lk( fromSelf ?
static_cast<Lock::ScopedLock*>(new Lock::GlobalWrite(txn->lockState())) :
static_cast<Lock::ScopedLock*>(new Lock::DBWrite(txn->lockState(), todb)));
-
- return cloner.go(txn, todb, fromhost, cloneOptions, NULL, errmsg );
+ WriteUnitOfWork wunit(txn->recoveryUnit());
+ if (!cloner.go(txn, todb, fromhost, cloneOptions, NULL, errmsg )) {
+ return false;
+ }
+ wunit.commit();
+ return true;
}
} cmdCopyDB;
diff --git a/src/mongo/db/commands/cpuprofile.cpp b/src/mongo/db/commands/cpuprofile.cpp
index de614b8a553..f2d79da97a7 100644
--- a/src/mongo/db/commands/cpuprofile.cpp
+++ b/src/mongo/db/commands/cpuprofile.cpp
@@ -136,6 +136,7 @@ namespace mongo {
BSONObjBuilder &result,
bool fromRepl ) {
Lock::DBWrite dbXLock(db);
+ // The lock here is just to prevent concurrency, nothing will write.
Client::Context ctx(txn, db);
std::string profileFilename = cmdObj[commandName]["profileFilename"].String();
@@ -154,9 +155,11 @@ namespace mongo {
BSONObjBuilder &result,
bool fromRepl ) {
Lock::DBWrite dbXLock(db);
+ WriteUnitOfWork wunit(txn->recoveryUnit());
Client::Context ctx(txn, db);
::ProfilerStop();
+ wunit.commit();
return true;
}
diff --git a/src/mongo/db/commands/create_indexes.cpp b/src/mongo/db/commands/create_indexes.cpp
index 502f3e94f79..53db0748a77 100644
--- a/src/mongo/db/commands/create_indexes.cpp
+++ b/src/mongo/db/commands/create_indexes.cpp
@@ -206,6 +206,7 @@ namespace mongo {
result.append( "numIndexesAfter", collection->getIndexCatalog()->numIndexesTotal() );
+ writeContext.commit();
return true;
}
diff --git a/src/mongo/db/commands/drop_indexes.cpp b/src/mongo/db/commands/drop_indexes.cpp
index d5491d166e7..b44708d5c6b 100644
--- a/src/mongo/db/commands/drop_indexes.cpp
+++ b/src/mongo/db/commands/drop_indexes.cpp
@@ -94,11 +94,17 @@ namespace mongo {
CmdDropIndexes() : Command("dropIndexes", false, "deleteIndexes") { }
bool run(OperationContext* txn, const string& dbname, BSONObj& jsobj, int, string& errmsg, BSONObjBuilder& anObjBuilder, bool fromRepl) {
Lock::DBWrite dbXLock(txn->lockState(), dbname);
+ WriteUnitOfWork wunit(txn->recoveryUnit());
bool ok = wrappedRun(txn, dbname, jsobj, errmsg, anObjBuilder);
- if (ok && !fromRepl)
+ if (!ok) {
+ return false;
+ }
+ if (!fromRepl)
repl::logOp(txn, "c",(dbname + ".$cmd").c_str(), jsobj);
- return ok;
+ wunit.commit();
+ return true;
}
+
bool wrappedRun(OperationContext* txn,
const string& dbname,
BSONObj& jsobj,
@@ -222,6 +228,7 @@ namespace mongo {
LOG(0) << "CMD: reIndex " << toDeleteNs << endl;
Lock::DBWrite dbXLock(txn->lockState(), dbname);
+ WriteUnitOfWork wunit(txn->recoveryUnit());
Client::Context ctx(txn, toDeleteNs);
Collection* collection = ctx.db()->getCollection( txn, toDeleteNs );
@@ -272,6 +279,7 @@ namespace mongo {
result.appendArray( "indexes" , b.obj() );
IndexBuilder::restoreIndexes(indexesInProg);
+ wunit.commit();
return true;
}
} cmdReIndex;
diff --git a/src/mongo/db/commands/find_and_modify.cpp b/src/mongo/db/commands/find_and_modify.cpp
index 3981705ed00..6de75da79f5 100644
--- a/src/mongo/db/commands/find_and_modify.cpp
+++ b/src/mongo/db/commands/find_and_modify.cpp
@@ -134,7 +134,9 @@ namespace mongo {
string& errmsg) {
Lock::DBWrite lk(txn->lockState(), ns);
+ WriteUnitOfWork wunit(txn->recoveryUnit());
Client::Context cx(txn, ns);
+
Collection* collection = cx.db()->getCollection( txn, ns );
const WhereCallbackReal whereCallback = WhereCallbackReal(StringData(ns));
@@ -297,7 +299,7 @@ namespace mongo {
}
}
-
+ wunit.commit();
return true;
}
@@ -330,6 +332,7 @@ namespace mongo {
}
Lock::DBWrite dbXLock(txn->lockState(), dbname);
+ WriteUnitOfWork wunit(txn->recoveryUnit());
Client::Context ctx(txn, ns);
BSONObj out = db.findOne(ns, q, fields);
@@ -423,9 +426,9 @@ namespace mongo {
result.append("value", out);
+ wunit.commit();
return true;
}
} cmdFindAndModify;
-
}
diff --git a/src/mongo/db/commands/fsync.cpp b/src/mongo/db/commands/fsync.cpp
index 2f40aac1fe2..9b7b16e4e7e 100644
--- a/src/mongo/db/commands/fsync.cpp
+++ b/src/mongo/db/commands/fsync.cpp
@@ -135,6 +135,7 @@ namespace mongo {
// can this be GlobalRead? and if it can, it should be nongreedy.
Lock::GlobalWrite w(txn->lockState());
getDur().commitNow(txn);
+ // No WriteUnitOfWork needed, as this does no writes of its own.
}
result.append( "numFiles" , globalStorageEngine->flushAllFiles( sync ) );
}
@@ -148,7 +149,7 @@ namespace mongo {
SimpleMutex::scoped_lock lkf(filesLockedFsync);
OperationContextImpl txn; // XXX?
- Lock::GlobalWrite global(txn.lockState());
+ Lock::GlobalWrite global(txn.lockState()); // No WriteUnitOfWork needed
SimpleMutex::scoped_lock lk(fsyncCmd.m);
diff --git a/src/mongo/db/commands/mr.cpp b/src/mongo/db/commands/mr.cpp
index b359a6fa3e4..776b86c3819 100644
--- a/src/mongo/db/commands/mr.cpp
+++ b/src/mongo/db/commands/mr.cpp
@@ -389,6 +389,7 @@ namespace mongo {
indexesToInsert.push_back( b.obj() );
}
}
+ finalCtx.commit();
}
{
@@ -415,6 +416,7 @@ namespace mongo {
string logNs = nsToDatabase( _config.tempNamespace ) + ".system.indexes";
repl::logOp(_txn, "i", logNs.c_str(), *it);
}
+ tempCtx.commit();
}
}
@@ -565,9 +567,11 @@ namespace mongo {
auto_ptr<DBClientCursor> cursor = _db.query( _config.tempNamespace , BSONObj() );
while ( cursor->more() ) {
Lock::DBWrite lock(_txn->lockState(), _config.outputOptions.finalNamespace);
+ WriteUnitOfWork wunit(_txn->recoveryUnit());
BSONObj o = cursor->nextSafe();
Helpers::upsert( _txn, _config.outputOptions.finalNamespace , o );
_txn->recoveryUnit()->commitIfNeeded();
+ wunit.commit();
pm.hit();
}
_db.dropCollection( _config.tempNamespace );
@@ -583,6 +587,7 @@ namespace mongo {
auto_ptr<DBClientCursor> cursor = _db.query( _config.tempNamespace , BSONObj() );
while ( cursor->more() ) {
Lock::GlobalWrite lock(txn->lockState()); // TODO(erh) why global?
+ WriteUnitOfWork wunit(txn->recoveryUnit());
BSONObj temp = cursor->nextSafe();
BSONObj old;
@@ -611,6 +616,7 @@ namespace mongo {
else {
Helpers::upsert( _txn, _config.outputOptions.finalNamespace , temp );
}
+ wunit.commit();
_txn->recoveryUnit()->commitIfNeeded();
pm.hit();
}
@@ -644,6 +650,7 @@ namespace mongo {
coll->insertDocument( _txn, bo, true );
repl::logOp(_txn, "i", ns.c_str(), bo);
+ ctx.commit();
}
/**
@@ -660,6 +667,7 @@ namespace mongo {
" collection expected: " << _config.incLong );
coll->insertDocument( _txn, o, true );
+ ctx.commit();
_txn->recoveryUnit()->commitIfNeeded();
}
@@ -944,6 +952,7 @@ namespace mongo {
break;
}
}
+ incCtx.commit();
verify( foundIndex );
}
@@ -1069,6 +1078,7 @@ namespace mongo {
return;
Lock::DBWrite kl(_txn->lockState(), _config.incLong);
+ WriteUnitOfWork wunit(_txn->recoveryUnit());
for ( InMemory::iterator i=_temp->begin(); i!=_temp->end(); i++ ) {
BSONList& all = i->second;
@@ -1080,6 +1090,7 @@ namespace mongo {
}
_temp->clear();
_size = 0;
+ wunit.commit();
}
diff --git a/src/mongo/db/commands/rename_collection.cpp b/src/mongo/db/commands/rename_collection.cpp
index a25b2e19a09..a878e8222f1 100644
--- a/src/mongo/db/commands/rename_collection.cpp
+++ b/src/mongo/db/commands/rename_collection.cpp
@@ -94,10 +94,15 @@ namespace mongo {
virtual bool run(OperationContext* txn, const string& dbname, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
Lock::GlobalWrite globalWriteLock(txn->lockState());
- bool ok = wrappedRun(txn, dbname, cmdObj, errmsg, result, fromRepl);
- if (ok && !fromRepl)
+ WriteUnitOfWork wunit(txn->recoveryUnit());
+ if (!wrappedRun(txn, dbname, cmdObj, errmsg, result, fromRepl)) {
+ return false;
+ }
+ if (!fromRepl) {
repl::logOp(txn, "c",(dbname + ".$cmd").c_str(), cmdObj);
- return ok;
+ }
+ wunit.commit();
+ return true;
}
virtual bool wrappedRun(OperationContext* txn,
const string& dbname,
diff --git a/src/mongo/db/commands/test_commands.cpp b/src/mongo/db/commands/test_commands.cpp
index 20175588afc..60164663ff7 100644
--- a/src/mongo/db/commands/test_commands.cpp
+++ b/src/mongo/db/commands/test_commands.cpp
@@ -62,6 +62,7 @@ namespace mongo {
BSONObj obj = cmdObj[ "obj" ].embeddedObjectUserCheck();
Lock::DBWrite lk(txn->lockState(), ns);
+ WriteUnitOfWork wunit(txn->recoveryUnit());
Client::Context ctx(txn, ns );
Database* db = ctx.db();
Collection* collection = db->getCollection( txn, ns );
@@ -73,6 +74,10 @@ namespace mongo {
}
}
StatusWith<DiskLoc> res = collection->insertDocument( txn, obj, false );
+ Status status = res.getStatus();
+ if (status.isOK()) {
+ wunit.commit();
+ }
return appendCommandStatus( result, res.getStatus() );
}
};
@@ -153,6 +158,7 @@ namespace mongo {
massert( 13418, "captrunc invalid n", Runner::RUNNER_ADVANCED == state);
}
collection->temp_cappedTruncateAfter( txn, end, inc );
+ ctx.commit();
return true;
}
};
@@ -200,6 +206,7 @@ namespace mongo {
if (!fromRepl)
repl::logOp(txn, "c",(dbname + ".$cmd").c_str(), cmdObj);
+ ctx.commit();
return true;
}
};
diff --git a/src/mongo/db/commands/write_commands/batch_executor.cpp b/src/mongo/db/commands/write_commands/batch_executor.cpp
index 39b5e7c0014..a35603e7db8 100644
--- a/src/mongo/db/commands/write_commands/batch_executor.cpp
+++ b/src/mongo/db/commands/write_commands/batch_executor.cpp
@@ -850,12 +850,14 @@ namespace mongo {
incOpStats( updateItem );
WriteOpResult result;
+
+ WriteUnitOfWork wunit(_txn->recoveryUnit());
multiUpdate( _txn, updateItem, &result );
+ wunit.commit();
if ( !result.getStats().upsertedID.isEmpty() ) {
*upsertedId = result.getStats().upsertedID;
}
-
// END CURRENT OP
incWriteStats( updateItem, result.getStats(), result.getError(), currentOp.get() );
finishCurrentOp( _txn, _client, currentOp.get(), result.getError() );
@@ -925,6 +927,7 @@ namespace mongo {
dassert(database);
_collection = database->getCollection(txn, request->getTargetingNS());
if (!_collection) {
+ WriteUnitOfWork wunit (txn->recoveryUnit());
// Implicitly create if it doesn't exist
_collection = database->createCollection(txn, request->getTargetingNS());
if (!_collection) {
@@ -934,6 +937,7 @@ namespace mongo {
request->getTargetingNS())));
return false;
}
+ wunit.commit();
}
return true;
}
@@ -966,12 +970,14 @@ namespace mongo {
try {
if (state->lockAndCheck(result)) {
+ WriteUnitOfWork wunit (state->txn->recoveryUnit());
if (!state->request->isInsertIndexRequest()) {
singleInsert(state->txn, insertDoc, state->getCollection(), result);
}
else {
singleCreateIndex(state->txn, insertDoc, state->getCollection(), result);
}
+ wunit.commit();
}
}
catch (const DBException& ex) {
@@ -1096,6 +1102,7 @@ namespace mongo {
Lock::DBWrite writeLock(txn->lockState(), nsString.ns(), useExperimentalDocLocking);
///////////////////////////////////////////
+ WriteUnitOfWork wunit(txn->recoveryUnit());
if (!checkShardVersion(txn, &shardingState, *updateItem.getRequest(), result))
return;
@@ -1122,6 +1129,7 @@ namespace mongo {
}
result->setError(toWriteError(status));
}
+ wunit.commit();
}
/**
@@ -1150,6 +1158,7 @@ namespace mongo {
///////////////////////////////////////////
Lock::DBWrite writeLock(txn->lockState(), nss.ns());
///////////////////////////////////////////
+ WriteUnitOfWork wunit(txn->recoveryUnit());
// Check version once we're locked
@@ -1172,6 +1181,7 @@ namespace mongo {
}
result->setError(toWriteError(status));
}
+ wunit.commit();
}
} // namespace mongo
diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp
index 75242557c32..becde7a04b5 100644
--- a/src/mongo/db/db.cpp
+++ b/src/mongo/db/db.cpp
@@ -255,6 +255,7 @@ namespace mongo {
OperationContextImpl txn;
Lock::GlobalWrite lk(txn.lockState());
+ // No WriteUnitOfWork, as DirectClient creates its own units of work
DBDirectClient c(&txn);
static const char* name = "local.startup_log";
@@ -327,6 +328,7 @@ namespace mongo {
OperationContextImpl txn;
Lock::GlobalWrite lk(txn.lockState());
+ WriteUnitOfWork wunit(txn.recoveryUnit());
vector< string > dbNames;
globalStorageEngine->listDatabases( &dbNames );
@@ -396,6 +398,7 @@ namespace mongo {
Database::closeDatabase(&txn, dbName.c_str());
}
}
+ wunit.commit();
LOG(1) << "done repairDatabases" << endl;
}
diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp
index aaaec51e0a7..6a8484e68e2 100644
--- a/src/mongo/db/dbcommands.cpp
+++ b/src/mongo/db/dbcommands.cpp
@@ -182,6 +182,7 @@ namespace mongo {
// and that may need a global lock.
Lock::GlobalWrite lk(txn->lockState());
Client::Context context(txn, dbname);
+ WriteUnitOfWork wunit(txn->recoveryUnit());
log() << "dropDatabase " << dbname << " starting" << endl;
@@ -192,6 +193,8 @@ namespace mongo {
if (!fromRepl)
repl::logOp(txn, "c",(dbname + ".$cmd").c_str(), cmdObj);
+
+ wunit.commit();
}
result.append( "dropped" , dbname );
@@ -331,6 +334,7 @@ namespace mongo {
// in the local database.
//
Lock::DBWrite dbXLock(txn->lockState(), dbname);
+ WriteUnitOfWork wunit(txn->recoveryUnit());
Client::Context ctx(txn, dbname);
BSONElement e = cmdObj.firstElement();
@@ -350,6 +354,7 @@ namespace mongo {
if ( slow.isNumber() )
serverGlobalParams.slowMS = slow.numberInt();
+ wunit.commit();
return ok;
}
} cmdProfile;
@@ -436,6 +441,7 @@ namespace mongo {
}
Lock::DBWrite dbXLock(txn->lockState(), dbname);
+ WriteUnitOfWork wunit(txn->recoveryUnit());
Client::Context ctx(txn, nsToDrop);
Database* db = ctx.db();
@@ -455,15 +461,16 @@ namespace mongo {
Status s = db->dropCollection( txn, nsToDrop );
- if ( s.isOK() ) {
- if (!fromRepl)
- repl::logOp(txn, "c",(dbname + ".$cmd").c_str(), cmdObj);
- return true;
+ if ( !s.isOK() ) {
+ return appendCommandStatus( result, s );
}
- appendCommandStatus( result, s );
+ if ( !fromRepl ) {
+ repl::logOp(txn, "c",(dbname + ".$cmd").c_str(), cmdObj);
+ }
+ wunit.commit();
+ return true;
- return false;
}
} cmdDrop;
@@ -534,11 +541,17 @@ namespace mongo {
options.hasField("$nExtents"));
Lock::DBWrite dbXLock(txn->lockState(), dbname);
+ WriteUnitOfWork wunit(txn->recoveryUnit());
Client::Context ctx(txn, ns);
// Create collection.
- return appendCommandStatus( result,
- userCreateNS(txn, ctx.db(), ns.c_str(), options, !fromRepl) );
+ status = userCreateNS(txn, ctx.db(), ns.c_str(), options, !fromRepl);
+ if ( !status.isOK() ) {
+ return appendCommandStatus( result, status );
+ }
+
+ wunit.commit();
+ return true;
}
} cmdCreate;
@@ -570,6 +583,7 @@ namespace mongo {
bool run(OperationContext* txn, const string& dbname , BSONObj& jsobj, int, string& errmsg, BSONObjBuilder& result, bool /*fromRepl*/) {
Lock::GlobalWrite globalWriteLock(txn->lockState());
+ // No WriteUnitOfWork necessary, as no actual writes happen.
Client::Context ctx(txn, dbname);
try {
@@ -954,6 +968,7 @@ namespace mongo {
const string ns = dbname + "." + jsobj.firstElement().valuestr();
Lock::DBWrite dbXLock(txn->lockState(), dbname);
+ WriteUnitOfWork wunit(txn->recoveryUnit());
Client::Context ctx(txn, ns );
Collection* coll = ctx.db()->getCollection( txn, ns );
@@ -1035,11 +1050,17 @@ namespace mongo {
}
}
}
+
+ if (!ok) {
+ return false;
+ }
- if (ok && !fromRepl)
+ if (!fromRepl) {
repl::logOp(txn, "c",(dbname + ".$cmd").c_str(), jsobj);
+ }
- return ok;
+ wunit.commit();
+ return true;
}
} collectionModCommand;
diff --git a/src/mongo/db/dbeval.cpp b/src/mongo/db/dbeval.cpp
index e5bd01890e7..41069802f1d 100644
--- a/src/mongo/db/dbeval.cpp
+++ b/src/mongo/db/dbeval.cpp
@@ -1,4 +1,4 @@
-// commands.cpp
+// dbeval.cpp
/**
* Copyright (C) 2012 10gen Inc.
@@ -143,6 +143,7 @@ namespace mongo {
}
Lock::GlobalWrite lk(txn->lockState());
+ // No WriteUnitOfWork necessary, as dbEval will create its own, see "nolock" case above
Client::Context ctx(txn, dbname );
return dbEval(dbname, cmdObj, result, errmsg);
diff --git a/src/mongo/db/dbhelpers.cpp b/src/mongo/db/dbhelpers.cpp
index 0de77233f93..a587d1084a4 100644
--- a/src/mongo/db/dbhelpers.cpp
+++ b/src/mongo/db/dbhelpers.cpp
@@ -423,6 +423,7 @@ namespace mongo {
collection->deleteDocument( txn, rloc, false, false, &deletedId );
// The above throws on failure, and so is not logged
repl::logOp(txn, "d", ns.c_str(), deletedId, 0, 0, fromMigrate);
+ ctx.commit();
numDeleted++;
}
diff --git a/src/mongo/db/index_builder.cpp b/src/mongo/db/index_builder.cpp
index c99a51d15be..0486baf8abd 100644
--- a/src/mongo/db/index_builder.cpp
+++ b/src/mongo/db/index_builder.cpp
@@ -72,6 +72,7 @@ namespace mongo {
if ( !status.isOK() ) {
log() << "IndexBuilder could not build index: " << status.toString();
}
+ ctx.commit();
cc().shutdown();
}
diff --git a/src/mongo/db/index_rebuilder.cpp b/src/mongo/db/index_rebuilder.cpp
index c85c6b66f3f..d85a0379042 100644
--- a/src/mongo/db/index_rebuilder.cpp
+++ b/src/mongo/db/index_rebuilder.cpp
@@ -145,6 +145,7 @@ namespace mongo {
}
}
+ ctx.commit();
}
}
diff --git a/src/mongo/db/instance.cpp b/src/mongo/db/instance.cpp
index 3edb27e5e65..bd35e4f2bd6 100644
--- a/src/mongo/db/instance.cpp
+++ b/src/mongo/db/instance.cpp
@@ -609,6 +609,7 @@ namespace mongo {
uassertStatusOK(executor.prepare());
Lock::DBWrite lk(txn->lockState(), ns.ns(), useExperimentalDocLocking);
+ WriteUnitOfWork wunit(txn->recoveryUnit());
// if this ever moves to outside of lock, need to adjust check
// Client::Context::_finishInit
@@ -621,6 +622,7 @@ namespace mongo {
// for getlasterror
lastError.getSafe()->recordUpdate( res.existing , res.numMatched , res.upserted );
+ wunit.commit();
}
void receivedDelete(OperationContext* txn, Message& m, CurOp& op) {
@@ -649,6 +651,7 @@ namespace mongo {
DeleteExecutor executor(&request);
uassertStatusOK(executor.prepare());
Lock::DBWrite lk(txn->lockState(), ns.ns());
+ WriteUnitOfWork wunit(txn->recoveryUnit());
// if this ever moves to outside of lock, need to adjust check Client::Context::_finishInit
if ( ! broadcast && handlePossibleShardedMessage( m , 0 ) )
@@ -659,6 +662,7 @@ namespace mongo {
long long n = executor.execute(txn, ctx.db());
lastError.getSafe()->recordDelete( n );
op.debug().ndeleted = n;
+ wunit.commit();
}
QueryResult* emptyMoreResult(long long);
@@ -895,6 +899,7 @@ namespace mongo {
if ( handlePossibleShardedMessage( m , 0 ) )
return;
+ WriteUnitOfWork wunit(txn->recoveryUnit());
Client::Context ctx(txn, ns);
if (multi.size() > 1) {
@@ -905,6 +910,7 @@ namespace mongo {
globalOpCounters.incInsertInWriteLock(1);
op.debug().ninserted = 1;
}
+ wunit.commit();
}
/* returns true if there is data on this server. useful when starting replication.
diff --git a/src/mongo/db/introspect.cpp b/src/mongo/db/introspect.cpp
index 87b74e6201a..3c3bb24353d 100644
--- a/src/mongo/db/introspect.cpp
+++ b/src/mongo/db/introspect.cpp
@@ -138,8 +138,11 @@ namespace {
// we're sometimes inside the lock already
Lock::DBWrite lk(txn->lockState(), currentOp.getNS() );
if (dbHolder().get(txn, nsToDatabase(currentOp.getNS())) != NULL) {
+ // We are ok with the profiling happening in a different WUOW from the actual op.
+ WriteUnitOfWork wunit(txn->recoveryUnit());
Client::Context cx(txn, currentOp.getNS(), false);
_profile(txn, c, cx.db(), currentOp, profileBufBuilder);
+ wunit.commit();
}
else {
mongo::log() << "note: not profiling because db went away - probably a close on: "
diff --git a/src/mongo/db/repl/master_slave.cpp b/src/mongo/db/repl/master_slave.cpp
index bdbbc14cc41..3199c82d4db 100644
--- a/src/mongo/db/repl/master_slave.cpp
+++ b/src/mongo/db/repl/master_slave.cpp
@@ -180,6 +180,7 @@ namespace repl {
_me = b.obj();
Helpers::putSingleton(&txn, "local.me", _me);
}
+ ctx.commit();
}
}
diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp
index 18754046e2f..5206c3f613b 100644
--- a/src/mongo/db/repl/oplog.cpp
+++ b/src/mongo/db/repl/oplog.cpp
@@ -117,6 +117,9 @@ namespace repl {
void _logOpObjRS(const BSONObj& op) {
OperationContextImpl txn;
Lock::DBWrite lk(txn.lockState(), "local");
+ // XXX soon this needs to be part of an outer WUOW not its own.
+ // We can't do this yet due to locking limitations.
+ WriteUnitOfWork wunit(txn.recoveryUnit());
const OpTime ts = op["ts"]._opTime();
long long h = op["h"].numberLong();
@@ -160,6 +163,7 @@ namespace repl {
}
setNewOptime(ts);
+ wunit.commit();
}
/**
@@ -236,6 +240,7 @@ namespace repl {
bool *bb,
bool fromMigrate ) {
Lock::DBWrite lk1(txn->lockState(), "local");
+ WriteUnitOfWork wunit(txn->recoveryUnit());
if ( strncmp(ns, "local.", 6) == 0 ) {
if ( strncmp(ns, "local.slaves", 12) == 0 )
@@ -314,6 +319,7 @@ namespace repl {
theReplSet->lastH = hashNew;
ctx.getClient()->setLastOp( ts );
}
+ wunit.commit();
}
@@ -326,6 +332,7 @@ namespace repl {
bool *bb,
bool fromMigrate ) {
Lock::DBWrite lk(txn->lockState(), "local");
+ WriteUnitOfWork wunit(txn->recoveryUnit());
static BufBuilder bufbuilder(8*1024); // todo there is likely a mutex on this constructor
if ( strncmp(ns, "local.", 6) == 0 ) {
@@ -374,6 +381,7 @@ namespace repl {
checkOplogInsert( localOplogMainCollection->insertDocument( txn, &writer, false ) );
ctx.getClient()->setLastOp( ts );
+ wunit.commit();
}
static void (*_logOp)(OperationContext* txn,
@@ -512,9 +520,11 @@ namespace repl {
options.cappedSize = sz;
options.autoIndexId = CollectionOptions::NO;
+ WriteUnitOfWork wunit(txn.recoveryUnit());
invariant( ctx.db()->createCollection( &txn, ns, options ) );
if( !rs )
logOp( &txn, "n", "", BSONObj() );
+ wunit.commit();
/* sync here so we don't get any surprising lag later when we try to sync */
globalStorageEngine->flushAllFiles(true);
diff --git a/src/mongo/db/repl/repl_set_impl.cpp b/src/mongo/db/repl/repl_set_impl.cpp
index 030da5fc532..1cedecf0880 100644
--- a/src/mongo/db/repl/repl_set_impl.cpp
+++ b/src/mongo/db/repl/repl_set_impl.cpp
@@ -871,13 +871,17 @@ namespace {
void ReplSetImpl::clearInitialSyncFlag() {
OperationContextImpl txn; // XXX?
Lock::DBWrite lk(txn.lockState(), "local");
+ WriteUnitOfWork wunit(txn.recoveryUnit());
Helpers::putSingleton(&txn, "local.replset.minvalid", BSON("$unset" << _initialSyncFlag));
+ wunit.commit();
}
void ReplSetImpl::setInitialSyncFlag() {
OperationContextImpl txn; // XXX?
Lock::DBWrite lk(txn.lockState(), "local");
+ WriteUnitOfWork wunit(txn.recoveryUnit());
Helpers::putSingleton(&txn, "local.replset.minvalid", BSON("$set" << _initialSyncFlag));
+ wunit.commit();
}
bool ReplSetImpl::getInitialSyncFlag() {
@@ -898,7 +902,9 @@ namespace {
OperationContextImpl txn; // XXX?
Lock::DBWrite lk(txn.lockState(), "local");
+ WriteUnitOfWork wunit(txn.recoveryUnit());
Helpers::putSingleton(&txn, "local.replset.minvalid", builder.obj());
+ wunit.commit();
}
OpTime ReplSetImpl::getMinValid() {
diff --git a/src/mongo/db/repl/resync.cpp b/src/mongo/db/repl/resync.cpp
index ca16a00139a..5267532e17e 100644
--- a/src/mongo/db/repl/resync.cpp
+++ b/src/mongo/db/repl/resync.cpp
@@ -68,6 +68,7 @@ namespace repl {
const std::string ns = parseNs(dbname, cmdObj);
Lock::GlobalWrite globalWriteLock(txn->lockState());
+ WriteUnitOfWork wunit(txn->recoveryUnit());
Client::Context ctx(txn, ns);
if (replSettings.usingReplSets()) {
if (!theReplSet) {
@@ -96,6 +97,7 @@ namespace repl {
ReplSource::forceResyncDead( txn, "client" );
result.append( "info", "triggered resync for all sources" );
+ wunit.commit();
return true;
}
diff --git a/src/mongo/db/repl/rs_config.cpp b/src/mongo/db/repl/rs_config.cpp
index a064289ab86..b92e665b2b1 100644
--- a/src/mongo/db/repl/rs_config.cpp
+++ b/src/mongo/db/repl/rs_config.cpp
@@ -94,6 +94,7 @@ namespace {
false/*logOp=false; local db so would work regardless...*/);
if( !comment.isEmpty() && (!theReplSet || theReplSet->isPrimary()) )
logOpInitiate(&txn, comment);
+ cx.commit();
}
log() << "replSet saveConfigLocally done" << rsLog;
}
diff --git a/src/mongo/db/repl/rs_initialsync.cpp b/src/mongo/db/repl/rs_initialsync.cpp
index f045a6155f7..b685325a1c4 100644
--- a/src/mongo/db/repl/rs_initialsync.cpp
+++ b/src/mongo/db/repl/rs_initialsync.cpp
@@ -115,6 +115,7 @@ namespace repl {
// Make database stable
Lock::DBWrite dbWrite(txn->lockState(), db);
+ WriteUnitOfWork wunit(txn->recoveryUnit());
if (!cloner.go(txn, db, master, options, NULL, err, &errCode)) {
sethbmsg(str::stream() << "initial sync: error while "
@@ -123,6 +124,7 @@ namespace repl {
<< "sleeping 5 minutes" ,0);
return false;
}
+ wunit.commit();
}
return true;
@@ -142,6 +144,7 @@ namespace repl {
LOG(1) << "replSet empty oplog" << rsLog;
uassertStatusOK( collection->truncate(&txn) );
+ ctx.commit();
}
const Member* ReplSetImpl::getMemberToSyncTo() {
@@ -477,6 +480,7 @@ namespace repl {
// Clear the initial sync flag.
theReplSet->clearInitialSyncFlag();
+ cx.commit();
}
{
boost::unique_lock<boost::mutex> lock(theReplSet->initialSyncMutex);
diff --git a/src/mongo/db/repl/sync.cpp b/src/mongo/db/repl/sync.cpp
index c9f43ebf894..a112603aed0 100644
--- a/src/mongo/db/repl/sync.cpp
+++ b/src/mongo/db/repl/sync.cpp
@@ -124,6 +124,7 @@ namespace repl {
return false;
}
else {
+ WriteUnitOfWork wunit(txn->recoveryUnit());
Collection* collection = ctx.db()->getOrCreateCollection(txn, ns);
invariant(collection != NULL); // should never happen
@@ -133,6 +134,7 @@ namespace repl {
result.isOK() );
LOG(1) << "replication inserted missing doc: " << missingObj.toString() << endl;
+ wunit.commit();
return true;
}
}
diff --git a/src/mongo/db/repl/sync_source_feedback.cpp b/src/mongo/db/repl/sync_source_feedback.cpp
index 774748288b5..0062fe20f20 100644
--- a/src/mongo/db/repl/sync_source_feedback.cpp
+++ b/src/mongo/db/repl/sync_source_feedback.cpp
@@ -84,6 +84,7 @@ namespace repl {
_me = b.obj();
Helpers::putSingleton(&txn, "local.me", _me);
}
+ ctx.commit();
// _me is used outside of a read lock, so we must copy it out of the mmap
_me = _me.getOwned();
}
diff --git a/src/mongo/db/repl/sync_tail.cpp b/src/mongo/db/repl/sync_tail.cpp
index ce4e3902a59..742fa123412 100644
--- a/src/mongo/db/repl/sync_tail.cpp
+++ b/src/mongo/db/repl/sync_tail.cpp
@@ -107,11 +107,13 @@ namespace repl {
}
Client::Context ctx(txn, ns);
+ WriteUnitOfWork wunit(txn->recoveryUnit());
ctx.getClient()->curop()->reset();
// For non-initial-sync, we convert updates to upserts
// to suppress errors when replaying oplog entries.
bool ok = !applyOperation_inlock(txn, ctx.db(), op, true, convertUpdateToUpsert);
opsAppliedStats.increment();
+ wunit.commit();
txn->recoveryUnit()->commitIfNeeded();
return ok;
@@ -478,6 +480,7 @@ namespace repl {
{
OperationContextImpl txn; // XXX?
Lock::DBWrite lk(txn.lockState(), "local");
+ WriteUnitOfWork wunit(txn.recoveryUnit());
while (!ops->empty()) {
const BSONObj& op = ops->front();
@@ -485,6 +488,7 @@ namespace repl {
_logOpObjRS(op);
ops->pop_front();
}
+ wunit.commit();
}
if (BackgroundSync::get()->isAssumingPrimary()) {
diff --git a/src/mongo/db/ttl.cpp b/src/mongo/db/ttl.cpp
index a3e1d7ccea3..8fb39e89642 100644
--- a/src/mongo/db/ttl.cpp
+++ b/src/mongo/db/ttl.cpp
@@ -138,6 +138,7 @@ namespace mongo {
n = deleteObjects(&txn, ctx.ctx().db(), ns, query, false, true);
ttlDeletedDocuments.increment( n );
+ ctx.commit();
}
LOG(1) << "\tTTL deleted: " << n << endl;
diff --git a/src/mongo/dbtests/basictests.cpp b/src/mongo/dbtests/basictests.cpp
index 1fbd27763c4..fc8ec367167 100644
--- a/src/mongo/dbtests/basictests.cpp
+++ b/src/mongo/dbtests/basictests.cpp
@@ -379,7 +379,9 @@ namespace BasicTests {
OperationContextImpl txn;
Lock::GlobalWrite lk(txn.lockState());
+ WriteUnitOfWork wunit(txn.recoveryUnit());
Database db( &txn, "dbtests_basictests_ownsns", NULL );
+ wunit.commit();
ASSERT( db.ownsNS( "dbtests_basictests_ownsns.x" ) );
ASSERT( db.ownsNS( "dbtests_basictests_ownsns.x.y" ) );
diff --git a/src/mongo/dbtests/clienttests.cpp b/src/mongo/dbtests/clienttests.cpp
index 1ba539f0266..4f4e7a96f15 100644
--- a/src/mongo/dbtests/clienttests.cpp
+++ b/src/mongo/dbtests/clienttests.cpp
@@ -160,6 +160,7 @@ namespace ClientTests {
ASSERT_EQUALS(3U, db.count("test.system.namespaces"));
db.ensureIndex(ns(), BSON("x" << 1), true);
+ ctx.commit();
ASSERT_EQUALS(2, indexCatalog->numIndexesReady());
ASSERT_EQUALS(2U, db.count("test.system.indexes"));
diff --git a/src/mongo/dbtests/counttests.cpp b/src/mongo/dbtests/counttests.cpp
index f8119b632a1..879d4353a0e 100644
--- a/src/mongo/dbtests/counttests.cpp
+++ b/src/mongo/dbtests/counttests.cpp
@@ -42,7 +42,7 @@ namespace CountTests {
class Base {
public:
- Base() : lk(_txn.lockState(), ns()), _context(&_txn, ns()) {
+ Base() : lk(_txn.lockState(), ns()), _wunit(_txn.recoveryUnit()), _context(&_txn, ns()) {
_database = _context.db();
_collection = _database->getCollection( &_txn, ns() );
if ( _collection ) {
@@ -55,6 +55,7 @@ namespace CountTests {
~Base() {
try {
uassertStatusOK( _database->dropCollection( &_txn, ns() ) );
+ _wunit.commit();
}
catch ( ... ) {
FAIL( "Exception while cleaning up collection" );
@@ -97,6 +98,7 @@ namespace CountTests {
private:
Lock::DBWrite lk;
+ WriteUnitOfWork _wunit;
Client::Context _context;
diff --git a/src/mongo/dbtests/dbhelper_tests.cpp b/src/mongo/dbtests/dbhelper_tests.cpp
index 88c04aece66..33d190ed34c 100644
--- a/src/mongo/dbtests/dbhelper_tests.cpp
+++ b/src/mongo/dbtests/dbhelper_tests.cpp
@@ -61,6 +61,7 @@ namespace mongo {
{
// Remove _id range [_min, _max).
Lock::DBWrite lk(txn.lockState(), ns);
+ WriteUnitOfWork wunit(txn.recoveryUnit());
Client::Context ctx(&txn, ns );
KeyRange range( ns,
@@ -68,6 +69,7 @@ namespace mongo {
BSON( "_id" << _max ),
BSON( "_id" << 1 ) );
Helpers::removeRange( &txn, range );
+ wunit.commit();
}
// Check that the expected documents remain.
diff --git a/src/mongo/dbtests/indexcatalogtests.cpp b/src/mongo/dbtests/indexcatalogtests.cpp
index bf9b61cf5d3..21fb94ca24b 100644
--- a/src/mongo/dbtests/indexcatalogtests.cpp
+++ b/src/mongo/dbtests/indexcatalogtests.cpp
@@ -37,6 +37,7 @@ namespace IndexCatalogTests {
_db = ctx.ctx().db();
_coll = _db->createCollection(&txn, _ns);
_catalog = _coll->getIndexCatalog();
+ ctx.commit();
}
~IndexIteratorTests() {
@@ -44,6 +45,7 @@ namespace IndexCatalogTests {
Client::WriteContext ctx(&txn, _ns);
_db->dropCollection(&txn, _ns);
+ ctx.commit();
}
void run() {
@@ -83,6 +85,7 @@ namespace IndexCatalogTests {
}
}
+ ctx.commit();
ASSERT_TRUE(indexesIterated == _catalog->numIndexesReady());
ASSERT_TRUE(foundIndex);
}
diff --git a/src/mongo/dbtests/indexupdatetests.cpp b/src/mongo/dbtests/indexupdatetests.cpp
index 3458181887a..f5c24e3ce59 100644
--- a/src/mongo/dbtests/indexupdatetests.cpp
+++ b/src/mongo/dbtests/indexupdatetests.cpp
@@ -59,6 +59,7 @@ namespace IndexUpdateTests {
}
~IndexBuildBase() {
_client.dropCollection( _ns );
+ _ctx.commit(); // just for testing purposes
getGlobalEnvironment()->unsetKillAllOperations();
}
Collection* collection() {
@@ -469,6 +470,7 @@ namespace IndexUpdateTests {
public:
void run() {
OperationContextImpl txn;
+ WriteUnitOfWork wunit (txn.recoveryUnit());
// Insert some documents.
int32_t nDocs = 1000;
for( int32_t i = 0; i < nDocs; ++i ) {
@@ -481,6 +483,7 @@ namespace IndexUpdateTests {
// The call is not interrupted.
Helpers::ensureIndex( &txn, collection(), BSON( "a" << 1 ), false, "a_1" );
// only want to interrupt the index build
+ wunit.commit();
getGlobalEnvironment()->unsetKillAllOperations();
// The new index is listed in system.indexes because the index build completed.
ASSERT_EQUALS( 1U,
diff --git a/src/mongo/dbtests/oplogstarttests.cpp b/src/mongo/dbtests/oplogstarttests.cpp
index 45015afe883..4f4f88c1ccc 100644
--- a/src/mongo/dbtests/oplogstarttests.cpp
+++ b/src/mongo/dbtests/oplogstarttests.cpp
@@ -38,6 +38,7 @@ namespace OplogStartTests {
class Base {
public:
Base() : _lk(_txn.lockState()),
+ _wunit(_txn.recoveryUnit()),
_context(&_txn, ns()),
_client(&_txn) {
@@ -50,6 +51,7 @@ namespace OplogStartTests {
~Base() {
client()->dropCollection(ns());
+ _wunit.commit();
}
protected:
@@ -94,6 +96,7 @@ namespace OplogStartTests {
// The order of these is important in order to ensure order of destruction
OperationContextImpl _txn;
Lock::GlobalWrite _lk;
+ WriteUnitOfWork _wunit;
Client::Context _context;
DBDirectClient _client;
diff --git a/src/mongo/dbtests/pdfiletests.cpp b/src/mongo/dbtests/pdfiletests.cpp
index d954c801fdd..aa6026d3d40 100644
--- a/src/mongo/dbtests/pdfiletests.cpp
+++ b/src/mongo/dbtests/pdfiletests.cpp
@@ -48,14 +48,15 @@ namespace PdfileTests {
class Base {
public:
Base() : _lk(_txn.lockState()),
+ _wunit(_txn.recoveryUnit()),
_context(&_txn, ns()) {
-
}
virtual ~Base() {
if ( !collection() )
return;
_context.db()->dropCollection( &_txn, ns() );
+ _wunit.commit();
}
protected:
@@ -68,7 +69,7 @@ namespace PdfileTests {
OperationContextImpl _txn;
Lock::GlobalWrite _lk;
-
+ WriteUnitOfWork _wunit;
Client::Context _context;
};
diff --git a/src/mongo/dbtests/plan_ranking.cpp b/src/mongo/dbtests/plan_ranking.cpp
index 79419bb60fa..7b8f01add03 100644
--- a/src/mongo/dbtests/plan_ranking.cpp
+++ b/src/mongo/dbtests/plan_ranking.cpp
@@ -66,6 +66,7 @@ namespace PlanRankingTests {
Client::WriteContext ctx(&_txn, ns);
_client.dropCollection(ns);
+ ctx.commit();
}
virtual ~PlanRankingTestBase() {
@@ -76,11 +77,13 @@ namespace PlanRankingTests {
void insert(const BSONObj& obj) {
Client::WriteContext ctx(&_txn, ns);
_client.insert(ns, obj);
+ ctx.commit();
}
void addIndex(const BSONObj& obj) {
Client::WriteContext ctx(&_txn, ns);
_client.ensureIndex(ns, obj);
+ ctx.commit();
}
/**
diff --git a/src/mongo/dbtests/query_multi_plan_runner.cpp b/src/mongo/dbtests/query_multi_plan_runner.cpp
index f47d08ecfe8..81982df6768 100644
--- a/src/mongo/dbtests/query_multi_plan_runner.cpp
+++ b/src/mongo/dbtests/query_multi_plan_runner.cpp
@@ -164,6 +164,7 @@ namespace QueryMultiPlanRunner {
ASSERT_EQUALS(obj["foo"].numberInt(), 7);
++results;
}
+ ctx.commit();
ASSERT_EQUALS(results, N / 10);
}
diff --git a/src/mongo/dbtests/query_single_solution_runner.cpp b/src/mongo/dbtests/query_single_solution_runner.cpp
index d5290853151..91596c5cf49 100644
--- a/src/mongo/dbtests/query_single_solution_runner.cpp
+++ b/src/mongo/dbtests/query_single_solution_runner.cpp
@@ -205,6 +205,7 @@ namespace QuerySingleSolutionRunner {
ASSERT_EQUALS(Runner::RUNNER_DEAD, ssr->getNext(&objOut, NULL));
deregisterRunner(ssr.get());
+ ctx.commit();
}
};
@@ -235,6 +236,7 @@ namespace QuerySingleSolutionRunner {
ASSERT_EQUALS(Runner::RUNNER_DEAD, ssr->getNext(&objOut, NULL));
deregisterRunner(ssr.get());
+ ctx.commit();
}
};
@@ -300,6 +302,7 @@ namespace QuerySingleSolutionRunner {
int ids[] = {3, 4, 2};
checkIds(ids, ssr.get());
+ ctx.commit();
}
};
@@ -329,6 +332,7 @@ namespace QuerySingleSolutionRunner {
// we should not see the moved document again.
int ids[] = {3, 4};
checkIds(ids, ssr.get());
+ ctx.commit();
}
};
@@ -357,6 +361,7 @@ namespace QuerySingleSolutionRunner {
ASSERT_EQUALS(1U, numCursors());
ctx.ctx().db()->getCollection( &_txn, ns() )->cursorCache()->invalidateAll(false);
ASSERT_EQUALS(0U, numCursors());
+ ctx.commit();
}
};
@@ -394,6 +399,7 @@ namespace QuerySingleSolutionRunner {
// number of cursors to return to 0.
ccPin.deleteUnderlying();
ASSERT_EQUALS(0U, numCursors());
+ ctx.commit();
}
};
@@ -407,6 +413,7 @@ namespace QuerySingleSolutionRunner {
{
Client::WriteContext ctx(&_txn, ns());
insert(BSON("a" << 1 << "b" << 1));
+ ctx.commit();
}
{
diff --git a/src/mongo/dbtests/query_stage_and.cpp b/src/mongo/dbtests/query_stage_and.cpp
index 59a5ae3819f..75b144c7e45 100644
--- a/src/mongo/dbtests/query_stage_and.cpp
+++ b/src/mongo/dbtests/query_stage_and.cpp
@@ -222,6 +222,7 @@ namespace QueryStageAnd {
ASSERT_GREATER_THAN_OR_EQUALS(elt.numberInt(), 10);
}
+ ctx.commit();
ASSERT_EQUALS(10, count);
}
};
@@ -308,6 +309,7 @@ namespace QueryStageAnd {
++count;
}
+ ctx.commit();
ASSERT_EQUALS(count, 20);
}
};
@@ -351,6 +353,7 @@ namespace QueryStageAnd {
params.bounds.endKeyInclusive = true;
params.direction = 1;
ah->addChild(new IndexScan(params, &ws, NULL));
+ ctx.commit();
// foo == bar == baz, and foo<=20, bar>=10, so our values are:
// foo == 10, 11, 12, 13, 14, 15. 16, 17, 18, 19, 20
@@ -405,6 +408,7 @@ namespace QueryStageAnd {
params.bounds.endKeyInclusive = true;
params.direction = 1;
ah->addChild(new IndexScan(params, &ws, NULL));
+ ctx.commit();
// Stage execution should fail.
ASSERT_EQUALS(-1, countResults(ah.get()));
@@ -457,6 +461,7 @@ namespace QueryStageAnd {
params.bounds.endKeyInclusive = true;
params.direction = 1;
ah->addChild(new IndexScan(params, &ws, NULL));
+ ctx.commit();
// foo == bar == baz, and foo<=20, bar>=10, so our values are:
// foo == 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20.
@@ -512,6 +517,7 @@ namespace QueryStageAnd {
params.bounds.endKeyInclusive = true;
params.direction = 1;
ah->addChild(new IndexScan(params, &ws, NULL));
+ ctx.commit();
// foo == bar == baz, and foo<=20, bar>=10, 5<=baz<=15, so our values are:
// foo == 10, 11, 12, 13, 14, 15.
@@ -578,6 +584,7 @@ namespace QueryStageAnd {
params.bounds.endKeyInclusive = true;
params.direction = 1;
ah->addChild(new IndexScan(params, &ws, NULL));
+ ctx.commit();
// Stage execution should fail.
ASSERT_EQUALS(-1, countResults(ah.get()));
@@ -633,6 +640,7 @@ namespace QueryStageAnd {
if (PlanStage::ADVANCED != status) { continue; }
++count;
}
+ ctx.commit();
ASSERT_EQUALS(0, count);
@@ -686,6 +694,7 @@ namespace QueryStageAnd {
params.bounds.endKeyInclusive = false;
params.direction = -1;
ah->addChild(new IndexScan(params, &ws, NULL));
+ ctx.commit();
ASSERT_EQUALS(0, countResults(ah.get()));
}
@@ -734,6 +743,7 @@ namespace QueryStageAnd {
params.bounds.endKeyInclusive = true;
params.direction = 1;
ah->addChild(new IndexScan(params, &ws, NULL));
+ ctx.commit();
// Bar == 97
ASSERT_EQUALS(1, countResults(ah.get()));
@@ -856,6 +866,7 @@ namespace QueryStageAnd {
ASSERT_TRUE(member->getFieldDotted("bar", &elt));
ASSERT_EQUALS(1, elt.numberInt());
}
+ ctx.commit();
ASSERT_EQUALS(count, 48);
@@ -912,6 +923,7 @@ namespace QueryStageAnd {
// baz == 1
params.descriptor = getIndex(BSON("baz" << 1), coll);
ah->addChild(new IndexScan(params, &ws, NULL));
+ ctx.commit();
ASSERT_EQUALS(50, countResults(ah.get()));
}
@@ -957,6 +969,7 @@ namespace QueryStageAnd {
params.bounds.endKeyInclusive = true;
params.direction = 1;
ah->addChild(new IndexScan(params, &ws, NULL));
+ ctx.commit();
ASSERT_EQUALS(0, countResults(ah.get()));
}
@@ -1005,6 +1018,7 @@ namespace QueryStageAnd {
params.bounds.endKeyInclusive = true;
params.direction = 1;
ah->addChild(new IndexScan(params, &ws, NULL));
+ ctx.commit();
ASSERT_EQUALS(0, countResults(ah.get()));
}
@@ -1049,6 +1063,7 @@ namespace QueryStageAnd {
// bar == 1
params.descriptor = getIndex(BSON("bar" << 1), coll);
ah->addChild(new IndexScan(params, &ws, NULL));
+ ctx.commit();
// Filter drops everything.
ASSERT_EQUALS(0, countResults(ah.get()));
@@ -1109,6 +1124,7 @@ namespace QueryStageAnd {
}
lastId = id;
}
+ ctx.commit();
ASSERT_EQUALS(count, 43);
}
diff --git a/src/mongo/dbtests/query_stage_collscan.cpp b/src/mongo/dbtests/query_stage_collscan.cpp
index 647b721f878..06088bf425a 100644
--- a/src/mongo/dbtests/query_stage_collscan.cpp
+++ b/src/mongo/dbtests/query_stage_collscan.cpp
@@ -59,6 +59,7 @@ namespace QueryStageCollectionScan {
virtual ~QueryStageCollectionScanCappedBase() {
_context.db()->dropCollection( &_txn, ns() );
+ wunit.commit();
}
void run() {
@@ -175,6 +176,7 @@ namespace QueryStageCollectionScan {
Lock::GlobalWrite lk_;
Client::Context _context;
OperationContextImpl _txn;
+ WriteUnitOfWork wunit(_txn.recoveryUnit());
};
class QueryStageCollscanEmpty : public QueryStageCollectionScanCappedBase {
@@ -321,11 +323,13 @@ namespace QueryStageCollectionScan {
bob.append("foo", i);
_client.insert(ns(), bob.obj());
}
+ ctx.commit();
}
virtual ~QueryStageCollectionScanBase() {
Client::WriteContext ctx(&_txn, ns());
_client.dropCollection(ns());
+ ctx.commit();
}
void remove(const BSONObj& obj) {
@@ -552,6 +556,7 @@ namespace QueryStageCollectionScan {
++count;
}
}
+ ctx.commit();
ASSERT_EQUALS(numObj(), count);
}
@@ -613,6 +618,7 @@ namespace QueryStageCollectionScan {
++count;
}
}
+ ctx.commit();
ASSERT_EQUALS(numObj(), count);
}
diff --git a/src/mongo/dbtests/query_stage_count.cpp b/src/mongo/dbtests/query_stage_count.cpp
index 04a45d98044..b4a86309568 100644
--- a/src/mongo/dbtests/query_stage_count.cpp
+++ b/src/mongo/dbtests/query_stage_count.cpp
@@ -55,6 +55,7 @@ namespace QueryStageCount {
virtual ~CountBase() {
Client::WriteContext ctx(&_txn, ns());
_client.dropCollection(ns());
+ ctx.commit();
}
void addIndex(const BSONObj& obj) {
@@ -116,6 +117,7 @@ namespace QueryStageCount {
// Add an index on a:1
addIndex(BSON("a" << 1));
+ ctx.commit();
// Set up the count stage
CountParams params;
@@ -149,6 +151,7 @@ namespace QueryStageCount {
// Add an index
addIndex(BSON("a" << 1));
+ ctx.commit();
// Set up the count stage
CountParams params;
@@ -181,6 +184,7 @@ namespace QueryStageCount {
// Add an index
addIndex(BSON("a" << 1));
+ ctx.commit();
// Set up the count stage
CountParams params;
@@ -209,6 +213,7 @@ namespace QueryStageCount {
// Insert doc, add index
insert(BSON("a" << 2));
addIndex(BSON("a" << 1));
+ ctx.commit();
// Set up count, and run
CountParams params;
@@ -238,6 +243,7 @@ namespace QueryStageCount {
insert(BSON("a" << 2));
insert(BSON("a" << 3));
addIndex(BSON("a" << 1));
+ ctx.commit();
// Set up count, and run
CountParams params;
@@ -268,6 +274,7 @@ namespace QueryStageCount {
insert(BSON("a" << 2));
insert(BSON("a" << 4));
addIndex(BSON("a" << 1));
+ ctx.commit();
// Set up count, and run
CountParams params;
@@ -299,6 +306,7 @@ namespace QueryStageCount {
insert(BSON("a" << i));
}
addIndex(BSON("a" << 1));
+ ctx.commit();
// Set up count stage
CountParams params;
@@ -350,6 +358,7 @@ namespace QueryStageCount {
insert(BSON("a" << i));
}
addIndex(BSON("a" << 1));
+ ctx.commit();
// Set up count stage
CountParams params;
@@ -404,6 +413,7 @@ namespace QueryStageCount {
insert(BSON("a" << i));
}
addIndex(BSON("a" << 1));
+ ctx.commit();
// Set up count stage
CountParams params;
@@ -461,6 +471,7 @@ namespace QueryStageCount {
insert(BSON("a" << i));
}
addIndex(BSON("a" << 1));
+ ctx.commit();
// Set up count stage
CountParams params;
@@ -514,6 +525,7 @@ namespace QueryStageCount {
insert(BSON("a" << 1 << "b" << i));
}
addIndex(BSON("a" << 1));
+ ctx.commit();
// Mark several keys as 'unused'
remove(BSON("a" << 1 << "b" << 0));
@@ -552,6 +564,7 @@ namespace QueryStageCount {
// Mark key at end position as 'unused' by deleting
remove(BSON("a" << 1 << "b" << 9));
+ ctx.commit();
// Run count and check
CountParams params;
@@ -582,6 +595,7 @@ namespace QueryStageCount {
insert(BSON("a" << 1 << "b" << i));
}
addIndex(BSON("a" << 1));
+ ctx.commit();
// Set up count stage
CountParams params;
diff --git a/src/mongo/dbtests/query_stage_distinct.cpp b/src/mongo/dbtests/query_stage_distinct.cpp
index 942c87b264a..ac61fc55fce 100644
--- a/src/mongo/dbtests/query_stage_distinct.cpp
+++ b/src/mongo/dbtests/query_stage_distinct.cpp
@@ -53,16 +53,19 @@ namespace QueryStageDistinct {
virtual ~DistinctBase() {
Client::WriteContext ctx(&_txn, ns());
_client.dropCollection(ns());
+ ctx.commit();
}
void addIndex(const BSONObj& obj) {
Client::WriteContext ctx(&_txn, ns());
_client.ensureIndex(ns(), obj);
+ ctx.commit();
}
void insert(const BSONObj& obj) {
Client::WriteContext ctx(&_txn, ns());
_client.insert(ns(), obj);
+ ctx.commit();
}
IndexDescriptor* getIndex(const BSONObj& obj) {
diff --git a/src/mongo/dbtests/query_stage_fetch.cpp b/src/mongo/dbtests/query_stage_fetch.cpp
index 4bea8b9e004..bc95554164a 100644
--- a/src/mongo/dbtests/query_stage_fetch.cpp
+++ b/src/mongo/dbtests/query_stage_fetch.cpp
@@ -103,6 +103,7 @@ namespace QueryStageFetch {
set<DiskLoc> locs;
getLocs(&locs, coll);
ASSERT_EQUALS(size_t(1), locs.size());
+ ctx.commit();
// Create a mock stage that returns the WSM.
auto_ptr<MockStage> mockStage(new MockStage(&ws));
@@ -199,6 +200,7 @@ namespace QueryStageFetch {
// No more data to fetch, so, EOF.
state = fetchStage->work(&id);
ASSERT_EQUALS(PlanStage::IS_EOF, state);
+ ctx.commit();
}
};
diff --git a/src/mongo/dbtests/query_stage_keep.cpp b/src/mongo/dbtests/query_stage_keep.cpp
index 3283b66ab8c..eca675d6966 100644
--- a/src/mongo/dbtests/query_stage_keep.cpp
+++ b/src/mongo/dbtests/query_stage_keep.cpp
@@ -127,6 +127,7 @@ namespace QueryStageKeep {
member->obj = BSON("x" << 2);
ws.flagForReview(id);
}
+ ctx.commit();
// Create a collscan to provide the 10 objects in the collection.
CollectionScanParams params;
diff --git a/src/mongo/dbtests/query_stage_merge_sort.cpp b/src/mongo/dbtests/query_stage_merge_sort.cpp
index 11161a5c6be..2aa83912515 100644
--- a/src/mongo/dbtests/query_stage_merge_sort.cpp
+++ b/src/mongo/dbtests/query_stage_merge_sort.cpp
@@ -54,6 +54,7 @@ namespace QueryStageMergeSortTests {
virtual ~QueryStageMergeSortTestBase() {
Client::WriteContext ctx(&_txn, ns());
_client.dropCollection(ns());
+ ctx.commit();
}
void addIndex(const BSONObj& obj) {
@@ -149,6 +150,7 @@ namespace QueryStageMergeSortTests {
// b:1
params.descriptor = getIndex(secondIndex, coll);
ms->addChild(new IndexScan(params, ws, NULL));
+ ctx.commit();
// Must fetch if we want to easily pull out an obj.
PlanExecutor runner(ws, new FetchStage(ws, ms, NULL, coll), coll);
@@ -212,6 +214,7 @@ namespace QueryStageMergeSortTests {
// b:1
params.descriptor = getIndex(secondIndex, coll);
ms->addChild(new IndexScan(params, ws, NULL));
+ ctx.commit();
PlanExecutor runner(ws, new FetchStage(ws, ms, NULL, coll), coll);
@@ -274,6 +277,7 @@ namespace QueryStageMergeSortTests {
// b:1
params.descriptor = getIndex(secondIndex, coll);
ms->addChild(new IndexScan(params, ws, NULL));
+ ctx.commit();
PlanExecutor runner(ws, new FetchStage(ws, ms, NULL, coll), coll);
@@ -339,6 +343,7 @@ namespace QueryStageMergeSortTests {
// b:1
params.descriptor = getIndex(secondIndex, coll);
ms->addChild(new IndexScan(params, ws, NULL));
+ ctx.commit();
PlanExecutor runner(ws, new FetchStage(ws, ms, NULL, coll), coll);
@@ -403,6 +408,7 @@ namespace QueryStageMergeSortTests {
params.bounds.startKey = BSON("" << 51 << "" << MinKey);
params.bounds.endKey = BSON("" << 51 << "" << MaxKey);
ms->addChild(new IndexScan(params, ws, NULL));
+ ctx.commit();
PlanExecutor runner(ws, new FetchStage(ws, ms, NULL, coll), coll);
@@ -455,6 +461,7 @@ namespace QueryStageMergeSortTests {
params.descriptor = getIndex(indexSpec, coll);
ms->addChild(new IndexScan(params, ws, NULL));
}
+ ctx.commit();
PlanExecutor runner(ws, new FetchStage(ws, ms, NULL, coll), coll);
@@ -514,6 +521,7 @@ namespace QueryStageMergeSortTests {
getLocs(&locs, coll);
set<DiskLoc>::iterator it = locs.begin();
+ ctx.commit();
// Get 10 results. Should be getting results in order of 'locs'.
int count = 0;
diff --git a/src/mongo/dbtests/query_stage_sort.cpp b/src/mongo/dbtests/query_stage_sort.cpp
index 6ae66a0b7bb..60838f5df77 100644
--- a/src/mongo/dbtests/query_stage_sort.cpp
+++ b/src/mongo/dbtests/query_stage_sort.cpp
@@ -193,6 +193,7 @@ namespace QueryStageSortTests {
fillData();
sortAndCheck(1, coll);
+ ctx.commit();
}
};
@@ -212,6 +213,7 @@ namespace QueryStageSortTests {
fillData();
sortAndCheck(-1, coll);
+ ctx.commit();
}
};
@@ -240,6 +242,7 @@ namespace QueryStageSortTests {
fillData();
sortAndCheck(-1, coll);
+ ctx.commit();
}
};
@@ -315,6 +318,7 @@ namespace QueryStageSortTests {
ASSERT(!member->hasLoc());
++count;
}
+ ctx.commit();
// Returns all docs.
ASSERT_EQUALS(limit() ? limit() : numObj(), count);
@@ -371,6 +375,7 @@ namespace QueryStageSortTests {
ws, new FetchStage(ws, new SortStage(params, ws, ms), NULL, coll), coll);
Runner::RunnerState runnerState = runner.getNext(NULL, NULL);
ASSERT_EQUALS(Runner::RUNNER_ERROR, runnerState);
+ ctx.commit();
}
};
diff --git a/src/mongo/dbtests/query_stage_tests.cpp b/src/mongo/dbtests/query_stage_tests.cpp
index fc5ee43ea50..91640817f74 100644
--- a/src/mongo/dbtests/query_stage_tests.cpp
+++ b/src/mongo/dbtests/query_stage_tests.cpp
@@ -59,16 +59,19 @@ namespace QueryStageTests {
addIndex(BSON("foo" << 1));
addIndex(BSON("foo" << 1 << "baz" << 1));
+ ctx.commit();
}
virtual ~IndexScanBase() {
Client::WriteContext ctx(&_txn, ns());
_client.dropCollection(ns());
+ ctx.commit();
}
void addIndex(const BSONObj& obj) {
Client::WriteContext ctx(&_txn, ns());
_client.ensureIndex(ns(), obj);
+ ctx.commit();
}
int countResults(const IndexScanParams& params, BSONObj filterObj = BSONObj()) {
@@ -99,6 +102,7 @@ namespace QueryStageTests {
double lng = double(rand()) / RAND_MAX;
_client.insert(ns(), BSON("geo" << BSON_ARRAY(lng << lat)));
}
+ ctx.commit();
}
IndexDescriptor* getIndex(const BSONObj& obj) {
diff --git a/src/mongo/dbtests/querytests.cpp b/src/mongo/dbtests/querytests.cpp
index ef3d859a260..f18e9121713 100644
--- a/src/mongo/dbtests/querytests.cpp
+++ b/src/mongo/dbtests/querytests.cpp
@@ -57,7 +57,7 @@ namespace QueryTests {
protected:
OperationContextImpl _txn;
Lock::GlobalWrite _lk;
-
+ WriteUnitOfWork _wunit;
Client::Context _context;
Database* _database;
@@ -65,8 +65,8 @@ namespace QueryTests {
public:
Base() : _lk(_txn.lockState()),
+ _wunit(_txn.recoveryUnit()),
_context(&_txn, ns()) {
-
_database = _context.db();
_collection = _database->getCollection( &_txn, ns() );
if ( _collection ) {
@@ -78,6 +78,7 @@ namespace QueryTests {
~Base() {
try {
uassertStatusOK( _database->dropCollection( &_txn, ns() ) );
+ _wunit.commit();
}
catch ( ... ) {
FAIL( "Exception while cleaning up collection" );
@@ -245,12 +246,14 @@ namespace QueryTests {
{
// Check internal server handoff to getmore.
Lock::DBWrite lk(_txn.lockState(), ns);
+ WriteUnitOfWork wunit(_txn.recoveryUnit());
Client::Context ctx(&_txn, ns );
ClientCursorPin clientCursor( ctx.db()->getCollection(&_txn, ns), cursorId );
// pq doesn't exist if it's a runner inside of the clientcursor.
// ASSERT( clientCursor.c()->pq );
// ASSERT_EQUALS( 2, clientCursor.c()->pq->getNumToReturn() );
ASSERT_EQUALS( 2, clientCursor.c()->pos() );
+ wunit.commit();
}
cursor = _client.getMore( ns, cursorId );
@@ -593,8 +596,9 @@ namespace QueryTests {
void run() {
const char *ns = "unittests.querytests.OplogReplaySlaveReadTill";
Lock::DBWrite lk(_txn.lockState(), ns);
+ WriteUnitOfWork wunit(_txn.recoveryUnit());
Client::Context ctx(&_txn, ns );
-
+
BSONObj info;
_client.runCommand( "unittests",
BSON( "create" << "querytests.OplogReplaySlaveReadTill" <<
@@ -616,6 +620,7 @@ namespace QueryTests {
ClientCursorPin clientCursor( ctx.db()->getCollection( &_txn, ns ), cursorId );
ASSERT_EQUALS( three.millis, clientCursor.c()->getSlaveReadTill().asDate() );
+ wunit.commit();
}
};
@@ -1057,7 +1062,9 @@ namespace QueryTests {
void run() {
Lock::GlobalWrite lk(_txn.lockState());
Client::Context ctx(&_txn, "unittests.DirectLocking");
+ WriteUnitOfWork wunit(_txn.recoveryUnit());
_client.remove( "a.b", BSONObj() );
+ wunit.commit();
ASSERT_EQUALS( "unittests", ctx.db()->name() );
}
const char *ns;
@@ -1208,6 +1215,7 @@ namespace QueryTests {
for ( int i=0; i<90; i++ ) {
insertNext();
}
+ ctx.commit();
while ( c->more() ) { c->next(); }
ASSERT( c->isDead() );
@@ -1235,6 +1243,7 @@ namespace QueryTests {
for ( int i=0; i<50; i++ ) {
insert( ns() , BSON( "_id" << i << "x" << i * 2 ) );
}
+ ctx.commit();
ASSERT_EQUALS( 50 , count() );
@@ -1289,6 +1298,7 @@ namespace QueryTests {
for ( int i=0; i<1000; i+=2 ) {
_client.remove( ns() , BSON( "_id" << i ) );
}
+ ctx.commit();
BSONObj res;
for ( int i=0; i<1000; i++ ) {
@@ -1309,7 +1319,7 @@ namespace QueryTests {
for ( int i=0; i<1000; i++ ) {
insert( ns() , BSON( "_id" << i << "x" << i * 2 ) );
}
-
+ ctx.commit();
}
};
@@ -1421,11 +1431,16 @@ namespace QueryTests {
CollectionInternalBase( const char *nsLeaf ) :
CollectionBase( nsLeaf ),
_lk(_txn.lockState(), ns() ),
+ _wunit( _txn.recoveryUnit() ),
_ctx(&_txn, ns()) {
-
}
+ ~CollectionInternalBase() {
+ _wunit.commit();
+ }
+
private:
Lock::DBWrite _lk;
+ WriteUnitOfWork _wunit;
Client::Context _ctx;
};
@@ -1511,6 +1526,7 @@ namespace QueryTests {
string expectedAssertion =
str::stream() << "Cannot kill active cursor " << cursorId;
ASSERT_EQUALS( expectedAssertion, _client.getLastError() );
+ ctx.commit();
}
// Verify that the remaining document is read from the cursor.
diff --git a/src/mongo/dbtests/replsettests.cpp b/src/mongo/dbtests/replsettests.cpp
index 0cd3597f34c..3e6b7ef7ad7 100644
--- a/src/mongo/dbtests/replsettests.cpp
+++ b/src/mongo/dbtests/replsettests.cpp
@@ -161,6 +161,7 @@ namespace ReplSetTests {
}
db->dropCollection(&_txn, ns());
+ c.commit();
}
static void setup() {
@@ -315,15 +316,19 @@ namespace ReplSetTests {
void create() {
Client::Context c(&_txn, _cappedNs);
+ WriteUnitOfWork wunit(_txn.recoveryUnit());
ASSERT( userCreateNS( &_txn, c.db(), _cappedNs, fromjson( spec() ), false ).isOK() );
+ wunit.commit();
}
void dropCapped() {
Client::Context c(&_txn, _cappedNs);
+ WriteUnitOfWork wunit(_txn.recoveryUnit());
Database* db = c.db();
if ( db->getCollection( &_txn, _cappedNs ) ) {
db->dropCollection( &_txn, _cappedNs );
}
+ wunit.commit();
}
BSONObj updateFail() {
@@ -358,17 +363,24 @@ namespace ReplSetTests {
// returns true on success, false on failure
bool apply(const BSONObj& op) {
Client::Context ctx(&_txn, _cappedNs );
+ WriteUnitOfWork wunit(_txn.recoveryUnit());
// in an annoying twist of api, returns true on failure
- return !applyOperation_inlock(&_txn, ctx.db(), op, true);
+ if (applyOperation_inlock(&_txn, ctx.db(), op, true)) {
+ return false;
+ }
+ wunit.commit();
+ return true;
}
void run() {
Lock::DBWrite lk(_txn.lockState(), _cappedNs);
+ WriteUnitOfWork wunit(_txn.recoveryUnit());
BSONObj op = updateFail();
Sync s("");
verify(!s.shouldRetry(&_txn, op));
+ wunit.commit();
}
};
@@ -388,6 +400,7 @@ namespace ReplSetTests {
void insert(OperationContext* txn) {
Client::Context ctx(txn, cappedNs());
+ WriteUnitOfWork wunit(txn->recoveryUnit());
Database* db = ctx.db();
Collection* coll = db->getCollection(txn, cappedNs());
if (!coll) {
@@ -397,6 +410,7 @@ namespace ReplSetTests {
BSONObj o = BSON(GENOID << "x" << 456);
DiskLoc loc = coll->insertDocument(txn, o, true).getValue();
verify(!loc.isNull());
+ wunit.commit();
}
public:
virtual ~CappedUpdate() {}
@@ -432,6 +446,7 @@ namespace ReplSetTests {
public:
virtual ~CappedInsert() {}
void run() {
+ WriteUnitOfWork wunit(_txn.recoveryUnit());
// This will succeed, but not insert anything because they are changed to upserts
for (int i=0; i<150; i++) {
insertSucceed();
@@ -442,6 +457,7 @@ namespace ReplSetTests {
Client::Context ctx(&_txn, cappedNs());
Collection* collection = ctx.db()->getCollection( &_txn, cappedNs() );
verify(collection->getIndexCatalog()->findIdIndex());
+ wunit.commit();
}
};
diff --git a/src/mongo/dbtests/repltests.cpp b/src/mongo/dbtests/repltests.cpp
index 11338a61225..4694c942f73 100644
--- a/src/mongo/dbtests/repltests.cpp
+++ b/src/mongo/dbtests/repltests.cpp
@@ -58,12 +58,14 @@ namespace ReplTests {
protected:
mutable OperationContextImpl _txn;
Lock::GlobalWrite _lk;
+ WriteUnitOfWork _wunit;
mutable DBDirectClient _client;
Client::Context _context;
public:
Base() : _lk(_txn.lockState()),
+ _wunit( _txn.recoveryUnit()),
_client(&_txn),
_context(&_txn, ns()) {
@@ -73,6 +75,7 @@ namespace ReplTests {
replSettings.master = true;
createOplog();
+
Collection* c = _context.db()->getCollection( &_txn, ns() );
if ( ! c ) {
c = _context.db()->createCollection( &_txn, ns() );
@@ -84,6 +87,7 @@ namespace ReplTests {
replSettings.master = false;
deleteAll( ns() );
deleteAll( cllNS() );
+ _wunit.commit();
}
catch ( ... ) {
FAIL( "Exception while cleaning up test" );
@@ -140,6 +144,7 @@ namespace ReplTests {
static int opCount() {
OperationContextImpl txn;
Lock::GlobalWrite lk(txn.lockState());
+ WriteUnitOfWork wunit(txn.recoveryUnit());
Client::Context ctx(&txn, cllNS() );
Database* db = ctx.db();
@@ -155,12 +160,13 @@ namespace ReplTests {
++count;
}
delete it;
+ wunit.commit();
return count;
}
static void applyAllOperations() {
OperationContextImpl txn;
Lock::GlobalWrite lk(txn.lockState());
-
+ WriteUnitOfWork wunit(txn.recoveryUnit());
vector< BSONObj > ops;
{
Client::Context ctx(&txn, cllNS() );
@@ -188,10 +194,12 @@ namespace ReplTests {
a.applyOperation( &txn, ctx.db(), *i );
}
}
+ wunit.commit();
}
static void printAll( const char *ns ) {
OperationContextImpl txn;
Lock::GlobalWrite lk(txn.lockState());
+ WriteUnitOfWork wunit(txn.recoveryUnit());
Client::Context ctx(&txn, ns );
Database* db = ctx.db();
@@ -208,13 +216,14 @@ namespace ReplTests {
::mongo::log() << coll->docFor(currLoc).toString() << endl;
}
delete it;
+ wunit.commit();
}
// These deletes don't get logged.
static void deleteAll( const char *ns ) {
OperationContextImpl txn;
Lock::GlobalWrite lk(txn.lockState());
Client::Context ctx(&txn, ns );
-
+ WriteUnitOfWork wunit(txn.recoveryUnit());
Database* db = ctx.db();
Collection* coll = db->getCollection( &txn, ns );
if ( !coll ) {
@@ -231,12 +240,13 @@ namespace ReplTests {
for( vector< DiskLoc >::iterator i = toDelete.begin(); i != toDelete.end(); ++i ) {
coll->deleteDocument( &txn, *i, true );
}
+ wunit.commit();
}
static void insert( const BSONObj &o ) {
OperationContextImpl txn;
Lock::GlobalWrite lk(txn.lockState());
Client::Context ctx(&txn, ns() );
-
+ WriteUnitOfWork wunit(txn.recoveryUnit());
Database* db = ctx.db();
Collection* coll = db->getCollection( &txn, ns() );
if ( !coll ) {
@@ -254,6 +264,7 @@ namespace ReplTests {
b.appendOID( "_id", &id );
b.appendElements( o );
coll->insertDocument( &txn, b.obj(), true );
+ wunit.commit();
}
static BSONObj wid( const char *json ) {
class BSONObjBuilder b;
diff --git a/src/mongo/dbtests/runner_registry.cpp b/src/mongo/dbtests/runner_registry.cpp
index b7c5981a27f..a6c2b4dfac6 100644
--- a/src/mongo/dbtests/runner_registry.cpp
+++ b/src/mongo/dbtests/runner_registry.cpp
@@ -60,6 +60,12 @@ namespace RunnerRegistry {
}
}
+ ~RunnerRegistryBase() {
+ if (_ctx.get()) {
+ _ctx->commit();
+ }
+ }
+
/**
* Return a runner that is going over the collection in ns().
*/
@@ -270,6 +276,7 @@ namespace RunnerRegistry {
// Drop a DB that's not ours. We can't have a lock at all to do this as dropping a DB
// requires a "global write lock."
+ _ctx->commit();
_ctx.reset();
_client.dropDatabase("somesillydb");
_ctx.reset(new Client::WriteContext(&_opCtx, ns()));
@@ -286,6 +293,7 @@ namespace RunnerRegistry {
registerRunner(run.get());
// Drop our DB. Once again, must give up the lock.
+ _ctx->commit();
_ctx.reset();
_client.dropDatabase("unittests");
_ctx.reset(new Client::WriteContext(&_opCtx, ns()));
@@ -293,6 +301,8 @@ namespace RunnerRegistry {
// Unregister and restore state.
deregisterRunner(run.get());
run->restoreState(&_opCtx);
+ _ctx->commit();
+ _ctx.reset();
// Runner was killed.
ASSERT_EQUALS(Runner::RUNNER_DEAD, run->getNext(&obj, NULL));
diff --git a/src/mongo/dbtests/threadedtests.cpp b/src/mongo/dbtests/threadedtests.cpp
index 0e36df8f43f..8c6f5d7c2fa 100644
--- a/src/mongo/dbtests/threadedtests.cpp
+++ b/src/mongo/dbtests/threadedtests.cpp
@@ -220,6 +220,7 @@ namespace ThreadedTests {
}
{
Lock::DBWrite x(&lockState, "local");
+ // No actual writing here, so no WriteUnitOfWork
if( sometimes ) {
Lock::TempRelease t(&lockState);
}
diff --git a/src/mongo/s/d_migrate.cpp b/src/mongo/s/d_migrate.cpp
index 47facbfc02a..fef22237850 100644
--- a/src/mongo/s/d_migrate.cpp
+++ b/src/mongo/s/d_migrate.cpp
@@ -1671,6 +1671,7 @@ namespace mongo {
db->createCollection( txn, ns );
}
}
+ ctx.commit();
}
{
@@ -1710,6 +1711,7 @@ namespace mongo {
// make sure to create index on secondaries as well
repl::logOp(txn, "i", db->getSystemIndexesName().c_str(), idx,
NULL, NULL, true /* fromMigrate */);
+ ctx.commit();
}
timing.done(1);
@@ -1809,6 +1811,7 @@ namespace mongo {
}
Helpers::upsert( txn, ns, o, true );
+ cx.commit();
}
thisTime++;
numCloned++;
@@ -2046,6 +2049,7 @@ namespace mongo {
true ); /*fromMigrate*/
*lastOpApplied = cx.ctx().getClient()->getLastOp().asDate();
+ cx.commit();
didAnything = true;
}
}
@@ -2075,6 +2079,7 @@ namespace mongo {
Helpers::upsert( txn, ns , it , true );
*lastOpApplied = cx.ctx().getClient()->getLastOp().asDate();
+ cx.commit();
didAnything = true;
}
}
diff --git a/src/mongo/tools/dump.cpp b/src/mongo/tools/dump.cpp
index c4aab6b1bf4..ba3ff655092 100644
--- a/src/mongo/tools/dump.cpp
+++ b/src/mongo/tools/dump.cpp
@@ -408,6 +408,7 @@ public:
toolError() << "ERROR recovering: " << ns << " " << e.toString() << std::endl;
}
}
+ cx.commit();
return 0;
}