Index build retrying skipped records can result in untimestamped catalog writes

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Fixed
    • Priority: Major - P3
    • 5.2.0
    • Affects Version/s: None
    • Component/s: None
    • None
    • Fully Compatible
    • ALL
    • Execution Team 2021-12-13
    • 104
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      When a document's field to be indexed does not conform to the requirements of the index type, we keep track of that document using the SkippedRecordTracker. Then at the end of the index build, we check that each of these skipped records either no longer exists or has been updated to conform to the index type. These writes (both to the index and the SkippedRecordTracker table itself) are performed without a timestamp. In the case where the document was updated, if the new updated record also causes the index to be flipped to multikey, the multikey-flipping catalog write also gets performed without a timestamp. The following test can be used to reproduce this:

      /**
       * Reproduces SERVER-61606.
       */
      (function() {
      'use strict';
      
      load('jstests/libs/fail_point_util.js');
      load('jstests/libs/parallel_shell_helpers.js');
      
      const replTest = new ReplSetTest({nodes: 1});
      replTest.startSet();
      replTest.initiate();
      
      const primary = replTest.getPrimary();
      const coll = primary.getDB('test')[jsTestName()];
      
      assert.commandWorked(coll.insert([
          {
              _id: 0,
              a: {loc: {type: 'Point', coordinates: [-73.97, 40.77]}, num: 0},
          },
          {
              _id: 1,
              a: {
                  loc: {
                      type: 'Polygon',
                      coordinates: [
                          // One square.
                          [[9, 9], [9, 11], [11, 11], [11, 9], [9, 9]],
                          // Another disjoint square.
                          [[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]
                      ]
                  },
                  num: 1,
              }
          }
      ]));
      
      const fp = configureFailPoint(primary, 'hangAfterIndexBuildFirstDrain');
      const awaitCreateIndex = startParallelShell(
          funWithArgs(function(collName) {
              assert.commandWorked(db[collName].createIndex({'a.loc': '2dsphere', 'a.num': 1}));
          }, coll.getName()), primary.port);
      fp.wait();
      
      assert.commandWorked(coll.update({_id: 1}, {
          a: {loc: {type: 'Point', coordinates: [-73.88, 40.78]}, num: [1, 1]},
      }));
      
      fp.off();
      awaitCreateIndex();
      
      replTest.stopSet();
      })();
      

            Assignee:
            Gregory Noma
            Reporter:
            Gregory Noma
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: