summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorHari Khalsa <hkhalsa@10gen.com>2014-05-16 14:59:16 -0400
committerHari Khalsa <hkhalsa@10gen.com>2014-05-16 17:23:21 -0400
commit99bd567db407a89fda29bd83f46c0b72c6f775e3 (patch)
tree4965067fbdb513ee2bcb75dfe986024cd4cc2545 /src/mongo/db
parent33e3abd0c81e2cb70f5b8159818dc1ec685d7b34 (diff)
downloadmongo-99bd567db407a89fda29bd83f46c0b72c6f775e3.tar.gz
SERVER-13931 do some killCurrentOp cleanup
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/catalog/index_create.cpp4
-rw-r--r--src/mongo/db/client.cpp7
-rw-r--r--src/mongo/db/client.h9
-rw-r--r--src/mongo/db/commands/get_last_error.cpp2
-rw-r--r--src/mongo/db/commands/test_commands.cpp2
-rw-r--r--src/mongo/db/commands/write_commands/batch_executor.cpp4
-rw-r--r--src/mongo/db/dbcommands.cpp2
-rw-r--r--src/mongo/db/extsort.cpp18
-rw-r--r--src/mongo/db/extsort.h10
-rw-r--r--src/mongo/db/index/btree_based_bulk_access_method.cpp4
-rw-r--r--src/mongo/db/instance.cpp3
-rw-r--r--src/mongo/db/kill_current_op.cpp24
-rw-r--r--src/mongo/db/kill_current_op.h8
-rw-r--r--src/mongo/db/operation_context_noop.h65
-rw-r--r--src/mongo/db/query/new_find.cpp14
-rw-r--r--src/mongo/db/query/new_find.h10
-rw-r--r--src/mongo/db/storage/mmap_v1/dur.cpp6
-rw-r--r--src/mongo/db/storage/mmap_v1/dur_commitjob.cpp2
-rw-r--r--src/mongo/db/storage/mmap_v1/dur_recovery_unit.cpp10
-rw-r--r--src/mongo/db/storage/mmap_v1/dur_recovery_unit.h9
-rw-r--r--src/mongo/db/storage/recovery_unit.h5
-rw-r--r--src/mongo/db/storage/recovery_unit_noop.h56
-rw-r--r--src/mongo/db/structure/collection_compact.cpp2
-rw-r--r--src/mongo/db/structure/record_store_v1_capped_test.cpp21
-rw-r--r--src/mongo/db/structure/record_store_v1_simple_test.cpp35
-rw-r--r--src/mongo/db/structure/record_store_v1_test_help.cpp38
-rw-r--r--src/mongo/db/structure/record_store_v1_test_help.h40
-rw-r--r--src/mongo/db/write_concern.cpp11
-rw-r--r--src/mongo/db/write_concern.h5
29 files changed, 232 insertions, 194 deletions
diff --git a/src/mongo/db/catalog/index_create.cpp b/src/mongo/db/catalog/index_create.cpp
index b62d9d1f849..e28bc4b7ec3 100644
--- a/src/mongo/db/catalog/index_create.cpp
+++ b/src/mongo/db/catalog/index_create.cpp
@@ -162,7 +162,7 @@ namespace mongo {
n++;
progress.hit();
- getDur().commitIfNeeded();
+ txn->recoveryUnit()->commitIfNeeded();
if (canBeKilled) {
// Checking for interrupt here is necessary because the bg index
@@ -278,7 +278,7 @@ namespace mongo {
logOp( txn, "d", ns.c_str(), toDelete );
}
- getDur().commitIfNeeded();
+ txn->recoveryUnit()->commitIfNeeded();
RARELY if ( mayInterrupt ) {
txn->checkForInterrupt();
diff --git a/src/mongo/db/client.cpp b/src/mongo/db/client.cpp
index b9505375194..eb28db87eb8 100644
--- a/src/mongo/db/client.cpp
+++ b/src/mongo/db/client.cpp
@@ -102,7 +102,6 @@ namespace mongo {
_god(0),
_lastOp(0)
{
- _hasWrittenThisOperation = false;
_hasWrittenSinceCheckpoint = false;
_connectionId = p ? p->connectionId() : 0;
_curOp = new CurOp( this );
@@ -421,12 +420,6 @@ namespace mongo {
time = min( time , 1000000 );
- // if there has been a kill request for this op - we should yield to allow the op to stop
- // This function returns empty string if we aren't interrupted
- if ( *killCurrentOp.checkForInterruptNoAssert() ) {
- return 100;
- }
-
return time;
}
diff --git a/src/mongo/db/client.h b/src/mongo/db/client.h
index bb4951b69fb..af634f1e13b 100644
--- a/src/mongo/db/client.h
+++ b/src/mongo/db/client.h
@@ -108,12 +108,14 @@ namespace mongo {
BSONObj getHandshake() const { return _handshake; }
ConnectionId getConnectionId() const { return _connectionId; }
- void writeHappened() { _hasWrittenSinceCheckpoint = true; _hasWrittenThisOperation = true; }
+ // XXX(hk): this is per-thread mmapv1 recovery unit stuff, move into that
+ // impl of recovery unit
+ void writeHappened() { _hasWrittenSinceCheckpoint = true; }
bool hasWrittenSinceCheckpoint() const { return _hasWrittenSinceCheckpoint; }
void checkpointHappened() { _hasWrittenSinceCheckpoint = false; }
- bool hasWrittenThisOperation() const { return _hasWrittenThisOperation; }
+
+ // XXX: this is really a method in the recovery unit iface to reset any state
void newTopLevelRequest() {
- _hasWrittenThisOperation = false;
_hasWrittenSinceCheckpoint = false;
}
@@ -133,7 +135,6 @@ namespace mongo {
BSONObj _handshake;
BSONObj _remoteId;
- bool _hasWrittenThisOperation;
bool _hasWrittenSinceCheckpoint;
LockState _ls;
diff --git a/src/mongo/db/commands/get_last_error.cpp b/src/mongo/db/commands/get_last_error.cpp
index 31005f5e1fb..30aaede898b 100644
--- a/src/mongo/db/commands/get_last_error.cpp
+++ b/src/mongo/db/commands/get_last_error.cpp
@@ -232,7 +232,7 @@ namespace mongo {
cc().curop()->setMessage( "waiting for write concern" );
WriteConcernResult wcResult;
- status = waitForWriteConcern( writeConcern, lastOpTime, &wcResult );
+ status = waitForWriteConcern( txn, writeConcern, lastOpTime, &wcResult );
wcResult.appendTo( writeConcern, &result );
// For backward compatibility with 2.4, wtimeout returns ok : 1.0
diff --git a/src/mongo/db/commands/test_commands.cpp b/src/mongo/db/commands/test_commands.cpp
index a257aa1d335..91364dbba3a 100644
--- a/src/mongo/db/commands/test_commands.cpp
+++ b/src/mongo/db/commands/test_commands.cpp
@@ -117,7 +117,7 @@ namespace mongo {
}
// Interrupt point for testing (e.g. maxTimeMS).
- killCurrentOp.checkForInterrupt();
+ txn->checkForInterrupt();
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 8dfc371634e..8d56a43d647 100644
--- a/src/mongo/db/commands/write_commands/batch_executor.cpp
+++ b/src/mongo/db/commands/write_commands/batch_executor.cpp
@@ -258,7 +258,7 @@ namespace mongo {
_client->curop()->setMessage( "waiting for write concern" );
WriteConcernResult res;
- Status status = waitForWriteConcern( writeConcern, _client->getLastOp(), &res );
+ Status status = waitForWriteConcern( _txn, writeConcern, _client->getLastOp(), &res );
if ( !status.isOK() ) {
wcError.reset( toWriteConcernError( status, res ) );
@@ -820,7 +820,7 @@ namespace mongo {
if (elapsedTracker.intervalHasElapsed()) {
// Consider yielding between inserts.
- killCurrentOp.checkForInterrupt();
+ _txn->checkForInterrupt();
elapsedTracker.resetLastTime();
}
diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp
index a6c5444614a..126866dc82b 100644
--- a/src/mongo/db/dbcommands.cpp
+++ b/src/mongo/db/dbcommands.cpp
@@ -1568,7 +1568,7 @@ namespace mongo {
client.curop()->setMaxTimeMicros(static_cast<unsigned long long>(maxTimeMS.getValue())
* 1000);
try {
- killCurrentOp.checkForInterrupt(); // May trigger maxTimeAlwaysTimeOut fail point.
+ txn->checkForInterrupt(); // May trigger maxTimeAlwaysTimeOut fail point.
}
catch (UserException& e) {
appendCommandStatus(result, e.toStatus());
diff --git a/src/mongo/db/extsort.cpp b/src/mongo/db/extsort.cpp
index a25888c692e..5baaf6716e5 100644
--- a/src/mongo/db/extsort.cpp
+++ b/src/mongo/db/extsort.cpp
@@ -32,7 +32,6 @@
#include "mongo/db/extsort.h"
-#include "mongo/db/kill_current_op.h"
#include "mongo/db/storage_options.h"
namespace mongo {
@@ -42,34 +41,25 @@ namespace mongo {
public:
typedef pair<BSONObj, DiskLoc> Data;
- ComparatorWithInterruptCheck(const ExternalSortComparison* comp,
- boost::shared_ptr<const bool> mayInterrupt)
- : _comp(comp)
- , _mayInterrupt(mayInterrupt)
- {}
+ ComparatorWithInterruptCheck(const ExternalSortComparison* comp)
+ : _comp(comp) { }
int operator() (const Data& l, const Data& r) const {
- RARELY if (*_mayInterrupt) {
- killCurrentOp.checkForInterrupt(!*_mayInterrupt);
- }
-
return _comp->compare(l, r);
}
private:
const ExternalSortComparison* _comp;
- boost::shared_ptr<const bool> _mayInterrupt;
};
}
BSONObjExternalSorter::BSONObjExternalSorter(const ExternalSortComparison* comp,
long maxFileSize)
- : _mayInterrupt(boost::make_shared<bool>(false))
- , _sorter(Sorter<BSONObj, DiskLoc>::make(
+ : _sorter(Sorter<BSONObj, DiskLoc>::make(
SortOptions().TempDir(storageGlobalParams.dbpath + "/_tmp")
.ExtSortAllowed()
.MaxMemoryUsageBytes(maxFileSize),
- ComparatorWithInterruptCheck(comp, _mayInterrupt)))
+ ComparatorWithInterruptCheck(comp)))
{}
}
diff --git a/src/mongo/db/extsort.h b/src/mongo/db/extsort.h
index 73a3f35f06a..76c032bf21d 100644
--- a/src/mongo/db/extsort.h
+++ b/src/mongo/db/extsort.h
@@ -56,20 +56,22 @@ namespace mongo {
BSONObjExternalSorter(const ExternalSortComparison* comp, long maxFileSize=100*1024*1024);
- void add( const BSONObj& o, const DiskLoc& loc, bool mayInterrupt ) {
- *_mayInterrupt = mayInterrupt;
+ void add( const BSONObj& o, const DiskLoc& loc ) {
_sorter->add(o.getOwned(), loc);
}
auto_ptr<Iterator> iterator() { return auto_ptr<Iterator>(_sorter->done()); }
- void sort( bool mayInterrupt ) { *_mayInterrupt = mayInterrupt; }
+ // XXX: do we need this
+ void sort() { }
+
int numFiles() { return _sorter->numFiles(); }
+
long getCurSizeSoFar() { return _sorter->memUsed(); }
+
void hintNumObjects(long long) {} // unused
private:
- shared_ptr<bool> _mayInterrupt;
scoped_ptr<Sorter<BSONObj, DiskLoc> > _sorter;
};
}
diff --git a/src/mongo/db/index/btree_based_bulk_access_method.cpp b/src/mongo/db/index/btree_based_bulk_access_method.cpp
index 09af9df2ee1..5d2f0906564 100644
--- a/src/mongo/db/index/btree_based_bulk_access_method.cpp
+++ b/src/mongo/db/index/btree_based_bulk_access_method.cpp
@@ -120,7 +120,7 @@ namespace mongo {
for (BSONObjSet::iterator it = keys.begin(); it != keys.end(); ++it) {
// False is for mayInterrupt.
- _sorter->add(*it, loc, false);
+ _sorter->add(*it, loc);
_keysInserted++;
}
@@ -147,7 +147,7 @@ namespace mongo {
_real->_btreeState->setMultikey( _txn );
}
- _sorter->sort(false);
+ _sorter->sort();
Timer timer;
IndexCatalogEntry* entry = _real->_btreeState;
diff --git a/src/mongo/db/instance.cpp b/src/mongo/db/instance.cpp
index ab0a7ca7531..b0f38faa22b 100644
--- a/src/mongo/db/instance.cpp
+++ b/src/mongo/db/instance.cpp
@@ -701,7 +701,8 @@ namespace mongo {
}
}
- msgdata = newGetMore(ns,
+ msgdata = newGetMore(txn,
+ ns,
ntoreturn,
cursorid,
curop,
diff --git a/src/mongo/db/kill_current_op.cpp b/src/mongo/db/kill_current_op.cpp
index ed38bc175a8..7ec7888045f 100644
--- a/src/mongo/db/kill_current_op.cpp
+++ b/src/mongo/db/kill_current_op.cpp
@@ -74,29 +74,6 @@ namespace mongo {
return _killImpl_inclientlock(i);
}
- void KillCurrentOp::blockingKill(AtomicUInt opId) {
- bool killed = false;
- LOG(1) << "KillCurrentOp: starting blockingkill" << endl;
-
- boost::scoped_ptr<scoped_lock> clientLock( new scoped_lock( Client::clientsMutex ) );
- boost::unique_lock<boost::mutex> lck(_mtx);
-
- bool foundId = _killImpl_inclientlock(opId, &killed);
- if (!foundId) {
- // don't wait if not found
- return;
- }
-
- clientLock.reset( NULL ); // unlock client since we don't need it anymore
-
- // block until the killed operation stops
- LOG(1) << "KillCurrentOp: waiting for confirmation of kill" << endl;
- while (killed == false) {
- _condvar.wait(lck);
- }
- LOG(1) << "KillCurrentOp: kill syncing complete" << endl;
- }
-
bool KillCurrentOp::_killImpl_inclientlock(AtomicUInt i, bool* pNotifyFlag /* = NULL */) {
bool found = false;
{
@@ -129,7 +106,6 @@ namespace mongo {
if (!haveClient())
return;
cc().curop()->setKillWaiterFlags();
- _condvar.notify_all();
}
namespace {
diff --git a/src/mongo/db/kill_current_op.h b/src/mongo/db/kill_current_op.h
index 4fd31ab3f7b..5f1db6a6271 100644
--- a/src/mongo/db/kill_current_op.h
+++ b/src/mongo/db/kill_current_op.h
@@ -53,13 +53,6 @@ namespace mongo {
* @return if operation was found
**/
bool kill(AtomicUInt i);
-
- /**
- * blocks until kill is acknowledged by the killee.
- *
- * Note: Does not wait for nested ops, only the top level op.
- */
- void blockingKill(AtomicUInt opId);
/** @return true if global interrupt and should terminate the operation */
bool globalInterruptCheck() const { return _globalKill; }
@@ -83,7 +76,6 @@ namespace mongo {
private:
void interruptJs( AtomicUInt *op );
volatile bool _globalKill;
- boost::condition _condvar;
boost::mutex _mtx;
/**
diff --git a/src/mongo/db/operation_context_noop.h b/src/mongo/db/operation_context_noop.h
new file mode 100644
index 00000000000..de5832215a7
--- /dev/null
+++ b/src/mongo/db/operation_context_noop.h
@@ -0,0 +1,65 @@
+/**
+ * Copyright (C) 2014 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.
+ */
+
+#include "mongo/db/operation_context.h"
+
+#include "mongo/db/storage/recovery_unit_noop.h"
+
+namespace mongo {
+
+ class OperationContextNoop : public OperationContext {
+ public:
+ OperationContextNoop() {
+ _recoveryUnit.reset(new RecoveryUnitNoop());
+ }
+
+ virtual ~OperationContextNoop() { }
+
+ virtual RecoveryUnit* recoveryUnit() const {
+ return _recoveryUnit.get();
+ }
+
+ virtual ProgressMeter* setMessage(const char* msg,
+ const std::string& name ,
+ unsigned long long progressMeterTotal,
+ int secondsBetween) {
+ invariant(false);
+ return NULL;
+ }
+
+ virtual void checkForInterrupt(bool heedMutex = true) const { }
+
+ virtual Status checkForInterruptNoAssert() const {
+ return Status::OK();
+ }
+
+ private:
+ boost::scoped_ptr<RecoveryUnitNoop> _recoveryUnit;
+ };
+
+} // namespace mongo
diff --git a/src/mongo/db/query/new_find.cpp b/src/mongo/db/query/new_find.cpp
index 51ce8036664..ce892370ac3 100644
--- a/src/mongo/db/query/new_find.cpp
+++ b/src/mongo/db/query/new_find.cpp
@@ -141,8 +141,14 @@ namespace mongo {
* when this method returns an empty result, incrementing pass on each call.
* Thus, pass == 0 indicates this is the first "attempt" before any 'awaiting'.
*/
- QueryResult* newGetMore(const char* ns, int ntoreturn, long long cursorid, CurOp& curop,
- int pass, bool& exhaust, bool* isCursorAuthorized) {
+ QueryResult* newGetMore(OperationContext* txn,
+ const char* ns,
+ int ntoreturn,
+ long long cursorid,
+ CurOp& curop,
+ int pass,
+ bool& exhaust,
+ bool* isCursorAuthorized) {
exhaust = false;
// This is a read lock.
@@ -192,7 +198,7 @@ namespace mongo {
// If the operation that spawned this cursor had a time limit set, apply leftover
// time to this getmore.
curop.setMaxTimeMicros(cc->getLeftoverMaxTimeMicros());
- killCurrentOp.checkForInterrupt(); // May trigger maxTimeAlwaysTimeOut fail point.
+ txn->checkForInterrupt(); // May trigger maxTimeAlwaysTimeOut fail point.
if (0 == pass) {
cc->updateSlaveLocation(curop);
@@ -516,7 +522,7 @@ namespace mongo {
// Handle query option $maxTimeMS (not used with commands).
curop.setMaxTimeMicros(static_cast<unsigned long long>(pq.getMaxTimeMS()) * 1000);
- killCurrentOp.checkForInterrupt(); // May trigger maxTimeAlwaysTimeOut fail point.
+ txn->checkForInterrupt(); // May trigger maxTimeAlwaysTimeOut fail point.
// uassert if we are not on a primary, and not a secondary with SlaveOk query parameter set.
replVerifyReadsOk(cq->ns(), &pq);
diff --git a/src/mongo/db/query/new_find.h b/src/mongo/db/query/new_find.h
index 263bf77065d..6050d90d633 100644
--- a/src/mongo/db/query/new_find.h
+++ b/src/mongo/db/query/new_find.h
@@ -44,8 +44,14 @@ namespace mongo {
/**
* Called from the getMore entry point in ops/query.cpp.
*/
- QueryResult* newGetMore(const char* ns, int ntoreturn, long long cursorid, CurOp& curop,
- int pass, bool& exhaust, bool* isCursorAuthorized);
+ QueryResult* newGetMore(OperationContext* txn,
+ const char* ns,
+ int ntoreturn,
+ long long cursorid,
+ CurOp& curop,
+ int pass,
+ bool& exhaust,
+ bool* isCursorAuthorized);
/**
* Run the query 'q' and place the result in 'result'.
diff --git a/src/mongo/db/storage/mmap_v1/dur.cpp b/src/mongo/db/storage/mmap_v1/dur.cpp
index 8b89e7b8c26..0445db976eb 100644
--- a/src/mongo/db/storage/mmap_v1/dur.cpp
+++ b/src/mongo/db/storage/mmap_v1/dur.cpp
@@ -186,21 +186,19 @@ namespace mongo {
}
void* NonDurableImpl::writingPtr(void *x, unsigned len) {
- cc().writeHappened();
return x;
}
void NonDurableImpl::declareWriteIntent(void *, unsigned) {
- cc().writeHappened();
}
bool NonDurableImpl::commitNow() {
- cc().checkpointHappened();
+ cc().checkpointHappened(); // XXX: remove when all dur goes through DurRecoveryUnit
return false;
}
bool NonDurableImpl::commitIfNeeded(bool) {
- cc().checkpointHappened();
+ cc().checkpointHappened(); // XXX: remove when all dur goes through DurRecoveryUnit
return false;
}
diff --git a/src/mongo/db/storage/mmap_v1/dur_commitjob.cpp b/src/mongo/db/storage/mmap_v1/dur_commitjob.cpp
index 8994b3f7d32..63f7906c27f 100644
--- a/src/mongo/db/storage/mmap_v1/dur_commitjob.cpp
+++ b/src/mongo/db/storage/mmap_v1/dur_commitjob.cpp
@@ -139,7 +139,6 @@ namespace mongo {
/** we batch up our write intents so that we do not have to synchronize too often */
void DurableImpl::declareWriteIntent(void *p, unsigned len) {
dassert( Lock::somethingWriteLocked() );
- cc().writeHappened();
MemoryMappedFile::makeWritable(p, len);
ThreadLocalIntents *t = tlIntents.getMake();
t->push(WriteIntent(p,len));
@@ -186,7 +185,6 @@ namespace mongo {
dassert(storageGlobalParams.dur);
// DurOp's are rare so it is ok to have the lock cost here
SimpleMutex::scoped_lock lk(groupCommitMutex);
- cc().writeHappened();
_hasWritten = true;
_intentsAndDurOps._durOps.push_back(p);
}
diff --git a/src/mongo/db/storage/mmap_v1/dur_recovery_unit.cpp b/src/mongo/db/storage/mmap_v1/dur_recovery_unit.cpp
index 7766a615365..20f61fd1c3e 100644
--- a/src/mongo/db/storage/mmap_v1/dur_recovery_unit.cpp
+++ b/src/mongo/db/storage/mmap_v1/dur_recovery_unit.cpp
@@ -32,7 +32,16 @@
namespace mongo {
+ DurRecoveryUnit::DurRecoveryUnit() {
+ _hasWrittenSinceCheckpoint = false;
+ }
+
+ bool DurRecoveryUnit::awaitCommit() {
+ return getDur().awaitCommit();
+ }
+
bool DurRecoveryUnit::commitIfNeeded(bool force) {
+ _hasWrittenSinceCheckpoint = false;
return getDur().commitIfNeeded(force);
}
@@ -41,6 +50,7 @@ namespace mongo {
}
void* DurRecoveryUnit::writingPtr(void* data, size_t len) {
+ _hasWrittenSinceCheckpoint = true;
return getDur().writingPtr(data, len);
}
diff --git a/src/mongo/db/storage/mmap_v1/dur_recovery_unit.h b/src/mongo/db/storage/mmap_v1/dur_recovery_unit.h
index 3b6ce9f85d4..3715ba4468e 100644
--- a/src/mongo/db/storage/mmap_v1/dur_recovery_unit.h
+++ b/src/mongo/db/storage/mmap_v1/dur_recovery_unit.h
@@ -39,10 +39,12 @@ namespace mongo {
*/
class DurRecoveryUnit : public RecoveryUnit {
public:
- DurRecoveryUnit() { }
+ DurRecoveryUnit();
virtual ~DurRecoveryUnit() { }
+ virtual bool awaitCommit();
+
virtual bool commitIfNeeded(bool force = false);
virtual bool isCommitNeeded() const;
@@ -52,6 +54,11 @@ namespace mongo {
virtual void createdFile(const std::string& filename, unsigned long long len);
virtual void syncDataAndTruncateJournal();
+
+ private:
+ // XXX: this will be meaningful once killCurrentOp doesn't examine this bool's evil sibling
+ // in client.h. This requires killCurrentOp to go through OperationContext...
+ bool _hasWrittenSinceCheckpoint;
};
} // namespace mongo
diff --git a/src/mongo/db/storage/recovery_unit.h b/src/mongo/db/storage/recovery_unit.h
index 7a4506c1ad6..f089c6180b8 100644
--- a/src/mongo/db/storage/recovery_unit.h
+++ b/src/mongo/db/storage/recovery_unit.h
@@ -44,6 +44,11 @@ namespace mongo {
virtual ~RecoveryUnit() { }
/**
+ * XXX: document
+ */
+ virtual bool awaitCommit() = 0;
+
+ /**
* Commit if required. May take a long time. Returns true if committed.
*
* WARNING: Data *must* be in a crash-recoverable state when this is called.
diff --git a/src/mongo/db/storage/recovery_unit_noop.h b/src/mongo/db/storage/recovery_unit_noop.h
new file mode 100644
index 00000000000..d808c4d261c
--- /dev/null
+++ b/src/mongo/db/storage/recovery_unit_noop.h
@@ -0,0 +1,56 @@
+/**
+ * Copyright (C) 2014 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.
+ */
+
+#include "mongo/db/storage/recovery_unit.h"
+
+namespace mongo {
+
+ class RecoveryUnitNoop : public RecoveryUnit {
+ public:
+ virtual bool commitIfNeeded(bool force = false) {
+ return false;
+ }
+
+ virtual bool awaitCommit() {
+ return true;
+ }
+
+ virtual bool isCommitNeeded() const {
+ return false;
+ }
+
+ virtual void* writingPtr(void* data, size_t len) {
+ return data;
+ }
+
+ virtual void createdFile(const std::string& filename, unsigned long long len) { }
+
+ virtual void syncDataAndTruncateJournal() { }
+ };
+
+} // namespace mongo
diff --git a/src/mongo/db/structure/collection_compact.cpp b/src/mongo/db/structure/collection_compact.cpp
index 2777d51918e..903ef8aa184 100644
--- a/src/mongo/db/structure/collection_compact.cpp
+++ b/src/mongo/db/structure/collection_compact.cpp
@@ -148,7 +148,7 @@ namespace mongo {
return StatusWith<CompactStats>( status );
}
- killCurrentOp.checkForInterrupt();
+ txn->checkForInterrupt();
CompactStats stats;
diff --git a/src/mongo/db/structure/record_store_v1_capped_test.cpp b/src/mongo/db/structure/record_store_v1_capped_test.cpp
index a1b4ab6e2e7..d1f4fa709e4 100644
--- a/src/mongo/db/structure/record_store_v1_capped_test.cpp
+++ b/src/mongo/db/structure/record_store_v1_capped_test.cpp
@@ -30,6 +30,7 @@
#include "mongo/db/structure/record_store_v1_capped.h"
+#include "mongo/db/operation_context_noop.h"
#include "mongo/db/storage/record.h"
#include "mongo/db/structure/record_store_v1_test_help.h"
#include "mongo/unittest/unittest.h"
@@ -53,7 +54,7 @@ namespace {
void simpleInsertTest( const char* buf, int size ) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( true, 0 );
DummyCappedDocumentDeleteCallback cb;
@@ -96,7 +97,7 @@ namespace {
}
TEST(CappedRecordStoreV1, EmptySingleExtent) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( true, 0 );
DummyCappedDocumentDeleteCallback cb;
@@ -133,7 +134,7 @@ namespace {
}
TEST(CappedRecordStoreV1, FirstLoopWithSingleExtentExactSize) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( true, 0 );
DummyCappedDocumentDeleteCallback cb;
@@ -179,7 +180,7 @@ namespace {
}
TEST(CappedRecordStoreV1, NonFirstLoopWithSingleExtentExactSize) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( true, 0 );
DummyCappedDocumentDeleteCallback cb;
@@ -228,7 +229,7 @@ namespace {
* Current code always tries to leave 24 bytes to create a DeletedRecord.
*/
TEST(CappedRecordStoreV1, WillLoopWithout24SpareBytes) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( true, 0 );
DummyCappedDocumentDeleteCallback cb;
@@ -274,7 +275,7 @@ namespace {
}
TEST(CappedRecordStoreV1, WontLoopWith24SpareBytes) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( true, 0 );
DummyCappedDocumentDeleteCallback cb;
@@ -321,7 +322,7 @@ namespace {
}
TEST(CappedRecordStoreV1, MoveToSecondExtentUnLooped) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( true, 0 );
DummyCappedDocumentDeleteCallback cb;
@@ -368,7 +369,7 @@ namespace {
}
TEST(CappedRecordStoreV1, MoveToSecondExtentLooped) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( true, 0 );
DummyCappedDocumentDeleteCallback cb;
@@ -428,7 +429,7 @@ namespace {
* This is a minimal example that shows the current allocator laying out records out-of-order.
*/
TEST(CappedRecordStoreV1Scrambler, Minimal) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( true, 0 );
DummyCappedDocumentDeleteCallback cb;
@@ -478,7 +479,7 @@ namespace {
* that leaves 4 deleted records in a single extent.
*/
TEST(CappedRecordStoreV1Scrambler, FourDeletedRecordsInSingleExtent) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( true, 0 );
DummyCappedDocumentDeleteCallback cb;
diff --git a/src/mongo/db/structure/record_store_v1_simple_test.cpp b/src/mongo/db/structure/record_store_v1_simple_test.cpp
index dfee65f5662..ec518b6b9c9 100644
--- a/src/mongo/db/structure/record_store_v1_simple_test.cpp
+++ b/src/mongo/db/structure/record_store_v1_simple_test.cpp
@@ -30,6 +30,7 @@
#include "mongo/db/structure/record_store_v1_simple.h"
+#include "mongo/db/operation_context_noop.h"
#include "mongo/db/storage/record.h"
#include "mongo/db/structure/record_store_v1_test_help.h"
#include "mongo/unittest/unittest.h"
@@ -151,7 +152,7 @@ namespace {
/** alloc() quantizes the requested size using quantizeAllocationSpace() rules. */
TEST(SimpleRecordStoreV1, AllocQuantized) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( false, 0 );
@@ -171,7 +172,7 @@ namespace {
* rules.
*/
TEST(SimpleRecordStoreV1, AllocIndexNamespaceNotQuantized) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( false, 0 );
@@ -189,7 +190,7 @@ namespace {
/** alloc() quantizes records in index collections to the nearest multiple of 4. */
TEST(SimpleRecordStoreV1, AllocIndexNamespaceSlightlyQuantized) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( false, 0 );
@@ -205,7 +206,7 @@ namespace {
/** alloc() returns a non quantized record larger than the requested size. */
TEST(SimpleRecordStoreV1, AllocUseNonQuantizedDeletedRecord) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( false, 0 );
SimpleRecordStoreV1 rs( &txn, "test.foo", md, &em, false );
@@ -236,7 +237,7 @@ namespace {
/** alloc() returns a non quantized record equal to the requested size. */
TEST(SimpleRecordStoreV1, AllocExactSizeNonQuantizedDeletedRecord) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( false, 0 );
SimpleRecordStoreV1 rs( &txn, "test.foo", md, &em, false );
@@ -270,7 +271,7 @@ namespace {
* too small to make a DeletedRecord.
*/
TEST(SimpleRecordStoreV1, AllocQuantizedWithExtra) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( false, 0 );
SimpleRecordStoreV1 rs( &txn, "test.foo", md, &em, false );
@@ -304,7 +305,7 @@ namespace {
* is large enough to form a new deleted record.
*/
TEST(SimpleRecordStoreV1, AllocQuantizedWithoutExtra) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( false, 0 );
SimpleRecordStoreV1 rs( &txn, "test.foo", md, &em, false );
@@ -342,7 +343,7 @@ namespace {
* if a quantized portion of the deleted record could be used instead.
*/
TEST(SimpleRecordStoreV1, AllocNotQuantizedNearDeletedSize) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( false, 0 );
SimpleRecordStoreV1 rs( &txn, "test.foo", md, &em, false );
@@ -377,7 +378,7 @@ namespace {
/** getRecordAllocationSize() returns its argument when the padding factor is 1.0. */
TEST(SimpleRecordStoreV1, GetRecordAllocationSizeNoPadding) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( false, 0 );
SimpleRecordStoreV1 rs( &txn, "test.foo", md, &em, false );
@@ -387,7 +388,7 @@ namespace {
/** getRecordAllocationSize() multiplies by a padding factor > 1.0. */
TEST(SimpleRecordStoreV1, GetRecordAllocationSizeWithPadding) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( false, 0 );
SimpleRecordStoreV1 rs( &txn, "test.foo", md, &em, false );
@@ -402,7 +403,7 @@ namespace {
* is set.
*/
TEST(SimpleRecordStoreV1, GetRecordAllocationSizePowerOf2) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData(
false,
@@ -417,7 +418,7 @@ namespace {
* is set, ignoring the padding factor.
*/
TEST(SimpleRecordStoreV1, GetRecordAllocationSizePowerOf2PaddingIgnored) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData(
false,
@@ -433,7 +434,7 @@ namespace {
// -----------------
TEST( SimpleRecordStoreV1, FullSimple1 ) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( false, 0 );
SimpleRecordStoreV1 rs( &txn,
@@ -457,7 +458,7 @@ namespace {
* Inserts take the first deleted record with the correct size.
*/
TEST( SimpleRecordStoreV1, InsertTakesFirstDeletedWithExactSize ) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( false, 0 );
SimpleRecordStoreV1 rs( &txn, "test.foo", md, &em, false );
@@ -506,7 +507,7 @@ namespace {
* WARNING: this test depends on magic numbers inside RSV1Simple::_allocFromExistingExtents.
*/
TEST( SimpleRecordStoreV1, InsertLooksForBetterMatchUpTo5Links ) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( false, 0 );
SimpleRecordStoreV1 rs( &txn, "test.foo", md, &em, false );
@@ -558,7 +559,7 @@ namespace {
* WARNING: this test depends on magic numbers inside RSV1Simple::_allocFromExistingExtents.
*/
TEST( SimpleRecordStoreV1, InsertLooksForMatchUpTo31Links ) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( false, 0 );
SimpleRecordStoreV1 rs( &txn, "test.foo", md, &em, false );
@@ -668,7 +669,7 @@ namespace {
* WARNING: this test depends on magic numbers inside RSV1Simple::_allocFromExistingExtents.
*/
TEST( SimpleRecordStoreV1, InsertLooksForMatchUpTo31LinksEvenIfFoundOversizedFit ) {
- DummyOperationContext txn;
+ OperationContextNoop txn;
DummyExtentManager em;
DummyRecordStoreV1MetaData* md = new DummyRecordStoreV1MetaData( false, 0 );
SimpleRecordStoreV1 rs( &txn, "test.foo", md, &em, false );
diff --git a/src/mongo/db/structure/record_store_v1_test_help.cpp b/src/mongo/db/structure/record_store_v1_test_help.cpp
index 1853ac3a622..cc2662ef498 100644
--- a/src/mongo/db/structure/record_store_v1_test_help.cpp
+++ b/src/mongo/db/structure/record_store_v1_test_help.cpp
@@ -41,44 +41,6 @@
namespace mongo {
- bool DummyRecoveryUnit::commitIfNeeded( bool force ) {
- return false;
- }
-
- bool DummyRecoveryUnit::isCommitNeeded() const {
- return false;
- }
-
- void* DummyRecoveryUnit::writingPtr(void* data, size_t len) {
- return data;
- }
-
- void DummyRecoveryUnit::createdFile(const std::string& filename, unsigned long long len) {
- }
-
- void DummyRecoveryUnit::syncDataAndTruncateJournal() {
- }
-
- DummyOperationContext::DummyOperationContext() {
- _recoveryUnit.reset(new DummyRecoveryUnit());
- }
-
- ProgressMeter* DummyOperationContext::setMessage(const char* msg,
- const std::string& name ,
- unsigned long long progressMeterTotal,
- int secondsBetween) {
- invariant( false );
- }
-
- void DummyOperationContext::checkForInterrupt(bool heedMutex ) const {
- }
-
- Status DummyOperationContext::checkForInterruptNoAssert() const {
- return Status::OK();
- }
-
- // -----------------------------------------
-
DummyRecordStoreV1MetaData::DummyRecordStoreV1MetaData( bool capped, int userFlags ) {
_dataSize = 0;
_numRecords = 0;
diff --git a/src/mongo/db/structure/record_store_v1_test_help.h b/src/mongo/db/structure/record_store_v1_test_help.h
index 164b6b8a0c1..2f33dbb5676 100644
--- a/src/mongo/db/structure/record_store_v1_test_help.h
+++ b/src/mongo/db/structure/record_store_v1_test_help.h
@@ -33,47 +33,10 @@
#include <vector>
#include "mongo/db/storage/extent_manager.h"
-#include "mongo/db/operation_context.h"
#include "mongo/db/structure/record_store_v1_base.h"
namespace mongo {
- class DummyRecoveryUnit : public RecoveryUnit {
- public:
- virtual bool commitIfNeeded(bool force = false);
-
- virtual bool isCommitNeeded() const;
-
- virtual void* writingPtr(void* data, size_t len);
-
- virtual void createdFile(const std::string& filename, unsigned long long len);
-
- virtual void syncDataAndTruncateJournal();
- };
-
- class DummyOperationContext : public OperationContext {
- public:
- DummyOperationContext();
-
- virtual ~DummyOperationContext() { }
-
- virtual RecoveryUnit* recoveryUnit() const {
- return _recoveryUnit.get();
- }
-
- virtual ProgressMeter* setMessage(const char* msg,
- const std::string& name ,
- unsigned long long progressMeterTotal,
- int secondsBetween);
-
- virtual void checkForInterrupt(bool heedMutex = true) const;
-
- virtual Status checkForInterruptNoAssert() const;
-
- private:
- boost::scoped_ptr<DummyRecoveryUnit> _recoveryUnit;
- };
-
class DummyRecordStoreV1MetaData : public RecordStoreV1MetaData {
public:
DummyRecordStoreV1MetaData( bool capped, int userFlags );
@@ -227,4 +190,5 @@ namespace mongo {
const LocAndSize* drecs,
const ExtentManager* em,
const DummyRecordStoreV1MetaData* md);
-}
+
+} // namespace mongo
diff --git a/src/mongo/db/write_concern.cpp b/src/mongo/db/write_concern.cpp
index b5529f6060f..ee09a8bd933 100644
--- a/src/mongo/db/write_concern.cpp
+++ b/src/mongo/db/write_concern.cpp
@@ -28,7 +28,7 @@
#include "mongo/base/counter.h"
#include "mongo/db/commands/server_status_metric.h"
-#include "mongo/db/kill_current_op.h"
+#include "mongo/db/operation_context.h"
#include "mongo/db/repl/is_master.h"
#include "mongo/db/repl/repl_settings.h"
#include "mongo/db/repl/write_concern.h"
@@ -124,7 +124,8 @@ namespace mongo {
}
}
- Status waitForWriteConcern( const WriteConcernOptions& writeConcern,
+ Status waitForWriteConcern( OperationContext* txn,
+ const WriteConcernOptions& writeConcern,
const OpTime& replOpTime,
WriteConcernResult* result ) {
@@ -144,11 +145,11 @@ namespace mongo {
}
else {
// We only need to commit the journal if we're durable
- getDur().awaitCommit();
+ txn->recoveryUnit()->awaitCommit();
}
break;
case WriteConcernOptions::JOURNAL:
- getDur().awaitCommit();
+ txn->recoveryUnit()->awaitCommit();
break;
}
@@ -207,7 +208,7 @@ namespace mongo {
}
sleepmillis(1);
- killCurrentOp.checkForInterrupt();
+ txn->checkForInterrupt();
}
}
catch( const AssertionException& ex ) {
diff --git a/src/mongo/db/write_concern.h b/src/mongo/db/write_concern.h
index c88404c1055..bfa31571a45 100644
--- a/src/mongo/db/write_concern.h
+++ b/src/mongo/db/write_concern.h
@@ -32,6 +32,8 @@
namespace mongo {
+ class OperationContext;
+
/**
* Verifies that a WriteConcern is valid for this particular host.
*/
@@ -74,7 +76,8 @@ namespace mongo {
* Returns NotMaster if the host steps down while waiting for replication
* Returns UnknownReplWriteConcern if the wMode specified was not enforceable
*/
- Status waitForWriteConcern( const WriteConcernOptions& writeConcern,
+ Status waitForWriteConcern( OperationContext* txn,
+ const WriteConcernOptions& writeConcern,
const OpTime& replOpTime,
WriteConcernResult* result );