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

getMore requests do not use a session in the mongo shell

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major - P3
    • Resolution: Fixed
    • None
    • 3.6.0-rc0
    • Shell
    • Fully Compatible
    • ALL
    • Hide

      /**
       * Tests that "getMore" commands use the same session id as the original "find" command when a
       * cursor is created in the mongo shell.
       */
      (function() {
          "use strict";
       
          load("jstests/libs/parallelTester.js");
       
          const conn = MongoRunner.runMongod({});
       
          const db = conn.startSession().getDatabase("test");
          const coll = db.repro_nosession_getmore;
       
          const insertRes = coll.insert([{}, {}, {}, {}, {}]);
          assert.writeOK(insertRes);
          assert.eq(5, insertRes.nInserted);
       
          const triggeredFind = new CountDownLatch(1);
          const triggerGetMore = new CountDownLatch(1);
       
          function runFindAndThenGetMore(host, triggeredFind, triggerGetMore) {
              try {
                  const conn = new Mongo(host);
                  const db = conn.startSession().getDatabase("test");
                  const coll = db.repro_nosession_getmore;
       
                  const cursor = coll.find().batchSize(2);
                  cursor.next();
                  cursor.next();
       
                  triggeredFind.countDown();
                  triggerGetMore.await();
       
                  cursor.next();
                  return {ok: 1};
              } catch (e) {
                  return {ok: 0, error: e.toString(), stack: e.stack};
              }
          }
       
          assert.commandWorked(conn.adminCommand({setParameter: 1, internalQueryExecYieldIterations: 1}));
          assert.commandWorked(
              conn.adminCommand({configureFailPoint: "setYieldAllLocksHang", mode: "alwaysOn"}));
       
          //
          // Run a "find" command and verify that it has a session id.
          //
       
          const cursorThread =
              new ScopedThread(runFindAndThenGetMore, conn.host, triggeredFind, triggerGetMore);
          cursorThread.start();
       
          let op;
          let currentOpRes;
       
          assert.soon(
              function() {
                  currentOpRes = assert.commandWorked(db.currentOp({ns: coll.getFullName()}));
                  if (currentOpRes.inprog.length === 1 && currentOpRes.inprog[0].numYields > 0) {
                      op = currentOpRes.inprog[0];
                      return true;
                  }
                  return false;
              },
              function() {
                  return "Failed to find operation in currentOp() output: " + tojson(currentOpRes);
              });
       
          assert(op.hasOwnProperty("lsid"),
                 "Expected 'find' command to have a session id: " + tojson(op));
          const sessionId = op.lsid;
       
          // Disable the failpoint and wait until 'cursorThread' has consumed the documents returned in
          // the "find" command's initial batch.
          assert.commandWorked(
              conn.adminCommand({configureFailPoint: "setYieldAllLocksHang", mode: "off"}));
       
          triggeredFind.await();
       
          assert.commandWorked(
              conn.adminCommand({configureFailPoint: "setYieldAllLocksHang", mode: "alwaysOn"}));
       
          triggerGetMore.countDown();
       
          //
          // Run a "getMore" command and verify that it has the same session id as the "find" command.
          //
       
          assert.soon(
              function() {
                  currentOpRes = assert.commandWorked(db.currentOp({ns: coll.getFullName()}));
                  if (currentOpRes.inprog.length === 1 && currentOpRes.inprog[0].numYields > 0) {
                      op = currentOpRes.inprog[0];
                      return true;
                  }
                  return false;
              },
              function() {
                  return "Failed to find operation in currentOp() output: " + tojson(currentOpRes);
              });
       
          assert.eq(sessionId,
                    op.lsid,
                    "Expected 'getMore' command to have the same session id: " + tojson(op));
       
          // Disable the failpoint and wait for 'cursorThread' to exit.
          assert.commandWorked(
              conn.adminCommand({configureFailPoint: "setYieldAllLocksHang", mode: "off"}));
       
          cursorThread.join();
          assert.commandWorked(cursorThread.returnData());
       
          MongoRunner.stopMongod(conn);
      })();
      

      Show
      /** * Tests that "getMore" commands use the same session id as the original "find" command when a * cursor is created in the mongo shell. */ ( function () { "use strict" ;   load( "jstests/libs/parallelTester.js" );   const conn = MongoRunner.runMongod({});   const db = conn.startSession().getDatabase( "test" ); const coll = db.repro_nosession_getmore;   const insertRes = coll.insert([{}, {}, {}, {}, {}]); assert.writeOK(insertRes); assert.eq(5, insertRes.nInserted);   const triggeredFind = new CountDownLatch(1); const triggerGetMore = new CountDownLatch(1);   function runFindAndThenGetMore(host, triggeredFind, triggerGetMore) { try { const conn = new Mongo(host); const db = conn.startSession().getDatabase( "test" ); const coll = db.repro_nosession_getmore;   const cursor = coll.find().batchSize(2); cursor.next(); cursor.next();   triggeredFind.countDown(); triggerGetMore.await();   cursor.next(); return {ok: 1}; } catch (e) { return {ok: 0, error: e.toString(), stack: e.stack}; } }   assert.commandWorked(conn.adminCommand({setParameter: 1, internalQueryExecYieldIterations: 1})); assert.commandWorked( conn.adminCommand({configureFailPoint: "setYieldAllLocksHang" , mode: "alwaysOn" }));   // // Run a "find" command and verify that it has a session id. //   const cursorThread = new ScopedThread(runFindAndThenGetMore, conn.host, triggeredFind, triggerGetMore); cursorThread.start();   let op; let currentOpRes;   assert.soon( function () { currentOpRes = assert.commandWorked(db.currentOp({ns: coll.getFullName()})); if (currentOpRes.inprog.length === 1 && currentOpRes.inprog[0].numYields > 0) { op = currentOpRes.inprog[0]; return true ; } return false ; }, function () { return "Failed to find operation in currentOp() output: " + tojson(currentOpRes); });   assert(op.hasOwnProperty( "lsid" ), "Expected 'find' command to have a session id: " + tojson(op)); const sessionId = op.lsid;   // Disable the failpoint and wait until 'cursorThread' has consumed the documents returned in // the "find" command's initial batch. assert.commandWorked( conn.adminCommand({configureFailPoint: "setYieldAllLocksHang" , mode: "off" }));   triggeredFind.await();   assert.commandWorked( conn.adminCommand({configureFailPoint: "setYieldAllLocksHang" , mode: "alwaysOn" }));   triggerGetMore.countDown();   // // Run a "getMore" command and verify that it has the same session id as the "find" command. //   assert.soon( function () { currentOpRes = assert.commandWorked(db.currentOp({ns: coll.getFullName()})); if (currentOpRes.inprog.length === 1 && currentOpRes.inprog[0].numYields > 0) { op = currentOpRes.inprog[0]; return true ; } return false ; }, function () { return "Failed to find operation in currentOp() output: " + tojson(currentOpRes); });   assert.eq(sessionId, op.lsid, "Expected 'getMore' command to have the same session id: " + tojson(op));   // Disable the failpoint and wait for 'cursorThread' to exit. assert.commandWorked( conn.adminCommand({configureFailPoint: "setYieldAllLocksHang" , mode: "off" }));   cursorThread.join(); assert.commandWorked(cursorThread.returnData());   MongoRunner.stopMongod(conn); })();
    • Platforms 2017-10-02, Platforms 2017-10-23
    • 21

    Description

      The DBCommandCursor object wraps a Mongo connection object, which doesn't have a notion of being associated with a ServerSession object. This causes "getMore" operations on the cursor to not be sent with a logical session id associated with them.

      Attachments

        Issue Links

          Activity

            People

              jason.carey@mongodb.com Jason Carey
              max.hirschhorn@mongodb.com Max Hirschhorn
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: