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

Periodic query yield timer incorrectly includes last lock acquisition time in calculation of whether to trigger yield

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • 3.2.0-rc3
    • Affects Version/s: 3.1.7
    • Component/s: Querying
    • None
    • Fully Compatible
    • ALL
    • QuInt C (11/23/15)

      Each query operation with a YIELD_AUTO yield policy incurs a time-based yield after every 10ms of active operation. However, the "start time" for the 10ms calculation is incorrectly considered to be before the last yield started, as opposed to after the last yield finished. This can lead to a scenario where a query will repeatedly yield after only one unit of work has completed, if the query needs to wait in line more than 10ms for a writer to yield the lock.

      This is a regression introduced in 3.1.7 by SERVER-19374 (affects development versions 3.1.7 through 3.2.0-rc2 only).

      Reproduce with the following script, and confirming the "numYields" value displayed in the diagnostic log. The query is expected to yield 2 times, but it instead yields 8 times.

      db.foo.drop();
      for (i=0; i<10; ++i) {
          assert.writeOK(db.foo.insert({}));
      }
      assert.commandWorked(db.adminCommand({configureFailPoint: "setYieldAllLocksWait", mode: "alwaysOn", data: {waitForMillis: 1000}}));
      assert.commandWorked(db.adminCommand({setParameter: 1, internalQueryExecYieldIterations: 5}));
      db.foo.find().itcount();
      

            Assignee:
            rassi J Rassi
            Reporter:
            rassi J Rassi
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: