diff options
author | Max Hirschhorn <max.hirschhorn@mongodb.com> | 2018-05-29 18:55:36 -0400 |
---|---|---|
committer | Max Hirschhorn <max.hirschhorn@mongodb.com> | 2018-05-29 18:55:36 -0400 |
commit | 9f4401a7b20be1a4b6bd190f5b04919a6abf5645 (patch) | |
tree | aa15a2c9e6ca52a4ebea4ed1db32028234068f64 /src/mongo/db/commands | |
parent | 2d60ce759071d2c5629f62c5fb4016b008db98ab (diff) | |
download | mongo-9f4401a7b20be1a4b6bd190f5b04919a6abf5645.tar.gz |
SERVER-35253 Fix dbHash cmd to acquire IX locks inside multi-stmt txn.
(cherry picked from commit 52976ef70f1fa991c9b30ba5e0e45fb8e2a1a1d8)
(cherry picked from commit 1b3963a81c6cf68519b9ef5e798cf997483cc7b3)
Diffstat (limited to 'src/mongo/db/commands')
-rw-r--r-- | src/mongo/db/commands/dbhash.cpp | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/src/mongo/db/commands/dbhash.cpp b/src/mongo/db/commands/dbhash.cpp index 42375adb09f..1a9b1ca3678 100644 --- a/src/mongo/db/commands/dbhash.cpp +++ b/src/mongo/db/commands/dbhash.cpp @@ -45,6 +45,7 @@ #include "mongo/db/exec/working_set_common.h" #include "mongo/db/namespace_string.h" #include "mongo/db/query/internal_plans.h" +#include "mongo/db/session_catalog.h" #include "mongo/stdx/mutex.h" #include "mongo/util/log.h" #include "mongo/util/md5.hpp" @@ -114,10 +115,11 @@ public: // We lock the entire database in S-mode in order to ensure that the contents will not // change for the snapshot. auto lockMode = LockMode::MODE_S; - if (repl::ReadConcernArgs::get(opCtx).getArgsAtClusterTime()) { - // However, if we are using "atClusterTime" to read from a consistent snapshot, then we - // only need to lock the database in intent mode to ensure that none of the collections - // get dropped. + auto* session = OperationContextSession::get(opCtx); + if (session && session->inSnapshotReadOrMultiDocumentTransaction()) { + // However, if we are inside a multi-statement transaction or using snapshot reads to + // read from a consistent snapshot, then we only need to lock the database in intent + // mode to ensure that none of the collections get dropped. lockMode = getLockModeForQuery(opCtx); } AutoGetDb autoDb(opCtx, ns, lockMode); @@ -217,11 +219,14 @@ private: return ""; boost::optional<Lock::CollectionLock> collLock; - if (repl::ReadConcernArgs::get(opCtx).getArgsAtClusterTime()) { - // When using "atClusterTime", we are only holding the database lock in intent mode. We - // need to also acquire the collection lock in intent mode to ensure reading from the - // consistent snapshot doesn't overlap with any catalog operations on the collection. - invariant(opCtx->lockState()->isDbLockedForMode(db->name(), MODE_IS)); + auto* session = OperationContextSession::get(opCtx); + if (session && session->inSnapshotReadOrMultiDocumentTransaction()) { + // When inside a multi-statement transaction or using snapshot reads, we are only + // holding the database lock in intent mode. We need to also acquire the collection lock + // in intent mode to ensure reading from the consistent snapshot doesn't overlap with + // any catalog operations on the collection. + invariant( + opCtx->lockState()->isDbLockedForMode(db->name(), getLockModeForQuery(opCtx))); collLock.emplace(opCtx->lockState(), fullCollectionName, getLockModeForQuery(opCtx)); auto minSnapshot = collection->getMinimumVisibleSnapshot(); |