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

    • Fully Compatible
    • ALL
    • 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(); })();
    • Storage NYC 2019-04-22

      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
      

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

              Created:
              Updated:
              Resolved: