summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCheahuychou Mao <cheahuychou.mao@mongodb.com>2020-01-20 01:58:47 +0000
committerA. Jesse Jiryu Davis <jesse@mongodb.com>2020-01-27 15:40:41 -0500
commita8c79b41242dde27db00a60a17fe0d60f5fa3c8a (patch)
tree7a0a439b1f7c95b1b0edf68005a05dfc289d0794
parenta56f09f03498b68985df062db12d84f0b0c7d905 (diff)
downloadmongo-a8c79b41242dde27db00a60a17fe0d60f5fa3c8a.tar.gz
SERVER-45249 Make recipient wait for orphan cleanup before cloning indexes
-rw-r--r--jstests/libs/chunk_manipulation_util.js10
-rw-r--r--src/mongo/base/error_codes.yml2
-rw-r--r--src/mongo/db/s/clone_collection_options_from_primary_shard_cmd.cpp5
-rw-r--r--src/mongo/db/s/collection_sharding_runtime.cpp21
-rw-r--r--src/mongo/db/s/collection_sharding_runtime.h6
-rw-r--r--src/mongo/db/s/migration_destination_manager.cpp200
-rw-r--r--src/mongo/db/s/migration_destination_manager.h23
-rw-r--r--src/mongo/db/s/migration_source_manager.cpp4
-rw-r--r--src/mongo/db/s/range_deletion_util.cpp11
-rw-r--r--src/mongo/db/s/range_deletion_util_test.cpp15
10 files changed, 171 insertions, 126 deletions
diff --git a/jstests/libs/chunk_manipulation_util.js b/jstests/libs/chunk_manipulation_util.js
index 90ea743ecf3..bba74a17886 100644
--- a/jstests/libs/chunk_manipulation_util.js
+++ b/jstests/libs/chunk_manipulation_util.js
@@ -127,7 +127,7 @@ function configureMoveChunkFailPoint(shardConnection, stepNumber, mode) {
function waitForMoveChunkStep(shardConnection, stepNumber) {
var searchString = 'step ' + stepNumber, admin = shardConnection.getDB('admin');
- assert.between(migrateStepNames.copiedIndexes,
+ assert.between(migrateStepNames.deletedPriorDataInRange,
stepNumber,
migrateStepNames.done,
"incorrect stepNumber",
@@ -158,8 +158,8 @@ function waitForMoveChunkStep(shardConnection, stepNumber) {
}
var migrateStepNames = {
- copiedIndexes: 1,
- deletedPriorDataInRange: 2,
+ deletedPriorDataInRange: 1,
+ copiedIndexes: 2,
cloned: 3,
catchup: 4, // About to enter steady state.
steady: 5,
@@ -191,7 +191,7 @@ function proceedToMigrateStep(shardConnection, stepNumber) {
}
function configureMigrateFailPoint(shardConnection, stepNumber, mode) {
- assert.between(migrateStepNames.copiedIndexes,
+ assert.between(migrateStepNames.deletedPriorDataInRange,
stepNumber,
migrateStepNames.done,
"incorrect stepNumber",
@@ -208,7 +208,7 @@ function configureMigrateFailPoint(shardConnection, stepNumber, mode) {
function waitForMigrateStep(shardConnection, stepNumber) {
var searchString = 'step ' + stepNumber, admin = shardConnection.getDB('admin');
- assert.between(migrateStepNames.copiedIndexes,
+ assert.between(migrateStepNames.deletedPriorDataInRange,
stepNumber,
migrateStepNames.done,
"incorrect stepNumber",
diff --git a/src/mongo/base/error_codes.yml b/src/mongo/base/error_codes.yml
index baa25cc2821..71f09e7d92a 100644
--- a/src/mongo/base/error_codes.yml
+++ b/src/mongo/base/error_codes.yml
@@ -333,7 +333,7 @@ error_codes:
- {code: 297,name: HierarchicalAcquisitionLevelViolation}
- {code: 298,name: InvalidServerType}
- {code: 299,name: OCSPCertificateStatusRevoked}
- - {code: 300,name: RangeDeletionAbandonedDueToCollectionDrop}
+ - {code: 300,name: RangeDeletionAbandonedBecauseCollectionWithUUIDDoesNotExist}
- {code: 301,name: DataCorruptionDetected}
# Error codes 4000-8999 are reserved.
diff --git a/src/mongo/db/s/clone_collection_options_from_primary_shard_cmd.cpp b/src/mongo/db/s/clone_collection_options_from_primary_shard_cmd.cpp
index 963c1c660a2..7f7439ae15b 100644
--- a/src/mongo/db/s/clone_collection_options_from_primary_shard_cmd.cpp
+++ b/src/mongo/db/s/clone_collection_options_from_primary_shard_cmd.cpp
@@ -52,8 +52,11 @@ public:
void typedRun(OperationContext* opCtx) {
auto primaryShardId = ShardId(request().getPrimaryShard().toString());
+ auto collectionOptionsAndIndexes =
+ MigrationDestinationManager::getCollectionIndexesAndOptions(
+ opCtx, ns(), primaryShardId);
MigrationDestinationManager::cloneCollectionIndexesAndOptions(
- opCtx, ns(), primaryShardId);
+ opCtx, ns(), collectionOptionsAndIndexes);
// At the time this command is invoked, the config server primary has already written
// the collection's routing metadata, so sync from the config server
diff --git a/src/mongo/db/s/collection_sharding_runtime.cpp b/src/mongo/db/s/collection_sharding_runtime.cpp
index 93b4529d502..bef293677d8 100644
--- a/src/mongo/db/s/collection_sharding_runtime.cpp
+++ b/src/mongo/db/s/collection_sharding_runtime.cpp
@@ -248,7 +248,7 @@ SharedSemiFuture<void> CollectionShardingRuntime::cleanUpRange(ChunkRange const&
Status CollectionShardingRuntime::waitForClean(OperationContext* opCtx,
const NamespaceString& nss,
- OID const& epoch,
+ const UUID& collectionUuid,
ChunkRange orphanRange) {
while (true) {
boost::optional<SharedSemiFuture<void>> stillScheduled;
@@ -258,13 +258,13 @@ Status CollectionShardingRuntime::waitForClean(OperationContext* opCtx,
auto* const self = CollectionShardingRuntime::get(opCtx, nss);
stdx::lock_guard lk(self->_metadataManagerLock);
- // If the metadata was reset, the collection does not exist, or the collection was
- // dropped and recreated since the metadata manager was created, return an error.
- if (!self->_metadataManager || !autoColl.getCollection() ||
- autoColl.getCollection()->uuid() != self->_metadataManager->getCollectionUuid()) {
+ // If the metadata was reset, or the collection was dropped and recreated since the
+ // metadata manager was created, return an error.
+ if (!self->_metadataManager ||
+ (collectionUuid != self->_metadataManager->getCollectionUuid())) {
return {ErrorCodes::ConflictingOperationInProgress,
- "Collection being migrated was dropped or otherwise had its metadata "
- "reset"};
+ "Collection being migrated was dropped and created or otherwise had its "
+ "metadata reset"};
}
stillScheduled = self->_metadataManager->trackOrphanedDataCleanup(orphanRange);
@@ -278,7 +278,12 @@ Status CollectionShardingRuntime::waitForClean(OperationContext* opCtx,
log() << "Waiting for deletion of " << nss.ns() << " range " << orphanRange;
Status result = stillScheduled->getNoThrow(opCtx);
- if (!result.isOK()) {
+
+ // Swallow RangeDeletionAbandonedBecauseCollectionWithUUIDDoesNotExist error since the
+ // collection could either never exist or get dropped directly from the shard after
+ // the range deletion task got scheduled.
+ if (!result.isOK() &&
+ result != ErrorCodes::RangeDeletionAbandonedBecauseCollectionWithUUIDDoesNotExist) {
return result.withContext(str::stream() << "Failed to delete orphaned " << nss.ns()
<< " range " << orphanRange.toString());
}
diff --git a/src/mongo/db/s/collection_sharding_runtime.h b/src/mongo/db/s/collection_sharding_runtime.h
index 054f637440e..9e0e3a7f9e4 100644
--- a/src/mongo/db/s/collection_sharding_runtime.h
+++ b/src/mongo/db/s/collection_sharding_runtime.h
@@ -74,12 +74,12 @@ public:
const NamespaceString& nss);
/**
- * Tracks deletion of any documents within the range, returning when deletion is complete.
- * Throws if the collection is dropped while it sleeps.
+ * Waits for all ranges deletion tasks with UUID 'collectionUuid' overlapping range
+ * 'orphanRange' to be processed, even if the collection does not exist in the storage catalog.
*/
static Status waitForClean(OperationContext* opCtx,
const NamespaceString& nss,
- OID const& epoch,
+ const UUID& collectionUuid,
ChunkRange orphanRange);
ScopedCollectionMetadata getOrphansFilter(OperationContext* opCtx, bool isCollection) override;
diff --git a/src/mongo/db/s/migration_destination_manager.cpp b/src/mongo/db/s/migration_destination_manager.cpp
index 63d098e96a0..ad170299a1a 100644
--- a/src/mongo/db/s/migration_destination_manager.cpp
+++ b/src/mongo/db/s/migration_destination_manager.cpp
@@ -531,9 +531,8 @@ Status MigrationDestinationManager::startCommit(const MigrationSessionId& sessio
return Status::OK();
}
-void MigrationDestinationManager::cloneCollectionIndexesAndOptions(OperationContext* opCtx,
- const NamespaceString& nss,
- const ShardId& fromShardId) {
+CollectionOptionsAndIndexes MigrationDestinationManager::getCollectionIndexesAndOptions(
+ OperationContext* opCtx, const NamespaceString& nss, const ShardId& fromShardId) {
auto fromShard =
uassertStatusOK(Grid::get(opCtx)->shardRegistry()->getShard(opCtx, fromShardId));
@@ -542,73 +541,80 @@ void MigrationDestinationManager::cloneCollectionIndexesAndOptions(OperationCont
std::vector<BSONObj> donorIndexSpecs;
BSONObj donorIdIndexSpec;
BSONObj donorOptions;
- {
- // 0. Get the collection indexes and options from the donor shard.
-
- // Do not hold any locks while issuing remote calls.
- invariant(!opCtx->lockState()->isLocked());
-
- // Get indexes by calling listIndexes against the donor.
- auto indexes = uassertStatusOK(fromShard->runExhaustiveCursorCommand(
- opCtx,
- ReadPreferenceSetting(ReadPreference::PrimaryOnly),
- nss.db().toString(),
- BSON("listIndexes" << nss.coll().toString()),
- Milliseconds(-1)));
-
- for (auto&& spec : indexes.docs) {
- donorIndexSpecs.push_back(spec);
- if (auto indexNameElem = spec[IndexDescriptor::kIndexNameFieldName]) {
- if (indexNameElem.type() == BSONType::String &&
- indexNameElem.valueStringData() == "_id_"_sd) {
- donorIdIndexSpec = spec;
- }
+
+ // Get the collection indexes and options from the donor shard.
+
+ // Do not hold any locks while issuing remote calls.
+ invariant(!opCtx->lockState()->isLocked());
+
+ // Get indexes by calling listIndexes against the donor.
+ auto indexes = uassertStatusOK(
+ fromShard->runExhaustiveCursorCommand(opCtx,
+ ReadPreferenceSetting(ReadPreference::PrimaryOnly),
+ nss.db().toString(),
+ BSON("listIndexes" << nss.coll().toString()),
+ Milliseconds(-1)));
+
+ for (auto&& spec : indexes.docs) {
+ donorIndexSpecs.push_back(spec);
+ if (auto indexNameElem = spec[IndexDescriptor::kIndexNameFieldName]) {
+ if (indexNameElem.type() == BSONType::String &&
+ indexNameElem.valueStringData() == "_id_"_sd) {
+ donorIdIndexSpec = spec;
}
}
+ }
- // Get collection options by calling listCollections against the donor.
- auto infosRes = uassertStatusOK(fromShard->runExhaustiveCursorCommand(
- opCtx,
- ReadPreferenceSetting(ReadPreference::PrimaryOnly),
- nss.db().toString(),
- BSON("listCollections" << 1 << "filter" << BSON("name" << nss.coll())),
- Milliseconds(-1)));
+ // Get collection options by calling listCollections against the donor.
+ auto infosRes = uassertStatusOK(fromShard->runExhaustiveCursorCommand(
+ opCtx,
+ ReadPreferenceSetting(ReadPreference::PrimaryOnly),
+ nss.db().toString(),
+ BSON("listCollections" << 1 << "filter" << BSON("name" << nss.coll())),
+ Milliseconds(-1)));
- auto infos = infosRes.docs;
- uassert(ErrorCodes::NamespaceNotFound,
- str::stream() << "expected listCollections against the primary shard for "
- << nss.toString() << " to return 1 entry, but got " << infos.size()
- << " entries",
- infos.size() == 1);
+ auto infos = infosRes.docs;
+ uassert(ErrorCodes::NamespaceNotFound,
+ str::stream() << "expected listCollections against the primary shard for "
+ << nss.toString() << " to return 1 entry, but got " << infos.size()
+ << " entries",
+ infos.size() == 1);
- BSONObj entry = infos.front();
+ BSONObj entry = infos.front();
- // The entire options include both the settable options under the 'options' field in the
- // listCollections response, and the UUID under the 'info' field.
- BSONObjBuilder donorOptionsBob;
+ // The entire options include both the settable options under the 'options' field in the
+ // listCollections response, and the UUID under the 'info' field.
+ BSONObjBuilder donorOptionsBob;
- if (entry["options"].isABSONObj()) {
- donorOptionsBob.appendElements(entry["options"].Obj());
- }
+ if (entry["options"].isABSONObj()) {
+ donorOptionsBob.appendElements(entry["options"].Obj());
+ }
- BSONObj info;
- if (entry["info"].isABSONObj()) {
- info = entry["info"].Obj();
- }
+ BSONObj info;
+ if (entry["info"].isABSONObj()) {
+ info = entry["info"].Obj();
+ }
- uassert(ErrorCodes::InvalidUUID,
- str::stream() << "The donor shard did not return a UUID for collection " << nss.ns()
- << " as part of its listCollections response: " << entry
- << ", but this node expects to see a UUID.",
- !info["uuid"].eoo());
+ uassert(ErrorCodes::InvalidUUID,
+ str::stream() << "The donor shard did not return a UUID for collection " << nss.ns()
+ << " as part of its listCollections response: " << entry
+ << ", but this node expects to see a UUID.",
+ !info["uuid"].eoo());
- donorOptionsBob.append(info["uuid"]);
+ auto donorUUID = info["uuid"].uuid();
- donorOptions = donorOptionsBob.obj();
- }
+ donorOptionsBob.append(info["uuid"]);
+ donorOptions = donorOptionsBob.obj();
+
+ return {donorUUID, donorIndexSpecs, donorIdIndexSpec, donorOptions};
+}
- // 1. If this shard doesn't own any chunks for the collection to be cloned and the collection
+void MigrationDestinationManager::cloneCollectionIndexesAndOptions(
+ OperationContext* opCtx,
+ const NamespaceString& nss,
+ const CollectionOptionsAndIndexes& collectionOptionsAndIndexes) {
+ // 0. If this shard doesn't own any chunks for the collection to be cloned and the collection
// exists locally, we drop its indexes to guarantee that no stale indexes carry over.
bool dropNonDonorIndexes = [&]() -> bool {
AutoGetCollection autoColl(opCtx, nss, MODE_IS);
@@ -636,7 +642,7 @@ void MigrationDestinationManager::cloneCollectionIndexesAndOptions(OperationCont
auto indexes = client.getIndexSpecs(nss);
for (auto&& recipientIndex : indexes) {
bool dropIndex = true;
- for (auto&& donorIndex : donorIndexSpecs) {
+ for (auto&& donorIndex : collectionOptionsAndIndexes.indexSpecs) {
if (recipientIndex.woCompare(donorIndex) == 0) {
dropIndex = false;
break;
@@ -658,7 +664,7 @@ void MigrationDestinationManager::cloneCollectionIndexesAndOptions(OperationCont
}
{
- // 2. Create the collection (if it doesn't already exist) and create any indexes we are
+ // 1. Create the collection (if it doesn't already exist) and create any indexes we are
// missing (auto-heal indexes).
// Checks that the collection's UUID matches the donor's.
@@ -668,28 +674,24 @@ void MigrationDestinationManager::cloneCollectionIndexesAndOptions(OperationCont
<< " because the node is not primary",
repl::ReplicationCoordinator::get(opCtx)->canAcceptWritesFor(opCtx, nss));
- boost::optional<UUID> donorUUID;
- if (!donorOptions["uuid"].eoo()) {
- donorUUID.emplace(UUID::parse(donorOptions));
- }
-
uassert(ErrorCodes::InvalidUUID,
str::stream()
<< "Cannot create collection " << nss.ns()
<< " because we already have an identically named collection with UUID "
<< collection->uuid() << ", which differs from the donor's UUID "
- << (donorUUID ? donorUUID->toString() : "(none)")
+ << collectionOptionsAndIndexes.uuid
<< ". Manually drop the collection on this shard if it contains data from "
"a previous incarnation of "
<< nss.ns(),
- collection->uuid() == donorUUID);
+ collection->uuid() == collectionOptionsAndIndexes.uuid);
};
// Gets the missing indexes and checks if the collection is empty (auto-healing is
// possible).
auto checkEmptyOrGetMissingIndexesFromDonor = [&](Collection* collection) {
auto indexCatalog = collection->getIndexCatalog();
- auto indexSpecs = indexCatalog->removeExistingIndexesNoChecks(opCtx, donorIndexSpecs);
+ auto indexSpecs = indexCatalog->removeExistingIndexesNoChecks(
+ opCtx, collectionOptionsAndIndexes.indexSpecs);
if (!indexSpecs.empty()) {
// Only allow indexes to be copied if the collection does not have any documents.
uassert(ErrorCodes::CannotCreateCollection,
@@ -727,11 +729,15 @@ void MigrationDestinationManager::cloneCollectionIndexesAndOptions(OperationCont
// We do not have a collection by this name. Create the collection with the donor's
// options.
WriteUnitOfWork wuow(opCtx);
- CollectionOptions collectionOptions = uassertStatusOK(CollectionOptions::parse(
- donorOptions, CollectionOptions::ParseKind::parseForStorage));
+ CollectionOptions collectionOptions = uassertStatusOK(
+ CollectionOptions::parse(collectionOptionsAndIndexes.options,
+ CollectionOptions::ParseKind::parseForStorage));
const bool createDefaultIndexes = true;
- uassertStatusOK(db->userCreateNS(
- opCtx, nss, collectionOptions, createDefaultIndexes, donorIdIndexSpec));
+ uassertStatusOK(db->userCreateNS(opCtx,
+ nss,
+ collectionOptions,
+ createDefaultIndexes,
+ collectionOptionsAndIndexes.idIndexSpec));
wuow.commit();
collection = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nss);
}
@@ -796,33 +802,25 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* opCtx) {
invariant(initialState == READY);
- {
- cloneCollectionIndexesAndOptions(opCtx, _nss, _fromShard);
-
- timing.done(1);
- migrateThreadHangAtStep1.pauseWhileSet();
- }
+ auto donorCollectionOptionsAndIndexes = getCollectionIndexesAndOptions(opCtx, _nss, _fromShard);
auto fromShard =
uassertStatusOK(Grid::get(opCtx)->shardRegistry()->getShard(opCtx, _fromShard));
- const UUID collectionUuid = [&] {
- AutoGetCollection autoGetCollection(opCtx, _nss, MODE_IS);
- return autoGetCollection.getCollection()->uuid();
- }();
-
{
const ChunkRange range(_min, _max);
// 2. Ensure any data which might have been left orphaned in the range being moved has been
// deleted.
if (_useFCV44Protocol) {
- while (migrationutil::checkForConflictingDeletions(opCtx, range, collectionUuid)) {
+ while (migrationutil::checkForConflictingDeletions(
+ opCtx, range, donorCollectionOptionsAndIndexes.uuid)) {
LOG(0) << "Migration paused because range overlaps with a "
"range that is scheduled for deletion: collection: "
<< _nss.ns() << " range: " << redact(range.toString());
- auto status = CollectionShardingRuntime::waitForClean(opCtx, _nss, _epoch, range);
+ auto status = CollectionShardingRuntime::waitForClean(
+ opCtx, _nss, donorCollectionOptionsAndIndexes.uuid, range);
if (!status.isOK()) {
_setStateFail(redact(status.reason()));
@@ -832,8 +830,12 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* opCtx) {
opCtx->sleepFor(Milliseconds(1000));
}
- RangeDeletionTask recipientDeletionTask(
- _migrationId, _nss, collectionUuid, _fromShard, range, CleanWhenEnum::kNow);
+ RangeDeletionTask recipientDeletionTask(_migrationId,
+ _nss,
+ donorCollectionOptionsAndIndexes.uuid,
+ _fromShard,
+ range,
+ CleanWhenEnum::kNow);
recipientDeletionTask.setPending(true);
migrationutil::persistRangeDeletionTaskLocally(opCtx, recipientDeletionTask);
@@ -842,20 +844,34 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* opCtx) {
// being moved, and wait for completion
auto cleanupCompleteFuture = _notePending(opCtx, range);
- // Wait for the range deletion to report back
- if (!cleanupCompleteFuture.getNoThrow(opCtx).isOK()) {
- _setStateFail(redact(cleanupCompleteFuture.getNoThrow(opCtx).reason()));
+ auto cleanupStatus = cleanupCompleteFuture.getNoThrow(opCtx);
+ // Wait for the range deletion to report back. Swallow
+ // RangeDeletionAbandonedBecauseCollectionWithUUIDDoesNotExist error since the
+ // collection could either never exist or get dropped directly from the shard after the
+ // range deletion task got scheduled.
+ if (!cleanupStatus.isOK() &&
+ cleanupStatus !=
+ ErrorCodes::RangeDeletionAbandonedBecauseCollectionWithUUIDDoesNotExist) {
+ _setStateFail(redact(cleanupStatus.reason()));
return;
}
// Wait for any other, overlapping queued deletions to drain
- auto status = CollectionShardingRuntime::waitForClean(opCtx, _nss, _epoch, range);
- if (!status.isOK()) {
- _setStateFail(redact(status.reason()));
+ cleanupStatus = CollectionShardingRuntime::waitForClean(
+ opCtx, _nss, donorCollectionOptionsAndIndexes.uuid, range);
+ if (!cleanupStatus.isOK()) {
+ _setStateFail(redact(cleanupStatus.reason()));
return;
}
}
+ timing.done(1);
+ migrateThreadHangAtStep1.pauseWhileSet();
+ }
+
+ {
+ cloneCollectionIndexesAndOptions(opCtx, _nss, donorCollectionOptionsAndIndexes);
+
timing.done(2);
migrateThreadHangAtStep2.pauseWhileSet();
}
diff --git a/src/mongo/db/s/migration_destination_manager.h b/src/mongo/db/s/migration_destination_manager.h
index b97a9b60217..78ea4741e8e 100644
--- a/src/mongo/db/s/migration_destination_manager.h
+++ b/src/mongo/db/s/migration_destination_manager.h
@@ -59,6 +59,13 @@ namespace repl {
class OpTime;
}
+struct CollectionOptionsAndIndexes {
+ UUID uuid;
+ std::vector<BSONObj> indexSpecs;
+ BSONObj idIndexSpec;
+ BSONObj options;
+};
+
/**
* Drives the receiving side of the MongoD migration process. One instance exists per shard.
*/
@@ -129,11 +136,19 @@ public:
Status startCommit(const MigrationSessionId& sessionId);
/**
- * Creates the collection nss on the shard and clones the indexes and options from fromShardId.
+ * Gets the collection uuid, options and indexes from fromShardId.
+ */
+ static CollectionOptionsAndIndexes getCollectionIndexesAndOptions(OperationContext* opCtx,
+ const NamespaceString& nss,
+ const ShardId& fromShardId);
+
+ /**
+ * Creates the collection on the shard and clones the indexes and options.
*/
- static void cloneCollectionIndexesAndOptions(OperationContext* opCtx,
- const NamespaceString& nss,
- const ShardId& fromShardId);
+ static void cloneCollectionIndexesAndOptions(
+ OperationContext* opCtx,
+ const NamespaceString& nss,
+ const CollectionOptionsAndIndexes& collectionOptionsAndIndexes);
private:
/**
diff --git a/src/mongo/db/s/migration_source_manager.cpp b/src/mongo/db/s/migration_source_manager.cpp
index 0380e137b4b..935f903c511 100644
--- a/src/mongo/db/s/migration_source_manager.cpp
+++ b/src/mongo/db/s/migration_source_manager.cpp
@@ -658,8 +658,8 @@ Status MigrationSourceManager::commitChunkMetadataOnConfig() {
log() << "Waiting for cleanup of " << getNss().ns() << " range "
<< redact(range.toString());
- auto deleteStatus =
- CollectionShardingRuntime::waitForClean(_opCtx, getNss(), _collectionEpoch, range);
+ auto deleteStatus = CollectionShardingRuntime::waitForClean(
+ _opCtx, getNss(), _collectionUuid.get(), range);
if (!deleteStatus.isOK()) {
return {ErrorCodes::OrphanedRangeCleanUpFailed,
diff --git a/src/mongo/db/s/range_deletion_util.cpp b/src/mongo/db/s/range_deletion_util.cpp
index a6aa47c0a14..561b032a452 100644
--- a/src/mongo/db/s/range_deletion_util.cpp
+++ b/src/mongo/db/s/range_deletion_util.cpp
@@ -232,8 +232,8 @@ ExecutorFuture<int> deleteBatchAndWaitForReplication(
AutoGetCollection autoColl(opCtx, nss, MODE_IX);
auto* const collection = autoColl.getCollection();
- // Ensure the collection has not been dropped or dropped and recreated.
- uassert(ErrorCodes::RangeDeletionAbandonedDueToCollectionDrop,
+ // Ensure the collection exists and has not been dropped or dropped and recreated.
+ uassert(ErrorCodes::RangeDeletionAbandonedBecauseCollectionWithUUIDDoesNotExist,
"Collection has been dropped since enqueuing this range "
"deletion task. No need to delete documents.",
!collectionUuidHasChanged(nss, collection, collectionUuid));
@@ -278,7 +278,8 @@ ExecutorFuture<void> deleteRangeInBatches(const std::shared_ptr<executor::TaskEx
// Continue iterating until there are no more documents to delete, retrying on
// any error that doesn't indicate that this node is stepping down.
return (swNumDeleted.isOK() && swNumDeleted.getValue() == 0) ||
- swNumDeleted.getStatus() == ErrorCodes::RangeDeletionAbandonedDueToCollectionDrop ||
+ swNumDeleted.getStatus() ==
+ ErrorCodes::RangeDeletionAbandonedBecauseCollectionWithUUIDDoesNotExist ||
ErrorCodes::isShutdownError(swNumDeleted.getStatus()) ||
ErrorCodes::isNotMasterError(swNumDeleted.getStatus());
})
@@ -373,7 +374,9 @@ SharedSemiFuture<void> removeDocumentsInRange(
<< redact(range.toString()) << causedBy(redact(s));
}
- if (s.isOK() || s.code() == ErrorCodes::RangeDeletionAbandonedDueToCollectionDrop) {
+ if (s.isOK() ||
+ s.code() ==
+ ErrorCodes::RangeDeletionAbandonedBecauseCollectionWithUUIDDoesNotExist) {
removePersistentRangeDeletionTask(nss, collectionUuid, range);
LOG(1) << "Completed removal of persistent range deletion task for " << nss.ns()
diff --git a/src/mongo/db/s/range_deletion_util_test.cpp b/src/mongo/db/s/range_deletion_util_test.cpp
index b1b6fd582f7..a2d245e185c 100644
--- a/src/mongo/db/s/range_deletion_util_test.cpp
+++ b/src/mongo/db/s/range_deletion_util_test.cpp
@@ -297,8 +297,9 @@ TEST_F(RangeDeleterTest,
Milliseconds(0) /* delayBetweenBatches */);
- ASSERT_THROWS_CODE(
- cleanupComplete.get(), DBException, ErrorCodes::RangeDeletionAbandonedDueToCollectionDrop);
+ ASSERT_THROWS_CODE(cleanupComplete.get(),
+ DBException,
+ ErrorCodes::RangeDeletionAbandonedBecauseCollectionWithUUIDDoesNotExist);
ASSERT_EQUALS(dbclient.count(kNss, BSONObj()), numDocsToInsert);
}
@@ -316,8 +317,9 @@ TEST_F(RangeDeleterTest, RemoveDocumentsInRangeThrowsErrorWhenCollectionDoesNotE
Milliseconds(0) /* delayBetweenBatches */);
- ASSERT_THROWS_CODE(
- cleanupComplete.get(), DBException, ErrorCodes::RangeDeletionAbandonedDueToCollectionDrop);
+ ASSERT_THROWS_CODE(cleanupComplete.get(),
+ DBException,
+ ErrorCodes::RangeDeletionAbandonedBecauseCollectionWithUUIDDoesNotExist);
}
@@ -631,8 +633,9 @@ TEST_F(RangeDeleterTest,
Seconds(0) /* delayForActiveQueriesOnSecondariesToComplete */,
Milliseconds(0) /* delayBetweenBatches */);
- ASSERT_THROWS_CODE(
- cleanupComplete.get(), DBException, ErrorCodes::RangeDeletionAbandonedDueToCollectionDrop);
+ ASSERT_THROWS_CODE(cleanupComplete.get(),
+ DBException,
+ ErrorCodes::RangeDeletionAbandonedBecauseCollectionWithUUIDDoesNotExist);
// Document should have been deleted.
ASSERT_EQUALS(countDocsInConfigRangeDeletions(store, operationContext()), 0);