summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEliot Horowitz <eliot@10gen.com>2014-11-26 17:07:11 -0500
committerEliot Horowitz <eliot@10gen.com>2014-11-27 16:40:34 -0500
commitfe363010e4b2b953c9876608861c02df4c8662ec (patch)
tree469b805d555a32b6f27c1fcee80739e89d15c039 /src
parentd36eac67be457c8a4e11373b0332e2d8d54975e1 (diff)
downloadmongo-fe363010e4b2b953c9876608861c02df4c8662ec.tar.gz
SERVER-16119: faster WT shutdown race avoidance
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp7
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h6
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp39
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.h6
4 files changed, 30 insertions, 28 deletions
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
index 01e4e6bbaa9..0ad0d32e9bf 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
@@ -330,7 +330,7 @@ namespace mongo {
{
boost::mutex::scoped_lock lk( _identToDropMutex );
_identToDrop.insert( uri );
- _epoch++;
+ _epoch.fetchAndAdd(1);
}
_sessionCache->closeAll();
return false;
@@ -340,11 +340,14 @@ namespace mongo {
return false;
}
- bool WiredTigerKVEngine::haveDropsQueued() const {
+ void WiredTigerKVEngine::syncSizeInfoOccasionally() const {
if ( _sizeStorerSyncTracker.intervalHasElapsed() ) {
_sizeStorerSyncTracker.resetLastTime();
syncSizeInfo(false);
}
+ }
+
+ bool WiredTigerKVEngine::haveDropsQueued() const {
boost::mutex::scoped_lock lk( _identToDropMutex );
return !_identToDrop.empty();
}
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
index 0d2efc4cd44..04b030f51ad 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h
@@ -112,10 +112,12 @@ namespace mongo {
void dropAllQueued();
bool haveDropsQueued() const;
- int currentEpoch() const { return _epoch; }
+ int currentEpoch() const { return _epoch.loadRelaxed(); }
void syncSizeInfo(bool sync) const;
+ void syncSizeInfoOccasionally() const;
+
private:
string _uri( const StringData& ident ) const;
@@ -132,7 +134,7 @@ namespace mongo {
std::set<std::string> _identToDrop;
mutable boost::mutex _identToDropMutex;
- int _epoch; // this is how we keep track of if a session is too old
+ AtomicInt32 _epoch; // this is how we keep track of if a session is too old
scoped_ptr<WiredTigerSizeStorer> _sizeStorer;
string _sizeStorerUri;
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp
index 328af4f9905..d8dbf0b0d50 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp
@@ -112,11 +112,11 @@ namespace mongo {
// -----------------------
WiredTigerSessionCache::WiredTigerSessionCache( WiredTigerKVEngine* engine )
- : _engine( engine ), _conn( engine->getConnection() ), _shuttingDown(0) {
+ : _engine( engine ), _conn( engine->getConnection() ), _inShutdown(false) {
}
WiredTigerSessionCache::WiredTigerSessionCache( WT_CONNECTION* conn )
- : _engine( NULL ), _conn( conn ), _shuttingDown(0) {
+ : _engine( NULL ), _conn( conn ), _inShutdown(false) {
}
WiredTigerSessionCache::~WiredTigerSessionCache() {
@@ -124,14 +124,14 @@ namespace mongo {
}
void WiredTigerSessionCache::shuttingDown() {
- if (_shuttingDown.load()) return;
- _shuttingDown.store(1);
-
{
// This ensures that any calls, which are currently inside of getSession/releaseSession
// will be able to complete before we start cleaning up the pool. Any others, which are
- // about to enter will return immediately because of _shuttingDown == true.
- boost::lock_guard<boost::shared_mutex> lk(_shutdownLock);
+ // about to enter will return immediately because of _inShutdown == true.
+ boost::mutex::scoped_lock lk(_sessionLock);
+ if ( _inShutdown )
+ return;
+ _inShutdown = true;
}
closeAll();
@@ -154,15 +154,13 @@ namespace mongo {
}
WiredTigerSession* WiredTigerSessionCache::getSession() {
- boost::shared_lock<boost::shared_mutex> shutdownLock(_shutdownLock);
-
- // We should never be able to get here after _shuttingDown is set, because no new
- // operations should be allowed to start.
- invariant(!_shuttingDown.loadRelaxed());
-
{
boost::mutex::scoped_lock lk( _sessionLock );
+ // We should never be able to get here after _inShutdown is set, because no new
+ // operations should be allowed to start.
+ invariant(!_inShutdown);
+
if (!_sessionPool.empty()) {
WiredTigerSession* cachedSession = _sessionPool.back();
_sessionPool.pop_back();
@@ -175,11 +173,11 @@ namespace mongo {
}
void WiredTigerSessionCache::releaseSession( WiredTigerSession* session ) {
- invariant( session );
+ invariant(session);
invariant(session->cursorsOut() == 0);
- boost::shared_lock<boost::shared_mutex> shutdownLock(_shutdownLock);
- if (_shuttingDown.loadRelaxed()) {
+ boost::mutex::scoped_lock lk(_sessionLock);
+ if ( _inShutdown ) {
// Leak the session in order to avoid race condition with clean shutdown, where the
// storage engine is ripped from underneath transactions, which are not "active"
// (i.e., do not have any locks), but are just about to delete the recovery unit.
@@ -189,20 +187,23 @@ namespace mongo {
// This checks that we are only caching idle sessions and not something which might hold
// locks or otherwise prevent truncation.
- {
+ DEV {
WT_SESSION* ss = session->getSession();
uint64_t range;
invariantWTOK(ss->transaction_pinned_range(ss, &range));
invariant(range == 0);
}
- if (_engine && _engine->haveDropsQueued() && session->epoch() < _engine->currentEpoch()) {
+ if (_engine) {
+ _engine->syncSizeInfoOccasionally();
+ }
+
+ if (_engine && session->epoch() < _engine->currentEpoch() && _engine->haveDropsQueued()) {
delete session;
_engine->dropAllQueued();
return;
}
- boost::mutex::scoped_lock lk(_sessionLock);
_sessionPool.push_back( session );
}
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.h b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.h
index cfdb42b18f7..c245f86b1e6 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.h
@@ -111,11 +111,7 @@ namespace mongo {
mutable boost::mutex _sessionLock;
SessionPool _sessionPool;
- // Regular operations take it in shared mode. Shutdown sets the _shuttingDown flag and
- // then takes it in exclusive mode. This ensures that all threads, which would return
- // sessions to the cache would leak them.
- boost::shared_mutex _shutdownLock;
- AtomicUInt32 _shuttingDown; // Used as boolean - 0 = false, 1 = true
+ bool _inShutdown;
};
}