diff options
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/client/dbclient_base.cpp | 27 | ||||
-rw-r--r-- | src/mongo/client/dbclient_base.h | 35 | ||||
-rw-r--r-- | src/mongo/shell/bench.cpp | 71 | ||||
-rw-r--r-- | src/mongo/shell/bench.h | 2 |
4 files changed, 106 insertions, 29 deletions
diff --git a/src/mongo/client/dbclient_base.cpp b/src/mongo/client/dbclient_base.cpp index d2ff6128a72..4e40dc95cfa 100644 --- a/src/mongo/client/dbclient_base.cpp +++ b/src/mongo/client/dbclient_base.cpp @@ -220,7 +220,6 @@ std::pair<rpc::UniqueReply, DBClientBase*> DBClientBase::runCommandWithTarget( auto opCtx = haveClient() ? cc().getOperationContext() : nullptr; appendMetadata(opCtx, _metadataWriter, _apiParameters, request); auto requestMsg = request.serialize(); - Message replyMsg; try { @@ -838,20 +837,26 @@ std::list<BSONObj> DBClientBase::_getIndexSpecs(const NamespaceStringOrUUID& nsO void DBClientBase::dropIndex(const string& ns, BSONObj keys, - boost::optional<BSONObj> writeConcernObj) { - dropIndex(ns, genIndexName(keys), writeConcernObj); + boost::optional<BSONObj> writeConcernObj, + boost::optional<TenantId> tenantId) { + dropIndex(ns, genIndexName(keys), writeConcernObj, tenantId); } void DBClientBase::dropIndex(const string& ns, const string& indexName, - boost::optional<BSONObj> writeConcernObj) { + boost::optional<BSONObj> writeConcernObj, + boost::optional<TenantId> tenantId) { BSONObjBuilder cmdBuilder; cmdBuilder.append("dropIndexes", nsToCollectionSubstring(ns)); cmdBuilder.append("index", indexName); if (writeConcernObj) { cmdBuilder.append(WriteConcernOptions::kWriteConcernField, *writeConcernObj); } + if (tenantId) { + tenantId->serializeToBSON("$tenant"_sd, &cmdBuilder); + } + BSONObj info; if (!runCommand(nsToDatabase(ns), cmdBuilder.obj(), info)) { LOGV2_DEBUG(20118, @@ -905,9 +910,14 @@ string DBClientBase::genIndexName(const BSONObj& keys) { void DBClientBase::createIndexes(StringData ns, const std::vector<const IndexSpec*>& descriptors, - boost::optional<BSONObj> writeConcernObj) { + boost::optional<BSONObj> writeConcernObj, + boost::optional<TenantId> tenantId) { BSONObjBuilder command; command.append("createIndexes", nsToCollectionSubstring(ns)); + if (tenantId) { + tenantId->serializeToBSON("$tenant", &command); + } + { BSONArrayBuilder indexes(command.subarrayStart("indexes")); for (const auto& desc : descriptors) { @@ -929,9 +939,14 @@ void DBClientBase::createIndexes(StringData ns, void DBClientBase::createIndexes(StringData ns, const std::vector<BSONObj>& specs, - boost::optional<BSONObj> writeConcernObj) { + boost::optional<BSONObj> writeConcernObj, + boost::optional<TenantId> tenantId) { BSONObjBuilder command; command.append("createIndexes", nsToCollectionSubstring(ns)); + if (tenantId) { + tenantId->serializeToBSON("$tenant", &command); + } + { BSONArrayBuilder indexes(command.subarrayStart("indexes")); for (const auto& spec : specs) { diff --git a/src/mongo/client/dbclient_base.h b/src/mongo/client/dbclient_base.h index e8376b2b8ec..4de6ef59288 100644 --- a/src/mongo/client/dbclient_base.h +++ b/src/mongo/client/dbclient_base.h @@ -421,11 +421,14 @@ public: * 'ns': Namespace on which to create the index * 'keys': Document describing keys and index types. You must provide at least one field and * its direction. + * + * SERVER-70433 Remove 'tenantId' as parameter. */ void createIndex(StringData ns, const BSONObj& keys, - boost::optional<BSONObj> writeConcernObj = boost::none) { - return createIndex(ns, IndexSpec().addKeys(keys), writeConcernObj); + boost::optional<BSONObj> writeConcernObj = boost::none, + boost::optional<TenantId> tenantId = boost::none) { + return createIndex(ns, IndexSpec().addKeys(keys), writeConcernObj, tenantId); } /** @@ -435,27 +438,37 @@ public: * 'ns': Namespace on which to create the index * 'descriptor': Configuration object describing the index to create. The descriptor must * describe at least one key and index type. + * + * SERVER-70433 Remove 'tenantId' as parameter. */ virtual void createIndex(StringData ns, const IndexSpec& descriptor, - boost::optional<BSONObj> writeConcernObj = boost::none) { + boost::optional<BSONObj> writeConcernObj = boost::none, + boost::optional<TenantId> tenantId = boost::none) { std::vector<const IndexSpec*> toBuild; toBuild.push_back(&descriptor); - createIndexes(ns, toBuild, writeConcernObj); + createIndexes(ns, toBuild, writeConcernObj, tenantId); } + /** + * SERVER-70433 Remove 'tenantId' as parameter. + */ virtual void createIndexes(StringData ns, const std::vector<const IndexSpec*>& descriptor, - boost::optional<BSONObj> writeConcernObj = boost::none); + boost::optional<BSONObj> writeConcernObj = boost::none, + boost::optional<TenantId> tenantId = boost::none); /** * Creates indexes on the collection 'ns' as described by 'specs'. * * Failure to construct the indexes is reported by throwing an AssertionException. + * + * SERVER-70433 Remove 'tenantId' as parameter. */ virtual void createIndexes(StringData ns, const std::vector<BSONObj>& specs, - boost::optional<BSONObj> writeConcernObj = boost::none); + boost::optional<BSONObj> writeConcernObj = boost::none, + boost::optional<TenantId> tenantId = boost::none); /** * Lists indexes on the collection 'nsOrUuid'. @@ -474,13 +487,17 @@ public: virtual std::list<BSONObj> getIndexSpecs(const NamespaceStringOrUUID& nsOrUuid, bool includeBuildUUIDs, int options); - + /* + * SERVER-70433 Remove 'tenantId' as parameter. + */ virtual void dropIndex(const std::string& ns, BSONObj keys, - boost::optional<BSONObj> writeConcernObj = boost::none); + boost::optional<BSONObj> writeConcernObj = boost::none, + boost::optional<TenantId> tenantId = boost::none); virtual void dropIndex(const std::string& ns, const std::string& indexName, - boost::optional<BSONObj> writeConcernObj = boost::none); + boost::optional<BSONObj> writeConcernObj = boost::none, + boost::optional<TenantId> tenantId = boost::none); /** * Drops all indexes for the collection. diff --git a/src/mongo/shell/bench.cpp b/src/mongo/shell/bench.cpp index ff9bb11327b..cbaa79a866a 100644 --- a/src/mongo/shell/bench.cpp +++ b/src/mongo/shell/bench.cpp @@ -209,8 +209,11 @@ int runQueryWithReadCommands(DBClientBase* conn, Milliseconds delayBeforeGetMore, BSONObj readPrefObj, BSONObj* objOut) { - const auto dbName = - findCommand->getNamespaceOrUUID().nss().value_or(NamespaceString()).db().toString(); + const auto dbName = findCommand->getNamespaceOrUUID() + .nss() + .value_or(NamespaceString()) + .dbName() + .toStringWithTenantId(); BSONObj findCommandResult; BSONObj findCommandObj = findCommand->toBSON(readPrefObj); @@ -380,7 +383,7 @@ BenchRunOp opFromBson(const BSONObj& op) { auto name = arg.fieldNameStringData(); if (name == "batchSize") { uassert(34377, - str::stream() << "Field 'batchSize' should be a number, instead it's type: " + str::stream() << "Field 'batchSize' should be a number, instead it's of type: " << typeName(arg.type()), arg.isNumber()); uassert(34378, @@ -399,13 +402,13 @@ BenchRunOp opFromBson(const BSONObj& op) { myOp.context = arg.Obj(); } else if (name == "cpuFactor") { uassert(40436, - str::stream() << "Field 'cpuFactor' should be a number, instead it's type: " + str::stream() << "Field 'cpuFactor' should be a number, instead it's of type: " << typeName(arg.type()), arg.isNumber()); myOp.cpuFactor = arg.numberDouble(); } else if (name == "delay") { uassert(34379, - str::stream() << "Field 'delay' should be a number, instead it's type: " + str::stream() << "Field 'delay' should be a number, instead it's of type: " << typeName(arg.type()), arg.isNumber()); myOp.delay = arg.numberInt(); @@ -418,14 +421,21 @@ BenchRunOp opFromBson(const BSONObj& op) { myOp.doc = arg.Obj(); } else if (name == "expected") { uassert(34380, - str::stream() << "Field 'Expected' should be a number, instead it's type: " + str::stream() << "Field 'expected' should be a number, instead it's of type: " << typeName(arg.type()), arg.isNumber()); uassert(34400, - str::stream() << "Field 'Expected' only valid for find op type. Type is " + str::stream() << "Field 'expected' only valid for find op type. Type is " << opType, (opType == "find") || (opType == "query")); myOp.expected = arg.numberInt(); + } else if (name == "expectedDoc") { + uassert( + 7056700, + str::stream() << "Field 'expectedDoc' should be an object, instead it's of type: " + << typeName(arg.type()), + arg.isABSONObj()); + myOp.expectedDoc = arg.Obj(); } else if (name == "filter") { uassert( 34401, @@ -450,7 +460,7 @@ BenchRunOp opFromBson(const BSONObj& op) { << opType, (opType == "find") || (opType == "query")); uassert(ErrorCodes::BadValue, - str::stream() << "Field 'limit' should be a number, instead it's type: " + str::stream() << "Field 'limit' should be a number, instead it's of type: " << typeName(arg.type()), arg.isNumber()); myOp.limit = arg.numberInt(); @@ -463,13 +473,20 @@ BenchRunOp opFromBson(const BSONObj& op) { myOp.multi = arg.trueValue(); } else if (name == "ns") { uassert(34385, - str::stream() << "Field 'ns' should be a string, instead it's type: " + str::stream() << "Field 'ns' should be a string, instead it's of type: " << typeName(arg.type()), arg.type() == String); myOp.ns = arg.String(); + } else if (name == "tenantId") { + uassert( + 7056701, + str::stream() << "Field 'tenantId' should be an ObjectId, instead it's of type: " + << typeName(arg.type()), + arg.type() == jstOID); + myOp.tenantId = TenantId{arg.OID()}; } else if (name == "op") { uassert(ErrorCodes::BadValue, - str::stream() << "Field 'op' is not a string, instead it's type: " + str::stream() << "Field 'op' is not a string, instead it's of type: " << typeName(arg.type()), arg.type() == String); auto type = arg.valueStringData(); @@ -1009,6 +1026,7 @@ void BenchRunOp::executeOnce(DBClientBase* conn, findCommand->setLimit(1LL); findCommand->setSingleBatch(true); findCommand->setSort(this->sort); + findCommand->setDollarTenant(this->tenantId); if (config.useSnapshotReads) { findCommand->setReadConcern(readConcernSnapshot); } @@ -1029,6 +1047,16 @@ void BenchRunOp::executeOnce(DBClientBase* conn, readPrefObj, &result); LOGV2_DEBUG(22796, 5, "Result from benchRun thread [findOne]", "result"_attr = result); + + if (!this->expectedDoc.isEmpty() && this->expectedDoc.woCompare(result) != 0) { + LOGV2_INFO(7056702, + "Bench 'findOne' on: {namespace} expected: {expected} got: {got}", + "Bench 'findOne' on namespace got different results then expected", + "namespace"_attr = this->ns, + "expected"_attr = this->expectedDoc, + "got"_attr = result); + verify(false); + } } break; case OpType::COMMAND: { bool ok; @@ -1094,6 +1122,8 @@ void BenchRunOp::executeOnce(DBClientBase* conn, if (!this->sort.isEmpty()) { findCommand->setSort(this->sort); } + findCommand->setDollarTenant(this->tenantId); + BSONObjBuilder readConcernBuilder; if (config.useSnapshotReads) { readConcernBuilder.append("level", "snapshot"); @@ -1132,8 +1162,8 @@ void BenchRunOp::executeOnce(DBClientBase* conn, if (this->expected >= 0 && count != this->expected) { LOGV2_INFO(22797, - "Bench query on: {namespace} expected: {expected} got: {got}", - "Bench query on namespace got diffrent results then expected", + "Bench 'find' on: {namespace} expected: {expected} got: {got}", + "Bench 'find' on namespace got different results then expected", "namespace"_attr = this->ns, "expected"_attr = this->expected, "got"_attr = count); @@ -1149,6 +1179,10 @@ void BenchRunOp::executeOnce(DBClientBase* conn, BSONObjBuilder builder; builder.append("update", nsToCollectionSubstring(this->ns)); + if (this->tenantId) { + this->tenantId->serializeToBSON("$tenant"_sd, &builder); + } + BSONArrayBuilder updateArray(builder.subarrayStart("updates")); { BSONObjBuilder singleUpdate; @@ -1215,6 +1249,10 @@ void BenchRunOp::executeOnce(DBClientBase* conn, BSONObj insertDoc; BSONObjBuilder builder; builder.append("insert", nsToCollectionSubstring(this->ns)); + if (this->tenantId) { + this->tenantId->serializeToBSON("$tenant"_sd, &builder); + } + BSONArrayBuilder docBuilder(builder.subarrayStart("documents")); if (this->isDocAnArray) { for (const auto& element : this->doc) { @@ -1251,6 +1289,10 @@ void BenchRunOp::executeOnce(DBClientBase* conn, BSONObj predicate = fixQuery(this->query, *state->bsonTemplateEvaluator); BSONObjBuilder builder; builder.append("delete", nsToCollectionSubstring(this->ns)); + if (this->tenantId) { + this->tenantId->serializeToBSON("$tenant"_sd, &builder); + } + BSONArrayBuilder docBuilder(builder.subarrayStart("deletes")); int limit = (this->multi == true) ? 0 : 1; docBuilder.append(BSON("q" << predicate << "limit" << limit)); @@ -1274,10 +1316,11 @@ void BenchRunOp::executeOnce(DBClientBase* conn, 22801, 5, "Result from benchRun thread [safe remove]", "result"_attr = result); } break; case OpType::CREATEINDEX: - conn->createIndex(this->ns, this->key); + conn->createIndex( + this->ns, this->key, boost::none /* writeConcernObj */, this->tenantId); break; case OpType::DROPINDEX: - conn->dropIndex(this->ns, this->key); + conn->dropIndex(this->ns, this->key, boost::none /* writeConcernObj */, this->tenantId); break; case OpType::LET: { BSONObjBuilder templateBuilder; diff --git a/src/mongo/shell/bench.h b/src/mongo/shell/bench.h index 053de58fd17..6badfbb346b 100644 --- a/src/mongo/shell/bench.h +++ b/src/mongo/shell/bench.h @@ -127,6 +127,8 @@ struct BenchRunOp { bool useWriteCmd = false; BSONObj writeConcern; BSONObj value; + BSONObj expectedDoc; + boost::optional<TenantId> tenantId; // Only used for find cmds when set greater than 0. A find operation will retrieve the latest // cluster time from the oplog and randomly chooses a time between that timestamp and |