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

Including a "txnNumber" field on a command using "linearizable" read concern will bypass post-execution read concern wait

    • Type: Icon: Bug Bug
    • Resolution: Duplicate
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 4.1.10
    • Component/s: Replication
    • None
    • ALL
    • Hide
      
      const name = "linearizable_read_txnNum";
      const replTest = new ReplSetTest({
          name: name,
          nodes: 1,
      });
      replTest.startSet();
      replTest.initiate();
      
      const dbName = name;
      const collName = "coll";
      
      let primary = replTest.getPrimary();
      const session = primary.startSession({causalConsistency: false});
      const sessionDb = session.getDatabase(dbName);
      const sessionColl = sessionDb[collName];
      
      // Insert a doc.
      assert.commandWorked(sessionColl.insert({x:1}));
      
      jsTestLog("Running find command.");
      let res = sessionDb.runCommand({
          find: collName,
          readConcern: {level: 'linearizable'},
      });
      counters = primary.adminCommand({serverStatus: 1}).opReadConcernCounters;
      assert.eq(counters.linearizable, 1);
      
      res = sessionDb.runCommand({
          find: collName,
          readConcern: {level: 'linearizable'},
          txnNumber: NumberLong(1)
      });
      counters = primary.adminCommand({serverStatus: 1}).opReadConcernCounters;
      // This assertion will fail if we don't do a proper 'linearizable' read above.
      assert.eq(counters.linearizable, 2);
      
      
      replTest.stopSet();
      
      Show
      const name = "linearizable_read_txnNum" ; const replTest = new ReplSetTest({ name: name, nodes: 1, }); replTest.startSet(); replTest.initiate(); const dbName = name; const collName = "coll" ; let primary = replTest.getPrimary(); const session = primary.startSession({causalConsistency: false }); const sessionDb = session.getDatabase(dbName); const sessionColl = sessionDb[collName]; // Insert a doc. assert.commandWorked(sessionColl.insert({x:1})); jsTestLog( "Running find command." ); let res = sessionDb.runCommand({ find: collName, readConcern: {level: 'linearizable' }, }); counters = primary.adminCommand({serverStatus: 1}).opReadConcernCounters; assert.eq(counters.linearizable, 1); res = sessionDb.runCommand({ find: collName, readConcern: {level: 'linearizable' }, txnNumber: NumberLong(1) }); counters = primary.adminCommand({serverStatus: 1}).opReadConcernCounters; // This assertion will fail if we don 't do a proper ' linearizable' read above. assert.eq(counters.linearizable, 2); replTest.stopSet();
    • Repl 2019-05-20
    • 10

      If you run a read command on a session (e.g. 'find') at "linearizable" read concern and include a "txnNumber" field, the server will do no waiting to satisfy the linearizable read concern i.e. it will bypass the call to waitForLinearizableReadConcern. This is due to the fact that when we check out a session, which we will do when a command includes a txnNumber, we read from the transactions table inside a DBDirectClient query. The DBDirectClient overrides the original read concern on the OperationContext and so at the end of command execution, we will not wait on any read concern.

            Assignee:
            tess.avitabile@mongodb.com Tess Avitabile (Inactive)
            Reporter:
            william.schultz@mongodb.com William Schultz (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved: