diff options
author | Will Buerger <will.buerger@mongodb.com> | 2022-12-05 20:20:13 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-12-05 22:13:32 +0000 |
commit | cf7c956c0dcf283f8c5442eec3cb31cc1ada2d4a (patch) | |
tree | 95eece715f47ee14137b6a733fbdbe1fc8685677 | |
parent | 8d700b6a9b12f9951b535517bd2d80c610194f08 (diff) | |
download | mongo-cf7c956c0dcf283f8c5442eec3cb31cc1ada2d4a.tar.gz |
SERVER-71644: Avoid parsing durable catalog entry when we only need to compare as BSON
-rw-r--r-- | src/mongo/db/catalog/collection.h | 2 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection_catalog.cpp | 19 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection_catalog_test.cpp | 7 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection_impl.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection_impl.h | 2 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection_mock.h | 2 | ||||
-rw-r--r-- | src/mongo/db/catalog/virtual_collection_impl.h | 2 | ||||
-rw-r--r-- | src/mongo/db/storage/durable_catalog.h | 15 |
8 files changed, 37 insertions, 17 deletions
diff --git a/src/mongo/db/catalog/collection.h b/src/mongo/db/catalog/collection.h index 6e76150d554..75595c5fdaa 100644 --- a/src/mongo/db/catalog/collection.h +++ b/src/mongo/db/catalog/collection.h @@ -559,7 +559,7 @@ public: virtual void replaceMetadata(OperationContext* opCtx, std::shared_ptr<BSONCollectionCatalogEntry::MetaData> md) = 0; - virtual bool isMetadataEqual(const BSONCollectionCatalogEntry::MetaData& md) const = 0; + virtual bool isMetadataEqual(const BSONObj& otherMetadata) const = 0; /** * Specifies whether writes to this collection should X-lock the metadata resource. It is only diff --git a/src/mongo/db/catalog/collection_catalog.cpp b/src/mongo/db/catalog/collection_catalog.cpp index 2c936194ca6..28453d2c900 100644 --- a/src/mongo/db/catalog/collection_catalog.cpp +++ b/src/mongo/db/catalog/collection_catalog.cpp @@ -793,22 +793,27 @@ CollectionPtr CollectionCatalog::openCollection(OperationContext* opCtx, catalogId = lookupResult.id; } - auto catalogEntry = DurableCatalog::get(opCtx)->getParsedCatalogEntry(opCtx, catalogId); - if (!catalogEntry || nss != catalogEntry->metadata->nss) { + auto catalogEntry = DurableCatalog::get(opCtx)->getCatalogEntry(opCtx, catalogId); + if (catalogEntry.isEmpty() || + nss != DurableCatalog::getNamespaceFromCatalogEntry(catalogEntry)) { return CollectionPtr(); } - auto latestCollection = _lookupCollectionByUUID(*catalogEntry->metadata->options.uuid); + + auto latestCollection = lookupCollectionByNamespaceForRead(opCtx, nss); + auto metadata = DurableCatalog::getMetadataFromCatalogEntry(catalogEntry); // Use the pendingCollection if there is no latestCollection or if the metadata of the // latestCollection doesn't match the durable catalogEntry. - if (!latestCollection || !latestCollection->isMetadataEqual(*catalogEntry->metadata)) { - invariant(pendingCollection->isMetadataEqual(*catalogEntry->metadata)); + if (!latestCollection || !latestCollection->isMetadataEqual(metadata)) { + invariant(pendingCollection->isMetadataEqual(metadata)); uncommittedCatalogUpdates.openCollection(opCtx, pendingCollection); return CollectionPtr(pendingCollection.get(), CollectionPtr::NoYieldTag{}); } - invariant(latestCollection->isMetadataEqual(*catalogEntry->metadata)); - uncommittedCatalogUpdates.openCollection(opCtx, latestCollection); + invariant(latestCollection->isMetadataEqual(metadata)); + // TODO SERVER-71817 remove const cast + uncommittedCatalogUpdates.openCollection( + opCtx, std::const_pointer_cast<Collection>(latestCollection)); return CollectionPtr(latestCollection.get(), CollectionPtr::NoYieldTag{}); } diff --git a/src/mongo/db/catalog/collection_catalog_test.cpp b/src/mongo/db/catalog/collection_catalog_test.cpp index d701426fd8c..496bac3b10e 100644 --- a/src/mongo/db/catalog/collection_catalog_test.cpp +++ b/src/mongo/db/catalog/collection_catalog_test.cpp @@ -1204,9 +1204,10 @@ private: ASSERT_EQ(coll->getIndexCatalog()->numIndexesTotal(), expectedNumIndexes); auto catalogEntry = - DurableCatalog::get(opCtx)->getParsedCatalogEntry(opCtx, coll->getCatalogId()); - ASSERT(catalogEntry); - ASSERT(coll->isMetadataEqual(*catalogEntry->metadata.get())); + DurableCatalog::get(opCtx)->getCatalogEntry(opCtx, coll->getCatalogId()); + ASSERT(!catalogEntry.isEmpty()); + ASSERT( + coll->isMetadataEqual(DurableCatalog::getMetadataFromCatalogEntry(catalogEntry))); } else { ASSERT(!coll); auto catalogEntry = DurableCatalog::get(opCtx)->scanForCatalogEntryByNss(opCtx, nss); diff --git a/src/mongo/db/catalog/collection_impl.cpp b/src/mongo/db/catalog/collection_impl.cpp index 22e78c3e8c4..c5d39ff8723 100644 --- a/src/mongo/db/catalog/collection_impl.cpp +++ b/src/mongo/db/catalog/collection_impl.cpp @@ -1771,9 +1771,8 @@ void CollectionImpl::replaceMetadata(OperationContext* opCtx, _metadata = std::move(md); } -bool CollectionImpl::isMetadataEqual( - const BSONCollectionCatalogEntry::MetaData& otherMetadata) const { - return !_metadata->toBSON().woCompare(otherMetadata.toBSON()); +bool CollectionImpl::isMetadataEqual(const BSONObj& otherMetadata) const { + return !_metadata->toBSON().woCompare(otherMetadata); } template <typename Func> diff --git a/src/mongo/db/catalog/collection_impl.h b/src/mongo/db/catalog/collection_impl.h index d50462158a2..fd1c854bbce 100644 --- a/src/mongo/db/catalog/collection_impl.h +++ b/src/mongo/db/catalog/collection_impl.h @@ -368,7 +368,7 @@ public: void replaceMetadata(OperationContext* opCtx, std::shared_ptr<BSONCollectionCatalogEntry::MetaData> md) final; - bool isMetadataEqual(const BSONCollectionCatalogEntry::MetaData& md) const final; + bool isMetadataEqual(const BSONObj& otherMetadata) const final; bool needsCappedLock() const final; diff --git a/src/mongo/db/catalog/collection_mock.h b/src/mongo/db/catalog/collection_mock.h index b1343d38c87..4cc17cf983a 100644 --- a/src/mongo/db/catalog/collection_mock.h +++ b/src/mongo/db/catalog/collection_mock.h @@ -437,7 +437,7 @@ public: MONGO_UNREACHABLE; } - bool isMetadataEqual(const BSONCollectionCatalogEntry::MetaData& md) const { + bool isMetadataEqual(const BSONObj& otherMetadata) const { MONGO_UNREACHABLE; } diff --git a/src/mongo/db/catalog/virtual_collection_impl.h b/src/mongo/db/catalog/virtual_collection_impl.h index 0f4f14a5c56..d45b46bd380 100644 --- a/src/mongo/db/catalog/virtual_collection_impl.h +++ b/src/mongo/db/catalog/virtual_collection_impl.h @@ -374,7 +374,7 @@ public: unimplementedTasserted(); } - bool isMetadataEqual(const BSONCollectionCatalogEntry::MetaData& md) const final { + bool isMetadataEqual(const BSONObj& otherMetadata) const final { unimplementedTasserted(); return false; } diff --git a/src/mongo/db/storage/durable_catalog.h b/src/mongo/db/storage/durable_catalog.h index 8c45922b95b..5167a8d681b 100644 --- a/src/mongo/db/storage/durable_catalog.h +++ b/src/mongo/db/storage/durable_catalog.h @@ -84,6 +84,21 @@ public: return false; } + /** + * Gets the parsed namespace from a raw BSON catalog entry. + */ + static NamespaceString getNamespaceFromCatalogEntry(const BSONObj& catalogEntry) { + return NamespaceString::parseFromStringExpectTenantIdInMultitenancyMode( + catalogEntry["ns"].checkAndGetStringData()); + } + + /** + * Gets the metadata as BSON from a raw BSON catalog entry. + */ + static BSONObj getMetadataFromCatalogEntry(const BSONObj& catalogEntry) { + return catalogEntry["md"].Obj(); + } + virtual void init(OperationContext* opCtx) = 0; virtual std::vector<EntryIdentifier> getAllCatalogEntries(OperationContext* opCtx) const = 0; |