diff options
32 files changed, 119 insertions, 258 deletions
diff --git a/jstests/replsets/libs/tenant_migration_util.js b/jstests/replsets/libs/tenant_migration_util.js index d6cd9f8bf70..acd11758349 100644 --- a/jstests/replsets/libs/tenant_migration_util.js +++ b/jstests/replsets/libs/tenant_migration_util.js @@ -265,33 +265,18 @@ var TenantMigrationUtil = (function() { * or shard merge for the given node. */ function getTenantMigrationAccessBlocker({donorNode, recipientNode, tenantId}) { + assert(donorNode || recipientNode, "missing required parameter donorNode or recipientNode"); if (donorNode && recipientNode) { throw new Error("please specify either 'donorNode' or 'recipientNode' but not both"); } - const node = donorNode || recipientNode; - const res = node.adminCommand({serverStatus: 1}); - assert.commandWorked(res); - - const isShardMergeEnabled = TenantMigrationUtil.isShardMergeEnabled( - typeof node.getDB === "function" ? node.getDB("admin") : node); - const {tenantMigrationAccessBlocker} = res; - if (!tenantMigrationAccessBlocker) { - return undefined; - } - if (isShardMergeEnabled && tenantId) { - tenantMigrationAccessBlocker.recipient = tenantMigrationAccessBlocker[tenantId] && - tenantMigrationAccessBlocker[tenantId].recipient; - return tenantMigrationAccessBlocker; - } - - if (tenantId) { - tenantMigrationAccessBlocker.donor = tenantMigrationAccessBlocker[tenantId] && - tenantMigrationAccessBlocker[tenantId].donor; - tenantMigrationAccessBlocker.recipient = tenantMigrationAccessBlocker[tenantId] && - tenantMigrationAccessBlocker[tenantId].recipient; + const node = donorNode || recipientNode; + const {tenantMigrationAccessBlocker} = + assert.commandWorked(node.adminCommand({serverStatus: 1})); - return tenantMigrationAccessBlocker; + if (tenantMigrationAccessBlocker && tenantId && + tenantMigrationAccessBlocker.hasOwnProperty(tenantId)) { + return tenantMigrationAccessBlocker[tenantId]; } return tenantMigrationAccessBlocker; diff --git a/jstests/serverless/libs/shard_split_test.js b/jstests/serverless/libs/shard_split_test.js index f455f5f6e20..cf6aa1df7e2 100644 --- a/jstests/serverless/libs/shard_split_test.js +++ b/jstests/serverless/libs/shard_split_test.js @@ -340,13 +340,13 @@ class ShardSplitOperation { */ class ShardSplitTest { constructor({ - recipientTagName, - recipientSetName, + recipientTagName = "recipientNode", + recipientSetName = "recipientSetName", quickGarbageCollection = false, nodeOptions, allowStaleReadsOnDonor = false, initiateWithShortElectionTimeout = false - }) { + } = {}) { nodeOptions = nodeOptions || {}; if (quickGarbageCollection) { nodeOptions["setParameter"] = nodeOptions["setParameter"] || {}; @@ -418,6 +418,15 @@ class ShardSplitTest { } /* + * Add recipient nodes to the current donor set, and wait for them to become ready. + * @param {numNodes} indicates the number of recipient nodes to be added. + */ + addAndAwaitRecipientNodes(numNodes) { + this.addRecipientNodes(numNodes); + this.donor.awaitSecondaryNodes(); + } + + /* * Remove and stops the recipient nodes from the donor set. */ removeAndStopRecipientNodes() { diff --git a/jstests/serverless/shard_split_abort_during_upgrade_downgrade.js b/jstests/serverless/shard_split_abort_during_upgrade_downgrade.js index 73e668bb947..318df14fead 100644 --- a/jstests/serverless/shard_split_abort_during_upgrade_downgrade.js +++ b/jstests/serverless/shard_split_abort_during_upgrade_downgrade.js @@ -19,12 +19,8 @@ if (MongoRunner.compareBinVersions(latestFCV, "6.3") < 0) { // Skip db hash check because secondary is left with a different config. TestData.skipCheckDBHashes = true; -const test = new ShardSplitTest({ - recipientTagName: "recipientNode", - recipientSetName: "recipient", - quickGarbageCollection: true -}); +const test = new ShardSplitTest({quickGarbageCollection: true}); test.addRecipientNodes(); const donorPrimary = testFixture.donor.getPrimary(); diff --git a/jstests/serverless/shard_split_abort_forget_retry.js b/jstests/serverless/shard_split_abort_forget_retry.js index b452cd414c9..8f5aa2e51a0 100644 --- a/jstests/serverless/shard_split_abort_forget_retry.js +++ b/jstests/serverless/shard_split_abort_forget_retry.js @@ -15,10 +15,8 @@ load('jstests/libs/parallel_shell_helpers.js'); // for "startParallelShell" load("jstests/libs/uuid_util.js"); load("jstests/serverless/libs/shard_split_test.js"); -const recipientTagName = "recipientNode"; -const recipientSetName = "recipientSetName"; TestData.skipCheckDBHashes = true; -const test = new ShardSplitTest({recipientTagName, recipientSetName, quickGarbageCollection: true}); +const test = new ShardSplitTest({quickGarbageCollection: true}); (() => { const tenantIds = ["tenant1", "tenant2"]; diff --git a/jstests/serverless/shard_split_abort_on_setfcv.js b/jstests/serverless/shard_split_abort_on_setfcv.js index 07a35bd4c0d..22f19e7efc2 100644 --- a/jstests/serverless/shard_split_abort_on_setfcv.js +++ b/jstests/serverless/shard_split_abort_on_setfcv.js @@ -12,12 +12,7 @@ load("jstests/serverless/libs/shard_split_test.js"); // Skip db hash check because secondary is left with a different config. TestData.skipCheckDBHashes = true; -const test = new ShardSplitTest({ - recipientTagName: "recipientNode", - recipientSetName: "recipient", - quickGarbageCollection: true -}); - +const test = new ShardSplitTest({quickGarbageCollection: true}); test.addRecipientNodes(); const donorPrimary = test.donor.getPrimary(); diff --git a/jstests/serverless/shard_split_abort_while_committing.js b/jstests/serverless/shard_split_abort_while_committing.js index a4e998088d4..f59ce81f6e7 100644 --- a/jstests/serverless/shard_split_abort_while_committing.js +++ b/jstests/serverless/shard_split_abort_while_committing.js @@ -14,11 +14,7 @@ function testAbortAfterSplitIsAppliedStillsCommits(failpoint) { const tenantIds = ["tenant1", "tenant2"]; - const test = new ShardSplitTest({ - recipientTagName: "recipientNode", - recipientSetName: "recipient", - quickGarbageCollection: true - }); + const test = new ShardSplitTest({quickGarbageCollection: true}); test.addRecipientNodes(); const donorPrimary = test.getDonorPrimary(); diff --git a/jstests/serverless/shard_split_basic_test.js b/jstests/serverless/shard_split_basic_test.js index 050f0a40469..d80752becda 100644 --- a/jstests/serverless/shard_split_basic_test.js +++ b/jstests/serverless/shard_split_basic_test.js @@ -8,12 +8,8 @@ load("jstests/serverless/libs/shard_split_test.js"); (function() { "use strict"; -const recipientTagName = "recipientNode"; -const recipientSetName = "recipientSetName"; const tenantIds = ["tenant1", "tenant2"]; - -const test = new ShardSplitTest({recipientTagName, recipientSetName, quickGarbageCollection: true}); - +const test = new ShardSplitTest({quickGarbageCollection: true}); test.addRecipientNodes(); test.donor.awaitSecondaryNodes(); diff --git a/jstests/serverless/shard_split_buildindex.js b/jstests/serverless/shard_split_buildindex.js index c8b3810a8b8..ff6e1d61a5a 100644 --- a/jstests/serverless/shard_split_buildindex.js +++ b/jstests/serverless/shard_split_buildindex.js @@ -19,11 +19,7 @@ load("jstests/libs/fail_point_util.js"); load("jstests/replsets/libs/tenant_migration_test.js"); load("jstests/serverless/libs/shard_split_test.js"); -const shardSplitTest = new ShardSplitTest({ - recipientTagName: "recipientNode", - recipientSetName: "recipient", - quickGarbageCollection: true -}); +const shardSplitTest = new ShardSplitTest({quickGarbageCollection: true}); shardSplitTest.addRecipientNodes(); const kTenantId = "testTenantId1"; diff --git a/jstests/serverless/shard_split_concurrent_reconfig.js b/jstests/serverless/shard_split_concurrent_reconfig.js index fce1cd04c42..1ef29f70675 100644 --- a/jstests/serverless/shard_split_concurrent_reconfig.js +++ b/jstests/serverless/shard_split_concurrent_reconfig.js @@ -9,10 +9,8 @@ load("jstests/serverless/libs/shard_split_test.js"); (function() { "use strict"; -const recipientTagName = "recipientNode"; -const recipientSetName = "recipientSetName"; const tenantIds = ["tenant1", "tenant2"]; -const test = new ShardSplitTest({recipientTagName, recipientSetName, quickGarbageCollection: true}); +const test = new ShardSplitTest({quickGarbageCollection: true}); test.addRecipientNodes(); test.donor.awaitSecondaryNodes(); diff --git a/jstests/serverless/shard_split_concurrent_writes_on_donor_aborted.js b/jstests/serverless/shard_split_concurrent_writes_on_donor_aborted.js index 78c1e16e5f3..053872f37c3 100644 --- a/jstests/serverless/shard_split_concurrent_writes_on_donor_aborted.js +++ b/jstests/serverless/shard_split_concurrent_writes_on_donor_aborted.js @@ -21,11 +21,7 @@ load("jstests/replsets/tenant_migration_concurrent_writes_on_donor_util.js"); load("jstests/serverless/libs/shard_split_test.js"); TestData.skipCheckDBHashes = true; -const recipientTagName = "recipientNode"; -const recipientSetName = "recipient"; const tenantMigrationTest = new ShardSplitTest({ - recipientTagName, - recipientSetName, quickGarbageCollection: true, allowStaleReadsOnDonor: true, initiateWithShortElectionTimeout: true 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 b6e53662901..a37aeb0f326 100644 --- a/jstests/serverless/shard_split_concurrent_writes_on_donor_blocking.js +++ b/jstests/serverless/shard_split_concurrent_writes_on_donor_blocking.js @@ -22,11 +22,7 @@ load("jstests/replsets/tenant_migration_concurrent_writes_on_donor_util.js"); load("jstests/serverless/libs/shard_split_test.js"); TestData.skipCheckDBHashes = true; -const recipientTagName = "recipientNode"; -const recipientSetName = "recipient"; const tenantMigrationTest = new ShardSplitTest({ - recipientTagName, - recipientSetName, quickGarbageCollection: true, allowStaleReadsOnDonor: true, initiateWithShortElectionTimeout: true, diff --git a/jstests/serverless/shard_split_concurrent_writes_on_donor_committed.js b/jstests/serverless/shard_split_concurrent_writes_on_donor_committed.js index 357e0ae20fb..c96a7432165 100644 --- a/jstests/serverless/shard_split_concurrent_writes_on_donor_committed.js +++ b/jstests/serverless/shard_split_concurrent_writes_on_donor_committed.js @@ -21,17 +21,13 @@ load("jstests/replsets/tenant_migration_concurrent_writes_on_donor_util.js"); load("jstests/serverless/libs/shard_split_test.js"); TestData.skipCheckDBHashes = true; -const recipientTagName = "recipientNode"; -const recipientSetName = "recipient"; -const tenantMigrationTest = new ShardSplitTest({ - recipientTagName, - recipientSetName, +const test = new ShardSplitTest({ quickGarbageCollection: true, allowStaleReadsOnDonor: true, initiateWithShortElectionTimeout: true }); -const donorPrimary = tenantMigrationTest.getDonorPrimary(); +const donorPrimary = test.getDonorPrimary(); const kCollName = "testColl"; const kTenantDefinedDbName = "0"; @@ -126,9 +122,9 @@ function runTestsAfterMigration() { } } -tenantMigrationTest.addRecipientNodes(); +test.addRecipientNodes(); const tenantIds = [kTenantID]; -const operation = tenantMigrationTest.createSplitOperation(tenantIds); +const operation = test.createSplitOperation(tenantIds); setupTestsBeforeMigration(); @@ -140,5 +136,5 @@ ShardSplitTest.checkShardSplitAccessBlocker(donorPrimary, kTenantID, { numTenantMigrationCommittedErrors: countTenantMigrationCommittedErrors }); -tenantMigrationTest.stop(); +test.stop(); })(); 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 bb23ce85087..1eca072a709 100644 --- a/jstests/serverless/shard_split_drop_state_doc_collection_aborted.js +++ b/jstests/serverless/shard_split_drop_state_doc_collection_aborted.js @@ -19,9 +19,6 @@ load("jstests/libs/fail_point_util.js"); load("jstests/libs/uuid_util.js"); load("jstests/serverless/libs/shard_split_test.js"); -const recipientTagName = "recipientNode"; -const recipientSetName = "recipient"; - TestData.skipCheckDBHashes = true; function testDroppingStateDocCollections( @@ -87,12 +84,8 @@ function testDroppingStateDocCollections( } jsTest.log("Test dropping donor and recipient state doc collections during a shard split."); -const test = new ShardSplitTest({ - recipientTagName, - recipientSetName, - quickGarbageCollection: true, - initiateWithShortElectionTimeout: true -}); +const test = + new ShardSplitTest({quickGarbageCollection: true, initiateWithShortElectionTimeout: true}); const fpName = "abortShardSplitBeforeLeavingBlockingState"; testDroppingStateDocCollections(test, fpName, {dropDonorsCollection: true}); 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 268ac46c6ad..dd79ff12683 100644 --- a/jstests/serverless/shard_split_drop_state_doc_collection_blocking.js +++ b/jstests/serverless/shard_split_drop_state_doc_collection_blocking.js @@ -19,9 +19,6 @@ load("jstests/libs/fail_point_util.js"); load("jstests/libs/uuid_util.js"); load("jstests/serverless/libs/shard_split_test.js"); -const recipientTagName = "recipientNode"; -const recipientSetName = "recipient"; - TestData.skipCheckDBHashes = true; function testDroppingStateDocCollections( @@ -87,12 +84,8 @@ function testDroppingStateDocCollections( } jsTest.log("Test dropping donor and recipient state doc collections during a shard split."); -const test = new ShardSplitTest({ - recipientTagName, - recipientSetName, - quickGarbageCollection: true, - initiateWithShortElectionTimeout: true -}); +const test = + new ShardSplitTest({quickGarbageCollection: true, initiateWithShortElectionTimeout: true}); const fpName = "pauseShardSplitAfterBlocking"; testDroppingStateDocCollections(test, fpName, {dropDonorsCollection: true}); 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 681f304db55..76f44e59a3e 100644 --- a/jstests/serverless/shard_split_drop_state_doc_collection_committed.js +++ b/jstests/serverless/shard_split_drop_state_doc_collection_committed.js @@ -19,9 +19,6 @@ load("jstests/libs/fail_point_util.js"); load("jstests/libs/uuid_util.js"); load("jstests/serverless/libs/shard_split_test.js"); -const recipientTagName = "recipientNode"; -const recipientSetName = "recipient"; - TestData.skipCheckDBHashes = true; function testDroppingStateDocCollections( @@ -73,12 +70,8 @@ function testDroppingStateDocCollections( } jsTest.log("Test dropping donor and recipient state doc collections during a shard split."); -const test = new ShardSplitTest({ - recipientTagName, - recipientSetName, - quickGarbageCollection: true, - initiateWithShortElectionTimeout: true -}); +const test = + new ShardSplitTest({quickGarbageCollection: true, initiateWithShortElectionTimeout: true}); const fpName = undefined; testDroppingStateDocCollections(test, fpName, {dropDonorsCollection: true}); 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 83feef23d38..00e694d026b 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 @@ -20,9 +20,6 @@ load("jstests/libs/fail_point_util.js"); load("jstests/libs/uuid_util.js"); load("jstests/serverless/libs/shard_split_test.js"); -const recipientTagName = "recipientNode"; -const recipientSetName = "recipient"; - TestData.skipCheckDBHashes = true; function testDroppingStateDocCollections( @@ -90,12 +87,8 @@ function testDroppingStateDocCollections( } jsTest.log("Test dropping donor and recipient state doc collections during a shard split."); -const test = new ShardSplitTest({ - recipientTagName, - recipientSetName, - quickGarbageCollection: true, - initiateWithShortElectionTimeout: true -}); +const test = + new ShardSplitTest({quickGarbageCollection: true, initiateWithShortElectionTimeout: true}); const fpName = "pauseShardSplitAfterDecision"; testDroppingStateDocCollections(test, fpName, {dropDonorsCollection: true}); diff --git a/jstests/serverless/shard_split_ensure_split_outcome_visibility_for_blocked_writes.js b/jstests/serverless/shard_split_ensure_split_outcome_visibility_for_blocked_writes.js index ef97ea05472..b9332a52471 100644 --- a/jstests/serverless/shard_split_ensure_split_outcome_visibility_for_blocked_writes.js +++ b/jstests/serverless/shard_split_ensure_split_outcome_visibility_for_blocked_writes.js @@ -43,11 +43,8 @@ function insertDocument(primaryHost, dbName, collName) { jsTestLog( "Testing blocked writes can see shard split outcome for a split that has been committed and garbage collected."); - const test = new ShardSplitTest({ - recipientTagName: "recipientNode", - recipientSetName: "recipient", - nodeOptions: Object.assign({setParameter: kGarbageCollectionParams}) - }); + const test = + new ShardSplitTest({nodeOptions: Object.assign({setParameter: kGarbageCollectionParams})}); test.addRecipientNodes(); const tenantIds = ["migrationOutcome-committed"]; const operation = test.createSplitOperation(tenantIds); @@ -94,11 +91,8 @@ function insertDocument(primaryHost, dbName, collName) { jsTestLog( "Testing blocked writes can see shard split outcome for a split that has been aborted and garbage collected."); - const test = new ShardSplitTest({ - recipientTagName: "recipientNode", - recipientSetName: "recipient", - nodeOptions: Object.assign({setParameter: kGarbageCollectionParams}) - }); + const test = + new ShardSplitTest({nodeOptions: Object.assign({setParameter: kGarbageCollectionParams})}); test.addRecipientNodes(); const tenantIds = ["migrationOutcome-committed"]; const operation = test.createSplitOperation(tenantIds); diff --git a/jstests/serverless/shard_split_performance_test.js b/jstests/serverless/shard_split_performance_test.js index a3a338aff03..c9c2c8c15f6 100644 --- a/jstests/serverless/shard_split_performance_test.js +++ b/jstests/serverless/shard_split_performance_test.js @@ -58,13 +58,8 @@ function extractTs(message) { function runOneSplit() { "use strict"; - const recipientTagName = "recipientNode"; - const recipientSetName = "recipientSetName"; - const test = - new ShardSplitTest({recipientTagName, recipientSetName, quickGarbageCollection: true}); - - test.addRecipientNodes(); - test.donor.awaitSecondaryNodes(); + const test = new ShardSplitTest({quickGarbageCollection: true}); + test.addAndAwaitRecipientNodes(); const primary = test.donor.getPrimary(); diff --git a/jstests/serverless/shard_split_recipient_removes_access_blockers.js b/jstests/serverless/shard_split_recipient_removes_access_blockers.js index 9d5496e398e..785c8a95673 100644 --- a/jstests/serverless/shard_split_recipient_removes_access_blockers.js +++ b/jstests/serverless/shard_split_recipient_removes_access_blockers.js @@ -13,11 +13,7 @@ load("jstests/serverless/libs/shard_split_test.js"); // Skip db hash check because secondary is left with a different config. TestData.skipCheckDBHashes = true; -const test = new ShardSplitTest({ - recipientTagName: "recipientNode", - recipientSetName: "recipient", - quickGarbageCollection: true -}); +const test = new ShardSplitTest({quickGarbageCollection: true}); test.addRecipientNodes(); const donorPrimary = test.donor.getPrimary(); diff --git a/jstests/serverless/shard_split_recipient_removes_serverless_lock.js b/jstests/serverless/shard_split_recipient_removes_serverless_lock.js index ecceb01b5ce..ea2611edda2 100644 --- a/jstests/serverless/shard_split_recipient_removes_serverless_lock.js +++ b/jstests/serverless/shard_split_recipient_removes_serverless_lock.js @@ -16,11 +16,7 @@ const {ServerlessLockType, getServerlessOperationLock} = TenantMigrationUtil; // Skip db hash check because secondary is left with a different config. TestData.skipCheckDBHashes = true; -const test = new ShardSplitTest({ - recipientTagName: "recipientNode", - recipientSetName: "recipient", - quickGarbageCollection: true -}); +const test = new ShardSplitTest({quickGarbageCollection: true}); test.addRecipientNodes(); const donorPrimary = test.donor.getPrimary(); diff --git a/jstests/serverless/shard_split_rejects_multiple_ops.js b/jstests/serverless/shard_split_rejects_multiple_ops.js index 48b77d3ac37..ca8bed73777 100644 --- a/jstests/serverless/shard_split_rejects_multiple_ops.js +++ b/jstests/serverless/shard_split_rejects_multiple_ops.js @@ -11,13 +11,10 @@ load("jstests/serverless/libs/shard_split_test.js"); (function() { "use strict"; -const recipientTagName = "recipientNode"; -const recipientSetName = "recipientSetName"; const tenantIds = ["tenant1", "tenant2"]; function commitShardSplitConcurrently() { - const test = - new ShardSplitTest({recipientTagName, recipientSetName, quickGarbageCollection: true}); + const test = new ShardSplitTest({quickGarbageCollection: true}); test.addRecipientNodes(); const donorPrimary = test.donor.getPrimary(); diff --git a/jstests/serverless/shard_split_remove_split_config_after_decision.js b/jstests/serverless/shard_split_remove_split_config_after_decision.js index 84a65da0eaa..36b2c3bd6f2 100644 --- a/jstests/serverless/shard_split_remove_split_config_after_decision.js +++ b/jstests/serverless/shard_split_remove_split_config_after_decision.js @@ -7,13 +7,13 @@ load("jstests/libs/fail_point_util.js"); load("jstests/serverless/libs/shard_split_test.js"); -function assertSplitConfigExists(donorPrimary) { +function assertSplitConfigExists(donorPrimary, recipientSetName) { jsTestLog("Asserting a split config has been applied"); const config = assert.commandWorked(donorPrimary.adminCommand({replSetGetConfig: 1})).config; assert(config, "There must be a config document"); assert.eq(config["members"].length, 3); assert(config["recipientConfig"]); - assert.eq(config["recipientConfig"]["_id"], "recipient"); + assert.eq(config["recipientConfig"]["_id"], recipientSetName); assert.eq(config["recipientConfig"]["members"].length, 3); } @@ -32,12 +32,7 @@ function splitConfigRemovedAfterDecision(simulateErrorToAbortOperation) { // Skip db hash check because secondary is left with a different config. TestData.skipCheckDBHashes = true; const tenantIds = ["tenant1", "tenant2"]; - const test = new ShardSplitTest({ - recipientTagName: "recipientNode", - recipientSetName: "recipient", - quickGarbageCollection: true - }); - + const test = new ShardSplitTest({quickGarbageCollection: true}); test.addRecipientNodes(); const donorPrimary = test.donor.getPrimary(); @@ -62,7 +57,7 @@ function splitConfigRemovedAfterDecision(simulateErrorToAbortOperation) { assertMigrationState(donorPrimary, operation.migrationId, "committed"); } - assertSplitConfigExists(donorPrimary); + assertSplitConfigExists(donorPrimary, test.recipientSetName); beforeConfigRemovalFp.off(); afterDecisionFp.wait(); diff --git a/jstests/serverless/shard_split_startup_recovery_aborted.js b/jstests/serverless/shard_split_startup_recovery_aborted.js index 171266128c2..8e77998c19c 100644 --- a/jstests/serverless/shard_split_startup_recovery_aborted.js +++ b/jstests/serverless/shard_split_startup_recovery_aborted.js @@ -17,11 +17,7 @@ load("jstests/replsets/libs/tenant_migration_test.js"); // Skip db hash check because secondary is left with a different config. TestData.skipCheckDBHashes = true; -const recipientTagName = "recipientNode"; -const recipientSetName = "recipient"; const test = new ShardSplitTest({ - recipientTagName, - recipientSetName, quickGarbageCollection: true, nodeOptions: { setParameter: { @@ -33,30 +29,26 @@ const test = new ShardSplitTest({ test.addRecipientNodes(); let donorPrimary = test.donor.getPrimary(); -const migrationId = UUID(); -assert.isnull(findSplitOperation(donorPrimary, migrationId)); // Pause the shard split before waiting to mark the doc for garbage collection. let fp = configureFailPoint(donorPrimary.getDB("admin"), "pauseShardSplitAfterBlocking"); const tenantIds = ["tenant5", "tenant6"]; - -assert.commandFailed(donorPrimary.adminCommand( - {commitShardSplit: 1, migrationId, recipientTagName, recipientSetName, tenantIds})); - +const operation = test.createSplitOperation(tenantIds); +assert.commandFailed(operation.commit()); fp.wait(); -assertMigrationState(donorPrimary, migrationId, "aborted"); +assertMigrationState(donorPrimary, operation.migrationId, "aborted"); test.stop({shouldRestart: true}); test.donor.startSet({restart: true}); donorPrimary = test.donor.getPrimary(); -assert(findSplitOperation(donorPrimary, migrationId), "There must be a config document"); +assert(findSplitOperation(donorPrimary, operation.migrationId), "There must be a config document"); test.validateTenantAccessBlockers( - migrationId, tenantIds, TenantMigrationTest.DonorAccessState.kAborted); + operation.migrationId, tenantIds, TenantMigrationTest.DonorAccessState.kAborted); test.stop(); })(); diff --git a/jstests/serverless/shard_split_startup_recovery_blocking.js b/jstests/serverless/shard_split_startup_recovery_blocking.js index 85f81c9779f..72af421a979 100644 --- a/jstests/serverless/shard_split_startup_recovery_blocking.js +++ b/jstests/serverless/shard_split_startup_recovery_blocking.js @@ -16,12 +16,7 @@ load("jstests/replsets/libs/tenant_migration_test.js"); // Skip db hash check because secondary is left with a different config. TestData.skipCheckDBHashes = true; -const recipientTagName = "recipientNode"; -const recipientSetName = "recipientSetName"; - const test = new ShardSplitTest({ - recipientTagName, - recipientSetName, quickGarbageCollection: true, nodeOptions: { setParameter: @@ -30,34 +25,27 @@ const test = new ShardSplitTest({ }); test.addRecipientNodes(); -const migrationId = UUID(); let donorPrimary = test.donor.getPrimary(); -assert.isnull(findSplitOperation(donorPrimary, migrationId)); - -let fp = configureFailPoint(donorPrimary.getDB("admin"), "pauseShardSplitAfterBlocking"); +const fp = configureFailPoint(donorPrimary.getDB("admin"), "pauseShardSplitAfterBlocking"); jsTestLog("Running Shard Split restart after blocking"); const tenantIds = ["tenant1", "tenant2"]; -const awaitFirstSplitOperation = startParallelShell( - funWithArgs(function(migrationId, recipientTagName, recipientSetName, tenantIds) { - db.adminCommand( - {commitShardSplit: 1, migrationId, recipientTagName, recipientSetName, tenantIds}); - }, migrationId, recipientTagName, recipientSetName, tenantIds), donorPrimary.port); +const operation = test.createSplitOperation(tenantIds); +const splitThread = operation.commitAsync(); fp.wait(); - -assertMigrationState(donorPrimary, migrationId, "blocking"); +assertMigrationState(donorPrimary, operation.migrationId, "blocking"); test.stop({shouldRestart: true}); -awaitFirstSplitOperation(); +splitThread.join(); test.donor.startSet({restart: true}); donorPrimary = test.donor.getPrimary(); -assert(findSplitOperation(donorPrimary, migrationId), "There must be a config document"); +assert(findSplitOperation(donorPrimary, operation.migrationId), "There must be a config document"); test.validateTenantAccessBlockers( - migrationId, tenantIds, TenantMigrationTest.DonorAccessState.kBlockWritesAndReads); + operation.migrationId, tenantIds, TenantMigrationTest.DonorAccessState.kBlockWritesAndReads); test.stop(); })(); diff --git a/jstests/serverless/shard_split_startup_recovery_committed.js b/jstests/serverless/shard_split_startup_recovery_committed.js index 4984cd45bf1..965c5c0e0d3 100644 --- a/jstests/serverless/shard_split_startup_recovery_committed.js +++ b/jstests/serverless/shard_split_startup_recovery_committed.js @@ -16,11 +16,7 @@ load("jstests/replsets/libs/tenant_migration_test.js"); // Skip db hash check because secondary is left with a different config. TestData.skipCheckDBHashes = true; -const recipientTagName = "recipientNode"; -const recipientSetName = "recipient"; const test = new ShardSplitTest({ - recipientTagName, - recipientSetName, quickGarbageCollection: true, nodeOptions: { setParameter: @@ -29,32 +25,30 @@ const test = new ShardSplitTest({ }); test.addRecipientNodes(); -const migrationId = UUID(); let donorPrimary = test.donor.getPrimary(); -assert.isnull(findSplitOperation(donorPrimary, migrationId)); // Pause the shard split before waiting to mark the doc for garbage collection. let fp = configureFailPoint(donorPrimary.getDB("admin"), "pauseShardSplitAfterDecision"); jsTestLog("Running Shard Split restart after committed"); const tenantIds = ["tenant3", "tenant4"]; -assert.commandWorked(donorPrimary.adminCommand( - {commitShardSplit: 1, migrationId, recipientTagName, recipientSetName, tenantIds})); - +const operation = test.createSplitOperation(tenantIds); +const splitThread = operation.commitAsync(); fp.wait(); -assertMigrationState(donorPrimary, migrationId, "committed"); +splitThread.join(); +assertMigrationState(donorPrimary, operation.migrationId, "committed"); test.stop({shouldRestart: true}); test.donor.startSet({restart: true}); donorPrimary = test.donor.getPrimary(); -const splitDoc = findSplitOperation(donorPrimary, migrationId); +const splitDoc = findSplitOperation(donorPrimary, operation.migrationId); assert(splitDoc, "There must be a config document"); test.validateTenantAccessBlockers( - migrationId, tenantIds, TenantMigrationTest.DonorAccessState.kReject); + operation.migrationId, tenantIds, TenantMigrationTest.DonorAccessState.kReject); test.stop(); })(); diff --git a/jstests/serverless/shard_split_startup_recovery_initially_aborted.js b/jstests/serverless/shard_split_startup_recovery_initially_aborted.js index 2876d5c8d3c..6cc9c89c3ee 100644 --- a/jstests/serverless/shard_split_startup_recovery_initially_aborted.js +++ b/jstests/serverless/shard_split_startup_recovery_initially_aborted.js @@ -20,11 +20,7 @@ const {ServerlessLockType, getServerlessOperationLock} = TenantMigrationUtil; // Skip db hash check because secondary is left with a different config. TestData.skipCheckDBHashes = true; -const recipientTagName = "recipientNode"; -const recipientSetName = "recipient"; const test = new ShardSplitTest({ - recipientTagName, - recipientSetName, quickGarbageCollection: true, nodeOptions: { setParameter: diff --git a/jstests/serverless/shard_split_tenant_access_blocking.js b/jstests/serverless/shard_split_tenant_access_blocking.js index df33370c49e..b15f5220fe2 100644 --- a/jstests/serverless/shard_split_tenant_access_blocking.js +++ b/jstests/serverless/shard_split_tenant_access_blocking.js @@ -17,15 +17,10 @@ jsTestLog("Starting runBlocking"); // Skip db hash check because secondary is left with a different config. TestData.skipCheckDBHashes = true; -const test = new ShardSplitTest({ - recipientTagName: "recipientNode", - recipientSetName: "recipient", - quickGarbageCollection: true -}); +const test = new ShardSplitTest({quickGarbageCollection: true}); test.addRecipientNodes(); const donorPrimary = test.donor.getPrimary(); -const maxTimeMS = 1 * 2000; // 2 seconds const tenantIds = ["tenant1", "tenant2"]; jsTestLog("Asserting no state document exist before command"); diff --git a/jstests/serverless/shard_split_wait_for_block_timestamp.js b/jstests/serverless/shard_split_wait_for_block_timestamp.js index 15e512cb1cf..468708b74d0 100644 --- a/jstests/serverless/shard_split_wait_for_block_timestamp.js +++ b/jstests/serverless/shard_split_wait_for_block_timestamp.js @@ -17,9 +17,8 @@ load("jstests/serverless/libs/shard_split_test.js"); // Skip db hash check because secondary is left with a different config. TestData.skipCheckDBHashes = true; + const test = new ShardSplitTest({ - recipientTagName: "recipientNode", - recipientSetName: "recipient", quickGarbageCollection: true, nodeOptions: { setParameter: // Timeout to test that the operation times out waiting for replication diff --git a/jstests/serverless/shard_split_write_during_aborted_split.js b/jstests/serverless/shard_split_write_during_aborted_split.js index bcf7aa2036b..195c2bbfd47 100644 --- a/jstests/serverless/shard_split_write_during_aborted_split.js +++ b/jstests/serverless/shard_split_write_during_aborted_split.js @@ -1,5 +1,4 @@ /** - * * Test that starts a shard split and abort it while doing a write. * @tags: [requires_fcv_62, serverless] */ @@ -9,61 +8,63 @@ load("jstests/serverless/libs/shard_split_test.js"); (function() { "use strict"; -const recipientTagName = "recipientNode"; -const recipientSetName = "recipientSetName"; +TestData.skipCheckDBHashes = true; const test = new ShardSplitTest({ - recipientTagName, - recipientSetName, nodeOptions: { // Set a short timeout to test that the operation times out waiting for replication setParameter: "shardSplitTimeoutMS=100000" } }); -test.addRecipientNodes(); -test.donor.awaitSecondaryNodes(); +test.addAndAwaitRecipientNodes(); -const donorPrimary = test.donor.getPrimary(); const tenantIds = ["tenant1", "tenant2"]; - -jsTestLog("Writing data before split"); -tenantIds.forEach(id => { - const kDbName = test.tenantDB(id, "testDb"); - const kCollName = "testColl"; - const kNs = `${kDbName}.${kCollName}`; - - assert.commandWorked(donorPrimary.getCollection(kNs).insert( - [{_id: 0, x: 0}, {_id: 1, x: 1}, {_id: 2, x: 2}], {writeConcern: {w: "majority"}})); -}); - const operation = test.createSplitOperation(tenantIds); - +const donorPrimary = test.donor.getPrimary(); const blockingFP = configureFailPoint(donorPrimary.getDB("admin"), "pauseShardSplitAfterBlocking"); +// Start the shard split and wait until we enter the kBlocking state const splitThread = operation.commitAsync(); - blockingFP.wait(); -const donorRst = createRstArgs(test.donor); -test.removeRecipientsFromRstArgs(donorRst); -const writeThread = new Thread(doWriteOperations, donorRst, tenantIds); -writeThread.start(); +// Assert there are no blocked writes for tenants so we can confirm there were blocks later +tenantIds.forEach( + tenantId => assert.eq(TenantMigrationUtil.getNumBlockedWrites(donorPrimary, tenantId), 0)); + +// Now perform one write for each tenantId being split and wait for the writes to become blocked +const writes = tenantIds.map(tenantId => { + const writeThread = new Thread(function(primaryConnStr, tenantId) { + const primary = new Mongo(primaryConnStr); + const coll = primary.getDB(`${tenantId}_testDb`).testColl; + const res = coll.insert([{_id: 0, x: 0}, {_id: 1, x: 1}, {_id: 2, x: 2}], + {writeConcern: {w: "majority"}}); + assert.commandFailedWithCode(res, ErrorCodes.TenantMigrationAborted); + }, donorPrimary.host, tenantId); + + writeThread.start(); + return writeThread; +}); -operation.abort(); +// Verify that we have blocked the expected number of writes to tenant data +tenantIds.forEach(tenantId => { + assert.soon(() => { + // We expect the numBlockedWrites to be a function of tenantIds size because shard split + // donor access blockers are shared for all tenants being split. I don't understand why + // there are two writes for each insert though. + const kExpectedBlockedWrites = tenantIds.length * 2; + + return TenantMigrationUtil.getNumBlockedWrites(donorPrimary, tenantId) == + kExpectedBlockedWrites; + }); +}); +// Then abort the operation, disable the failpoint, and assert the operation was aborted +operation.abort(); blockingFP.off(); +assert.commandFailedWithCode(splitThread.returnData(), ErrorCodes.TenantMigrationAborted); -splitThread.join(); -const result = splitThread.returnData(); -assert.commandFailed(result); - -writeThread.join(); -const writeResults = writeThread.returnData(); -writeResults.forEach(res => { - assert.eq(res, ErrorCodes.OK); -}); - -TestData.skipCheckDBHashes = true; +// Assert all writes were completed with a TenantMigrationAborted error +writes.forEach(write => write.join()); test.stop(); })(); diff --git a/jstests/serverless/shard_split_write_during_shard_split.js b/jstests/serverless/shard_split_write_during_shard_split.js index cee630c5f5c..2015ac0b804 100644 --- a/jstests/serverless/shard_split_write_during_shard_split.js +++ b/jstests/serverless/shard_split_write_during_shard_split.js @@ -9,12 +9,8 @@ load("jstests/serverless/libs/shard_split_test.js"); (function() { "use strict"; -const recipientTagName = "recipientNode"; -const recipientSetName = "recipientSetName"; -const test = new ShardSplitTest({recipientTagName, recipientSetName}); - -test.addRecipientNodes(); -test.donor.awaitSecondaryNodes(); +const test = new ShardSplitTest(); +test.addAndAwaitRecipientNodes(); const donorPrimary = test.donor.getPrimary(); const tenantIds = ["tenant1", "tenant2"]; diff --git a/jstests/serverless/shard_split_write_during_split_stepdown.js b/jstests/serverless/shard_split_write_during_split_stepdown.js index 44b8ef7c091..74a259292f0 100644 --- a/jstests/serverless/shard_split_write_during_split_stepdown.js +++ b/jstests/serverless/shard_split_write_during_split_stepdown.js @@ -11,19 +11,14 @@ load("jstests/serverless/libs/shard_split_test.js"); (function() { "use strict"; -const recipientTagName = "recipientNode"; -const recipientSetName = "recipientSetName"; const test = new ShardSplitTest({ - recipientTagName, - recipientSetName, nodeOptions: { // Set a short timeout to test that the operation times out waiting for replication setParameter: "shardSplitTimeoutMS=100000" } }); -test.addRecipientNodes(); -test.donor.awaitSecondaryNodes(); +test.addAndAwaitRecipientNodes(); const donorPrimary = test.donor.getPrimary(); const tenantIds = ["tenant1", "tenant2"]; diff --git a/src/mongo/db/repl/tenant_migration_access_blocker_registry.cpp b/src/mongo/db/repl/tenant_migration_access_blocker_registry.cpp index 52bda72e412..9b2ffed8755 100644 --- a/src/mongo/db/repl/tenant_migration_access_blocker_registry.cpp +++ b/src/mongo/db/repl/tenant_migration_access_blocker_registry.cpp @@ -342,16 +342,19 @@ void TenantMigrationAccessBlockerRegistry::appendInfoForServerStatus( BSONObjBuilder* builder) const { stdx::lock_guard<Latch> lg(_mutex); - if (const auto donorAccessBlocker = _getAllTenantDonorAccessBlocker(lg); donorAccessBlocker) { + const auto globalDonorAccessBlocker = _getAllTenantDonorAccessBlocker(lg); + if (globalDonorAccessBlocker) { BSONObjBuilder donorMtabInfoBuilder; - donorAccessBlocker->appendInfoForServerStatus(&donorMtabInfoBuilder); + globalDonorAccessBlocker->appendInfoForServerStatus(&donorMtabInfoBuilder); builder->append("donor", donorMtabInfoBuilder.obj()); } for (auto& [tenantId, mtabPair] : _tenantMigrationAccessBlockers) { BSONObjBuilder mtabInfoBuilder; - if (auto donorMtab = mtabPair.getDonorAccessBlocker()) { + auto donorMtab = mtabPair.getDonorAccessBlocker() ? mtabPair.getDonorAccessBlocker() + : globalDonorAccessBlocker; + if (donorMtab) { BSONObjBuilder donorMtabInfoBuilder; donorMtab->appendInfoForServerStatus(&donorMtabInfoBuilder); mtabInfoBuilder.append("donor", donorMtabInfoBuilder.obj()); |