summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/catalog/catalog_control.cpp4
-rw-r--r--src/mongo/db/catalog/collection_impl.cpp4
-rw-r--r--src/mongo/db/repl/storage_timestamp_test.cpp4
-rw-r--r--src/mongo/db/storage/SConscript1
-rw-r--r--src/mongo/db/storage/bson_collection_catalog_entry.cpp6
-rw-r--r--src/mongo/db/storage/bson_collection_catalog_entry.h2
-rw-r--r--src/mongo/db/storage/durable_catalog_impl.cpp24
-rw-r--r--src/mongo/db/storage/kv/durable_catalog_test.cpp22
-rw-r--r--src/mongo/db/storage/kv/kv_engine_test_harness.cpp65
-rw-r--r--src/mongo/db/storage/storage_engine_impl.cpp2
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;