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

OplogReplay query might need to scan extra oplog due to oplog visibility rules

    XMLWordPrintableJSON

Details

    • Icon: Bug Bug
    • Resolution: Works as Designed
    • Icon: Major - P3 Major - P3
    • None
    • 3.6.8, 4.0.2, 4.1.3
    • Querying
    • None
    • Storage Execution
    • ALL
    • Hide

      When the collection has not been read from, we use a collection scan:

      (function() {
          load("jstests/libs/analyze_plan.js");
       
          let t = db.getSiblingDB("local").oplog.jstests_query_oplogreplay;
          assert.commandWorked(t.getDB().createCollection(t.getName(), {capped: true, size: 16 * 1024}));
       
          for (let i = 1; i <= 10; i++) {
              assert.writeOK(t.insert({_id: i, ts: Timestamp(1000, i)}));
          }
       
          let res =
              assert.commandWorked(t.find({ts: {$gte: Timestamp(1000, 10), $lte: Timestamp(1000, 10)}})
                                       .addOption(DBQuery.Option.oplogReplay)
                                       .explain("executionStats"));
          assert.eq(res.executionStats.totalDocsExamined, 10, tojson(res));
      }());
      

      When the collection has been read from, we use the oplog start hack and only examine 1 document:

      (function() {
          load("jstests/libs/analyze_plan.js");
       
          let t = db.getSiblingDB("local").oplog.jstests_query_oplogreplay;
          assert.commandWorked(t.getDB().createCollection(t.getName(), {capped: true, size: 16 * 1024}));
       
          for (let i = 1; i <= 10; i++) {
              assert.writeOK(t.insert({_id: i, ts: Timestamp(1000, i)}));
          }
          t.find().itcount();
          let res =
              assert.commandWorked(t.find({ts: {$gte: Timestamp(1000, 10), $lte: Timestamp(1000, 10)}})
                                       .addOption(DBQuery.Option.oplogReplay)
                                       .explain("executionStats"));
          assert.eq(res.executionStats.totalDocsExamined, 1, tojson(res));
      }());
      

      Show
      When the collection has not been read from, we use a collection scan: (function() { load("jstests/libs/analyze_plan.js");   let t = db.getSiblingDB("local").oplog.jstests_query_oplogreplay; assert.commandWorked(t.getDB().createCollection(t.getName(), {capped: true, size: 16 * 1024}));   for (let i = 1; i <= 10; i++) { assert.writeOK(t.insert({_id: i, ts: Timestamp(1000, i)})); }   let res = assert.commandWorked(t.find({ts: {$gte: Timestamp(1000, 10), $lte: Timestamp(1000, 10)}}) .addOption(DBQuery.Option.oplogReplay) .explain("executionStats")); assert.eq(res.executionStats.totalDocsExamined, 10, tojson(res)); }()); When the collection has been read from, we use the oplog start hack and only examine 1 document: (function() { load("jstests/libs/analyze_plan.js");   let t = db.getSiblingDB("local").oplog.jstests_query_oplogreplay; assert.commandWorked(t.getDB().createCollection(t.getName(), {capped: true, size: 16 * 1024}));   for (let i = 1; i <= 10; i++) { assert.writeOK(t.insert({_id: i, ts: Timestamp(1000, i)})); } t.find().itcount(); let res = assert.commandWorked(t.find({ts: {$gte: Timestamp(1000, 10), $lte: Timestamp(1000, 10)}}) .addOption(DBQuery.Option.oplogReplay) .explain("executionStats")); assert.eq(res.executionStats.totalDocsExamined, 1, tojson(res)); }());

    Description

      An OplogReplay query may perform a full collection scan if the collection has not been read from, but utilize the oplog start hack if the collection has been read from. This issue was introduced in 3.6 (it does not exist in 3.4). However, it does not appear to have been introduced by SERVER-29843, since the issue does not present at that time.

      Attachments

        Activity

          People

            backlog-server-execution Backlog - Storage Execution Team
            tess.avitabile@mongodb.com Tess Avitabile (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            8 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: