diff options
author | Suganthi Mani <suganthi.mani@mongodb.com> | 2020-10-22 21:56:58 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-10-23 02:15:32 +0000 |
commit | bddf687cc0447f85062f312b90f5044abcf92400 (patch) | |
tree | 16209b98ca959389fab3ff132fb2570edc460794 /src | |
parent | 4a01bb629285c01c3ba307723747d06310a1a6b4 (diff) | |
download | mongo-bddf687cc0447f85062f312b90f5044abcf92400.tar.gz |
SERVER-51743 Fix query operator for regex in cloner utils. SERVER-51744 Fix the filter for OplogFetcher::_makeFindQuery(). SERVER-51746 Fix the application name for tenant migration recipient collection cloner & oplog fetcher DBClientConnection. SERVER-51745 Set setRequestMetadataWriter() for tenant collection cloner.
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/client/dbclient_base.h | 30 | ||||
-rw-r--r-- | src/mongo/db/repl/cloner_utils.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/repl/oplog_fetcher.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/repl/oplog_fetcher_test.cpp | 8 | ||||
-rw-r--r-- | src/mongo/db/repl/tenant_collection_cloner.cpp | 41 | ||||
-rw-r--r-- | src/mongo/db/repl/tenant_collection_cloner.h | 6 | ||||
-rw-r--r-- | src/mongo/db/repl/tenant_migration_recipient_service.cpp | 15 |
7 files changed, 68 insertions, 36 deletions
diff --git a/src/mongo/client/dbclient_base.h b/src/mongo/client/dbclient_base.h index 19bf9d2c417..a9dbe457a84 100644 --- a/src/mongo/client/dbclient_base.h +++ b/src/mongo/client/dbclient_base.h @@ -852,4 +852,34 @@ private: BSONElement getErrField(const BSONObj& result); bool hasErrField(const BSONObj& result); +/* + * RAII-style class to set new RequestMetadataWriter and ReplyMetadataReader on DBClientConnection + * "_conn". On object destruction, '_conn' is set back to it's old RequestsMetadataWriter and + * ReplyMetadataReader. + */ +class ScopedMetadataWriterAndReader { + ScopedMetadataWriterAndReader(const ScopedMetadataWriterAndReader&) = delete; + ScopedMetadataWriterAndReader& operator=(const ScopedMetadataWriterAndReader&) = delete; + +public: + ScopedMetadataWriterAndReader(DBClientBase* conn, + rpc::RequestMetadataWriter writer, + rpc::ReplyMetadataReader reader) + : _conn(conn), + _oldWriter(std::move(conn->getRequestMetadataWriter())), + _oldReader(std::move(conn->getReplyMetadataReader())) { + _conn->setRequestMetadataWriter(std::move(writer)); + _conn->setReplyMetadataReader(std::move(reader)); + } + ~ScopedMetadataWriterAndReader() { + _conn->setRequestMetadataWriter(std::move(_oldWriter)); + _conn->setReplyMetadataReader(std::move(_oldReader)); + } + +private: + DBClientBase* const _conn; // not owned. + rpc::RequestMetadataWriter _oldWriter; + rpc::ReplyMetadataReader _oldReader; +}; + } // namespace mongo diff --git a/src/mongo/db/repl/cloner_utils.cpp b/src/mongo/db/repl/cloner_utils.cpp index 7f061a4f1ff..ae7f11a89e8 100644 --- a/src/mongo/db/repl/cloner_utils.cpp +++ b/src/mongo/db/repl/cloner_utils.cpp @@ -38,7 +38,7 @@ namespace mongo { namespace repl { BSONObj ClonerUtils::makeTenantDatabaseRegex(StringData prefix) { - return BSON("$regexp" + return BSON("$regex" << "^" + prefix + "_"); } diff --git a/src/mongo/db/repl/oplog_fetcher.cpp b/src/mongo/db/repl/oplog_fetcher.cpp index d9f3db55ae7..e9763ae329f 100644 --- a/src/mongo/db/repl/oplog_fetcher.cpp +++ b/src/mongo/db/repl/oplog_fetcher.cpp @@ -499,7 +499,7 @@ BSONObj OplogFetcher::_makeFindQuery(long long findTimeout) const { filterBob.append("ts", BSON("$gte" << lastOpTimeFetched.getTimestamp())); // Handle caller-provided filter. if (!_queryFilter.isEmpty()) { - filterBob.append("$and", _queryFilter); + filterBob.append("$and", BSON_ARRAY(_queryFilter)); } filterBob.done(); diff --git a/src/mongo/db/repl/oplog_fetcher_test.cpp b/src/mongo/db/repl/oplog_fetcher_test.cpp index ef4c0ff2785..0bb0d41379b 100644 --- a/src/mongo/db/repl/oplog_fetcher_test.cpp +++ b/src/mongo/db/repl/oplog_fetcher_test.cpp @@ -173,9 +173,9 @@ void validateFindCommand(Message m, msg.body.getObjectField("filter")); } else { - ASSERT_BSONOBJ_EQ( - BSON("ts" << BSON("$gte" << lastFetched.getTimestamp()) << "$and" << filter), - msg.body.getObjectField("filter")); + ASSERT_BSONOBJ_EQ(BSON("ts" << BSON("$gte" << lastFetched.getTimestamp()) << "$and" + << BSON_ARRAY(filter)), + msg.body.getObjectField("filter")); } ASSERT_EQUALS(lastFetched.getTerm(), msg.body.getIntField("term")); ASSERT_BSONOBJ_EQ(readConcern.toBSONInner(), msg.body.getObjectField("readConcern")); @@ -2316,7 +2316,7 @@ TEST_F(OplogFetcherTest, CheckFindCommandIncludesFilter) { // Create an oplog fetcher without any retries but with a filter. Note the filter is not // respected as our Mock objects do not respect them; this unit test only tests the command // is well-formed. - const BSONObj filter = BSON("ns" << BSON("$regexp" + const BSONObj filter = BSON("ns" << BSON("$regex" << "/^tenant_.*/")); auto oplogFetcher = getOplogFetcherAfterConnectionCreated(std::ref(shutdownState), diff --git a/src/mongo/db/repl/tenant_collection_cloner.cpp b/src/mongo/db/repl/tenant_collection_cloner.cpp index 43251eb6294..e1e023960d2 100644 --- a/src/mongo/db/repl/tenant_collection_cloner.cpp +++ b/src/mongo/db/repl/tenant_collection_cloner.cpp @@ -250,8 +250,25 @@ BaseCloner::AfterStageBehavior TenantCollectionCloner::createCollectionStage() { } BaseCloner::AfterStageBehavior TenantCollectionCloner::queryStage() { - ON_BLOCK_EXIT([this] { this->unsetMetadataReader(); }); - setMetadataReader(); + // Sets up tracking the lastVisibleOpTime from response metadata. + auto requestMetadataWriter = [this](OperationContext* opCtx, + BSONObjBuilder* metadataBob) -> Status { + *metadataBob << rpc::kReplSetMetadataFieldName << 1; + return Status::OK(); + }; + auto replyMetadataReader = + [this](OperationContext* opCtx, const BSONObj& metadataObj, StringData source) -> Status { + auto readResult = rpc::ReplSetMetadata::readFromMetadata(metadataObj); + if (!readResult.isOK()) { + return readResult.getStatus().withContext( + "tenant collection cloner failed to read repl set metadata"); + } + stdx::lock_guard<TenantMigrationSharedData> lk(*getSharedData()); + getSharedData()->setLastVisibleOpTime(lk, readResult.getValue().getLastOpVisible()); + return Status::OK(); + }; + ScopedMetadataWriterAndReader mwr(getClient(), requestMetadataWriter, replyMetadataReader); + runQuery(); waitForDatabaseWorkToComplete(); return kContinueNormally; @@ -357,26 +374,6 @@ void TenantCollectionCloner::waitForDatabaseWorkToComplete() { _dbWorkTaskRunner.join(); } -void TenantCollectionCloner::setMetadataReader() { - getClient()->setReplyMetadataReader( - [this](OperationContext* opCtx, const BSONObj& metadataObj, StringData source) { - auto readResult = rpc::ReplSetMetadata::readFromMetadata(metadataObj); - if (!readResult.isOK()) { - return readResult.getStatus().withContext( - "tenant collection cloner failed to read repl set metadata"); - } - stdx::lock_guard<TenantMigrationSharedData> lk(*getSharedData()); - getSharedData()->setLastVisibleOpTime(lk, readResult.getValue().getLastOpVisible()); - return Status::OK(); - }); -} - -void TenantCollectionCloner::unsetMetadataReader() { - getClient()->setReplyMetadataReader([this](OperationContext* opCtx, - const BSONObj& metadataObj, - StringData source) { return Status::OK(); }); -} - bool TenantCollectionCloner::isMyFailPoint(const BSONObj& data) const { auto nss = data["nss"].str(); return (nss.empty() || nss == _sourceNss.toString()) && BaseCloner::isMyFailPoint(data); diff --git a/src/mongo/db/repl/tenant_collection_cloner.h b/src/mongo/db/repl/tenant_collection_cloner.h index 45d0ba022f7..f0b654326dc 100644 --- a/src/mongo/db/repl/tenant_collection_cloner.h +++ b/src/mongo/db/repl/tenant_collection_cloner.h @@ -191,12 +191,6 @@ private: */ void waitForDatabaseWorkToComplete(); - /** - * Sets up tracking the lastVisibleOpTime from response metadata. - */ - void setMetadataReader(); - void unsetMetadataReader(); - // All member variables are labeled with one of the following codes indicating the // synchronization rules for accessing them. // diff --git a/src/mongo/db/repl/tenant_migration_recipient_service.cpp b/src/mongo/db/repl/tenant_migration_recipient_service.cpp index 03901fc5fe8..13ab60cebba 100644 --- a/src/mongo/db/repl/tenant_migration_recipient_service.cpp +++ b/src/mongo/db/repl/tenant_migration_recipient_service.cpp @@ -297,11 +297,22 @@ TenantMigrationRecipientService::Instance::_createAndConnectClients() { return _donorReplicaSetMonitor->getHostOrRefresh(_readPreference, findHostTimeout) .thenRunOn(**_scopedExecutor) .then([this](const HostAndPort& serverAddress) { + // Application name is constructed such that it doesn't exceeds + // kMaxApplicationNameByteLength (128 bytes). + // "TenantMigration_" (16 bytes) + <tenantId> (61 bytes) + "_" (1 byte) + + // <migrationUuid> (36 bytes) = 114 bytes length. + // Note: Since the total length of tenant database name (<tenantId>_<user provided db + // name>) can't exceed 63 bytes and the user provided db name should be at least one + // character long, the maximum length of tenantId can only be 61 bytes. auto applicationName = - "TenantMigrationRecipient_" + getTenantId() + "_" + getMigrationUUID().toString(); + "TenantMigration_" + getTenantId() + "_" + getMigrationUUID().toString(); auto client = _connectAndAuth(serverAddress, applicationName, _authParams); - applicationName += "_fetcher"; + // Application name is constructed such that it doesn't exceeds + // kMaxApplicationNameByteLength (128 bytes). + // "TenantMigration_" (16 bytes) + <tenantId> (61 bytes) + "_" (1 byte) + + // <migrationUuid> (36 bytes) + _oplogFetcher" (13 bytes) = 127 bytes length. + applicationName += "_oplogFetcher"; auto oplogFetcherClient = _connectAndAuth(serverAddress, applicationName, _authParams); return ConnectionPair(std::move(client), std::move(oplogFetcherClient)); }) |