diff options
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/db/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/clientcursor.cpp | 16 | ||||
-rw-r--r-- | src/mongo/db/clientcursor.h | 6 | ||||
-rw-r--r-- | src/mongo/db/commands/getmore_cmd.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/curop.cpp | 8 | ||||
-rw-r--r-- | src/mongo/db/curop.h | 9 | ||||
-rw-r--r-- | src/mongo/db/cursor_manager.cpp | 13 | ||||
-rw-r--r-- | src/mongo/db/cursor_manager.h | 4 | ||||
-rw-r--r-- | src/mongo/db/query/find.cpp | 10 | ||||
-rw-r--r-- | src/mongo/s/query/cluster_cursor_manager.cpp | 12 | ||||
-rw-r--r-- | src/mongo/s/query/cluster_cursor_manager.h | 5 | ||||
-rw-r--r-- | src/mongo/s/query/cluster_find.cpp | 1 |
12 files changed, 74 insertions, 14 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript index fc5a3a6e872..27e96498768 100644 --- a/src/mongo/db/SConscript +++ b/src/mongo/db/SConscript @@ -211,6 +211,7 @@ env.Library( '$BUILD_DIR/mongo/util/net/network', '$BUILD_DIR/mongo/util/progress_meter', 'server_options', + 'generic_cursor', ], ) diff --git a/src/mongo/db/clientcursor.cpp b/src/mongo/db/clientcursor.cpp index fca4761b28c..1c747d07998 100644 --- a/src/mongo/db/clientcursor.cpp +++ b/src/mongo/db/clientcursor.cpp @@ -129,6 +129,22 @@ void ClientCursor::dispose(OperationContext* opCtx) { _disposed = true; } +GenericCursor ClientCursor::toGenericCursor() const { + GenericCursor gc; + gc.setCursorId(cursorid()); + gc.setNs(nss()); + gc.setNDocsReturned(pos()); + gc.setTailable(isTailable()); + gc.setAwaitData(isAwaitData()); + gc.setNoCursorTimeout(isNoTimeout()); + gc.setOriginatingCommand(getOriginatingCommandObj()); + gc.setLsid(getSessionId()); + if (auto opCtx = _operationUsingCursor) { + gc.setOperationUsingCursorId(opCtx->getOpID()); + } + return gc; +} + // // Pin methods // diff --git a/src/mongo/db/clientcursor.h b/src/mongo/db/clientcursor.h index cc698e12bfd..7602af622d0 100644 --- a/src/mongo/db/clientcursor.h +++ b/src/mongo/db/clientcursor.h @@ -186,6 +186,12 @@ public: _pos = n; } + /** + * Returns a generic cursor containing diagnostics about this cursor. + * The caller must either have this cursor pinned or hold a mutex from the cursor manager. + */ + GenericCursor toGenericCursor() const; + // // Timing. // diff --git a/src/mongo/db/commands/getmore_cmd.cpp b/src/mongo/db/commands/getmore_cmd.cpp index a6fa17ab2d6..257e340b6b6 100644 --- a/src/mongo/db/commands/getmore_cmd.cpp +++ b/src/mongo/db/commands/getmore_cmd.cpp @@ -424,6 +424,9 @@ public: if (!originatingCommand.isEmpty()) { curOp->setOriginatingCommand_inlock(originatingCommand); } + + // Update the genericCursor stored in curOp with the new cursor stats. + curOp->setGenericCursor_inlock(cursor->toGenericCursor()); } CursorId respondWithId = 0; diff --git a/src/mongo/db/curop.cpp b/src/mongo/db/curop.cpp index 7fbc23630b7..57e0d04b59f 100644 --- a/src/mongo/db/curop.cpp +++ b/src/mongo/db/curop.cpp @@ -292,6 +292,10 @@ void CurOp::reportCurrentOpForClient(OperationContext* opCtx, } } +void CurOp::setGenericCursor_inlock(GenericCursor gc) { + _genericCursor = std::move(gc); +} + CurOp::CurOp(OperationContext* opCtx) : CurOp(opCtx, &_curopStack(opCtx)) { // If this is a sub-operation, we store the snapshot of lock stats as the base lock stats of the // current operation. @@ -491,6 +495,10 @@ void CurOp::reportState(BSONObjBuilder* builder, bool truncateOps) { builder->append("planSummary", _planSummary); } + if (_genericCursor) { + builder->append("cursor", _genericCursor->toBSON()); + } + if (!_message.empty()) { if (_progressMeter.isActive()) { StringBuilder buf; diff --git a/src/mongo/db/curop.h b/src/mongo/db/curop.h index 1c039d8f06c..61824cb3f2f 100644 --- a/src/mongo/db/curop.h +++ b/src/mongo/db/curop.h @@ -32,6 +32,7 @@ #pragma once #include "mongo/base/disallow_copying.h" +#include "mongo/db/clientcursor.h" #include "mongo/db/commands.h" #include "mongo/db/cursor_id.h" #include "mongo/db/operation_context.h" @@ -527,6 +528,10 @@ public: CurOp* parent() const { return _parent; } + boost::optional<GenericCursor> getGenericCursor_inlock() const { + return _genericCursor; + } + void yielded(int numYields = 1) { _numYields += numYields; } // Should be _inlock()? @@ -558,6 +563,8 @@ public: _planSummary = std::move(summary); } + void setGenericCursor_inlock(GenericCursor gc); + const boost::optional<SingleThreadedLockStats> getLockStatsBase() { return _lockStatsBase; } @@ -602,6 +609,8 @@ private: std::string _message; ProgressMeter _progressMeter; int _numYields{0}; + // A GenericCursor containing information about the active cursor for a getMore operation. + boost::optional<GenericCursor> _genericCursor; std::string _planSummary; boost::optional<SingleThreadedLockStats> diff --git a/src/mongo/db/cursor_manager.cpp b/src/mongo/db/cursor_manager.cpp index fb7cd6058d4..cb2266920c7 100644 --- a/src/mongo/db/cursor_manager.cpp +++ b/src/mongo/db/cursor_manager.cpp @@ -622,19 +622,6 @@ void CursorManager::appendActiveSessions(LogicalSessionIdSet* lsids) const { } } -GenericCursor CursorManager::buildGenericCursor_inlock(const ClientCursor* cursor) const { - GenericCursor gc; - gc.setCursorId(cursor->_cursorid); - gc.setNs(cursor->nss()); - gc.setLsid(cursor->getSessionId()); - gc.setNDocsReturned(cursor->pos()); - gc.setTailable(cursor->isTailable()); - gc.setAwaitData(cursor->isAwaitData()); - gc.setOriginatingCommand(cursor->getOriginatingCommandObj()); - gc.setNoCursorTimeout(cursor->isNoTimeout()); - return gc; -} - void CursorManager::appendIdleCursors(AuthorizationSession* ctxAuth, MongoProcessInterface::CurrentOpUserMode userMode, std::vector<GenericCursor>* cursors) const { diff --git a/src/mongo/db/cursor_manager.h b/src/mongo/db/cursor_manager.h index 4202afadc65..d75053fa4b5 100644 --- a/src/mongo/db/cursor_manager.h +++ b/src/mongo/db/cursor_manager.h @@ -264,7 +264,9 @@ private: * CursorManager partition lock. This is neccessary to protect concurrent access to the data * members of 'cursor', as it prevents other threads from pinning this cursor. */ - GenericCursor buildGenericCursor_inlock(const ClientCursor* cursor) const; + GenericCursor buildGenericCursor_inlock(const ClientCursor* cursor) const { + return cursor->toGenericCursor(); + } ClientCursorPin _registerCursor( OperationContext* opCtx, std::unique_ptr<ClientCursor, ClientCursor::Deleter> clientCursor); diff --git a/src/mongo/db/query/find.cpp b/src/mongo/db/query/find.cpp index b295df1d5e7..6a43af3c64f 100644 --- a/src/mongo/db/query/find.cpp +++ b/src/mongo/db/query/find.cpp @@ -39,6 +39,7 @@ #include "mongo/db/clientcursor.h" #include "mongo/db/commands.h" #include "mongo/db/curop.h" +#include "mongo/db/curop_failpoint_helpers.h" #include "mongo/db/db_raii.h" #include "mongo/db/exec/filter.h" #include "mongo/db/exec/working_set_common.h" @@ -73,6 +74,9 @@ using stdx::make_unique; // Failpoint for checking whether we've received a getmore. MONGO_FAIL_POINT_DEFINE(failReceivedGetmore); +// Failpoint to keep a cursor pinned. +MONGO_FAIL_POINT_DEFINE(legacyGetMoreWaitWithCursor) + bool shouldSaveCursor(OperationContext* opCtx, const Collection* collection, PlanExecutor::ExecState finalState, @@ -404,6 +408,8 @@ Message getMore(OperationContext* opCtx, // command or upconverted legacy query in the originatingCommand field. curOp.setOpDescription_inlock(upconvertGetMoreEntry(nss, cursorid, ntoreturn)); curOp.setOriginatingCommand_inlock(cc->getOriginatingCommandObj()); + // Update the generic cursor in curOp. + curOp.setGenericCursor_inlock(cc->toGenericCursor()); } PlanExecutor::ExecState state; @@ -413,6 +419,10 @@ Message getMore(OperationContext* opCtx, // metrics, as they accumulate over the course of a cursor's lifetime. PlanSummaryStats preExecutionStats; Explain::getSummaryStats(*exec, &preExecutionStats); + if (MONGO_FAIL_POINT(legacyGetMoreWaitWithCursor)) { + CurOpFailpointHelpers::waitWhileFailPointEnabled( + &legacyGetMoreWaitWithCursor, opCtx, "legacyGetMoreWaitWithCursor", nullptr); + } generateBatch(ntoreturn, cc, &bb, &numResults, &state); diff --git a/src/mongo/s/query/cluster_cursor_manager.cpp b/src/mongo/s/query/cluster_cursor_manager.cpp index 3b1079aabb0..4964991e8bb 100644 --- a/src/mongo/s/query/cluster_cursor_manager.cpp +++ b/src/mongo/s/query/cluster_cursor_manager.cpp @@ -171,6 +171,18 @@ bool ClusterCursorManager::PinnedCursor::remotesExhausted() { return _cursor->remotesExhausted(); } +GenericCursor ClusterCursorManager::PinnedCursor::toGenericCursor() const { + GenericCursor gc; + gc.setCursorId(getCursorId()); + gc.setNs(_nss); + gc.setLsid(getLsid()); + gc.setNDocsReturned(getNumReturnedSoFar()); + gc.setTailable(isTailable()); + gc.setAwaitData(isTailableAndAwaitData()); + gc.setOriginatingCommand(getOriginatingCommand()); + return gc; +} + Status ClusterCursorManager::PinnedCursor::setAwaitDataTimeout(Milliseconds awaitDataTimeout) { invariant(_cursor); return _cursor->setAwaitDataTimeout(awaitDataTimeout); diff --git a/src/mongo/s/query/cluster_cursor_manager.h b/src/mongo/s/query/cluster_cursor_manager.h index 37c7d7478b2..6c1b0d10c92 100644 --- a/src/mongo/s/query/cluster_cursor_manager.h +++ b/src/mongo/s/query/cluster_cursor_manager.h @@ -213,6 +213,11 @@ public: long long getNumReturnedSoFar() const; /** + * Returns a GenericCursor version of the pinned cursor. + */ + GenericCursor toGenericCursor() const; + + /** * Stashes 'obj' to be returned later by this cursor. A cursor must be owned. */ void queueResult(const ClusterQueryResult& result); diff --git a/src/mongo/s/query/cluster_find.cpp b/src/mongo/s/query/cluster_find.cpp index 5621ba5150e..a805ad35078 100644 --- a/src/mongo/s/query/cluster_find.cpp +++ b/src/mongo/s/query/cluster_find.cpp @@ -575,6 +575,7 @@ StatusWith<CursorResponse> ClusterFind::runGetMore(OperationContext* opCtx, stdx::lock_guard<Client> lk(*opCtx->getClient()); CurOp::get(opCtx)->setOriginatingCommand_inlock( pinnedCursor.getValue().getOriginatingCommand()); + CurOp::get(opCtx)->setGenericCursor_inlock(pinnedCursor.getValue().toGenericCursor()); } // If the 'waitAfterPinningCursorBeforeGetMoreBatch' fail point is enabled, set the 'msg' |