summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorMatthew Saltz <matthew.saltz@mongodb.com>2019-11-26 20:21:41 +0000
committerevergreen <evergreen@mongodb.com>2019-11-26 20:21:41 +0000
commita1bb3e698f2a79c463077b84c77cf2cee06d848b (patch)
tree23e5ebba8323a9240c33a4f2bdadc23ff840d9dc /src/mongo
parent058c4e3bbf94aa2ed1148dd0e8e473be6fcaa48b (diff)
downloadmongo-a1bb3e698f2a79c463077b84c77cf2cee06d848b.tar.gz
SERVER-44161 Implement MigrationCoordinator
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/namespace_string.cpp3
-rw-r--r--src/mongo/db/namespace_string.h3
-rw-r--r--src/mongo/db/s/SConscript3
-rw-r--r--src/mongo/db/s/migration_coordinator.cpp103
-rw-r--r--src/mongo/db/s/migration_coordinator.h88
-rw-r--r--src/mongo/db/s/migration_coordinator_document.idl65
-rw-r--r--src/mongo/db/s/migration_util.cpp108
-rw-r--r--src/mongo/db/s/migration_util.h57
-rw-r--r--src/mongo/db/s/migration_util_test.cpp11
-rw-r--r--src/mongo/db/s/range_deletion_task.idl26
-rw-r--r--src/mongo/s/catalog/type_chunk.h7
-rw-r--r--src/mongo/s/chunk_range.idl48
-rw-r--r--src/mongo/util/uuid.h1
13 files changed, 498 insertions, 25 deletions
diff --git a/src/mongo/db/namespace_string.cpp b/src/mongo/db/namespace_string.cpp
index 8d8656b8ec4..2397e3c1d0d 100644
--- a/src/mongo/db/namespace_string.cpp
+++ b/src/mongo/db/namespace_string.cpp
@@ -66,6 +66,9 @@ const NamespaceString NamespaceString::kSessionTransactionsTableNamespace(
const NamespaceString NamespaceString::kTransactionCoordinatorsNamespace(
NamespaceString::kConfigDb, "transaction_coordinators");
+const NamespaceString NamespaceString::kMigrationCoordinatorsNamespace(NamespaceString::kConfigDb,
+ "migrationCoordinators");
+
const NamespaceString NamespaceString::kShardConfigCollectionsNamespace(NamespaceString::kConfigDb,
"cache.collections");
const NamespaceString NamespaceString::kShardConfigDatabasesNamespace(NamespaceString::kConfigDb,
diff --git a/src/mongo/db/namespace_string.h b/src/mongo/db/namespace_string.h
index 653f0ed1546..add77a0dfaf 100644
--- a/src/mongo/db/namespace_string.h
+++ b/src/mongo/db/namespace_string.h
@@ -95,6 +95,9 @@ public:
// Namespace for storing the persisted state of transaction coordinators.
static const NamespaceString kTransactionCoordinatorsNamespace;
+ // Namespace for storing the persisted state of migration coordinators.
+ static const NamespaceString kMigrationCoordinatorsNamespace;
+
// Namespace for replica set configuration settings.
static const NamespaceString kSystemReplSetNamespace;
diff --git a/src/mongo/db/s/SConscript b/src/mongo/db/s/SConscript
index bbed7e25b50..6e4080a39b1 100644
--- a/src/mongo/db/s/SConscript
+++ b/src/mongo/db/s/SConscript
@@ -47,6 +47,7 @@ env.Library(
'metadata_manager.cpp',
'migration_chunk_cloner_source_legacy.cpp',
'migration_chunk_cloner_source.cpp',
+ 'migration_coordinator.cpp',
'migration_destination_manager.cpp',
'migration_session_id.cpp',
'migration_source_manager.cpp',
@@ -74,7 +75,7 @@ env.Library(
'start_chunk_clone_request.cpp',
env.Idlc('sharding_runtime_d_params.idl')[0],
env.Idlc('range_deletion_task.idl')[0],
-
+ env.Idlc('migration_coordinator_document.idl')[0],
],
LIBDEPS=[
'$BUILD_DIR/mongo/db/catalog/multi_index_block',
diff --git a/src/mongo/db/s/migration_coordinator.cpp b/src/mongo/db/s/migration_coordinator.cpp
new file mode 100644
index 00000000000..f1deb950a17
--- /dev/null
+++ b/src/mongo/db/s/migration_coordinator.cpp
@@ -0,0 +1,103 @@
+/**
+ * Copyright (C) 2019-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.
+ */
+
+#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kSharding
+
+#include "mongo/platform/basic.h"
+
+#include "mongo/db/s/migration_coordinator.h"
+
+#include "mongo/db/s/migration_util.h"
+#include "mongo/db/s/range_deletion_task_gen.h"
+#include "mongo/util/log.h"
+
+namespace mongo {
+namespace migrationutil {
+
+MigrationCoordinator::MigrationCoordinator(OperationContext* opCtx,
+ UUID migrationId,
+ ShardId donorShard,
+ ShardId recipientShard,
+ NamespaceString collectionNamespace,
+ UUID collectionUuid,
+ ChunkRange range)
+ : _migrationInfo(migrationId,
+ std::move(collectionNamespace),
+ collectionUuid,
+ std::move(donorShard),
+ std::move(recipientShard),
+ std::move(range)) {}
+
+MigrationCoordinator::~MigrationCoordinator() = default;
+
+void MigrationCoordinator::startMigration(OperationContext* opCtx, bool waitForDelete) {
+ migrationutil::persistMigrationCoordinatorLocally(opCtx, _migrationInfo);
+
+ RangeDeletionTask donorDeletionTask(_migrationInfo.getId(),
+ _migrationInfo.getNss(),
+ _migrationInfo.getCollectionUuid(),
+ _migrationInfo.getDonorShardId(),
+ _migrationInfo.getRange(),
+ waitForDelete ? CleanWhenEnum::kNow
+ : CleanWhenEnum::kDelayed);
+ donorDeletionTask.setPending(true);
+
+ LOG(0) << "Persisting range deletion task on donor for migration " << _migrationInfo.getId();
+ migrationutil::persistRangeDeletionTaskLocally(opCtx, donorDeletionTask);
+}
+
+void MigrationCoordinator::commitMigrationOnDonorAndRecipient(OperationContext* opCtx) {
+ LOG(0) << "Committing migration on donor and recipient for migration "
+ << _migrationInfo.getId();
+ LOG(0) << "Deleting range deletion task on recipient for migration " << _migrationInfo.getId();
+
+ migrationutil::deleteRangeDeletionTaskOnRecipient(
+ opCtx, _migrationInfo.getRecipientShardId(), _migrationInfo.getId());
+
+ LOG(0) << "Marking range deletion task on donor as ready for processing for migration "
+ << _migrationInfo.getId();
+ migrationutil::markAsReadyRangeDeletionTaskLocally(opCtx, _migrationInfo.getId());
+}
+
+void MigrationCoordinator::abortMigrationOnDonorAndRecipient(OperationContext* opCtx) {
+ LOG(0) << "Aborting migration on donor and recipient for migration " << _migrationInfo.getId();
+ LOG(0) << "Deleting range deletion task on donor for migration " << _migrationInfo.getId();
+
+ migrationutil::deleteRangeDeletionTaskLocally(opCtx, _migrationInfo.getId());
+
+ LOG(0) << "Marking range deletion task on recipient as ready for processing for migration "
+ << _migrationInfo.getId();
+
+ migrationutil::markAsReadyRangeDeletionTaskOnRecipient(
+ opCtx, _migrationInfo.getRecipientShardId(), _migrationInfo.getId());
+}
+
+} // namespace migrationutil
+
+} // namespace mongo
diff --git a/src/mongo/db/s/migration_coordinator.h b/src/mongo/db/s/migration_coordinator.h
new file mode 100644
index 00000000000..c0c2327a2c2
--- /dev/null
+++ b/src/mongo/db/s/migration_coordinator.h
@@ -0,0 +1,88 @@
+/**
+ * Copyright (C) 2019-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.
+ */
+
+#pragma once
+
+#include "mongo/db/s/migration_coordinator_document_gen.h"
+#include "mongo/s/catalog/type_chunk.h"
+
+namespace mongo {
+
+namespace migrationutil {
+/**
+ * Manages the migration commit/abort process, including updates to config.rangeDeletions on the
+ * donor and the recipient, and updates to the routing table on the config server.
+ *
+ * TODO (SERVER-44716): Implement commit/abort/recovery logic on the config server.
+ */
+class MigrationCoordinator {
+public:
+ MigrationCoordinator(OperationContext* opCtx,
+ UUID migrationId,
+ ShardId donorShard,
+ ShardId recipientShard,
+ NamespaceString collectionNamespace,
+ UUID collectionUuid,
+ ChunkRange range);
+ MigrationCoordinator(const MigrationCoordinator&) = delete;
+ MigrationCoordinator& operator=(const MigrationCoordinator&) = delete;
+ MigrationCoordinator(MigrationCoordinator&&) = delete;
+ MigrationCoordinator& operator=(MigrationCoordinator&&) = delete;
+
+ ~MigrationCoordinator();
+
+ /**
+ * Initializes persistent state required to ensure that orphaned ranges are properly handled,
+ * even after failover, by doing the following:
+ *
+ * 1) Inserts a document into the local config.migrationCoordinators with the lsid, txnNumber,
+ * and recipientId and waits for majority writeConcern.
+ * 2) Inserts a document into the local config.rangeDeletions with the collectionUUID, range to
+ * delete, and "pending: true" and waits for majority writeConcern.
+ */
+ void startMigration(OperationContext* opCtx, bool waitForDelete);
+
+ /**
+ * Deletes the range deletion task from the recipient node and marks the range deletion task on
+ * the donor as ready to be processed.
+ */
+ void commitMigrationOnDonorAndRecipient(OperationContext* opCtx);
+
+ /**
+ * Deletes the range deletion task from the donor node and marks the range deletion task on the
+ * recipient node as ready to be processed.
+ */
+ void abortMigrationOnDonorAndRecipient(OperationContext* opCtx);
+
+private:
+ MigrationCoordinatorDocument _migrationInfo;
+};
+
+} // namespace migrationutil
+} // namespace mongo
diff --git a/src/mongo/db/s/migration_coordinator_document.idl b/src/mongo/db/s/migration_coordinator_document.idl
new file mode 100644
index 00000000000..ff12d7e51f5
--- /dev/null
+++ b/src/mongo/db/s/migration_coordinator_document.idl
@@ -0,0 +1,65 @@
+# Copyright (C) 2019-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.
+#
+
+# This file defines the format of documents stored in config.rangeDeletions. Each document
+# represents a chunk range to be deleted by the CollectionRangeDeleter.
+
+global:
+ cpp_namespace: "mongo"
+
+imports:
+ - "mongo/idl/basic_types.idl"
+ - "mongo/s/sharding_types.idl"
+ - "mongo/s/chunk_range.idl"
+ - "mongo/db/logical_session_id.idl"
+
+structs:
+ migrationCoordinatorDocument:
+ description: "Represents an in-progress migration on the migration donor."
+ generate_comparison_operators: false
+ strict: true
+ fields:
+ _id:
+ type: uuid
+ description: "A unique identifier for the migration."
+ cpp_name: id
+ nss:
+ type: namespacestring
+ description: "The namespace of the collection that the chunk belongs to."
+ collectionUuid:
+ type: uuid
+ description: "The UUID of the collection that the chunk belongs to."
+ donorShardId:
+ type: shard_id
+ description: "The shard from which the chunk is being migrated."
+ recipientShardId:
+ type: shard_id
+ description: "The shard to which the chunk is being migrated."
+ range:
+ type: chunk_range
+ description: "The range being migrated."
diff --git a/src/mongo/db/s/migration_util.cpp b/src/mongo/db/s/migration_util.cpp
index afda204d544..bd5e2ac09da 100644
--- a/src/mongo/db/s/migration_util.cpp
+++ b/src/mongo/db/s/migration_util.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018-present MongoDB, Inc.
+ * Copyright (C) 2019-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,
@@ -37,12 +37,19 @@
#include "mongo/bson/bsonobjbuilder.h"
#include "mongo/client/query.h"
#include "mongo/db/catalog_raii.h"
+#include "mongo/db/dbdirectclient.h"
+#include "mongo/db/logical_session_cache.h"
#include "mongo/db/namespace_string.h"
+#include "mongo/db/ops/write_ops.h"
+#include "mongo/db/repl/repl_client_info.h"
#include "mongo/db/s/collection_sharding_runtime.h"
#include "mongo/db/s/shard_filtering_metadata_refresh.h"
+#include "mongo/db/write_concern.h"
#include "mongo/executor/task_executor_pool.h"
#include "mongo/executor/thread_pool_task_executor.h"
+#include "mongo/rpc/get_status_from_command_result.h"
#include "mongo/s/catalog/type_chunk.h"
+#include "mongo/s/client/shard.h"
#include "mongo/s/grid.h"
#include "mongo/util/log.h"
@@ -55,6 +62,27 @@ const char kDestinationShard[] = "destination";
const char kIsDonorShard[] = "isDonorShard";
const char kChunk[] = "chunk";
const char kCollection[] = "collection";
+
+const WriteConcernOptions kMajorityWriteConcern(WriteConcernOptions::kMajority,
+ WriteConcernOptions::SyncMode::UNSET,
+ WriteConcernOptions::kNoTimeout);
+
+template <typename Cmd>
+void sendToRecipient(OperationContext* opCtx, const ShardId& recipientId, const Cmd& cmd) {
+ auto recipientShard =
+ uassertStatusOK(Grid::get(opCtx)->shardRegistry()->getShard(opCtx, recipientId));
+
+ LOG(1) << "Sending request " << cmd.toBSON({}) << " to recipient.";
+
+ auto response = recipientShard->runCommandWithFixedRetryAttempts(
+ opCtx,
+ ReadPreferenceSetting{ReadPreference::PrimaryOnly},
+ "config",
+ cmd.toBSON({}),
+ Shard::RetryPolicy::kIdempotent);
+ uassertStatusOK(Shard::CommandResponse::getEffectiveStatus(response));
+}
+
} // namespace
BSONObj makeMigrationStatusDocument(const NamespaceString& nss,
@@ -118,7 +146,7 @@ bool submitRangeDeletionTask(OperationContext* opCtx, const RangeDeletionTask& d
return false;
}
- auto notification = css->cleanUpRange(*deletionTask.getRange(), whenToClean);
+ auto notification = css->cleanUpRange(deletionTask.getRange(), whenToClean);
if (notification.ready() && !notification.waitStatus(opCtx).isOK()) {
LOG(0) << "Failed to resubmit range for deletion: "
@@ -170,6 +198,80 @@ void resubmitRangeDeletionsOnStepUp(ServiceContext* serviceContext) {
});
}
-} // namespace migrationutil
+void persistMigrationCoordinatorLocally(OperationContext* opCtx,
+ const MigrationCoordinatorDocument& migrationDoc) {
+ PersistentTaskStore<MigrationCoordinatorDocument> store(
+ opCtx, NamespaceString::kMigrationCoordinatorsNamespace);
+ try {
+ store.add(opCtx, migrationDoc);
+ } catch (const ExceptionFor<ErrorCodes::DuplicateKey>& e) {
+ // Convert a DuplicateKey error to an anonymous error.
+ uasserted(
+ 31374,
+ str::stream() << "While attempting to write migration information for migration "
+ << ", found document with the same migration id. Attempted migration: "
+ << migrationDoc.toBSON());
+ }
+}
+
+void persistRangeDeletionTaskLocally(OperationContext* opCtx,
+ const RangeDeletionTask& deletionTask) {
+ PersistentTaskStore<RangeDeletionTask> store(opCtx, NamespaceString::kRangeDeletionNamespace);
+ try {
+ store.add(opCtx, deletionTask);
+ } catch (const ExceptionFor<ErrorCodes::DuplicateKey>& e) {
+ // Convert a DuplicateKey error to an anonymous error.
+ uasserted(31375,
+ str::stream() << "While attempting to write range deletion task for migration "
+ << ", found document with the same migration id. Attempted range "
+ "deletion task: "
+ << deletionTask.toBSON());
+ }
+}
+
+void deleteRangeDeletionTaskOnRecipient(OperationContext* opCtx,
+ const ShardId& recipientId,
+ const UUID& migrationId) {
+ write_ops::Delete deleteOp(NamespaceString::kRangeDeletionNamespace);
+ write_ops::DeleteOpEntry query(BSON(RangeDeletionTask::kIdFieldName << migrationId),
+ false /*multi*/);
+ deleteOp.setDeletes({query});
+ sendToRecipient(opCtx, recipientId, deleteOp);
+}
+
+void deleteRangeDeletionTaskLocally(OperationContext* opCtx, const UUID& deletionTaskId) {
+ PersistentTaskStore<RangeDeletionTask> store(opCtx, NamespaceString::kRangeDeletionNamespace);
+ store.remove(opCtx, QUERY(RangeDeletionTask::kIdFieldName << deletionTaskId));
+}
+
+void deleteRangeDeletionTasksForCollectionLocally(OperationContext* opCtx,
+ const UUID& collectionUuid) {
+ PersistentTaskStore<RangeDeletionTask> store(opCtx, NamespaceString::kRangeDeletionNamespace);
+ store.remove(opCtx, QUERY(RangeDeletionTask::kCollectionUuidFieldName << collectionUuid));
+}
+
+void markAsReadyRangeDeletionTaskOnRecipient(OperationContext* opCtx,
+ const ShardId& recipientId,
+ const UUID& migrationId) {
+ write_ops::Update updateOp(NamespaceString::kRangeDeletionNamespace);
+ auto queryFilter = BSON(RangeDeletionTask::kIdFieldName << migrationId);
+ auto updateModification = write_ops::UpdateModification(
+ BSON("$unset" << BSON(RangeDeletionTask::kPendingFieldName << "")));
+ write_ops::UpdateOpEntry updateEntry(queryFilter, updateModification);
+ updateEntry.setMulti(false);
+ updateEntry.setUpsert(false);
+ updateOp.setUpdates({updateEntry});
+
+ sendToRecipient(opCtx, recipientId, updateOp);
+}
+
+void markAsReadyRangeDeletionTaskLocally(OperationContext* opCtx, const UUID& migrationId) {
+ PersistentTaskStore<RangeDeletionTask> store(opCtx, NamespaceString::kRangeDeletionNamespace);
+ auto query = QUERY(RangeDeletionTask::kIdFieldName << migrationId);
+ auto update = BSON("$unset" << BSON(RangeDeletionTask::kPendingFieldName << ""));
+
+ store.update(opCtx, query, update);
+}
+} // namespace migrationutil
} // namespace mongo
diff --git a/src/mongo/db/s/migration_util.h b/src/mongo/db/s/migration_util.h
index 6ba282e321b..f3119de0ef6 100644
--- a/src/mongo/db/s/migration_util.h
+++ b/src/mongo/db/s/migration_util.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018-present MongoDB, Inc.
+ * Copyright (C) 2019-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,
@@ -29,6 +29,9 @@
#pragma once
+#include "mongo/db/logical_session_id.h"
+#include "mongo/db/repl/optime.h"
+#include "mongo/db/s/migration_coordinator_document_gen.h"
#include "mongo/db/s/persistent_task_store.h"
#include "mongo/db/s/range_deletion_task_gen.h"
#include "mongo/s/catalog/type_chunk.h"
@@ -81,6 +84,56 @@ void submitPendingDeletions(OperationContext* opCtx);
// Asynchronously calls submitPendingDeletions using the fixed executor pool.
void resubmitRangeDeletionsOnStepUp(ServiceContext* serviceContext);
-} // namespace migrationutil
+/**
+ * Writes the migration coordinator document to config.migrationCoordinators and waits for majority
+ * write concern.
+ */
+void persistMigrationCoordinatorLocally(OperationContext* opCtx,
+ const MigrationCoordinatorDocument& migrationDoc);
+
+/**
+ * Writes the range deletion task document to config.rangeDeletions and waits for majority write
+ * concern.
+ */
+void persistRangeDeletionTaskLocally(OperationContext* opCtx,
+ const RangeDeletionTask& deletionTask);
+
+/**
+ * Deletes the range deletion task document with the specified id from config.rangeDeletions and
+ * waits for majority write concern.
+ */
+void deleteRangeDeletionTaskLocally(OperationContext* opCtx, const UUID& deletionTaskId);
+
+/**
+ * Deletes all range deletion task documents with the specified collection UUID from
+ * config.rangeDeletions and waits for majority write concern.
+ */
+void deleteRangeDeletionTasksForCollectionLocally(OperationContext* opCtx,
+ const UUID& collectionUuid);
+
+/**
+ * Deletes the range deletion task document with the specified id from config.rangeDeletions on the
+ * specified shard and waits for majority write concern.
+ */
+void deleteRangeDeletionTaskOnRecipient(OperationContext* opCtx,
+ const ShardId& recipientId,
+ const UUID& migrationId);
+/**
+ * Removes the 'pending' flag from the range deletion task document with the specified id from
+ * config.rangeDeletions and waits for majority write concern. This marks the range as ready for
+ * deletion.
+ */
+void markAsReadyRangeDeletionTaskLocally(OperationContext* opCtx, const UUID& migrationId);
+
+
+/**
+ * Removes the 'pending' flag from the range deletion task document with the specified id from
+ * config.rangeDeletions on the specified shard and waits for majority write concern. This marks the
+ * range as ready for deletion.
+ */
+void markAsReadyRangeDeletionTaskOnRecipient(OperationContext* opCtx,
+ const ShardId& recipientId,
+ const UUID& migrationId);
+} // namespace migrationutil
} // namespace mongo
diff --git a/src/mongo/db/s/migration_util_test.cpp b/src/mongo/db/s/migration_util_test.cpp
index 0496e64388c..f93471b2141 100644
--- a/src/mongo/db/s/migration_util_test.cpp
+++ b/src/mongo/db/s/migration_util_test.cpp
@@ -261,11 +261,12 @@ void addRangeToReceivingChunks(OperationContext* opCtx,
}
RangeDeletionTask createDeletionTask(NamespaceString nss, const UUID& uuid, int min, int max) {
- RangeDeletionTask task{nss, uuid, CleanWhenEnum::kNow};
-
- task.setRange(ChunkRange{BSON("_id" << min), BSON("_id" << max)});
-
- return task;
+ return RangeDeletionTask(UUID::gen(),
+ nss,
+ uuid,
+ ShardId("donorShard"),
+ ChunkRange{BSON("_id" << min), BSON("_id" << max)},
+ CleanWhenEnum::kDelayed);
}
// Test that overlappingRangeQuery() can handle the cases that we expect to encounter.
diff --git a/src/mongo/db/s/range_deletion_task.idl b/src/mongo/db/s/range_deletion_task.idl
index 9af29c5181d..1c265f2656a 100644
--- a/src/mongo/db/s/range_deletion_task.idl
+++ b/src/mongo/db/s/range_deletion_task.idl
@@ -31,19 +31,12 @@
global:
cpp_namespace: "mongo"
- cpp_includes : "mongo/s/catalog/type_chunk.h"
imports:
- "mongo/idl/basic_types.idl"
-
-types:
- chunkRangeType:
- description: "Represents the bounds of a chunk range. See ChunkRange for the semantics of
- the bounds."
- bson_serialization_type: object
- cpp_type: "mongo::ChunkRange"
- serializer: "mongo::ChunkRange::toBSON"
- deserializer: "mongo::ChunkRange::fromBSONThrowing"
+ - "mongo/s/sharding_types.idl"
+ - "mongo/db/logical_session_id.idl"
+ - "mongo/s/chunk_range.idl"
enums:
CleanWhen:
@@ -58,17 +51,22 @@ structs:
description: "Represents a chunk range to be deleted by the range deleter."
strict: false
fields:
+ _id:
+ type: uuid
+ description: "A unique identifier for the migration."
+ cpp_name: id
nss:
type: namespacestring
description: "The namespace of the collection that the chunk belongs to."
collectionUuid:
type: uuid
description: "The UUID of the collection that the chunk belongs to."
+ donorShardId:
+ type: shard_id
+ description: "The shard from which the chunk was migrated."
range:
- type: chunkRangeType
- description: "The range to be deleted. Needs to be optional since ChunkRange
- doesn't have a default constructor."
- optional: true
+ type: chunk_range
+ description: "The range to be deleted."
pending:
type: bool
description: "Flag that is present if the range is not yet ready for deletion"
diff --git a/src/mongo/s/catalog/type_chunk.h b/src/mongo/s/catalog/type_chunk.h
index 1905280392b..2e64e86d3dc 100644
--- a/src/mongo/s/catalog/type_chunk.h
+++ b/src/mongo/s/catalog/type_chunk.h
@@ -117,6 +117,13 @@ public:
ChunkRange unionWith(ChunkRange const& other) const;
private:
+ // For use with IDL parsing - limited to friend access only.
+ ChunkRange() = default;
+
+ // Make the IDL generated parser a friend
+ friend class RangeDeletionTask;
+ friend class MigrationCoordinatorDocument;
+
BSONObj _minKey;
BSONObj _maxKey;
};
diff --git a/src/mongo/s/chunk_range.idl b/src/mongo/s/chunk_range.idl
new file mode 100644
index 00000000000..a60701bf952
--- /dev/null
+++ b/src/mongo/s/chunk_range.idl
@@ -0,0 +1,48 @@
+# Copyright (C) 2019-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.
+#
+
+# IDL type for the ChunkRange class
+
+global:
+ cpp_namespace: "mongo"
+ cpp_includes:
+ - "mongo/s/catalog/type_chunk.h"
+
+imports:
+ - "mongo/idl/basic_types.idl"
+
+types:
+ # Note that in order to use this type for a non-optional field, you must add the IDL struct as a
+ # friend class of ChunkRange so that it can access its default constructor.
+ chunk_range:
+ description: "Represents the bounds of a chunk range. See ChunkRange for the semantics of
+ the bounds."
+ bson_serialization_type: object
+ cpp_type: "mongo::ChunkRange"
+ serializer: "mongo::ChunkRange::toBSON"
+ deserializer: "mongo::ChunkRange::fromBSONThrowing"
diff --git a/src/mongo/util/uuid.h b/src/mongo/util/uuid.h
index ae82c800264..5f7e27d35b9 100644
--- a/src/mongo/util/uuid.h
+++ b/src/mongo/util/uuid.h
@@ -76,6 +76,7 @@ class UUID {
friend class LogicalSessionToClient;
friend class LogicalSessionIdToClient;
friend class LogicalSessionFromClient;
+ friend class MigrationCoordinatorDocument;
friend class RangeDeletionTask;
friend class ResolvedKeyId;
friend class repl::CollectionInfo;