summaryrefslogtreecommitdiff
path: root/src/mongo/db/s/migration_util.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/s/migration_util.cpp')
-rw-r--r--src/mongo/db/s/migration_util.cpp99
1 files changed, 39 insertions, 60 deletions
diff --git a/src/mongo/db/s/migration_util.cpp b/src/mongo/db/s/migration_util.cpp
index 1916bb0abff..ced6c1bc2a4 100644
--- a/src/mongo/db/s/migration_util.cpp
+++ b/src/mongo/db/s/migration_util.cpp
@@ -347,7 +347,6 @@ bool deletionTaskUuidMatchesFilteringMetadataUuid(
ExecutorFuture<void> cleanUpRange(ServiceContext* serviceContext,
const std::shared_ptr<executor::ThreadPoolTaskExecutor>& executor,
const RangeDeletionTask& deletionTask) {
-
return AsyncTry([=]() mutable {
ThreadClient tc(kRangeDeletionThreadName, serviceContext);
{
@@ -358,33 +357,45 @@ ExecutorFuture<void> cleanUpRange(ServiceContext* serviceContext,
auto opCtx = uniqueOpCtx.get();
opCtx->setAlwaysInterruptAtStepDownOrUp();
- AutoGetCollection autoColl(opCtx, deletionTask.getNss(), MODE_IS);
- auto csr = CollectionShardingRuntime::get(opCtx, deletionTask.getNss());
- // Keep the collection metadata from changing for the rest of this scope.
- auto csrLock = CollectionShardingRuntime::CSRLock::lockShared(opCtx, csr);
- auto optCollDescr = csr->getCurrentMetadataIfKnown();
- uassert(
- ErrorCodes::RangeDeletionAbandonedBecauseCollectionWithUUIDDoesNotExist,
- str::stream()
- << "Even after forced refresh, filtering metadata for namespace in "
- "deletion task "
- << (optCollDescr
- ? (optCollDescr->isSharded()
- ? " has UUID that does not match UUID of the deletion task"
- : " is unsharded")
- : " is not known"),
- deletionTaskUuidMatchesFilteringMetadataUuid(opCtx, optCollDescr, deletionTask));
-
- LOGV2(22026,
- "Submitting range deletion task",
- "deletionTask"_attr = redact(deletionTask.toBSON()),
- "migrationId"_attr = deletionTask.getId());
-
- const auto whenToClean = deletionTask.getWhenToClean() == CleanWhenEnum::kNow
- ? CollectionShardingRuntime::kNow
- : CollectionShardingRuntime::kDelayed;
-
- return csr->cleanUpRange(deletionTask.getRange(), deletionTask.getId(), whenToClean);
+ const NamespaceString& nss = deletionTask.getNss();
+
+ while (true) {
+ {
+ // Holding the locks while enqueueing the task protects against possible
+ // concurrent cleanups of the filtering metadata, that be serialized
+ AutoGetCollection autoColl(opCtx, nss, MODE_IS);
+ auto csr = CollectionShardingRuntime::get(opCtx, nss);
+ auto csrLock = CollectionShardingRuntime::CSRLock::lockShared(opCtx, csr);
+ auto optCollDescr = csr->getCurrentMetadataIfKnown();
+
+ if (optCollDescr) {
+ uassert(ErrorCodes::
+ RangeDeletionAbandonedBecauseCollectionWithUUIDDoesNotExist,
+ str::stream() << "Filtering metadata for " << nss
+ << (optCollDescr->isSharded()
+ ? " has UUID that does not match UUID of "
+ "the deletion task"
+ : " is unsharded"),
+ deletionTaskUuidMatchesFilteringMetadataUuid(
+ opCtx, optCollDescr, deletionTask));
+
+ LOGV2(22026,
+ "Submitting range deletion task",
+ "deletionTask"_attr = redact(deletionTask.toBSON()),
+ "migrationId"_attr = deletionTask.getId());
+
+ const auto whenToClean =
+ deletionTask.getWhenToClean() == CleanWhenEnum::kNow
+ ? CollectionShardingRuntime::kNow
+ : CollectionShardingRuntime::kDelayed;
+
+ return csr->cleanUpRange(
+ deletionTask.getRange(), deletionTask.getId(), whenToClean);
+ }
+ }
+
+ refreshFilteringMetadataUntilSuccess(opCtx, nss);
+ }
})
.until([](Status status) mutable {
// Resubmit the range for deletion on a RangeOverlapConflict error.
@@ -405,8 +416,6 @@ ExecutorFuture<void> submitRangeDeletionTask(OperationContext* opCtx,
stdx::lock_guard<Client> lk(*tc.get());
tc->setSystemOperationKillableByStepdown(lk);
}
- auto uniqueOpCtx = tc->makeOperationContext();
- auto opCtx = uniqueOpCtx.get();
uassert(
ErrorCodes::ResumableRangeDeleterDisabled,
@@ -415,36 +424,6 @@ ExecutorFuture<void> submitRangeDeletionTask(OperationContext* opCtx,
<< " because the disableResumableRangeDeleter server parameter is set to true",
!disableResumableRangeDeleter.load());
- // Make sure the collection metadata is up-to-date before submitting.
- boost::optional<CollectionMetadata> optCollDescr;
- {
- AutoGetCollection autoColl(opCtx, deletionTask.getNss(), MODE_IS);
- auto csr = CollectionShardingRuntime::get(opCtx, deletionTask.getNss());
- optCollDescr = csr->getCurrentMetadataIfKnown();
- }
-
- if (!deletionTaskUuidMatchesFilteringMetadataUuid(opCtx, optCollDescr, deletionTask)) {
-
- // If the collection's filtering metadata is not known, is unsharded, or its
- // UUID does not match the UUID of the deletion task, force a filtering metadata
- // refresh, because this node may have just stepped up and therefore may have a
- // stale cache.
- LOGV2(22024,
- "Filtering metadata for this range deletion task may be outdated; "
- "forcing refresh",
- "deletionTask"_attr = redact(deletionTask.toBSON()),
- "error"_attr =
- (optCollDescr ? (optCollDescr->isSharded()
- ? "Collection has UUID that does not match "
- "UUID of the deletion task"
- : "Collection is unsharded")
- : "Collection's sharding state is not known"),
- "namespace"_attr = deletionTask.getNss(),
- "migrationId"_attr = deletionTask.getId());
-
- refreshFilteringMetadataUntilSuccess(opCtx, deletionTask.getNss());
- }
-
return AsyncTry([=]() {
return cleanUpRange(serviceContext, executor, deletionTask)
.onError<ErrorCodes::KeyPatternShorterThanBound>([=](Status status) {