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

View graph invalid on WriteUnitOfWork rollback

    XMLWordPrintableJSON

Details

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Major - P3 Major - P3
    • 3.3.14
    • None
    • Storage
    • Major Change
    • ALL
    • Hide

      Reproducible via WIP fsm test for views cycle detection (SERVER-25808):

      'use strict';
       
      /**
       * view_catalog_cycle_with_drop.js
       *
       *
       */
       
      load('jstests/concurrency/fsm_workload_helpers/drop_utils.js');  // for dropCollections
       
      var $config = (function() {
       
          var data = {
              // Use the workload name as a prefix for the view names,
              // since the workload name is assumed to be unique.
              prefix: 'view_catalog_cycle_with_drop',
              viewList: ["viewA", "viewB", "viewC"],
          };
       
          function assertIfNotOKAndNotCode(result, code) {
              assertAlways(result.ok === 1 || (result.ok === 0 && result.code !== code, tojson(result)));
          }
       
          var states = (function() {
              function init(db, colName) {
              }
       
              function remapViewToView(db, colName) {
                  let fromName = this.viewList[Random.randInt(3)];
                  let toName = this.viewList[Random.randInt(3)];
                  let res = db.runCommand({collMod: fromName, viewOn: toName, pipeline: []});
                  assertIfNotOKAndNotCode(res, ErrorCodes.GraphContainsCycle);
              }
       
              function readFromView(db, colName) {
                  let viewName = this.viewList[Random.randInt(3)];
                  assert.commandWorked(db.runCommand({find: viewName}),
                                       viewName + ": " + tojson(db.runCommand({listCollections: 1})));
              }
       
              return {
                  init: init,
                  remapViewToView: remapViewToView,
                  readFromView: readFromView
              };
       
          })();
       
          var transitions = {
              init: {remapViewToView: .75, readFromView: .25},
              remapViewToView: {remapViewToView: .75, readFromView: .25},
              readFromView: {remapViewToView: .50, readFromView: .50},
          };
       
       
          function setup(db, collName, cluster) {
              // Setup base collection & populate.
              let col = db[collName];
       
              assertAlways.writeOK(col.insert({x: 1}));
       
              for (var i in this.viewList) {
                  db.createView(this.viewList[i], collName, []);
              }
       
              jsTest.log(tojson(db.runCommand({listCollections: 1})));
          };
       
          function teardown(db, collName, cluster) {
              var pattern = new RegExp('^' + this.prefix + '_\\d+$');
              dropCollections(db, pattern);
          };
       
          return {
              threadCount: 100,
              iterations: 100,
              data: data,
              states: states,
              transitions: transitions,
              setup: setup,
              teardown: teardown,
          };
       
      })();
      

      Show
      Reproducible via WIP fsm test for views cycle detection ( SERVER-25808 ): 'use strict';   /** * view_catalog_cycle_with_drop.js * * */   load('jstests/concurrency/fsm_workload_helpers/drop_utils.js'); // for dropCollections   var $config = (function() {   var data = { // Use the workload name as a prefix for the view names, // since the workload name is assumed to be unique. prefix: 'view_catalog_cycle_with_drop', viewList: ["viewA", "viewB", "viewC"], };   function assertIfNotOKAndNotCode(result, code) { assertAlways(result.ok === 1 || (result.ok === 0 && result.code !== code, tojson(result))); }   var states = (function() { function init(db, colName) { }   function remapViewToView(db, colName) { let fromName = this.viewList[Random.randInt(3)]; let toName = this.viewList[Random.randInt(3)]; let res = db.runCommand({collMod: fromName, viewOn: toName, pipeline: []}); assertIfNotOKAndNotCode(res, ErrorCodes.GraphContainsCycle); }   function readFromView(db, colName) { let viewName = this.viewList[Random.randInt(3)]; assert.commandWorked(db.runCommand({find: viewName}), viewName + ": " + tojson(db.runCommand({listCollections: 1}))); }   return { init: init, remapViewToView: remapViewToView, readFromView: readFromView };   })();   var transitions = { init: {remapViewToView: .75, readFromView: .25}, remapViewToView: {remapViewToView: .75, readFromView: .25}, readFromView: {remapViewToView: .50, readFromView: .50}, };     function setup(db, collName, cluster) { // Setup base collection & populate. let col = db[collName];   assertAlways.writeOK(col.insert({x: 1}));   for (var i in this.viewList) { db.createView(this.viewList[i], collName, []); }   jsTest.log(tojson(db.runCommand({listCollections: 1}))); };   function teardown(db, collName, cluster) { var pattern = new RegExp('^' + this.prefix + '_\\d+$'); dropCollections(db, pattern); };   return { threadCount: 100, iterations: 100, data: data, states: states, transitions: transitions, setup: setup, teardown: teardown, };   })();

    Description

      ViewCatalog::_upsertIntoGraph sets _viewGraphNeedsRefresh to false on successful insert, but does not take into account post-insert rollback. This can lead to successful creation of view definition cycles.

      _viewGraphNeedsRefresh should be set back to true on rollback.

      Attachments

        Activity

          People

            james.wahlin@mongodb.com James Wahlin
            james.wahlin@mongodb.com James Wahlin
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: