From ab689c15777a5c2f7d35f602d125fdc7f2fb344c Mon Sep 17 00:00:00 2001 From: Geert Bosch Date: Mon, 29 Apr 2019 14:11:12 -0400 Subject: SERVER-40892 Rename UUIDCatalog to CollectionCatalog --- src/mongo/db/SConscript | 33 +- src/mongo/db/catalog/SConscript | 29 +- src/mongo/db/catalog/catalog_control.cpp | 30 +- src/mongo/db/catalog/coll_mod.cpp | 4 +- src/mongo/db/catalog/collection.h | 4 +- src/mongo/db/catalog/collection_catalog.cpp | 607 +++++++++++++++++++ src/mongo/db/catalog/collection_catalog.h | 327 ++++++++++ src/mongo/db/catalog/collection_catalog_helper.cpp | 68 +++ src/mongo/db/catalog/collection_catalog_helper.h | 53 ++ src/mongo/db/catalog/collection_catalog_test.cpp | 669 +++++++++++++++++++++ src/mongo/db/catalog/collection_impl.cpp | 2 +- src/mongo/db/catalog/collection_impl.h | 2 +- src/mongo/db/catalog/collection_mock.h | 2 +- src/mongo/db/catalog/create_collection.cpp | 5 +- src/mongo/db/catalog/create_collection_test.cpp | 6 +- src/mongo/db/catalog/database.h | 6 +- src/mongo/db/catalog/database_holder_impl.cpp | 8 +- src/mongo/db/catalog/database_impl.cpp | 43 +- src/mongo/db/catalog/database_impl.h | 8 +- src/mongo/db/catalog/database_test.cpp | 10 +- src/mongo/db/catalog/index_builds_manager.cpp | 4 +- src/mongo/db/catalog/rename_collection.cpp | 7 +- src/mongo/db/catalog/rename_collection_test.cpp | 20 +- src/mongo/db/catalog/uuid_catalog.cpp | 599 ------------------ src/mongo/db/catalog/uuid_catalog.h | 327 ---------- src/mongo/db/catalog/uuid_catalog_helper.cpp | 68 --- src/mongo/db/catalog/uuid_catalog_helper.h | 53 -- src/mongo/db/catalog/uuid_catalog_test.cpp | 668 -------------------- src/mongo/db/catalog_raii.cpp | 14 +- src/mongo/db/catalog_raii.h | 24 +- src/mongo/db/commands/SConscript | 5 +- src/mongo/db/commands/apply_ops_cmd.cpp | 2 +- src/mongo/db/commands/dbcheck.cpp | 2 +- src/mongo/db/commands/dbhash.cpp | 2 +- src/mongo/db/commands/do_txn_cmd.cpp | 2 +- src/mongo/db/commands/list_collections.cpp | 2 +- src/mongo/db/commands/list_databases.cpp | 5 +- src/mongo/db/commands/oplog_application_checks.cpp | 6 +- src/mongo/db/concurrency/SConscript | 2 +- src/mongo/db/concurrency/lock_manager.cpp | 6 +- src/mongo/db/db.cpp | 2 +- src/mongo/db/exec/requires_collection_stage.cpp | 4 +- src/mongo/db/index_builds_coordinator.cpp | 9 +- src/mongo/db/index_builds_coordinator_mongod.cpp | 2 +- src/mongo/db/pipeline/SConscript | 1 + .../document_source_change_stream_test.cpp | 79 +-- .../document_source_change_stream_transform.cpp | 2 +- src/mongo/db/pipeline/mongos_process_interface.cpp | 2 +- .../db/pipeline/process_interface_shardsvr.cpp | 2 +- .../db/pipeline/process_interface_standalone.cpp | 2 +- src/mongo/db/query/SConscript | 2 +- src/mongo/db/query/query_request.cpp | 4 +- src/mongo/db/query/query_request.h | 4 +- src/mongo/db/query/query_request_test.cpp | 6 +- src/mongo/db/repair_database.cpp | 6 +- src/mongo/db/repair_database_and_check_version.cpp | 4 +- src/mongo/db/repl/SConscript | 2 + src/mongo/db/repl/dbcheck.cpp | 6 +- src/mongo/db/repl/do_txn.cpp | 4 +- .../repl/drop_pending_collection_reaper_test.cpp | 2 +- src/mongo/db/repl/idempotency_test_fixture.cpp | 8 +- src/mongo/db/repl/oplog.cpp | 8 +- src/mongo/db/repl/rollback_impl.cpp | 24 +- src/mongo/db/repl/rollback_impl_test.cpp | 9 +- src/mongo/db/repl/rs_rollback.cpp | 25 +- src/mongo/db/repl/rs_rollback_test.cpp | 2 +- src/mongo/db/repl/storage_interface_impl.cpp | 2 +- src/mongo/db/repl/sync_tail.cpp | 6 +- src/mongo/db/service_context_d_test_fixture.cpp | 2 +- src/mongo/db/storage/kv/SConscript | 4 +- src/mongo/db/storage/kv/kv_catalog.cpp | 32 +- .../db/storage/kv/kv_collection_catalog_entry.cpp | 2 +- .../kv/kv_collection_catalog_entry_test.cpp | 4 +- src/mongo/db/storage/kv/kv_storage_engine.cpp | 15 +- .../db/storage/kv/kv_storage_engine_test_fixture.h | 10 +- src/mongo/db/storage/wiredtiger/SConscript | 1 + src/mongo/db/transaction_participant.cpp | 2 +- src/mongo/db/views/SConscript | 3 + src/mongo/dbtests/framework.cpp | 2 +- src/mongo/dbtests/rollbacktests.cpp | 4 +- src/mongo/dbtests/storage_timestamp_tests.cpp | 2 +- src/mongo/embedded/embedded.cpp | 2 +- .../embedded/index_builds_coordinator_embedded.cpp | 2 +- 83 files changed, 2049 insertions(+), 2001 deletions(-) create mode 100644 src/mongo/db/catalog/collection_catalog.cpp create mode 100644 src/mongo/db/catalog/collection_catalog.h create mode 100644 src/mongo/db/catalog/collection_catalog_helper.cpp create mode 100644 src/mongo/db/catalog/collection_catalog_helper.h create mode 100644 src/mongo/db/catalog/collection_catalog_test.cpp delete mode 100644 src/mongo/db/catalog/uuid_catalog.cpp delete mode 100644 src/mongo/db/catalog/uuid_catalog.h delete mode 100644 src/mongo/db/catalog/uuid_catalog_helper.cpp delete mode 100644 src/mongo/db/catalog/uuid_catalog_helper.h delete mode 100644 src/mongo/db/catalog/uuid_catalog_test.cpp (limited to 'src/mongo') diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript index 98a730ab905..9f4088dba01 100644 --- a/src/mongo/db/SConscript +++ b/src/mongo/db/SConscript @@ -676,6 +676,7 @@ env.Library( 'stats/top', ], LIBDEPS_PRIVATE=[ + "catalog/database_holder", "$BUILD_DIR/mongo/idl/server_parameter", ], ) @@ -701,7 +702,7 @@ env.Library( ], LIBDEPS=[ 'catalog/collection', - 'catalog/uuid_catalog', + 'catalog/collection_catalog', 'concurrency/lock_manager', 'namespace_string', 'views/views', @@ -737,6 +738,7 @@ env.Library( '$BUILD_DIR/mongo/idl/server_parameter', '$BUILD_DIR/mongo/util/concurrency/thread_pool', 'catalog_raii', + 'catalog/database_holder', 'commands/server_status', 'commands/test_commands_enabled', 'curop_failpoint_helpers', @@ -757,6 +759,7 @@ env.CppUnitTest( LIBDEPS=[ 'auth/authmocks', 'catalog_raii', + 'catalog/database_holder', 'service_context_test_fixture', 'stats/fill_locker_info', ], @@ -868,13 +871,14 @@ env.Library( ], LIBDEPS=[ 'catalog/collection_options', + 'catalog/database_holder', 'op_observer', 'op_observer_util', 'repl/oplog', 's/sharding_api_d', 'views/views_mongod', '$BUILD_DIR/mongo/base', - '$BUILD_DIR/mongo/db/catalog/uuid_catalog', + '$BUILD_DIR/mongo/db/catalog/collection_catalog', '$BUILD_DIR/mongo/s/coreshard', "$BUILD_DIR/mongo/s/grid", ], @@ -939,7 +943,7 @@ env.Library( 'curop', 'db_raii', 'index_build_entry_helpers', - '$BUILD_DIR/mongo/db/catalog/uuid_catalog', + '$BUILD_DIR/mongo/db/catalog/collection_catalog', ], ) @@ -957,10 +961,11 @@ env.Library( "$BUILD_DIR/mongo/db/catalog/index_builds_manager", ], LIBDEPS_PRIVATE=[ + 'catalog/database_holder', 'db_raii', 'index_build_entry_helpers', '$BUILD_DIR/mongo/db/catalog/index_build_entry_idl', - '$BUILD_DIR/mongo/db/catalog/uuid_catalog', + '$BUILD_DIR/mongo/db/catalog/collection_catalog', '$BUILD_DIR/mongo/db/concurrency/lock_manager', '$BUILD_DIR/mongo/db/repl/repl_coordinator_interface', '$BUILD_DIR/mongo/db/s/sharding_api_d', @@ -1032,7 +1037,8 @@ env.Library( ], LIBDEPS_PRIVATE=[ '$BUILD_DIR/mongo/client/authentication', - '$BUILD_DIR/mongo/db/commands/list_collections_filter', + 'catalog/database_holder', + 'commands/list_collections_filter', ], ) @@ -1131,11 +1137,12 @@ env.Library( ], LIBDEPS_PRIVATE=[ 'index_builds_coordinator_interface', - '$BUILD_DIR/mongo/db/catalog/document_validation', - '$BUILD_DIR/mongo/db/catalog/index_key_validate', - '$BUILD_DIR/mongo/db/catalog/multi_index_block', - '$BUILD_DIR/mongo/db/storage/storage_repair_observer', - '$BUILD_DIR/mongo/db/repl/oplog', + 'catalog/database_holder', + 'catalog/document_validation', + 'catalog/index_key_validate', + 'catalog/multi_index_block', + 'storage/storage_repair_observer', + 'repl/oplog', ], ) @@ -1271,6 +1278,7 @@ env.Library( 'update/update_driver', ], LIBDEPS_PRIVATE=[ + 'catalog/database_holder', 'commands/server_status_core', 'kill_sessions', ], @@ -1282,8 +1290,9 @@ env.Library( "repair_database_and_check_version.cpp", ], LIBDEPS_PRIVATE=[ - '$BUILD_DIR/mongo/db/catalog/catalog_helpers', - '$BUILD_DIR/mongo/db/commands/mongod_fcv', + 'catalog/catalog_helpers', + 'catalog/database_holder', + 'commands/mongod_fcv', 'dbdirectclient', 'dbhelpers', 'repair_database', diff --git a/src/mongo/db/catalog/SConscript b/src/mongo/db/catalog/SConscript index 31857fcec6b..bf49127cdab 100644 --- a/src/mongo/db/catalog/SConscript +++ b/src/mongo/db/catalog/SConscript @@ -307,13 +307,12 @@ env.CppUnitTest( ) env.Library( - target='uuid_catalog', + target='collection_catalog', source=[ - 'uuid_catalog.cpp', + 'collection_catalog.cpp', ], LIBDEPS=[ 'collection', - 'database_holder', '$BUILD_DIR/mongo/base', '$BUILD_DIR/mongo/db/namespace_string', '$BUILD_DIR/mongo/db/service_context', @@ -324,23 +323,23 @@ env.Library( ) env.Library( - target='uuid_catalog_helper', + target='collection_catalog_helper', source=[ - 'uuid_catalog_helper.cpp', + 'collection_catalog_helper.cpp', ], LIBDEPS_PRIVATE=[ - 'uuid_catalog', + 'collection_catalog', '$BUILD_DIR/mongo/db/concurrency/lock_manager', ] ) env.CppUnitTest( - target='uuid_catalog_test', + target='collection_catalog_test', source=[ - 'uuid_catalog_test.cpp', + 'collection_catalog_test.cpp', ], LIBDEPS=[ - 'uuid_catalog', + 'collection_catalog', '$BUILD_DIR/mongo/db/service_context', '$BUILD_DIR/mongo/db/storage/kv/kv_prefix', ], @@ -353,7 +352,8 @@ env.Library( ], LIBDEPS_PRIVATE=[ 'collection', - 'uuid_catalog', + 'collection_catalog', + 'database_holder', '$BUILD_DIR/mongo/db/index_builds_coordinator_interface', '$BUILD_DIR/mongo/db/repair_database', '$BUILD_DIR/mongo/db/service_context', @@ -415,7 +415,7 @@ env.Library( '$BUILD_DIR/mongo/db/views/views_mongod', ], LIBDEPS_PRIVATE=[ - '$BUILD_DIR/mongo/db/catalog/uuid_catalog_helper', + '$BUILD_DIR/mongo/db/catalog/collection_catalog_helper', '$BUILD_DIR/mongo/db/commands/server_status_core', '$BUILD_DIR/mongo/db/index/index_build_interceptor', '$BUILD_DIR/mongo/db/logical_clock', @@ -452,6 +452,9 @@ env.Library( 'index_key_validate', 'multi_index_block', ], + LIBDEPS_PRIVATE=[ + 'database_holder', + ], ) env.CppUnitTest( @@ -478,7 +481,7 @@ env.CppUnitTest( ], LIBDEPS=[ 'catalog_helpers', - 'uuid_catalog', + 'collection_catalog', '$BUILD_DIR/mongo/db/auth/authmocks', '$BUILD_DIR/mongo/db/db_raii', '$BUILD_DIR/mongo/db/namespace_string', @@ -496,6 +499,7 @@ env.CppUnitTest( ], LIBDEPS=[ 'catalog_helpers', + 'database_holder', '$BUILD_DIR/mongo/db/auth/authmocks', '$BUILD_DIR/mongo/db/db_raii', '$BUILD_DIR/mongo/db/namespace_string', @@ -516,6 +520,7 @@ env.CppUnitTest( ], LIBDEPS=[ 'catalog_helpers', + 'database_holder', '$BUILD_DIR/mongo/db/auth/authmocks', '$BUILD_DIR/mongo/db/db_raii', '$BUILD_DIR/mongo/db/namespace_string', diff --git a/src/mongo/db/catalog/catalog_control.cpp b/src/mongo/db/catalog/catalog_control.cpp index 4e91be65a5b..92e9ec691da 100644 --- a/src/mongo/db/catalog/catalog_control.cpp +++ b/src/mongo/db/catalog/catalog_control.cpp @@ -36,9 +36,9 @@ #include "mongo/db/background.h" #include "mongo/db/catalog/collection.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/database.h" #include "mongo/db/catalog/database_holder.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/ftdc/ftdc_mongod.h" #include "mongo/db/index_builds_coordinator.h" #include "mongo/db/namespace_string.h" @@ -79,14 +79,15 @@ MinVisibleTimestampMap closeCatalog(OperationContext* opCtx) { } } - // Need to mark the UUIDCatalog as open if we our closeAll fails, dismissed if successful. - auto reopenOnFailure = makeGuard([opCtx] { UUIDCatalog::get(opCtx).onOpenCatalog(opCtx); }); - // Closing UUID Catalog: only lookupNSSByUUID will fall back to using pre-closing state to + // Need to mark the CollectionCatalog as open if we our closeAll fails, dismissed if successful. + auto reopenOnFailure = + makeGuard([opCtx] { CollectionCatalog::get(opCtx).onOpenCatalog(opCtx); }); + // Closing CollectionCatalog: only lookupNSSByUUID will fall back to using pre-closing state to // allow authorization for currently unknown UUIDs. This is needed because authorization needs // to work before acquiring locks, and might otherwise spuriously regard a UUID as unknown // while reloading the catalog. - UUIDCatalog::get(opCtx).onCloseCatalog(opCtx); - LOG(1) << "closeCatalog: closing UUID catalog"; + CollectionCatalog::get(opCtx).onCloseCatalog(opCtx); + LOG(1) << "closeCatalog: closing collection catalog"; // Close all databases. log() << "closeCatalog: closing all databases"; @@ -120,7 +121,7 @@ void openCatalog(OperationContext* opCtx, const MinVisibleTimestampMap& minVisib auto indexName = indexNamespace.second; auto collCatalogEntry = - UUIDCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(collNss); + CollectionCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(collNss); invariant(collCatalogEntry, str::stream() << "couldn't get collection catalog entry for collection " << collNss.toString()); @@ -155,7 +156,7 @@ void openCatalog(OperationContext* opCtx, const MinVisibleTimestampMap& minVisib NamespaceString collNss(entry.first); auto collCatalogEntry = - UUIDCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(collNss); + CollectionCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(collNss); invariant(collCatalogEntry, str::stream() << "couldn't get collection catalog entry for collection " << collNss.toString()); @@ -169,7 +170,7 @@ void openCatalog(OperationContext* opCtx, const MinVisibleTimestampMap& minVisib fassert(40690, rebuildIndexesOnCollection(opCtx, collCatalogEntry, indexSpecs)); } - // Open all databases and repopulate the UUID catalog. + // Open all databases and repopulate the CollectionCatalog. log() << "openCatalog: reopening all databases"; auto databaseHolder = DatabaseHolder::get(opCtx); std::vector databasesToOpen = storageEngine->listDatabases(); @@ -177,7 +178,8 @@ void openCatalog(OperationContext* opCtx, const MinVisibleTimestampMap& minVisib LOG_FOR_RECOVERY(1) << "openCatalog: dbholder reopening database " << dbName; auto db = databaseHolder->openDb(opCtx, dbName); invariant(db, str::stream() << "failed to reopen database " << dbName); - for (auto&& collNss : UUIDCatalog::get(opCtx).getAllCollectionNamesFromDb(opCtx, dbName)) { + for (auto&& collNss : + CollectionCatalog::get(opCtx).getAllCollectionNamesFromDb(opCtx, dbName)) { // Note that the collection name already includes the database component. auto collection = db->getCollection(opCtx, collNss); invariant(collection, @@ -199,10 +201,10 @@ void openCatalog(OperationContext* opCtx, const MinVisibleTimestampMap& minVisib } } } - // Opening UUID Catalog: The UUID catalog is now in sync with the storage engine catalog. Clear - // the pre-closing state. - UUIDCatalog::get(opCtx).onOpenCatalog(opCtx); - log() << "openCatalog: finished reloading UUID catalog"; + // Opening CollectionCatalog: The collection catalog is now in sync with the storage engine + // catalog. Clear the pre-closing state. + CollectionCatalog::get(opCtx).onOpenCatalog(opCtx); + log() << "openCatalog: finished reloading collection catalog"; } } // namespace catalog } // namespace mongo diff --git a/src/mongo/db/catalog/coll_mod.cpp b/src/mongo/db/catalog/coll_mod.cpp index bf0c62380c5..5f081288ea9 100644 --- a/src/mongo/db/catalog/coll_mod.cpp +++ b/src/mongo/db/catalog/coll_mod.cpp @@ -527,7 +527,7 @@ void updateUniqueIndexesOnUpgrade(OperationContext* opCtx) { std::vector dbNames; { Lock::GlobalLock lk(opCtx, MODE_IS); - dbNames = UUIDCatalog::get(opCtx).getAllDbNames(); + dbNames = CollectionCatalog::get(opCtx).getAllDbNames(); } for (auto it = dbNames.begin(); it != dbNames.end(); ++it) { @@ -561,7 +561,7 @@ Status updateNonReplicatedUniqueIndexes(OperationContext* opCtx) { std::vector dbNames; { Lock::GlobalLock lk(opCtx, MODE_IS); - dbNames = UUIDCatalog::get(opCtx).getAllDbNames(); + dbNames = CollectionCatalog::get(opCtx).getAllDbNames(); } for (auto it = dbNames.begin(); it != dbNames.end(); ++it) { auto dbName = *it; diff --git a/src/mongo/db/catalog/collection.h b/src/mongo/db/catalog/collection.h index 39cb24a20d7..37b8c25a988 100644 --- a/src/mongo/db/catalog/collection.h +++ b/src/mongo/db/catalog/collection.h @@ -183,8 +183,8 @@ public: * Sets a new namespace on this Collection, in the case that the Collection is being renamed. * In general, reads and writes to Collection objects are synchronized using locks from the lock * manager. However, there is special synchronization for ns() and setNs() so that the - * UUIDCatalog can perform UUID to namespace lookup without holding a Collection lock. See - * UUIDCatalog::setCollectionNamespace(). + * CollectionCatalog can perform UUID to namespace lookup without holding a Collection lock. See + * CollectionCatalog::setCollectionNamespace(). */ virtual void setNs(NamespaceString nss) = 0; diff --git a/src/mongo/db/catalog/collection_catalog.cpp b/src/mongo/db/catalog/collection_catalog.cpp new file mode 100644 index 00000000000..1bfb90dba4e --- /dev/null +++ b/src/mongo/db/catalog/collection_catalog.cpp @@ -0,0 +1,607 @@ +/** + * Copyright (C) 2018-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * . + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ +#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kStorage + +#include "mongo/platform/basic.h" + +#include "collection_catalog.h" + +#include "mongo/db/catalog/database.h" +#include "mongo/db/concurrency/lock_manager_defs.h" +#include "mongo/db/storage/recovery_unit.h" +#include "mongo/util/assert_util.h" +#include "mongo/util/log.h" +#include "mongo/util/uuid.h" + +namespace mongo { +namespace { +const ServiceContext::Decoration getCatalog = + ServiceContext::declareDecoration(); +} // namespace + +class CollectionCatalog::FinishDropChange : public RecoveryUnit::Change { +public: + FinishDropChange(CollectionCatalog& catalog, + std::unique_ptr coll, + CollectionUUID uuid) + : _catalog(catalog), _coll(std::move(coll)), _uuid(uuid) {} + + void commit(boost::optional) override { + _coll.reset(); + } + + void rollback() override { + _catalog.registerCollectionObject(_uuid, std::move(_coll)); + } + +private: + CollectionCatalog& _catalog; + std::unique_ptr _coll; + CollectionUUID _uuid; +}; + +CollectionCatalog::iterator::iterator(StringData dbName, + uint64_t genNum, + const CollectionCatalog& catalog) + : _dbName(dbName), _genNum(genNum), _catalog(&catalog) { + auto minUuid = UUID::parse("00000000-0000-0000-0000-000000000000").getValue(); + + stdx::lock_guard lock(_catalog->_catalogLock); + _mapIter = _catalog->_orderedCollections.lower_bound(std::make_pair(_dbName, minUuid)); + + // The entry _mapIter points to is valid if it's not at the end of _orderedCollections and + // the entry's database is the same as dbName. + while (_mapIter != _catalog->_orderedCollections.end() && _mapIter->first.first == _dbName && + _mapIter->second->collectionPtr == nullptr) { + _mapIter++; + } + if (_mapIter != _catalog->_orderedCollections.end() && _mapIter->first.first == _dbName) { + _uuid = _mapIter->first.second; + } +} + +CollectionCatalog::iterator::iterator( + std::map, CollectionInfo*>::const_iterator mapIter) + : _mapIter(mapIter) {} + +CollectionCatalog::iterator::pointer CollectionCatalog::iterator::operator->() { + stdx::lock_guard lock(_catalog->_catalogLock); + _repositionIfNeeded(); + if (_exhausted()) { + return nullptr; + } + + return &_mapIter->second->collectionPtr; +} + +CollectionCatalog::iterator::reference CollectionCatalog::iterator::operator*() { + stdx::lock_guard lock(_catalog->_catalogLock); + _repositionIfNeeded(); + if (_exhausted()) { + return _nullCollection; + } + + return _mapIter->second->collectionPtr; +} + +boost::optional CollectionCatalog::iterator::uuid() { + return _uuid; +} + +CollectionCatalog::iterator CollectionCatalog::iterator::operator++() { + stdx::lock_guard lock(_catalog->_catalogLock); + + // Skip over CollectionInfo that has CatalogEntry but has no Collection object. + do { + if (!_repositionIfNeeded()) { + _mapIter++; // If the position was not updated, increment iterator to next element. + } + + if (_exhausted()) { + // If the iterator is at the end of the map or now points to an entry that does not + // correspond to the correct database. + _mapIter = _catalog->_orderedCollections.end(); + _uuid = boost::none; + return *this; + } + } while (_mapIter->second->collectionPtr == nullptr); + + _uuid = _mapIter->first.second; + return *this; +} + +CollectionCatalog::iterator CollectionCatalog::iterator::operator++(int) { + auto oldPosition = *this; + ++(*this); + return oldPosition; +} + +bool CollectionCatalog::iterator::operator==(const iterator& other) { + stdx::lock_guard lock(_catalog->_catalogLock); + + if (other._mapIter == _catalog->_orderedCollections.end()) { + return _uuid == boost::none; + } + + return _uuid == other._uuid; +} + +bool CollectionCatalog::iterator::operator!=(const iterator& other) { + return !(*this == other); +} + +bool CollectionCatalog::iterator::_repositionIfNeeded() { + if (_genNum == _catalog->_generationNumber) { + return false; + } + + _genNum = _catalog->_generationNumber; + // If the map has been modified, find the entry the iterator was on, or the one right after it. + _mapIter = _catalog->_orderedCollections.lower_bound(std::make_pair(_dbName, *_uuid)); + + // It is possible that the collection object is gone while catalog entry is + // still in the map. Skip that type of entries. + while (!_exhausted() && _mapIter->second->collectionPtr == nullptr) { + _mapIter++; + } + + if (_exhausted()) { + return true; + } + + invariant(_mapIter->second->collectionPtr); + + // If the old pair matches the previous DB name and UUID, the iterator was not repositioned. + auto dbUuidPair = _mapIter->first; + bool repositioned = !(dbUuidPair.first == _dbName && dbUuidPair.second == _uuid); + _uuid = dbUuidPair.second; + + return repositioned; +} + +bool CollectionCatalog::iterator::_exhausted() { + return _mapIter == _catalog->_orderedCollections.end() || _mapIter->first.first != _dbName; +} + +CollectionCatalog& CollectionCatalog::get(ServiceContext* svcCtx) { + return getCatalog(svcCtx); +} +CollectionCatalog& CollectionCatalog::get(OperationContext* opCtx) { + return getCatalog(opCtx->getServiceContext()); +} + +void CollectionCatalog::onCreateCollection(OperationContext* opCtx, + std::unique_ptr coll, + CollectionUUID uuid) { + registerCollectionObject(uuid, std::move(coll)); + opCtx->recoveryUnit()->onRollback([this, uuid] { deregisterCollectionObject(uuid); }); +} + +void CollectionCatalog::onDropCollection(OperationContext* opCtx, CollectionUUID uuid) { + auto coll = deregisterCollectionObject(uuid); + opCtx->recoveryUnit()->registerChange(new FinishDropChange(*this, std::move(coll), uuid)); +} + +void CollectionCatalog::setCollectionNamespace(OperationContext* opCtx, + Collection* coll, + const NamespaceString& fromCollection, + const NamespaceString& toCollection) { + // Rather than maintain, in addition to the UUID -> Collection* mapping, an auxiliary + // data structure with the UUID -> namespace mapping, the CollectionCatalog relies on + // Collection::ns() to provide UUID to namespace lookup. In addition, the CollectionCatalog + // does not require callers to hold locks. + // + // This means that Collection::ns() may be called while only '_catalogLock' (and no lock + // manager locks) are held. The purpose of this function is ensure that we write to the + // Collection's namespace string under '_catalogLock'. + invariant(coll); + stdx::lock_guard lock(_catalogLock); + CollectionCatalogEntry* catalogEntry = + _collections[fromCollection]->collectionCatalogEntry.get(); + + coll->setNs(toCollection); + catalogEntry->setNs(toCollection); + + _collections[toCollection] = _collections[fromCollection]; + _collections.erase(fromCollection); + + ResourceId oldRid = ResourceId(RESOURCE_COLLECTION, fromCollection.ns()); + ResourceId newRid = ResourceId(RESOURCE_COLLECTION, toCollection.ns()); + + removeResource(oldRid, fromCollection.ns()); + addResource(newRid, toCollection.ns()); + + opCtx->recoveryUnit()->onRollback([this, coll, fromCollection, toCollection, catalogEntry] { + stdx::lock_guard lock(_catalogLock); + coll->setNs(std::move(fromCollection)); + catalogEntry->setNs(fromCollection); + + _collections[fromCollection] = _collections[toCollection]; + _collections.erase(toCollection); + + ResourceId oldRid = ResourceId(RESOURCE_COLLECTION, fromCollection.ns()); + ResourceId newRid = ResourceId(RESOURCE_COLLECTION, toCollection.ns()); + + removeResource(newRid, toCollection.ns()); + addResource(oldRid, fromCollection.ns()); + }); +} + +void CollectionCatalog::onCloseDatabase(OperationContext* opCtx, std::string dbName) { + invariant(opCtx->lockState()->isW()); + for (auto it = begin(dbName); it != end(); ++it) { + deregisterCollectionObject(it.uuid().get()); + } + + auto rid = ResourceId(RESOURCE_DATABASE, dbName); + removeResource(rid, dbName); +} + +void CollectionCatalog::onCloseCatalog(OperationContext* opCtx) { + invariant(opCtx->lockState()->isW()); + stdx::lock_guard lock(_catalogLock); + invariant(!_shadowCatalog); + _shadowCatalog.emplace(); + for (auto& entry : _catalog) + _shadowCatalog->insert({entry.first, entry.second.collection->ns()}); +} + +void CollectionCatalog::onOpenCatalog(OperationContext* opCtx) { + invariant(opCtx->lockState()->isW()); + stdx::lock_guard lock(_catalogLock); + invariant(_shadowCatalog); + _shadowCatalog.reset(); +} + +Collection* CollectionCatalog::lookupCollectionByUUID(CollectionUUID uuid) const { + stdx::lock_guard lock(_catalogLock); + auto foundIt = _catalog.find(uuid); + return foundIt == _catalog.end() || foundIt->second.collectionPtr == nullptr + ? nullptr + : foundIt->second.collection.get(); +} + +Collection* CollectionCatalog::lookupCollectionByNamespace(const NamespaceString& nss) const { + stdx::lock_guard lock(_catalogLock); + auto it = _collections.find(nss); + return it == _collections.end() || it->second->collectionPtr == nullptr + ? nullptr + : it->second->collection.get(); +} + +CollectionCatalogEntry* CollectionCatalog::lookupCollectionCatalogEntryByUUID( + CollectionUUID uuid) const { + stdx::lock_guard lock(_catalogLock); + auto foundIt = _catalog.find(uuid); + return foundIt == _catalog.end() ? nullptr : foundIt->second.collectionCatalogEntry.get(); +} + +CollectionCatalogEntry* CollectionCatalog::lookupCollectionCatalogEntryByNamespace( + const NamespaceString& nss) const { + stdx::lock_guard lock(_catalogLock); + auto it = _collections.find(nss); + return it == _collections.end() ? nullptr : it->second->collectionCatalogEntry.get(); +} + +boost::optional CollectionCatalog::lookupNSSByUUID(CollectionUUID uuid) const { + stdx::lock_guard lock(_catalogLock); + auto foundIt = _catalog.find(uuid); + if (foundIt != _catalog.end()) { + NamespaceString ns = foundIt->second.collectionCatalogEntry->ns(); + invariant(!ns.isEmpty()); + return ns; + } + + // Only in the case that the catalog is closed and a UUID is currently unknown, resolve it + // using the pre-close state. This ensures that any tasks reloading the catalog can see their + // own updates. + if (_shadowCatalog) { + auto shadowIt = _shadowCatalog->find(uuid); + if (shadowIt != _shadowCatalog->end()) + return shadowIt->second; + } + return boost::none; +} + +boost::optional CollectionCatalog::lookupUUIDByNSS( + const NamespaceString& nss) const { + stdx::lock_guard lock(_catalogLock); + auto minUuid = UUID::parse("00000000-0000-0000-0000-000000000000").getValue(); + auto it = _orderedCollections.lower_bound(std::make_pair(nss.db().toString(), minUuid)); + + // The entry _mapIter points to is valid if it's not at the end of _orderedCollections and + // the entry's database is the same as dbName. + while (it != _orderedCollections.end() && it->first.first == nss.db()) { + if (it->second->collectionCatalogEntry->ns() == nss) { + return it->first.second; + } + ++it; + } + return boost::none; +} + +std::vector CollectionCatalog::getAllCollectionUUIDsFromDb( + StringData dbName) const { + stdx::lock_guard lock(_catalogLock); + auto minUuid = UUID::parse("00000000-0000-0000-0000-000000000000").getValue(); + auto it = _orderedCollections.lower_bound(std::make_pair(dbName.toString(), minUuid)); + + std::vector ret; + while (it != _orderedCollections.end() && it->first.first == dbName) { + ret.push_back(it->first.second); + ++it; + } + return ret; +} + +std::vector CollectionCatalog::getAllCollectionNamesFromDb( + OperationContext* opCtx, StringData dbName) const { + invariant(opCtx->lockState()->isDbLockedForMode(dbName, MODE_S)); + + stdx::lock_guard lock(_catalogLock); + auto minUuid = UUID::parse("00000000-0000-0000-0000-000000000000").getValue(); + + std::vector ret; + for (auto it = _orderedCollections.lower_bound(std::make_pair(dbName.toString(), minUuid)); + it != _orderedCollections.end() && it->first.first == dbName; + ++it) { + ret.push_back(it->second->collectionCatalogEntry->ns()); + } + return ret; +} + +std::vector CollectionCatalog::getAllDbNames() const { + std::vector ret; + stdx::lock_guard lock(_catalogLock); + auto maxUuid = UUID::parse("FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF").getValue(); + auto iter = _orderedCollections.upper_bound(std::make_pair("", maxUuid)); + while (iter != _orderedCollections.end()) { + auto dbName = iter->first.first; + ret.push_back(dbName); + iter = _orderedCollections.upper_bound(std::make_pair(dbName, maxUuid)); + } + return ret; +} + +void CollectionCatalog::registerCatalogEntry( + CollectionUUID uuid, std::unique_ptr collectionCatalogEntry) { + stdx::lock_guard lock(_catalogLock); + + LOG(0) << "Registering catalog entry " << collectionCatalogEntry->ns() << " with UUID " << uuid; + + auto ns = collectionCatalogEntry->ns(); + auto dbName = ns.db().toString(); + auto dbIdPair = std::make_pair(dbName, uuid); + + // Make sure no entry related to this uuid. + invariant(_catalog.find(uuid) == _catalog.end()); + invariant(_collections.find(ns) == _collections.end()); + invariant(_orderedCollections.find(dbIdPair) == _orderedCollections.end()); + + CollectionInfo collectionInfo = {nullptr, /* std::unique_ptr */ + nullptr, + std::move(collectionCatalogEntry)}; + + _catalog[uuid] = std::move(collectionInfo); + _collections[ns] = &_catalog[uuid]; + _orderedCollections[dbIdPair] = &_catalog[uuid]; +} + +void CollectionCatalog::registerCollectionObject(CollectionUUID uuid, + std::unique_ptr coll) { + stdx::lock_guard lock(_catalogLock); + + LOG(0) << "Registering collection object " << coll->ns() << " with UUID " << uuid; + + auto ns = coll->ns(); + auto dbName = ns.db().toString(); + auto dbIdPair = std::make_pair(dbName, uuid); + + // Make sure catalog entry associated with this uuid already exists. + invariant(_catalog.find(uuid) != _catalog.end()); + invariant(_collections.find(ns) != _collections.end()); + invariant(_orderedCollections.find(dbIdPair) != _orderedCollections.end()); + invariant(_catalog[uuid].collectionCatalogEntry); + invariant(_collections[ns]->collectionCatalogEntry); + invariant(_orderedCollections[dbIdPair]->collectionCatalogEntry); + + // Make sure collection object does not exist. + invariant(_catalog[uuid].collection == nullptr); + invariant(_collections[ns]->collection == nullptr); + invariant(_orderedCollections[dbIdPair]->collection == nullptr); + + + _catalog[uuid].collection = std::move(coll); + _catalog[uuid].collectionPtr = _catalog[uuid].collection.get(); + + auto dbRid = ResourceId(RESOURCE_DATABASE, dbName); + addResource(dbRid, dbName); + + auto collRid = ResourceId(RESOURCE_COLLECTION, ns.ns()); + addResource(collRid, ns.ns()); +} + +std::unique_ptr CollectionCatalog::deregisterCollectionObject(CollectionUUID uuid) { + stdx::lock_guard lock(_catalogLock); + + invariant(_catalog.find(uuid) != _catalog.end()); + invariant(_catalog[uuid].collection); + + auto coll = std::move(_catalog[uuid].collection); + auto ns = coll->ns(); + auto dbName = ns.db().toString(); + auto dbIdPair = std::make_pair(dbName, uuid); + + LOG(0) << "Deregistering collection object " << ns << " with UUID " << uuid; + + // Make sure collection object exists. + invariant(_collections.find(ns) != _collections.end()); + invariant(_orderedCollections.find(dbIdPair) != _orderedCollections.end()); + + _catalog[uuid].collection = nullptr; + _catalog[uuid].collectionPtr = nullptr; + + // Make sure collection catalog entry still exists. + invariant(_catalog[uuid].collectionCatalogEntry); + + auto collRid = ResourceId(RESOURCE_COLLECTION, ns.ns()); + removeResource(collRid, ns.ns()); + + // Removal from an ordered map will invalidate iterators and potentially references to the + // references to the erased element. + _generationNumber++; + + return coll; +} + +std::unique_ptr CollectionCatalog::deregisterCatalogEntry( + CollectionUUID uuid) { + stdx::lock_guard lock(_catalogLock); + + invariant(_catalog.find(uuid) != _catalog.end()); + invariant(_catalog[uuid].collectionCatalogEntry); + + auto catalogEntry = std::move(_catalog[uuid].collectionCatalogEntry); + auto ns = catalogEntry->ns(); + auto dbName = ns.db().toString(); + auto dbIdPair = std::make_pair(dbName, uuid); + + LOG(0) << "Deregistering catalog entry " << ns << " with UUID " << uuid; + + // Make sure collection object is already gone. + invariant(_catalog[uuid].collection == nullptr); + invariant(_catalog[uuid].collectionPtr == nullptr); + + // Make sure catalog entry exist. + invariant(_collections.find(ns) != _collections.end()); + invariant(_orderedCollections.find(dbIdPair) != _orderedCollections.end()); + + _orderedCollections.erase(dbIdPair); + _collections.erase(ns); + _catalog.erase(uuid); + + // Removal from an ordered map will invalidate iterators and potentially references to the + // references to the erased element. + _generationNumber++; + + return catalogEntry; +} + +void CollectionCatalog::deregisterAllCatalogEntriesAndCollectionObjects() { + stdx::lock_guard lock(_catalogLock); + + LOG(0) << "Deregistering all the catalog entries and collection objects"; + for (auto& entry : _catalog) { + auto uuid = entry.first; + auto ns = entry.second.collectionCatalogEntry->ns(); + auto dbName = ns.db().toString(); + auto dbIdPair = std::make_pair(dbName, uuid); + + LOG(0) << "Deregistering collection " << ns << " with UUID " << uuid; + + entry.second.collection.reset(); + entry.second.collectionCatalogEntry.reset(); + } + + _collections.clear(); + _orderedCollections.clear(); + _catalog.clear(); + + stdx::lock_guard resourceLock(_resourceLock); + _resourceInformation.clear(); + + _generationNumber++; +} + +CollectionCatalog::iterator CollectionCatalog::begin(StringData db) const { + return iterator(db, _generationNumber, *this); +} + +CollectionCatalog::iterator CollectionCatalog::end() const { + return iterator(_orderedCollections.end()); +} + +boost::optional CollectionCatalog::lookupResourceName(const ResourceId& rid) { + invariant(rid.getType() == RESOURCE_DATABASE || rid.getType() == RESOURCE_COLLECTION); + stdx::lock_guard lock(_resourceLock); + + auto search = _resourceInformation.find(rid); + if (search == _resourceInformation.end()) { + return boost::none; + } + + std::set& namespaces = search->second; + + // When there are multiple namespaces mapped to the same ResourceId, return boost::none as the + // ResourceId does not identify a single namespace. + if (namespaces.size() > 1) { + return boost::none; + } + + return *namespaces.begin(); +} + +void CollectionCatalog::removeResource(const ResourceId& rid, const std::string& entry) { + invariant(rid.getType() == RESOURCE_DATABASE || rid.getType() == RESOURCE_COLLECTION); + stdx::lock_guard lock(_resourceLock); + + auto search = _resourceInformation.find(rid); + if (search == _resourceInformation.end()) { + return; + } + + std::set& namespaces = search->second; + namespaces.erase(entry); + + // Remove the map entry if this is the last namespace in the set for the ResourceId. + if (namespaces.size() == 0) { + _resourceInformation.erase(search); + } +} + +void CollectionCatalog::addResource(const ResourceId& rid, const std::string& entry) { + invariant(rid.getType() == RESOURCE_DATABASE || rid.getType() == RESOURCE_COLLECTION); + stdx::lock_guard lock(_resourceLock); + + auto search = _resourceInformation.find(rid); + if (search == _resourceInformation.end()) { + std::set newSet = {entry}; + _resourceInformation.insert(std::make_pair(rid, newSet)); + return; + } + + std::set& namespaces = search->second; + if (namespaces.count(entry) > 0) { + return; + } + + namespaces.insert(entry); +} + +} // namespace mongo diff --git a/src/mongo/db/catalog/collection_catalog.h b/src/mongo/db/catalog/collection_catalog.h new file mode 100644 index 00000000000..8a7dcaae650 --- /dev/null +++ b/src/mongo/db/catalog/collection_catalog.h @@ -0,0 +1,327 @@ +/** + * Copyright (C) 2018-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * . + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#pragma once + +#include +#include +#include + +#include "mongo/db/catalog/collection.h" +#include "mongo/db/catalog/collection_catalog_entry.h" +#include "mongo/db/service_context.h" +#include "mongo/stdx/functional.h" +#include "mongo/util/uuid.h" + +namespace mongo { + +/** + * This class comprises a UUID to collection catalog, allowing for efficient + * collection lookup by UUID. + */ +using CollectionUUID = UUID; +class Database; + +class CollectionCatalog { + CollectionCatalog(const CollectionCatalog&) = delete; + CollectionCatalog& operator=(const CollectionCatalog&) = delete; + + friend class iterator; + struct CollectionInfo; + +public: + class iterator { + public: + using value_type = Collection*; + using pointer = const value_type*; + using reference = const value_type&; + + iterator(StringData dbName, uint64_t genNum, const CollectionCatalog& catalog); + iterator(std::map, + CollectionCatalog::CollectionInfo*>::const_iterator mapIter); + pointer operator->(); + reference operator*(); + iterator operator++(); + iterator operator++(int); + boost::optional uuid(); + + /* + * Equality operators == and != do not attempt to reposition the iterators being compared. + * The behavior for comparing invalid iterators is undefined. + */ + bool operator==(const iterator& other); + bool operator!=(const iterator& other); + + private: + /** + * Check if _mapIter has been invalidated due to a change in the _orderedCollections map. If + * it has, restart iteration through a call to lower_bound. If the element that the iterator + * is currently pointing to has been deleted, the iterator will be repositioned to the + * element that follows it. + * + * Returns true if iterator got repositioned. + */ + bool _repositionIfNeeded(); + bool _exhausted(); + + std::string _dbName; + boost::optional _uuid; + uint64_t _genNum; + std::map, CollectionInfo*>::const_iterator _mapIter; + const CollectionCatalog* _catalog; + static constexpr Collection* _nullCollection = nullptr; + }; + + static CollectionCatalog& get(ServiceContext* svcCtx); + static CollectionCatalog& get(OperationContext* opCtx); + CollectionCatalog() = default; + + /** + * This function inserts the entry for uuid, coll into the collection catalog. It is called by + * the op observer when a collection is created. + */ + void onCreateCollection(OperationContext* opCtx, + std::unique_ptr coll, + CollectionUUID uuid); + + /** + * This function removes the entry for uuid from the collection catalog. It is called by the op + * observer when a collection is dropped. + */ + void onDropCollection(OperationContext* opCtx, CollectionUUID uuid); + + /** + * This function is responsible for safely setting the namespace string inside 'coll' to the + * value of 'toCollection'. The caller need not hold locks on the collection. + * + * Must be called within a WriteUnitOfWork. The Collection namespace will be set back to + * 'fromCollection' if the WriteUnitOfWork aborts. + */ + void setCollectionNamespace(OperationContext* opCtx, + Collection* coll, + const NamespaceString& fromCollection, + const NamespaceString& toCollection); + + /** + * Implies onDropCollection for all collections in db, but is not transactional. + */ + void onCloseDatabase(OperationContext* opCtx, std::string dbName); + + /** + * Register the collection catalog entry with `uuid`. The collection object with `uuid` must not + * exist in the CollectionCatalog yet. + */ + void registerCatalogEntry(CollectionUUID uuid, + std::unique_ptr collectionCatalogEntry); + + /** + * Deregister the collection catalog entry. The collection object with `uuid` is already gone, + * so this function completely removes any info about uuid. + */ + std::unique_ptr deregisterCatalogEntry(CollectionUUID uuid); + + /** + * Register the collection object with `uuid`. The collection catalog entry with `uuid` already + * exists in the CollectionCatalog. + */ + void registerCollectionObject(CollectionUUID uuid, std::unique_ptr coll); + + /** + * Deregister the collection object. The collection catalog entry still exists and will be + * deregistered later. + */ + std::unique_ptr deregisterCollectionObject(CollectionUUID uuid); + + + /** + * Deregister all the collection objects and catalog entries. + */ + void deregisterAllCatalogEntriesAndCollectionObjects(); + + /** + * This function gets the Collection pointer that corresponds to the CollectionUUID. + * The required locks must be obtained prior to calling this function, or else the found + * Collection pointer might no longer be valid when the call returns. + * + * Returns nullptr if the 'uuid' is not known. + */ + Collection* lookupCollectionByUUID(CollectionUUID uuid) const; + + /** + * This function gets the CollectionCatalogEntry pointer that corresponds to the + * CollectionUUID. + * The required locks must be obtained prior to calling this function, or else the found + * CollectionCatalogEntry pointer might no longer be valid when the call returns. + * + * Returns nullptr if the 'uuid' is not known. + */ + CollectionCatalogEntry* lookupCollectionCatalogEntryByUUID(CollectionUUID uuid) const; + + /** + * This function gets the Collection pointer that corresponds to the NamespaceString. + * The required locks must be obtained prior to calling this function, or else the found + * Collection pointer may no longer be valid when the call returns. + * + * Returns nullptr if the namespace is unknown. + */ + Collection* lookupCollectionByNamespace(const NamespaceString& nss) const; + + /** + * This function gets the CollectionCatalogEntry pointer that corresponds to the + * CollectionUUID. + * The required locks must be obtained prior to calling this function, or else the found + * CollectionCatalogEntry pointer might no longer be valid when the call returns. + * + * Returns nullptr if the 'uuid' is not known. + */ + CollectionCatalogEntry* lookupCollectionCatalogEntryByNamespace( + const NamespaceString& nss) const; + + /** + * This function gets the NamespaceString from the collection catalog entry that + * corresponds to CollectionUUID uuid. If no collection exists with the uuid, return + * boost::none. See onCloseCatalog/onOpenCatalog for more info. + */ + boost::optional lookupNSSByUUID(CollectionUUID uuid) const; + + /** + * Returns the UUID if `nss` exists in CollectionCatalog. The time complexity of + * this function is linear to the number of collections in `nss.db()`. + */ + boost::optional lookupUUIDByNSS(const NamespaceString& nss) const; + + /** + * This function gets the UUIDs of all collections from `dbName`. + * + * If the caller does not take a strong database lock, some of UUIDs might no longer exist (due + * to collection drop) after this function returns. + * + * Returns empty vector if the 'dbName' is not known. + */ + std::vector getAllCollectionUUIDsFromDb(StringData dbName) const; + + /** + * This function gets the ns of all collections from `dbName`. The result is not sorted. + * + * Caller must take a strong database lock; otherwise, collections returned could be dropped or + * renamed. + * + * Returns empty vector if the 'dbName' is not known. + */ + std::vector getAllCollectionNamesFromDb(OperationContext* opCtx, + StringData dbName) const; + + /** + * This functions gets all the database names. The result is sorted in alphabetical ascending + * order. + */ + std::vector getAllDbNames() 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, + * like authorization and replication, which need to do lookups outside of database locks, to + * proceed. + * + * Must be called with the global lock acquired in exclusive mode. + */ + void onCloseCatalog(OperationContext* opCtx); + + /** + * Puts the catatlog back in open state, removing the pre-close state. See onCloseCatalog. + * + * Must be called with the global lock acquired in exclusive mode. + */ + void onOpenCatalog(OperationContext* opCtx); + + iterator begin(StringData db) const; + iterator end() const; + + /** + * 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. + */ + boost::optional lookupResourceName(const ResourceId& rid); + + /** + * Removes an existing ResourceId 'rid' with namespace 'entry' from the map. + */ + void removeResource(const ResourceId& rid, const std::string& entry); + + /** + * Inserts a new ResourceId 'rid' into the map with namespace 'entry'. + */ + void addResource(const ResourceId& rid, const std::string& entry); + +private: + class FinishDropChange; + friend class CollectionCatalog::iterator; + + const std::vector& _getOrdering_inlock(const StringData& db, + const stdx::lock_guard&); + mutable mongo::stdx::mutex _catalogLock; + /** + * When present, indicates that the catalog is in closed state, and contains a map from UUID + * to pre-close NSS. See also onCloseCatalog. + */ + boost::optional< + mongo::stdx::unordered_map> + _shadowCatalog; + + /** + * Unordered map from Collection UUID to the corresponding Collection object and + * CollectionCatalogEntry object. + */ + struct CollectionInfo { + std::unique_ptr collection; + Collection* collectionPtr; // This store the address to the collection object + std::unique_ptr collectionCatalogEntry; + }; + mongo::stdx::unordered_map _catalog; + + /** + * Ordered map from to a Collection object. + */ + std::map, CollectionInfo*> _orderedCollections; + + mongo::stdx::unordered_map _collections; + + /** + * Generation number to track changes to the catalog that could invalidate iterators. + */ + uint64_t _generationNumber; + + // Protects _resourceInformation. + mutable stdx::mutex _resourceLock; + + // Mapping from ResourceId to a set of strings that contains collection and database namespaces. + std::map> _resourceInformation; +}; +} // namespace mongo diff --git a/src/mongo/db/catalog/collection_catalog_helper.cpp b/src/mongo/db/catalog/collection_catalog_helper.cpp new file mode 100644 index 00000000000..34b6ce992e1 --- /dev/null +++ b/src/mongo/db/catalog/collection_catalog_helper.cpp @@ -0,0 +1,68 @@ +/** + * Copyright (C) 2019-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * . + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#include "mongo/db/catalog/collection_catalog_helper.h" +#include "mongo/db/catalog/collection.h" +#include "mongo/db/catalog/collection_catalog.h" +#include "mongo/db/catalog/collection_catalog_entry.h" +#include "mongo/db/concurrency/d_concurrency.h" + +namespace mongo { +namespace catalog { + +void forEachCollectionFromDb( + OperationContext* opCtx, + StringData dbName, + LockMode collLockMode, + std::function callback) { + + CollectionCatalog& catalog = CollectionCatalog::get(opCtx); + for (auto collectionIt = catalog.begin(dbName); collectionIt != catalog.end(); ++collectionIt) { + auto uuid = collectionIt.uuid().get(); + auto nss = catalog.lookupNSSByUUID(uuid); + + // If the NamespaceString can't be resolved from the uuid, then the collection was dropped. + if (!nss) { + continue; + } + + Lock::CollectionLock clk(opCtx, *nss, collLockMode); + + auto collection = catalog.lookupCollectionByUUID(uuid); + auto catalogEntry = catalog.lookupCollectionCatalogEntryByUUID(uuid); + if (!collection || !catalogEntry || catalogEntry->ns() != *nss) + continue; + + if (!callback(collection, catalogEntry)) + break; + } +} + +} // namespace catalog +} // namespace mongo diff --git a/src/mongo/db/catalog/collection_catalog_helper.h b/src/mongo/db/catalog/collection_catalog_helper.h new file mode 100644 index 00000000000..50df494842e --- /dev/null +++ b/src/mongo/db/catalog/collection_catalog_helper.h @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2019-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * . + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#pragma once + +#include "mongo/db/concurrency/lock_manager_defs.h" +#include "mongo/db/operation_context.h" + +namespace mongo { + +class Collection; +class CollectionCatalogEntry; + +namespace catalog { + +/** + * Looping through all the collections in the database and run callback function on each one of + * them. The return value of the callback decides whether we should continue the loop. + */ +void forEachCollectionFromDb( + OperationContext* opCtx, + StringData dbName, + LockMode collLockMode, + std::function callback); + +} // namespace catalog +} // namespace mongo diff --git a/src/mongo/db/catalog/collection_catalog_test.cpp b/src/mongo/db/catalog/collection_catalog_test.cpp new file mode 100644 index 00000000000..7a4f96fd2f5 --- /dev/null +++ b/src/mongo/db/catalog/collection_catalog_test.cpp @@ -0,0 +1,669 @@ +/** + * Copyright (C) 2018-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * . + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ +#include "mongo/db/catalog/collection_catalog.h" + +#include +#include + +#include "mongo/db/catalog/collection_catalog_entry_mock.h" +#include "mongo/db/catalog/collection_mock.h" +#include "mongo/db/concurrency/lock_manager_defs.h" +#include "mongo/db/operation_context_noop.h" +#include "mongo/unittest/death_test.h" +#include "mongo/unittest/unittest.h" + +using namespace mongo; + +/** + * A test fixture that creates a CollectionCatalog and Collection* pointer to store in it. + */ +class CollectionCatalogTest : public unittest::Test { +public: + CollectionCatalogTest() + : nss("testdb", "testcol"), + col(nullptr), + colUUID(CollectionUUID::gen()), + nextUUID(CollectionUUID::gen()), + prevUUID(CollectionUUID::gen()) { + if (prevUUID > colUUID) + std::swap(prevUUID, colUUID); + if (colUUID > nextUUID) + std::swap(colUUID, nextUUID); + if (prevUUID > colUUID) + std::swap(prevUUID, colUUID); + ASSERT_GT(colUUID, prevUUID); + ASSERT_GT(nextUUID, colUUID); + + auto collection = std::make_unique(nss); + auto catalogEntry = std::make_unique(nss.ns()); + col = collection.get(); + // Register dummy collection in catalog. + catalog.registerCatalogEntry(colUUID, std::move(catalogEntry)); + catalog.onCreateCollection(&opCtx, std::move(collection), colUUID); + } + +protected: + CollectionCatalog catalog; + OperationContextNoop opCtx; + NamespaceString nss; + CollectionMock* col; + CollectionUUID colUUID; + CollectionUUID nextUUID; + CollectionUUID prevUUID; +}; + +class CollectionCatalogIterationTest : public unittest::Test { +public: + void setUp() { + for (int counter = 0; counter < 5; ++counter) { + NamespaceString fooNss("foo", "coll" + std::to_string(counter)); + NamespaceString barNss("bar", "coll" + std::to_string(counter)); + + auto fooUuid = CollectionUUID::gen(); + auto fooColl = std::make_unique(fooNss); + auto fooCatalogEntry = std::make_unique(fooNss.ns()); + + auto barUuid = CollectionUUID::gen(); + auto barColl = std::make_unique(barNss); + auto barCatalogEntry = std::make_unique(barNss.ns()); + + dbMap["foo"].insert(std::make_pair(fooUuid, fooColl.get())); + dbMap["bar"].insert(std::make_pair(barUuid, barColl.get())); + catalog.registerCatalogEntry(fooUuid, std::move(fooCatalogEntry)); + catalog.registerCatalogEntry(barUuid, std::move(barCatalogEntry)); + catalog.onCreateCollection(&opCtx, std::move(fooColl), fooUuid); + catalog.onCreateCollection(&opCtx, std::move(barColl), barUuid); + } + } + + void tearDown() { + for (auto& it : dbMap) { + for (auto& kv : it.second) { + catalog.onDropCollection(&opCtx, kv.first); + } + } + } + + std::map::iterator collsIterator(std::string dbName) { + auto it = dbMap.find(dbName); + ASSERT(it != dbMap.end()); + return it->second.begin(); + } + + std::map::iterator collsIteratorEnd(std::string dbName) { + auto it = dbMap.find(dbName); + ASSERT(it != dbMap.end()); + return it->second.end(); + } + + void checkCollections(std::string dbName) { + unsigned long counter = 0; + + for (auto[orderedIt, catalogIt] = std::tuple{collsIterator(dbName), catalog.begin(dbName)}; + catalogIt != catalog.end() && orderedIt != collsIteratorEnd(dbName); + ++catalogIt, ++orderedIt) { + + auto catalogColl = *catalogIt; + ASSERT(catalogColl != nullptr); + auto orderedColl = orderedIt->second; + ASSERT_EQ(catalogColl->ns(), orderedColl->ns()); + ++counter; + } + + ASSERT_EQUALS(counter, dbMap[dbName].size()); + } + + void dropColl(const std::string dbName, CollectionUUID uuid) { + dbMap[dbName].erase(uuid); + } + +protected: + CollectionCatalog catalog; + OperationContextNoop opCtx; + std::map> dbMap; +}; + +class CollectionCatalogResourceMapTest : public unittest::Test { +public: + void setUp() { + // The first and second collection namespaces map to the same ResourceId. + firstCollection = "1661880728"; + secondCollection = "1626936312"; + + firstResourceId = ResourceId(RESOURCE_COLLECTION, firstCollection); + secondResourceId = ResourceId(RESOURCE_COLLECTION, secondCollection); + ASSERT_EQ(firstResourceId, secondResourceId); + + thirdCollection = "2930102946"; + thirdResourceId = ResourceId(RESOURCE_COLLECTION, thirdCollection); + ASSERT_NE(firstResourceId, thirdResourceId); + } + +protected: + std::string firstCollection; + ResourceId firstResourceId; + + std::string secondCollection; + ResourceId secondResourceId; + + std::string thirdCollection; + ResourceId thirdResourceId; + + CollectionCatalog catalog; +}; + +TEST_F(CollectionCatalogResourceMapTest, EmptyTest) { + boost::optional resource = catalog.lookupResourceName(firstResourceId); + ASSERT_EQ(boost::none, resource); + + catalog.removeResource(secondResourceId, secondCollection); + resource = catalog.lookupResourceName(secondResourceId); + ASSERT_EQ(boost::none, resource); +} + +TEST_F(CollectionCatalogResourceMapTest, InsertTest) { + catalog.addResource(firstResourceId, firstCollection); + boost::optional resource = catalog.lookupResourceName(thirdResourceId); + ASSERT_EQ(boost::none, resource); + + catalog.addResource(thirdResourceId, thirdCollection); + + resource = catalog.lookupResourceName(firstResourceId); + ASSERT_EQ(firstCollection, *resource); + + resource = catalog.lookupResourceName(thirdResourceId); + ASSERT_EQ(thirdCollection, resource); +} + +TEST_F(CollectionCatalogResourceMapTest, RemoveTest) { + catalog.addResource(firstResourceId, firstCollection); + catalog.addResource(thirdResourceId, thirdCollection); + + // This fails to remove the resource because of an invalid namespace. + catalog.removeResource(firstResourceId, "BadNamespace"); + boost::optional resource = catalog.lookupResourceName(firstResourceId); + ASSERT_EQ(firstCollection, *resource); + + catalog.removeResource(firstResourceId, firstCollection); + catalog.removeResource(firstResourceId, firstCollection); + catalog.removeResource(thirdResourceId, thirdCollection); + + resource = catalog.lookupResourceName(firstResourceId); + ASSERT_EQ(boost::none, resource); + + resource = catalog.lookupResourceName(thirdResourceId); + ASSERT_EQ(boost::none, resource); +} + +TEST_F(CollectionCatalogResourceMapTest, CollisionTest) { + // firstCollection and secondCollection map to the same ResourceId. + catalog.addResource(firstResourceId, firstCollection); + catalog.addResource(secondResourceId, secondCollection); + + // Looking up the namespace on a ResourceId while it has a collision should + // return the empty string. + boost::optional resource = catalog.lookupResourceName(firstResourceId); + ASSERT_EQ(boost::none, resource); + + resource = catalog.lookupResourceName(secondResourceId); + ASSERT_EQ(boost::none, resource); + + // We remove a namespace, resolving the collision. + catalog.removeResource(firstResourceId, firstCollection); + resource = catalog.lookupResourceName(secondResourceId); + ASSERT_EQ(secondCollection, *resource); + + // Adding the same namespace twice does not create a collision. + catalog.addResource(secondResourceId, secondCollection); + resource = catalog.lookupResourceName(secondResourceId); + ASSERT_EQ(secondCollection, *resource); + + // The map should function normally for entries without collisions. + catalog.addResource(firstResourceId, firstCollection); + resource = catalog.lookupResourceName(secondResourceId); + ASSERT_EQ(boost::none, resource); + + catalog.addResource(thirdResourceId, thirdCollection); + resource = catalog.lookupResourceName(thirdResourceId); + ASSERT_EQ(thirdCollection, *resource); + + catalog.removeResource(thirdResourceId, thirdCollection); + resource = catalog.lookupResourceName(thirdResourceId); + ASSERT_EQ(boost::none, resource); + + catalog.removeResource(firstResourceId, firstCollection); + catalog.removeResource(secondResourceId, secondCollection); + + resource = catalog.lookupResourceName(firstResourceId); + ASSERT_EQ(boost::none, resource); + + resource = catalog.lookupResourceName(secondResourceId); + ASSERT_EQ(boost::none, resource); +} + +class CollectionCatalogResourceTest : public unittest::Test { +public: + void setUp() { + for (int i = 0; i < 5; i++) { + NamespaceString nss("resourceDb", "coll" + std::to_string(i)); + auto coll = std::make_unique(nss); + auto newCatalogEntry = std::make_unique(nss.ns()); + auto uuid = coll->uuid(); + + catalog.registerCatalogEntry(uuid.get(), std::move(newCatalogEntry)); + catalog.onCreateCollection(&opCtx, std::move(coll), uuid.get()); + } + + int numEntries = 0; + for (auto it = catalog.begin("resourceDb"); it != catalog.end(); it++) { + auto coll = *it; + std::string collName = coll->ns().ns(); + ResourceId rid(RESOURCE_COLLECTION, collName); + + ASSERT_NE(catalog.lookupResourceName(rid), boost::none); + numEntries++; + } + ASSERT_EQ(5, numEntries); + } + + void tearDown() { + for (auto it = catalog.begin("resourceDb"); it != catalog.end(); ++it) { + auto coll = *it; + auto uuid = coll->uuid().get(); + if (!coll) { + break; + } + + catalog.deregisterCollectionObject(uuid); + catalog.deregisterCatalogEntry(uuid); + } + + int numEntries = 0; + for (auto it = catalog.begin("resourceDb"); it != catalog.end(); it++) { + numEntries++; + } + ASSERT_EQ(0, numEntries); + } + +protected: + OperationContextNoop opCtx; + CollectionCatalog catalog; +}; + +namespace { + +TEST_F(CollectionCatalogResourceTest, RemoveAllResources) { + catalog.deregisterAllCatalogEntriesAndCollectionObjects(); + + const std::string dbName = "resourceDb"; + auto rid = ResourceId(RESOURCE_DATABASE, dbName); + ASSERT_EQ(boost::none, catalog.lookupResourceName(rid)); + + for (int i = 0; i < 5; i++) { + NamespaceString nss("resourceDb", "coll" + std::to_string(i)); + rid = ResourceId(RESOURCE_COLLECTION, nss.ns()); + ASSERT_EQ(boost::none, catalog.lookupResourceName((rid))); + } +} + +TEST_F(CollectionCatalogResourceTest, LookupDatabaseResource) { + const std::string dbName = "resourceDb"; + auto rid = ResourceId(RESOURCE_DATABASE, dbName); + boost::optional ridStr = catalog.lookupResourceName(rid); + + ASSERT(ridStr); + ASSERT(ridStr->find(dbName) != std::string::npos); +} + +TEST_F(CollectionCatalogResourceTest, LookupMissingDatabaseResource) { + const std::string dbName = "missingDb"; + auto rid = ResourceId(RESOURCE_DATABASE, dbName); + ASSERT(!catalog.lookupResourceName(rid)); +} + +TEST_F(CollectionCatalogResourceTest, LookupCollectionResource) { + const std::string collNs = "resourceDb.coll1"; + auto rid = ResourceId(RESOURCE_COLLECTION, collNs); + boost::optional ridStr = catalog.lookupResourceName(rid); + + ASSERT(ridStr); + ASSERT(ridStr->find(collNs) != std::string::npos); +} + +TEST_F(CollectionCatalogResourceTest, LookupMissingCollectionResource) { + const std::string dbName = "resourceDb.coll5"; + auto rid = ResourceId(RESOURCE_COLLECTION, dbName); + ASSERT(!catalog.lookupResourceName(rid)); +} + +TEST_F(CollectionCatalogResourceTest, RemoveCollection) { + const std::string collNs = "resourceDb.coll1"; + auto coll = catalog.lookupCollectionByNamespace(NamespaceString(collNs)); + auto uniqueColl = catalog.deregisterCollectionObject(coll->uuid().get()); + catalog.deregisterCatalogEntry(uniqueColl->uuid().get()); + auto rid = ResourceId(RESOURCE_COLLECTION, collNs); + ASSERT(!catalog.lookupResourceName(rid)); +} + +// Create an iterator over the CollectionCatalog and assert that all collections are present. +// Iteration ends when the end of the catalog is reached. +TEST_F(CollectionCatalogIterationTest, EndAtEndOfCatalog) { + checkCollections("foo"); +} + +// Create an iterator over the CollectionCatalog and test that all collections are present. +// Iteration ends +// when the end of a database-specific section of the catalog is reached. +TEST_F(CollectionCatalogIterationTest, EndAtEndOfSection) { + checkCollections("bar"); +} + +// Delete an entry in the catalog while iterating. +TEST_F(CollectionCatalogIterationTest, InvalidateEntry) { + auto it = catalog.begin("bar"); + + // Invalidate bar.coll1. + for (auto collsIt = collsIterator("bar"); collsIt != collsIteratorEnd("bar"); ++collsIt) { + if (collsIt->second->ns().ns() == "bar.coll1") { + catalog.onDropCollection(&opCtx, collsIt->first); + dropColl("bar", collsIt->first); + break; + } + } + + // Ensure bar.coll1 is not returned by the iterator. + for (; it != catalog.end(); ++it) { + auto coll = *it; + ASSERT(coll && coll->ns().ns() != "bar.coll1"); + } +} + +// Delete the entry pointed to by the iterator and dereference the iterator. +TEST_F(CollectionCatalogIterationTest, InvalidateAndDereference) { + auto it = catalog.begin("bar"); + auto collsIt = collsIterator("bar"); + auto uuid = collsIt->first; + catalog.onDropCollection(&opCtx, uuid); + ++collsIt; + + ASSERT(it != catalog.end()); + auto catalogColl = *it; + ASSERT(catalogColl != nullptr); + ASSERT_EQUALS(catalogColl->ns(), collsIt->second->ns()); + + dropColl("bar", uuid); +} + +// Delete the last entry for a database while pointing to it and dereference the iterator. +TEST_F(CollectionCatalogIterationTest, InvalidateLastEntryAndDereference) { + auto it = catalog.begin("bar"); + NamespaceString lastNs; + boost::optional uuid; + for (auto collsIt = collsIterator("bar"); collsIt != collsIteratorEnd("bar"); ++collsIt) { + lastNs = collsIt->second->ns(); + uuid = collsIt->first; + } + + // Increment until it points to the last collection. + for (; it != catalog.end(); ++it) { + auto coll = *it; + ASSERT(coll != nullptr); + if (coll->ns() == lastNs) { + break; + } + } + + catalog.onDropCollection(&opCtx, *uuid); + dropColl("bar", *uuid); + ASSERT(*it == nullptr); +} + +// Delete the last entry in the map while pointing to it and dereference the iterator. +TEST_F(CollectionCatalogIterationTest, InvalidateLastEntryInMapAndDereference) { + auto it = catalog.begin("foo"); + NamespaceString lastNs; + boost::optional uuid; + for (auto collsIt = collsIterator("foo"); collsIt != collsIteratorEnd("foo"); ++collsIt) { + lastNs = collsIt->second->ns(); + uuid = collsIt->first; + } + + // Increment until it points to the last collection. + for (; it != catalog.end(); ++it) { + auto coll = *it; + ASSERT(coll != nullptr); + if (coll->ns() == lastNs) { + break; + } + } + + catalog.onDropCollection(&opCtx, *uuid); + dropColl("foo", *uuid); + ASSERT(*it == nullptr); +} + +TEST_F(CollectionCatalogIterationTest, BeginSkipsOverEmptyCollectionObject) { + NamespaceString a1("a", "coll1"); + NamespaceString a2("a", "coll2"); + + auto a1Uuid = CollectionUUID::gen(); + auto a1CatalogEntry = std::make_unique(a1.ns()); + + auto a2Uuid = CollectionUUID::gen(); + if (a2Uuid < a1Uuid) + std::swap(a1Uuid, a2Uuid); + auto a2Coll = std::make_unique(a2); + auto a2CatalogEntry = std::make_unique(a2.ns()); + + catalog.registerCatalogEntry(a1Uuid, std::move(a1CatalogEntry)); + catalog.registerCatalogEntry(a2Uuid, std::move(a2CatalogEntry)); + catalog.onCreateCollection(&opCtx, std::move(a2Coll), a2Uuid); + + auto it = catalog.begin("a"); + ASSERT(it != catalog.end()); + auto coll = *it; + // Skips a.coll1 due to empty collection object. + ASSERT(coll->ns().ns() == a2.ns()); +} + +TEST_F(CollectionCatalogIterationTest, BeginSkipsOverEmptyCollectionObjectButStopsAtDbBoundary) { + NamespaceString a("a", "coll1"); + NamespaceString b("b", "coll1"); + + auto aUuid = CollectionUUID::gen(); + auto aCatalogEntry = std::make_unique(a.ns()); + + auto bUuid = CollectionUUID::gen(); + + auto bColl = std::make_unique(b); + auto bCatalogEntry = std::make_unique(b.ns()); + + catalog.registerCatalogEntry(aUuid, std::move(aCatalogEntry)); + catalog.registerCatalogEntry(bUuid, std::move(bCatalogEntry)); + catalog.onCreateCollection(&opCtx, std::move(bColl), bUuid); + + auto it = catalog.begin("a"); + ASSERT(it == catalog.end()); +} + +TEST_F(CollectionCatalogIterationTest, GetUUIDWontRepositionEvenIfEntryIsDropped) { + auto it = catalog.begin("bar"); + auto collsIt = collsIterator("bar"); + auto uuid = collsIt->first; + catalog.onDropCollection(&opCtx, uuid); + dropColl("bar", uuid); + + ASSERT_EQUALS(uuid, it.uuid()); +} + +TEST_F(CollectionCatalogTest, OnCreateCollection) { + ASSERT(catalog.lookupCollectionByUUID(colUUID) == col); +} + +TEST_F(CollectionCatalogTest, LookupCollectionByUUID) { + // Ensure the string value of the NamespaceString of the obtained Collection is equal to + // nss.ns(). + ASSERT_EQUALS(catalog.lookupCollectionByUUID(colUUID)->ns().ns(), nss.ns()); + // Ensure lookups of unknown UUIDs result in null pointers. + ASSERT(catalog.lookupCollectionByUUID(CollectionUUID::gen()) == nullptr); +} + +TEST_F(CollectionCatalogTest, LookupNSSByUUID) { + // Ensure the string value of the obtained NamespaceString is equal to nss.ns(). + ASSERT_EQUALS(catalog.lookupNSSByUUID(colUUID)->ns(), nss.ns()); + // Ensure namespace lookups of unknown UUIDs result in empty NamespaceStrings. + ASSERT_EQUALS(catalog.lookupNSSByUUID(CollectionUUID::gen()), boost::none); +} + +TEST_F(CollectionCatalogTest, InsertAfterLookup) { + auto newUUID = CollectionUUID::gen(); + NamespaceString newNss(nss.db(), "newcol"); + auto newCollUnique = std::make_unique(newNss); + auto newCatalogEntry = std::make_unique(newNss.ns()); + auto newCol = newCollUnique.get(); + + // Ensure that looking up non-existing UUIDs doesn't affect later registration of those UUIDs. + ASSERT(catalog.lookupCollectionByUUID(newUUID) == nullptr); + ASSERT_EQUALS(catalog.lookupNSSByUUID(newUUID), boost::none); + catalog.registerCatalogEntry(newUUID, std::move(newCatalogEntry)); + catalog.onCreateCollection(&opCtx, std::move(newCollUnique), newUUID); + ASSERT_EQUALS(catalog.lookupCollectionByUUID(newUUID), newCol); + ASSERT_EQUALS(*catalog.lookupNSSByUUID(colUUID), nss); +} + +TEST_F(CollectionCatalogTest, OnDropCollection) { + catalog.onDropCollection(&opCtx, colUUID); + // Ensure the lookup returns a null pointer upon removing the colUUID entry. + ASSERT(catalog.lookupCollectionByUUID(colUUID) == nullptr); +} + +TEST_F(CollectionCatalogTest, RenameCollection) { + auto uuid = CollectionUUID::gen(); + NamespaceString oldNss(nss.db(), "oldcol"); + auto collUnique = std::make_unique(oldNss); + auto catalogEntry = std::make_unique(oldNss.ns()); + auto collection = collUnique.get(); + catalog.registerCatalogEntry(uuid, std::move(catalogEntry)); + catalog.onCreateCollection(&opCtx, std::move(collUnique), uuid); + ASSERT_EQUALS(catalog.lookupCollectionByUUID(uuid), collection); + + NamespaceString newNss(nss.db(), "newcol"); + catalog.setCollectionNamespace(&opCtx, collection, oldNss, newNss); + ASSERT_EQ(collection->ns(), newNss); + ASSERT_EQUALS(catalog.lookupCollectionByUUID(uuid), collection); +} + +TEST_F(CollectionCatalogTest, LookupNSSByUUIDForClosedCatalogReturnsOldNSSIfDropped) { + catalog.onCloseCatalog(&opCtx); + catalog.onDropCollection(&opCtx, colUUID); + catalog.deregisterCatalogEntry(colUUID); + ASSERT(catalog.lookupCollectionByUUID(colUUID) == nullptr); + ASSERT_EQUALS(*catalog.lookupNSSByUUID(colUUID), nss); + catalog.onOpenCatalog(&opCtx); + ASSERT_EQUALS(catalog.lookupNSSByUUID(colUUID), boost::none); +} + +TEST_F(CollectionCatalogTest, LookupNSSByUUIDForClosedCatalogReturnsNewlyCreatedNSS) { + auto newUUID = CollectionUUID::gen(); + NamespaceString newNss(nss.db(), "newcol"); + auto newCollUnique = std::make_unique(newNss); + auto newCatalogEntry = std::make_unique(newNss.ns()); + auto newCol = newCollUnique.get(); + + // Ensure that looking up non-existing UUIDs doesn't affect later registration of those UUIDs. + catalog.onCloseCatalog(&opCtx); + ASSERT(catalog.lookupCollectionByUUID(newUUID) == nullptr); + ASSERT_EQUALS(catalog.lookupNSSByUUID(newUUID), boost::none); + catalog.registerCatalogEntry(newUUID, std::move(newCatalogEntry)); + catalog.onCreateCollection(&opCtx, std::move(newCollUnique), newUUID); + ASSERT_EQUALS(catalog.lookupCollectionByUUID(newUUID), newCol); + ASSERT_EQUALS(*catalog.lookupNSSByUUID(colUUID), nss); + + // Ensure that collection still exists after opening the catalog again. + catalog.onOpenCatalog(&opCtx); + ASSERT_EQUALS(catalog.lookupCollectionByUUID(newUUID), newCol); + ASSERT_EQUALS(*catalog.lookupNSSByUUID(colUUID), nss); +} + +TEST_F(CollectionCatalogTest, LookupNSSByUUIDForClosedCatalogReturnsFreshestNSS) { + NamespaceString newNss(nss.db(), "newcol"); + auto newCollUnique = std::make_unique(newNss); + auto newCatalogEntry = std::make_unique(newNss.ns()); + auto newCol = newCollUnique.get(); + + catalog.onCloseCatalog(&opCtx); + catalog.onDropCollection(&opCtx, colUUID); + catalog.deregisterCatalogEntry(colUUID); + ASSERT(catalog.lookupCollectionByUUID(colUUID) == nullptr); + ASSERT_EQUALS(*catalog.lookupNSSByUUID(colUUID), nss); + catalog.registerCatalogEntry(colUUID, std::move(newCatalogEntry)); + catalog.onCreateCollection(&opCtx, std::move(newCollUnique), colUUID); + ASSERT_EQUALS(catalog.lookupCollectionByUUID(colUUID), newCol); + ASSERT_EQUALS(*catalog.lookupNSSByUUID(colUUID), newNss); + + // Ensure that collection still exists after opening the catalog again. + catalog.onOpenCatalog(&opCtx); + ASSERT_EQUALS(catalog.lookupCollectionByUUID(colUUID), newCol); + ASSERT_EQUALS(*catalog.lookupNSSByUUID(colUUID), newNss); +} + +DEATH_TEST_F(CollectionCatalogResourceTest, AddInvalidResourceType, "invariant") { + auto rid = ResourceId(RESOURCE_GLOBAL, 0); + catalog.addResource(rid, ""); +} + +TEST_F(CollectionCatalogTest, GetAllCollectionNamesAndGetAllDbNames) { + NamespaceString aColl("dbA", "collA"); + NamespaceString b1Coll("dbB", "collB1"); + NamespaceString b2Coll("dbB", "collB2"); + NamespaceString cColl("dbC", "collC"); + NamespaceString d1Coll("dbD", "collD1"); + NamespaceString d2Coll("dbD", "collD2"); + NamespaceString d3Coll("dbD", "collD3"); + + std::vector nsss = {aColl, b1Coll, b2Coll, cColl, d1Coll, d2Coll, d3Coll}; + for (auto& nss : nsss) { + auto newColl = std::make_unique(nss); + auto newCatalogEntry = std::make_unique(nss.ns()); + auto uuid = CollectionUUID::gen(); + catalog.registerCatalogEntry(uuid, std::move(newCatalogEntry)); + catalog.registerCollectionObject(uuid, std::move(newColl)); + } + + std::vector dCollList = {d1Coll, d2Coll, d3Coll}; + auto res = catalog.getAllCollectionNamesFromDb(&opCtx, "dbD"); + std::sort(res.begin(), res.end()); + ASSERT(res == dCollList); + + std::vector dbNames = {"dbA", "dbB", "dbC", "dbD", "testdb"}; + ASSERT(catalog.getAllDbNames() == dbNames); + + catalog.deregisterAllCatalogEntriesAndCollectionObjects(); +} +} // namespace diff --git a/src/mongo/db/catalog/collection_impl.cpp b/src/mongo/db/catalog/collection_impl.cpp index 57f1f5fa173..16db8b5fb0e 100644 --- a/src/mongo/db/catalog/collection_impl.cpp +++ b/src/mongo/db/catalog/collection_impl.cpp @@ -42,6 +42,7 @@ #include "mongo/bson/simple_bsonelement_comparator.h" #include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/background.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_catalog_entry.h" #include "mongo/db/catalog/collection_info_cache_impl.h" #include "mongo/db/catalog/collection_options.h" @@ -49,7 +50,6 @@ #include "mongo/db/catalog/index_catalog_impl.h" #include "mongo/db/catalog/index_consistency.h" #include "mongo/db/catalog/index_key_validate.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/clientcursor.h" #include "mongo/db/commands/server_status_metric.h" #include "mongo/db/concurrency/d_concurrency.h" diff --git a/src/mongo/db/catalog/collection_impl.h b/src/mongo/db/catalog/collection_impl.h index cc26c48ae73..795c0947192 100644 --- a/src/mongo/db/catalog/collection_impl.h +++ b/src/mongo/db/catalog/collection_impl.h @@ -37,7 +37,7 @@ namespace mongo { class IndexConsistency; -class UUIDCatalog; +class CollectionCatalog; class CollectionImpl final : public Collection, public CappedCallback { private: static const int kMagicNumber = 1357924; diff --git a/src/mongo/db/catalog/collection_mock.h b/src/mongo/db/catalog/collection_mock.h index 14e9f8d1550..e4cd77b6809 100644 --- a/src/mongo/db/catalog/collection_mock.h +++ b/src/mongo/db/catalog/collection_mock.h @@ -35,7 +35,7 @@ namespace mongo { /** - * This class comprises a mock Collection for use by UUIDCatalog unit tests. + * This class comprises a mock Collection for use by CollectionCatalog unit tests. */ class CollectionMock : public Collection { public: diff --git a/src/mongo/db/catalog/create_collection.cpp b/src/mongo/db/catalog/create_collection.cpp index d2ecd5bed28..3a6a151106d 100644 --- a/src/mongo/db/catalog/create_collection.cpp +++ b/src/mongo/db/catalog/create_collection.cpp @@ -34,14 +34,15 @@ #include "mongo/db/catalog/create_collection.h" #include "mongo/bson/bsonobj.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/database_holder.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/command_generic_argument.h" #include "mongo/db/commands.h" #include "mongo/db/concurrency/write_conflict_exception.h" #include "mongo/db/curop.h" #include "mongo/db/db_raii.h" #include "mongo/db/namespace_string.h" +#include "mongo/db/op_observer.h" #include "mongo/db/operation_context.h" #include "mongo/db/ops/insert.h" #include "mongo/db/repl/replication_coordinator.h" @@ -222,7 +223,7 @@ Status createCollectionForApplyOps(OperationContext* opCtx, "Invalid UUID in applyOps create command: " + uuid.toString(), uuid.isRFC4122v4()); - auto& catalog = UUIDCatalog::get(opCtx); + auto& catalog = CollectionCatalog::get(opCtx); const auto currentName = catalog.lookupNSSByUUID(uuid); auto serviceContext = opCtx->getServiceContext(); auto opObserver = serviceContext->getOpObserver(); diff --git a/src/mongo/db/catalog/create_collection_test.cpp b/src/mongo/db/catalog/create_collection_test.cpp index 2d2061c1e98..591855f4479 100644 --- a/src/mongo/db/catalog/create_collection_test.cpp +++ b/src/mongo/db/catalog/create_collection_test.cpp @@ -29,9 +29,9 @@ #include "mongo/platform/basic.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_catalog_entry.h" #include "mongo/db/catalog/create_collection.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/client.h" #include "mongo/db/db_raii.h" #include "mongo/db/jsobj.h" @@ -186,8 +186,8 @@ TEST_F(CreateCollectionTest, ASSERT_EQUALS(uuid, getCollectionUuid(opCtx.get(), newNss)); // Check that old collection that was renamed out of the way still exists. - auto& uuidCatalog = UUIDCatalog::get(opCtx.get()); - auto renamedCollectionNss = uuidCatalog.lookupNSSByUUID(existingCollectionUuid); + auto& catalog = CollectionCatalog::get(opCtx.get()); + auto renamedCollectionNss = catalog.lookupNSSByUUID(existingCollectionUuid); ASSERT(renamedCollectionNss); ASSERT_TRUE(collectionExists(opCtx.get(), *renamedCollectionNss)) << "old renamed collection with UUID " << existingCollectionUuid diff --git a/src/mongo/db/catalog/database.h b/src/mongo/db/catalog/database.h index c13a0920b57..83402b8650e 100644 --- a/src/mongo/db/catalog/database.h +++ b/src/mongo/db/catalog/database.h @@ -36,8 +36,8 @@ #include "mongo/base/string_data.h" #include "mongo/bson/bsonobj.h" #include "mongo/db/catalog/collection.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_options.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/namespace_string.h" #include "mongo/db/repl/optime.h" #include "mongo/util/string_map.h" @@ -74,8 +74,8 @@ public: inline Database(Database&&) = delete; inline Database& operator=(Database&&) = delete; - virtual UUIDCatalog::iterator begin(OperationContext* opCtx) const = 0; - virtual UUIDCatalog::iterator end(OperationContext* opCtx) const = 0; + virtual CollectionCatalog::iterator begin(OperationContext* opCtx) const = 0; + virtual CollectionCatalog::iterator end(OperationContext* opCtx) const = 0; /** * Sets up internal memory structures. diff --git a/src/mongo/db/catalog/database_holder_impl.cpp b/src/mongo/db/catalog/database_holder_impl.cpp index 2446a074cc2..cd346130f0c 100644 --- a/src/mongo/db/catalog/database_holder_impl.cpp +++ b/src/mongo/db/catalog/database_holder_impl.cpp @@ -35,9 +35,9 @@ #include "mongo/db/audit.h" #include "mongo/db/background.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_impl.h" #include "mongo/db/catalog/database_impl.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/concurrency/write_conflict_exception.h" #include "mongo/db/operation_context.h" #include "mongo/db/repl/oplog.h" @@ -136,7 +136,7 @@ Database* DatabaseHolderImpl::openDb(OperationContext* opCtx, StringData ns, boo // different databases for the same name. lk.unlock(); - if (UUIDCatalog::get(opCtx).getAllCollectionUUIDsFromDb(dbname).empty()) { + if (CollectionCatalog::get(opCtx).getAllCollectionUUIDsFromDb(dbname).empty()) { audit::logCreateDatabase(opCtx->getClient(), dbname); if (justCreated) *justCreated = true; @@ -213,7 +213,7 @@ void DatabaseHolderImpl::close(OperationContext* opCtx, StringData ns) { auto db = it->second; repl::oplogCheckCloseDatabase(opCtx, db); - UUIDCatalog::get(opCtx).onCloseDatabase(opCtx, db); + CollectionCatalog::get(opCtx).onCloseDatabase(opCtx, dbName.toString()); db->close(opCtx); delete db; @@ -254,7 +254,7 @@ void DatabaseHolderImpl::closeAll(OperationContext* opCtx) { Database* db = _dbs[name]; repl::oplogCheckCloseDatabase(opCtx, db); - UUIDCatalog::get(opCtx).onCloseDatabase(opCtx, db); + CollectionCatalog::get(opCtx).onCloseDatabase(opCtx, name); db->close(opCtx); delete db; diff --git a/src/mongo/db/catalog/database_impl.cpp b/src/mongo/db/catalog/database_impl.cpp index 3eb78f7b082..ff36de7092e 100644 --- a/src/mongo/db/catalog/database_impl.cpp +++ b/src/mongo/db/catalog/database_impl.cpp @@ -42,14 +42,14 @@ #include "mongo/base/init.h" #include "mongo/db/audit.h" #include "mongo/db/background.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_catalog_entry.h" +#include "mongo/db/catalog/collection_catalog_helper.h" #include "mongo/db/catalog/collection_impl.h" #include "mongo/db/catalog/collection_options.h" #include "mongo/db/catalog/database_holder.h" #include "mongo/db/catalog/drop_indexes.h" #include "mongo/db/catalog/index_catalog.h" -#include "mongo/db/catalog/uuid_catalog.h" -#include "mongo/db/catalog/uuid_catalog_helper.h" #include "mongo/db/clientcursor.h" #include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/concurrency/write_conflict_exception.h" @@ -87,7 +87,7 @@ MONGO_FAIL_POINT_DEFINE(hangBeforeLoggingCreateCollection); std::unique_ptr _createCollectionInstance(OperationContext* opCtx, const NamespaceString& nss) { - auto cce = UUIDCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(nss); + auto cce = CollectionCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(nss); auto rs = cce->getRecordStore(); auto uuid = cce->getCollectionOptions(opCtx).uuid; invariant(rs, @@ -168,20 +168,20 @@ void DatabaseImpl::init(OperationContext* const opCtx) const { uasserted(10028, status.toString()); } - auto& uuidCatalog = UUIDCatalog::get(opCtx); - for (const auto& nss : uuidCatalog.getAllCollectionNamesFromDb(opCtx, _name)) { + auto& catalog = CollectionCatalog::get(opCtx); + for (const auto& nss : catalog.getAllCollectionNamesFromDb(opCtx, _name)) { auto ownedCollection = _createCollectionInstance(opCtx, nss); invariant(ownedCollection); // Call registerCollectionObject directly because we're not in a WUOW. auto uuid = *(ownedCollection->uuid()); - uuidCatalog.registerCollectionObject(uuid, std::move(ownedCollection)); + catalog.registerCollectionObject(uuid, std::move(ownedCollection)); } - // At construction time of the viewCatalog, the UUIDCatalog map wasn't initialized yet, so no - // system.views collection would be found. Now we're sufficiently initialized, signal a version - // change. Also force a reload, so if there are problems with the catalog contents as might be - // caused by incorrect mongod versions or similar, they are found right away. + // At construction time of the viewCatalog, the CollectionCatalog map wasn't initialized yet, + // so no system.views collection would be found. Now we're sufficiently initialized, signal a + // version change. Also force a reload, so if there are problems with the catalog contents as + // might be caused by incorrect mongod versions or similar, they are found right away. auto views = ViewCatalog::get(this); views->invalidate(); Status reloadStatus = views->reloadIfNeeded(opCtx); @@ -196,9 +196,10 @@ void DatabaseImpl::init(OperationContext* const opCtx) const { void DatabaseImpl::clearTmpCollections(OperationContext* opCtx) const { invariant(opCtx->lockState()->isDbLockedForMode(name(), MODE_X)); - for (const auto& nss : UUIDCatalog::get(opCtx).getAllCollectionNamesFromDb(opCtx, _name)) { + for (const auto& nss : + CollectionCatalog::get(opCtx).getAllCollectionNamesFromDb(opCtx, _name)) { CollectionCatalogEntry* coll = - UUIDCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(nss); + CollectionCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(nss); CollectionOptions options = coll->getCollectionOptions(opCtx); if (!options.temp) @@ -497,7 +498,7 @@ Status DatabaseImpl::_finishDropCollection(OperationContext* opCtx, UUID uuid = *collection->uuid(); log() << "Finishing collection drop for " << nss << " (" << uuid << ")."; - UUIDCatalog& catalog = UUIDCatalog::get(opCtx); + CollectionCatalog& catalog = CollectionCatalog::get(opCtx); catalog.onDropCollection(opCtx, uuid); auto storageEngine = @@ -506,7 +507,7 @@ Status DatabaseImpl::_finishDropCollection(OperationContext* opCtx, } Collection* DatabaseImpl::getCollection(OperationContext* opCtx, const NamespaceString& nss) const { - return UUIDCatalog::get(opCtx).lookupCollectionByNamespace(nss); + return CollectionCatalog::get(opCtx).lookupCollectionByNamespace(nss); } Status DatabaseImpl::renameCollection(OperationContext* opCtx, @@ -553,10 +554,11 @@ Status DatabaseImpl::renameCollection(OperationContext* opCtx, checked_cast(opCtx->getServiceContext()->getStorageEngine()); Status status = storageEngine->getCatalog()->renameCollection(opCtx, fromNss, toNss, stayTemp); - // Set the namespace of 'collToRename' from within the UUIDCatalog. This is necessary because - // the UUIDCatalog mutex synchronizes concurrent access to the collection's namespace for + // Set the namespace of 'collToRename' from within the CollectionCatalog. This is necessary + // because + // the CollectionCatalog mutex synchronizes concurrent access to the collection's namespace for // callers that may not hold a collection lock. - UUIDCatalog::get(opCtx).setCollectionNamespace(opCtx, collToRename, fromNss, toNss); + CollectionCatalog::get(opCtx).setCollectionNamespace(opCtx, collToRename, fromNss, toNss); opCtx->recoveryUnit()->onCommit([collToRename](auto commitTime) { // Ban reading from this collection on committed reads on snapshots before now. @@ -684,10 +686,10 @@ Collection* DatabaseImpl::createCollection(OperationContext* opCtx, opCtx, nss, optionsWithUUID, true /*allocateDefaultSpace*/)); // Create Collection object - auto& uuidCatalog = UUIDCatalog::get(opCtx); + auto& catalog = CollectionCatalog::get(opCtx); auto ownedCollection = _createCollectionInstance(opCtx, nss); Collection* collection = ownedCollection.get(); - uuidCatalog.onCreateCollection(opCtx, std::move(ownedCollection), *(collection->uuid())); + catalog.onCreateCollection(opCtx, std::move(ownedCollection), *(collection->uuid())); opCtx->recoveryUnit()->onCommit([collection](auto commitTime) { // Ban reading from this collection on committed reads on snapshots before now. if (commitTime) @@ -803,7 +805,8 @@ void DatabaseImpl::checkForIdIndexesAndDropPendingCollections(OperationContext* return; } - for (const auto& nss : UUIDCatalog::get(opCtx).getAllCollectionNamesFromDb(opCtx, _name)) { + for (const auto& nss : + CollectionCatalog::get(opCtx).getAllCollectionNamesFromDb(opCtx, _name)) { if (nss.isDropPendingNamespace()) { auto dropOpTime = fassert(40459, nss.getDropPendingNamespaceOpTime()); log() << "Found drop-pending namespace " << nss << " with drop optime " << dropOpTime; diff --git a/src/mongo/db/catalog/database_impl.h b/src/mongo/db/catalog/database_impl.h index ffaee26c449..ef90e9cf08f 100644 --- a/src/mongo/db/catalog/database_impl.h +++ b/src/mongo/db/catalog/database_impl.h @@ -128,12 +128,12 @@ public: void checkForIdIndexesAndDropPendingCollections(OperationContext* opCtx) const final; - UUIDCatalog::iterator begin(OperationContext* opCtx) const final { - return UUIDCatalog::get(opCtx).begin(_name); + CollectionCatalog::iterator begin(OperationContext* opCtx) const final { + return CollectionCatalog::get(opCtx).begin(_name); } - UUIDCatalog::iterator end(OperationContext* opCtx) const final { - return UUIDCatalog::get(opCtx).end(); + CollectionCatalog::iterator end(OperationContext* opCtx) const final { + return CollectionCatalog::get(opCtx).end(); } uint64_t epoch() const { diff --git a/src/mongo/db/catalog/database_test.cpp b/src/mongo/db/catalog/database_test.cpp index fdf80e6b1f8..4a9d08b678b 100644 --- a/src/mongo/db/catalog/database_test.cpp +++ b/src/mongo/db/catalog/database_test.cpp @@ -33,9 +33,9 @@ #include #include "mongo/bson/util/builder.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_catalog_entry.h" #include "mongo/db/catalog/index_catalog.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/client.h" #include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/concurrency/write_conflict_exception.h" @@ -352,14 +352,14 @@ TEST_F(DatabaseTest, RenameCollectionPreservesUuidOfSourceCollectionAndUpdatesUu auto fromUuid = UUID::gen(); - auto&& uuidCatalog = UUIDCatalog::get(opCtx); - ASSERT_EQUALS(boost::none, uuidCatalog.lookupNSSByUUID(fromUuid)); + auto&& catalog = CollectionCatalog::get(opCtx); + ASSERT_EQUALS(boost::none, catalog.lookupNSSByUUID(fromUuid)); WriteUnitOfWork wuow(opCtx); CollectionOptions fromCollectionOptions; fromCollectionOptions.uuid = fromUuid; ASSERT_TRUE(db->createCollection(opCtx, fromNss, fromCollectionOptions)); - ASSERT_EQUALS(fromNss, *uuidCatalog.lookupNSSByUUID(fromUuid)); + ASSERT_EQUALS(fromNss, *catalog.lookupNSSByUUID(fromUuid)); auto stayTemp = false; ASSERT_OK(db->renameCollection(opCtx, fromNss, toNss, stayTemp)); @@ -375,7 +375,7 @@ TEST_F(DatabaseTest, RenameCollectionPreservesUuidOfSourceCollectionAndUpdatesUu ASSERT_TRUE(toUuid); ASSERT_EQUALS(fromUuid, *toUuid); - ASSERT_EQUALS(toNss, *uuidCatalog.lookupNSSByUUID(*toUuid)); + ASSERT_EQUALS(toNss, *catalog.lookupNSSByUUID(*toUuid)); wuow.commit(); }); diff --git a/src/mongo/db/catalog/index_builds_manager.cpp b/src/mongo/db/catalog/index_builds_manager.cpp index c061074efa7..67bbcb94059 100644 --- a/src/mongo/db/catalog/index_builds_manager.cpp +++ b/src/mongo/db/catalog/index_builds_manager.cpp @@ -34,10 +34,10 @@ #include "mongo/db/catalog/index_builds_manager.h" #include "mongo/db/catalog/collection.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_catalog_entry.h" #include "mongo/db/catalog/index_catalog.h" #include "mongo/db/catalog/index_timestamp_helper.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/concurrency/write_conflict_exception.h" #include "mongo/db/operation_context.h" #include "mongo/db/storage/write_unit_of_work.h" @@ -141,7 +141,7 @@ StatusWith> IndexBuildsManager::startBuildingInd OperationContext* opCtx, NamespaceString ns, const UUID& buildUUID) { auto builder = _getBuilder(buildUUID); - auto cce = UUIDCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(ns); + auto cce = CollectionCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(ns); auto rs = cce ? cce->getRecordStore() : nullptr; // Iterate all records in the collection. Delete them if they aren't valid BSON. Index them diff --git a/src/mongo/db/catalog/rename_collection.cpp b/src/mongo/db/catalog/rename_collection.cpp index 3f8f82c35cc..6baf2ddfbe8 100644 --- a/src/mongo/db/catalog/rename_collection.cpp +++ b/src/mongo/db/catalog/rename_collection.cpp @@ -34,12 +34,12 @@ #include "mongo/db/catalog/rename_collection.h" #include "mongo/db/background.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_catalog_entry.h" #include "mongo/db/catalog/database_holder.h" #include "mongo/db/catalog/document_validation.h" #include "mongo/db/catalog/drop_collection.h" #include "mongo/db/catalog/index_catalog.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/client.h" #include "mongo/db/concurrency/write_conflict_exception.h" #include "mongo/db/curop.h" @@ -48,6 +48,7 @@ #include "mongo/db/index_builds_coordinator.h" #include "mongo/db/jsobj.h" #include "mongo/db/namespace_string.h" +#include "mongo/db/op_observer.h" #include "mongo/db/ops/insert.h" #include "mongo/db/query/query_knobs_gen.h" #include "mongo/db/repl/replication_coordinator.h" @@ -66,7 +67,7 @@ namespace { MONGO_FAIL_POINT_DEFINE(writeConfilctInRenameCollCopyToTmp); boost::optional getNamespaceFromUUID(OperationContext* opCtx, const UUID& uuid) { - return UUIDCatalog::get(opCtx).lookupNSSByUUID(uuid); + return CollectionCatalog::get(opCtx).lookupNSSByUUID(uuid); } bool isCollectionSharded(OperationContext* opCtx, const NamespaceString& nss) { @@ -762,7 +763,7 @@ Status renameCollectionForApplyOps(OperationContext* opCtx, OptionalCollectionUUID uuidToRename; if (!ui.eoo()) { uuidToRename = uassertStatusOK(UUID::parse(ui)); - auto nss = UUIDCatalog::get(opCtx).lookupNSSByUUID(uuidToRename.get()); + auto nss = CollectionCatalog::get(opCtx).lookupNSSByUUID(uuidToRename.get()); if (nss) sourceNss = *nss; } diff --git a/src/mongo/db/catalog/rename_collection_test.cpp b/src/mongo/db/catalog/rename_collection_test.cpp index 96b8fc46890..9a70e6c3105 100644 --- a/src/mongo/db/catalog/rename_collection_test.cpp +++ b/src/mongo/db/catalog/rename_collection_test.cpp @@ -33,12 +33,12 @@ #include #include +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_catalog_entry.h" #include "mongo/db/catalog/collection_options.h" #include "mongo/db/catalog/database_holder.h" #include "mongo/db/catalog/index_catalog.h" #include "mongo/db/catalog/rename_collection.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/client.h" #include "mongo/db/concurrency/write_conflict_exception.h" #include "mongo/db/db_raii.h" @@ -387,7 +387,7 @@ CollectionUUID _getCollectionUuid(OperationContext* opCtx, const NamespaceString * Get collection namespace by UUID. */ NamespaceString _getCollectionNssFromUUID(OperationContext* opCtx, const UUID& uuid) { - Collection* source = UUIDCatalog::get(opCtx).lookupCollectionByUUID(uuid); + Collection* source = CollectionCatalog::get(opCtx).lookupCollectionByUUID(uuid); return source ? source->ns() : NamespaceString(); } @@ -626,7 +626,7 @@ TEST_F(RenameCollectionTest, RenameCollectionForApplyOpsDropTargetByUUIDTargetDo ASSERT_FALSE(_collectionExists(_opCtx.get(), collC)); // B (originally A) should exist ASSERT_TRUE(_collectionExists(_opCtx.get(), collB)); - // collAUUID should be associated with collB's NamespaceString in the UUIDCatalog. + // collAUUID should be associated with collB's NamespaceString in the CollectionCatalog. auto newCollNS = _getCollectionNssFromUUID(_opCtx.get(), collAUUID); ASSERT_TRUE(newCollNS.isValid()); ASSERT_EQUALS(newCollNS, collB); @@ -652,7 +652,7 @@ TEST_F(RenameCollectionTest, RenameCollectionForApplyOpsDropTargetByUUIDTargetEx // B (originally A) should exist ASSERT_TRUE(_collectionExists(_opCtx.get(), collB)); // The original B should exist too, but with a temporary name - const auto& tmpB = UUIDCatalog::get(_opCtx.get()).lookupNSSByUUID(collBUUID); + const auto& tmpB = CollectionCatalog::get(_opCtx.get()).lookupNSSByUUID(collBUUID); ASSERT(tmpB); ASSERT_TRUE(tmpB->coll().startsWith("tmp")); ASSERT_TRUE(*tmpB != collB); @@ -685,7 +685,7 @@ TEST_F(RenameCollectionTest, // B (originally A) should exist ASSERT_TRUE(_collectionExists(_opCtx.get(), collB)); // The original B should exist too, but with a temporary name - const auto& tmpB = UUIDCatalog::get(_opCtx.get()).lookupNSSByUUID(collBUUID); + const auto& tmpB = CollectionCatalog::get(_opCtx.get()).lookupNSSByUUID(collBUUID); ASSERT(tmpB); ASSERT_TRUE(*tmpB != collB); ASSERT_TRUE(tmpB->coll().startsWith("tmp")); @@ -711,7 +711,7 @@ TEST_F(RenameCollectionTest, // B (originally A) should exist ASSERT_TRUE(_collectionExists(_opCtx.get(), collB)); // The original B should exist too, but with a temporary name - const auto& tmpB = UUIDCatalog::get(_opCtx.get()).lookupNSSByUUID(collBUUID); + const auto& tmpB = CollectionCatalog::get(_opCtx.get()).lookupNSSByUUID(collBUUID); ASSERT(tmpB); ASSERT_TRUE(*tmpB != collB); ASSERT_TRUE(tmpB->coll().startsWith("tmp")); @@ -1168,15 +1168,15 @@ TEST_F(RenameCollectionTest, RenameAcrossDatabasesDoesNotPreserveCatalogPointers ASSERT_NE(targetCatalogEntry, sourceCatalogEntry); } -TEST_F(RenameCollectionTest, UUIDCatalogMappingRemainsIntactThroughRename) { +TEST_F(RenameCollectionTest, CollectionCatalogMappingRemainsIntactThroughRename) { _createCollection(_opCtx.get(), _sourceNss); Lock::GlobalWrite globalWrite(_opCtx.get()); - auto& uuidCatalog = UUIDCatalog::get(_opCtx.get()); + auto& catalog = CollectionCatalog::get(_opCtx.get()); Collection* sourceColl = _getCollection_inlock(_opCtx.get(), _sourceNss); ASSERT(sourceColl); - ASSERT_EQ(sourceColl, uuidCatalog.lookupCollectionByUUID(*sourceColl->uuid())); + ASSERT_EQ(sourceColl, catalog.lookupCollectionByUUID(*sourceColl->uuid())); ASSERT_OK(renameCollection(_opCtx.get(), _sourceNss, _targetNss, {})); - ASSERT_EQ(sourceColl, uuidCatalog.lookupCollectionByUUID(*sourceColl->uuid())); + ASSERT_EQ(sourceColl, catalog.lookupCollectionByUUID(*sourceColl->uuid())); } TEST_F(RenameCollectionTest, FailRenameCollectionFromReplicatedToUnreplicatedDB) { diff --git a/src/mongo/db/catalog/uuid_catalog.cpp b/src/mongo/db/catalog/uuid_catalog.cpp deleted file mode 100644 index f8edcc77a77..00000000000 --- a/src/mongo/db/catalog/uuid_catalog.cpp +++ /dev/null @@ -1,599 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * . - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ -#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kStorage - -#include "mongo/platform/basic.h" - -#include "uuid_catalog.h" - -#include "mongo/db/catalog/database.h" -#include "mongo/db/catalog/database_holder.h" -#include "mongo/db/concurrency/lock_manager_defs.h" -#include "mongo/db/storage/recovery_unit.h" -#include "mongo/util/assert_util.h" -#include "mongo/util/log.h" -#include "mongo/util/uuid.h" - -namespace mongo { -namespace { -const ServiceContext::Decoration getCatalog = - ServiceContext::declareDecoration(); -} // namespace - -class UUIDCatalog::FinishDropChange : public RecoveryUnit::Change { -public: - FinishDropChange(UUIDCatalog& catalog, std::unique_ptr coll, CollectionUUID uuid) - : _catalog(catalog), _coll(std::move(coll)), _uuid(uuid) {} - - void commit(boost::optional) override { - _coll.reset(); - } - - void rollback() override { - _catalog.registerCollectionObject(_uuid, std::move(_coll)); - } - -private: - UUIDCatalog& _catalog; - std::unique_ptr _coll; - CollectionUUID _uuid; -}; - -UUIDCatalog::iterator::iterator(StringData dbName, uint64_t genNum, const UUIDCatalog& uuidCatalog) - : _dbName(dbName), _genNum(genNum), _uuidCatalog(&uuidCatalog) { - auto minUuid = UUID::parse("00000000-0000-0000-0000-000000000000").getValue(); - - stdx::lock_guard lock(_uuidCatalog->_catalogLock); - _mapIter = _uuidCatalog->_orderedCollections.lower_bound(std::make_pair(_dbName, minUuid)); - - // The entry _mapIter points to is valid if it's not at the end of _orderedCollections and - // the entry's database is the same as dbName. - while (_mapIter != _uuidCatalog->_orderedCollections.end() && - _mapIter->first.first == _dbName && _mapIter->second->collectionPtr == nullptr) { - _mapIter++; - } - if (_mapIter != _uuidCatalog->_orderedCollections.end() && _mapIter->first.first == _dbName) { - _uuid = _mapIter->first.second; - } -} - -UUIDCatalog::iterator::iterator( - std::map, CollectionInfo*>::const_iterator mapIter) - : _mapIter(mapIter) {} - -UUIDCatalog::iterator::pointer UUIDCatalog::iterator::operator->() { - stdx::lock_guard lock(_uuidCatalog->_catalogLock); - _repositionIfNeeded(); - if (_exhausted()) { - return nullptr; - } - - return &_mapIter->second->collectionPtr; -} - -UUIDCatalog::iterator::reference UUIDCatalog::iterator::operator*() { - stdx::lock_guard lock(_uuidCatalog->_catalogLock); - _repositionIfNeeded(); - if (_exhausted()) { - return _nullCollection; - } - - return _mapIter->second->collectionPtr; -} - -boost::optional UUIDCatalog::iterator::uuid() { - return _uuid; -} - -UUIDCatalog::iterator UUIDCatalog::iterator::operator++() { - stdx::lock_guard lock(_uuidCatalog->_catalogLock); - - // Skip over CollectionInfo that has CatalogEntry but has no Collection object. - do { - if (!_repositionIfNeeded()) { - _mapIter++; // If the position was not updated, increment iterator to next element. - } - - if (_exhausted()) { - // If the iterator is at the end of the map or now points to an entry that does not - // correspond to the correct database. - _mapIter = _uuidCatalog->_orderedCollections.end(); - _uuid = boost::none; - return *this; - } - } while (_mapIter->second->collectionPtr == nullptr); - - _uuid = _mapIter->first.second; - return *this; -} - -UUIDCatalog::iterator UUIDCatalog::iterator::operator++(int) { - auto oldPosition = *this; - ++(*this); - return oldPosition; -} - -bool UUIDCatalog::iterator::operator==(const iterator& other) { - stdx::lock_guard lock(_uuidCatalog->_catalogLock); - - if (other._mapIter == _uuidCatalog->_orderedCollections.end()) { - return _uuid == boost::none; - } - - return _uuid == other._uuid; -} - -bool UUIDCatalog::iterator::operator!=(const iterator& other) { - return !(*this == other); -} - -bool UUIDCatalog::iterator::_repositionIfNeeded() { - if (_genNum == _uuidCatalog->_generationNumber) { - return false; - } - - _genNum = _uuidCatalog->_generationNumber; - // If the map has been modified, find the entry the iterator was on, or the one right after it. - _mapIter = _uuidCatalog->_orderedCollections.lower_bound(std::make_pair(_dbName, *_uuid)); - - // It is possible that the collection object is gone while catalog entry is - // still in the map. Skip that type of entries. - while (!_exhausted() && _mapIter->second->collectionPtr == nullptr) { - _mapIter++; - } - - if (_exhausted()) { - return true; - } - - invariant(_mapIter->second->collectionPtr); - - // If the old pair matches the previous DB name and UUID, the iterator was not repositioned. - auto dbUuidPair = _mapIter->first; - bool repositioned = !(dbUuidPair.first == _dbName && dbUuidPair.second == _uuid); - _uuid = dbUuidPair.second; - - return repositioned; -} - -bool UUIDCatalog::iterator::_exhausted() { - return _mapIter == _uuidCatalog->_orderedCollections.end() || _mapIter->first.first != _dbName; -} - -UUIDCatalog& UUIDCatalog::get(ServiceContext* svcCtx) { - return getCatalog(svcCtx); -} -UUIDCatalog& UUIDCatalog::get(OperationContext* opCtx) { - return getCatalog(opCtx->getServiceContext()); -} - -void UUIDCatalog::onCreateCollection(OperationContext* opCtx, - std::unique_ptr coll, - CollectionUUID uuid) { - registerCollectionObject(uuid, std::move(coll)); - opCtx->recoveryUnit()->onRollback([this, uuid] { deregisterCollectionObject(uuid); }); -} - -void UUIDCatalog::onDropCollection(OperationContext* opCtx, CollectionUUID uuid) { - auto coll = deregisterCollectionObject(uuid); - opCtx->recoveryUnit()->registerChange(new FinishDropChange(*this, std::move(coll), uuid)); -} - -void UUIDCatalog::setCollectionNamespace(OperationContext* opCtx, - Collection* coll, - const NamespaceString& fromCollection, - const NamespaceString& toCollection) { - // Rather than maintain, in addition to the UUID -> Collection* mapping, an auxiliary data - // structure with the UUID -> namespace mapping, the UUIDCatalog relies on Collection::ns() to - // provide UUID to namespace lookup. In addition, the UUIDCatalog does not require callers to - // hold locks. - // - // This means that Collection::ns() may be called while only '_catalogLock' (and no lock manager - // locks) are held. The purpose of this function is ensure that we write to the Collection's - // namespace string under '_catalogLock'. - invariant(coll); - stdx::lock_guard lock(_catalogLock); - CollectionCatalogEntry* catalogEntry = - _collections[fromCollection]->collectionCatalogEntry.get(); - - coll->setNs(toCollection); - catalogEntry->setNs(toCollection); - - _collections[toCollection] = _collections[fromCollection]; - _collections.erase(fromCollection); - - ResourceId oldRid = ResourceId(RESOURCE_COLLECTION, fromCollection.ns()); - ResourceId newRid = ResourceId(RESOURCE_COLLECTION, toCollection.ns()); - - removeResource(oldRid, fromCollection.ns()); - addResource(newRid, toCollection.ns()); - - opCtx->recoveryUnit()->onRollback([this, coll, fromCollection, toCollection, catalogEntry] { - stdx::lock_guard lock(_catalogLock); - coll->setNs(std::move(fromCollection)); - catalogEntry->setNs(fromCollection); - - _collections[fromCollection] = _collections[toCollection]; - _collections.erase(toCollection); - - ResourceId oldRid = ResourceId(RESOURCE_COLLECTION, fromCollection.ns()); - ResourceId newRid = ResourceId(RESOURCE_COLLECTION, toCollection.ns()); - - removeResource(newRid, toCollection.ns()); - addResource(oldRid, fromCollection.ns()); - }); -} - -void UUIDCatalog::onCloseDatabase(OperationContext* opCtx, Database* db) { - invariant(opCtx->lockState()->isW()); - for (auto it = begin(db->name()); it != end(); ++it) { - deregisterCollectionObject(it.uuid().get()); - } - - auto rid = ResourceId(RESOURCE_DATABASE, db->name()); - removeResource(rid, db->name()); -} - -void UUIDCatalog::onCloseCatalog(OperationContext* opCtx) { - invariant(opCtx->lockState()->isW()); - stdx::lock_guard lock(_catalogLock); - invariant(!_shadowCatalog); - _shadowCatalog.emplace(); - for (auto& entry : _catalog) - _shadowCatalog->insert({entry.first, entry.second.collection->ns()}); -} - -void UUIDCatalog::onOpenCatalog(OperationContext* opCtx) { - invariant(opCtx->lockState()->isW()); - stdx::lock_guard lock(_catalogLock); - invariant(_shadowCatalog); - _shadowCatalog.reset(); -} - -Collection* UUIDCatalog::lookupCollectionByUUID(CollectionUUID uuid) const { - stdx::lock_guard lock(_catalogLock); - auto foundIt = _catalog.find(uuid); - return foundIt == _catalog.end() || foundIt->second.collectionPtr == nullptr - ? nullptr - : foundIt->second.collection.get(); -} - -Collection* UUIDCatalog::lookupCollectionByNamespace(const NamespaceString& nss) const { - stdx::lock_guard lock(_catalogLock); - auto it = _collections.find(nss); - return it == _collections.end() || it->second->collectionPtr == nullptr - ? nullptr - : it->second->collection.get(); -} - -CollectionCatalogEntry* UUIDCatalog::lookupCollectionCatalogEntryByUUID(CollectionUUID uuid) const { - stdx::lock_guard lock(_catalogLock); - auto foundIt = _catalog.find(uuid); - return foundIt == _catalog.end() ? nullptr : foundIt->second.collectionCatalogEntry.get(); -} - -CollectionCatalogEntry* UUIDCatalog::lookupCollectionCatalogEntryByNamespace( - const NamespaceString& nss) const { - stdx::lock_guard lock(_catalogLock); - auto it = _collections.find(nss); - return it == _collections.end() ? nullptr : it->second->collectionCatalogEntry.get(); -} - -boost::optional UUIDCatalog::lookupNSSByUUID(CollectionUUID uuid) const { - stdx::lock_guard lock(_catalogLock); - auto foundIt = _catalog.find(uuid); - if (foundIt != _catalog.end()) { - NamespaceString ns = foundIt->second.collectionCatalogEntry->ns(); - invariant(!ns.isEmpty()); - return ns; - } - - // Only in the case that the catalog is closed and a UUID is currently unknown, resolve it - // using the pre-close state. This ensures that any tasks reloading the catalog can see their - // own updates. - if (_shadowCatalog) { - auto shadowIt = _shadowCatalog->find(uuid); - if (shadowIt != _shadowCatalog->end()) - return shadowIt->second; - } - return boost::none; -} - -boost::optional UUIDCatalog::lookupUUIDByNSS(const NamespaceString& nss) const { - stdx::lock_guard lock(_catalogLock); - auto minUuid = UUID::parse("00000000-0000-0000-0000-000000000000").getValue(); - auto it = _orderedCollections.lower_bound(std::make_pair(nss.db().toString(), minUuid)); - - // The entry _mapIter points to is valid if it's not at the end of _orderedCollections and - // the entry's database is the same as dbName. - while (it != _orderedCollections.end() && it->first.first == nss.db()) { - if (it->second->collectionCatalogEntry->ns() == nss) { - return it->first.second; - } - ++it; - } - return boost::none; -} - -std::vector UUIDCatalog::getAllCollectionUUIDsFromDb(StringData dbName) const { - stdx::lock_guard lock(_catalogLock); - auto minUuid = UUID::parse("00000000-0000-0000-0000-000000000000").getValue(); - auto it = _orderedCollections.lower_bound(std::make_pair(dbName.toString(), minUuid)); - - std::vector ret; - while (it != _orderedCollections.end() && it->first.first == dbName) { - ret.push_back(it->first.second); - ++it; - } - return ret; -} - -std::vector UUIDCatalog::getAllCollectionNamesFromDb(OperationContext* opCtx, - StringData dbName) const { - invariant(opCtx->lockState()->isDbLockedForMode(dbName, MODE_S)); - - stdx::lock_guard lock(_catalogLock); - auto minUuid = UUID::parse("00000000-0000-0000-0000-000000000000").getValue(); - - std::vector ret; - for (auto it = _orderedCollections.lower_bound(std::make_pair(dbName.toString(), minUuid)); - it != _orderedCollections.end() && it->first.first == dbName; - ++it) { - ret.push_back(it->second->collectionCatalogEntry->ns()); - } - return ret; -} - -std::vector UUIDCatalog::getAllDbNames() const { - std::vector ret; - stdx::lock_guard lock(_catalogLock); - auto maxUuid = UUID::parse("FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF").getValue(); - auto iter = _orderedCollections.upper_bound(std::make_pair("", maxUuid)); - while (iter != _orderedCollections.end()) { - auto dbName = iter->first.first; - ret.push_back(dbName); - iter = _orderedCollections.upper_bound(std::make_pair(dbName, maxUuid)); - } - return ret; -} - -void UUIDCatalog::registerCatalogEntry( - CollectionUUID uuid, std::unique_ptr collectionCatalogEntry) { - stdx::lock_guard lock(_catalogLock); - - LOG(0) << "Registering catalog entry " << collectionCatalogEntry->ns() << " with UUID " << uuid; - - auto ns = collectionCatalogEntry->ns(); - auto dbName = ns.db().toString(); - auto dbIdPair = std::make_pair(dbName, uuid); - - // Make sure no entry related to this uuid. - invariant(_catalog.find(uuid) == _catalog.end()); - invariant(_collections.find(ns) == _collections.end()); - invariant(_orderedCollections.find(dbIdPair) == _orderedCollections.end()); - - CollectionInfo collectionInfo = {nullptr, /* std::unique_ptr */ - nullptr, - std::move(collectionCatalogEntry)}; - - _catalog[uuid] = std::move(collectionInfo); - _collections[ns] = &_catalog[uuid]; - _orderedCollections[dbIdPair] = &_catalog[uuid]; -} - -void UUIDCatalog::registerCollectionObject(CollectionUUID uuid, std::unique_ptr coll) { - stdx::lock_guard lock(_catalogLock); - - LOG(0) << "Registering collection object " << coll->ns() << " with UUID " << uuid; - - auto ns = coll->ns(); - auto dbName = ns.db().toString(); - auto dbIdPair = std::make_pair(dbName, uuid); - - // Make sure catalog entry associated with this uuid already exists. - invariant(_catalog.find(uuid) != _catalog.end()); - invariant(_collections.find(ns) != _collections.end()); - invariant(_orderedCollections.find(dbIdPair) != _orderedCollections.end()); - invariant(_catalog[uuid].collectionCatalogEntry); - invariant(_collections[ns]->collectionCatalogEntry); - invariant(_orderedCollections[dbIdPair]->collectionCatalogEntry); - - // Make sure collection object does not exist. - invariant(_catalog[uuid].collection == nullptr); - invariant(_collections[ns]->collection == nullptr); - invariant(_orderedCollections[dbIdPair]->collection == nullptr); - - - _catalog[uuid].collection = std::move(coll); - _catalog[uuid].collectionPtr = _catalog[uuid].collection.get(); - - auto dbRid = ResourceId(RESOURCE_DATABASE, dbName); - addResource(dbRid, dbName); - - auto collRid = ResourceId(RESOURCE_COLLECTION, ns.ns()); - addResource(collRid, ns.ns()); -} - -std::unique_ptr UUIDCatalog::deregisterCollectionObject(CollectionUUID uuid) { - stdx::lock_guard lock(_catalogLock); - - invariant(_catalog.find(uuid) != _catalog.end()); - invariant(_catalog[uuid].collection); - - auto coll = std::move(_catalog[uuid].collection); - auto ns = coll->ns(); - auto dbName = ns.db().toString(); - auto dbIdPair = std::make_pair(dbName, uuid); - - LOG(0) << "Deregistering collection object " << ns << " with UUID " << uuid; - - // Make sure collection object exists. - invariant(_collections.find(ns) != _collections.end()); - invariant(_orderedCollections.find(dbIdPair) != _orderedCollections.end()); - - _catalog[uuid].collection = nullptr; - _catalog[uuid].collectionPtr = nullptr; - - // Make sure collection catalog entry still exists. - invariant(_catalog[uuid].collectionCatalogEntry); - - auto collRid = ResourceId(RESOURCE_COLLECTION, ns.ns()); - removeResource(collRid, ns.ns()); - - // Removal from an ordered map will invalidate iterators and potentially references to the - // references to the erased element. - _generationNumber++; - - return coll; -} - -std::unique_ptr UUIDCatalog::deregisterCatalogEntry(CollectionUUID uuid) { - stdx::lock_guard lock(_catalogLock); - - invariant(_catalog.find(uuid) != _catalog.end()); - invariant(_catalog[uuid].collectionCatalogEntry); - - auto catalogEntry = std::move(_catalog[uuid].collectionCatalogEntry); - auto ns = catalogEntry->ns(); - auto dbName = ns.db().toString(); - auto dbIdPair = std::make_pair(dbName, uuid); - - LOG(0) << "Deregistering catalog entry " << ns << " with UUID " << uuid; - - // Make sure collection object is already gone. - invariant(_catalog[uuid].collection == nullptr); - invariant(_catalog[uuid].collectionPtr == nullptr); - - // Make sure catalog entry exist. - invariant(_collections.find(ns) != _collections.end()); - invariant(_orderedCollections.find(dbIdPair) != _orderedCollections.end()); - - _orderedCollections.erase(dbIdPair); - _collections.erase(ns); - _catalog.erase(uuid); - - // Removal from an ordered map will invalidate iterators and potentially references to the - // references to the erased element. - _generationNumber++; - - return catalogEntry; -} - -void UUIDCatalog::deregisterAllCatalogEntriesAndCollectionObjects() { - stdx::lock_guard lock(_catalogLock); - - LOG(0) << "Deregistering all the catalog entries and collection objects"; - for (auto& entry : _catalog) { - auto uuid = entry.first; - auto ns = entry.second.collectionCatalogEntry->ns(); - auto dbName = ns.db().toString(); - auto dbIdPair = std::make_pair(dbName, uuid); - - LOG(0) << "Deregistering collection " << ns << " with UUID " << uuid; - - entry.second.collection.reset(); - entry.second.collectionCatalogEntry.reset(); - } - - _collections.clear(); - _orderedCollections.clear(); - _catalog.clear(); - - stdx::lock_guard resourceLock(_resourceLock); - _resourceInformation.clear(); - - _generationNumber++; -} - -UUIDCatalog::iterator UUIDCatalog::begin(StringData db) const { - return iterator(db, _generationNumber, *this); -} - -UUIDCatalog::iterator UUIDCatalog::end() const { - return iterator(_orderedCollections.end()); -} - -boost::optional UUIDCatalog::lookupResourceName(const ResourceId& rid) { - invariant(rid.getType() == RESOURCE_DATABASE || rid.getType() == RESOURCE_COLLECTION); - stdx::lock_guard lock(_resourceLock); - - auto search = _resourceInformation.find(rid); - if (search == _resourceInformation.end()) { - return boost::none; - } - - std::set& namespaces = search->second; - - // When there are multiple namespaces mapped to the same ResourceId, return boost::none as the - // ResourceId does not identify a single namespace. - if (namespaces.size() > 1) { - return boost::none; - } - - return *namespaces.begin(); -} - -void UUIDCatalog::removeResource(const ResourceId& rid, const std::string& entry) { - invariant(rid.getType() == RESOURCE_DATABASE || rid.getType() == RESOURCE_COLLECTION); - stdx::lock_guard lock(_resourceLock); - - auto search = _resourceInformation.find(rid); - if (search == _resourceInformation.end()) { - return; - } - - std::set& namespaces = search->second; - namespaces.erase(entry); - - // Remove the map entry if this is the last namespace in the set for the ResourceId. - if (namespaces.size() == 0) { - _resourceInformation.erase(search); - } -} - -void UUIDCatalog::addResource(const ResourceId& rid, const std::string& entry) { - invariant(rid.getType() == RESOURCE_DATABASE || rid.getType() == RESOURCE_COLLECTION); - stdx::lock_guard lock(_resourceLock); - - auto search = _resourceInformation.find(rid); - if (search == _resourceInformation.end()) { - std::set newSet = {entry}; - _resourceInformation.insert(std::make_pair(rid, newSet)); - return; - } - - std::set& namespaces = search->second; - if (namespaces.count(entry) > 0) { - return; - } - - namespaces.insert(entry); -} - -} // namespace mongo diff --git a/src/mongo/db/catalog/uuid_catalog.h b/src/mongo/db/catalog/uuid_catalog.h deleted file mode 100644 index 33d36b34780..00000000000 --- a/src/mongo/db/catalog/uuid_catalog.h +++ /dev/null @@ -1,327 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * . - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include -#include - -#include "mongo/db/catalog/collection.h" -#include "mongo/db/catalog/collection_catalog_entry.h" -#include "mongo/db/op_observer.h" -#include "mongo/db/service_context.h" -#include "mongo/stdx/functional.h" -#include "mongo/util/uuid.h" - -namespace mongo { - -/** - * This class comprises a UUID to collection catalog, allowing for efficient - * collection lookup by UUID. - */ -using CollectionUUID = UUID; -class Database; - -class UUIDCatalog { - UUIDCatalog(const UUIDCatalog&) = delete; - UUIDCatalog& operator=(const UUIDCatalog&) = delete; - - friend class iterator; - struct CollectionInfo; - -public: - class iterator { - public: - using value_type = Collection*; - using pointer = const value_type*; - using reference = const value_type&; - - iterator(StringData dbName, uint64_t genNum, const UUIDCatalog& uuidCatalog); - iterator(std::map, - UUIDCatalog::CollectionInfo*>::const_iterator mapIter); - pointer operator->(); - reference operator*(); - iterator operator++(); - iterator operator++(int); - boost::optional uuid(); - - /* - * Equality operators == and != do not attempt to reposition the iterators being compared. - * The behavior for comparing invalid iterators is undefined. - */ - bool operator==(const iterator& other); - bool operator!=(const iterator& other); - - private: - /** - * Check if _mapIter has been invalidated due to a change in the _orderedCollections map. If - * it has, restart iteration through a call to lower_bound. If the element that the iterator - * is currently pointing to has been deleted, the iterator will be repositioned to the - * element that follows it. - * - * Returns true if iterator got repositioned. - */ - bool _repositionIfNeeded(); - bool _exhausted(); - - std::string _dbName; - boost::optional _uuid; - uint64_t _genNum; - std::map, CollectionInfo*>::const_iterator _mapIter; - const UUIDCatalog* _uuidCatalog; - static constexpr Collection* _nullCollection = nullptr; - }; - - static UUIDCatalog& get(ServiceContext* svcCtx); - static UUIDCatalog& get(OperationContext* opCtx); - UUIDCatalog() = default; - - /** - * This function inserts the entry for uuid, coll into the UUID Collection. It is called by - * the op observer when a collection is created. - */ - void onCreateCollection(OperationContext* opCtx, - std::unique_ptr coll, - CollectionUUID uuid); - - /** - * This function removes the entry for uuid from the UUID catalog. It is called by the op - * observer when a collection is dropped. - */ - void onDropCollection(OperationContext* opCtx, CollectionUUID uuid); - - /** - * This function is responsible for safely setting the namespace string inside 'coll' to the - * value of 'toCollection'. The caller need not hold locks on the collection. - * - * Must be called within a WriteUnitOfWork. The Collection namespace will be set back to - * 'fromCollection' if the WriteUnitOfWork aborts. - */ - void setCollectionNamespace(OperationContext* opCtx, - Collection* coll, - const NamespaceString& fromCollection, - const NamespaceString& toCollection); - - /** - * Implies onDropCollection for all collections in db, but is not transactional. - */ - void onCloseDatabase(OperationContext* opCtx, Database* db); - - /** - * Register the collection catalog entry with `uuid`. The collection object with `uuid` must not - * exist in the UUIDCatalog yet. - */ - void registerCatalogEntry(CollectionUUID uuid, - std::unique_ptr collectionCatalogEntry); - - /** - * Deregister the collection catalog entry. The collection object with `uuid` is already gone, - * so this function completely removes any info about uuid. - */ - std::unique_ptr deregisterCatalogEntry(CollectionUUID uuid); - - /** - * Register the collection object with `uuid`. The collection catalog entry with `uuid` already - * exists in the UUIDCatalog. - */ - void registerCollectionObject(CollectionUUID uuid, std::unique_ptr coll); - - /** - * Deregister the collection object. The collection catalog entry still exists and will be - * deregistered later. - */ - std::unique_ptr deregisterCollectionObject(CollectionUUID uuid); - - - /** - * Deregister all the collection objects and catalog entries. - */ - void deregisterAllCatalogEntriesAndCollectionObjects(); - - /** - * This function gets the Collection pointer that corresponds to the CollectionUUID. - * The required locks must be obtained prior to calling this function, or else the found - * Collection pointer might no longer be valid when the call returns. - * - * Returns nullptr if the 'uuid' is not known. - */ - Collection* lookupCollectionByUUID(CollectionUUID uuid) const; - - /** - * This function gets the CollectionCatalogEntry pointer that corresponds to the - * CollectionUUID. - * The required locks must be obtained prior to calling this function, or else the found - * CollectionCatalogEntry pointer might no longer be valid when the call returns. - * - * Returns nullptr if the 'uuid' is not known. - */ - CollectionCatalogEntry* lookupCollectionCatalogEntryByUUID(CollectionUUID uuid) const; - - /** - * This function gets the Collection pointer that corresponds to the NamespaceString. - * The required locks must be obtained prior to calling this function, or else the found - * Collection pointer may no longer be valid when the call returns. - * - * Returns nullptr if the namespace is unknown. - */ - Collection* lookupCollectionByNamespace(const NamespaceString& nss) const; - - /** - * This function gets the CollectionCatalogEntry pointer that corresponds to the - * CollectionUUID. - * The required locks must be obtained prior to calling this function, or else the found - * CollectionCatalogEntry pointer might no longer be valid when the call returns. - * - * Returns nullptr if the 'uuid' is not known. - */ - CollectionCatalogEntry* lookupCollectionCatalogEntryByNamespace( - const NamespaceString& nss) const; - - /** - * This function gets the NamespaceString from the collection catalog entry that - * corresponds to CollectionUUID uuid. If no collection exists with the uuid, return - * boost::none. See onCloseCatalog/onOpenCatalog for more info. - */ - boost::optional lookupNSSByUUID(CollectionUUID uuid) const; - - /** - * Returns the UUID if `nss` exists in UUIDCatalog. The time complexity of - * this function is linear to the number of collections in `nss.db()`. - */ - boost::optional lookupUUIDByNSS(const NamespaceString& nss) const; - - /** - * This function gets the UUIDs of all collections from `dbName`. - * - * If the caller does not take a strong database lock, some of UUIDs might no longer exist (due - * to collection drop) after this function returns. - * - * Returns empty vector if the 'dbName' is not known. - */ - std::vector getAllCollectionUUIDsFromDb(StringData dbName) const; - - /** - * This function gets the ns of all collections from `dbName`. The result is not sorted. - * - * Caller must take a strong database lock; otherwise, collections returned could be dropped or - * renamed. - * - * Returns empty vector if the 'dbName' is not known. - */ - std::vector getAllCollectionNamesFromDb(OperationContext* opCtx, - StringData dbName) const; - - /** - * This functions gets all the database names. The result is sorted in alphabetical ascending - * order. - */ - std::vector getAllDbNames() 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, - * like authorization and replication, which need to do lookups outside of database locks, to - * proceed. - * - * Must be called with the global lock acquired in exclusive mode. - */ - void onCloseCatalog(OperationContext* opCtx); - - /** - * Puts the catatlog back in open state, removing the pre-close state. See onCloseCatalog. - * - * Must be called with the global lock acquired in exclusive mode. - */ - void onOpenCatalog(OperationContext* opCtx); - - iterator begin(StringData db) const; - iterator end() const; - - /** - * 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. - */ - boost::optional lookupResourceName(const ResourceId& rid); - - /** - * Removes an existing ResourceId 'rid' with namespace 'entry' from the map. - */ - void removeResource(const ResourceId& rid, const std::string& entry); - - /** - * Inserts a new ResourceId 'rid' into the map with namespace 'entry'. - */ - void addResource(const ResourceId& rid, const std::string& entry); - -private: - class FinishDropChange; - friend class UUIDCatalog::iterator; - - const std::vector& _getOrdering_inlock(const StringData& db, - const stdx::lock_guard&); - mutable mongo::stdx::mutex _catalogLock; - /** - * When present, indicates that the catalog is in closed state, and contains a map from UUID - * to pre-close NSS. See also onCloseCatalog. - */ - boost::optional< - mongo::stdx::unordered_map> - _shadowCatalog; - - /** - * Unordered map from Collection UUID to the corresponding Collection object and - * CollectionCatalogEntry object. - */ - struct CollectionInfo { - std::unique_ptr collection; - Collection* collectionPtr; // This store the address to the collection object - std::unique_ptr collectionCatalogEntry; - }; - mongo::stdx::unordered_map _catalog; - - /** - * Ordered map from to a Collection object. - */ - std::map, CollectionInfo*> _orderedCollections; - - mongo::stdx::unordered_map _collections; - - /** - * Generation number to track changes to the catalog that could invalidate iterators. - */ - uint64_t _generationNumber; - - // Protects _resourceInformation. - mutable stdx::mutex _resourceLock; - - // Mapping from ResourceId to a set of strings that contains collection and database namespaces. - std::map> _resourceInformation; -}; -} // namespace mongo diff --git a/src/mongo/db/catalog/uuid_catalog_helper.cpp b/src/mongo/db/catalog/uuid_catalog_helper.cpp deleted file mode 100644 index 5bbc2bf6618..00000000000 --- a/src/mongo/db/catalog/uuid_catalog_helper.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Copyright (C) 2019-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * . - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#include "mongo/db/catalog/uuid_catalog_helper.h" -#include "mongo/db/catalog/collection.h" -#include "mongo/db/catalog/collection_catalog_entry.h" -#include "mongo/db/concurrency/d_concurrency.h" - -namespace mongo { -namespace catalog { - -void forEachCollectionFromDb( - OperationContext* opCtx, - StringData dbName, - LockMode collLockMode, - std::function callback) { - - UUIDCatalog& uuidCatalog = UUIDCatalog::get(opCtx); - for (auto collectionIt = uuidCatalog.begin(dbName); collectionIt != uuidCatalog.end(); - ++collectionIt) { - auto uuid = collectionIt.uuid().get(); - auto nss = uuidCatalog.lookupNSSByUUID(uuid); - - // If the NamespaceString can't be resolved from the uuid, then the collection was dropped. - if (!nss) { - continue; - } - - Lock::CollectionLock clk(opCtx, *nss, collLockMode); - - auto collection = uuidCatalog.lookupCollectionByUUID(uuid); - auto catalogEntry = uuidCatalog.lookupCollectionCatalogEntryByUUID(uuid); - if (!collection || !catalogEntry || catalogEntry->ns() != *nss) - continue; - - if (!callback(collection, catalogEntry)) - break; - } -} - -} // namespace catalog -} // namespace mongo diff --git a/src/mongo/db/catalog/uuid_catalog_helper.h b/src/mongo/db/catalog/uuid_catalog_helper.h deleted file mode 100644 index 0530618b102..00000000000 --- a/src/mongo/db/catalog/uuid_catalog_helper.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright (C) 2019-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * . - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include "mongo/db/catalog/uuid_catalog.h" -#include "mongo/db/concurrency/lock_manager_defs.h" - -namespace mongo { - -class Collection; -class CollectionCatalogEntry; - -namespace catalog { - -/** - * Looping through all the collections in the database and run callback function on each one of - * them. The return value of the callback decides whether we should continue the loop. - */ -void forEachCollectionFromDb( - OperationContext* opCtx, - StringData dbName, - LockMode collLockMode, - std::function callback); - -} // namespace catalog -} // namespace mongo diff --git a/src/mongo/db/catalog/uuid_catalog_test.cpp b/src/mongo/db/catalog/uuid_catalog_test.cpp deleted file mode 100644 index 34542ae9e91..00000000000 --- a/src/mongo/db/catalog/uuid_catalog_test.cpp +++ /dev/null @@ -1,668 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * . - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ -#include "mongo/db/catalog/uuid_catalog.h" - -#include -#include - -#include "mongo/db/catalog/collection_catalog_entry_mock.h" -#include "mongo/db/catalog/collection_mock.h" -#include "mongo/db/concurrency/lock_manager_defs.h" -#include "mongo/db/operation_context_noop.h" -#include "mongo/unittest/death_test.h" -#include "mongo/unittest/unittest.h" - -using namespace mongo; - -/** - * A test fixture that creates a UUID Catalog and Collection* pointer to store in it. - */ -class UUIDCatalogTest : public unittest::Test { -public: - UUIDCatalogTest() - : nss("testdb", "testcol"), - col(nullptr), - colUUID(CollectionUUID::gen()), - nextUUID(CollectionUUID::gen()), - prevUUID(CollectionUUID::gen()) { - if (prevUUID > colUUID) - std::swap(prevUUID, colUUID); - if (colUUID > nextUUID) - std::swap(colUUID, nextUUID); - if (prevUUID > colUUID) - std::swap(prevUUID, colUUID); - ASSERT_GT(colUUID, prevUUID); - ASSERT_GT(nextUUID, colUUID); - - auto collection = std::make_unique(nss); - auto catalogEntry = std::make_unique(nss.ns()); - col = collection.get(); - // Register dummy collection in catalog. - catalog.registerCatalogEntry(colUUID, std::move(catalogEntry)); - catalog.onCreateCollection(&opCtx, std::move(collection), colUUID); - } - -protected: - UUIDCatalog catalog; - OperationContextNoop opCtx; - NamespaceString nss; - CollectionMock* col; - CollectionUUID colUUID; - CollectionUUID nextUUID; - CollectionUUID prevUUID; -}; - -class UUIDCatalogIterationTest : public unittest::Test { -public: - void setUp() { - for (int counter = 0; counter < 5; ++counter) { - NamespaceString fooNss("foo", "coll" + std::to_string(counter)); - NamespaceString barNss("bar", "coll" + std::to_string(counter)); - - auto fooUuid = CollectionUUID::gen(); - auto fooColl = std::make_unique(fooNss); - auto fooCatalogEntry = std::make_unique(fooNss.ns()); - - auto barUuid = CollectionUUID::gen(); - auto barColl = std::make_unique(barNss); - auto barCatalogEntry = std::make_unique(barNss.ns()); - - dbMap["foo"].insert(std::make_pair(fooUuid, fooColl.get())); - dbMap["bar"].insert(std::make_pair(barUuid, barColl.get())); - catalog.registerCatalogEntry(fooUuid, std::move(fooCatalogEntry)); - catalog.registerCatalogEntry(barUuid, std::move(barCatalogEntry)); - catalog.onCreateCollection(&opCtx, std::move(fooColl), fooUuid); - catalog.onCreateCollection(&opCtx, std::move(barColl), barUuid); - } - } - - void tearDown() { - for (auto& it : dbMap) { - for (auto& kv : it.second) { - catalog.onDropCollection(&opCtx, kv.first); - } - } - } - - std::map::iterator collsIterator(std::string dbName) { - auto it = dbMap.find(dbName); - ASSERT(it != dbMap.end()); - return it->second.begin(); - } - - std::map::iterator collsIteratorEnd(std::string dbName) { - auto it = dbMap.find(dbName); - ASSERT(it != dbMap.end()); - return it->second.end(); - } - - void checkCollections(std::string dbName) { - unsigned long counter = 0; - - for (auto[orderedIt, catalogIt] = std::tuple{collsIterator(dbName), catalog.begin(dbName)}; - catalogIt != catalog.end() && orderedIt != collsIteratorEnd(dbName); - ++catalogIt, ++orderedIt) { - - auto catalogColl = *catalogIt; - ASSERT(catalogColl != nullptr); - auto orderedColl = orderedIt->second; - ASSERT_EQ(catalogColl->ns(), orderedColl->ns()); - ++counter; - } - - ASSERT_EQUALS(counter, dbMap[dbName].size()); - } - - void dropColl(const std::string dbName, CollectionUUID uuid) { - dbMap[dbName].erase(uuid); - } - -protected: - UUIDCatalog catalog; - OperationContextNoop opCtx; - std::map> dbMap; -}; - -class UUIDCatalogResourceMapTest : public unittest::Test { -public: - void setUp() { - // The first and second collection namespaces map to the same ResourceId. - firstCollection = "1661880728"; - secondCollection = "1626936312"; - - firstResourceId = ResourceId(RESOURCE_COLLECTION, firstCollection); - secondResourceId = ResourceId(RESOURCE_COLLECTION, secondCollection); - ASSERT_EQ(firstResourceId, secondResourceId); - - thirdCollection = "2930102946"; - thirdResourceId = ResourceId(RESOURCE_COLLECTION, thirdCollection); - ASSERT_NE(firstResourceId, thirdResourceId); - } - -protected: - std::string firstCollection; - ResourceId firstResourceId; - - std::string secondCollection; - ResourceId secondResourceId; - - std::string thirdCollection; - ResourceId thirdResourceId; - - UUIDCatalog catalog; -}; - -TEST_F(UUIDCatalogResourceMapTest, EmptyTest) { - boost::optional resource = catalog.lookupResourceName(firstResourceId); - ASSERT_EQ(boost::none, resource); - - catalog.removeResource(secondResourceId, secondCollection); - resource = catalog.lookupResourceName(secondResourceId); - ASSERT_EQ(boost::none, resource); -} - -TEST_F(UUIDCatalogResourceMapTest, InsertTest) { - catalog.addResource(firstResourceId, firstCollection); - boost::optional resource = catalog.lookupResourceName(thirdResourceId); - ASSERT_EQ(boost::none, resource); - - catalog.addResource(thirdResourceId, thirdCollection); - - resource = catalog.lookupResourceName(firstResourceId); - ASSERT_EQ(firstCollection, *resource); - - resource = catalog.lookupResourceName(thirdResourceId); - ASSERT_EQ(thirdCollection, resource); -} - -TEST_F(UUIDCatalogResourceMapTest, RemoveTest) { - catalog.addResource(firstResourceId, firstCollection); - catalog.addResource(thirdResourceId, thirdCollection); - - // This fails to remove the resource because of an invalid namespace. - catalog.removeResource(firstResourceId, "BadNamespace"); - boost::optional resource = catalog.lookupResourceName(firstResourceId); - ASSERT_EQ(firstCollection, *resource); - - catalog.removeResource(firstResourceId, firstCollection); - catalog.removeResource(firstResourceId, firstCollection); - catalog.removeResource(thirdResourceId, thirdCollection); - - resource = catalog.lookupResourceName(firstResourceId); - ASSERT_EQ(boost::none, resource); - - resource = catalog.lookupResourceName(thirdResourceId); - ASSERT_EQ(boost::none, resource); -} - -TEST_F(UUIDCatalogResourceMapTest, CollisionTest) { - // firstCollection and secondCollection map to the same ResourceId. - catalog.addResource(firstResourceId, firstCollection); - catalog.addResource(secondResourceId, secondCollection); - - // Looking up the namespace on a ResourceId while it has a collision should - // return the empty string. - boost::optional resource = catalog.lookupResourceName(firstResourceId); - ASSERT_EQ(boost::none, resource); - - resource = catalog.lookupResourceName(secondResourceId); - ASSERT_EQ(boost::none, resource); - - // We remove a namespace, resolving the collision. - catalog.removeResource(firstResourceId, firstCollection); - resource = catalog.lookupResourceName(secondResourceId); - ASSERT_EQ(secondCollection, *resource); - - // Adding the same namespace twice does not create a collision. - catalog.addResource(secondResourceId, secondCollection); - resource = catalog.lookupResourceName(secondResourceId); - ASSERT_EQ(secondCollection, *resource); - - // The map should function normally for entries without collisions. - catalog.addResource(firstResourceId, firstCollection); - resource = catalog.lookupResourceName(secondResourceId); - ASSERT_EQ(boost::none, resource); - - catalog.addResource(thirdResourceId, thirdCollection); - resource = catalog.lookupResourceName(thirdResourceId); - ASSERT_EQ(thirdCollection, *resource); - - catalog.removeResource(thirdResourceId, thirdCollection); - resource = catalog.lookupResourceName(thirdResourceId); - ASSERT_EQ(boost::none, resource); - - catalog.removeResource(firstResourceId, firstCollection); - catalog.removeResource(secondResourceId, secondCollection); - - resource = catalog.lookupResourceName(firstResourceId); - ASSERT_EQ(boost::none, resource); - - resource = catalog.lookupResourceName(secondResourceId); - ASSERT_EQ(boost::none, resource); -} - -class UUIDCatalogResourceTest : public unittest::Test { -public: - void setUp() { - for (int i = 0; i < 5; i++) { - NamespaceString nss("resourceDb", "coll" + std::to_string(i)); - auto coll = std::make_unique(nss); - auto newCatalogEntry = std::make_unique(nss.ns()); - auto uuid = coll->uuid(); - - catalog.registerCatalogEntry(uuid.get(), std::move(newCatalogEntry)); - catalog.onCreateCollection(&opCtx, std::move(coll), uuid.get()); - } - - int numEntries = 0; - for (auto it = catalog.begin("resourceDb"); it != catalog.end(); it++) { - auto coll = *it; - std::string collName = coll->ns().ns(); - ResourceId rid(RESOURCE_COLLECTION, collName); - - ASSERT_NE(catalog.lookupResourceName(rid), boost::none); - numEntries++; - } - ASSERT_EQ(5, numEntries); - } - - void tearDown() { - for (auto it = catalog.begin("resourceDb"); it != catalog.end(); ++it) { - auto coll = *it; - auto uuid = coll->uuid().get(); - if (!coll) { - break; - } - - catalog.deregisterCollectionObject(uuid); - catalog.deregisterCatalogEntry(uuid); - } - - int numEntries = 0; - for (auto it = catalog.begin("resourceDb"); it != catalog.end(); it++) { - numEntries++; - } - ASSERT_EQ(0, numEntries); - } - -protected: - OperationContextNoop opCtx; - UUIDCatalog catalog; -}; - -namespace { - -TEST_F(UUIDCatalogResourceTest, RemoveAllResources) { - catalog.deregisterAllCatalogEntriesAndCollectionObjects(); - - const std::string dbName = "resourceDb"; - auto rid = ResourceId(RESOURCE_DATABASE, dbName); - ASSERT_EQ(boost::none, catalog.lookupResourceName(rid)); - - for (int i = 0; i < 5; i++) { - NamespaceString nss("resourceDb", "coll" + std::to_string(i)); - rid = ResourceId(RESOURCE_COLLECTION, nss.ns()); - ASSERT_EQ(boost::none, catalog.lookupResourceName((rid))); - } -} - -TEST_F(UUIDCatalogResourceTest, LookupDatabaseResource) { - const std::string dbName = "resourceDb"; - auto rid = ResourceId(RESOURCE_DATABASE, dbName); - boost::optional ridStr = catalog.lookupResourceName(rid); - - ASSERT(ridStr); - ASSERT(ridStr->find(dbName) != std::string::npos); -} - -TEST_F(UUIDCatalogResourceTest, LookupMissingDatabaseResource) { - const std::string dbName = "missingDb"; - auto rid = ResourceId(RESOURCE_DATABASE, dbName); - ASSERT(!catalog.lookupResourceName(rid)); -} - -TEST_F(UUIDCatalogResourceTest, LookupCollectionResource) { - const std::string collNs = "resourceDb.coll1"; - auto rid = ResourceId(RESOURCE_COLLECTION, collNs); - boost::optional ridStr = catalog.lookupResourceName(rid); - - ASSERT(ridStr); - ASSERT(ridStr->find(collNs) != std::string::npos); -} - -TEST_F(UUIDCatalogResourceTest, LookupMissingCollectionResource) { - const std::string dbName = "resourceDb.coll5"; - auto rid = ResourceId(RESOURCE_COLLECTION, dbName); - ASSERT(!catalog.lookupResourceName(rid)); -} - -TEST_F(UUIDCatalogResourceTest, RemoveCollection) { - const std::string collNs = "resourceDb.coll1"; - auto coll = catalog.lookupCollectionByNamespace(NamespaceString(collNs)); - auto uniqueColl = catalog.deregisterCollectionObject(coll->uuid().get()); - catalog.deregisterCatalogEntry(uniqueColl->uuid().get()); - auto rid = ResourceId(RESOURCE_COLLECTION, collNs); - ASSERT(!catalog.lookupResourceName(rid)); -} - -// Create an iterator over the UUIDCatalog and assert that all collections are present. -// Iteration ends when the end of the catalog is reached. -TEST_F(UUIDCatalogIterationTest, EndAtEndOfCatalog) { - checkCollections("foo"); -} - -// Create an iterator over the UUIDCatalog and test that all collections are present. Iteration ends -// when the end of a database-specific section of the catalog is reached. -TEST_F(UUIDCatalogIterationTest, EndAtEndOfSection) { - checkCollections("bar"); -} - -// Delete an entry in the catalog while iterating. -TEST_F(UUIDCatalogIterationTest, InvalidateEntry) { - auto it = catalog.begin("bar"); - - // Invalidate bar.coll1. - for (auto collsIt = collsIterator("bar"); collsIt != collsIteratorEnd("bar"); ++collsIt) { - if (collsIt->second->ns().ns() == "bar.coll1") { - catalog.onDropCollection(&opCtx, collsIt->first); - dropColl("bar", collsIt->first); - break; - } - } - - // Ensure bar.coll1 is not returned by the iterator. - for (; it != catalog.end(); ++it) { - auto coll = *it; - ASSERT(coll && coll->ns().ns() != "bar.coll1"); - } -} - -// Delete the entry pointed to by the iterator and dereference the iterator. -TEST_F(UUIDCatalogIterationTest, InvalidateAndDereference) { - auto it = catalog.begin("bar"); - auto collsIt = collsIterator("bar"); - auto uuid = collsIt->first; - catalog.onDropCollection(&opCtx, uuid); - ++collsIt; - - ASSERT(it != catalog.end()); - auto catalogColl = *it; - ASSERT(catalogColl != nullptr); - ASSERT_EQUALS(catalogColl->ns(), collsIt->second->ns()); - - dropColl("bar", uuid); -} - -// Delete the last entry for a database while pointing to it and dereference the iterator. -TEST_F(UUIDCatalogIterationTest, InvalidateLastEntryAndDereference) { - auto it = catalog.begin("bar"); - NamespaceString lastNs; - boost::optional uuid; - for (auto collsIt = collsIterator("bar"); collsIt != collsIteratorEnd("bar"); ++collsIt) { - lastNs = collsIt->second->ns(); - uuid = collsIt->first; - } - - // Increment until it points to the last collection. - for (; it != catalog.end(); ++it) { - auto coll = *it; - ASSERT(coll != nullptr); - if (coll->ns() == lastNs) { - break; - } - } - - catalog.onDropCollection(&opCtx, *uuid); - dropColl("bar", *uuid); - ASSERT(*it == nullptr); -} - -// Delete the last entry in the map while pointing to it and dereference the iterator. -TEST_F(UUIDCatalogIterationTest, InvalidateLastEntryInMapAndDereference) { - auto it = catalog.begin("foo"); - NamespaceString lastNs; - boost::optional uuid; - for (auto collsIt = collsIterator("foo"); collsIt != collsIteratorEnd("foo"); ++collsIt) { - lastNs = collsIt->second->ns(); - uuid = collsIt->first; - } - - // Increment until it points to the last collection. - for (; it != catalog.end(); ++it) { - auto coll = *it; - ASSERT(coll != nullptr); - if (coll->ns() == lastNs) { - break; - } - } - - catalog.onDropCollection(&opCtx, *uuid); - dropColl("foo", *uuid); - ASSERT(*it == nullptr); -} - -TEST_F(UUIDCatalogIterationTest, BeginSkipsOverEmptyCollectionObject) { - NamespaceString a1("a", "coll1"); - NamespaceString a2("a", "coll2"); - - auto a1Uuid = CollectionUUID::gen(); - auto a1CatalogEntry = std::make_unique(a1.ns()); - - auto a2Uuid = CollectionUUID::gen(); - if (a2Uuid < a1Uuid) - std::swap(a1Uuid, a2Uuid); - auto a2Coll = std::make_unique(a2); - auto a2CatalogEntry = std::make_unique(a2.ns()); - - catalog.registerCatalogEntry(a1Uuid, std::move(a1CatalogEntry)); - catalog.registerCatalogEntry(a2Uuid, std::move(a2CatalogEntry)); - catalog.onCreateCollection(&opCtx, std::move(a2Coll), a2Uuid); - - auto it = catalog.begin("a"); - ASSERT(it != catalog.end()); - auto coll = *it; - // Skips a.coll1 due to empty collection object. - ASSERT(coll->ns().ns() == a2.ns()); -} - -TEST_F(UUIDCatalogIterationTest, BeginSkipsOverEmptyCollectionObjectButStopsAtDbBoundary) { - NamespaceString a("a", "coll1"); - NamespaceString b("b", "coll1"); - - auto aUuid = CollectionUUID::gen(); - auto aCatalogEntry = std::make_unique(a.ns()); - - auto bUuid = CollectionUUID::gen(); - - auto bColl = std::make_unique(b); - auto bCatalogEntry = std::make_unique(b.ns()); - - catalog.registerCatalogEntry(aUuid, std::move(aCatalogEntry)); - catalog.registerCatalogEntry(bUuid, std::move(bCatalogEntry)); - catalog.onCreateCollection(&opCtx, std::move(bColl), bUuid); - - auto it = catalog.begin("a"); - ASSERT(it == catalog.end()); -} - -TEST_F(UUIDCatalogIterationTest, GetUUIDWontRepositionEvenIfEntryIsDropped) { - auto it = catalog.begin("bar"); - auto collsIt = collsIterator("bar"); - auto uuid = collsIt->first; - catalog.onDropCollection(&opCtx, uuid); - dropColl("bar", uuid); - - ASSERT_EQUALS(uuid, it.uuid()); -} - -TEST_F(UUIDCatalogTest, OnCreateCollection) { - ASSERT(catalog.lookupCollectionByUUID(colUUID) == col); -} - -TEST_F(UUIDCatalogTest, LookupCollectionByUUID) { - // Ensure the string value of the NamespaceString of the obtained Collection is equal to - // nss.ns(). - ASSERT_EQUALS(catalog.lookupCollectionByUUID(colUUID)->ns().ns(), nss.ns()); - // Ensure lookups of unknown UUIDs result in null pointers. - ASSERT(catalog.lookupCollectionByUUID(CollectionUUID::gen()) == nullptr); -} - -TEST_F(UUIDCatalogTest, LookupNSSByUUID) { - // Ensure the string value of the obtained NamespaceString is equal to nss.ns(). - ASSERT_EQUALS(catalog.lookupNSSByUUID(colUUID)->ns(), nss.ns()); - // Ensure namespace lookups of unknown UUIDs result in empty NamespaceStrings. - ASSERT_EQUALS(catalog.lookupNSSByUUID(CollectionUUID::gen()), boost::none); -} - -TEST_F(UUIDCatalogTest, InsertAfterLookup) { - auto newUUID = CollectionUUID::gen(); - NamespaceString newNss(nss.db(), "newcol"); - auto newCollUnique = std::make_unique(newNss); - auto newCatalogEntry = std::make_unique(newNss.ns()); - auto newCol = newCollUnique.get(); - - // Ensure that looking up non-existing UUIDs doesn't affect later registration of those UUIDs. - ASSERT(catalog.lookupCollectionByUUID(newUUID) == nullptr); - ASSERT_EQUALS(catalog.lookupNSSByUUID(newUUID), boost::none); - catalog.registerCatalogEntry(newUUID, std::move(newCatalogEntry)); - catalog.onCreateCollection(&opCtx, std::move(newCollUnique), newUUID); - ASSERT_EQUALS(catalog.lookupCollectionByUUID(newUUID), newCol); - ASSERT_EQUALS(*catalog.lookupNSSByUUID(colUUID), nss); -} - -TEST_F(UUIDCatalogTest, OnDropCollection) { - catalog.onDropCollection(&opCtx, colUUID); - // Ensure the lookup returns a null pointer upon removing the colUUID entry. - ASSERT(catalog.lookupCollectionByUUID(colUUID) == nullptr); -} - -TEST_F(UUIDCatalogTest, RenameCollection) { - auto uuid = CollectionUUID::gen(); - NamespaceString oldNss(nss.db(), "oldcol"); - auto collUnique = std::make_unique(oldNss); - auto catalogEntry = std::make_unique(oldNss.ns()); - auto collection = collUnique.get(); - catalog.registerCatalogEntry(uuid, std::move(catalogEntry)); - catalog.onCreateCollection(&opCtx, std::move(collUnique), uuid); - ASSERT_EQUALS(catalog.lookupCollectionByUUID(uuid), collection); - - NamespaceString newNss(nss.db(), "newcol"); - catalog.setCollectionNamespace(&opCtx, collection, oldNss, newNss); - ASSERT_EQ(collection->ns(), newNss); - ASSERT_EQUALS(catalog.lookupCollectionByUUID(uuid), collection); -} - -TEST_F(UUIDCatalogTest, LookupNSSByUUIDForClosedCatalogReturnsOldNSSIfDropped) { - catalog.onCloseCatalog(&opCtx); - catalog.onDropCollection(&opCtx, colUUID); - catalog.deregisterCatalogEntry(colUUID); - ASSERT(catalog.lookupCollectionByUUID(colUUID) == nullptr); - ASSERT_EQUALS(*catalog.lookupNSSByUUID(colUUID), nss); - catalog.onOpenCatalog(&opCtx); - ASSERT_EQUALS(catalog.lookupNSSByUUID(colUUID), boost::none); -} - -TEST_F(UUIDCatalogTest, LookupNSSByUUIDForClosedCatalogReturnsNewlyCreatedNSS) { - auto newUUID = CollectionUUID::gen(); - NamespaceString newNss(nss.db(), "newcol"); - auto newCollUnique = std::make_unique(newNss); - auto newCatalogEntry = std::make_unique(newNss.ns()); - auto newCol = newCollUnique.get(); - - // Ensure that looking up non-existing UUIDs doesn't affect later registration of those UUIDs. - catalog.onCloseCatalog(&opCtx); - ASSERT(catalog.lookupCollectionByUUID(newUUID) == nullptr); - ASSERT_EQUALS(catalog.lookupNSSByUUID(newUUID), boost::none); - catalog.registerCatalogEntry(newUUID, std::move(newCatalogEntry)); - catalog.onCreateCollection(&opCtx, std::move(newCollUnique), newUUID); - ASSERT_EQUALS(catalog.lookupCollectionByUUID(newUUID), newCol); - ASSERT_EQUALS(*catalog.lookupNSSByUUID(colUUID), nss); - - // Ensure that collection still exists after opening the catalog again. - catalog.onOpenCatalog(&opCtx); - ASSERT_EQUALS(catalog.lookupCollectionByUUID(newUUID), newCol); - ASSERT_EQUALS(*catalog.lookupNSSByUUID(colUUID), nss); -} - -TEST_F(UUIDCatalogTest, LookupNSSByUUIDForClosedCatalogReturnsFreshestNSS) { - NamespaceString newNss(nss.db(), "newcol"); - auto newCollUnique = std::make_unique(newNss); - auto newCatalogEntry = std::make_unique(newNss.ns()); - auto newCol = newCollUnique.get(); - - catalog.onCloseCatalog(&opCtx); - catalog.onDropCollection(&opCtx, colUUID); - catalog.deregisterCatalogEntry(colUUID); - ASSERT(catalog.lookupCollectionByUUID(colUUID) == nullptr); - ASSERT_EQUALS(*catalog.lookupNSSByUUID(colUUID), nss); - catalog.registerCatalogEntry(colUUID, std::move(newCatalogEntry)); - catalog.onCreateCollection(&opCtx, std::move(newCollUnique), colUUID); - ASSERT_EQUALS(catalog.lookupCollectionByUUID(colUUID), newCol); - ASSERT_EQUALS(*catalog.lookupNSSByUUID(colUUID), newNss); - - // Ensure that collection still exists after opening the catalog again. - catalog.onOpenCatalog(&opCtx); - ASSERT_EQUALS(catalog.lookupCollectionByUUID(colUUID), newCol); - ASSERT_EQUALS(*catalog.lookupNSSByUUID(colUUID), newNss); -} - -DEATH_TEST_F(UUIDCatalogResourceTest, AddInvalidResourceType, "invariant") { - auto rid = ResourceId(RESOURCE_GLOBAL, 0); - catalog.addResource(rid, ""); -} - -TEST_F(UUIDCatalogTest, GetAllCollectionNamesAndGetAllDbNames) { - NamespaceString aColl("dbA", "collA"); - NamespaceString b1Coll("dbB", "collB1"); - NamespaceString b2Coll("dbB", "collB2"); - NamespaceString cColl("dbC", "collC"); - NamespaceString d1Coll("dbD", "collD1"); - NamespaceString d2Coll("dbD", "collD2"); - NamespaceString d3Coll("dbD", "collD3"); - - std::vector nsss = {aColl, b1Coll, b2Coll, cColl, d1Coll, d2Coll, d3Coll}; - for (auto& nss : nsss) { - auto newColl = std::make_unique(nss); - auto newCatalogEntry = std::make_unique(nss.ns()); - auto uuid = CollectionUUID::gen(); - catalog.registerCatalogEntry(uuid, std::move(newCatalogEntry)); - catalog.registerCollectionObject(uuid, std::move(newColl)); - } - - std::vector dCollList = {d1Coll, d2Coll, d3Coll}; - auto res = catalog.getAllCollectionNamesFromDb(&opCtx, "dbD"); - std::sort(res.begin(), res.end()); - ASSERT(res == dCollList); - - std::vector dbNames = {"dbA", "dbB", "dbC", "dbD", "testdb"}; - ASSERT(catalog.getAllDbNames() == dbNames); - - catalog.deregisterAllCatalogEntriesAndCollectionObjects(); -} -} // namespace diff --git a/src/mongo/db/catalog_raii.cpp b/src/mongo/db/catalog_raii.cpp index 5222dcf1843..1293f752769 100644 --- a/src/mongo/db/catalog_raii.cpp +++ b/src/mongo/db/catalog_raii.cpp @@ -31,8 +31,8 @@ #include "mongo/db/catalog_raii.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/database_holder.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/s/database_sharding_state.h" #include "mongo/db/views/view_catalog.h" #include "mongo/util/fail_point_service.h" @@ -157,8 +157,8 @@ NamespaceString AutoGetCollection::resolveNamespaceStringOrUUID(OperationContext return *nss; } - UUIDCatalog& uuidCatalog = UUIDCatalog::get(opCtx); - auto resolvedNss = uuidCatalog.lookupNSSByUUID(*nsOrUUID.uuid()); + CollectionCatalog& catalog = CollectionCatalog::get(opCtx); + auto resolvedNss = catalog.lookupNSSByUUID(*nsOrUUID.uuid()); uassert(ErrorCodes::NamespaceNotFound, str::stream() << "Unable to resolve " << nsOrUUID.toString(), @@ -197,14 +197,14 @@ AutoGetOrCreateDb::AutoGetOrCreateDb(OperationContext* opCtx, dss.checkDbVersion(opCtx, dssLock); } -ConcealUUIDCatalogChangesBlock::ConcealUUIDCatalogChangesBlock(OperationContext* opCtx) +ConcealCollectionCatalogChangesBlock::ConcealCollectionCatalogChangesBlock(OperationContext* opCtx) : _opCtx(opCtx) { - UUIDCatalog::get(_opCtx).onCloseCatalog(_opCtx); + CollectionCatalog::get(_opCtx).onCloseCatalog(_opCtx); } -ConcealUUIDCatalogChangesBlock::~ConcealUUIDCatalogChangesBlock() { +ConcealCollectionCatalogChangesBlock::~ConcealCollectionCatalogChangesBlock() { invariant(_opCtx); - UUIDCatalog::get(_opCtx).onOpenCatalog(_opCtx); + CollectionCatalog::get(_opCtx).onOpenCatalog(_opCtx); } ReadSourceScope::ReadSourceScope(OperationContext* opCtx) diff --git a/src/mongo/db/catalog_raii.h b/src/mongo/db/catalog_raii.h index aa18dd23e23..8522f33c92b 100644 --- a/src/mongo/db/catalog_raii.h +++ b/src/mongo/db/catalog_raii.h @@ -192,29 +192,31 @@ private: }; /** - * RAII-style class. Hides changes to the UUIDCatalog For the life of the object so that calls to - * UUIDCatalog::lookupNSSByUUID will return results as before the RAII object was instantiated. + * RAII-style class. Hides changes to the CollectionCatalog for the life of the object, so that + * calls to CollectionCatalog::lookupNSSByUUID will return results as before the RAII object was + * instantiated. * * The caller must hold the global exclusive lock for the life of the instance. */ -class ConcealUUIDCatalogChangesBlock { - ConcealUUIDCatalogChangesBlock(const ConcealUUIDCatalogChangesBlock&) = delete; - ConcealUUIDCatalogChangesBlock& operator=(const ConcealUUIDCatalogChangesBlock&) = delete; +class ConcealCollectionCatalogChangesBlock { + ConcealCollectionCatalogChangesBlock(const ConcealCollectionCatalogChangesBlock&) = delete; + ConcealCollectionCatalogChangesBlock& operator=(const ConcealCollectionCatalogChangesBlock&) = + delete; public: /** - * Conceals future UUIDCatalog changes and stashes a pointer to the opCtx for the destructor to - * use. + * Conceals future CollectionCatalog changes and stashes a pointer to the opCtx for the + * destructor to use. */ - ConcealUUIDCatalogChangesBlock(OperationContext* opCtx); + ConcealCollectionCatalogChangesBlock(OperationContext* opCtx); /** - * Reveals UUIDCatalog changes. + * Reveals CollectionCatalog changes. */ - ~ConcealUUIDCatalogChangesBlock(); + ~ConcealCollectionCatalogChangesBlock(); private: - // Needed for the destructor to access the UUIDCatalog in order to call onOpenCatalog. + // Needed for the destructor to access the CollectionCatalog in order to call onOpenCatalog. OperationContext* _opCtx; }; diff --git a/src/mongo/db/commands/SConscript b/src/mongo/db/commands/SConscript index 882331f0073..7f83d0d192d 100644 --- a/src/mongo/db/commands/SConscript +++ b/src/mongo/db/commands/SConscript @@ -265,7 +265,8 @@ env.Library( LIBDEPS_PRIVATE=[ '$BUILD_DIR/mongo/base', '$BUILD_DIR/mongo/db/catalog/catalog_helpers', - '$BUILD_DIR/mongo/db/catalog/uuid_catalog_helper', + '$BUILD_DIR/mongo/db/catalog/collection_catalog_helper', + '$BUILD_DIR/mongo/db/catalog/database_holder', '$BUILD_DIR/mongo/db/catalog/index_key_validate', '$BUILD_DIR/mongo/db/catalog/multi_index_block', '$BUILD_DIR/mongo/db/command_can_run_here', @@ -368,7 +369,7 @@ env.Library( '$BUILD_DIR/mongo/db/background', '$BUILD_DIR/mongo/db/catalog/catalog_control', '$BUILD_DIR/mongo/db/catalog/catalog_helpers', - '$BUILD_DIR/mongo/db/catalog/uuid_catalog_helper', + '$BUILD_DIR/mongo/db/catalog/collection_catalog_helper', '$BUILD_DIR/mongo/db/catalog/index_key_validate', '$BUILD_DIR/mongo/db/cloner', '$BUILD_DIR/mongo/db/commands', diff --git a/src/mongo/db/commands/apply_ops_cmd.cpp b/src/mongo/db/commands/apply_ops_cmd.cpp index f8c169f4703..c7f216fe160 100644 --- a/src/mongo/db/commands/apply_ops_cmd.cpp +++ b/src/mongo/db/commands/apply_ops_cmd.cpp @@ -36,8 +36,8 @@ #include "mongo/bson/util/bson_check.h" #include "mongo/bson/util/bson_extract.h" #include "mongo/db/auth/authorization_session.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/document_validation.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/client.h" #include "mongo/db/commands.h" #include "mongo/db/commands/oplog_application_checks.h" diff --git a/src/mongo/db/commands/dbcheck.cpp b/src/mongo/db/commands/dbcheck.cpp index c29677cd3e9..90160598ba6 100644 --- a/src/mongo/db/commands/dbcheck.cpp +++ b/src/mongo/db/commands/dbcheck.cpp @@ -32,9 +32,9 @@ #include "mongo/platform/basic.h" #include "mongo/db/auth/authorization_session.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/database.h" #include "mongo/db/catalog/health_log.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/command_generic_argument.h" #include "mongo/db/commands.h" #include "mongo/db/commands/test_commands_enabled.h" diff --git a/src/mongo/db/commands/dbhash.cpp b/src/mongo/db/commands/dbhash.cpp index 20e14103f79..9cb4a5adbd5 100644 --- a/src/mongo/db/commands/dbhash.cpp +++ b/src/mongo/db/commands/dbhash.cpp @@ -37,9 +37,9 @@ #include #include "mongo/db/catalog/collection.h" +#include "mongo/db/catalog/collection_catalog_helper.h" #include "mongo/db/catalog/database.h" #include "mongo/db/catalog/index_catalog.h" -#include "mongo/db/catalog/uuid_catalog_helper.h" #include "mongo/db/commands.h" #include "mongo/db/commands/test_commands_enabled.h" #include "mongo/db/db_raii.h" diff --git a/src/mongo/db/commands/do_txn_cmd.cpp b/src/mongo/db/commands/do_txn_cmd.cpp index 915ed3da0f3..6c5723c6de3 100644 --- a/src/mongo/db/commands/do_txn_cmd.cpp +++ b/src/mongo/db/commands/do_txn_cmd.cpp @@ -36,8 +36,8 @@ #include "mongo/bson/util/bson_check.h" #include "mongo/bson/util/bson_extract.h" #include "mongo/db/auth/authorization_session.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/document_validation.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/client.h" #include "mongo/db/commands.h" #include "mongo/db/commands/oplog_application_checks.h" diff --git a/src/mongo/db/commands/list_collections.cpp b/src/mongo/db/commands/list_collections.cpp index e1f20746eb4..3e715d3a69a 100644 --- a/src/mongo/db/commands/list_collections.cpp +++ b/src/mongo/db/commands/list_collections.cpp @@ -39,9 +39,9 @@ #include "mongo/db/auth/authorization_session.h" #include "mongo/db/catalog/collection.h" #include "mongo/db/catalog/collection_catalog_entry.h" +#include "mongo/db/catalog/collection_catalog_helper.h" #include "mongo/db/catalog/database.h" #include "mongo/db/catalog/index_catalog.h" -#include "mongo/db/catalog/uuid_catalog_helper.h" #include "mongo/db/clientcursor.h" #include "mongo/db/commands.h" #include "mongo/db/commands/list_collections_filter.h" diff --git a/src/mongo/db/commands/list_databases.cpp b/src/mongo/db/commands/list_databases.cpp index dccec13a8b6..52f4c49f2f2 100644 --- a/src/mongo/db/commands/list_databases.cpp +++ b/src/mongo/db/commands/list_databases.cpp @@ -169,8 +169,9 @@ public: }); b.append("sizeOnDisk", static_cast(size)); - b.appendBool("empty", - UUIDCatalog::get(opCtx).getAllCollectionUUIDsFromDb(dbname).empty()); + b.appendBool( + "empty", + CollectionCatalog::get(opCtx).getAllCollectionUUIDsFromDb(dbname).empty()); } BSONObj curDbObj = b.obj(); diff --git a/src/mongo/db/commands/oplog_application_checks.cpp b/src/mongo/db/commands/oplog_application_checks.cpp index cb29312ef84..783d1002b35 100644 --- a/src/mongo/db/commands/oplog_application_checks.cpp +++ b/src/mongo/db/commands/oplog_application_checks.cpp @@ -30,8 +30,8 @@ #include "mongo/bson/util/bson_check.h" #include "mongo/db/auth/authorization_session.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/document_validation.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/commands.h" #include "mongo/db/commands/oplog_application_checks.h" @@ -65,9 +65,9 @@ Status OplogApplicationChecks::checkOperationAuthorization(OperationContext* opC if (oplogEntry.hasField("ui"_sd)) { // ns by UUID overrides the ns specified if they are different. - auto& uuidCatalog = UUIDCatalog::get(opCtx); + auto& catalog = CollectionCatalog::get(opCtx); boost::optional uuidCollNS = - uuidCatalog.lookupNSSByUUID(getUUIDFromOplogEntry(oplogEntry)); + catalog.lookupNSSByUUID(getUUIDFromOplogEntry(oplogEntry)); if (uuidCollNS && *uuidCollNS != ns) ns = *uuidCollNS; } diff --git a/src/mongo/db/concurrency/SConscript b/src/mongo/db/concurrency/SConscript index f8e5c142eec..558dff39364 100644 --- a/src/mongo/db/concurrency/SConscript +++ b/src/mongo/db/concurrency/SConscript @@ -54,7 +54,7 @@ env.Library( '$BUILD_DIR/third_party/shim_boost', ], LIBDEPS_PRIVATE=[ - '$BUILD_DIR/mongo/db/catalog/uuid_catalog', + '$BUILD_DIR/mongo/db/catalog/collection_catalog', '$BUILD_DIR/mongo/db/concurrency/flow_control_ticketholder', ], ) diff --git a/src/mongo/db/concurrency/lock_manager.cpp b/src/mongo/db/concurrency/lock_manager.cpp index 6b80b3b9aca..e3c7fc77809 100644 --- a/src/mongo/db/concurrency/lock_manager.cpp +++ b/src/mongo/db/concurrency/lock_manager.cpp @@ -38,7 +38,7 @@ #include "mongo/base/static_assert.h" #include "mongo/bson/bsonobjbuilder.h" #include "mongo/config.h" -#include "mongo/db/catalog/uuid_catalog.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/concurrency/locker.h" #include "mongo/util/assert_util.h" @@ -965,8 +965,8 @@ std::string ResourceId::toString() const { } if (getType() == RESOURCE_DATABASE || getType() == RESOURCE_COLLECTION) { - UUIDCatalog& uuidCatalog = UUIDCatalog::get(getGlobalServiceContext()); - boost::optional resourceName = uuidCatalog.lookupResourceName(*this); + CollectionCatalog& catalog = CollectionCatalog::get(getGlobalServiceContext()); + boost::optional resourceName = catalog.lookupResourceName(*this); if (resourceName) { ss << ", " << *resourceName; } diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp index da81a6d4a07..474c05ac8ab 100644 --- a/src/mongo/db/db.cpp +++ b/src/mongo/db/db.cpp @@ -50,13 +50,13 @@ #include "mongo/db/auth/authorization_manager.h" #include "mongo/db/auth/sasl_options.h" #include "mongo/db/catalog/collection.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/create_collection.h" #include "mongo/db/catalog/database.h" #include "mongo/db/catalog/database_holder_impl.h" #include "mongo/db/catalog/health_log.h" #include "mongo/db/catalog/index_catalog.h" #include "mongo/db/catalog/index_key_validate.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/client.h" #include "mongo/db/clientcursor.h" #include "mongo/db/commands/feature_compatibility_version.h" diff --git a/src/mongo/db/exec/requires_collection_stage.cpp b/src/mongo/db/exec/requires_collection_stage.cpp index 358d2bcc72a..f49a0a7e7cb 100644 --- a/src/mongo/db/exec/requires_collection_stage.cpp +++ b/src/mongo/db/exec/requires_collection_stage.cpp @@ -31,7 +31,7 @@ #include "mongo/db/exec/requires_collection_stage.h" -#include "mongo/db/catalog/uuid_catalog.h" +#include "mongo/db/catalog/collection_catalog.h" namespace mongo { @@ -47,7 +47,7 @@ template void RequiresCollectionStageBase::doRestoreState() { invariant(!_collection); - const UUIDCatalog& catalog = UUIDCatalog::get(getOpCtx()); + const CollectionCatalog& catalog = CollectionCatalog::get(getOpCtx()); _collection = catalog.lookupCollectionByUUID(_collectionUUID); uassert(ErrorCodes::QueryPlanKilled, str::stream() << "collection dropped. UUID " << _collectionUUID, diff --git a/src/mongo/db/index_builds_coordinator.cpp b/src/mongo/db/index_builds_coordinator.cpp index e2f7372b381..6f26850d256 100644 --- a/src/mongo/db/index_builds_coordinator.cpp +++ b/src/mongo/db/index_builds_coordinator.cpp @@ -33,10 +33,10 @@ #include "mongo/db/index_builds_coordinator.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/commit_quorum_options.h" #include "mongo/db/catalog/database_holder.h" #include "mongo/db/catalog/index_build_entry_gen.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/catalog_raii.h" #include "mongo/db/concurrency/locker.h" #include "mongo/db/curop.h" @@ -546,7 +546,7 @@ IndexBuildsCoordinator::_registerAndSetUpIndexBuild( const UUID& buildUUID, IndexBuildProtocol protocol, boost::optional commitQuorum) { - auto nss = UUIDCatalog::get(opCtx).lookupNSSByUUID(collectionUUID); + auto nss = CollectionCatalog::get(opCtx).lookupNSSByUUID(collectionUUID); if (!nss) { return Status(ErrorCodes::NamespaceNotFound, str::stream() << "Cannot create index on collection '" << collectionUUID @@ -742,7 +742,7 @@ void IndexBuildsCoordinator::_runIndexBuildInner(OperationContext* opCtx, Status status{ErrorCodes::InternalError, "Uninitialized status value in IndexBuildsCoordinator"}; boost::optional nss = - UUIDCatalog::get(opCtx).lookupNSSByUUID(replState->collectionUUID); + CollectionCatalog::get(opCtx).lookupNSSByUUID(replState->collectionUUID); invariant(nss, str::stream() << "Collection '" << replState->collectionUUID @@ -759,7 +759,8 @@ void IndexBuildsCoordinator::_runIndexBuildInner(OperationContext* opCtx, // not allow locks or re-locks to be interrupted. UninterruptibleLockGuard noInterrupt(opCtx->lockState()); - auto collection = UUIDCatalog::get(opCtx).lookupCollectionByUUID(replState->collectionUUID); + auto collection = + CollectionCatalog::get(opCtx).lookupCollectionByUUID(replState->collectionUUID); invariant(collection, str::stream() << "Collection " << *nss << " should exist because an index build is in progress."); diff --git a/src/mongo/db/index_builds_coordinator_mongod.cpp b/src/mongo/db/index_builds_coordinator_mongod.cpp index 2ab88e52ada..4e9cca08386 100644 --- a/src/mongo/db/index_builds_coordinator_mongod.cpp +++ b/src/mongo/db/index_builds_coordinator_mongod.cpp @@ -33,7 +33,7 @@ #include "mongo/db/index_builds_coordinator_mongod.h" -#include "mongo/db/catalog/uuid_catalog.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/curop.h" #include "mongo/db/db_raii.h" #include "mongo/db/index_build_entry_helpers.h" diff --git a/src/mongo/db/pipeline/SConscript b/src/mongo/db/pipeline/SConscript index b2aa0480266..6a0ccb087bb 100644 --- a/src/mongo/db/pipeline/SConscript +++ b/src/mongo/db/pipeline/SConscript @@ -317,6 +317,7 @@ env.Library( 'mongo_process_common', ], LIBDEPS_PRIVATE=[ + '$BUILD_DIR/mongo/db/catalog/database_holder', '$BUILD_DIR/mongo/db/concurrency/flow_control_ticketholder', '$BUILD_DIR/mongo/db/session_catalog', '$BUILD_DIR/mongo/db/storage/backup_cursor_hooks', diff --git a/src/mongo/db/pipeline/document_source_change_stream_test.cpp b/src/mongo/db/pipeline/document_source_change_stream_test.cpp index 686b4a51670..6f89c07e734 100644 --- a/src/mongo/db/pipeline/document_source_change_stream_test.cpp +++ b/src/mongo/db/pipeline/document_source_change_stream_test.cpp @@ -34,9 +34,9 @@ #include "mongo/bson/bsonobj.h" #include "mongo/bson/json.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_catalog_entry_mock.h" #include "mongo/db/catalog/collection_mock.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/pipeline/aggregation_context_fixture.h" #include "mongo/db/pipeline/document.h" #include "mongo/db/pipeline/document_source.h" @@ -374,11 +374,12 @@ TEST_F(ChangeStreamStageTest, ShouldRejectUnrecognizedFullDocumentOption) { TEST_F(ChangeStreamStageTest, ShouldRejectBothStartAtOperationTimeAndResumeAfterOptions) { auto expCtx = getExpCtx(); - // Need to put the collection in the UUID catalog so the resume token is valid. + // Need to put the collection in the collection catalog so the resume token is valid. auto collection = std::make_unique(nss); auto catalogEntry = std::make_unique(nss.ns()); - UUIDCatalog::get(getExpCtx()->opCtx).registerCatalogEntry(testUuid(), std::move(catalogEntry)); - UUIDCatalog::get(expCtx->opCtx) + CollectionCatalog::get(getExpCtx()->opCtx) + .registerCatalogEntry(testUuid(), std::move(catalogEntry)); + CollectionCatalog::get(expCtx->opCtx) .onCreateCollection(expCtx->opCtx, std::move(collection), testUuid()); ASSERT_THROWS_CODE( @@ -398,12 +399,12 @@ TEST_F(ChangeStreamStageTest, ShouldRejectBothStartAfterAndResumeAfterOptions) { auto expCtx = getExpCtx(); auto opCtx = expCtx->opCtx; - // Need to put the collection in the UUID catalog so the resume token is valid. + // Need to put the collection in the collection catalog so the resume token is validcollection auto collection = std::make_unique(nss); auto catalogEntry = std::make_unique(nss.ns()); - auto& uuidCatalog = UUIDCatalog::get(opCtx); - uuidCatalog.registerCatalogEntry(testUuid(), std::move(catalogEntry)); - uuidCatalog.onCreateCollection(expCtx->opCtx, std::move(collection), testUuid()); + auto& catalog = CollectionCatalog::get(opCtx); + catalog.registerCatalogEntry(testUuid(), std::move(catalogEntry)); + catalog.onCreateCollection(expCtx->opCtx, std::move(collection), testUuid()); ASSERT_THROWS_CODE( DSChangeStream::createFromBson( @@ -422,12 +423,12 @@ TEST_F(ChangeStreamStageTest, ShouldRejectBothStartAtOperationTimeAndStartAfterO auto expCtx = getExpCtx(); auto opCtx = expCtx->opCtx; - // Need to put the collection in the UUID catalog so the resume token is valid. + // Need to put the collection in the collection catalog so the resume token is valid. auto collection = std::make_unique(nss); auto catalogEntry = std::make_unique(nss.ns()); - auto& uuidCatalog = UUIDCatalog::get(opCtx); - uuidCatalog.registerCatalogEntry(testUuid(), std::move(catalogEntry)); - uuidCatalog.onCreateCollection(expCtx->opCtx, std::move(collection), testUuid()); + auto& catalog = CollectionCatalog::get(opCtx); + catalog.registerCatalogEntry(testUuid(), std::move(catalogEntry)); + catalog.onCreateCollection(expCtx->opCtx, std::move(collection), testUuid()); ASSERT_THROWS_CODE( DSChangeStream::createFromBson( @@ -446,12 +447,12 @@ TEST_F(ChangeStreamStageTest, ShouldRejectResumeAfterWithResumeTokenMissingUUID) auto expCtx = getExpCtx(); auto opCtx = expCtx->opCtx; - // Need to put the collection in the UUID catalog so the resume token is valid. + // Need to put the collection in the collection catalog so the resume token is valid. auto collection = std::make_unique(nss); auto catalogEntry = std::make_unique(nss.ns()); - auto& uuidCatalog = UUIDCatalog::get(opCtx); - uuidCatalog.registerCatalogEntry(testUuid(), std::move(catalogEntry)); - uuidCatalog.onCreateCollection(expCtx->opCtx, std::move(collection), testUuid()); + auto& catalog = CollectionCatalog::get(opCtx); + catalog.registerCatalogEntry(testUuid(), std::move(catalogEntry)); + catalog.onCreateCollection(expCtx->opCtx, std::move(collection), testUuid()); ASSERT_THROWS_CODE( DSChangeStream::createFromBson( @@ -1182,8 +1183,8 @@ TEST_F(ChangeStreamStageTest, DocumentKeyShouldIncludeShardKeyFromResumeToken) { auto collection = std::make_unique(nss); auto catalogEntry = std::make_unique(nss.ns()); - UUIDCatalog::get(getExpCtx()->opCtx).registerCatalogEntry(uuid, std::move(catalogEntry)); - UUIDCatalog::get(getExpCtx()->opCtx) + CollectionCatalog::get(getExpCtx()->opCtx).registerCatalogEntry(uuid, std::move(catalogEntry)); + CollectionCatalog::get(getExpCtx()->opCtx) .onCreateCollection(getExpCtx()->opCtx, std::move(collection), uuid); BSONObj o2 = BSON("_id" << 1 << "shardKey" << 2); @@ -1230,8 +1231,8 @@ TEST_F(ChangeStreamStageTest, DocumentKeyShouldNotIncludeShardKeyFieldsIfNotPres auto collection = std::make_unique(nss); auto catalogEntry = std::make_unique(nss.ns()); - UUIDCatalog::get(getExpCtx()->opCtx).registerCatalogEntry(uuid, std::move(catalogEntry)); - UUIDCatalog::get(getExpCtx()->opCtx) + CollectionCatalog::get(getExpCtx()->opCtx).registerCatalogEntry(uuid, std::move(catalogEntry)); + CollectionCatalog::get(getExpCtx()->opCtx) .onCreateCollection(getExpCtx()->opCtx, std::move(collection), uuid); BSONObj o2 = BSON("_id" << 1 << "shardKey" << 2); @@ -1275,8 +1276,8 @@ TEST_F(ChangeStreamStageTest, ResumeAfterFailsIfResumeTokenDoesNotContainUUID) { auto collection = std::make_unique(nss); auto catalogEntry = std::make_unique(nss.ns()); - UUIDCatalog::get(getExpCtx()->opCtx).registerCatalogEntry(uuid, std::move(catalogEntry)); - UUIDCatalog::get(getExpCtx()->opCtx) + CollectionCatalog::get(getExpCtx()->opCtx).registerCatalogEntry(uuid, std::move(catalogEntry)); + CollectionCatalog::get(getExpCtx()->opCtx) .onCreateCollection(getExpCtx()->opCtx, std::move(collection), uuid); // Create a resume token from only the timestamp. @@ -1328,11 +1329,12 @@ TEST_F(ChangeStreamStageTest, RenameFromUserToSystemCollectionShouldIncludeNotif TEST_F(ChangeStreamStageTest, ResumeAfterWithTokenFromInvalidateShouldFail) { auto expCtx = getExpCtx(); - // Need to put the collection in the UUID catalog so the resume token is valid. + // Need to put the collection in the collection catalog so the resume token is valid. auto collection = std::make_unique(nss); auto catalogEntry = std::make_unique(nss.ns()); - UUIDCatalog::get(getExpCtx()->opCtx).registerCatalogEntry(testUuid(), std::move(catalogEntry)); - UUIDCatalog::get(expCtx->opCtx) + CollectionCatalog::get(getExpCtx()->opCtx) + .registerCatalogEntry(testUuid(), std::move(catalogEntry)); + CollectionCatalog::get(expCtx->opCtx) .onCreateCollection(expCtx->opCtx, std::move(collection), testUuid()); const auto resumeTokenInvalidate = @@ -1746,8 +1748,8 @@ TEST_F(ChangeStreamStageDBTest, DocumentKeyShouldIncludeShardKeyFromResumeToken) auto collection = std::make_unique(nss); auto catalogEntry = std::make_unique(nss.ns()); - UUIDCatalog::get(getExpCtx()->opCtx).registerCatalogEntry(uuid, std::move(catalogEntry)); - UUIDCatalog::get(getExpCtx()->opCtx) + CollectionCatalog::get(getExpCtx()->opCtx).registerCatalogEntry(uuid, std::move(catalogEntry)); + CollectionCatalog::get(getExpCtx()->opCtx) .onCreateCollection(getExpCtx()->opCtx, std::move(collection), uuid); BSONObj o2 = BSON("_id" << 1 << "shardKey" << 2); @@ -1785,8 +1787,8 @@ TEST_F(ChangeStreamStageDBTest, DocumentKeyShouldNotIncludeShardKeyFieldsIfNotPr auto collection = std::make_unique(nss); auto catalogEntry = std::make_unique(nss.ns()); - UUIDCatalog::get(getExpCtx()->opCtx).registerCatalogEntry(uuid, std::move(catalogEntry)); - UUIDCatalog::get(getExpCtx()->opCtx) + CollectionCatalog::get(getExpCtx()->opCtx).registerCatalogEntry(uuid, std::move(catalogEntry)); + CollectionCatalog::get(getExpCtx()->opCtx) .onCreateCollection(getExpCtx()->opCtx, std::move(collection), uuid); BSONObj o2 = BSON("_id" << 1 << "shardKey" << 2); @@ -1825,8 +1827,8 @@ TEST_F(ChangeStreamStageDBTest, DocumentKeyShouldNotIncludeShardKeyIfResumeToken auto collection = std::make_unique(nss); auto catalogEntry = std::make_unique(nss.ns()); - UUIDCatalog::get(getExpCtx()->opCtx).registerCatalogEntry(uuid, std::move(catalogEntry)); - UUIDCatalog::get(getExpCtx()->opCtx) + CollectionCatalog::get(getExpCtx()->opCtx).registerCatalogEntry(uuid, std::move(catalogEntry)); + CollectionCatalog::get(getExpCtx()->opCtx) .onCreateCollection(getExpCtx()->opCtx, std::move(collection), uuid); // Create a resume token from only the timestamp. @@ -1861,11 +1863,12 @@ TEST_F(ChangeStreamStageDBTest, DocumentKeyShouldNotIncludeShardKeyIfResumeToken TEST_F(ChangeStreamStageDBTest, ResumeAfterWithTokenFromInvalidateShouldFail) { auto expCtx = getExpCtx(); - // Need to put the collection in the UUID catalog so the resume token is valid. + // Need to put the collection in the collection catalog so the resume token is valid. auto collection = std::make_unique(nss); auto catalogEntry = std::make_unique(nss.ns()); - UUIDCatalog::get(getExpCtx()->opCtx).registerCatalogEntry(testUuid(), std::move(catalogEntry)); - UUIDCatalog::get(expCtx->opCtx) + CollectionCatalog::get(getExpCtx()->opCtx) + .registerCatalogEntry(testUuid(), std::move(catalogEntry)); + CollectionCatalog::get(expCtx->opCtx) .onCreateCollection(expCtx->opCtx, std::move(collection), testUuid()); const auto resumeTokenInvalidate = @@ -1888,8 +1891,8 @@ TEST_F(ChangeStreamStageDBTest, ResumeAfterWithTokenFromDropDatabase) { auto collection = std::make_unique(nss); auto catalogEntry = std::make_unique(nss.ns()); - UUIDCatalog::get(getExpCtx()->opCtx).registerCatalogEntry(uuid, std::move(catalogEntry)); - UUIDCatalog::get(getExpCtx()->opCtx) + CollectionCatalog::get(getExpCtx()->opCtx).registerCatalogEntry(uuid, std::move(catalogEntry)); + CollectionCatalog::get(getExpCtx()->opCtx) .onCreateCollection(getExpCtx()->opCtx, std::move(collection), uuid); // Create a resume token from only the timestamp, similar to a 'dropDatabase' entry. @@ -1920,8 +1923,8 @@ TEST_F(ChangeStreamStageDBTest, StartAfterSucceedsEvenIfResumeTokenDoesNotContai auto collection = std::make_unique(nss); auto catalogEntry = std::make_unique(nss.ns()); - UUIDCatalog::get(getExpCtx()->opCtx).registerCatalogEntry(uuid, std::move(catalogEntry)); - UUIDCatalog::get(getExpCtx()->opCtx) + CollectionCatalog::get(getExpCtx()->opCtx).registerCatalogEntry(uuid, std::move(catalogEntry)); + CollectionCatalog::get(getExpCtx()->opCtx) .onCreateCollection(getExpCtx()->opCtx, std::move(collection), uuid); // Create a resume token from only the timestamp, similar to a 'dropDatabase' entry. diff --git a/src/mongo/db/pipeline/document_source_change_stream_transform.cpp b/src/mongo/db/pipeline/document_source_change_stream_transform.cpp index 95eca6fff47..3598ad97f51 100644 --- a/src/mongo/db/pipeline/document_source_change_stream_transform.cpp +++ b/src/mongo/db/pipeline/document_source_change_stream_transform.cpp @@ -35,7 +35,7 @@ #include "mongo/bson/simple_bsonelement_comparator.h" #include "mongo/db/bson/bson_helper.h" -#include "mongo/db/catalog/uuid_catalog.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/commands/feature_compatibility_version_documentation.h" #include "mongo/db/logical_clock.h" #include "mongo/db/pipeline/change_stream_constants.h" diff --git a/src/mongo/db/pipeline/mongos_process_interface.cpp b/src/mongo/db/pipeline/mongos_process_interface.cpp index 0683a7d4ef9..d8452f4f7eb 100644 --- a/src/mongo/db/pipeline/mongos_process_interface.cpp +++ b/src/mongo/db/pipeline/mongos_process_interface.cpp @@ -32,7 +32,7 @@ #include "mongo/db/pipeline/mongos_process_interface.h" #include "mongo/db/auth/authorization_session.h" -#include "mongo/db/catalog/uuid_catalog.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/curop.h" #include "mongo/db/index/index_descriptor.h" #include "mongo/db/pipeline/document_source.h" diff --git a/src/mongo/db/pipeline/process_interface_shardsvr.cpp b/src/mongo/db/pipeline/process_interface_shardsvr.cpp index 3d54341c325..fe8de93ea71 100644 --- a/src/mongo/db/pipeline/process_interface_shardsvr.cpp +++ b/src/mongo/db/pipeline/process_interface_shardsvr.cpp @@ -35,9 +35,9 @@ #include "mongo/db/auth/authorization_session.h" #include "mongo/db/catalog/collection.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/database_holder.h" #include "mongo/db/catalog/document_validation.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/curop.h" #include "mongo/db/db_raii.h" diff --git a/src/mongo/db/pipeline/process_interface_standalone.cpp b/src/mongo/db/pipeline/process_interface_standalone.cpp index a0d787794f4..a372c51ad93 100644 --- a/src/mongo/db/pipeline/process_interface_standalone.cpp +++ b/src/mongo/db/pipeline/process_interface_standalone.cpp @@ -35,10 +35,10 @@ #include "mongo/db/auth/authorization_session.h" #include "mongo/db/catalog/collection.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/database_holder.h" #include "mongo/db/catalog/document_validation.h" #include "mongo/db/catalog/index_catalog_entry.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/curop.h" #include "mongo/db/cursor_manager.h" diff --git a/src/mongo/db/query/SConscript b/src/mongo/db/query/SConscript index 7a47464da57..b520db9b29a 100644 --- a/src/mongo/db/query/SConscript +++ b/src/mongo/db/query/SConscript @@ -209,7 +209,7 @@ env.Library( LIBDEPS=[ "$BUILD_DIR/mongo/base", "$BUILD_DIR/mongo/db/repl/read_concern_args", - "$BUILD_DIR/mongo/db/catalog/uuid_catalog" + "$BUILD_DIR/mongo/db/catalog/collection_catalog" ], ) diff --git a/src/mongo/db/query/query_request.cpp b/src/mongo/db/query/query_request.cpp index 4dddbb9d361..a8698404ea8 100644 --- a/src/mongo/db/query/query_request.cpp +++ b/src/mongo/db/query/query_request.cpp @@ -34,7 +34,7 @@ #include "mongo/base/status.h" #include "mongo/base/status_with.h" #include "mongo/bson/simple_bsonobj_comparator.h" -#include "mongo/db/catalog/uuid_catalog.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/command_generic_argument.h" #include "mongo/db/commands.h" #include "mongo/db/dbmessage.h" @@ -117,7 +117,7 @@ QueryRequest::QueryRequest(NamespaceStringOrUUID nssOrUuid) void QueryRequest::refreshNSS(OperationContext* opCtx) { if (_uuid) { - const UUIDCatalog& catalog = UUIDCatalog::get(opCtx); + const CollectionCatalog& catalog = CollectionCatalog::get(opCtx); auto foundColl = catalog.lookupCollectionByUUID(_uuid.get()); uassert(ErrorCodes::NamespaceNotFound, str::stream() << "UUID " << _uuid.get() << " specified in query request not found", diff --git a/src/mongo/db/query/query_request.h b/src/mongo/db/query/query_request.h index ec504078a28..c87d9f951e3 100644 --- a/src/mongo/db/query/query_request.h +++ b/src/mongo/db/query/query_request.h @@ -77,8 +77,8 @@ public: /** * If _uuid exists for this QueryRequest, use it to update the value of _nss via the - * UUIDCatalog associated with opCtx. This should only be called when we hold a DBLock - * on the database to which _uuid belongs, if the _uuid is present in the UUIDCatalog. + * CollectionCatalog associated with opCtx. This should only be called when we hold a DBLock + * on the database to which _uuid belongs, if the _uuid is present in the CollectionCatalog. */ void refreshNSS(OperationContext* opCtx); diff --git a/src/mongo/db/query/query_request_test.cpp b/src/mongo/db/query/query_request_test.cpp index 11e7f01863a..3af9d96921e 100644 --- a/src/mongo/db/query/query_request_test.cpp +++ b/src/mongo/db/query/query_request_test.cpp @@ -33,9 +33,9 @@ #include #include +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_catalog_entry_mock.h" #include "mongo/db/catalog/collection_mock.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/dbmessage.h" #include "mongo/db/json.h" #include "mongo/db/namespace_string.h" @@ -1419,12 +1419,12 @@ class QueryRequestTest : public ServiceContextTest {}; TEST_F(QueryRequestTest, ParseFromUUID) { auto opCtx = makeOperationContext(); - // Register a UUID/Collection pair in the UUIDCatalog. + // Register a UUID/Collection pair in the CollectionCatalog. const CollectionUUID uuid = UUID::gen(); const NamespaceString nss("test.testns"); auto coll = std::make_unique(nss); auto catalogEntry = std::make_unique(nss.ns()); - UUIDCatalog& catalog = UUIDCatalog::get(opCtx.get()); + CollectionCatalog& catalog = CollectionCatalog::get(opCtx.get()); catalog.registerCatalogEntry(uuid, std::move(catalogEntry)); catalog.onCreateCollection(opCtx.get(), std::move(coll), uuid); QueryRequest qr(NamespaceStringOrUUID("test", uuid)); diff --git a/src/mongo/db/repair_database.cpp b/src/mongo/db/repair_database.cpp index 3f59866ee74..650dae1636d 100644 --- a/src/mongo/db/repair_database.cpp +++ b/src/mongo/db/repair_database.cpp @@ -41,13 +41,13 @@ #include "mongo/bson/bsonobjbuilder.h" #include "mongo/db/background.h" #include "mongo/db/catalog/collection.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_catalog_entry.h" #include "mongo/db/catalog/database.h" #include "mongo/db/catalog/database_holder.h" #include "mongo/db/catalog/document_validation.h" #include "mongo/db/catalog/index_key_validate.h" #include "mongo/db/catalog/multi_index_block.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/concurrency/write_conflict_exception.h" #include "mongo/db/index/index_descriptor.h" #include "mongo/db/index_builds_coordinator.h" @@ -141,7 +141,7 @@ Status repairCollections(OperationContext* opCtx, const std::string& dbName, stdx::function onRecordStoreRepair) { - auto colls = UUIDCatalog::get(opCtx).getAllCollectionNamesFromDb(opCtx, dbName); + auto colls = CollectionCatalog::get(opCtx).getAllCollectionNamesFromDb(opCtx, dbName); for (const auto& nss : colls) { opCtx->checkForInterrupt(); @@ -159,7 +159,7 @@ Status repairCollections(OperationContext* opCtx, opCtx->checkForInterrupt(); CollectionCatalogEntry* cce = - UUIDCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(nss); + CollectionCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(nss); auto swIndexNameObjs = getIndexNameObjs(opCtx, cce); if (!swIndexNameObjs.isOK()) return swIndexNameObjs.getStatus(); diff --git a/src/mongo/db/repair_database_and_check_version.cpp b/src/mongo/db/repair_database_and_check_version.cpp index 7e3ac75d22f..bc83a173eaf 100644 --- a/src/mongo/db/repair_database_and_check_version.cpp +++ b/src/mongo/db/repair_database_and_check_version.cpp @@ -268,7 +268,7 @@ void rebuildIndexes(OperationContext* opCtx, StorageEngine* storageEngine) { const std::string& indexName = indexNamespace.second; CollectionCatalogEntry* cce = - UUIDCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(collNss); + CollectionCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(collNss); invariant(cce, str::stream() << "couldn't get collection catalog entry for collection " << collNss.toString()); @@ -297,7 +297,7 @@ void rebuildIndexes(OperationContext* opCtx, StorageEngine* storageEngine) { NamespaceString collNss(entry.first); auto collCatalogEntry = - UUIDCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(collNss); + CollectionCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(collNss); for (const auto& indexName : entry.second.first) { log() << "Rebuilding index. Collection: " << collNss << " Index: " << indexName; } diff --git a/src/mongo/db/repl/SConscript b/src/mongo/db/repl/SConscript index c206077d0f5..f849bffbdf6 100644 --- a/src/mongo/db/repl/SConscript +++ b/src/mongo/db/repl/SConscript @@ -46,6 +46,7 @@ env.Library( '$BUILD_DIR/mongo/base', '$BUILD_DIR/mongo/db/background', '$BUILD_DIR/mongo/db/catalog/catalog_helpers', + '$BUILD_DIR/mongo/db/catalog/database_holder', '$BUILD_DIR/mongo/db/commands/feature_compatibility_parsers', '$BUILD_DIR/mongo/db/db_raii', '$BUILD_DIR/mongo/db/dbdirectclient', @@ -289,6 +290,7 @@ env.Library( '$BUILD_DIR/mongo/db/query_exec', ], LIBDEPS_PRIVATE=[ + '$BUILD_DIR/mongo/db/catalog/database_holder', '$BUILD_DIR/mongo/db/logical_clock', ], ) diff --git a/src/mongo/db/repl/dbcheck.cpp b/src/mongo/db/repl/dbcheck.cpp index 81568788519..b2130ae9e2c 100644 --- a/src/mongo/db/repl/dbcheck.cpp +++ b/src/mongo/db/repl/dbcheck.cpp @@ -30,12 +30,12 @@ #include "mongo/platform/basic.h" #include "mongo/bson/simple_bsonelement_comparator.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_catalog_entry.h" #include "mongo/db/catalog/database.h" #include "mongo/db/catalog/database_holder.h" #include "mongo/db/catalog/health_log.h" #include "mongo/db/catalog/index_catalog.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/concurrency/write_conflict_exception.h" #include "mongo/db/db_raii.h" #include "mongo/db/operation_context.h" @@ -240,7 +240,7 @@ std::string hashCollectionInfo(const DbCheckCollectionInformation& info) { std::pair, boost::optional> getPrevAndNextUUIDs( OperationContext* opCtx, Collection* collection) { - const UUIDCatalog& catalog = UUIDCatalog::get(opCtx); + const CollectionCatalog& catalog = CollectionCatalog::get(opCtx); const UUID uuid = *collection->uuid(); std::vector collectionUUIDs = @@ -479,7 +479,7 @@ Status dbCheckDatabaseOnSecondary(OperationContext* opCtx, const DbCheckOplogCollection& entry) { // dbCheckCollectionResult-specific stuff. auto uuid = uassertStatusOK(UUID::parse(entry.getUuid().toString())); - auto collection = UUIDCatalog::get(opCtx).lookupCollectionByUUID(uuid); + auto collection = CollectionCatalog::get(opCtx).lookupCollectionByUUID(uuid); if (!collection) { Status status(ErrorCodes::NamespaceNotFound, "Could not find collection for dbCheck"); diff --git a/src/mongo/db/repl/do_txn.cpp b/src/mongo/db/repl/do_txn.cpp index 109df753fc6..7f0f50787c9 100644 --- a/src/mongo/db/repl/do_txn.cpp +++ b/src/mongo/db/repl/do_txn.cpp @@ -34,10 +34,10 @@ #include "mongo/bson/util/bson_extract.h" #include "mongo/db/catalog/collection.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/database.h" #include "mongo/db/catalog/database_holder.h" #include "mongo/db/catalog/document_validation.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/client.h" #include "mongo/db/concurrency/lock_state.h" #include "mongo/db/concurrency/write_conflict_exception.h" @@ -135,7 +135,7 @@ Status _doTxn(OperationContext* opCtx, auto uuidStatus = UUID::parse(opObj["ui"]); uassertStatusOK(uuidStatus.getStatus()); // If "ui" is present, it overrides "nss" for the collection name. - nss = UUIDCatalog::get(opCtx).lookupNSSByUUID(uuidStatus.getValue()); + nss = CollectionCatalog::get(opCtx).lookupNSSByUUID(uuidStatus.getValue()); uassert(ErrorCodes::NamespaceNotFound, str::stream() << "cannot find collection uuid " << uuidStatus.getValue(), nss); diff --git a/src/mongo/db/repl/drop_pending_collection_reaper_test.cpp b/src/mongo/db/repl/drop_pending_collection_reaper_test.cpp index 4a3b2ffdc55..281b864d0d1 100644 --- a/src/mongo/db/repl/drop_pending_collection_reaper_test.cpp +++ b/src/mongo/db/repl/drop_pending_collection_reaper_test.cpp @@ -31,7 +31,7 @@ #include -#include "mongo/db/catalog/uuid_catalog.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/client.h" #include "mongo/db/jsobj.h" #include "mongo/db/op_observer_registry.h" diff --git a/src/mongo/db/repl/idempotency_test_fixture.cpp b/src/mongo/db/repl/idempotency_test_fixture.cpp index 1422874d999..5c9bfdcd6b5 100644 --- a/src/mongo/db/repl/idempotency_test_fixture.cpp +++ b/src/mongo/db/repl/idempotency_test_fixture.cpp @@ -36,11 +36,11 @@ #include #include "mongo/db/catalog/collection.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_catalog_entry.h" #include "mongo/db/catalog/database.h" #include "mongo/db/catalog/database_holder.h" #include "mongo/db/catalog/index_catalog.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/client.h" #include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/concurrency/write_conflict_exception.h" @@ -541,15 +541,15 @@ std::string IdempotencyTest::computeDataHash(Collection* collection) { std::vector IdempotencyTest::validateAllCollections() { std::vector collStates; - auto& uuidCatalog = UUIDCatalog::get(_opCtx.get()); - auto dbs = uuidCatalog.getAllDbNames(); + auto& catalog = CollectionCatalog::get(_opCtx.get()); + auto dbs = catalog.getAllDbNames(); for (auto& db : dbs) { // Skip local database. if (db != "local") { std::vector collectionNames; { Lock::DBLock lk(_opCtx.get(), db, MODE_S); - collectionNames = uuidCatalog.getAllCollectionNamesFromDb(_opCtx.get(), db); + collectionNames = catalog.getAllCollectionNamesFromDb(_opCtx.get(), db); } for (const auto& nss : collectionNames) { collStates.push_back(validate(nss)); diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp index 9aa26b0bfc6..0a472d04861 100644 --- a/src/mongo/db/repl/oplog.cpp +++ b/src/mongo/db/repl/oplog.cpp @@ -46,6 +46,7 @@ #include "mongo/db/catalog/capped_utils.h" #include "mongo/db/catalog/coll_mod.h" #include "mongo/db/catalog/collection.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_catalog_entry.h" #include "mongo/db/catalog/create_collection.h" #include "mongo/db/catalog/database_holder.h" @@ -53,7 +54,6 @@ #include "mongo/db/catalog/drop_database.h" #include "mongo/db/catalog/drop_indexes.h" #include "mongo/db/catalog/rename_collection.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/client.h" #include "mongo/db/commands.h" #include "mongo/db/commands/feature_compatibility_version_parser.h" @@ -795,7 +795,7 @@ std::pair parseCollModUUIDAndNss(Operat return std::pair(boost::none, parseNs(ns, cmd)); } CollectionUUID uuid = uassertStatusOK(UUID::parse(ui)); - auto& catalog = UUIDCatalog::get(opCtx); + auto& catalog = CollectionCatalog::get(opCtx); const auto nsByUUID = catalog.lookupNSSByUUID(uuid); uassert(ErrorCodes::NamespaceNotFound, str::stream() << "Failed to apply operation due to missing collection (" << uuid @@ -809,7 +809,7 @@ NamespaceString parseUUID(OperationContext* opCtx, const BSONElement& ui) { auto statusWithUUID = UUID::parse(ui); uassertStatusOK(statusWithUUID); auto uuid = statusWithUUID.getValue(); - auto& catalog = UUIDCatalog::get(opCtx); + auto& catalog = CollectionCatalog::get(opCtx); auto nss = catalog.lookupNSSByUUID(uuid); uassert(ErrorCodes::NamespaceNotFound, "No namespace with UUID " + uuid.toString(), nss); return *nss; @@ -1363,7 +1363,7 @@ Status applyOperation_inlock(OperationContext* opCtx, NamespaceString requestNss; Collection* collection = nullptr; if (fieldUI) { - UUIDCatalog& catalog = UUIDCatalog::get(opCtx); + CollectionCatalog& catalog = CollectionCatalog::get(opCtx); auto uuid = uassertStatusOK(UUID::parse(fieldUI)); collection = catalog.lookupCollectionByUUID(uuid); uassert(ErrorCodes::NamespaceNotFound, diff --git a/src/mongo/db/repl/rollback_impl.cpp b/src/mongo/db/repl/rollback_impl.cpp index 678c63cd56e..1b6fd2482fb 100644 --- a/src/mongo/db/repl/rollback_impl.cpp +++ b/src/mongo/db/repl/rollback_impl.cpp @@ -37,8 +37,8 @@ #include "mongo/bson/util/bson_extract.h" #include "mongo/db/background.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/database_holder.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/commands.h" #include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/concurrency/replication_state_transition_lock_guard.h" @@ -500,13 +500,13 @@ StatusWith> RollbackImpl::_namespacesForOp(const Oplog void RollbackImpl::_correctRecordStoreCounts(OperationContext* opCtx) { // This function explicitly does not check for shutdown since a clean shutdown post oplog // truncation is not allowed to occur until the record store counts are corrected. - const auto& uuidCatalog = UUIDCatalog::get(opCtx); + const auto& catalog = CollectionCatalog::get(opCtx); for (const auto& uiCount : _newCounts) { const auto uuid = uiCount.first; - const auto coll = uuidCatalog.lookupCollectionByUUID(uuid); + const auto coll = catalog.lookupCollectionByUUID(uuid); invariant(coll, str::stream() << "The collection with UUID " << uuid - << " is unexpectedly missing in the UUIDCatalog"); + << " is unexpectedly missing in the CollectionCatalog"); const auto nss = coll->ns(); invariant(!nss.isEmpty(), str::stream() << "The collection with UUID " << uuid << " has no namespace."); @@ -576,7 +576,7 @@ Status RollbackImpl::_findRecordStoreCounts(OperationContext* opCtx) { if (_isInShutdown()) { return Status(ErrorCodes::ShutdownInProgress, "rollback shutting down"); } - const auto& uuidCatalog = UUIDCatalog::get(opCtx); + const auto& catalog = CollectionCatalog::get(opCtx); auto storageEngine = opCtx->getServiceContext()->getStorageEngine(); log() << "finding record store counts"; @@ -587,7 +587,7 @@ Status RollbackImpl::_findRecordStoreCounts(OperationContext* opCtx) { continue; } - auto nss = uuidCatalog.lookupNSSByUUID(uuid); + auto nss = catalog.lookupNSSByUUID(uuid); StorageInterface::CollectionCount oldCount = 0; // Drop-pending collections are not visible to rollback via the catalog when they are @@ -595,7 +595,7 @@ Status RollbackImpl::_findRecordStoreCounts(OperationContext* opCtx) { if (!nss) { invariant(storageEngine->supportsPendingDrops(), str::stream() << "The collection with UUID " << uuid - << " is unexpectedly missing in the UUIDCatalog"); + << " is unexpectedly missing in the CollectionCatalog"); auto it = _pendingDrops.find(uuid); if (it == _pendingDrops.end()) { _newCounts[uuid] = kCollectionScanRequired; @@ -1006,25 +1006,25 @@ boost::optional RollbackImpl::_findDocumentById(OperationContext* opCtx } Status RollbackImpl::_writeRollbackFiles(OperationContext* opCtx) { - const auto& uuidCatalog = UUIDCatalog::get(opCtx); + const auto& catalog = CollectionCatalog::get(opCtx); auto storageEngine = opCtx->getServiceContext()->getStorageEngine(); for (auto&& entry : _observerInfo.rollbackDeletedIdsMap) { const auto& uuid = entry.first; - const auto nss = uuidCatalog.lookupNSSByUUID(uuid); + const auto nss = catalog.lookupNSSByUUID(uuid); // Drop-pending collections are not visible to rollback via the catalog when they are // managed by the storage engine. See StorageEngine::supportsPendingDrops(). if (!nss && storageEngine->supportsPendingDrops()) { log() << "The collection with UUID " << uuid - << " is missing in the UUIDCatalog. This could be due to a dropped collection. " - "Not writing rollback file for uuid " + << " is missing in the CollectionCatalog. This could be due to a dropped " + " collection. Not writing rollback file for uuid " << uuid; continue; } invariant(nss, str::stream() << "The collection with UUID " << uuid - << " is unexpectedly missing in the UUIDCatalog"); + << " is unexpectedly missing in the CollectionCatalog"); if (_isInShutdown()) { log() << "Rollback shutting down; not writing rollback file for namespace " << nss->ns() diff --git a/src/mongo/db/repl/rollback_impl_test.cpp b/src/mongo/db/repl/rollback_impl_test.cpp index 042286025c3..328b1f1572d 100644 --- a/src/mongo/db/repl/rollback_impl_test.cpp +++ b/src/mongo/db/repl/rollback_impl_test.cpp @@ -32,9 +32,9 @@ #include +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_mock.h" #include "mongo/db/catalog/drop_collection.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/index/index_descriptor.h" #include "mongo/db/repl/drop_pending_collection_reaper.h" #include "mongo/db/repl/oplog_entry.h" @@ -160,7 +160,8 @@ private: protected: /** * Creates a new mock collection with name 'nss' via the StorageInterface and associates 'uuid' - * with the new collection in the UUIDCatalog. There must not already exist a collection with + * with the new collection in the CollectionCatalog. There must not already exist a collection + * with * name 'nss'. */ std::unique_ptr _initializeCollection(OperationContext* opCtx, @@ -1179,7 +1180,7 @@ TEST_F(RollbackImplTest, RollbackStopsWritingRollbackFilesWhenShutdownIsInProgre DEATH_TEST_F(RollbackImplTest, InvariantFailureIfNamespaceIsMissingWhenWritingRollbackFiles, - "unexpectedly missing in the UUIDCatalog") { + "unexpectedly missing in the CollectionCatalog") { const auto commonOp = makeOpAndRecordId(1); _remoteOplog->setOperations({commonOp}); ASSERT_OK(_insertOplogEntry(commonOp.first)); @@ -1207,7 +1208,7 @@ DEATH_TEST_F(RollbackImplTest, DEATH_TEST_F(RollbackImplTest, InvariantFailureIfNamespaceIsMissingWhenGettingCollectionSizes, - "unexpectedly missing in the UUIDCatalog") { + "unexpectedly missing in the CollectionCatalog") { const auto commonOp = makeOpAndRecordId(1); _remoteOplog->setOperations({commonOp}); ASSERT_OK(_insertOplogEntry(commonOp.first)); diff --git a/src/mongo/db/repl/rs_rollback.cpp b/src/mongo/db/repl/rs_rollback.cpp index 1ae1cae9a82..8d149b03b71 100644 --- a/src/mongo/db/repl/rs_rollback.cpp +++ b/src/mongo/db/repl/rs_rollback.cpp @@ -39,12 +39,12 @@ #include "mongo/bson/bsonelement_comparator.h" #include "mongo/bson/util/bson_extract.h" #include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_catalog_entry.h" #include "mongo/db/catalog/database_holder.h" #include "mongo/db/catalog/document_validation.h" #include "mongo/db/catalog/index_catalog.h" #include "mongo/db/catalog/rename_collection.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/catalog_raii.h" #include "mongo/db/client.h" #include "mongo/db/commands.h" @@ -710,15 +710,15 @@ void dropIndex(OperationContext* opCtx, */ void rollbackCreateIndexes(OperationContext* opCtx, UUID uuid, std::set indexNames) { - boost::optional nss = UUIDCatalog::get(opCtx).lookupNSSByUUID(uuid); + boost::optional nss = CollectionCatalog::get(opCtx).lookupNSSByUUID(uuid); invariant(nss); Lock::DBLock dbLock(opCtx, nss->db(), MODE_X); - Collection* collection = UUIDCatalog::get(opCtx).lookupCollectionByUUID(uuid); + Collection* collection = CollectionCatalog::get(opCtx).lookupCollectionByUUID(uuid); // If we cannot find the collection, we skip over dropping the index. if (!collection) { LOG(2) << "Cannot find the collection with uuid: " << uuid.toString() - << " in UUID catalog during roll back of a createIndexes command."; + << " in CollectionCatalog during roll back of a createIndexes command."; return; } @@ -751,14 +751,14 @@ void rollbackDropIndexes(OperationContext* opCtx, UUID uuid, std::map indexNames) { - boost::optional nss = UUIDCatalog::get(opCtx).lookupNSSByUUID(uuid); + boost::optional nss = CollectionCatalog::get(opCtx).lookupNSSByUUID(uuid); invariant(nss); Lock::DBLock dbLock(opCtx, nss->db(), MODE_X); - Collection* collection = UUIDCatalog::get(opCtx).lookupCollectionByUUID(uuid); + Collection* collection = CollectionCatalog::get(opCtx).lookupCollectionByUUID(uuid); // If we cannot find the collection, we skip over dropping the index. if (!collection) { LOG(2) << "Cannot find the collection with uuid: " << uuid.toString() - << "in UUID catalog during roll back of a dropIndexes command."; + << "in CollectionCatalog during roll back of a dropIndexes command."; return; } @@ -1040,7 +1040,7 @@ void rollback_internal::syncFixUp(OperationContext* opCtx, // UUID -> doc id -> doc stdx::unordered_map, UUID::Hash> goodVersions; - auto& catalog = UUIDCatalog::get(opCtx); + auto& catalog = CollectionCatalog::get(opCtx); // Fetches all the goodVersions of each document from the current sync source. unsigned long long numFetched = 0; @@ -1166,7 +1166,7 @@ void rollback_internal::syncFixUp(OperationContext* opCtx, invariant(!fixUpInfo.collectionsToRename.count(uuid)); invariant(!fixUpInfo.collectionsToResyncMetadata.count(uuid)); - boost::optional nss = UUIDCatalog::get(opCtx).lookupNSSByUUID(uuid); + boost::optional nss = CollectionCatalog::get(opCtx).lookupNSSByUUID(uuid); // Do not attempt to acquire the database lock with an empty namespace. We should survive // an attempt to drop a non-existent collection. if (!nss) { @@ -1177,7 +1177,7 @@ void rollback_internal::syncFixUp(OperationContext* opCtx, Database* db = dbLock.getDb(); if (db) { - Collection* collection = UUIDCatalog::get(opCtx).lookupCollectionByUUID(uuid); + Collection* collection = CollectionCatalog::get(opCtx).lookupCollectionByUUID(uuid); dropCollection(opCtx, *nss, collection, db); LOG(1) << "Dropped collection: " << *nss << ", UUID: " << uuid; } @@ -1224,7 +1224,8 @@ void rollback_internal::syncFixUp(OperationContext* opCtx, // occurs and then the collection is dropped. If we do not first re-create the // collection, we will not be able to retrieve the collection's catalog entries. for (auto uuid : fixUpInfo.collectionsToResyncMetadata) { - boost::optional nss = UUIDCatalog::get(opCtx).lookupNSSByUUID(uuid); + boost::optional nss = + CollectionCatalog::get(opCtx).lookupNSSByUUID(uuid); invariant(nss); log() << "Resyncing collection metadata for collection: " << *nss << ", UUID: " << uuid; @@ -1235,7 +1236,7 @@ void rollback_internal::syncFixUp(OperationContext* opCtx, auto db = databaseHolder->openDb(opCtx, nss->db().toString()); invariant(db); - Collection* collection = UUIDCatalog::get(opCtx).lookupCollectionByUUID(uuid); + Collection* collection = CollectionCatalog::get(opCtx).lookupCollectionByUUID(uuid); invariant(collection); auto cce = collection->getCatalogEntry(); diff --git a/src/mongo/db/repl/rs_rollback_test.cpp b/src/mongo/db/repl/rs_rollback_test.cpp index acf1bf40d8b..88931143977 100644 --- a/src/mongo/db/repl/rs_rollback_test.cpp +++ b/src/mongo/db/repl/rs_rollback_test.cpp @@ -34,11 +34,11 @@ #include #include +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_catalog_entry.h" #include "mongo/db/catalog/database_holder.h" #include "mongo/db/catalog/drop_indexes.h" #include "mongo/db/catalog/index_catalog.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/client.h" #include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/db_raii.h" diff --git a/src/mongo/db/repl/storage_interface_impl.cpp b/src/mongo/db/repl/storage_interface_impl.cpp index 44c2904ba1d..7bb1dfc9ab1 100644 --- a/src/mongo/db/repl/storage_interface_impl.cpp +++ b/src/mongo/db/repl/storage_interface_impl.cpp @@ -46,11 +46,11 @@ #include "mongo/db/auth/authorization_manager.h" #include "mongo/db/catalog/coll_mod.h" #include "mongo/db/catalog/collection.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_catalog_entry.h" #include "mongo/db/catalog/database_holder.h" #include "mongo/db/catalog/document_validation.h" #include "mongo/db/catalog/index_catalog.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/client.h" #include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/concurrency/write_conflict_exception.h" diff --git a/src/mongo/db/repl/sync_tail.cpp b/src/mongo/db/repl/sync_tail.cpp index ed9ebf77454..a3dcb97e410 100644 --- a/src/mongo/db/repl/sync_tail.cpp +++ b/src/mongo/db/repl/sync_tail.cpp @@ -41,10 +41,10 @@ #include "mongo/bson/bsonelement_comparator.h" #include "mongo/bson/timestamp.h" #include "mongo/db/catalog/collection.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/database.h" #include "mongo/db/catalog/database_holder.h" #include "mongo/db/catalog/document_validation.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/catalog_raii.h" #include "mongo/db/client.h" #include "mongo/db/commands/fsync.h" @@ -219,7 +219,7 @@ NamespaceString parseUUIDOrNs(OperationContext* opCtx, const OplogEntry& oplogEn } const auto& uuid = optionalUuid.get(); - auto& catalog = UUIDCatalog::get(opCtx); + auto& catalog = CollectionCatalog::get(opCtx); auto nss = catalog.lookupNSSByUUID(uuid); uassert(ErrorCodes::NamespaceNotFound, str::stream() << "No namespace with UUID " << uuid.toString(), @@ -992,7 +992,7 @@ void SyncTail::fetchAndInsertMissingDocument(OperationContext* opCtx, } else { // If the oplog entry has a UUID, use it to find the collection in which to insert the // missing document. - auto& catalog = UUIDCatalog::get(opCtx); + auto& catalog = CollectionCatalog::get(opCtx); coll = catalog.lookupCollectionByUUID(*uuid); if (!coll) { // TODO(SERVER-30819) insert this UUID into the missing UUIDs set. diff --git a/src/mongo/db/service_context_d_test_fixture.cpp b/src/mongo/db/service_context_d_test_fixture.cpp index 903520968a3..9f12ca6ea41 100644 --- a/src/mongo/db/service_context_d_test_fixture.cpp +++ b/src/mongo/db/service_context_d_test_fixture.cpp @@ -35,8 +35,8 @@ #include "mongo/base/checked_cast.h" #include "mongo/db/catalog/catalog_control.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/database_holder_impl.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/index_builds_coordinator_mongod.h" #include "mongo/db/logical_clock.h" diff --git a/src/mongo/db/storage/kv/SConscript b/src/mongo/db/storage/kv/SConscript index 77505aa4747..09c485f28c3 100644 --- a/src/mongo/db/storage/kv/SConscript +++ b/src/mongo/db/storage/kv/SConscript @@ -26,7 +26,7 @@ env.Library( '$BUILD_DIR/mongo/db/index_names', '$BUILD_DIR/mongo/db/namespace_string', '$BUILD_DIR/mongo/db/storage/bson_collection_catalog_entry', - '$BUILD_DIR/mongo/db/catalog/uuid_catalog', + '$BUILD_DIR/mongo/db/catalog/collection_catalog', 'kv_drop_pending_ident_reaper', 'kv_prefix', ], @@ -60,7 +60,7 @@ env.Library( LIBDEPS_PRIVATE=[ '$BUILD_DIR/mongo/db/logical_clock', '$BUILD_DIR/mongo/db/storage/storage_repair_observer', - '$BUILD_DIR/mongo/db/catalog/uuid_catalog_helper', + '$BUILD_DIR/mongo/db/catalog/collection_catalog_helper', ], ) diff --git a/src/mongo/db/storage/kv/kv_catalog.cpp b/src/mongo/db/storage/kv/kv_catalog.cpp index d63fe3a56a5..d268f64394e 100644 --- a/src/mongo/db/storage/kv/kv_catalog.cpp +++ b/src/mongo/db/storage/kv/kv_catalog.cpp @@ -35,7 +35,7 @@ #include "mongo/bson/util/bson_extract.h" #include "mongo/bson/util/builder.h" -#include "mongo/db/catalog/uuid_catalog.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/namespace_string.h" #include "mongo/db/operation_context.h" @@ -729,15 +729,15 @@ void KVCatalog::initCollection(OperationContext* opCtx, invariant(rs); } - UUIDCatalog::get(getGlobalServiceContext()) + CollectionCatalog::get(getGlobalServiceContext()) .registerCatalogEntry(uuid, std::make_unique( _engine, this, nss.ns(), ident, std::move(rs))); } void KVCatalog::reinitCollectionAfterRepair(OperationContext* opCtx, const NamespaceString& nss) { - auto& uuidCatalog = UUIDCatalog::get(getGlobalServiceContext()); - uuidCatalog.deregisterCatalogEntry(uuidCatalog.lookupUUIDByNSS(nss).get()); + auto& catalog = CollectionCatalog::get(getGlobalServiceContext()); + catalog.deregisterCatalogEntry(catalog.lookupUUIDByNSS(nss).get()); initCollection(opCtx, nss, false); } @@ -748,7 +748,7 @@ Status KVCatalog::createCollection(OperationContext* opCtx, invariant(opCtx->lockState()->isDbLockedForMode(nss.db(), MODE_IX)); invariant(nss.coll().size() > 0); - if (UUIDCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(nss)) { + if (CollectionCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(nss)) { return Status(ErrorCodes::NamespaceExists, str::stream() << "collection already exists " << nss); } @@ -780,13 +780,13 @@ Status KVCatalog::createCollection(OperationContext* opCtx, // Intentionally ignoring failure catalog->_engine->getEngine()->dropIdent(opCtx, ident).ignore(); - UUIDCatalog::get(opCtx).deregisterCatalogEntry(uuid); + CollectionCatalog::get(opCtx).deregisterCatalogEntry(uuid); }); auto rs = _engine->getEngine()->getGroupedRecordStore(opCtx, nss.ns(), ident, options, prefix); invariant(rs); - UUIDCatalog::get(getGlobalServiceContext()) + CollectionCatalog::get(getGlobalServiceContext()) .registerCatalogEntry(uuid, std::make_unique( _engine, this, nss.ns(), ident, std::move(rs))); @@ -820,10 +820,10 @@ Status KVCatalog::renameCollection(OperationContext* opCtx, class KVCatalog::FinishDropCatalogEntryChange : public RecoveryUnit::Change { public: - FinishDropCatalogEntryChange(UUIDCatalog& uuidCatalog, + FinishDropCatalogEntryChange(CollectionCatalog& catalog, std::unique_ptr collectionCatalogEntry, CollectionUUID uuid) - : _uuidCatalog(uuidCatalog), + : _catalog(catalog), _collectionCatalogEntry(std::move(collectionCatalogEntry)), _uuid(uuid) {} @@ -832,11 +832,11 @@ public: } void rollback() override { - _uuidCatalog.registerCatalogEntry(_uuid, std::move(_collectionCatalogEntry)); + _catalog.registerCatalogEntry(_uuid, std::move(_collectionCatalogEntry)); } private: - UUIDCatalog& _uuidCatalog; + CollectionCatalog& _catalog; std::unique_ptr _collectionCatalogEntry; CollectionUUID _uuid; }; @@ -845,13 +845,13 @@ Status KVCatalog::dropCollection(OperationContext* opCtx, const NamespaceString& invariant(opCtx->lockState()->isCollectionLockedForMode(nss, MODE_X)); CollectionCatalogEntry* const entry = - UUIDCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(nss); + CollectionCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(nss); if (!entry) { return Status(ErrorCodes::NamespaceNotFound, "cannnot find collection to drop"); } - auto& uuidCatalog = UUIDCatalog::get(opCtx); - auto uuid = uuidCatalog.lookupUUIDByNSS(nss); + auto& catalog = CollectionCatalog::get(opCtx); + auto uuid = catalog.lookupUUIDByNSS(nss); invariant(entry->getTotalIndexCount(opCtx) == entry->getCompletedIndexCount(opCtx)); @@ -875,10 +875,10 @@ Status KVCatalog::dropCollection(OperationContext* opCtx, const NamespaceString& // Remove catalog entry std::unique_ptr removedCatalogEntry = - UUIDCatalog::get(opCtx).deregisterCatalogEntry(uuid.get()); + CollectionCatalog::get(opCtx).deregisterCatalogEntry(uuid.get()); opCtx->recoveryUnit()->registerChange(new FinishDropCatalogEntryChange( - UUIDCatalog::get(opCtx), std::move(removedCatalogEntry), uuid.get())); + CollectionCatalog::get(opCtx), std::move(removedCatalogEntry), uuid.get())); // This will lazily delete the KVCollectionCatalogEntry and notify the storageEngine to // drop the collection only on WUOW::commit(). diff --git a/src/mongo/db/storage/kv/kv_collection_catalog_entry.cpp b/src/mongo/db/storage/kv/kv_collection_catalog_entry.cpp index 7c63a745530..70457522913 100644 --- a/src/mongo/db/storage/kv/kv_collection_catalog_entry.cpp +++ b/src/mongo/db/storage/kv/kv_collection_catalog_entry.cpp @@ -35,7 +35,7 @@ #include -#include "mongo/db/catalog/uuid_catalog.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/index/index_descriptor.h" #include "mongo/db/storage/kv/kv_catalog.h" #include "mongo/db/storage/kv/kv_catalog_feature_tracker.h" diff --git a/src/mongo/db/storage/kv/kv_collection_catalog_entry_test.cpp b/src/mongo/db/storage/kv/kv_collection_catalog_entry_test.cpp index 315576dd011..c4eee897176 100644 --- a/src/mongo/db/storage/kv/kv_collection_catalog_entry_test.cpp +++ b/src/mongo/db/storage/kv/kv_collection_catalog_entry_test.cpp @@ -33,8 +33,8 @@ #include #include +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_catalog_entry.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/index/index_descriptor.h" #include "mongo/db/index/multikey_paths.h" #include "mongo/db/index_names.h" @@ -90,7 +90,7 @@ public: } CollectionCatalogEntry* getCollectionCatalogEntry() { - return UUIDCatalog::get(getGlobalServiceContext()) + return CollectionCatalog::get(getGlobalServiceContext()) .lookupCollectionCatalogEntryByNamespace(_nss); } diff --git a/src/mongo/db/storage/kv/kv_storage_engine.cpp b/src/mongo/db/storage/kv/kv_storage_engine.cpp index f0a1fb6dc96..d922f598d8e 100644 --- a/src/mongo/db/storage/kv/kv_storage_engine.cpp +++ b/src/mongo/db/storage/kv/kv_storage_engine.cpp @@ -36,8 +36,8 @@ #include #include "mongo/db/catalog/catalog_control.h" -#include "mongo/db/catalog/uuid_catalog.h" -#include "mongo/db/catalog/uuid_catalog_helper.h" +#include "mongo/db/catalog/collection_catalog.h" +#include "mongo/db/catalog/collection_catalog_helper.h" #include "mongo/db/client.h" #include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/logical_clock.h" @@ -241,7 +241,7 @@ void KVStorageEngine::closeCatalog(OperationContext* opCtx) { LOG_FOR_RECOVERY(kCatalogLogLevel) << "loadCatalog:"; _dumpCatalog(opCtx); } - UUIDCatalog::get(opCtx).deregisterAllCatalogEntriesAndCollectionObjects(); + CollectionCatalog::get(opCtx).deregisterAllCatalogEntriesAndCollectionObjects(); _catalog.reset(); _catalogRecordStore.reset(); @@ -485,7 +485,8 @@ void KVStorageEngine::cleanShutdown() { _timestampMonitor->removeListener(&_minOfCheckpointAndOldestTimestampListener); } - UUIDCatalog::get(getGlobalServiceContext()).deregisterAllCatalogEntriesAndCollectionObjects(); + CollectionCatalog::get(getGlobalServiceContext()) + .deregisterAllCatalogEntriesAndCollectionObjects(); _catalog.reset(); _catalogRecordStore.reset(); @@ -516,7 +517,7 @@ RecoveryUnit* KVStorageEngine::newRecoveryUnit() { } std::vector KVStorageEngine::listDatabases() const { - return UUIDCatalog::get(getGlobalServiceContext()).getAllDbNames(); + return CollectionCatalog::get(getGlobalServiceContext()).getAllDbNames(); } Status KVStorageEngine::closeDatabase(OperationContext* opCtx, StringData db) { @@ -526,14 +527,14 @@ Status KVStorageEngine::closeDatabase(OperationContext* opCtx, StringData db) { Status KVStorageEngine::dropDatabase(OperationContext* opCtx, StringData db) { { - auto dbs = UUIDCatalog::get(opCtx).getAllDbNames(); + auto dbs = CollectionCatalog::get(opCtx).getAllDbNames(); if (std::count(dbs.begin(), dbs.end(), db.toString()) == 0) { return Status(ErrorCodes::NamespaceNotFound, "db not found to drop"); } } std::vector toDrop = - UUIDCatalog::get(opCtx).getAllCollectionNamesFromDb(opCtx, db); + CollectionCatalog::get(opCtx).getAllCollectionNamesFromDb(opCtx, db); // Do not timestamp any of the following writes. This will remove entries from the catalog as // well as drop any underlying tables. It's not expected for dropping tables to be reversible diff --git a/src/mongo/db/storage/kv/kv_storage_engine_test_fixture.h b/src/mongo/db/storage/kv/kv_storage_engine_test_fixture.h index d530ebb4922..2b704e7b4e5 100644 --- a/src/mongo/db/storage/kv/kv_storage_engine_test_fixture.h +++ b/src/mongo/db/storage/kv/kv_storage_engine_test_fixture.h @@ -29,7 +29,7 @@ #pragma once -#include "mongo/db/catalog/uuid_catalog.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog_raii.h" #include "mongo/db/service_context_d_test_fixture.h" #include "mongo/db/storage/kv/kv_catalog.h" @@ -134,7 +134,7 @@ public: stdx::make_unique(coll, IndexNames::findPluginName(spec), spec); CollectionCatalogEntry* cce = - UUIDCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(collNs); + CollectionCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(collNs); const auto protocol = IndexBuildProtocol::kTwoPhase; auto ret = cce->prepareForIndexBuild( opCtx, descriptor.get(), protocol, isBackgroundSecondaryBuild); @@ -147,19 +147,19 @@ public: std::string sideWritesIdent, std::string constraintViolationsIdent) { CollectionCatalogEntry* cce = - UUIDCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(collNs); + CollectionCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(collNs); cce->setIndexBuildScanning(opCtx, key, sideWritesIdent, constraintViolationsIdent); } void indexBuildDrain(OperationContext* opCtx, NamespaceString collNs, std::string key) { CollectionCatalogEntry* cce = - UUIDCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(collNs); + CollectionCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(collNs); cce->setIndexBuildDraining(opCtx, key); } void indexBuildSuccess(OperationContext* opCtx, NamespaceString collNs, std::string key) { CollectionCatalogEntry* cce = - UUIDCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(collNs); + CollectionCatalog::get(opCtx).lookupCollectionCatalogEntryByNamespace(collNs); cce->indexBuildSuccess(opCtx, key); } diff --git a/src/mongo/db/storage/wiredtiger/SConscript b/src/mongo/db/storage/wiredtiger/SConscript index f14ad099ec9..70f57dc349c 100644 --- a/src/mongo/db/storage/wiredtiger/SConscript +++ b/src/mongo/db/storage/wiredtiger/SConscript @@ -106,6 +106,7 @@ if wiredtiger: '$BUILD_DIR/mongo/db/storage/storage_engine_metadata', ], LIBDEPS_PRIVATE=[ + '$BUILD_DIR/mongo/db/catalog/database_holder', '$BUILD_DIR/mongo/db/commands/server_status', '$BUILD_DIR/mongo/db/concurrency/lock_manager', '$BUILD_DIR/mongo/db/storage/storage_engine_common', diff --git a/src/mongo/db/transaction_participant.cpp b/src/mongo/db/transaction_participant.cpp index 6f22faf4cf1..43e4dc37233 100644 --- a/src/mongo/db/transaction_participant.cpp +++ b/src/mongo/db/transaction_participant.cpp @@ -1023,7 +1023,7 @@ Timestamp TransactionParticipant::Participant::prepareTransaction( transactionOperationUuids.insert(transactionOp.getUuid().get()); } for (const auto& uuid : transactionOperationUuids) { - auto collection = UUIDCatalog::get(opCtx).lookupCollectionByUUID(uuid); + auto collection = CollectionCatalog::get(opCtx).lookupCollectionByUUID(uuid); uassert(ErrorCodes::OperationNotSupportedInTransaction, str::stream() << "prepareTransaction failed because one of the transaction " "operations was done against a temporary collection '" diff --git a/src/mongo/db/views/SConscript b/src/mongo/db/views/SConscript index 2636109617b..d22244dfacd 100644 --- a/src/mongo/db/views/SConscript +++ b/src/mongo/db/views/SConscript @@ -13,6 +13,9 @@ env.Library( '$BUILD_DIR/mongo/db/dbhelpers', '$BUILD_DIR/mongo/db/views/views', ], + LIBDEPS_PRIVATE=[ + '$BUILD_DIR/mongo/db/catalog/database_holder', + ], ) env.Library( diff --git a/src/mongo/dbtests/framework.cpp b/src/mongo/dbtests/framework.cpp index df04db41b04..30cf5b64262 100644 --- a/src/mongo/dbtests/framework.cpp +++ b/src/mongo/dbtests/framework.cpp @@ -37,8 +37,8 @@ #include "mongo/base/checked_cast.h" #include "mongo/base/status.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/database_holder_impl.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/client.h" #include "mongo/db/concurrency/lock_state.h" #include "mongo/db/dbdirectclient.h" diff --git a/src/mongo/dbtests/rollbacktests.cpp b/src/mongo/dbtests/rollbacktests.cpp index c91b941632d..499661fe8ed 100644 --- a/src/mongo/dbtests/rollbacktests.cpp +++ b/src/mongo/dbtests/rollbacktests.cpp @@ -63,8 +63,8 @@ void dropDatabase(OperationContext* opCtx, const NamespaceString& nss) { } bool collectionExists(OperationContext* opCtx, OldClientContext* ctx, const string& ns) { auto nss = NamespaceString(ns); - std::vector collections = - UUIDCatalog::get(getGlobalServiceContext()).getAllCollectionNamesFromDb(opCtx, nss.db()); + std::vector collections = CollectionCatalog::get(getGlobalServiceContext()) + .getAllCollectionNamesFromDb(opCtx, nss.db()); return std::count(collections.begin(), collections.end(), nss) > 0; } diff --git a/src/mongo/dbtests/storage_timestamp_tests.cpp b/src/mongo/dbtests/storage_timestamp_tests.cpp index e83430fb809..6a7823ef75f 100644 --- a/src/mongo/dbtests/storage_timestamp_tests.cpp +++ b/src/mongo/dbtests/storage_timestamp_tests.cpp @@ -34,12 +34,12 @@ #include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/bson/timestamp.h" #include "mongo/db/catalog/collection.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/create_collection.h" #include "mongo/db/catalog/drop_database.h" #include "mongo/db/catalog/drop_indexes.h" #include "mongo/db/catalog/index_catalog.h" #include "mongo/db/catalog/multi_index_block.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/client.h" #include "mongo/db/concurrency/write_conflict_exception.h" #include "mongo/db/db_raii.h" diff --git a/src/mongo/embedded/embedded.cpp b/src/mongo/embedded/embedded.cpp index 999909c2b03..13e9d4ddc75 100644 --- a/src/mongo/embedded/embedded.cpp +++ b/src/mongo/embedded/embedded.cpp @@ -35,10 +35,10 @@ #include "mongo/base/initializer.h" #include "mongo/config.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/database_holder_impl.h" #include "mongo/db/catalog/health_log.h" #include "mongo/db/catalog/index_key_validate.h" -#include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/client.h" #include "mongo/db/commands/feature_compatibility_version.h" #include "mongo/db/commands/fsync_locked.h" diff --git a/src/mongo/embedded/index_builds_coordinator_embedded.cpp b/src/mongo/embedded/index_builds_coordinator_embedded.cpp index f6fb6544017..110838b6dcc 100644 --- a/src/mongo/embedded/index_builds_coordinator_embedded.cpp +++ b/src/mongo/embedded/index_builds_coordinator_embedded.cpp @@ -33,7 +33,7 @@ #include "mongo/embedded/index_builds_coordinator_embedded.h" -#include "mongo/db/catalog/uuid_catalog.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/operation_context.h" #include "mongo/db/service_context.h" #include "mongo/util/log.h" -- cgit v1.2.1