diff options
author | Ted Tuckman <ted.tuckman@mongodb.com> | 2018-09-13 13:43:53 -0400 |
---|---|---|
committer | Ted Tuckman <ted.tuckman@mongodb.com> | 2018-09-18 13:15:13 -0400 |
commit | 157691ef0babb24cd1566446f5f88206f9607564 (patch) | |
tree | c4d9f1f68218f86f8418f712073d0dce830cab47 | |
parent | cd441ed71c1453993b3af4617e704fbbad3783ef (diff) | |
download | mongo-157691ef0babb24cd1566446f5f88206f9607564.tar.gz |
SERVER-37090 Add idleCursors to currentOp output for mongos
-rw-r--r-- | jstests/core/currentop_cursors.js | 18 | ||||
-rw-r--r-- | src/mongo/db/pipeline/mongos_process_interface.h | 2 | ||||
-rw-r--r-- | src/mongo/s/query/cluster_cursor_manager.cpp | 22 | ||||
-rw-r--r-- | src/mongo/s/query/cluster_cursor_manager.h | 8 |
4 files changed, 36 insertions, 14 deletions
diff --git a/jstests/core/currentop_cursors.js b/jstests/core/currentop_cursors.js index 4e8feffa9cc..b4e0949fac9 100644 --- a/jstests/core/currentop_cursors.js +++ b/jstests/core/currentop_cursors.js @@ -2,10 +2,7 @@ * Tests that an idle cursor will appear in the $currentOp output if the idleCursors option is * set to true. * - * The work to make this feature available on mongos is deferred to SERVER-37004 - * and SERVER-37005. Those tickets will make the idleCursor fields available to curOp. - * @tags: [assumes_against_mongod_not_mongos, assumes_read_concern_unchanged] - * + * @tags: [assumes_read_concern_unchanged] */ (function() { @@ -20,12 +17,19 @@ assert.commandWorked(db.runCommand({find: "jstests_currentop", batchSize: 2})).cursor.id; const result = adminDB .aggregate([ - {$currentOp: {allUsers: false, idleCursors: true}}, + {$currentOp: {localOps: true, allUsers: false, idleCursors: true}}, {$match: {$and: [{type: "idleCursor"}, {"cursor.cursorId": findOut}]}} ]) .toArray(); - assert.eq(result.length, 1, tojson(result)); - assert.eq(result[0].cursor.nDocsReturned, 2, tojson(result)); + assert.eq(result.length, 1, result); + assert.eq(result[0].cursor.nDocsReturned, 2, result); + assert.eq(result[0].cursor.tailable, false, result); + assert.eq(result[0].cursor.awaitData, false, result); + assert.eq(result[0].cursor.noCursorTimeout, false, result); + assert.eq(result[0].cursor.ns, coll.getFullName(), result); + assert.eq(result[0].cursor.originatingCommand.find, "jstests_currentop", result); + assert.eq(result[0].cursor.originatingCommand.batchSize, 2, result); + const noIdle = adminDB .aggregate([ {$currentOp: {allUsers: false, idleCursors: false}}, diff --git a/src/mongo/db/pipeline/mongos_process_interface.h b/src/mongo/db/pipeline/mongos_process_interface.h index 05182b4116a..b16f72608bb 100644 --- a/src/mongo/db/pipeline/mongos_process_interface.h +++ b/src/mongo/db/pipeline/mongos_process_interface.h @@ -52,8 +52,6 @@ public: const Document& documentKey, boost::optional<BSONObj> readConcern) final; - // TODO: SERVER-37090 bring mongos getIdleCursors to match mongod and pass back GenericCursors - // with all available fields. std::vector<GenericCursor> getIdleCursors(const boost::intrusive_ptr<ExpressionContext>& expCtx, CurrentOpUserMode userMode) const final; diff --git a/src/mongo/s/query/cluster_cursor_manager.cpp b/src/mongo/s/query/cluster_cursor_manager.cpp index a521bc13000..3b1079aabb0 100644 --- a/src/mongo/s/query/cluster_cursor_manager.cpp +++ b/src/mongo/s/query/cluster_cursor_manager.cpp @@ -572,6 +572,21 @@ void ClusterCursorManager::appendActiveSessions(LogicalSessionIdSet* lsids) cons } } +GenericCursor ClusterCursorManager::CursorEntry::cursorToGenericCursor( + CursorId cursorId, const NamespaceString& ns) const { + invariant(_cursor); + GenericCursor gc; + gc.setCursorId(cursorId); + gc.setNs(ns); + gc.setLsid(_cursor->getLsid()); + gc.setNDocsReturned(_cursor->getNumReturnedSoFar()); + gc.setTailable(_cursor->isTailable()); + gc.setAwaitData(_cursor->isTailableAndAwaitData()); + gc.setOriginatingCommand(_cursor->getOriginatingCommand()); + gc.setNoCursorTimeout(getLifetimeType() == CursorLifetime::Immortal); + return gc; +} + std::vector<GenericCursor> ClusterCursorManager::getIdleCursors() const { std::vector<GenericCursor> cursors; @@ -586,11 +601,8 @@ std::vector<GenericCursor> ClusterCursorManager::getIdleCursors() const { continue; } - cursors.emplace_back(); - auto& gc = cursors.back(); - gc.setCursorId(cursorIdEntryPair.first); - gc.setNs(nsContainerPair.first); - gc.setLsid(entry.getLsid()); + cursors.emplace_back( + entry.cursorToGenericCursor(cursorIdEntryPair.first, nsContainerPair.first)); } } diff --git a/src/mongo/s/query/cluster_cursor_manager.h b/src/mongo/s/query/cluster_cursor_manager.h index 611aa306543..37c7d7478b2 100644 --- a/src/mongo/s/query/cluster_cursor_manager.h +++ b/src/mongo/s/query/cluster_cursor_manager.h @@ -554,6 +554,14 @@ private: } /** + * Creates a generic cursor from the cursor inside this entry. Should only be called on + * idle cursors. The caller must supply the cursorId and namespace because the CursorEntry + * does not have access to them. Cannot be called if this CursorEntry does not own an + * underlying ClusterClientCursor. + */ + GenericCursor cursorToGenericCursor(CursorId cursorId, const NamespaceString& ns) const; + + /** * Returns the cursor owned by this CursorEntry for an operation to use. Only one operation * may use the cursor at a time, so callers should check that getOperationUsingCursor() * returns null before using this function. Callers may pass nullptr, but only if the |