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

Make 'reIndex' a standalone-only command

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major - P3
    • Resolution: Fixed
    • Affects Version/s: 4.2.1, 4.3.1
    • Fix Version/s: 4.7.0
    • Component/s: Replication, Storage
    • Labels:
      None
    • Backwards Compatibility:
      Minor Change
    • Operating System:
      ALL
    • Steps To Reproduce:
      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(); })();
    • Sprint:
      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
    • Linked BF Score:
      14

      Description

      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.

        Attachments

          Issue Links

            Activity

              People

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

                Dates

                Created:
                Updated:
                Resolved: