summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeert Bosch <geert@mongodb.com>2016-02-01 10:01:27 -0500
committerRamon Fernandez <ramon@mongodb.com>2016-02-02 17:19:49 -0500
commit9e55fe2085f8627ae7791b8a4b55e0c6114feac3 (patch)
tree7727ee7a6c318444be3e8a82ea15bef4054c6d9c
parentdd1d0205b7e92947953c6846ee4642f662b8df88 (diff)
downloadmongo-9e55fe2085f8627ae7791b8a4b55e0c6114feac3.tar.gz
SERVER-22011: Obtain tickets at outermost global lock in WT
(cherry picked from commit 2969c83e3dcd4ca26e81b27454938e1c2aa7fe53)
-rw-r--r--jstests/noPassthrough/write_local.js47
-rw-r--r--src/mongo/db/concurrency/lock_state.cpp46
-rw-r--r--src/mongo/db/concurrency/lock_state.h2
-rw-r--r--src/mongo/db/concurrency/locker.h9
-rw-r--r--src/mongo/db/storage/wiredtiger/SConscript3
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp75
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h2
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp2
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_record_store_mongod.cpp1
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp107
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.h6
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_server_status.cpp2
12 files changed, 185 insertions, 117 deletions
diff --git a/jstests/noPassthrough/write_local.js b/jstests/noPassthrough/write_local.js
new file mode 100644
index 00000000000..66b50f968ca
--- /dev/null
+++ b/jstests/noPassthrough/write_local.js
@@ -0,0 +1,47 @@
+// SERVER-22011: Deadlock in ticket distribution
+(function() {
+ 'use strict'
+
+ // Limit concurrent WiredTiger transactions to maximize locking issues, harmless for other SEs.
+ var options = { verbose: 1 };
+
+ // Create a new single node replicaSet
+ var replTest = new ReplSetTest({ name: "write_local",
+ nodes: 1,
+ oplogSize: 1,
+ nodeOptions: options });
+ replTest.startSet();
+ replTest.initiate();
+ var mongod = replTest.getPrimary();
+ mongod.adminCommand({ setParameter: 1, wiredTigerConcurrentWriteTransactions: 1 });
+
+ var local = mongod.getDB('local');
+
+ // Start inserting documents in test.capped and local.capped capped collections.
+ var shells = ['test', 'local'].map(function(dbname){
+ var mydb = local.getSiblingDB(dbname);
+ mydb.capped.drop();
+ mydb.createCollection('capped', { capped: true, size: 20*1000 });
+ return startParallelShell(
+ 'var mydb=db.getSiblingDB("' + dbname + '"); ' +
+ '(function() { ' +
+ ' for(var i=0; i < 10*1000; i++) { ' +
+ ' mydb.capped.insert({ x: i }); ' +
+ ' } ' +
+ '})();', mongod.port);
+ });
+
+ // The following causes inconsistent locking order in the ticket system, depending on
+ // timeouts to avoid deadlock.
+ var oldObjects = 0;
+ for (var i = 0; i < 1000; i++) {
+ print(local.stats().objects);
+ sleep(1);
+ };
+
+ // Wait for parallel shells to terminate and stop our replset.
+ shells.forEach((function(f) {
+ f();
+ }));
+ replTest.stopSet();
+}())
diff --git a/src/mongo/db/concurrency/lock_state.cpp b/src/mongo/db/concurrency/lock_state.cpp
index ea2b9b9c63a..04512bce9bd 100644
--- a/src/mongo/db/concurrency/lock_state.cpp
+++ b/src/mongo/db/concurrency/lock_state.cpp
@@ -39,6 +39,7 @@
#include "mongo/platform/compiler.h"
#include "mongo/util/background.h"
#include "mongo/util/concurrency/synchronization.h"
+#include "mongo/util/concurrency/ticketholder.h"
#include "mongo/util/debug_util.h"
#include "mongo/util/log.h"
#include "mongo/util/mongoutils/str.h"
@@ -188,6 +189,7 @@ void LockerImpl<IsForMMAPV1>::assertEmptyAndReset() {
invariant(!inAWriteUnitOfWork());
invariant(_resourcesToUnlockAtEndOfUnitOfWork.empty());
invariant(_requests.empty());
+ invariant(_modeForTicket == MODE_NONE);
// Reset the locking statistics so the object can be reused
_stats.reset();
@@ -243,11 +245,38 @@ void CondVarLockGrantNotification::notify(ResourceId resId, LockResult result) {
_cond.notify_all();
}
+namespace {
+TicketHolder* ticketHolders[LockModesCount] = {};
+
+void acquireTicket(LockMode mode) {
+ auto holder = ticketHolders[mode];
+ if (holder) {
+ holder->waitForTicket();
+ }
+}
+
+void releaseTicket(LockMode* mode) {
+ invariant(*mode != MODE_NONE);
+ auto holder = ticketHolders[*mode];
+ *mode = MODE_NONE;
+ if (holder) {
+ holder->release();
+ }
+}
+} // namespace
+
//
// Locker
//
+/* static */
+void Locker::setGlobalThrottling(class TicketHolder* reading, class TicketHolder* writing) {
+ ticketHolders[MODE_S] = reading;
+ ticketHolders[MODE_IS] = reading;
+ ticketHolders[MODE_IX] = writing;
+}
+
template <bool IsForMMAPV1>
LockerImpl<IsForMMAPV1>::LockerImpl()
: _id(idCounter.addAndFetch(1)), _wuowNestingLevel(0), _batchWriter(false) {}
@@ -276,6 +305,11 @@ LockResult LockerImpl<IsForMMAPV1>::lockGlobal(LockMode mode, unsigned timeoutMs
template <bool IsForMMAPV1>
LockResult LockerImpl<IsForMMAPV1>::lockGlobalBegin(LockMode mode) {
+ dassert(isLocked() == (_modeForTicket != MODE_NONE));
+ if (_modeForTicket == MODE_NONE) {
+ acquireTicket(mode);
+ _modeForTicket = mode;
+ }
const LockResult result = lockBegin(resourceIdGlobal, mode);
if (result == LOCK_OK)
return LOCK_OK;
@@ -315,6 +349,10 @@ void LockerImpl<IsForMMAPV1>::downgradeGlobalXtoSForMMAPV1() {
LockRequest* globalLockRequest = _requests.find(resourceIdGlobal).objAddr();
invariant(globalLockRequest->mode == MODE_X);
invariant(globalLockRequest->recursiveCount == 1);
+ invariant(_modeForTicket == MODE_X);
+ // Note that this locker will not actually have a ticket (as MODE_X has no TicketHolder) or
+ // acquire one now, but at most a single thread can be in this downgraded MODE_S situation,
+ // so it's OK.
// Making this call here will record lock downgrades as acquisitions, which is acceptable
globalStats.recordAcquisition(_id, resourceIdGlobal, MODE_S);
@@ -561,6 +599,7 @@ bool LockerImpl<IsForMMAPV1>::saveLockStateAndUnlock(Locker::LockSnapshot* state
invariant(unlock(resId));
}
+ invariant(!isLocked());
// Sort locks by ResourceId. They'll later be acquired in this canonical locking order.
std::sort(stateOut->locks.begin(), stateOut->locks.end());
@@ -572,6 +611,7 @@ template <bool IsForMMAPV1>
void LockerImpl<IsForMMAPV1>::restoreLockState(const Locker::LockSnapshot& state) {
// We shouldn't be saving and restoring lock state from inside a WriteUnitOfWork.
invariant(!inAWriteUnitOfWork());
+ invariant(_modeForTicket == MODE_NONE);
std::vector<OneLock>::const_iterator it = state.locks.begin();
// If we locked the PBWM, it must be locked before the resourceIdGlobal resource.
@@ -590,6 +630,7 @@ void LockerImpl<IsForMMAPV1>::restoreLockState(const Locker::LockSnapshot& state
invariant(LOCK_OK == lock(it->resourceId, it->mode));
}
}
+ invariant(_modeForTicket != MODE_NONE);
}
template <bool IsForMMAPV1>
@@ -722,6 +763,8 @@ LockResult LockerImpl<IsForMMAPV1>::lockComplete(ResourceId resId,
if (result != LOCK_OK) {
LockRequestsMap::Iterator it = _requests.find(resId);
if (globalLockManager.unlock(it.objAddr())) {
+ if (resId == resourceIdGlobal)
+ releaseTicket(&_modeForTicket);
scoped_spinlock scopedLock(_lock);
it.remove();
}
@@ -744,6 +787,9 @@ bool LockerImpl<IsForMMAPV1>::_unlockImpl(LockRequestsMap::Iterator& it) {
}
if (globalLockManager.unlock(it.objAddr())) {
+ if (it.key() == resourceIdGlobal)
+ releaseTicket(&_modeForTicket);
+
scoped_spinlock scopedLock(_lock);
it.remove();
diff --git a/src/mongo/db/concurrency/lock_state.h b/src/mongo/db/concurrency/lock_state.h
index cf634fd3168..de19f38ae44 100644
--- a/src/mongo/db/concurrency/lock_state.h
+++ b/src/mongo/db/concurrency/lock_state.h
@@ -214,6 +214,8 @@ private:
int _wuowNestingLevel;
std::queue<ResourceId> _resourcesToUnlockAtEndOfUnitOfWork;
+ // Mode for which the Locker acquired a ticket, or MODE_NONE if no ticket was acquired.
+ LockMode _modeForTicket = MODE_NONE;
//////////////////////////////////////////////////////////////////////////////////////////
//
diff --git a/src/mongo/db/concurrency/locker.h b/src/mongo/db/concurrency/locker.h
index 7c19f421e5c..be9f3ea0730 100644
--- a/src/mongo/db/concurrency/locker.h
+++ b/src/mongo/db/concurrency/locker.h
@@ -48,6 +48,15 @@ class Locker {
public:
virtual ~Locker() {}
+ /**
+ * Require global lock attempts with obtain tickets from 'reading' (for MODE_S and MODE_IS),
+ * and from 'writing' (for MODE_IX), which must have static lifetimes. There is no throttling
+ * for MODE_X, as there can only ever be a single locker using this mode. The throttling is
+ * intended to defend against arge drops in throughput under high load due to too much
+ * concurrency.
+ */
+ static void setGlobalThrottling(class TicketHolder* reading, class TicketHolder* writing);
+
virtual LockerId getId() const = 0;
/**
diff --git a/src/mongo/db/storage/wiredtiger/SConscript b/src/mongo/db/storage/wiredtiger/SConscript
index 15a1aeb9003..26e4435c956 100644
--- a/src/mongo/db/storage/wiredtiger/SConscript
+++ b/src/mongo/db/storage/wiredtiger/SConscript
@@ -37,6 +37,7 @@ if wiredtiger:
'$BUILD_DIR/mongo/base',
'$BUILD_DIR/mongo/db/namespace_string',
'$BUILD_DIR/mongo/db/catalog/collection_options',
+ '$BUILD_DIR/mongo/db/concurrency/lock_manager',
'$BUILD_DIR/mongo/db/concurrency/write_conflict_exception',
'$BUILD_DIR/mongo/db/index/index_descriptor',
'$BUILD_DIR/mongo/db/service_context',
@@ -44,10 +45,10 @@ if wiredtiger:
'$BUILD_DIR/mongo/db/storage/key_string',
'$BUILD_DIR/mongo/db/storage/oplog_hack',
'$BUILD_DIR/mongo/db/storage/storage_options',
+ '$BUILD_DIR/mongo/util/concurrency/ticketholder',
'$BUILD_DIR/mongo/util/elapsed_tracker',
'$BUILD_DIR/mongo/util/foundation',
'$BUILD_DIR/mongo/util/processinfo',
- '$BUILD_DIR/mongo/util/concurrency/ticketholder',
'$BUILD_DIR/third_party/shim_wiredtiger',
'$BUILD_DIR/third_party/shim_snappy',
'$BUILD_DIR/third_party/shim_zlib',
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
index 5a9ab07b36a..8420434cf4e 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
@@ -42,10 +42,14 @@
#include <valgrind/valgrind.h>
#include "mongo/base/error_codes.h"
+#include "mongo/bson/bsonobjbuilder.h"
#include "mongo/db/catalog/collection_catalog_entry.h"
#include "mongo/db/client.h"
+#include "mongo/db/concurrency/locker.h"
#include "mongo/db/concurrency/write_conflict_exception.h"
+#include "mongo/db/commands/server_status_metric.h"
#include "mongo/db/index/index_descriptor.h"
+#include "mongo/db/server_parameters.h"
#include "mongo/db/service_context.h"
#include "mongo/db/storage/wiredtiger/wiredtiger_customization_hooks.h"
#include "mongo/db/storage/wiredtiger/wiredtiger_global_options.h"
@@ -58,6 +62,7 @@
#include "mongo/db/storage/storage_options.h"
#include "mongo/util/log.h"
#include "mongo/util/background.h"
+#include "mongo/util/concurrency/ticketholder.h"
#include "mongo/util/exit.h"
#include "mongo/util/processinfo.h"
#include "mongo/util/scopeguard.h"
@@ -113,6 +118,55 @@ private:
std::atomic<bool> _shuttingDown{false}; // NOLINT
};
+namespace {
+
+class TicketServerParameter : public ServerParameter {
+ MONGO_DISALLOW_COPYING(TicketServerParameter);
+
+public:
+ TicketServerParameter(TicketHolder* holder, const std::string& name)
+ : ServerParameter(ServerParameterSet::getGlobal(), name, true, true), _holder(holder) {}
+
+ virtual void append(OperationContext* txn, BSONObjBuilder& b, const std::string& name) {
+ b.append(name, _holder->outof());
+ }
+
+ virtual Status set(const BSONElement& newValueElement) {
+ if (!newValueElement.isNumber())
+ return Status(ErrorCodes::BadValue, str::stream() << name() << " has to be a number");
+ return _set(newValueElement.numberInt());
+ }
+
+ virtual Status setFromString(const std::string& str) {
+ int num = 0;
+ Status status = parseNumberFromString(str, &num);
+ if (!status.isOK())
+ return status;
+ return _set(num);
+ }
+
+ Status _set(int newNum) {
+ if (newNum <= 0) {
+ return Status(ErrorCodes::BadValue, str::stream() << name() << " has to be > 0");
+ }
+
+ return _holder->resize(newNum);
+ }
+
+private:
+ TicketHolder* _holder;
+};
+
+TicketHolder openWriteTransaction(128);
+TicketServerParameter openWriteTransactionParam(&openWriteTransaction,
+ "wiredTigerConcurrentWriteTransactions");
+
+TicketHolder openReadTransaction(128);
+TicketServerParameter openReadTransactionParam(&openReadTransaction,
+ "wiredTigerConcurrentReadTransactions");
+
+} // namespace
+
WiredTigerKVEngine::WiredTigerKVEngine(const std::string& canonicalName,
const std::string& path,
const std::string& extraOpenOptions,
@@ -208,6 +262,8 @@ WiredTigerKVEngine::WiredTigerKVEngine(const std::string& canonicalName,
_sizeStorer.reset(new WiredTigerSizeStorer(_conn, _sizeStorerUri));
_sizeStorer->fillCache();
}
+
+ Locker::setGlobalThrottling(&openReadTransaction, &openWriteTransaction);
}
@@ -219,6 +275,25 @@ WiredTigerKVEngine::~WiredTigerKVEngine() {
_sessionCache.reset(NULL);
}
+void WiredTigerKVEngine::appendGlobalStats(BSONObjBuilder& b) {
+ BSONObjBuilder bb(b.subobjStart("concurrentTransactions"));
+ {
+ BSONObjBuilder bbb(bb.subobjStart("write"));
+ bbb.append("out", openWriteTransaction.used());
+ bbb.append("available", openWriteTransaction.available());
+ bbb.append("totalTickets", openWriteTransaction.outof());
+ bbb.done();
+ }
+ {
+ BSONObjBuilder bbb(bb.subobjStart("read"));
+ bbb.append("out", openReadTransaction.used());
+ bbb.append("available", openReadTransaction.available());
+ bbb.append("totalTickets", openReadTransaction.outof());
+ bbb.done();
+ }
+ bb.done();
+}
+
void WiredTigerKVEngine::cleanShutdown() {
log() << "WiredTigerKVEngine shutting down";
syncSizeInfo(true);
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
index f17c060220f..bc0a5f71301 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
@@ -142,6 +142,8 @@ public:
*/
static bool initRsOplogBackgroundThread(StringData ns);
+ static void appendGlobalStats(BSONObjBuilder& b);
+
private:
class WiredTigerJournalFlusher;
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp
index a38a6fd517b..d37bc706093 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp
@@ -1062,7 +1062,6 @@ int64_t WiredTigerRecordStore::cappedDeleteAsNeeded_inlock(OperationContext* txn
OperationContext::RecoveryUnitState const realRUstate =
txn->setRecoveryUnit(new WiredTigerRecoveryUnit(sc), OperationContext::kNotInUnitOfWork);
- WiredTigerRecoveryUnit::get(txn)->markNoTicketRequired(); // realRecoveryUnit already has
WT_SESSION* session = WiredTigerRecoveryUnit::get(txn)->getSession(txn)->getSession();
int64_t dataSize = _dataSize.load();
@@ -1220,7 +1219,6 @@ void WiredTigerRecordStore::reclaimOplog(OperationContext* txn) {
<< " records totaling to " << stone->bytes << " bytes";
WiredTigerRecoveryUnit* ru = WiredTigerRecoveryUnit::get(txn);
- ru->markNoTicketRequired(); // No ticket is needed for internal operations.
WT_SESSION* session = ru->getSession(txn)->getSession();
try {
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_mongod.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_mongod.cpp
index 449714aca6e..ce089a38ce9 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_mongod.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_mongod.cpp
@@ -78,7 +78,6 @@ public:
}
OperationContextImpl txn;
- checked_cast<WiredTigerRecoveryUnit*>(txn.recoveryUnit())->markNoTicketRequired();
try {
ScopedTransaction transaction(&txn, MODE_IX);
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp
index 7d5d277e5c9..7a41d0d7341 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp
@@ -33,8 +33,6 @@
#include "mongo/base/checked_cast.h"
#include "mongo/base/init.h"
#include "mongo/bson/bsonobjbuilder.h"
-#include "mongo/db/commands/server_status_metric.h"
-#include "mongo/db/server_parameters.h"
#include "mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.h"
#include "mongo/db/storage/wiredtiger/wiredtiger_session_cache.h"
#include "mongo/db/storage/wiredtiger/wiredtiger_util.h"
@@ -53,8 +51,7 @@ WiredTigerRecoveryUnit::WiredTigerRecoveryUnit(WiredTigerSessionCache* sc)
_inUnitOfWork(false),
_active(false),
_myTransactionCount(1),
- _everStartedWrite(false),
- _noTicketNeeded(false) {}
+ _everStartedWrite(false) {}
WiredTigerRecoveryUnit::~WiredTigerRecoveryUnit() {
invariant(!_inUnitOfWork);
@@ -69,7 +66,6 @@ void WiredTigerRecoveryUnit::reportState(BSONObjBuilder* b) const {
b->append("wt_inUnitOfWork", _inUnitOfWork);
b->append("wt_active", _active);
b->append("wt_everStartedWrite", _everStartedWrite);
- b->append("wt_hasTicket", _ticket.hasTicket());
b->appendNumber("wt_myTransactionCount", static_cast<long long>(_myTransactionCount));
if (_active)
b->append("wt_millisSinceCommit", _timer.millis());
@@ -128,7 +124,6 @@ void WiredTigerRecoveryUnit::beginUnitOfWork(OperationContext* opCtx) {
invariant(!_inUnitOfWork);
_inUnitOfWork = true;
_everStartedWrite = true;
- _getTicket(opCtx);
}
void WiredTigerRecoveryUnit::commitUnitOfWork() {
@@ -205,74 +200,6 @@ void WiredTigerRecoveryUnit::setOplogReadTill(const RecordId& id) {
_oplogReadTill = id;
}
-namespace {
-
-class TicketServerParameter : public ServerParameter {
- MONGO_DISALLOW_COPYING(TicketServerParameter);
-
-public:
- TicketServerParameter(TicketHolder* holder, const std::string& name)
- : ServerParameter(ServerParameterSet::getGlobal(), name, true, true), _holder(holder) {}
-
- virtual void append(OperationContext* txn, BSONObjBuilder& b, const std::string& name) {
- b.append(name, _holder->outof());
- }
-
- virtual Status set(const BSONElement& newValueElement) {
- if (!newValueElement.isNumber())
- return Status(ErrorCodes::BadValue, str::stream() << name() << " has to be a number");
- return _set(newValueElement.numberInt());
- }
-
- virtual Status setFromString(const std::string& str) {
- int num = 0;
- Status status = parseNumberFromString(str, &num);
- if (!status.isOK())
- return status;
- return _set(num);
- }
-
- Status _set(int newNum) {
- if (newNum <= 0) {
- return Status(ErrorCodes::BadValue, str::stream() << name() << " has to be > 0");
- }
-
- return _holder->resize(newNum);
- }
-
-private:
- TicketHolder* _holder;
-};
-
-TicketHolder openWriteTransaction(128);
-TicketServerParameter openWriteTransactionParam(&openWriteTransaction,
- "wiredTigerConcurrentWriteTransactions");
-
-TicketHolder openReadTransaction(128);
-TicketServerParameter openReadTransactionParam(&openReadTransaction,
- "wiredTigerConcurrentReadTransactions");
-
-} // namespace
-
-void WiredTigerRecoveryUnit::appendGlobalStats(BSONObjBuilder& b) {
- BSONObjBuilder bb(b.subobjStart("concurrentTransactions"));
- {
- BSONObjBuilder bbb(bb.subobjStart("write"));
- bbb.append("out", openWriteTransaction.used());
- bbb.append("available", openWriteTransaction.available());
- bbb.append("totalTickets", openWriteTransaction.outof());
- bbb.done();
- }
- {
- BSONObjBuilder bbb(bb.subobjStart("read"));
- bbb.append("out", openReadTransaction.used());
- bbb.append("available", openReadTransaction.available());
- bbb.append("totalTickets", openReadTransaction.outof());
- bbb.done();
- }
- bb.done();
-}
-
void WiredTigerRecoveryUnit::_txnClose(bool commit) {
invariant(_active);
WT_SESSION* s = _session->getSession();
@@ -285,7 +212,6 @@ void WiredTigerRecoveryUnit::_txnClose(bool commit) {
}
_active = false;
_myTransactionCount++;
- _ticket.reset(NULL);
}
SnapshotId WiredTigerRecoveryUnit::getSnapshotId() const {
@@ -311,39 +237,8 @@ boost::optional<SnapshotName> WiredTigerRecoveryUnit::getMajorityCommittedSnapsh
return _majorityCommittedSnapshot;
}
-void WiredTigerRecoveryUnit::markNoTicketRequired() {
- invariant(!_ticket.hasTicket());
- _noTicketNeeded = true;
-}
-
-void WiredTigerRecoveryUnit::_getTicket(OperationContext* opCtx) {
- // already have a ticket
- if (_ticket.hasTicket())
- return;
-
- if (_noTicketNeeded)
- return;
-
- bool writeLocked;
-
- // If we have a strong lock, waiting for a ticket can cause a deadlock.
- if (opCtx != NULL && opCtx->lockState() != NULL) {
- if (opCtx->lockState()->hasStrongLocks())
- return;
- writeLocked = opCtx->lockState()->isWriteLocked();
- } else {
- writeLocked = _everStartedWrite;
- }
-
- TicketHolder* holder = writeLocked ? &openWriteTransaction : &openReadTransaction;
-
- holder->waitForTicket();
- _ticket.reset(holder);
-}
-
void WiredTigerRecoveryUnit::_txnOpen(OperationContext* opCtx) {
invariant(!_active);
- _getTicket(opCtx);
_ensureSession();
WT_SESSION* s = _session->getSession();
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.h b/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.h
index af9872fa96b..b70b4bebfea 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.h
@@ -107,8 +107,6 @@ public:
return _oplogReadTill;
}
- void markNoTicketRequired();
-
static WiredTigerRecoveryUnit* get(OperationContext* txn);
static void appendGlobalStats(BSONObjBuilder& b);
@@ -143,10 +141,6 @@ private:
typedef OwnedPointerVector<Change> Changes;
Changes _changes;
-
- bool _noTicketNeeded;
- void _getTicket(OperationContext* opCtx);
- TicketHolderReleaser _ticket;
};
/**
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_server_status.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_server_status.cpp
index fc62b8d84f9..4967dfc2f86 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_server_status.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_server_status.cpp
@@ -74,7 +74,7 @@ BSONObj WiredTigerServerStatusSection::generateSection(OperationContext* txn,
bob.append("reason", status.reason());
}
- WiredTigerRecoveryUnit::appendGlobalStats(bob);
+ WiredTigerKVEngine::appendGlobalStats(bob);
return bob.obj();
}