summaryrefslogtreecommitdiff
path: root/src/mongo/db/commands
diff options
context:
space:
mode:
authorMax Hirschhorn <max.hirschhorn@mongodb.com>2018-05-29 18:55:36 -0400
committerMax Hirschhorn <max.hirschhorn@mongodb.com>2018-05-29 18:55:36 -0400
commit9f4401a7b20be1a4b6bd190f5b04919a6abf5645 (patch)
treeaa15a2c9e6ca52a4ebea4ed1db32028234068f64 /src/mongo/db/commands
parent2d60ce759071d2c5629f62c5fb4016b008db98ab (diff)
downloadmongo-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.cpp23
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();