Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-53083

collStats results depend on topology and option.

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 4.9.0
    • Affects Version/s: None
    • Component/s: None
    • None
    • Fully Compatible
    • ALL
    • Hide

      1) Setup a mongod instance.
      2) Connect to the mongod instance and run the following commands producing the following output:

      > db.runCommand({aggregate: "dne", pipeline:[{"$collStats": {"unknown": {}}}], cursor:{}})
      {
              "ok" : 0,
              "errmsg" : "unrecognized option to $collStats: unknown",
              "code" : 40168,
              "codeName" : "Location40168"
      }
      > db.runCommand({aggregate: "dne", pipeline:[{"$collStats": {"queryExecStats": {}}}], cursor:{}})
      {
              "ok" : 0,
              "errmsg" : "PlanExecutor error during aggregation :: caused by :: Unable to retrieve queryExecStats in $collStats stage :: caused by :: Collection [test.dne] not found.",
              "code" : 26,
              "codeName" : "NamespaceNotFound"
      }
      > db.runCommand({aggregate: "dne", pipeline:[{"$collStats": {"storageStats": {}}}], cursor:{}})
      {
              "ok" : 0,
              "errmsg" : "PlanExecutor error during aggregation :: caused by :: Unable to retrieve storageStats in $collStats stage :: caused by :: Collection [test.dne] not found.",
              "code" : 26,
              "codeName" : "NamespaceNotFound"
      }
      

      3) Start a sharded cluster (e.g. by running

      let st = ShardingTest({shards: 2})

      in the mongo shell with the `--nodb` option).
      4) Connect to the mongos and run the following commands producing the following results: (if you use `ShardingTest` to start the sharded cluster the mongos should be on port 20005)

      mongos> db.runCommand({aggregate: "dne", pipeline:[{"$collStats": {"unknown": {}}}], cursor:{}})
      {
              "result" : [ ],
              "cursor" : {
                      "id" : NumberLong(0),
                      "ns" : "test.dne",
                      "firstBatch" : [ ]
              },
              "ok" : 1,
              "$clusterTime" : {
                      "clusterTime" : Timestamp(1606339832, 1),
                      "signature" : {
                              "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                              "keyId" : NumberLong(0)
                      }
              },
              "operationTime" : Timestamp(1606339832, 1)
      }
      mongos> db.runCommand({aggregate: "dne", pipeline:[{"$collStats": {"queryExecStats": {}}}], cursor:{}})
      {
              "result" : [ ],
              "cursor" : {
                      "id" : NumberLong(0),
                      "ns" : "test.dne",
                      "firstBatch" : [ ]
              },
              "ok" : 1,
              "$clusterTime" : {
                      "clusterTime" : Timestamp(1606339835, 1),
                      "signature" : {
                              "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                              "keyId" : NumberLong(0)
                      }
              },
              "operationTime" : Timestamp(1606339835, 1)
      }
      mongos> db.runCommand({aggregate: "dne", pipeline:[{"$collStats": {"storageStats": {}}}], cursor:{}})
      {
              "result" : [ ],
              "cursor" : {
                      "id" : NumberLong(0),
                      "ns" : "test.dne",
                      "firstBatch" : [ ]
              },
              "ok" : 1,
              "$clusterTime" : {
                      "clusterTime" : Timestamp(1606339835, 1),
                      "signature" : {
                              "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                              "keyId" : NumberLong(0)
                      }
              },
              "operationTime" : Timestamp(1606339835, 1)
      }
      
      Show
      1) Setup a mongod instance. 2) Connect to the mongod instance and run the following commands producing the following output: > db.runCommand({aggregate: "dne" , pipeline:[{ "$collStats" : { "unknown" : {}}}], cursor:{}}) { "ok" : 0, "errmsg" : "unrecognized option to $collStats: unknown" , "code" : 40168, "codeName" : "Location40168" } > db.runCommand({aggregate: "dne" , pipeline:[{ "$collStats" : { "queryExecStats" : {}}}], cursor:{}}) { "ok" : 0, "errmsg" : "PlanExecutor error during aggregation :: caused by :: Unable to retrieve queryExecStats in $collStats stage :: caused by :: Collection [test.dne] not found." , "code" : 26, "codeName" : "NamespaceNotFound" } > db.runCommand({aggregate: "dne" , pipeline:[{ "$collStats" : { "storageStats" : {}}}], cursor:{}}) { "ok" : 0, "errmsg" : "PlanExecutor error during aggregation :: caused by :: Unable to retrieve storageStats in $collStats stage :: caused by :: Collection [test.dne] not found." , "code" : 26, "codeName" : "NamespaceNotFound" } 3) Start a sharded cluster (e.g. by running let st = ShardingTest({shards: 2}) in the mongo shell with the `--nodb` option). 4) Connect to the mongos and run the following commands producing the following results: (if you use `ShardingTest` to start the sharded cluster the mongos should be on port 20005) mongos> db.runCommand({aggregate: "dne" , pipeline:[{ "$collStats" : { "unknown" : {}}}], cursor:{}}) { "result" : [ ], "cursor" : { "id" : NumberLong(0), "ns" : "test.dne" , "firstBatch" : [ ] }, "ok" : 1, "$clusterTime" : { "clusterTime" : Timestamp(1606339832, 1), "signature" : { "hash" : BinData(0, "AAAAAAAAAAAAAAAAAAAAAAAAAAA=" ), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1606339832, 1) } mongos> db.runCommand({aggregate: "dne" , pipeline:[{ "$collStats" : { "queryExecStats" : {}}}], cursor:{}}) { "result" : [ ], "cursor" : { "id" : NumberLong(0), "ns" : "test.dne" , "firstBatch" : [ ] }, "ok" : 1, "$clusterTime" : { "clusterTime" : Timestamp(1606339835, 1), "signature" : { "hash" : BinData(0, "AAAAAAAAAAAAAAAAAAAAAAAAAAA=" ), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1606339835, 1) } mongos> db.runCommand({aggregate: "dne" , pipeline:[{ "$collStats" : { "storageStats" : {}}}], cursor:{}}) { "result" : [ ], "cursor" : { "id" : NumberLong(0), "ns" : "test.dne" , "firstBatch" : [ ] }, "ok" : 1, "$clusterTime" : { "clusterTime" : Timestamp(1606339835, 1), "signature" : { "hash" : BinData(0, "AAAAAAAAAAAAAAAAAAAAAAAAAAA=" ), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1606339835, 1) }
    • Query 2020-12-28, Query 2021-01-25, Query Optimization 2021-02-22, Query Optimization 2021-03-08, Query Optimization 2021-03-22, Query Optimization 2021-04-05

      In three additional cases (beyond the ones described in SERVER-35479 and SERVER-35522) the results of collStats depends on the topology of the server.

      Currently, if one attaches to a standalone instance of mongo, one will receive the NamespaceNotFound error code if one asks for collStats with the queryExecStats or storageStats options on a namespace that doesn't exist (e.g. "dne"). Additionally, one will receive a numeric error code if one passes an unknown option (e.g. "unknown").

      However, if one connects to a mongos the NamespaceNotFound errors will be suppressed by the mongos instance if one pass such options to a namespace that doesn't exist. Additionally, because we don't validate that the options passed to collStats are correct when we do a "light parse" of the pipeline we actually get a NamespaceNotFound error when we get the routing info which then gets suppressed by the same code path if one asks for collStats on a collection that doesn't exist with an unknown option.

      Resolution of this ticket should include:
      1) Stopping mongos from suppressing namespace not found errors.
      2) Ensuring that mongos produces an option validation error before a namespace not found error in the event of unknown options being passed to a collStats stage being run on a nonexistent namespace.
      3) Tests to verify that collStats behaves correctly regardless of topology.

            Assignee:
            ruslan.abdulkhalikov@mongodb.com Ruslan Abdulkhalikov (Inactive)
            Reporter:
            samuel.mercier@mongodb.com Sam Mercier
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved: