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

Make 'reIndex' a standalone-only command

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 4.7.0
    • Affects Version/s: 4.2.1, 4.3.1
    • Component/s: Replication, Storage
    • None
    • Minor Change
    • ALL
    • Hide

      Run the following script using --suites=replica_sets.

      (function() {
          "use strict";
          load("jstests/core/txns/libs/prepare_helpers.js");
          
          const dbName = "test";
          const collName = "re_index_secondary_with_prepared_transaction";
      
          const rst = new ReplSetTest({
              nodes: [
                  {},
                  {rsConfig: {priority: 0}},
              ],
          });
          rst.startSet();
          rst.initiate();
          
          const primary = rst.getPrimary();
          const secondary = rst.getSecondary();
          const testDB = primary.getDB(dbName);
          
          assert.commandWorked(testDB.runCommand({create: collName, writeConcern: {w: "majority"}}));
      
          const priSession = primary.startSession({causalConsistency: false});
          const priSessionDB = priSession.getDatabase(dbName);
          const priSessionColl = priSessionDB.getCollection(collName);
      
          priSession.startTransaction();
          assert.commandWorked(priSessionColl.insert({_id: 1}));
          const prepareTimestamp = PrepareHelpers.prepareTransaction(priSession);
      
          rst.awaitReplication();
      
          // Add 1 to the increment so that the commitTimestamp is "after" the prepareTimestamp.
          const commitTimestamp = Timestamp(prepareTimestamp.getTime(), prepareTimestamp.getInc() + 1);
      
          // Run 'reIndex' on the secondary.
          assert.commandWorked(secondary.getDB(dbName).runCommand({reIndex: collName}));
      
          assert.commandWorked(PrepareHelpers.commitTransaction(priSession, commitTimestamp));
          rst.awaitReplication();
      
          assert.commandWorked(secondary.getDB(dbName).runCommand({validate: collName}));
          
          rst.stopSet();
          })();
      
      Show
      Run the following script using --suites=replica_sets. ( function () { "use strict" ; load( "jstests/core/txns/libs/prepare_helpers.js" ); const dbName = "test" ; const collName = "re_index_secondary_with_prepared_transaction" ; const rst = new ReplSetTest({ nodes: [ {}, {rsConfig: {priority: 0}}, ], }); rst.startSet(); rst.initiate(); const primary = rst.getPrimary(); const secondary = rst.getSecondary(); const testDB = primary.getDB(dbName); assert.commandWorked(testDB.runCommand({create: collName, writeConcern: {w: "majority" }})); const priSession = primary.startSession({causalConsistency: false }); const priSessionDB = priSession.getDatabase(dbName); const priSessionColl = priSessionDB.getCollection(collName); priSession.startTransaction(); assert.commandWorked(priSessionColl.insert({_id: 1})); const prepareTimestamp = PrepareHelpers.prepareTransaction(priSession); rst.awaitReplication(); // Add 1 to the increment so that the commitTimestamp is "after" the prepareTimestamp. const commitTimestamp = Timestamp(prepareTimestamp.getTime(), prepareTimestamp.getInc() + 1); // Run 'reIndex' on the secondary. assert.commandWorked(secondary.getDB(dbName).runCommand({reIndex: collName})); assert.commandWorked(PrepareHelpers.commitTransaction(priSession, commitTimestamp)); rst.awaitReplication(); assert.commandWorked(secondary.getDB(dbName).runCommand({validate: collName})); rst.stopSet(); })();
    • Repl 2019-12-02, Repl 2019-12-16, Repl 2019-12-30, Repl 2020-01-13, Repl 2020-03-09, Repl 2020-03-23, Repl 2020-04-06, Repl 2020-04-20
    • 14

      Trying to run the 'reIndex' command on a secondary while having unfinished prepared transactions will hit an invariant. After dropping the index that will be re-indexed, we hit an invariant when doing a collection scan to insert all the documents in the collection for that index.

      Invariant failure lock.mode != MODE_S && lock.mode != MODE_X {6917529027641081857: Global, 1} in X src/mongo/db/storage/wiredtiger/wiredtiger_prepare_conflict.h 111
      

      ldeng recommended to try set the 'canIgnorePrepareConflicts' flag to true for the 'reIndex' command but that ended up hitting another invariant while trying to drop all the indexes.

      WiredTiger error (95) [1572545292:296845][8488:0x7f381342b700], file:_mdb_catalog.wt, WT_CURSOR.insert: __wt_txn_modify, 463: Transactions with ignore_prepare=true cannot perform updates: Operation not supported Raw: [1572545292:296845][8488:0x7f381342b700], file:_mdb_catalog.wt, WT_CURSOR.insert: __wt_txn_modify, 463: Transactions with ignore_prepare=true cannot perform updates: Operation not supported
      
      Invariant failure: ret resulted in status UnknownError: 95: Operation not supported at src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp 1442
      

      We should consider disallowing the 'reIndex' command from running on secondaries and removing it in a future release.

            Assignee:
            samy.lanka@mongodb.com Samyukta Lanka
            Reporter:
            gregory.wlodarek@mongodb.com Gregory Wlodarek
            Votes:
            0 Vote for this issue
            Watchers:
            11 Start watching this issue

              Created:
              Updated:
              Resolved: