diff options
author | Hari Khalsa <hkhalsa@10gen.com> | 2014-05-16 14:59:16 -0400 |
---|---|---|
committer | Hari Khalsa <hkhalsa@10gen.com> | 2014-05-16 17:23:21 -0400 |
commit | 99bd567db407a89fda29bd83f46c0b72c6f775e3 (patch) | |
tree | 4965067fbdb513ee2bcb75dfe986024cd4cc2545 /src/mongo/db | |
parent | 33e3abd0c81e2cb70f5b8159818dc1ec685d7b34 (diff) | |
download | mongo-99bd567db407a89fda29bd83f46c0b72c6f775e3.tar.gz |
SERVER-13931 do some killCurrentOp cleanup
Diffstat (limited to 'src/mongo/db')
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 ); |