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

Aggregation exchange partitioning does not work correctly for dotted keys, results in invariant() failure

    XMLWordPrintableJSON

Details

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Critical - P2 Critical - P2
    • 4.1.4
    • 4.1.2
    • Aggregation Framework
    • None
    • Fully Compatible
    • ALL
    • Hide

      (function() {
          "use strict";
       
          db.c.drop();
          assert.commandWorked(db.c.insert({a: {b: -1}}));
          assert.commandWorked(db.c.insert({a: {b: 1}}));
       
          let result = assert.commandWorked(db.runCommand({
              aggregate: "c",
              pipeline: [],
              exchange: {
                  policy: "range",
                  consumers: NumberInt(2),
                  bufferSize: NumberInt(1024),
                  key: {"a.b": 1},
                  boundaries: [{"a.b": MinKey}, {"a.b": 0}, {"a.b": MaxKey}],
                  consumerids: [NumberInt(0), NumberInt(1)]
              },
              cursor: {batchSize: 0}
          }));
          assert.eq(result.cursors.length, 2);
          assert.eq(result.cursors[0].ok, true);
          assert.eq(result.cursors[1].ok, true);
          let firstCursorId = result.cursors[0].cursor.id;
          let secondCursorId = result.cursors[1].cursor.id;
       
          let firstGetMore =
              assert.commandWorked(db.runCommand({getMore: firstCursorId, collection: "c"}));
          printjson(firstGetMore);
       
          let secondGetMore =
              assert.commandWorked(db.runCommand({getMore: secondCursorId, collection: "c"}));
          printjson(secondGetMore);
      }());
      

      Show
      (function() { "use strict";   db.c.drop(); assert.commandWorked(db.c.insert({a: {b: -1}})); assert.commandWorked(db.c.insert({a: {b: 1}}));   let result = assert.commandWorked(db.runCommand({ aggregate: "c", pipeline: [], exchange: { policy: "range", consumers: NumberInt(2), bufferSize: NumberInt(1024), key: {"a.b": 1}, boundaries: [{"a.b": MinKey}, {"a.b": 0}, {"a.b": MaxKey}], consumerids: [NumberInt(0), NumberInt(1)] }, cursor: {batchSize: 0} })); assert.eq(result.cursors.length, 2); assert.eq(result.cursors[0].ok, true); assert.eq(result.cursors[1].ok, true); let firstCursorId = result.cursors[0].cursor.id; let secondCursorId = result.cursors[1].cursor.id;   let firstGetMore = assert.commandWorked(db.runCommand({getMore: firstCursorId, collection: "c"})); printjson(firstGetMore);   let secondGetMore = assert.commandWorked(db.runCommand({getMore: secondCursorId, collection: "c"})); printjson(secondGetMore); }());
    • Query 2018-09-24, Query 2018-10-08, Query 2018-10-22

    Description

      When using range-based partitioning, the Exchange class is responsible for extracting the value of the key on which we are partitioning. In practice, this will be the shard key. This key extraction is not implemented properly when the key pattern contains a dotted field:

      https://github.com/mongodb/mongo/blob/f45a68e589850bbf43c9d656bbbffa0d6b1efc79/src/mongo/db/pipeline/document_source_exchange.cpp#L284

      This can cause an invariant to be tripped when attempting to assign an input document to a particular exchange partition. See the repro steps for a detailed example.

      Attachments

        Activity

          People

            Unassigned Unassigned
            david.storch@mongodb.com David Storch
            Votes:
            0 Vote for this issue
            Watchers:
            8 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: