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

Deadlock involving ViewCatalog mutex

    • ALL
    • Hide
      // Hangs roughly 1 in 10 times.
      (function() {
          assert.writeOK(db.coll.insert({}));
          assert.commandWorked(db.createView("view", "coll", []));
          db.system.js.drop();
      
          var join1 = startParallelShell(
                  "for(var i = 0; i < 1000; i++) { assert.writeOK(db.system.views.remove({$isolated: true, $where: function () {return true;}})); print(\"Statement 1\");}");
      
          var join2 = startParallelShell(
                  "for(var i = 0; i < 1000; i++) { assert.writeOK(db.coll.remove({$where: function () {return true;}})); print(\"Statement 2\");}");
      
          join1();
          join2();
      })();
      
      Show
      // Hangs roughly 1 in 10 times. (function() { assert .writeOK(db.coll.insert({})); assert .commandWorked(db.createView( "view" , "coll" , [])); db.system.js.drop(); var join1 = startParallelShell( " for ( var i = 0; i < 1000; i++) { assert .writeOK(db.system.views.remove({$isolated: true , $where: function () { return true ;}})); print(\" Statement 1\ ");}" ); var join2 = startParallelShell( " for ( var i = 0; i < 1000; i++) { assert .writeOK(db.coll.remove({$where: function () { return true ;}})); print(\" Statement 2\ ");}" ); join1(); join2(); })();
    • Execution Team 2019-10-07

      The repro deadlocks in the following way:

      • Statement 1 takes a lock on db.system.views in MODE_X.
      • Statement 2 parses the $where, which causes a find to be run on db.system.js. Since there is no collection called db.system.js, we check if it is a view, which takes a mutex on the ViewCatalog.
      • Statement 1 parses the $where, which causes a find to be run on db.system.js. It waits for the mutex on the ViewCatalog.
      • Statement 2 attempts to iterate the DurableViewCatalog. It waits for a MODE_IS lock on db.system.views.

      The deadlock was introduced in this commit, which changed DBClientCursor to use read commands by default, instead of OP_QUERY. When using OP_QUERY, if a collection does not exist, we do not check whether it is a view.

            Assignee:
            xiangyu.yao@mongodb.com Xiangyu Yao (Inactive)
            Reporter:
            tess.avitabile@mongodb.com Tess Avitabile (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            14 Start watching this issue

              Created:
              Updated:
              Resolved: