diff options
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/catalog/catalog_control.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection_impl.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/repl/storage_timestamp_test.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/storage/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/storage/bson_collection_catalog_entry.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/storage/bson_collection_catalog_entry.h | 2 | ||||
-rw-r--r-- | src/mongo/db/storage/durable_catalog_impl.cpp | 24 | ||||
-rw-r--r-- | src/mongo/db/storage/kv/durable_catalog_test.cpp | 22 | ||||
-rw-r--r-- | src/mongo/db/storage/kv/kv_engine_test_harness.cpp | 65 | ||||
-rw-r--r-- | src/mongo/db/storage/storage_engine_impl.cpp | 2 |
10 files changed, 108 insertions, 26 deletions
diff --git a/src/mongo/db/catalog/catalog_control.cpp b/src/mongo/db/catalog/catalog_control.cpp index 6d653b29e36..b20abdc4c87 100644 --- a/src/mongo/db/catalog/catalog_control.cpp +++ b/src/mongo/db/catalog/catalog_control.cpp @@ -203,7 +203,7 @@ void openCatalog(OperationContext* opCtx, // Determine which indexes need to be rebuilt. rebuildIndexesOnCollection() requires that all // indexes on that collection are done at once, so we use a map to group them together. - StringMap<IndexNameObjs> nsToIndexNameObjMap; + stdx::unordered_map<NamespaceString, IndexNameObjs> nsToIndexNameObjMap; auto catalog = CollectionCatalog::get(opCtx); for (StorageEngine::IndexIdentifier indexIdentifier : reconcileResult.indexesToRebuild) { auto indexName = indexIdentifier.indexName; @@ -226,7 +226,7 @@ void openCatalog(OperationContext* opCtx, str::stream() << "expected to find a list containing exactly 1 index spec, but found " << indexesToRebuild.second.size()); - auto& ino = nsToIndexNameObjMap[indexIdentifier.nss.ns()]; + auto& ino = nsToIndexNameObjMap[indexIdentifier.nss]; ino.first.emplace_back(std::move(indexesToRebuild.first.back())); ino.second.emplace_back(std::move(indexesToRebuild.second.back())); } diff --git a/src/mongo/db/catalog/collection_impl.cpp b/src/mongo/db/catalog/collection_impl.cpp index 8ee5bf51518..2f1f87f6633 100644 --- a/src/mongo/db/catalog/collection_impl.cpp +++ b/src/mongo/db/catalog/collection_impl.cpp @@ -2030,7 +2030,7 @@ std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> CollectionImpl::makePlanExe Status CollectionImpl::rename(OperationContext* opCtx, const NamespaceString& nss, bool stayTemp) { auto metadata = std::make_shared<BSONCollectionCatalogEntry::MetaData>(*_metadata); - metadata->ns = nss.ns(); + metadata->nss = nss; if (!stayTemp) metadata->options.temp = false; Status status = @@ -2135,7 +2135,7 @@ std::vector<std::string> CollectionImpl::repairInvalidIndexOptions(OperationCont } indexesWithInvalidOptions.push_back(std::string(index.nameStringData())); - index.spec = index_key_validate::repairIndexSpec(NamespaceString(md.ns), oldSpec); + index.spec = index_key_validate::repairIndexSpec(md.nss, oldSpec); } } }); diff --git a/src/mongo/db/repl/storage_timestamp_test.cpp b/src/mongo/db/repl/storage_timestamp_test.cpp index bb3268859e9..3c687376795 100644 --- a/src/mongo/db/repl/storage_timestamp_test.cpp +++ b/src/mongo/db/repl/storage_timestamp_test.cpp @@ -3058,8 +3058,8 @@ TEST_F(StorageTimestampTest, ViewCreationSeparateTransaction) { << " incorrectly exists before creation. CreateTs: " << systemViewsCreateTs; systemViewsMd = getMetaDataAtTime(durableCatalog, catalogId, systemViewsCreateTs); - auto nss = systemViewsMd->ns; - ASSERT_EQ(systemViewsNss.ns(), nss); + auto nss = systemViewsMd->nss; + ASSERT_EQ(systemViewsNss, nss); assertDocumentAtTimestamp(autoColl.getCollection(), systemViewsCreateTs, BSONObj()); assertDocumentAtTimestamp(autoColl.getCollection(), diff --git a/src/mongo/db/storage/SConscript b/src/mongo/db/storage/SConscript index ebc7fbdd4b7..7b73ea2a25d 100644 --- a/src/mongo/db/storage/SConscript +++ b/src/mongo/db/storage/SConscript @@ -126,6 +126,7 @@ env.Library( ], LIBDEPS_PRIVATE=[ '$BUILD_DIR/mongo/db/multitenancy', + '$BUILD_DIR/mongo/db/namespace_string', '$BUILD_DIR/mongo/db/server_options', ], ) diff --git a/src/mongo/db/storage/bson_collection_catalog_entry.cpp b/src/mongo/db/storage/bson_collection_catalog_entry.cpp index 80012f1733c..601d9df7ac3 100644 --- a/src/mongo/db/storage/bson_collection_catalog_entry.cpp +++ b/src/mongo/db/storage/bson_collection_catalog_entry.cpp @@ -33,6 +33,7 @@ #include <numeric> #include "mongo/db/field_ref.h" +#include "mongo/db/namespace_string.h" #include "mongo/db/server_options.h" namespace mongo { @@ -216,7 +217,7 @@ bool BSONCollectionCatalogEntry::MetaData::eraseIndex(StringData name) { BSONObj BSONCollectionCatalogEntry::MetaData::toBSON(bool hasExclusiveAccess) const { BSONObjBuilder b; - b.append("ns", ns); + b.append("ns", nss.toStringWithTenantId()); b.append("options", options.toBSON()); { BSONArrayBuilder arr(b.subarrayStart("indexes")); @@ -264,7 +265,8 @@ BSONObj BSONCollectionCatalogEntry::MetaData::toBSON(bool hasExclusiveAccess) co } void BSONCollectionCatalogEntry::MetaData::parse(const BSONObj& obj) { - ns = obj.getStringField("ns").toString(); + nss = NamespaceString::parseFromStringExpectTenantIdInMultitenancyMode( + obj.getStringField("ns").toString()); if (obj["options"].isABSONObj()) { options = uassertStatusOK( diff --git a/src/mongo/db/storage/bson_collection_catalog_entry.h b/src/mongo/db/storage/bson_collection_catalog_entry.h index 4cad84b6c98..c5044db616d 100644 --- a/src/mongo/db/storage/bson_collection_catalog_entry.h +++ b/src/mongo/db/storage/bson_collection_catalog_entry.h @@ -149,7 +149,7 @@ public: */ bool eraseIndex(StringData name); - std::string ns; + NamespaceString nss; CollectionOptions options; // May include empty instances which represent indexes already dropped. std::vector<IndexMetaData> indexes; diff --git a/src/mongo/db/storage/durable_catalog_impl.cpp b/src/mongo/db/storage/durable_catalog_impl.cpp index 03f7079808e..0da130c0c50 100644 --- a/src/mongo/db/storage/durable_catalog_impl.cpp +++ b/src/mongo/db/storage/durable_catalog_impl.cpp @@ -236,8 +236,9 @@ void DurableCatalogImpl::init(OperationContext* opCtx) { // No rollback since this is just loading already committed data. auto ident = obj["ident"].String(); - auto ns = obj["ns"].String(); - _catalogIdToEntryMap[record->id] = Entry(record->id, ident, NamespaceString(ns)); + auto nss = + NamespaceString::parseFromStringExpectTenantIdInMultitenancyMode(obj["ns"].String()); + _catalogIdToEntryMap[record->id] = Entry(record->id, ident, nss); } // In the unlikely event that we have used this _rand before generate a new one. @@ -259,9 +260,10 @@ std::vector<DurableCatalog::Entry> DurableCatalogImpl::getAllCatalogEntries( continue; } auto ident = obj["ident"].String(); - auto ns = obj["ns"].String(); + auto nss = + NamespaceString::parseFromStringExpectTenantIdInMultitenancyMode(obj["ns"].String()); - ret.emplace_back(record->id, ident, NamespaceString(ns)); + ret.emplace_back(record->id, ident, nss); } return ret; @@ -284,10 +286,10 @@ StatusWith<DurableCatalog::Entry> DurableCatalogImpl::_addEntry(OperationContext BSONObj obj; { BSONObjBuilder b; - b.append("ns", nss.ns()); + b.append("ns", nss.toStringWithTenantId()); b.append("ident", ident); BSONCollectionCatalogEntry::MetaData md; - md.ns = nss.ns(); + md.nss = nss; md.options = options; if (options.timeseries) { @@ -395,7 +397,7 @@ std::shared_ptr<BSONCollectionCatalogEntry::MetaData> DurableCatalogImpl::getMet void DurableCatalogImpl::putMetaData(OperationContext* opCtx, const RecordId& catalogId, BSONCollectionCatalogEntry::MetaData& md) { - NamespaceString nss(md.ns); + NamespaceString nss(md.nss); BSONObj obj = _findEntry(opCtx, catalogId); { @@ -448,7 +450,7 @@ Status DurableCatalogImpl::_replaceEntry(OperationContext* opCtx, { BSONObjBuilder b; - b.append("ns", toNss.ns()); + b.append("ns", toNss.toStringWithTenantId()); b.append("md", md.toBSON()); b.appendElementsUnique(old); @@ -564,10 +566,10 @@ StatusWith<std::string> DurableCatalogImpl::newOrphanedIdent(OperationContext* o BSONObj obj; { BSONObjBuilder b; - b.append("ns", nss.ns()); + b.append("ns", nss.toStringWithTenantId()); b.append("ident", ident); BSONCollectionCatalogEntry::MetaData md; - md.ns = nss.ns(); + md.nss = nss; // Default options with newly generated UUID. md.options = optionsWithUUID; b.append("md", md.toBSON()); @@ -587,7 +589,7 @@ StatusWith<std::string> DurableCatalogImpl::newOrphanedIdent(OperationContext* o "stored meta data for orphaned collection {namespace} @ {res_getValue}", logAttrs(nss), "res_getValue"_attr = res.getValue()); - return {nss.ns()}; + return {nss.toStringWithTenantId()}; } StatusWith<std::pair<RecordId, std::unique_ptr<RecordStore>>> DurableCatalogImpl::createCollection( diff --git a/src/mongo/db/storage/kv/durable_catalog_test.cpp b/src/mongo/db/storage/kv/durable_catalog_test.cpp index f87744b6d1a..c240f2dd9f3 100644 --- a/src/mongo/db/storage/kv/durable_catalog_test.cpp +++ b/src/mongo/db/storage/kv/durable_catalog_test.cpp @@ -740,5 +740,27 @@ TEST_F(DurableCatalogTest, CheckTimeseriesBucketsMayHaveMixedSchemaDataFlagFCVLa } } +TEST_F(DurableCatalogTest, CreateCollectionCatalogEntryHasCorrectTenantNamespace) { + gMultitenancySupport = true; + + auto tenantId = TenantId(OID::gen()); + const NamespaceString nss = NamespaceString(tenantId, "test.regular"); + createCollection(nss, CollectionOptions()); + + auto collection = CollectionCatalog::get(operationContext()) + ->lookupCollectionByNamespace(operationContext(), nss); + RecordId catalogId = collection->getCatalogId(); + ASSERT_EQ(getCatalog()->getEntry(catalogId).nss.tenantId(), nss.tenantId()); + ASSERT_EQ(getCatalog()->getEntry(catalogId).nss, nss); + + Lock::GlobalLock globalLock{operationContext(), MODE_IS}; + ASSERT_EQ(getCatalog()->getMetaData(operationContext(), catalogId)->nss.tenantId(), + nss.tenantId()); + ASSERT_EQ(getCatalog()->getMetaData(operationContext(), catalogId)->nss, nss); + + gMultitenancySupport = false; +} + + } // namespace } // namespace mongo diff --git a/src/mongo/db/storage/kv/kv_engine_test_harness.cpp b/src/mongo/db/storage/kv/kv_engine_test_harness.cpp index ce7b10e5287..69f23a73803 100644 --- a/src/mongo/db/storage/kv/kv_engine_test_harness.cpp +++ b/src/mongo/db/storage/kv/kv_engine_test_harness.cpp @@ -31,6 +31,7 @@ #include "mongo/db/catalog/collection_impl.h" #include "mongo/db/index/index_descriptor.h" +#include "mongo/db/multitenancy_gen.h" #include "mongo/db/operation_context_noop.h" #include "mongo/db/service_context_test_fixture.h" #include "mongo/db/storage/durable_catalog_impl.h" @@ -1112,7 +1113,7 @@ TEST_F(DurableCatalogImplTest, Idx1) { WriteUnitOfWork uow(opCtx); BSONCollectionCatalogEntry::MetaData md; - md.ns = "a.b"; + md.nss = NamespaceString(boost::none, "a.b"); BSONCollectionCatalogEntry::IndexMetaData imd; imd.spec = BSON("name" @@ -1146,7 +1147,7 @@ TEST_F(DurableCatalogImplTest, Idx1) { WriteUnitOfWork uow(opCtx); BSONCollectionCatalogEntry::MetaData md; - md.ns = "a.b"; + md.nss = NamespaceString(boost::none, "a.b"); putMetaData(opCtx, catalog.get(), catalogId, md); // remove index BSONCollectionCatalogEntry::IndexMetaData imd; @@ -1202,7 +1203,7 @@ TEST_F(DurableCatalogImplTest, DirectoryPerDb1) { WriteUnitOfWork uow(opCtx); BSONCollectionCatalogEntry::MetaData md; - md.ns = "a.b"; + md.nss = NamespaceString(boost::none, "a.b"); BSONCollectionCatalogEntry::IndexMetaData imd; imd.spec = BSON("name" @@ -1254,7 +1255,7 @@ TEST_F(DurableCatalogImplTest, Split1) { WriteUnitOfWork uow(opCtx); BSONCollectionCatalogEntry::MetaData md; - md.ns = "a.b"; + md.nss = NamespaceString(boost::none, "a.b"); BSONCollectionCatalogEntry::IndexMetaData imd; imd.spec = BSON("name" @@ -1306,7 +1307,7 @@ TEST_F(DurableCatalogImplTest, DirectoryPerAndSplit1) { WriteUnitOfWork uow(opCtx); BSONCollectionCatalogEntry::MetaData md; - md.ns = "a.b"; + md.nss = NamespaceString(boost::none, "a.b"); BSONCollectionCatalogEntry::IndexMetaData imd; imd.spec = BSON("name" @@ -1381,6 +1382,60 @@ DEATH_TEST_REGEX_F(DurableCatalogImplTest, } } +TEST_F(DurableCatalogImplTest, EntryIncludesTenantIdInMultitenantEnv) { + gMultitenancySupport = true; + KVEngine* engine = helper->getEngine(); + + // Create a DurableCatalog and RecordStore + std::unique_ptr<RecordStore> rs; + std::unique_ptr<DurableCatalogImpl> catalog; + { + auto clientAndCtx = makeClientAndCtx("opCtx"); + auto opCtx = clientAndCtx.opCtx(); + WriteUnitOfWork uow(opCtx); + ASSERT_OK(engine->createRecordStore( + opCtx, NamespaceString("catalog"), "catalog", CollectionOptions())); + rs = engine->getRecordStore( + opCtx, NamespaceString("catalog"), "catalog", CollectionOptions()); + catalog = std::make_unique<DurableCatalogImpl>(rs.get(), false, false, nullptr); + uow.commit(); + } + + // Insert an entry into the DurableCatalog, and ensure the tenantId is stored on the nss in the + // entry. + RecordId catalogId; + auto tenantId = TenantId(OID::gen()); + const NamespaceString nss = NamespaceString(tenantId, "a.b"); + { + auto clientAndCtx = makeClientAndCtx("opCtx"); + auto opCtx = clientAndCtx.opCtx(); + WriteUnitOfWork uow(opCtx); + catalogId = newCollection(opCtx, nss, CollectionOptions(), catalog.get()); + uow.commit(); + } + ASSERT_EQUALS(nss.tenantId(), catalog->getEntry(catalogId).nss.tenantId()); + ASSERT_EQUALS(nss, catalog->getEntry(catalogId).nss); + + // Re-initialize the DurableCatalog (as if it read from disk). Ensure the tenantId is still + // stored on the nss in the entry. + std::string ident = catalog->getEntry(catalogId).ident; + { + auto clientAndCtx = makeClientAndCtx("opCtx"); + auto opCtx = clientAndCtx.opCtx(); + Lock::GlobalLock globalLk(opCtx, MODE_IX); + + WriteUnitOfWork uow(opCtx); + catalog = std::make_unique<DurableCatalogImpl>(rs.get(), false, false, nullptr); + catalog->init(opCtx); + uow.commit(); + } + ASSERT_EQUALS(ident, catalog->getEntry(catalogId).ident); + ASSERT_EQUALS(nss.tenantId(), catalog->getEntry(catalogId).nss.tenantId()); + ASSERT_EQUALS(nss, catalog->getEntry(catalogId).nss); + + gMultitenancySupport = false; +} + } // namespace std::unique_ptr<KVHarnessHelper> KVHarnessHelper::create(ServiceContext* svcCtx) { diff --git a/src/mongo/db/storage/storage_engine_impl.cpp b/src/mongo/db/storage/storage_engine_impl.cpp index 98d7f0e3f1a..294ffa62f86 100644 --- a/src/mongo/db/storage/storage_engine_impl.cpp +++ b/src/mongo/db/storage/storage_engine_impl.cpp @@ -636,7 +636,7 @@ StatusWith<StorageEngine::ReconcileResult> StorageEngineImpl::reconcileCatalogAn for (DurableCatalog::Entry entry : catalogEntries) { std::shared_ptr<BSONCollectionCatalogEntry::MetaData> metaData = _catalog->getMetaData(opCtx, entry.catalogId); - NamespaceString nss(metaData->ns); + NamespaceString nss(metaData->nss); // Batch up the indexes to remove them from `metaData` outside of the iterator. std::vector<std::string> indexesToDrop; |