summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorCheahuychou Mao <mao.cheahuychou@gmail.com>2021-05-04 15:00:46 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-05-05 17:47:50 +0000
commit6701ac9e1cb8f42ae479d70f0fa6d1fa2b8bc995 (patch)
treedcb5d392e16b907ba8eb746291a927aa87b64b18 /src/mongo
parentb37de758aa8a5fcc74d8af8b7556e3a18d76e90c (diff)
downloadmongo-6701ac9e1cb8f42ae479d70f0fa6d1fa2b8bc995.tar.gz
SERVER-54302 Handle retrying with different migration id after dropping donor state collection
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/repl/tenant_migration_donor_service.cpp8
-rw-r--r--src/mongo/db/repl/tenant_migration_recipient_service.cpp31
2 files changed, 21 insertions, 18 deletions
diff --git a/src/mongo/db/repl/tenant_migration_donor_service.cpp b/src/mongo/db/repl/tenant_migration_donor_service.cpp
index d8fc0ee8fb3..5a89ea13fe4 100644
--- a/src/mongo/db/repl/tenant_migration_donor_service.cpp
+++ b/src/mongo/db/repl/tenant_migration_donor_service.cpp
@@ -1152,9 +1152,13 @@ ExecutorFuture<void> TenantMigrationDonorService::Instance::_handleErrorOrEnterA
auto mtab = tenant_migration_access_blocker::getTenantMigrationDonorAccessBlocker(
_serviceContext, _tenantId);
- if (status == ErrorCodes::ConflictingOperationInProgress || !mtab) {
+ if ((status == ErrorCodes::ConflictingOperationInProgress &&
+ !_initialDonorStateDurablePromise.getFuture().isReady()) ||
+ !mtab) {
+ // The migration failed either before or during inserting the state doc. Use the status to
+ // fulfill the _initialDonorStateDurablePromise to fail the donorStartMigration command
+ // immediately.
stdx::lock_guard<Latch> lg(_mutex);
- // Fulfill the promise since the state doc failed to insert.
setPromiseErrorIfNotReady(lg, _initialDonorStateDurablePromise, status);
return ExecutorFuture(**executor);
diff --git a/src/mongo/db/repl/tenant_migration_recipient_service.cpp b/src/mongo/db/repl/tenant_migration_recipient_service.cpp
index 67660fe8d55..37e099b14b1 100644
--- a/src/mongo/db/repl/tenant_migration_recipient_service.cpp
+++ b/src/mongo/db/repl/tenant_migration_recipient_service.cpp
@@ -1835,6 +1835,21 @@ SemiFuture<void> TenantMigrationRecipientService::Instance::run(
return AsyncTry([this, self = shared_from_this(), executor, token] {
return ExecutorFuture(**executor)
.then([this, self = shared_from_this()] {
+ stdx::unique_lock lk(_mutex);
+ // Instance task can be started only once for the current term on a primary.
+ invariant(!_taskState.isDone());
+ // If the task state is interrupted, then don't start the task.
+ if (_taskState.isInterrupted()) {
+ uassertStatusOK(_taskState.getInterruptStatus());
+ }
+
+ // The task state will already have been set to 'kRunning' if we restarted
+ // the future chain on donor failover.
+ if (!_taskState.isRunning()) {
+ _taskState.setState(TaskState::kRunning);
+ }
+ pauseAfterRunTenantMigrationRecipientInstance.pauseWhileSet();
+
auto mtab = tenant_migration_access_blocker::
getTenantMigrationRecipientAccessBlocker(_serviceContext,
_stateDoc.getTenantId());
@@ -1855,22 +1870,6 @@ SemiFuture<void> TenantMigrationRecipientService::Instance::run(
<< "\" with migration id " << mtab->getMigrationId(),
deleted);
}
- })
- .then([this, self = shared_from_this()] {
- stdx::unique_lock lk(_mutex);
- // Instance task can be started only once for the current term on a primary.
- invariant(!_taskState.isDone());
- // If the task state is interrupted, then don't start the task.
- if (_taskState.isInterrupted()) {
- uassertStatusOK(_taskState.getInterruptStatus());
- }
-
- // The task state will already have been set to 'kRunning' if we restarted
- // the future chain on donor failover.
- if (!_taskState.isRunning()) {
- _taskState.setState(TaskState::kRunning);
- }
- pauseAfterRunTenantMigrationRecipientInstance.pauseWhileSet();
if (_stateDoc.getState() !=
TenantMigrationRecipientStateEnum::kUninitialized &&