...
In ViewsShardingCheck, we make an assumption that the source namespace of a view must be a collection or a nonexistent namespace. But because of $collStats, it may in fact be a view, and this overeager assumption causes a failure when running a query over a view whose first stage is $collStats and whose "viewOn" is another view. mongos> db.createView("v1", "v2", [{: {}}]) { "ok" : 1, "logicalTime" : { "clusterTime" : Timestamp(1491580269, 4), "signature" : { "hash" : BinData(0,"TC4eCke2sj28GEb7y236Nspy0ZE="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1491580269, 4) } mongos> db.createView("v2", "c", [{: {}}]) { "ok" : 1, "logicalTime" : { "clusterTime" : Timestamp(1491580277, 1), "signature" : { "hash" : BinData(0,"DYSY4YyCpNPs2tciTcRwkzusMLc="), "keyId" : NumberLong(0) } } } mongos> db.c.insert({x: 1}) WriteResult({ "nInserted" : 1 }) mongos> db.c.find() { "_id" : ObjectId("58e7b57d102c4c693c576c34"), "x" : 1 } mongos> db.v2.find() { "ns" : "test.c", "localTime" : ISODate("2017-04-07T15:51:32.358Z") } mongos> db.v1.find() Error: error: { "ok" : 0, "errmsg" : "Namespace test.v2 is a view, not a collection", "code" : 166, "codeName" : "CommandNotSupportedOnView", "logicalTime" : { "clusterTime" : Timestamp(1491580293, 1), "signature" : { "hash" : BinData(0,"3GtlKHmzhSsEx1vHk8I0Lz5F5E8="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(0, 0) } Original Description When running an aggregation on a view that starts with $collStats and has a batchSize of 0, the following error occurs: > db.runCommand( { aggregate: "view", pipeline: [ { $collStats: {} } ], cursor: { batchSize: 0 } } ) { "ok" : 0, "errmsg" : "Aggregation has more results than fit in initial batch, but can't create cursor since collection test.view doesn't exist", "code" : 17391, "codeName" : "Location17391" } Either this should work as expected, or fail with a clearer error message.
david.storch commented on Fri, 2 Aug 2019 15:00:25 +0000: As far as I can tell, this bug no longer exists: MongoDB Enterprise mongos> db.createView("v1", "v2", [{$collStats: {}}]) { "ok" : 1, "operationTime" : Timestamp(1564757734, 5), "$clusterTime" : { "clusterTime" : Timestamp(1564757734, 5), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } } MongoDB Enterprise mongos> db.createView("v2", "coll", []) { "ok" : 1, "operationTime" : Timestamp(1564757749, 5), "$clusterTime" : { "clusterTime" : Timestamp(1564757749, 5), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } } MongoDB Enterprise mongos> db.coll.insert({}) WriteResult({ "nInserted" : 1 }) MongoDB Enterprise mongos> db.v2.find() { "_id" : ObjectId("5d444ef81e6a73b6c1ebc744") } MongoDB Enterprise mongos> db.v1.find() { "ns" : "test.v2", "shard" : "__unknown_name__-rs1", "host" : "storchbox:20001", "localTime" : ISODate("2019-08-02T14:56:07.479Z") } Closing as Gone Away. kyle.suarez commented on Fri, 7 Apr 2017 16:25:33 +0000: Alright, status update. Charlie's cursor manager fixes have wholly eliminated the problem of views with batch size 0. The remaining problem is that you can't perform an operation on a view via mongos if the view's pipeline starts with a $collStats stage and its backing namespace is another view. mongos> db.createView("v1", "v2", [{: {}}]) { "ok" : 1, "logicalTime" : { "clusterTime" : Timestamp(1491580269, 4), "signature" : { "hash" : BinData(0,"TC4eCke2sj28GEb7y236Nspy0ZE="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1491580269, 4) } mongos> db.createView("v2", "c", [{: {}}]) { "ok" : 1, "logicalTime" : { "clusterTime" : Timestamp(1491580277, 1), "signature" : { "hash" : BinData(0,"DYSY4YyCpNPs2tciTcRwkzusMLc="), "keyId" : NumberLong(0) } } } mongos> db.c.insert({x: 1}) WriteResult({ "nInserted" : 1 }) mongos> db.c.find() { "_id" : ObjectId("58e7b57d102c4c693c576c34"), "x" : 1 } mongos> db.v2.find() { "ns" : "test.c", "localTime" : ISODate("2017-04-07T15:51:32.358Z") } mongos> db.v1.find() Error: error: { "ok" : 0, "errmsg" : "Namespace test.v2 is a view, not a collection", "code" : 166, "codeName" : "CommandNotSupportedOnView", "logicalTime" : { "clusterTime" : Timestamp(1491580293, 1), "signature" : { "hash" : BinData(0,"3GtlKHmzhSsEx1vHk8I0Lz5F5E8="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(0, 0) } Note that the same code works on a standalone. > db.createView("v1", "v2", [{: {}}]) { "ok" : 1 } > db.createView("v2", "c", [{: {}}]) { "ok" : 1 } > db.v2.find() { "ns" : "test.c", "localTime" : ISODate("2017-04-07T15:48:55.186Z") } > db.v1.find() { "ns" : "test.v2", "localTime" : ISODate("2017-04-07T15:48:58Z") } I've updated the ticket's description to match the current reality. david.storch commented on Mon, 3 Apr 2017 14:19:34 +0000: kyle.suarez, yeah, if this wasn't completely fixed by the global agg ownership work, then I agree that we should reopen it and mark it as "Needs Triage". kyle.suarez commented on Mon, 3 Apr 2017 13:50:38 +0000: I believe Charlie's work to make aggregation cursors owned by the global cursor manager have fixed the most serious problems regarding views and $collStats. However, jstests/core/views/views_coll_stats.js still fails in the sharding_jscore_passthrough suite: assert: command failed: { "operationTime" : Timestamp(1491226844, 11), "ok" : 0, "errmsg" : "Namespace views_coll_stats.b is a view, not a collection", "code" : 166, "codeName" : "CommandNotSupportedOnView", "logicalTime" : { "clusterTime" : Timestamp(1491226844, 11), "signature" : { "hash" : BinData(0,"Rh30yN/9DK1QsUgGGlqz3tm5MF4="), "keyId" : NumberLong(0) } } } : aggregate failed _getErrorWithCode@src/mongo/shell/utils.js:25:13 doassert@src/mongo/shell/assert.js:16:14 assert.commandWorked@src/mongo/shell/assert.js:387:5 DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1319:5 @jstests/core/views/views_coll_stats.js:57:28 @jstests/core/views/views_coll_stats.js:2:2 I'm quite certain that this is due to us taking an AutoGetCollection on the view namespace in view_sharding_check.cpp, which makes an invalid assumption that the namespace is always a collection. After fixing this, we should unblacklist views_coll_stats.js from sharding_jscore_passthrough and probably consider expanding the test coverage: Unable to find source-code formatter for language: diff. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml diff --git a/jstests/views/views_coll_stats.js b/jstests/views/views_coll_stats.js index 384fa17..a557849 100644 --- a/jstests/views/views_coll_stats.js +++ b/jstests/views/views_coll_stats.js @@ -58,6 +58,14 @@ checkCollStatsBelongTo(viewsDB["b"].aggregate().next(), "c"); clear(); + // Check for expected behavior when running an aggregation against a view which is a + // on an identity view. + makeView("a", "b", [collStatsStage]); + makeView("b", "c", []); + checkCollStatsBelongTo(viewsDB["a"].latencyStats().next(), "a"); + checkCollStatsBelongTo(viewsDB["a"].aggregate().next(), "b"); + clear(); + // Assert that attempting to retrieve storageStats fails. makeView("a", "b"); assert.commandFailedWithCode( david.storch, can I reopen this ticket and send it to triage? charlie.swanson commented on Thu, 16 Mar 2017 15:43:47 +0000: This has been resolved by work on SERVER-22541, specifically this commit. kyle.suarez commented on Tue, 13 Dec 2016 22:53:53 +0000: This fails because when PipelineCmd::runParsed() detects that a $collStats is run against a view, it skips view resolution altogether. Then, the aggregation proceeds as usual, but on a namespace that's a view. However, views don't have a cursor manager and rely on a backing collection on which to hang the cursor, so we find ourselves out of luck with regard to constructing a cursor in this case.
db.runCommand( { create: "view", viewOn: "collection" } ); db.runCommand( { aggregate: "view", pipeline: [ { $collStats: {} } ], cursor: { batchSize: 0 } } );