diff options
-rw-r--r-- | src/mongo/db/commands/find_cmd.cpp | 13 | ||||
-rw-r--r-- | src/mongo/db/commands/getmore_cmd.cpp | 13 |
2 files changed, 24 insertions, 2 deletions
diff --git a/src/mongo/db/commands/find_cmd.cpp b/src/mongo/db/commands/find_cmd.cpp index e7313d834f9..50384636a63 100644 --- a/src/mongo/db/commands/find_cmd.cpp +++ b/src/mongo/db/commands/find_cmd.cpp @@ -316,11 +316,22 @@ public: !qr->getReadAtClusterTime() || storageEngine->supportsDocLocking()); // Validate term before acquiring locks, if provided. - if (auto term = qr->getReplicationTerm()) { + auto term = qr->getReplicationTerm(); + if (term) { // Note: updateTerm returns ok if term stayed the same. uassertStatusOK(replCoord->updateTerm(opCtx, *term)); } + // The presence of a term in the request indicates that this is an internal replication + // oplog read request. + if (term && parsedNss == NamespaceString::kRsOplogNamespace) { + // We do not want to take tickets for internal (replication) oplog reads. Stalling + // on ticket acquisition can cause complicated deadlocks. Primaries may depend on + // data reaching secondaries in order to proceed; and secondaries may get stalled + // replicating because of an inability to acquire a read ticket. + opCtx->lockState()->skipAcquireTicket(); + } + // We call RecoveryUnit::setTimestampReadSource() before acquiring a lock on the // collection via AutoGetCollectionForRead in order to ensure the comparison to the // collection's minimum visible snapshot is accurate. diff --git a/src/mongo/db/commands/getmore_cmd.cpp b/src/mongo/db/commands/getmore_cmd.cpp index af923252d7a..450fc19c4bd 100644 --- a/src/mongo/db/commands/getmore_cmd.cpp +++ b/src/mongo/db/commands/getmore_cmd.cpp @@ -622,11 +622,22 @@ public: auto curOp = CurOp::get(opCtx); curOp->debug().cursorid = _request.cursorid; - // Validate term before acquiring locks, if provided. if (_request.term) { + // Validate term before acquiring locks. auto replCoord = repl::ReplicationCoordinator::get(opCtx); // Note: updateTerm returns ok if term stayed the same. uassertStatusOK(replCoord->updateTerm(opCtx, *_request.term)); + + // If this is an oplog request, then this is a getMore for replication oplog + // fetching. The term field is only allowed for internal clients (see + // checkAuthForGetMore). + if (_request.nss == NamespaceString::kRsOplogNamespace) { + // We do not want to take tickets for internal (replication) oplog reads. + // Stalling on ticket acquisition can cause complicated deadlocks. Primaries may + // depend on data reaching secondaries in order to proceed; and secondaries may + // get stalled replicating because of an inability to acquire a read ticket. + opCtx->lockState()->skipAcquireTicket(); + } } auto cursorManager = CursorManager::get(opCtx); |