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

Equality queries on _id with projection on _id may return orphan documents on sharded collections

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Critical - P2 Critical - P2
    • 2.6.3, 2.7.3
    • Affects Version/s: 2.6.0, 2.6.1, 2.6.2
    • Component/s: Querying, Sharding
    • None
    • ALL

      Issue Status as of Jun 19, 2014

      ISSUE SUMMARY
      Queries on sharded collections that include an equality predicate on _id and specify a projection on {_id:1} (with no additional fields) may erroneously return orphan documents.

      Example:

      The following query has an equality predicate on _id and a projection on {_id:1} and is thus affected by the bug. It returns any orphaned documents present on any shards targeted by the query.

      db.coll.find({_id:ObjectId("53a349440d3a24cdc742e1df"), baz:50}, {_id:1})
      

      USER IMPACT
      Queries on sharded collections that match the above conditions can return incorrect or duplicated results.

      WORKAROUNDS
      Add a hint of {_id:1} to these queries to avoid the issue.

      AFFECTED VERSIONS
      MongoDB production releases 2.6.0 - 2.6.2 are affected by this issue.

      FIX VERSION
      The fix is included in the 2.6.3 production release.

      RESOLUTION DETAILS
      The IDHackRunner has been changed to no longer allow covered projections on sharded connections.

      Original description

      If a sharded query that includes an equality predicate on _id and a projection of {_id: 1} targets shards with matching orphan documents, then the orphans will incorrectly be returned by the query.

      The cause of this issue is a regression introduced in 2.6.0-rc2 (SERVER-12902). IDHackRunner incorrectly allows covered projections on sharded connections, and as such does not apply the sharding filter (which removes orphan documents).

      Reproduce with the following:

      var st = new ShardingTest({shards: 2});
      var collName = "test.foo";
      var collRouter = st.s0.getCollection(collName);
      var collShard0 = st.shard0.getCollection(collName);
      var collShard1 = st.shard1.getCollection(collName);
      assert.commandWorked(collRouter.getDB().adminCommand({enableSharding: "test"}));
      assert.commandWorked(collRouter.getDB().adminCommand({shardCollection: "test.foo",
                                                            key: {x: "hashed"}}));
      assert.writeOK(collShard0.insert({_id: 1, x: 1}));
      assert.writeOK(collShard1.insert({_id: 1, x: 1}));
      assert.eq(2, collRouter.count());
      assert.eq(1, collRouter.find().itcount());
      assert.eq(1, collRouter.find({_id: 1}, {_id: 1}).itcount()); // Fails with "[1] != [2] are not equal".
      

            Assignee:
            rassi J Rassi
            Reporter:
            rassi J Rassi
            Votes:
            0 Vote for this issue
            Watchers:
            9 Start watching this issue

              Created:
              Updated:
              Resolved: