summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorPierlauro Sciarelli <pierlauro.sciarelli@mongodb.com>2021-03-11 17:30:12 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-03-11 18:42:46 +0000
commit254838f3481faa1b967d4c5798473b8bf5f4d384 (patch)
treea59e4573cf19721b2d0e47743e0c2cd02da90055 /src/mongo
parente2dd9ca37c2027541fe1eb8b4a14c767d4384d2a (diff)
downloadmongo-254838f3481faa1b967d4c5798473b8bf5f4d384.tar.gz
SERVER-55113 Split rename/range-deletion procedures in idempotent steps
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/namespace_string.cpp2
-rw-r--r--src/mongo/db/namespace_string.h3
-rw-r--r--src/mongo/db/s/range_deletion_util.cpp50
-rw-r--r--src/mongo/db/s/range_deletion_util.h25
-rw-r--r--src/mongo/db/s/shardsvr_rename_collection_participant_command.cpp10
5 files changed, 70 insertions, 20 deletions
diff --git a/src/mongo/db/namespace_string.cpp b/src/mongo/db/namespace_string.cpp
index ae08e4c640c..352d65311f4 100644
--- a/src/mongo/db/namespace_string.cpp
+++ b/src/mongo/db/namespace_string.cpp
@@ -93,6 +93,8 @@ const NamespaceString NamespaceString::kIndexBuildEntryNamespace(NamespaceString
"system.indexBuilds");
const NamespaceString NamespaceString::kRangeDeletionNamespace(NamespaceString::kConfigDb,
"rangeDeletions");
+const NamespaceString NamespaceString::kRangeDeletionForRenameNamespace(NamespaceString::kConfigDb,
+ "rangeDeletionsForRename");
const NamespaceString NamespaceString::kConfigReshardingOperationsNamespace(
NamespaceString::kConfigDb, "reshardingOperations");
diff --git a/src/mongo/db/namespace_string.h b/src/mongo/db/namespace_string.h
index 02265c9641a..b0558eea4a8 100644
--- a/src/mongo/db/namespace_string.h
+++ b/src/mongo/db/namespace_string.h
@@ -141,6 +141,9 @@ public:
// Namespace for pending range deletions.
static const NamespaceString kRangeDeletionNamespace;
+ // Namespace containing pending range deletions snapshots for rename operations.
+ static const NamespaceString kRangeDeletionForRenameNamespace;
+
// Namespace for the coordinator's resharding operation state.
static const NamespaceString kConfigReshardingOperationsNamespace;
diff --git a/src/mongo/db/s/range_deletion_util.cpp b/src/mongo/db/s/range_deletion_util.cpp
index 599fa90d6a4..03a1b3a1540 100644
--- a/src/mongo/db/s/range_deletion_util.cpp
+++ b/src/mongo/db/s/range_deletion_util.cpp
@@ -411,8 +411,6 @@ ExecutorFuture<void> waitForDeletionsToMajorityReplicate(
});
}
-} // namespace
-
std::vector<RangeDeletionTask> getPersistentRangeDeletionTasks(OperationContext* opCtx,
const NamespaceString& nss) {
std::vector<RangeDeletionTask> tasks;
@@ -428,17 +426,51 @@ std::vector<RangeDeletionTask> getPersistentRangeDeletionTasks(OperationContext*
return tasks;
}
-void storeRangeDeletionTasks(OperationContext* opCtx, std::vector<RangeDeletionTask>& tasks) {
- PersistentTaskStore<RangeDeletionTask> store(NamespaceString::kRangeDeletionNamespace);
- for (const auto& deletionTask : tasks) {
- store.add(opCtx, deletionTask);
+} // namespace
+
+void snapshotRangeDeletionsForRename(OperationContext* opCtx,
+ const NamespaceString& fromNss,
+ const NamespaceString& toNss) {
+ auto rangeDeletionTasks = getPersistentRangeDeletionTasks(opCtx, fromNss);
+ PersistentTaskStore<RangeDeletionTask> store(NamespaceString::kRangeDeletionForRenameNamespace);
+ for (auto& task : rangeDeletionTasks) {
+ task.setNss(toNss); // Associate task to the new namespace
+ store.add(opCtx, task);
}
}
-void deleteRangeDeletionTasks(OperationContext* opCtx, const NamespaceString& nss) {
- PersistentTaskStore<RangeDeletionTask> store(NamespaceString::kRangeDeletionNamespace);
+void restoreRangeDeletionTasksForRename(OperationContext* opCtx, const NamespaceString& nss) {
+ PersistentTaskStore<RangeDeletionTask> rangeDeletionsForRenameStore(
+ NamespaceString::kRangeDeletionForRenameNamespace);
+ PersistentTaskStore<RangeDeletionTask> rangeDeletionsStore(
+ NamespaceString::kRangeDeletionNamespace);
+
const auto query = QUERY(RangeDeletionTask::kNssFieldName << nss.ns());
- store.remove(opCtx, query);
+
+ // Remove eventual leftovers from a previously uncompleted restore
+ rangeDeletionsStore.remove(opCtx, query);
+
+ rangeDeletionsForRenameStore.forEach(opCtx, query, [&](const RangeDeletionTask& deletionTask) {
+ auto task = deletionTask;
+ task.setId(UUID::gen()); // Assign a new id to prevent duplicate key errors
+ rangeDeletionsStore.add(opCtx, task);
+ return true;
+ });
+}
+
+void deleteRangeDeletionTasksForRename(OperationContext* opCtx,
+ const NamespaceString& fromNss,
+ const NamespaceString& toNss) {
+ // Delete range deletion tasks associated to the source collection
+ PersistentTaskStore<RangeDeletionTask> rangeDeletionsStore(
+ NamespaceString::kRangeDeletionNamespace);
+ rangeDeletionsStore.remove(opCtx, QUERY(RangeDeletionTask::kNssFieldName << fromNss.ns()));
+
+ // Delete already restored snapshots associated to the target collection
+ PersistentTaskStore<RangeDeletionTask> rangeDeletionsForRenameStore(
+ NamespaceString::kRangeDeletionForRenameNamespace);
+ rangeDeletionsForRenameStore.remove(opCtx,
+ QUERY(RangeDeletionTask::kNssFieldName << toNss.ns()));
}
diff --git a/src/mongo/db/s/range_deletion_util.h b/src/mongo/db/s/range_deletion_util.h
index 6045975a293..bff30e76299 100644
--- a/src/mongo/db/s/range_deletion_util.h
+++ b/src/mongo/db/s/range_deletion_util.h
@@ -76,10 +76,27 @@ SharedSemiFuture<void> removeDocumentsInRange(
Seconds delayForActiveQueriesOnSecondariesToComplete,
Milliseconds delayBetweenBatches);
-std::vector<RangeDeletionTask> getPersistentRangeDeletionTasks(OperationContext* opCtx,
- const NamespaceString& nss);
-void storeRangeDeletionTasks(OperationContext* opCtx, std::vector<RangeDeletionTask>& tasks);
+/**
+ * - Retrieves source collection's persistent range deletion tasks from `config.rangeDeletions`
+ * - Associates tasks to the target collection
+ * - Stores tasks in `config.rangeDeletionsForRename`
+ */
+void snapshotRangeDeletionsForRename(OperationContext* opCtx,
+ const NamespaceString& fromNss,
+ const NamespaceString& toNss);
-void deleteRangeDeletionTasks(OperationContext* opCtx, const NamespaceString& nss);
+/**
+ * Copies `config.rangeDeletionsForRename` tasks for the specified namespace to
+ * `config.rangeDeletions`.
+ */
+void restoreRangeDeletionTasksForRename(OperationContext* opCtx, const NamespaceString& nss);
+
+/**
+ * - Deletes range deletion tasks for the FROM namespace from `config.rangeDeletions`.
+ * - Deletes range deletion tasks for the TO namespace from `config.rangeDeletionsForRename`
+ */
+void deleteRangeDeletionTasksForRename(OperationContext* opCtx,
+ const NamespaceString& fromNss,
+ const NamespaceString& toNss);
} // namespace mongo
diff --git a/src/mongo/db/s/shardsvr_rename_collection_participant_command.cpp b/src/mongo/db/s/shardsvr_rename_collection_participant_command.cpp
index fcf9da184b7..c0833d662db 100644
--- a/src/mongo/db/s/shardsvr_rename_collection_participant_command.cpp
+++ b/src/mongo/db/s/shardsvr_rename_collection_participant_command.cpp
@@ -109,19 +109,15 @@ public:
dropCollectionLocally(opCtx, toNss);
try {
- auto rangeDeletionTasks = getPersistentRangeDeletionTasks(opCtx, fromNss);
+ snapshotRangeDeletionsForRename(opCtx, fromNss, toNss);
// Rename the collection locally and clear the cache
validateAndRunRenameCollection(opCtx, fromNss, toNss, options);
uassertStatusOK(
shardmetadatautil::dropChunksAndDeleteCollectionsEntry(opCtx, fromNss));
- deleteRangeDeletionTasks(opCtx, toNss);
- for (auto& task : rangeDeletionTasks) {
- task.setId(UUID::gen());
- task.setNss(toNss);
- }
- storeRangeDeletionTasks(opCtx, rangeDeletionTasks);
+ restoreRangeDeletionTasksForRename(opCtx, toNss);
+ deleteRangeDeletionTasksForRename(opCtx, fromNss, toNss);
} catch (ExceptionFor<ErrorCodes::NamespaceNotFound>&) {
// It's ok for a participant shard to have no knowledge about a collection
LOGV2_DEBUG(