diff options
12 files changed, 38 insertions, 52 deletions
diff --git a/jstests/serverless/shard_split_basic_test.js b/jstests/serverless/shard_split_basic_test.js index c5bb56f2d7e..37a19fcaaf8 100644 --- a/jstests/serverless/shard_split_basic_test.js +++ b/jstests/serverless/shard_split_basic_test.js @@ -15,8 +15,13 @@ test.donor.awaitSecondaryNodes(); const donorPrimary = test.getDonorPrimary(); const operation = test.createSplitOperation(tenantIds); -assert.commandWorked(operation.commit()); +const result = assert.commandWorked(operation.commit()); assertMigrationState(donorPrimary, operation.migrationId, "committed"); + +// Confirm blockOpTime in result matches the state document before forgetting the operation +const stateDoc = findSplitOperation(donorPrimary, operation.migrationId); +assert.eq(stateDoc.blockOpTime.ts, result.blockOpTime.ts); + operation.forget(); const status = donorPrimary.adminCommand({serverStatus: 1}); diff --git a/jstests/serverless/shard_split_concurrent_bulk_writes.js b/jstests/serverless/shard_split_concurrent_bulk_writes.js index 9e7383c4b1c..6618214b1e9 100644 --- a/jstests/serverless/shard_split_concurrent_bulk_writes.js +++ b/jstests/serverless/shard_split_concurrent_bulk_writes.js @@ -15,13 +15,6 @@ * ] */ -function assertAsyncCommitted(splitThread) { - const data = splitThread.returnData(); - - assert.commandWorked(data); - assert.eq(data.state, "committed"); -} - (function() { 'use strict'; @@ -226,7 +219,7 @@ function bulkMultiUpdateDocsUnordered(primaryHost, dbName, collName, numDocs) { bulkWriteThread.join(); splitThread.join(); - assertAsyncCommitted(splitThread); + assert.commandWorked(splitThread.returnData()); let bulkWriteRes = bulkWriteThread.returnData(); let writeErrors = bulkWriteRes.res.writeErrors; @@ -388,7 +381,7 @@ function bulkMultiUpdateDocsUnordered(primaryHost, dbName, collName, numDocs) { bulkWriteThread.join(); splitThread.join(); - assertAsyncCommitted(splitThread); + assert.commandWorked(splitThread.returnData()); const bulkWriteRes = bulkWriteThread.returnData(); const writeErrors = bulkWriteRes.res.writeErrors; @@ -499,7 +492,7 @@ function bulkMultiUpdateDocsUnordered(primaryHost, dbName, collName, numDocs) { bulkWriteThread.join(); splitThread.join(); - assertAsyncCommitted(splitThread); + assert.commandWorked(splitThread.returnData()); let bulkWriteRes = bulkWriteThread.returnData(); assert.eq(bulkWriteRes.res.code, ErrorCodes.Interrupted, tojson(bulkWriteRes)); @@ -546,9 +539,9 @@ function bulkMultiUpdateDocsUnordered(primaryHost, dbName, collName, numDocs) { bulkWriteThread.join(); splitThread.join(); - assertAsyncCommitted(splitThread); + assert.commandWorked(splitThread.returnData()); - let bulkWriteRes = bulkWriteThread.returnData(); + const bulkWriteRes = bulkWriteThread.returnData(); assert.eq(bulkWriteRes.res.code, ErrorCodes.Interrupted, tojson(bulkWriteRes)); assert.eq( bulkWriteRes.res.errmsg, diff --git a/jstests/serverless/shard_split_concurrent_writes_on_donor_blocking.js b/jstests/serverless/shard_split_concurrent_writes_on_donor_blocking.js index ca76c1ec60f..06e8d231d58 100644 --- a/jstests/serverless/shard_split_concurrent_writes_on_donor_blocking.js +++ b/jstests/serverless/shard_split_concurrent_writes_on_donor_blocking.js @@ -177,9 +177,7 @@ runTestsWhileBlocking(); blockFp.off(); splitThread.join(); -const data = splitThread.returnData(); -assert.commandWorked(data); -assert.eq(data.state, "committed"); +assert.commandWorked(splitThread.returnData()); // run test after blocking is over and the migration committed. runTestsAfterMigrationCommitted(); diff --git a/jstests/serverless/shard_split_drop_state_doc_collection_aborted.js b/jstests/serverless/shard_split_drop_state_doc_collection_aborted.js index 5b4414c7dfc..81f54d9d5bb 100644 --- a/jstests/serverless/shard_split_drop_state_doc_collection_aborted.js +++ b/jstests/serverless/shard_split_drop_state_doc_collection_aborted.js @@ -73,10 +73,7 @@ function testDroppingStateDocCollections( const operation2 = retryWithDifferentMigrationId ? test.createSplitOperation(tenantIds) : operation; migrationId = operation2.migrationId; - const runMigrationRes = operation2.commit(); - - assert.commandWorked(runMigrationRes); - assert.eq(runMigrationRes.state, "committed"); + assert.commandWorked(operation2.commit()); operation2.forget(); diff --git a/jstests/serverless/shard_split_drop_state_doc_collection_blocking.js b/jstests/serverless/shard_split_drop_state_doc_collection_blocking.js index 8200564429c..bf313671714 100644 --- a/jstests/serverless/shard_split_drop_state_doc_collection_blocking.js +++ b/jstests/serverless/shard_split_drop_state_doc_collection_blocking.js @@ -73,10 +73,7 @@ function testDroppingStateDocCollections( const operation2 = retryWithDifferentMigrationId ? test.createSplitOperation(tenantIds) : operation; migrationId = operation2.migrationId; - const runMigrationRes = operation2.commit(); - - assert.commandWorked(runMigrationRes); - assert.eq(runMigrationRes.state, "committed"); + assert.commandWorked(operation2.commit()); operation2.forget(); diff --git a/jstests/serverless/shard_split_drop_state_doc_collection_committed.js b/jstests/serverless/shard_split_drop_state_doc_collection_committed.js index a43c140dc51..56b6cbcf31d 100644 --- a/jstests/serverless/shard_split_drop_state_doc_collection_committed.js +++ b/jstests/serverless/shard_split_drop_state_doc_collection_committed.js @@ -59,10 +59,7 @@ function testDroppingStateDocCollections( const operation2 = retryWithDifferentMigrationId ? test.createSplitOperation(tenantIds) : operation; migrationId = operation2.migrationId; - const runMigrationRes = operation2.commit(); - - assert.commandWorked(runMigrationRes); - assert.eq(runMigrationRes.state, "committed"); + assert.commandWorked(operation2.commit()); operation2.forget(); diff --git a/jstests/serverless/shard_split_drop_state_doc_collection_decision_fullfilled.js b/jstests/serverless/shard_split_drop_state_doc_collection_decision_fullfilled.js index 0e6bd3ebc34..6be3fc6a920 100644 --- a/jstests/serverless/shard_split_drop_state_doc_collection_decision_fullfilled.js +++ b/jstests/serverless/shard_split_drop_state_doc_collection_decision_fullfilled.js @@ -76,10 +76,7 @@ function testDroppingStateDocCollections( const operation2 = retryWithDifferentMigrationId ? test.createSplitOperation(tenantIds) : operation; migrationId = operation2.migrationId; - const runMigrationRes = operation2.commit(); - - assert.commandWorked(runMigrationRes); - assert.eq(runMigrationRes.state, "committed"); + assert.commandWorked(operation2.commit()); operation2.forget(); diff --git a/jstests/serverless/shard_split_write_during_shard_split.js b/jstests/serverless/shard_split_write_during_shard_split.js index dad67d46ad5..59e6994e891 100644 --- a/jstests/serverless/shard_split_write_during_shard_split.js +++ b/jstests/serverless/shard_split_write_during_shard_split.js @@ -43,7 +43,6 @@ blockingFP.off(); splitThread.join(); const result = splitThread.returnData(); assert.eq(result.ok, 1); -assert.eq(result.state, "committed"); writeThread.join(); const writeResults = writeThread.returnData(); diff --git a/src/mongo/db/serverless/shard_split_commands.cpp b/src/mongo/db/serverless/shard_split_commands.cpp index 5ce6c9c0307..b7757134c4b 100644 --- a/src/mongo/db/serverless/shard_split_commands.cpp +++ b/src/mongo/db/serverless/shard_split_commands.cpp @@ -84,13 +84,9 @@ public: (state.abortReason ? state.abortReason->toString() : ""), state.state != ShardSplitDonorStateEnum::kAborted); - Response response(state.state); - if (state.abortReason) { - BSONObjBuilder bob; - - state.abortReason->serializeErrorToBSON(&bob); - response.setAbortReason(bob.obj()); - } + Response response; + invariant(state.blockOpTime.has_value()); + response.setBlockOpTime(*state.blockOpTime); return response; } diff --git a/src/mongo/db/serverless/shard_split_commands.idl b/src/mongo/db/serverless/shard_split_commands.idl index 95382514160..da1f4fe71b0 100644 --- a/src/mongo/db/serverless/shard_split_commands.idl +++ b/src/mongo/db/serverless/shard_split_commands.idl @@ -40,13 +40,11 @@ structs: description: "Response for the `commitShardSplit` command." strict: false fields: - state: - type: ShardSplitDonorState - description: "The state of the shard split operation." - abortReason: - type: object - description: "The error that caused the shard split operation to abort." - optional: true + blockOpTime: + type: optime + description: >- + The opTime at which writes and causal reads against the data being migrated + started blocking. commands: commitShardSplit: @@ -81,7 +79,7 @@ commands: migrationId: description: "Unique identifier for the shard split operation." type: uuid - + forgetShardSplit: description: "Parser for the `forgetShardSplit` command." command_name: forgetShardSplit diff --git a/src/mongo/db/serverless/shard_split_donor_service.cpp b/src/mongo/db/serverless/shard_split_donor_service.cpp index 8c0fd38f2b1..f0d930c171b 100644 --- a/src/mongo/db/serverless/shard_split_donor_service.cpp +++ b/src/mongo/db/serverless/shard_split_donor_service.cpp @@ -290,7 +290,10 @@ SemiFuture<void> ShardSplitDonorService::DonorStateMachine::run( return _cleanRecipientStateDoc(executor, primaryToken); }) .then([this, executor, migrationId = _migrationId]() { - return DurableState{ShardSplitDonorStateEnum::kCommitted}; + stdx::lock_guard<Latch> lg(_mutex); + return DurableState{ShardSplitDonorStateEnum::kCommitted, + boost::none, + _stateDoc.getBlockOpTime()}; }) .unsafeToInlineFuture(); } @@ -383,7 +386,10 @@ SemiFuture<void> ShardSplitDonorService::DonorStateMachine::run( "id"_attr = _migrationId, "state"_attr = ShardSplitDonorState_serializer(_stateDoc.getState())); - return ExecutorFuture(**executor, DurableState{_stateDoc.getState(), _abortReason}); + stdx::lock_guard<Latch> lg(_mutex); + return ExecutorFuture( + **executor, + DurableState{_stateDoc.getState(), _abortReason, _stateDoc.getBlockOpTime()}); }) .unsafeToInlineFuture(); }); @@ -1060,7 +1066,9 @@ ShardSplitDonorService::DonorStateMachine::_handleErrorOrEnterAbortedState( "abortReason"_attr = _abortReason.value()); return ExecutorFuture(**executor, - DurableState{ShardSplitDonorStateEnum::kAborted, _abortReason}); + DurableState{ShardSplitDonorStateEnum::kAborted, + _abortReason, + _stateDoc.getBlockOpTime()}); } } @@ -1103,7 +1111,7 @@ ShardSplitDonorService::DonorStateMachine::_handleErrorOrEnterAbortedState( }) .then([this, executor] { stdx::lock_guard<Latch> lg(_mutex); - return DurableState{_stateDoc.getState(), _abortReason}; + return DurableState{_stateDoc.getState(), _abortReason, _stateDoc.getBlockOpTime()}; }); } diff --git a/src/mongo/db/serverless/shard_split_donor_service.h b/src/mongo/db/serverless/shard_split_donor_service.h index ddfd91b1f20..aa871fe6bf0 100644 --- a/src/mongo/db/serverless/shard_split_donor_service.h +++ b/src/mongo/db/serverless/shard_split_donor_service.h @@ -85,6 +85,7 @@ public: struct DurableState { ShardSplitDonorStateEnum state; boost::optional<Status> abortReason; + boost::optional<repl::OpTime> blockOpTime; }; DonorStateMachine(ServiceContext* serviceContext, |