diff options
author | Luis Osta <luis.osta@mongodb.com> | 2020-07-15 21:30:17 +0000 |
---|---|---|
committer | Luis Osta <luis.osta@mongodb.com> | 2020-07-17 15:26:06 +0000 |
commit | a701b8503794223b2ae81b7aa7214b4775562ed1 (patch) | |
tree | 1ee8bfb54fdb9170063834f3a3f1c00964e45755 | |
parent | 39ca11ba8370f2078c13996f243e03fb9efa070b (diff) | |
download | mongo-a701b8503794223b2ae81b7aa7214b4775562ed1.tar.gz |
implemented basic persistance and fixed class command issue
-rw-r--r-- | jstests/replsets/migrating_tenant_mtab_blocks_writes.js | 28 | ||||
-rw-r--r-- | src/mongo/db/commands/migrate_tenant_cmds.cpp | 83 | ||||
-rw-r--r-- | src/mongo/db/commands/migrate_tenant_cmds.h | 60 | ||||
-rw-r--r-- | src/mongo/db/repl/migrating_tenant_donor_util.cpp | 25 | ||||
-rw-r--r-- | src/mongo/db/repl/migrating_tenant_donor_util.h | 3 |
5 files changed, 150 insertions, 49 deletions
diff --git a/jstests/replsets/migrating_tenant_mtab_blocks_writes.js b/jstests/replsets/migrating_tenant_mtab_blocks_writes.js index a77e7f8328d..5206426b98f 100644 --- a/jstests/replsets/migrating_tenant_mtab_blocks_writes.js +++ b/jstests/replsets/migrating_tenant_mtab_blocks_writes.js @@ -5,13 +5,37 @@ (function () { "use strict"; - + const runDonorStartMigrationCommand = + (primaryConnection, migrationId, recipientConnectionString, dbPrefix, readPreference) => { + return primaryConnection.adminCommand({ + donorStartMigration: 1, + migrationId, + recipientConnectionString, + databasePrefix: dbPrefix, + readPreference + }); + }; const rst = new ReplSetTest({ nodes: 1 }); rst.startSet(); rst.initiate(); - assert(true) + const donorPrimary = rst.getPrimary(); + + const kMigrationId = new UUID(); + const kRecipientConnectionString = new ReplSetTest({ nodes: 1 }).getURL(); + + const kReadPreference = { + mode: "primary" + }; + const kDBPrefixes = 'databaseABC'; + + jsTest.log('Running donorStartMigration command.') + assert.commandWorked(runDonorStartMigrationCommand(donorPrimary, kMigrationId, kRecipientConnectionString, kDBPrefixes, kReadPreference)); + + jsTest.log('Running the serverStatus command.') + const res = donorPrimary.adminCommand({ serverStatus: 1 }); + jsTest.log(tojson(res)); rst.stopSet(); })();
\ No newline at end of file diff --git a/src/mongo/db/commands/migrate_tenant_cmds.cpp b/src/mongo/db/commands/migrate_tenant_cmds.cpp index 14eb45c7506..b75dbfbd99f 100644 --- a/src/mongo/db/commands/migrate_tenant_cmds.cpp +++ b/src/mongo/db/commands/migrate_tenant_cmds.cpp @@ -26,59 +26,36 @@ * exception statement from all source files in the program, then also delete * it in the license file. */ +#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kReplication; -#include "mongo/db/commands.h" +#include "mongo/db/commands/migrate_tenant_cmds.h" #include "mongo/db/commands/migrate_tenant_cmds_gen.h" #include "mongo/db/repl/migrate_tenant_state_machine_gen.h" #include "mongo/db/repl/migrating_tenant_donor_util.h" +#include "mongo/logv2/log.h" namespace mongo { namespace { -template <typename RequestT> -class MigrationDonorCmdBase : public TypedCommand<MigrationDonorCmdBase<RequestT>> { + +class DonorStartMigrationCmd : public MigrationDonorCmdBase<DonorStartMigrationCmd> { public: - using Request = RequestT; - using TC = TypedCommand<MigrationDonorCmdBase<RequestT>>; + using Request = DonorStartMigration; + using ParentInvocation = MigrationDonorCmdBase<DonorStartMigrationCmd>::Invocation; + class Invocation : public ParentInvocation { + using ParentInvocation::ParentInvocation; - class Invocation : public TC::InvocationBase { public: - using TC::InvocationBase::InvocationBase; - using TC::InvocationBase::request; - - void typedRun(OperationContext* opCtx) {} + void typedRun(OperationContext* opCtx) { + const auto requestBody = request(); + auto donorDocument = getDonorDocumentFromRequest(requestBody); - private: - bool supportsWriteConcern() const override { - return false; - } - NamespaceString ns() const override { - return NamespaceString(request().getDbName(), ""); + migrating_tenant_donor_util::persistDonorStateMachine(opCtx, donorDocument); + migrating_tenant_donor_util::dataSync(opCtx, donorDocument); } - void doCheckAuthorization(OperationContext* opCtx) const override {} - }; - - bool adminOnly() const override { - return true; - } - - std::string help() const override { - return "Multi-tenant migration command on the donor."; - } - BasicCommand::AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { - return BasicCommand::AllowedOnSecondary::kNever; - } -}; - -class DonorStartMigrationCmd : public MigrationDonorCmdBase<DonorStartMigration> { -public: - using ParentInvocation = MigrationDonorCmdBase<DonorStartMigration>::Invocation; - class Invocation final : public ParentInvocation { - public: - void typedRun(OperationContext* opCtx) { - const auto requestBody = request(); + TenantMigrationDonorDocument getDonorDocumentFromRequest(const RequestType& requestBody) { mongo::UUID migrationId = requestBody.getMigrationId(); std::string recipientURI = requestBody.getRecipientConnectionString().toString(); @@ -89,14 +66,14 @@ public: const TenantMigrationDonorDocument donorDocument( OID::gen(), migrationId, recipientURI, dbPrefix, donorStartState, garbageCollect); - migrating_tenant_donor_util::dataSync(opCtx, donorDocument); + return donorDocument; } private: - void doCheckAuthorization(OperationContext* opCtx) const override {} + void doCheckAuthorization(OperationContext* opCtx) const {} }; - std::string help() const override { + std::string help() const { return "Start migrating databases whose names match the specified prefix to the specified " "replica set."; } @@ -104,12 +81,18 @@ public: } donorStartMigrationCmd; class DonorWaitForMigrationToCommitCmd - : public MigrationDonorCmdBase<DonorWaitForMigrationToCommit> { + : public MigrationDonorCmdBase<DonorWaitForMigrationToCommitCmd> { public: - using ParentInvocation = MigrationDonorCmdBase<DonorWaitForMigrationToCommit>::Invocation; - class Invocation final : public ParentInvocation { + using Request = DonorWaitForMigrationToCommit; + using ParentInvocation = MigrationDonorCmdBase<DonorWaitForMigrationToCommitCmd>::Invocation; + class Invocation : public ParentInvocation { + using ParentInvocation::ParentInvocation; + public: void typedRun(OperationContext* opCtx) {} + + private: + void doCheckAuthorization(OperationContext* opCtx) const {} }; std::string help() const override { @@ -118,12 +101,18 @@ public: } donorWaitForMigrationToCommit; -class DonorForgetMigrationCmd : public MigrationDonorCmdBase<DonorForgetMigration> { +class DonorForgetMigrationCmd : public MigrationDonorCmdBase<DonorForgetMigrationCmd> { public: - using ParentInvocation = MigrationDonorCmdBase<DonorWaitForMigrationToCommit>::Invocation; - class Invocation final : public ParentInvocation { + using Request = DonorForgetMigration; + using ParentInvocation = MigrationDonorCmdBase<DonorForgetMigrationCmd>::Invocation; + class Invocation : public ParentInvocation { + using ParentInvocation::ParentInvocation; + public: void typedRun(OperationContext* opCtx) {} + + private: + void doCheckAuthorization(OperationContext* opCtx) const {} }; std::string help() const override { diff --git a/src/mongo/db/commands/migrate_tenant_cmds.h b/src/mongo/db/commands/migrate_tenant_cmds.h new file mode 100644 index 00000000000..77fc3f6a48f --- /dev/null +++ b/src/mongo/db/commands/migrate_tenant_cmds.h @@ -0,0 +1,60 @@ +/** + * Copyright (C) 2020-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + + +#include "mongo/db/commands.h" + +namespace mongo { + +template <typename DerivedT> +class MigrationDonorCmdBase : public TypedCommand<DerivedT> { +public: + using TC = TypedCommand<DerivedT>; + + class Invocation : public TC::InvocationBase { + using TC::InvocationBase::InvocationBase; + + private: + bool supportsWriteConcern() const override { + return false; + } + NamespaceString ns() const { + return NamespaceString(TC::InvocationBase::request().getDbName(), ""); + } + }; + + bool adminOnly() const override { + return true; + } + + BasicCommand::AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { + return BasicCommand::AllowedOnSecondary::kNever; + } +}; +} // namespace mongo
\ No newline at end of file diff --git a/src/mongo/db/repl/migrating_tenant_donor_util.cpp b/src/mongo/db/repl/migrating_tenant_donor_util.cpp index 826551972a6..84c93afacfd 100644 --- a/src/mongo/db/repl/migrating_tenant_donor_util.cpp +++ b/src/mongo/db/repl/migrating_tenant_donor_util.cpp @@ -27,7 +27,10 @@ * it in the license file. */ +#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kReplication; + #include "mongo/platform/basic.h" +#include "mongo/util/str.h" #include "mongo/db/repl/migrating_tenant_donor_util.h" @@ -36,10 +39,13 @@ #include "mongo/db/dbhelpers.h" #include "mongo/db/repl/migrate_tenant_state_machine_gen.h" #include "mongo/db/repl/migrating_tenant_access_blocker_by_prefix.h" +#include "mongo/db/s/persistent_task_store.h" #include "mongo/executor/network_interface_factory.h" #include "mongo/executor/thread_pool_task_executor.h" +#include "mongo/logv2/log.h" #include "mongo/util/concurrency/thread_pool.h" + namespace mongo { namespace migrating_tenant_donor_util { @@ -137,13 +143,16 @@ void dataSync(OperationContext* opCtx, const TenantMigrationDonorDocument& origi // Reserve an opTime for the write and use it as the blockTimestamp for the migration. auto oplogSlot = repl::LocalOplogInfo::get(opCtx)->getNextOpTimes(opCtx, 1U)[0]; + TenantMigrationDonorDocument updatedDoc; updatedDoc.setId(originalDoc.getId()); updatedDoc.setDatabasePrefix(originalDoc.getDatabasePrefix()); updatedDoc.setState(TenantMigrationDonorStateEnum::kBlocking); updatedDoc.setBlockTimestamp(oplogSlot.getTimestamp()); + CollectionUpdateArgs args; + // ! Since the updatedDoc isn't properly created, this will throw an error args.update = updatedDoc.toBSON(); args.criteria = BSON("_id" << originalDoc.getId()); args.oplogSlot = oplogSlot; @@ -196,6 +205,22 @@ void onTenantMigrationDonorStateTransition(OperationContext* opCtx, const BSONOb } } +void persistDonorStateMachine(OperationContext* opCtx, + const TenantMigrationDonorDocument& donorDoc) { + PersistentTaskStore<TenantMigrationDonorDocument> store( + NamespaceString::kMigrationDonorsNamespace); + try { + store.add(opCtx, donorDoc); + } catch (const ExceptionFor<ErrorCodes::DuplicateKey>&) { + uasserted( + 4917300, + str::stream() + << "While attempting to persist the donor state machine for tenant migration" + << ", found another document with the same migration id. Attempted migration: " + << donorDoc.toBSON()); + } +} + } // namespace migrating_tenant_donor_util } // namespace mongo diff --git a/src/mongo/db/repl/migrating_tenant_donor_util.h b/src/mongo/db/repl/migrating_tenant_donor_util.h index 64bfe1474ec..fd48b203057 100644 --- a/src/mongo/db/repl/migrating_tenant_donor_util.h +++ b/src/mongo/db/repl/migrating_tenant_donor_util.h @@ -53,6 +53,9 @@ std::shared_ptr<executor::TaskExecutor> getTenantMigrationExecutor(ServiceContex * config.migrationDonors document. */ void onTenantMigrationDonorStateTransition(OperationContext* opCtx, const BSONObj& doc); + +void persistDonorStateMachine(OperationContext* opCtx, + const TenantMigrationDonorDocument& donorDoc); } // namespace migrating_tenant_donor_util } // namespace mongo |