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

$where queries block execution of other operations

    • Type: Icon: Bug Bug
    • Resolution: Works as Designed
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 8.0.4, 7.0.16
    • Component/s: None
    • Query Integration
    • ALL
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      I'm simulating slow queries via find+$where+sleep and see other operations on other connections (which should be fast) start to block. For example:

      import sys
      import time
      
      import pymongo
      from pymongo import MongoClient
      from pymongo.errors import PyMongoError
      from threading import Thread
      
      client = MongoClient("mongodb://localhost:27017/")
      coll1 = client.test1.test1
      coll2 = client.test1.test1
      N_SLOW_FINDS = 20
      
      
      coll1.insert_one({})
      coll2.insert_one({})
      mdb_version = client.server_info()["version"]
      print(f"MongoDB: {mdb_version}, PyMongo: {pymongo.__version__}, Python: {sys.version}")
      
      def slow_find():
          coll1.find_one({"$where": "sleep(5000) || true"}, comment="FIND_SLOW")
      
      def fast_find():
          start = time.monotonic()
          try:
              # coll1.database.list_collection_names()
              coll2.find_one({"_id": 1}, comment="FIND_FAST")
          except PyMongoError as exc:
              print(f"FIND_FAST failed after {time.monotonic()-start} seconds: {exc}")
          else:
              print(f"FIND_FAST succeeded after {time.monotonic() - start} seconds")
      
      # Run fast find once to get a baseline.
      fast_find()
      
      print(f"Starting {N_SLOW_FINDS} slow find operations in parallel")
      threads = [Thread(target=slow_find) for _ in range(N_SLOW_FINDS)]
      for t in threads:
          t.start()
      
      # Run fast find again to show that it blocks on the slow finds.
      time.sleep(0.5)  # Sleep to ensure the above finds have started.
      fast_find()
      
      for t in threads:
          t.join()
      

      And the output:

      $ python3 repro-find-hang-where.py
      MongoDB: 7.0.16, PyMongo: 4.12.0.dev0, Python: 3.13.0 (v3.13.0:60403a5409f, Oct  7 2024, 00:37:40) [Clang 15.0.0 (clang-1500.3.9.4)]
      FIND_FAST succeeded after 0.000891833973582834 seconds
      Starting 20 slow find operations in parallel
      FIND_FAST succeeded after 4.556467916991096 seconds
      

      Is this a known limitation? I would expect the FIND_FAST operation to run quickly regardless of how many slow $where queries are running. I tested on 7.0.16 and 8.0.4 mongod and see the same behavior.

            Assignee:
            santiago.roche@mongodb.com Santiago Roche
            Reporter:
            shane.harvey@mongodb.com Shane Harvey
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved:
              None
              None
              None
              None