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

rollback makes config.transactions fastcount inaccurate

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major - P3
    • Resolution: Won't Fix
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: Replication
    • Labels:
    • Operating System:
      ALL
    • Steps To Reproduce:
      Hide

      (function() {
          "use strict";
       
          load("jstests/replsets/libs/rollback_test.js");
       
          const testName = "rollback_transactions_count";
          const dbName = testName;
       
          let replSet = new ReplSetTest({name: testName, nodes: 3, useBridge: true});
          replSet.startSet();
       
          const nodes = replSet.nodeList();
          replSet.initiate({
              _id: testName,
              members: [
                  {_id: 0, host: nodes[0]},
                  {_id: 1, host: nodes[1]},
                  {_id: 2, host: nodes[2], arbiterOnly: true}
              ]
          });
       
          // Set up Rollback Test.
          let rollbackTest = new RollbackTest(testName, replSet);
          let primary = rollbackTest.getPrimary();
          assert.commandWorked(primary.setLogLevel(3, 'storage.recovery'));
          let testDb = primary.getDB(dbName);
       
          const txnName = "txnCollName";
       
          const session1 = primary.startSession();
          const sessionDb1 = session1.getDatabase(dbName);
          const sessionColl1 = sessionDb1[txnName];
          assert.commandWorked(sessionColl1.insert({a: 1}));
          session1.startTransaction();
          assert.commandWorked(sessionColl1.insert({b: 1}));
          session1.commitTransaction();
       
          replSet.awaitLastOpCommitted();
          assert.commandWorked(
              primary.adminCommand({configureFailPoint: 'disableSnapshotting', mode: 'alwaysOn'}));
       
          const session2 = primary.startSession();
          const sessionDb2 = session2.getDatabase(dbName);
          const sessionColl2 = sessionDb2[txnName];
          session2.startTransaction();
          assert.commandWorked(sessionColl2.insert({c: 1}));
          session2.commitTransaction();
       
          rollbackTest.transitionToRollbackOperations();
       
          session2.startTransaction();
          assert.commandWorked(sessionColl2.insert({d: 1}));
          session2.commitTransaction();
       
          const session3 = primary.startSession();
          const sessionDb3 = session3.getDatabase(dbName);
          const sessionColl3 = sessionDb3[txnName];
          session3.startTransaction();
          assert.commandWorked(sessionColl3.insert({e: 1}));
          session3.commitTransaction();
       
          rollbackTest.transitionToSyncSourceOperationsBeforeRollback();
          rollbackTest.transitionToSyncSourceOperationsDuringRollback();
          try {
              rollbackTest.transitionToSteadyStateOperations();
          } finally {
              assert.commandWorked(
                  primary.adminCommand({configureFailPoint: 'disableSnapshotting', mode: 'off'}));
          }
       
          rollbackTest.stop();
      })();
      

      Show
      (function() { "use strict";   load("jstests/replsets/libs/rollback_test.js");   const testName = "rollback_transactions_count"; const dbName = testName;   let replSet = new ReplSetTest({name: testName, nodes: 3, useBridge: true}); replSet.startSet();   const nodes = replSet.nodeList(); replSet.initiate({ _id: testName, members: [ {_id: 0, host: nodes[0]}, {_id: 1, host: nodes[1]}, {_id: 2, host: nodes[2], arbiterOnly: true} ] });   // Set up Rollback Test. let rollbackTest = new RollbackTest(testName, replSet); let primary = rollbackTest.getPrimary(); assert.commandWorked(primary.setLogLevel(3, 'storage.recovery')); let testDb = primary.getDB(dbName);   const txnName = "txnCollName";   const session1 = primary.startSession(); const sessionDb1 = session1.getDatabase(dbName); const sessionColl1 = sessionDb1[txnName]; assert.commandWorked(sessionColl1.insert({a: 1})); session1.startTransaction(); assert.commandWorked(sessionColl1.insert({b: 1})); session1.commitTransaction();   replSet.awaitLastOpCommitted(); assert.commandWorked( primary.adminCommand({configureFailPoint: 'disableSnapshotting', mode: 'alwaysOn'}));   const session2 = primary.startSession(); const sessionDb2 = session2.getDatabase(dbName); const sessionColl2 = sessionDb2[txnName]; session2.startTransaction(); assert.commandWorked(sessionColl2.insert({c: 1})); session2.commitTransaction();   rollbackTest.transitionToRollbackOperations();   session2.startTransaction(); assert.commandWorked(sessionColl2.insert({d: 1})); session2.commitTransaction();   const session3 = primary.startSession(); const sessionDb3 = session3.getDatabase(dbName); const sessionColl3 = sessionDb3[txnName]; session3.startTransaction(); assert.commandWorked(sessionColl3.insert({e: 1})); session3.commitTransaction();   rollbackTest.transitionToSyncSourceOperationsBeforeRollback(); rollbackTest.transitionToSyncSourceOperationsDuringRollback(); try { rollbackTest.transitionToSteadyStateOperations(); } finally { assert.commandWorked( primary.adminCommand({configureFailPoint: 'disableSnapshotting', mode: 'off'})); }   rollbackTest.stop(); })();

      Description

      When an applyOps entry causes a record to be upserted into the config.transactions table, it's impossible to know whether the entry changed the count of the collection or not. If it's a new session it will change the count, but if it's an existing session it won't. We would need to actually inspect the table for the existence of the session to correct this.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              backlog-server-repl Backlog - Replication Team
              Reporter:
              judah.schvimer Judah Schvimer
              Participants:
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: