|
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.
|
|
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.
|
|
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.
|
|
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".
|
|
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:
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?
|
|
This has been resolved by work on SERVER-22541, specifically this commit.
|
|
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.
|
Generated at Thu Feb 08 04:15:06 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.