summaryrefslogtreecommitdiff
path: root/src/mongo/db/introspect.cpp
diff options
context:
space:
mode:
authorLingzhi Deng <lingzhi.deng@mongodb.com>2019-05-20 00:49:33 -0400
committerLingzhi Deng <lingzhi.deng@mongodb.com>2019-05-23 16:46:30 -0400
commit8a89b076d28a904c200e491698ef1169dd8a7254 (patch)
treedc32fa3bdc62cdd9f8b9b84777f0df8f03f43cec /src/mongo/db/introspect.cpp
parent47d4eca3fcdfa8eed0f1bef28021c8603452dec3 (diff)
downloadmongo-8a89b076d28a904c200e491698ef1169dd8a7254.tar.gz
SERVER-40938: disallow afterClusterTime and ignore prepare conflicts for dbhash and map-reduce
Diffstat (limited to 'src/mongo/db/introspect.cpp')
-rw-r--r--src/mongo/db/introspect.cpp39
1 files changed, 6 insertions, 33 deletions
diff --git a/src/mongo/db/introspect.cpp b/src/mongo/db/introspect.cpp
index a82e67a0e6c..425d100f183 100644
--- a/src/mongo/db/introspect.cpp
+++ b/src/mongo/db/introspect.cpp
@@ -80,39 +80,6 @@ void _appendUserInfo(const CurOp& c, BSONObjBuilder& builder, AuthorizationSessi
builder.append("user", bestUser.getUser().empty() ? "" : bestUser.getFullName());
}
-/**
- * When in scope, closes any active storage transactions and enforces prepare conflicts for reads.
- *
- * Locks must be held while this is in scope because both constructor and destructor access the
- * storage engine.
- */
-class EnforcePrepareConflictsBlock {
-public:
- explicit EnforcePrepareConflictsBlock(OperationContext* opCtx)
- : _opCtx(opCtx), _originalValue(opCtx->recoveryUnit()->getIgnorePrepared()) {
- dassert(_opCtx->lockState()->isLocked());
- dassert(!_opCtx->lockState()->inAWriteUnitOfWork());
-
- // It is illegal to call setIgnorePrepared() while any storage transaction is active. This
- // call is also harmless because any previous reads or writes should have already completed,
- // as profile() is called at the end of an operation.
- _opCtx->recoveryUnit()->abandonSnapshot();
- _opCtx->recoveryUnit()->setIgnorePrepared(false);
- }
-
- ~EnforcePrepareConflictsBlock() {
- dassert(_opCtx->lockState()->isLocked());
- dassert(!_opCtx->lockState()->inAWriteUnitOfWork());
-
- _opCtx->recoveryUnit()->abandonSnapshot();
- _opCtx->recoveryUnit()->setIgnorePrepared(_originalValue);
- }
-
-private:
- OperationContext* _opCtx;
- bool _originalValue;
-};
-
} // namespace
@@ -188,6 +155,12 @@ void profile(OperationContext* opCtx, NetworkOp op) {
Lock::CollectionLock collLock(opCtx, db->getProfilingNS(), MODE_IX);
+ // We are about to enforce prepare conflicts for the OperationContext. But it is illegal
+ // to change the behavior of ignoring prepare conflicts while any storage transaction is
+ // still active. So we need to call abandonSnapshot() to close any open transactions.
+ // This call is also harmless because any previous reads or writes should have already
+ // completed, as profile() is called at the end of an operation.
+ opCtx->recoveryUnit()->abandonSnapshot();
// The profiler performs writes even after read commands. Ignoring prepare conflicts is
// not allowed while performing writes, so temporarily enforce prepare conflicts.
EnforcePrepareConflictsBlock enforcePrepare(opCtx);