diff options
author | Michael Cahill <michael.cahill@mongodb.com> | 2016-08-10 13:33:32 +1000 |
---|---|---|
committer | Michael Cahill <michael.cahill@mongodb.com> | 2016-08-10 13:33:32 +1000 |
commit | 22ec9e93b40c85fc7cae7d56e7d6a02fd811088c (patch) | |
tree | 85d2ad2653dc80e4fbb70a6bf1fe2eea25c60408 | |
parent | cb7ae1686f4482f50e1a008f96c667ee6eb93d6e (diff) | |
download | mongo-22ec9e93b40c85fc7cae7d56e7d6a02fd811088c.tar.gz |
SERVER-25500 If drop fails, close cursors, not sessions.r3.2.9-rc1r3.2.9
3 files changed, 47 insertions, 14 deletions
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp index 26406288303..d0d28218770 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp @@ -547,7 +547,7 @@ bool WiredTigerKVEngine::_drop(StringData ident) { stdx::lock_guard<stdx::mutex> lk(_identToDropMutex); _identToDrop.push(uri); } - _sessionCache->closeAll(); + _sessionCache->closeAllCursors(); return false; } diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp index 6619ce01865..836d42b9e42 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp @@ -44,8 +44,13 @@ namespace mongo { -WiredTigerSession::WiredTigerSession(WT_CONNECTION* conn, int epoch) - : _epoch(epoch), _session(NULL), _cursorGen(0), _cursorsCached(0), _cursorsOut(0) { +WiredTigerSession::WiredTigerSession(WT_CONNECTION* conn, uint64_t epoch, uint64_t cursorEpoch) + : _epoch(epoch), + _cursorEpoch(cursorEpoch), + _session(NULL), + _cursorGen(0), + _cursorsCached(0), + _cursorsOut(0) { invariantWTOK(conn->open_session(conn, NULL, "isolation=snapshot", &_session)); } @@ -101,7 +106,7 @@ void WiredTigerSession::releaseCursor(uint64_t id, WT_CURSOR* cursor) { } } -void WiredTigerSession::closeAllCursors() { +void WiredTigerSession::closeAllCursors(uint64_t cursorEpoch) { invariant(_session); for (CursorCache::iterator i = _cursors.begin(); i != _cursors.end(); ++i) { WT_CURSOR* cursor = i->_cursor; @@ -110,6 +115,7 @@ void WiredTigerSession::closeAllCursors() { } } _cursors.clear(); + _cursorEpoch = cursorEpoch; } namespace { @@ -209,8 +215,18 @@ void WiredTigerSessionCache::waitUntilDurable(bool forceCheckpoint) { _journalListener->onDurable(token); } +void WiredTigerSessionCache::closeAllCursors() { + // Increment the cursor epoch so that all cursors from this epoch are closed. + uint64_t cursorEpoch = _cursorEpoch.addAndFetch(1); + + stdx::lock_guard<stdx::mutex> lock(_cacheLock); + for (SessionCache::iterator i = _sessions.begin(); i != _sessions.end(); i++) { + (*i)->closeAllCursors(cursorEpoch); + } +} + void WiredTigerSessionCache::closeAll() { - // Increment the epoch as we are now closing all sessions with this epoch + // Increment the epoch as we are now closing all sessions with this epoch. SessionCache swap; { @@ -245,7 +261,7 @@ WiredTigerSession* WiredTigerSessionCache::getSession() { } // Outside of the cache partition lock, but on release will be put back on the cache - return new WiredTigerSession(_conn, _epoch.load()); + return new WiredTigerSession(_conn, _epoch.load(), _cursorEpoch.load()); } void WiredTigerSessionCache::releaseSession(WiredTigerSession* session) { @@ -272,6 +288,11 @@ void WiredTigerSessionCache::releaseSession(WiredTigerSession* session) { invariant(range == 0); } + // If the cursor epoch has moved on, close all cursors in the session. + uint64_t cursorEpoch = _cursorEpoch.load(); + if (session->_getCursorEpoch() != cursorEpoch) + session->closeAllCursors(cursorEpoch); + bool returnedToCache = false; uint64_t currentEpoch = _epoch.load(); diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.h b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.h index d5354101ac7..4cd482f9772 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.h +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.h @@ -68,14 +68,11 @@ public: * Creates a new WT session on the specified connection. * * @param conn WT connection - * @param cachePartition If the session comes from the session cache, this indicates to - * which partition it should be returned. Value of -1 means it doesn't come from - * cache and that it should not be cached, but closed directly. - * @param epoch In which session cache cleanup epoch was this session instantiated. Value - * of -1 means that this value is not necessary since the session will not be - * cached. + * @param epoch In which session cache cleanup epoch was this session instantiated. + * @param cursorEpoch In which cursor cache cleanup epoch was this session instantiated. */ - WiredTigerSession(WT_CONNECTION* conn, int epoch = -1); + WiredTigerSession(WT_CONNECTION* conn, uint64_t epoch = 0, uint64_t cursorEpoch = 0); + ~WiredTigerSession(); WT_SESSION* getSession() const { @@ -86,7 +83,7 @@ public: void releaseCursor(uint64_t id, WT_CURSOR* cursor); - void closeAllCursors(); + void closeAllCursors(uint64_t cursorEpoch = 0); int cursorsOut() const { return _cursorsOut; @@ -110,7 +107,13 @@ private: return _epoch; } + // Used internally by WiredTigerSessionCache + uint64_t _getCursorEpoch() const { + return _cursorEpoch; + } + const uint64_t _epoch; + uint64_t _cursorEpoch; WT_SESSION* _session; // owned CursorCache _cursors; // owned uint64_t _cursorGen; @@ -147,6 +150,12 @@ public: void closeAll(); /** + * Closes all cached cursors and ensures that previously opened cursors will be closed on + * release. + */ + void closeAllCursors(); + + /** * Transitions the cache to shutting down mode. Any already released sessions are freed and * any sessions released subsequently are leaked. Must be called while holding the global * lock in exclusive mode to avoid races with getSession. @@ -192,6 +201,9 @@ private: // Bumped when all open sessions need to be closed AtomicUInt64 _epoch; // atomic so we can check it outside of the lock + // Bumped when all open cursors need to be closed + AtomicUInt64 _cursorEpoch; // atomic so we can check it outside of the lock + // Counter and critical section mutex for waitUntilDurable AtomicUInt32 _lastSyncTime; stdx::mutex _lastSyncMutex; |