diff options
author | Daniel Solnik <dansolnik@gmail.com> | 2019-06-25 14:54:09 -0400 |
---|---|---|
committer | Daniel Solnik <dansolnik@gmail.com> | 2019-07-01 13:47:50 -0400 |
commit | 0dd86314ef266490ca0d7bd76c49d3f09a7ada78 (patch) | |
tree | 5292624ad3a00bc9e352e0b0d68dd03f5f513eb2 | |
parent | 171fe8052de7705247e24f33ec5cf19c05bad193 (diff) | |
download | mongo-0dd86314ef266490ca0d7bd76c49d3f09a7ada78.tar.gz |
SERVER-40915 View namespaces now included in the LockManager's ResourceId::toString()
-rw-r--r-- | src/mongo/db/views/view_catalog.cpp | 26 | ||||
-rw-r--r-- | src/mongo/db/views/view_catalog_test.cpp | 92 |
2 files changed, 115 insertions, 3 deletions
diff --git a/src/mongo/db/views/view_catalog.cpp b/src/mongo/db/views/view_catalog.cpp index b952731f82c..2de991d959e 100644 --- a/src/mongo/db/views/view_catalog.cpp +++ b/src/mongo/db/views/view_catalog.cpp @@ -39,6 +39,7 @@ #include "mongo/base/status_with.h" #include "mongo/base/string_data.h" #include "mongo/bson/util/builder.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/database.h" #include "mongo/db/commands/feature_compatibility_version_command_parser.h" #include "mongo/db/namespace_string.h" @@ -195,9 +196,17 @@ Status ViewCatalog::_createOrUpdateView(WithLock lk, _durable->upsert(opCtx, viewName, viewDefBuilder.obj()); _viewMap[viewName.ns()] = view; - opCtx->recoveryUnit()->onRollback([this, viewName]() { + + // Register the view in the CollectionCatalog mapping from ResourceID->namespace + CollectionCatalog& catalog = CollectionCatalog::get(opCtx); + auto viewRid = ResourceId(RESOURCE_COLLECTION, viewName.ns()); + catalog.addResource(viewRid, viewName.ns()); + + opCtx->recoveryUnit()->onRollback([this, viewName, opCtx, viewRid]() { this->_viewMap.erase(viewName.ns()); this->_viewGraphNeedsRefresh = true; + CollectionCatalog& catalog = CollectionCatalog::get(opCtx); + catalog.removeResource(viewRid, viewName.ns()); }); // We may get invalidated, but we're exclusively locked, so the change must be ours. @@ -411,8 +420,12 @@ Status ViewCatalog::modifyView(OperationContext* opCtx, str::stream() << "invalid name for 'viewOn': " << viewOn.coll()); ViewDefinition savedDefinition = *viewPtr; - opCtx->recoveryUnit()->onRollback([this, viewName, savedDefinition]() { + + opCtx->recoveryUnit()->onRollback([this, viewName, savedDefinition, opCtx]() { this->_viewMap[viewName.ns()] = std::make_shared<ViewDefinition>(savedDefinition); + auto viewRid = ResourceId(RESOURCE_COLLECTION, viewName.ns()); + CollectionCatalog& catalog = CollectionCatalog::get(opCtx); + catalog.addResource(viewRid, viewName.ns()); }); return _createOrUpdateView(lk, @@ -446,9 +459,16 @@ Status ViewCatalog::dropView(OperationContext* opCtx, const NamespaceString& vie _durable->remove(opCtx, viewName); _viewGraph.remove(savedDefinition.name()); _viewMap.erase(viewName.ns()); - opCtx->recoveryUnit()->onRollback([this, viewName, savedDefinition]() { + + CollectionCatalog& catalog = CollectionCatalog::get(opCtx); + auto viewRid = ResourceId(RESOURCE_COLLECTION, viewName.ns()); + catalog.removeResource(viewRid, viewName.ns()); + + opCtx->recoveryUnit()->onRollback([this, viewName, savedDefinition, opCtx, viewRid]() { this->_viewGraphNeedsRefresh = true; this->_viewMap[viewName.ns()] = std::make_shared<ViewDefinition>(savedDefinition); + CollectionCatalog& catalog = CollectionCatalog::get(opCtx); + catalog.addResource(viewRid, viewName.ns()); }); // We may get invalidated, but we're exclusively locked, so the change must be ours. diff --git a/src/mongo/db/views/view_catalog_test.cpp b/src/mongo/db/views/view_catalog_test.cpp index 7802f9a42c5..6737a38b6a1 100644 --- a/src/mongo/db/views/view_catalog_test.cpp +++ b/src/mongo/db/views/view_catalog_test.cpp @@ -39,6 +39,8 @@ #include "mongo/bson/bsonmisc.h" #include "mongo/bson/bsonobj.h" #include "mongo/bson/bsonobjbuilder.h" +#include "mongo/db/catalog/collection_catalog.h" +#include "mongo/db/concurrency/lock_manager_defs.h" #include "mongo/db/namespace_string.h" #include "mongo/db/operation_context.h" #include "mongo/db/query/collation/collator_factory_interface.h" @@ -451,6 +453,96 @@ TEST_F(ViewCatalogFixture, LookupExistingView) { ASSERT(viewCatalog.lookup(opCtx.get(), "db.view"_sd)); } +TEST_F(ViewCatalogFixture, LookupRIDExistingView) { + const NamespaceString viewName("db.view"); + const NamespaceString viewOn("db.coll"); + + ASSERT_OK(viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation)); + + auto resourceID = ResourceId(RESOURCE_COLLECTION, "db.view"_sd); + auto& collectionCatalog = CollectionCatalog::get(opCtx.get()); + ASSERT(collectionCatalog.lookupResourceName(resourceID).get() == "db.view"); +} + +TEST_F(ViewCatalogFixture, LookupRIDExistingViewRollback) { + const NamespaceString viewName("db.view"); + const NamespaceString viewOn("db.coll"); + { + WriteUnitOfWork wunit(opCtx.get()); + ASSERT_OK( + viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation)); + } + auto resourceID = ResourceId(RESOURCE_COLLECTION, "db.view"_sd); + auto& collectionCatalog = CollectionCatalog::get(opCtx.get()); + ASSERT(!collectionCatalog.lookupResourceName(resourceID)); +} + +TEST_F(ViewCatalogFixture, LookupRIDAfterDrop) { + const NamespaceString viewName("db.view"); + const NamespaceString viewOn("db.coll"); + + ASSERT_OK(viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation)); + ASSERT_OK(viewCatalog.dropView(opCtx.get(), viewName)); + + auto resourceID = ResourceId(RESOURCE_COLLECTION, "db.view"_sd); + auto& collectionCatalog = CollectionCatalog::get(opCtx.get()); + ASSERT(!collectionCatalog.lookupResourceName(resourceID)); +} + +TEST_F(ViewCatalogFixture, LookupRIDAfterDropRollback) { + const NamespaceString viewName("db.view"); + const NamespaceString viewOn("db.coll"); + + auto resourceID = ResourceId(RESOURCE_COLLECTION, "db.view"_sd); + auto& collectionCatalog = CollectionCatalog::get(opCtx.get()); + { + WriteUnitOfWork wunit(opCtx.get()); + ASSERT_OK( + viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation)); + ASSERT(collectionCatalog.lookupResourceName(resourceID).get() == viewName.ns()); + wunit.commit(); + } + + { + WriteUnitOfWork wunit(opCtx.get()); + ASSERT_OK(viewCatalog.dropView(opCtx.get(), viewName)); + } + + ASSERT(collectionCatalog.lookupResourceName(resourceID).get() == viewName.ns()); +} + +TEST_F(ViewCatalogFixture, LookupRIDAfterModify) { + const NamespaceString viewName("db.view"); + const NamespaceString viewOn("db.coll"); + + auto resourceID = ResourceId(RESOURCE_COLLECTION, "db.view"_sd); + auto& collectionCatalog = CollectionCatalog::get(opCtx.get()); + ASSERT_OK(viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation)); + ASSERT_OK(viewCatalog.modifyView(opCtx.get(), viewName, viewOn, emptyPipeline)); + ASSERT(collectionCatalog.lookupResourceName(resourceID).get() == viewName.ns()); +} + +TEST_F(ViewCatalogFixture, LookupRIDAfterModifyRollback) { + const NamespaceString viewName("db.view"); + const NamespaceString viewOn("db.coll"); + + auto resourceID = ResourceId(RESOURCE_COLLECTION, "db.view"_sd); + auto& collectionCatalog = CollectionCatalog::get(opCtx.get()); + { + WriteUnitOfWork wunit(opCtx.get()); + ASSERT_OK( + viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation)); + ASSERT(collectionCatalog.lookupResourceName(resourceID).get() == viewName.ns()); + wunit.commit(); + } + { + WriteUnitOfWork wunit(opCtx.get()); + ASSERT_OK(viewCatalog.modifyView(opCtx.get(), viewName, viewOn, emptyPipeline)); + ASSERT(collectionCatalog.lookupResourceName(resourceID).get() == viewName.ns()); + } + ASSERT(collectionCatalog.lookupResourceName(resourceID).get() == viewName.ns()); +} + TEST_F(ViewCatalogFixture, CreateViewThenDropAndLookup) { const NamespaceString viewName("db.view"); const NamespaceString viewOn("db.coll"); |