summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@mongodb.com>2016-08-10 13:33:32 +1000
committerMichael Cahill <michael.cahill@mongodb.com>2016-08-10 13:33:32 +1000
commit22ec9e93b40c85fc7cae7d56e7d6a02fd811088c (patch)
tree85d2ad2653dc80e4fbb70a6bf1fe2eea25c60408
parentcb7ae1686f4482f50e1a008f96c667ee6eb93d6e (diff)
downloadmongo-22ec9e93b40c85fc7cae7d56e7d6a02fd811088c.tar.gz
SERVER-25500 If drop fails, close cursors, not sessions.r3.2.9-rc1r3.2.9
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp2
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp31
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.h28
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;