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

Fastcount isn't adjusted correctly when transaction started and prepared is entirely rolled back

    XMLWordPrintable

    Details

    • Backwards Compatibility:
      Fully Compatible
    • Operating System:
      ALL
    • Steps To Reproduce:
      Hide

      python buildscripts/resmoke.py --suites=no_server repro_server40517.js
      

      repro_server40517.js

      (function() {
          "use strict";
       
          load("jstests/core/txns/libs/prepare_helpers.js");
          load("jstests/replsets/libs/rollback_test.js");
       
          const rollbackTest = new RollbackTest();
          const rollbackNode = rollbackTest.getPrimary();
       
          // The makeDocs() function makes it easier to have transactions insert varying numbers of
          // documents in order to keep all possible sums of count adjustments as distinct values.
          let nextId = 0;
          const makeDocs = (numDocs) => {
              return Array.from({length: numDocs}, () => ({_id: ++nextId}));
          };
       
          const testDB = rollbackNode.getDB("test");
          assert.commandWorked(testDB.mycoll.insert(makeDocs(2)));
       
          rollbackTest.transitionToRollbackOperations();
       
          // We perform some operations on the "test.mycoll" collection aside from starting and preparing
          // a transaction in order to cause the count diff computed by replication to be non-zero.
          assert.commandWorked(testDB.mycoll.insert(makeDocs(5)));
       
          const session = rollbackNode.startSession({causalConsistency: false});
          const sessionDB = session.getDatabase(testDB.getName());
       
          session.startTransaction();
          assert.commandWorked(sessionDB.mycoll.insert(makeDocs(10)));
          PrepareHelpers.prepareTransaction(session);
       
          rollbackTest.transitionToSyncSourceOperationsBeforeRollback();
       
          // XXX: Workaround for SERVER-40322.
          assert.commandWorked(rollbackNode.adminCommand(
              {setParameter: 1, createRollbackDataFiles: false}));
       
          rollbackTest.transitionToSyncSourceOperationsDuringRollback();
          rollbackTest.transitionToSteadyStateOperations();
       
          rollbackTest.stop();
      })();
      

      Show
      python buildscripts/resmoke.py --suites=no_server repro_server40517.js repro_server40517.js ( function () { "use strict" ;   load( "jstests/core/txns/libs/prepare_helpers.js" ); load( "jstests/replsets/libs/rollback_test.js" );   const rollbackTest = new RollbackTest(); const rollbackNode = rollbackTest.getPrimary();   // The makeDocs() function makes it easier to have transactions insert varying numbers of // documents in order to keep all possible sums of count adjustments as distinct values. let nextId = 0; const makeDocs = (numDocs) => { return Array.from({length: numDocs}, () => ({_id: ++nextId})); };   const testDB = rollbackNode.getDB( "test" ); assert.commandWorked(testDB.mycoll.insert(makeDocs(2)));   rollbackTest.transitionToRollbackOperations();   // We perform some operations on the "test.mycoll" collection aside from starting and preparing // a transaction in order to cause the count diff computed by replication to be non-zero. assert.commandWorked(testDB.mycoll.insert(makeDocs(5)));   const session = rollbackNode.startSession({causalConsistency: false }); const sessionDB = session.getDatabase(testDB.getName());   session.startTransaction(); assert.commandWorked(sessionDB.mycoll.insert(makeDocs(10))); PrepareHelpers.prepareTransaction(session);   rollbackTest.transitionToSyncSourceOperationsBeforeRollback();   // XXX: Workaround for SERVER-40322. assert.commandWorked(rollbackNode.adminCommand( {setParameter: 1, createRollbackDataFiles: false }));   rollbackTest.transitionToSyncSourceOperationsDuringRollback(); rollbackTest.transitionToSteadyStateOperations();   rollbackTest.stop(); })();
    • Sprint:
      Storage NYC 2019-04-22

      Description

      Stashing the record store counts in memory via the call to _findRecordStoreCounts() is done prior to aborting the storage transaction underlying a prepared transaction. This causes the call to _correctRecordStoreCounts() to restore the counts to a version including the effects of prepared transctions that weren't majority-committed.

      [js_test:repro_server40517] 2019-04-06T10:12:58.355-0400 d20030| 2019-04-06T10:12:58.354-0400 D2 ROLLBACK [rsBackgroundSync] Record count of test.mycoll (2549dc22-8ef8-419a-b800-d565111894d7) before rollback is 17. Setting it to 12, due to change of -5
      

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              louis.williams Louis Williams
              Reporter:
              max.hirschhorn Max Hirschhorn
              Participants:
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: