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

MapReduce with single reduce optimization fails when merging results in sharded cluster

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 4.4.19, 5.0.15, 6.0.4, 6.3.0-rc0
    • Affects Version/s: None
    • Component/s: None
    • Labels:
      None
    • Fully Compatible
    • ALL
    • v6.2, v6.1, v6.0, v5.0, v4.4
    • Hide

      Resmoke test:

      (function() {
      const st = new ShardingTest({
          shards: 2,
          mongos: 1,
          other: {
              mongosOptions: {setParameter: {mrEnableSingleReduceOptimization: true}},
              shardOptions: {setParameter: {mrEnableSingleReduceOptimization: true}},
          }
      });
      
      const mongosDB = st.s0.getDB(jsTestName());
      const mongosColl = mongosDB[jsTestName()];
      
      assert.commandWorked(mongosDB.dropDatabase());
      assert.commandWorked(mongosDB.adminCommand({enableSharding: mongosDB.getName()}));
      st.ensurePrimaryShard(mongosDB.getName(), st.shard0.shardName);
      
      assert.commandWorked(
          mongosDB.adminCommand({shardCollection: mongosColl.getFullName(), key: {_id: 1}}));
      
      // Split the collection into 4 chunks: [MinKey, -100), [-100, 0), [0, 100), [100, MaxKey).
      assert.commandWorked(mongosDB.adminCommand({split: mongosColl.getFullName(), middle: {_id: 0}}));
      
      // Move the [0, 100) and [100, MaxKey) chunks to shard1.
      assert.commandWorked(mongosDB.adminCommand(
          {moveChunk: mongosColl.getFullName(), find: {_id: 50}, to: st.shard1.shardName}));
      assert.commandWorked(mongosDB.adminCommand(
          {moveChunk: mongosColl.getFullName(), find: {_id: 150}, to: st.shard1.shardName}));
      
      assert.commandWorked(mongosColl.insert({_id: -1}));
      const map = function() {
          emit(0, {val: "mapped value"});
      };
      
      const reduce = function(key, values) {
          return {val: "reduced value"};
      };
      
      let res = assert.commandWorked(mongosDB.runCommand(
          {mapReduce: mongosColl.getName(), map: map, reduce: reduce, out: {inline: 1}}));
      assert.eq(res.results[0], {_id: 0, value: {val: "mapped value"}});
      
      assert.commandWorked(mongosColl.insert({_id: 1}));
      
      res = assert.commandWorked(mongosDB.runCommand(
          {mapReduce: mongosColl.getName(), map: map, reduce: reduce, out: {inline: 1}}));
      assert.eq(res.results[0], {_id: 0, value: {val: "reduced value"}});
      
      st.stop();
      }());
      
      Show
      Resmoke test: (function() { const st = new ShardingTest({ shards: 2, mongos: 1, other: { mongosOptions: {setParameter: {mrEnableSingleReduceOptimization: true }}, shardOptions: {setParameter: {mrEnableSingleReduceOptimization: true }}, } }); const mongosDB = st.s0.getDB(jsTestName()); const mongosColl = mongosDB[jsTestName()]; assert .commandWorked(mongosDB.dropDatabase()); assert .commandWorked(mongosDB.adminCommand({enableSharding: mongosDB.getName()})); st.ensurePrimaryShard(mongosDB.getName(), st.shard0.shardName); assert .commandWorked( mongosDB.adminCommand({shardCollection: mongosColl.getFullName(), key: {_id: 1}})); // Split the collection into 4 chunks: [MinKey, -100), [-100, 0), [0, 100), [100, MaxKey). assert .commandWorked(mongosDB.adminCommand({split: mongosColl.getFullName(), middle: {_id: 0}})); // Move the [0, 100) and [100, MaxKey) chunks to shard1. assert .commandWorked(mongosDB.adminCommand( {moveChunk: mongosColl.getFullName(), find: {_id: 50}, to: st.shard1.shardName})); assert .commandWorked(mongosDB.adminCommand( {moveChunk: mongosColl.getFullName(), find: {_id: 150}, to: st.shard1.shardName})); assert .commandWorked(mongosColl.insert({_id: -1})); const map = function() { emit(0, {val: "mapped value" }); }; const reduce = function(key, values) { return {val: "reduced value" }; }; let res = assert .commandWorked(mongosDB.runCommand( {mapReduce: mongosColl.getName(), map: map, reduce: reduce, out: {inline: 1}})); assert .eq(res.results[0], {_id: 0, value: {val: "mapped value" }}); assert .commandWorked(mongosColl.insert({_id: 1})); res = assert .commandWorked(mongosDB.runCommand( {mapReduce: mongosColl.getName(), map: map, reduce: reduce, out: {inline: 1}})); assert .eq(res.results[0], {_id: 0, value: {val: "reduced value" }}); st.stop(); }());
    • QO 2022-12-26

      This is because the output of $_accumulatorJsReduce has a different format depending on if `toBeMerged` is true or false. The codepath for the single reduce optimization added in SERVER-68766 does not change its output format accordingly. This ticket should make sure that the output of the accumulator respects the toBeMerged flag.

            Assignee:
            davis.haupt@mongodb.com Davis Haupt (Inactive)
            Reporter:
            davis.haupt@mongodb.com Davis Haupt (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved: