diff options
author | Dan Larkin-York <dan.larkin-york@mongodb.com> | 2022-02-26 13:50:02 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-02-26 14:34:46 +0000 |
commit | cd92f1325982f82314e0cbb08ced8d254198a7b2 (patch) | |
tree | 5539b750af2e6ed189698edbe994d3f3b64bf194 /src/mongo/db/catalog/collection_catalog.h | |
parent | fcad5cd7a9267980fefda51b1e4a3db0a12000ec (diff) | |
download | mongo-cd92f1325982f82314e0cbb08ced8d254198a7b2.tar.gz |
SERVER-57250 Merge ViewCatalog into CollectionCatalog
Diffstat (limited to 'src/mongo/db/catalog/collection_catalog.h')
-rw-r--r-- | src/mongo/db/catalog/collection_catalog.h | 187 |
1 files changed, 166 insertions, 21 deletions
diff --git a/src/mongo/db/catalog/collection_catalog.h b/src/mongo/db/catalog/collection_catalog.h index f8ec0db2533..9bb23cfa5a8 100644 --- a/src/mongo/db/catalog/collection_catalog.h +++ b/src/mongo/db/catalog/collection_catalog.h @@ -34,9 +34,11 @@ #include <set> #include "mongo/db/catalog/collection.h" +#include "mongo/db/catalog/views_for_database.h" #include "mongo/db/profile_filter.h" #include "mongo/db/service_context.h" #include "mongo/db/tenant_database_name.h" +#include "mongo/db/views/view.h" #include "mongo/stdx/unordered_map.h" #include "mongo/util/uuid.h" @@ -44,12 +46,14 @@ namespace mongo { class CollectionCatalog; class Database; +class UncommittedCatalogUpdates; class CollectionCatalog { friend class iterator; public: using CollectionInfoFn = std::function<bool(const CollectionPtr& collection)>; + using ViewIteratorCallback = std::function<bool(const ViewDefinition& view)>; /** * Defines lifetime and behavior of writable Collections. @@ -148,6 +152,58 @@ public: static void write(OperationContext* opCtx, CatalogWriteFn job); /** + * Create a new view 'viewName' with contents defined by running the specified aggregation + * 'pipeline' with collation 'collation' on a collection or view 'viewOn'. + * + * Must be in WriteUnitOfWork. View creation rolls back if the unit of work aborts. + * + * Caller must ensure corresponding database exists. + */ + Status createView(OperationContext* opCtx, + const NamespaceString& viewName, + const NamespaceString& viewOn, + const BSONArray& pipeline, + const BSONObj& collation, + const ViewsForDatabase::PipelineValidatorFn& pipelineValidator) const; + + /** + * Drop the view named 'viewName'. + * + * Must be in WriteUnitOfWork. The drop rolls back if the unit of work aborts. + * + * Caller must ensure corresponding database exists. + */ + Status dropView(OperationContext* opCtx, const NamespaceString& viewName) const; + + /** + * Modify the view named 'viewName' to have the new 'viewOn' and 'pipeline'. + * + * Must be in WriteUnitOfWork. The modification rolls back if the unit of work aborts. + * + * Caller must ensure corresponding database exists. + */ + Status modifyView(OperationContext* opCtx, + const NamespaceString& viewName, + const NamespaceString& viewOn, + const BSONArray& pipeline, + const ViewsForDatabase::PipelineValidatorFn& pipelineValidator) const; + + /** + * Reloads the in-memory state of the view catalog from the 'system.views' collection. The + * durable view definitions will be validated. Reading stops on the first invalid entry with + * errors logged and returned. Performs no cycle detection, etc. + * + * This is implicitly called by other methods when write operations are performed on the + * view catalog, on external changes to the 'system.views' collection and on the first + * opening of a database. + * + * Callers must re-fetch the catalog to observe changes. + * + * Requires an IS lock on the 'system.views' collection'. + */ + Status reloadViews(OperationContext* opCtx, StringData dbName) const; + + /** * This function is responsible for safely tracking a Collection rename within a * WriteUnitOfWork. * @@ -166,6 +222,17 @@ public: */ void dropCollection(OperationContext* opCtx, Collection* coll) const; + /** + * Initializes view records for database 'dbName'. Can throw a 'WriteConflictException' if this + * database has already been initialized. + */ + void onOpenDatabase(OperationContext* opCtx, StringData dbName, ViewsForDatabase&& viewsForDb); + + /** + * Removes the view records associated with 'tenantDbName', if any, from the in-memory + * representation of the catalog. Should be called when Database instance is closed. Requires X + * lock on database namespace. + */ void onCloseDatabase(OperationContext* opCtx, TenantDatabaseName tenantDbName); /** @@ -181,29 +248,27 @@ public: std::shared_ptr<Collection> deregisterCollection(OperationContext* opCtx, const UUID& uuid); /** - * Deregister all the collection objects and view namespaces. + * Create a temporary record of an uncommitted view namespace to aid in detecting a simultaneous + * attempt to create a collection with the same namespace. */ - void deregisterAllCollectionsAndViews(); + void registerUncommittedView(OperationContext* opCtx, const NamespaceString& nss); /** - * Register the namespace to be used as a view. - * - * Throws WriteConflictException if namespace is used by a Collection + * Remove the temporary record for an uncommitted view namespace, either on commit or rollback. */ - void registerView(const NamespaceString& ns); + void deregisterUncommittedView(const NamespaceString& nss); /** - * Deregister the namespace from being used as a view. + * Deregister all the collection objects and view namespaces. */ - void deregisterView(const NamespaceString& ns); + void deregisterAllCollectionsAndViews(); /** - * Sets all namespaces used by views for a database. Does not validate if they are used by - * Collections. When creating new view its namespace should be registered with registerView() - * above. + * Clears the in-memory state for the views associated with a particular database. + * + * Callers must re-fetch the catalog to observe changes. */ - void replaceViewsForDatabase(const TenantDatabaseName& tenantDbName, - absl::flat_hash_set<NamespaceString> views); + void clearViews(OperationContext* opCtx, StringData dbName) const; /** * This function gets the Collection pointer that corresponds to the UUID. @@ -273,6 +338,36 @@ public: const NamespaceString& nss) const; /** + * Iterates through the views in the catalog associated with database `dbName`, applying + * 'callback' to each view. If the 'callback' returns false, the iterator exits early. + * + * Caller must ensure corresponding database exists. + */ + void iterateViews( + OperationContext* opCtx, + StringData dbName, + ViewIteratorCallback callback, + ViewCatalogLookupBehavior lookupBehavior = ViewCatalogLookupBehavior::kValidateViews) const; + + /** + * Look up the 'nss' in the view catalog, returning a shared pointer to a View definition, + * or nullptr if it doesn't exist. + * + * Caller must ensure corresponding database exists. + */ + std::shared_ptr<const ViewDefinition> lookupView(OperationContext* opCtx, + const NamespaceString& nss) const; + + /** + * Same functionality as above, except this function skips validating durable views in the + * view catalog. + * + * Caller must ensure corresponding database exists. + */ + std::shared_ptr<const ViewDefinition> lookupViewWithoutValidatingDurable( + OperationContext* opCtx, const NamespaceString& nss) const; + + /** * Without acquiring any locks resolves the given NamespaceStringOrUUID to an actual namespace. * Throws NamespaceNotFound if the collection UUID cannot be resolved to a name, or if the UUID * can be resolved, but the resulting collection is in the wrong database. @@ -365,14 +460,20 @@ public: Stats getStats() const; /** + * Returns view statistics for the specified database. + */ + boost::optional<ViewsForDatabase::Stats> getViewStatsForDatabase(OperationContext* opCtx, + StringData dbName) const; + + /** * Returns a set of databases, by name, that have view catalogs. */ using ViewCatalogSet = absl::flat_hash_set<TenantDatabaseName>; - ViewCatalogSet getViewCatalogDbNames() const; + ViewCatalogSet getViewCatalogDbNames(OperationContext* opCtx) const; /** - * Puts the catalog in closed state. In this state, the lookupNSSByUUID method will fall back - * to the pre-close state to resolve queries for currently unknown UUIDs. This allows processes, + * Puts the catalog in closed state. In this state, the lookupNSSByUUID method will fall back to + * the pre-close state to resolve queries for currently unknown UUIDs. This allows processes, * like authorization and replication, which need to do lookups outside of database locks, to * proceed. * @@ -381,7 +482,7 @@ public: void onCloseCatalog(OperationContext* opCtx); /** - * Puts the catatlog back in open state, removing the pre-close state. See onCloseCatalog. + * Puts the catalog back in open state, removing the pre-close state. See onCloseCatalog. * * Must be called with the global lock acquired in exclusive mode. */ @@ -403,8 +504,8 @@ public: /** * Lookup the name of a resource by its ResourceId. If there are multiple namespaces mapped to - * the same ResourceId entry, we return the boost::none for those namespaces until there is - * only one namespace in the set. If the ResourceId is not found, boost::none is returned. + * the same ResourceId entry, we return the boost::none for those namespaces until there is only + * one namespace in the set. If the ResourceId is not found, boost::none is returned. */ boost::optional<std::string> lookupResourceName(const ResourceId& rid) const; @@ -425,6 +526,48 @@ private: std::shared_ptr<Collection> _lookupCollectionByUUID(UUID uuid) const; /** + * Retrieves the views for a given database, including any uncommitted changes for this + * operation. + */ + boost::optional<const ViewsForDatabase&> _getViewsForDatabase(OperationContext* opCtx, + StringData dbName) const; + + /** + * Sets all namespaces used by views for a database. Will uassert if there is a conflicting + * collection name in the catalog. + */ + void _replaceViewsForDatabase(StringData dbName, ViewsForDatabase&& views); + + /** + * Helper to take care of shared functionality for 'createView(...)' and 'modifyView(...)'. + */ + Status _createOrUpdateView(OperationContext* opCtx, + const NamespaceString& viewName, + const NamespaceString& viewOn, + const BSONArray& pipeline, + const ViewsForDatabase::PipelineValidatorFn& pipelineValidator, + std::unique_ptr<CollatorInterface> collator, + ViewsForDatabase&& viewsForDb) const; + + /** + * Throws 'WriteConflictException' if given namespace is already registered with the catalog, as + * either a view or collection. In the case of an collection drop (by the calling thread) that + * has not been committed yet, it will not throw, but it will return + * 'NonExistenceType::kDropPending' to distinguish from the case that the namespace is simply + * not registered with the catalog at all. The results will include namespaces which have been + * registered by preCommitHooks on other threads, but which have not truly been committed yet. + * + * If 'type' is set to 'NamespaceType::kCollection', we will only check for collisions with + * collections. If set to 'NamespaceType::kAll', we will check against both collections and + * views. + */ + enum class NonExistenceType { kDropPending, kNormal }; + enum class NamespaceType { kAll, kCollection }; + NonExistenceType _ensureNamespaceDoesNotExist(OperationContext* opCtx, + const NamespaceString& nss, + NamespaceType type) const; + + /** * When present, indicates that the catalog is in closed state, and contains a map from UUID * to pre-close NSS. See also onCloseCatalog. */ @@ -435,14 +578,16 @@ private: std::map<std::pair<TenantDatabaseName, UUID>, std::shared_ptr<Collection>>; using NamespaceCollectionMap = stdx::unordered_map<NamespaceString, std::shared_ptr<Collection>>; + using UncommittedViewsSet = stdx::unordered_set<NamespaceString>; using DatabaseProfileSettingsMap = StringMap<ProfileSettings>; CollectionCatalogMap _catalog; OrderedCollectionMap _orderedCollections; // Ordered by <tenantDbName, collUUID> pair NamespaceCollectionMap _collections; + UncommittedViewsSet _uncommittedViews; - // Map of database names to a set of their views. Only databases with views are present. - absl::flat_hash_map<TenantDatabaseName, absl::flat_hash_set<NamespaceString>> _views; + // Map of database names to their corresponding views and other associated state. + StringMap<ViewsForDatabase> _viewsForDatabase; // Incremented whenever the CollectionCatalog gets closed and reopened (onCloseCatalog and // onOpenCatalog). |