diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/commands/getmore_cmd.cpp | 68 | ||||
-rw-r--r-- | src/mongo/db/read_concern.h | 6 | ||||
-rw-r--r-- | src/mongo/db/read_concern_mongod.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/service_entry_point_mongod.cpp | 2 | ||||
-rw-r--r-- | src/mongo/embedded/read_concern_embedded.cpp | 3 | ||||
-rw-r--r-- | src/mongo/embedded/service_entry_point_embedded.cpp | 2 |
6 files changed, 30 insertions, 57 deletions
diff --git a/src/mongo/db/commands/getmore_cmd.cpp b/src/mongo/db/commands/getmore_cmd.cpp index adb9ecabc7f..604d0535f5b 100644 --- a/src/mongo/db/commands/getmore_cmd.cpp +++ b/src/mongo/db/commands/getmore_cmd.cpp @@ -71,9 +71,6 @@ namespace { MONGO_FAIL_POINT_DEFINE(rsStopGetMoreCmd); -// The timeout when waiting for linearizable read concern on a getMore command. -static constexpr int kLinearizableReadConcernTimeout = 15000; - /** * Validates that the lsid of 'opCtx' matches that of 'cursor'. This must be called after * authenticating, so that it is safe to report the lsid of 'cursor'. @@ -272,11 +269,19 @@ public: MONGO_UNREACHABLE; } - void acquireLocksAndIterateCursor(OperationContext* opCtx, - rpc::ReplyBuilderInterface* reply, - CursorManager* cursorManager, - ClientCursorPin& cursorPin, - CurOp* curOp) { + void run(OperationContext* opCtx, rpc::ReplyBuilderInterface* reply) override { + // Counted as a getMore, not as a command. + globalOpCounters.gotGetMore(); + auto curOp = CurOp::get(opCtx); + curOp->debug().cursorid = _request.cursorid; + + // Validate term before acquiring locks, if provided. + if (_request.term) { + auto replCoord = repl::ReplicationCoordinator::get(opCtx); + // Note: updateTerm returns ok if term stayed the same. + uassertStatusOK(replCoord->updateTerm(opCtx, *_request.term)); + } + // Cursors come in one of two flavors: // // - Cursors which read from a single collection, such as those generated via the @@ -298,6 +303,9 @@ public: boost::optional<AutoGetCollectionForRead> readLock; boost::optional<AutoStatsTracker> statsTracker; + auto cursorManager = CursorManager::get(opCtx); + auto cursorPin = uassertStatusOK(cursorManager->pinCursor(opCtx, _request.cursorid)); + { // We call RecoveryUnit::setTimestampReadSource() before acquiring a lock on the // collection via AutoGetCollectionForRead in order to ensure the comparison to the @@ -323,6 +331,7 @@ public: opCtx->recoveryUnit()->setIgnorePrepared(false); } } + if (cursorPin->lockPolicy() == ClientCursorParams::LockPolicy::kLocksInternally) { if (!_request.nss.isCollectionlessCursorNamespace()) { const boost::optional<int> dbProfilingLevel = boost::none; @@ -346,7 +355,7 @@ public: } // Only used by the failpoints. - stdx::function<void()> dropAndReacquireReadLock = [&readLock, opCtx, this]() { + stdx::function<void()> dropAndReaquireReadLock = [&readLock, opCtx, this]() { // Make sure an interrupted operation does not prevent us from reacquiring the lock. UninterruptibleLockGuard noInterrupt(opCtx->lockState()); @@ -409,14 +418,14 @@ public: MONGO_FAIL_POINT_BLOCK(waitAfterPinningCursorBeforeGetMoreBatch, options) { const BSONObj& data = options.getData(); if (data["shouldNotdropLock"].booleanSafe()) { - dropAndReacquireReadLock = []() {}; + dropAndReaquireReadLock = []() {}; } CurOpFailpointHelpers::waitWhileFailPointEnabled( &waitAfterPinningCursorBeforeGetMoreBatch, opCtx, "waitAfterPinningCursorBeforeGetMoreBatch", - dropAndReacquireReadLock, + dropAndReaquireReadLock, false, _request.nss); } @@ -503,7 +512,7 @@ public: &waitWithPinnedCursorDuringGetMoreBatch, opCtx, "waitWithPinnedCursorDuringGetMoreBatch", - dropAndReacquireReadLock); + dropAndReaquireReadLock); } uassertStatusOK(generateBatch( @@ -549,38 +558,6 @@ public: if (respondWithId) { cursorFreer.dismiss(); } - } - - void run(OperationContext* opCtx, rpc::ReplyBuilderInterface* reply) override { - // Counted as a getMore, not as a command. - globalOpCounters.gotGetMore(); - auto curOp = CurOp::get(opCtx); - curOp->debug().cursorid = _request.cursorid; - - // Validate term before acquiring locks, if provided. - if (_request.term) { - auto replCoord = repl::ReplicationCoordinator::get(opCtx); - // Note: updateTerm returns ok if term stayed the same. - uassertStatusOK(replCoord->updateTerm(opCtx, *_request.term)); - } - - auto cursorManager = CursorManager::get(opCtx); - auto cursorPin = uassertStatusOK(cursorManager->pinCursor(opCtx, _request.cursorid)); - - acquireLocksAndIterateCursor(opCtx, reply, cursorManager, cursorPin, curOp); - - const auto isLinearizableReadConcern = cursorPin->getReadConcernArgs().getLevel() == - repl::ReadConcernLevel::kLinearizableReadConcern; - - if (isLinearizableReadConcern) { - // waitForLinearizableReadConcern performs a NoOp write and waits for that write - // to have been majority committed. awaitReplication requires that we release all - // locks to prevent blocking for a long time while doing network activity. Since - // getMores do not have support for a maxTimeout duration, we hardcode the timeout - // to avoid waiting indefinitely. - uassertStatusOK( - mongo::waitForLinearizableReadConcern(opCtx, kLinearizableReadConcernTimeout)); - } // We're about to unpin or delete the cursor as the ClientCursorPin goes out of scope. // If the 'waitBeforeUnpinningOrDeletingCursorAfterGetMoreBatch' failpoint is active, we @@ -590,7 +567,8 @@ public: CurOpFailpointHelpers::waitWhileFailPointEnabled( &waitBeforeUnpinningOrDeletingCursorAfterGetMoreBatch, opCtx, - "waitBeforeUnpinningOrDeletingCursorAfterGetMoreBatch"); + "waitBeforeUnpinningOrDeletingCursorAfterGetMoreBatch", + dropAndReaquireReadLock); } } diff --git a/src/mongo/db/read_concern.h b/src/mongo/db/read_concern.h index 2fd42beb71f..49a0b92acb0 100644 --- a/src/mongo/db/read_concern.h +++ b/src/mongo/db/read_concern.h @@ -58,12 +58,8 @@ extern MONGO_DECLARE_SHIM((OperationContext * opCtx, /* * Given a linearizable read command, confirm that * current primary is still the true primary of the replica set. - * - * A readConcernTimeout of 0 indicates that the operation will block indefinitely waiting for read - * concern. */ -extern MONGO_DECLARE_SHIM((OperationContext * opCtx, const int readConcernTimeout)->Status) - waitForLinearizableReadConcern; +extern MONGO_DECLARE_SHIM((OperationContext * opCtx)->Status) waitForLinearizableReadConcern; /** * Waits to satisfy a "speculative" majority read. diff --git a/src/mongo/db/read_concern_mongod.cpp b/src/mongo/db/read_concern_mongod.cpp index 84584a01bc6..968c06c2893 100644 --- a/src/mongo/db/read_concern_mongod.cpp +++ b/src/mongo/db/read_concern_mongod.cpp @@ -344,8 +344,8 @@ MONGO_REGISTER_SHIM(waitForReadConcern) return Status::OK(); } -MONGO_REGISTER_SHIM(waitForLinearizableReadConcern) -(OperationContext* opCtx, const int readConcernTimeout)->Status { +MONGO_REGISTER_SHIM(waitForLinearizableReadConcern)(OperationContext* opCtx)->Status { + CurOpFailpointHelpers::waitWhileFailPointEnabled( &hangBeforeLinearizableReadConcern, opCtx, "hangBeforeLinearizableReadConcern", [opCtx]() { log() << "batch update - hangBeforeLinearizableReadConcern fail point enabled. " @@ -374,7 +374,7 @@ MONGO_REGISTER_SHIM(waitForLinearizableReadConcern) }); } WriteConcernOptions wc = WriteConcernOptions( - WriteConcernOptions::kMajority, WriteConcernOptions::SyncMode::UNSET, readConcernTimeout); + WriteConcernOptions::kMajority, WriteConcernOptions::SyncMode::UNSET, 0); repl::OpTime lastOpApplied = repl::ReplClientInfo::forClient(opCtx->getClient()).getLastOp(); auto awaitReplResult = replCoord->awaitReplication(opCtx, lastOpApplied, wc); diff --git a/src/mongo/db/service_entry_point_mongod.cpp b/src/mongo/db/service_entry_point_mongod.cpp index 0e870bf80a6..4af38918684 100644 --- a/src/mongo/db/service_entry_point_mongod.cpp +++ b/src/mongo/db/service_entry_point_mongod.cpp @@ -118,7 +118,7 @@ public: // from the primary. if (repl::ReadConcernArgs::get(opCtx).getLevel() == repl::ReadConcernLevel::kLinearizableReadConcern) { - uassertStatusOK(mongo::waitForLinearizableReadConcern(opCtx, 0)); + uassertStatusOK(mongo::waitForLinearizableReadConcern(opCtx)); } } diff --git a/src/mongo/embedded/read_concern_embedded.cpp b/src/mongo/embedded/read_concern_embedded.cpp index db4dbe3ef83..1d52d3d39fb 100644 --- a/src/mongo/embedded/read_concern_embedded.cpp +++ b/src/mongo/embedded/read_concern_embedded.cpp @@ -55,8 +55,7 @@ MONGO_REGISTER_SHIM(waitForSpeculativeMajorityReadConcern) return Status::OK(); } -MONGO_REGISTER_SHIM(waitForLinearizableReadConcern) -(OperationContext* opCtx, const int readConcernTimeout)->Status { +MONGO_REGISTER_SHIM(waitForLinearizableReadConcern)(OperationContext* opCtx)->Status { return Status::OK(); } diff --git a/src/mongo/embedded/service_entry_point_embedded.cpp b/src/mongo/embedded/service_entry_point_embedded.cpp index bacdad22ffd..74bb9dfb034 100644 --- a/src/mongo/embedded/service_entry_point_embedded.cpp +++ b/src/mongo/embedded/service_entry_point_embedded.cpp @@ -75,7 +75,7 @@ public: void waitForLinearizableReadConcern(OperationContext* opCtx) const override { if (repl::ReadConcernArgs::get(opCtx).getLevel() == repl::ReadConcernLevel::kLinearizableReadConcern) { - uassertStatusOK(mongo::waitForLinearizableReadConcern(opCtx, 0)); + uassertStatusOK(mongo::waitForLinearizableReadConcern(opCtx)); } } |