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

Creating a collection or a view should fail if a bucket namespace exists without its view

    • Type: Icon: Bug Bug
    • Resolution: Unresolved
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 5.0.0, 6.0.0, 7.0.0, 8.1.0-rc0, 8.0.0-rc6
    • Component/s: None
    • None
    • Catalog and Routing
    • ALL
    • v8.0, v7.0, v6.0, v5.0
    • Hide
      // Create collection works if a bucket namespace exists without its view
      {
          const coll1 = db.getCollection('coll1');
      
          st.shard0.adminCommand({
              configureFailPoint: "failTimeseriesViewCreation",
              mode: "alwaysOn",
              data: {ns: coll1.getFullName()}
          })
      
          db.createCollection(coll1.getName(), {timeseries: {timeField: "time"}});
          assert.commandWorked(db.createCollection(coll1.getName()));
      
          const collInfos = db.getCollectionInfos();
          jsTestLog("listCollections1: " + tojson(collInfos));
      }
      
      // Create view works if a bucket namespace exists without its view
      {
          const coll2 = db.getCollection('coll2');
          const collViewOn = db.getCollection("collViewOn");
      
          st.shard0.adminCommand({
              configureFailPoint: "failTimeseriesViewCreation",
              mode: "alwaysOn",
              data: {ns: coll2.getFullName()}
          });
      
          db.createCollection(coll2.getName(), {timeseries: {timeField: "time"}});
          st.shard0.adminCommand({configureFailPoint: "failTimeseriesViewCreation", mode: "off"});
      
          assert.commandWorked(db.createCollection(collViewOn.getName()));
          assert.commandWorked(db.createView(coll2.getName(), collViewOn.getName(), []));
      
          const collInfos = db.getCollectionInfos();
          jsTestLog("listCollections2: " + tojson(collInfos));
      }
      
      diff --git a/src/mongo/db/catalog/create_collection.cpp b/src/mongo/db/catalog/create_collection.cpp
      index a5065d64376..0281c5c3ddd 100644
      --- a/src/mongo/db/catalog/create_collection.cpp
      +++ b/src/mongo/db/catalog/create_collection.cpp
      @@ -313,7 +313,7 @@ Status _createView(OperationContext* opCtx,
                   LOGV2(5490200,
                         "failTimeseriesViewCreation fail point enabled. Failing creation of view "
                         "definition.");
      -            return Status{ErrorCodes::OperationFailed,
      +            return Status{ErrorCodes::NamespaceExists,
                                 str::stream() << "View definition " << nss.toStringForErrorMsg()
                                               << " creation failed due to 'failTimeseriesViewCreation' "
                                                  "fail point enabled."}; 
      
      Show
      // Create collection works if a bucket namespace exists without its view { const coll1 = db.getCollection('coll1'); st.shard0.adminCommand({ configureFailPoint: "failTimeseriesViewCreation", mode: "alwaysOn", data: {ns: coll1.getFullName()} }) db.createCollection(coll1.getName(), {timeseries: {timeField: "time"}}); assert.commandWorked(db.createCollection(coll1.getName())); const collInfos = db.getCollectionInfos(); jsTestLog("listCollections1: " + tojson(collInfos)); } // Create view works if a bucket namespace exists without its view { const coll2 = db.getCollection('coll2'); const collViewOn = db.getCollection("collViewOn"); st.shard0.adminCommand({ configureFailPoint: "failTimeseriesViewCreation", mode: "alwaysOn", data: {ns: coll2.getFullName()} }); db.createCollection(coll2.getName(), {timeseries: {timeField: "time"}}); st.shard0.adminCommand({configureFailPoint: "failTimeseriesViewCreation", mode: "off"}); assert.commandWorked(db.createCollection(collViewOn.getName())); assert.commandWorked(db.createView(coll2.getName(), collViewOn.getName(), [])); const collInfos = db.getCollectionInfos(); jsTestLog("listCollections2: " + tojson(collInfos)); } diff --git a/src/mongo/db/catalog/create_collection.cpp b/src/mongo/db/catalog/create_collection.cpp index a5065d64376..0281c5c3ddd 100644 --- a/src/mongo/db/catalog/create_collection.cpp +++ b/src/mongo/db/catalog/create_collection.cpp @@ -313,7 +313,7 @@ Status _createView(OperationContext* opCtx, LOGV2(5490200, "failTimeseriesViewCreation fail point enabled. Failing creation of view " "definition."); - return Status{ErrorCodes::OperationFailed, + return Status{ErrorCodes::NamespaceExists, str::stream() << "View definition " << nss.toStringForErrorMsg() << " creation failed due to 'failTimeseriesViewCreation' " "fail point enabled."};
    • CAR Team 2024-06-10
    • 200

      When a bucket namespace exists without its view (which may happen due to SERVER-85855 or because the creation of a timeseries collection has failed before creating the view), it is possible to create a collection or a view with the same name, leading to an inconsistency in the catalog.

      db.createCollection('coll', {timeseries: {...}});  // view fail but the bucket has been created
      db.createCollection('coll');  // succeed
      // At this point, the collections db.coll and db.system.buckets.coll coexist 
      db.createCollection('coll', {timeseries: {...}});  // view fail but the bucket has been created
      db.createView('coll','otherColl');  // succeed
      // At this point, the view db.coll targeting 'otherColl' and the collection db.system.buckets.coll coexist

      As a side note, this has been fixed under the featureFlagTrackUnshardedCollectionsUponCreation for the create command under SERVER-81190, however, there is no plan to enable this feature flag sooner than v8.3.

            Assignee:
            Unassigned Unassigned
            Reporter:
            silvia.surroca@mongodb.com Silvia Surroca
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated: