diff options
31 files changed, 242 insertions, 56 deletions
diff --git a/buildscripts/resmokeconfig/suites/tenant_migration_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/tenant_migration_jscore_passthrough.yml index 02be93b00b8..6df777169de 100644 --- a/buildscripts/resmokeconfig/suites/tenant_migration_jscore_passthrough.yml +++ b/buildscripts/resmokeconfig/suites/tenant_migration_jscore_passthrough.yml @@ -96,7 +96,6 @@ executor: mongod_options: set_parameters: enableTestCommands: 1 - enableTenantMigrations: true # TODO SERVER-51734: Remove the failpoint 'returnResponseOkForRecipientSyncDataCmd'. failpoint.returnResponseOkForRecipientSyncDataCmd: mode: alwaysOn diff --git a/etc/evergreen.yml b/etc/evergreen.yml index f558b29c286..fd93bcde9bf 100644 --- a/etc/evergreen.yml +++ b/etc/evergreen.yml @@ -8825,7 +8825,6 @@ buildvariants: - name: libunwind_tests - name: .multi_shard - name: multi_stmt_txn_jscore_passthrough_with_migration_gen - - name: tenant_migration_jscore_passthrough_gen - name: .ocsp - name: .read_write_concern - name: .replica_sets !.encrypt @@ -10448,7 +10447,6 @@ buildvariants: - name: mqlrun - name: .multi_shard - name: multi_stmt_txn_jscore_passthrough_with_migration_gen - - name: tenant_migration_jscore_passthrough_gen - name: multiversion_gen - name: .query_fuzzer - name: .random_multiversion_ds @@ -10516,7 +10514,7 @@ buildvariants: burn_in_tag_buildvariants: enterprise-rhel-62-64-bit-majority-read-concern-off enterprise-rhel-62-64-bit-inmem linux-64-duroff enterprise-rhel-62-64-bit-multiversion num_scons_link_jobs_available: 0.99 test_flags: >- - --mongodSetParameters="{featureFlagToaster: true, featureFlagSpoon: true}" + --mongodSetParameters="{featureFlagToaster: true, featureFlagSpoon: true, featureFlagTenantMigrations: true}" tasks: - name: compile_parallel_TG distros: @@ -13195,7 +13193,6 @@ buildvariants: # - name: multiversion_sanity_check_gen # - name: mqlrun # - name: .multi_shard -# - name: tenant_migration_jscore_passthrough_gen # - name: .query_fuzzer # - name: .read_write_concern # - name: .replica_sets !.encrypt !.auth !.non_live_record diff --git a/jstests/replsets/libs/tenant_migration_test.js b/jstests/replsets/libs/tenant_migration_test.js index 3875d2ab0d5..646932ae78b 100644 --- a/jstests/replsets/libs/tenant_migration_test.js +++ b/jstests/replsets/libs/tenant_migration_test.js @@ -36,7 +36,7 @@ function TenantMigrationTest({name = "TenantMigrationTest", donorRst, recipientR * Creates a ReplSetTest instance. The repl set will have 2 nodes. */ function performSetUp(isDonor) { - let setParameterOpts = {"enableTenantMigrations": true}; + let setParameterOpts = {}; if (TestData.logComponentVerbosity) { setParameterOpts["logComponentVerbosity"] = tojsononeline(TestData.logComponentVerbosity); @@ -60,6 +60,30 @@ function TenantMigrationTest({name = "TenantMigrationTest", donorRst, recipientR } /** + * Returns whether tenant migration commands are supported. + */ + this.isFeatureFlagEnabled = function() { + const donorPrimary = this.getDonorPrimary(); + const recipientPrimary = this.getRecipientPrimary(); + + function supportsTenantMigrations(conn) { + return assert + .commandWorked(conn.adminCommand({getParameter: 1, featureFlagTenantMigrations: 1})) + .featureFlagTenantMigrations.value; + } + const retVal = + (supportsTenantMigrations(donorPrimary) && supportsTenantMigrations(recipientPrimary)); + if (!retVal) { + jsTestLog("At least one of the donor or recipient replica sets do not support tenant " + + "migration commands. Terminating any replica sets started by the " + + "TenantMigrationTest fixture."); + // Stop any replica sets started by the TenantMigrationTest fixture. + this.stop(); + } + return retVal; + }; + + /** * Runs a tenant migration with the given migration options and waits for the migration to be * committed or aborted. * diff --git a/jstests/replsets/libs/tenant_migration_util.js b/jstests/replsets/libs/tenant_migration_util.js index 8b903a9aa14..e6d38691516 100644 --- a/jstests/replsets/libs/tenant_migration_util.js +++ b/jstests/replsets/libs/tenant_migration_util.js @@ -5,6 +5,15 @@ var TenantMigrationUtil = (function() { load("jstests/replsets/libs/tenant_migration_test.js"); /** + * Returns whether tenant migration commands are supported. + */ + function isFeatureFlagEnabled(conn) { + return assert + .commandWorked(conn.adminCommand({getParameter: 1, featureFlagTenantMigrations: 1})) + .featureFlagTenantMigrations.value; + } + + /** * Runs the donorStartMigration command with the given migration options * until the migration commits or aborts, or until the command fails. Returns the last command * response. @@ -109,5 +118,5 @@ var TenantMigrationUtil = (function() { return donorRstArgs; } - return {runMigrationAsync, forgetMigrationAsync, createRstArgs}; + return {runMigrationAsync, forgetMigrationAsync, createRstArgs, isFeatureFlagEnabled}; })(); diff --git a/jstests/replsets/tenant_migration_commit_transaction_retry.js b/jstests/replsets/tenant_migration_commit_transaction_retry.js index 8f4259b612a..d99a48c80cc 100644 --- a/jstests/replsets/tenant_migration_commit_transaction_retry.js +++ b/jstests/replsets/tenant_migration_commit_transaction_retry.js @@ -20,8 +20,6 @@ const donorRst = new ReplSetTest({ name: "donor", nodeOptions: { setParameter: { - enableTenantMigrations: true, - // Set the delay before a donor state doc is garbage collected to be short to speed up // the test. tenantMigrationGarbageCollectionDelayMS: 3 * 1000, @@ -36,7 +34,6 @@ const recipientRst = new ReplSetTest({ name: "recipient", nodeOptions: { setParameter: { - enableTenantMigrations: true, // TODO SERVER-51734: Remove the failpoint 'returnResponseOkForRecipientSyncDataCmd'. 'failpoint.returnResponseOkForRecipientSyncDataCmd': tojson({mode: 'alwaysOn'}) } @@ -50,6 +47,12 @@ recipientRst.startSet(); recipientRst.initiate(); const tenantMigrationTest = new TenantMigrationTest({name: jsTestName(), donorRst, recipientRst}); +if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + donorRst.stopSet(); + recipientRst.stopSet(); + return; +} const kTenantId = "testTenantId"; const kDbName = tenantMigrationTest.tenantDB(kTenantId, "testDB"); diff --git a/jstests/replsets/tenant_migration_concurrent_bulk_writes.js b/jstests/replsets/tenant_migration_concurrent_bulk_writes.js index a4d4f4146da..e91b9d8adac 100644 --- a/jstests/replsets/tenant_migration_concurrent_bulk_writes.js +++ b/jstests/replsets/tenant_migration_concurrent_bulk_writes.js @@ -33,7 +33,6 @@ const donorRst = new ReplSetTest({ name: 'donor', nodeOptions: { setParameter: { - enableTenantMigrations: true, internalInsertMaxBatchSize: kMaxBatchSize /* Decrease internal max batch size so we can still show writes are batched without inserting hundreds of documents. */ @@ -45,7 +44,6 @@ const recipientRst = new ReplSetTest({ name: 'recipient', nodeOptions: { setParameter: { - enableTenantMigrations: true, internalInsertMaxBatchSize: kMaxBatchSize /* Decrease internal max batch size so we can still show writes are batched without inserting hundreds of documents. */ @@ -121,11 +119,18 @@ function retryFailedWrites(primaryDB, collName, writeErrors, ops) { donorRst.startSet(); donorRst.initiate(); + recipientRst.startSet(); recipientRst.initiate(); const tenantMigrationTest = new TenantMigrationTest({name: jsTestName(), donorRst, recipientRst}); + if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + donorRst.stopSet(); + recipientRst.stopSet(); + return; + } const tenantId = "bulkUnorderedInserts-committed"; const migrationOpts = { @@ -184,11 +189,18 @@ function retryFailedWrites(primaryDB, collName, writeErrors, ops) { donorRst.startSet(); donorRst.initiate(); + recipientRst.startSet(); recipientRst.initiate(); const tenantMigrationTest = new TenantMigrationTest({name: jsTestName(), donorRst, recipientRst}); + if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + donorRst.stopSet(); + recipientRst.stopSet(); + return; + } const tenantId = "bulkUnorderedInserts-committed"; const migrationOpts = { @@ -259,12 +271,19 @@ function retryFailedWrites(primaryDB, collName, writeErrors, ops) { donorRst.startSet(); donorRst.initiate(); + recipientRst.startSet(); recipientRst.initiate(); const tenantMigrationTest = new TenantMigrationTest({name: jsTestName(), donorRst, recipientRst}); + if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + donorRst.stopSet(); + recipientRst.stopSet(); + return; + } const tenantId = "bulkUnorderedInserts-aborted"; const migrationOpts = { migrationIdString: extractUUIDFromObject(UUID()), @@ -337,11 +356,18 @@ function retryFailedWrites(primaryDB, collName, writeErrors, ops) { donorRst.startSet(); donorRst.initiate(); + recipientRst.startSet(); recipientRst.initiate(); const tenantMigrationTest = new TenantMigrationTest({name: jsTestName(), donorRst, recipientRst}); + if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + donorRst.stopSet(); + recipientRst.stopSet(); + return; + } const tenantId = "bulkOrderedInserts-committed"; const migrationOpts = { @@ -395,11 +421,18 @@ function retryFailedWrites(primaryDB, collName, writeErrors, ops) { donorRst.startSet(); donorRst.initiate(); + recipientRst.startSet(); recipientRst.initiate(); const tenantMigrationTest = new TenantMigrationTest({name: jsTestName(), donorRst, recipientRst}); + if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + donorRst.stopSet(); + recipientRst.stopSet(); + return; + } const tenantId = "bulkOrderedInserts-committed"; const migrationOpts = { @@ -465,11 +498,18 @@ function retryFailedWrites(primaryDB, collName, writeErrors, ops) { donorRst.startSet(); donorRst.initiate(); + recipientRst.startSet(); recipientRst.initiate(); const tenantMigrationTest = new TenantMigrationTest({name: jsTestName(), donorRst, recipientRst}); + if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + donorRst.stopSet(); + recipientRst.stopSet(); + return; + } const tenantId = "bulkOrderedInserts-aborted"; const migrationOpts = { diff --git a/jstests/replsets/tenant_migration_concurrent_migrations.js b/jstests/replsets/tenant_migration_concurrent_migrations.js index 63796243762..923f52668c1 100644 --- a/jstests/replsets/tenant_migration_concurrent_migrations.js +++ b/jstests/replsets/tenant_migration_concurrent_migrations.js @@ -18,7 +18,7 @@ load("jstests/libs/uuid_util.js"); load("jstests/replsets/libs/tenant_migration_test.js"); let startupParams = {}; -startupParams["enableTenantMigrations"] = true; + // TODO SERVER-51734: Remove the failpoint 'returnResponseOkForRecipientSyncDataCmd'. startupParams["failpoint.returnResponseOkForRecipientSyncDataCmd"] = tojson({mode: 'alwaysOn'}); @@ -40,6 +40,10 @@ const kTenantIdPrefix = "testTenantId"; // Test concurrent outgoing migrations to different recipients. (() => { const tenantMigrationTest0 = new TenantMigrationTest({donorRst: rst0, recipientRst: rst1}); + if (!tenantMigrationTest0.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + return; + } const tenantMigrationTest1 = new TenantMigrationTest({donorRst: rst0, recipientRst: rst2}); const tenantId0 = `${kTenantIdPrefix}_ConcurrentOutgoingMigrationsToDifferentRecipient0`; const tenantId1 = `${kTenantIdPrefix}_ConcurrentOutgoingMigrationsToDifferentRecipient1`; @@ -69,6 +73,10 @@ const kTenantIdPrefix = "testTenantId"; // Test concurrent incoming migrations from different donors. (() => { const tenantMigrationTest0 = new TenantMigrationTest({donorRst: rst0, recipientRst: rst2}); + if (!tenantMigrationTest0.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + return; + } const tenantMigrationTest1 = new TenantMigrationTest({donorRst: rst1, recipientRst: rst2}); const tenantId0 = `${kTenantIdPrefix}_ConcurrentIncomingMigrations0`; const tenantId1 = `${kTenantIdPrefix}_ConcurrentIncomingMigrations1`; diff --git a/jstests/replsets/tenant_migration_concurrent_reads.js b/jstests/replsets/tenant_migration_concurrent_reads.js index 6170d73891c..aadb9158321 100644 --- a/jstests/replsets/tenant_migration_concurrent_reads.js +++ b/jstests/replsets/tenant_migration_concurrent_reads.js @@ -17,6 +17,10 @@ load("jstests/libs/uuid_util.js"); load("jstests/replsets/libs/tenant_migration_test.js"); const tenantMigrationTest = new TenantMigrationTest({name: jsTestName()}); +if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + return; +} const kCollName = "testColl"; const kTenantDefinedDbName = "0"; diff --git a/jstests/replsets/tenant_migration_concurrent_writes.js b/jstests/replsets/tenant_migration_concurrent_writes.js index 26e7fdbcd6d..adfa22b72c5 100644 --- a/jstests/replsets/tenant_migration_concurrent_writes.js +++ b/jstests/replsets/tenant_migration_concurrent_writes.js @@ -18,6 +18,10 @@ load("jstests/libs/uuid_util.js"); load("jstests/replsets/libs/tenant_migration_test.js"); const tenantMigrationTest = new TenantMigrationTest({name: jsTestName()}); +if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + return; +} const donorRst = tenantMigrationTest.getDonorRst(); const primary = donorRst.getPrimary(); diff --git a/jstests/replsets/tenant_migration_conflicting_donor_start_migration_cmds.js b/jstests/replsets/tenant_migration_conflicting_donor_start_migration_cmds.js index a9d5f60b80a..8c0f53260fa 100644 --- a/jstests/replsets/tenant_migration_conflicting_donor_start_migration_cmds.js +++ b/jstests/replsets/tenant_migration_conflicting_donor_start_migration_cmds.js @@ -32,13 +32,17 @@ function generateUniqueTenantId() { return chars[charIndex++]; } -const donorRst = new ReplSetTest( - {nodes: 1, name: 'donorRst', nodeOptions: {setParameter: {enableTenantMigrations: true}}}); +const donorRst = new ReplSetTest({nodes: 1, name: 'donorRst'}); donorRst.startSet(); donorRst.initiate(); const tenantMigrationTest0 = new TenantMigrationTest({name: jsTestName(), donorRst}); +if (!tenantMigrationTest0.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + donorRst.stopSet(); + return; +} const donorPrimary = donorRst.getPrimary(); const recipientPrimary = tenantMigrationTest0.getRecipientPrimary(); diff --git a/jstests/replsets/tenant_migration_conflicting_recipient_sync_data_cmds.js b/jstests/replsets/tenant_migration_conflicting_recipient_sync_data_cmds.js index 79e4cfaa259..7cdb7116018 100644 --- a/jstests/replsets/tenant_migration_conflicting_recipient_sync_data_cmds.js +++ b/jstests/replsets/tenant_migration_conflicting_recipient_sync_data_cmds.js @@ -8,10 +8,16 @@ "use strict"; load("jstests/libs/parallel_shell_helpers.js"); load("jstests/libs/curop_helpers.js"); // for waitForCurOpByFailPoint(). +load("jstests/replsets/libs/tenant_migration_util.js"); -var rst = new ReplSetTest({nodes: 1, nodeOptions: {setParameter: {enableTenantMigrations: true}}}); +var rst = new ReplSetTest({nodes: 1}); rst.startSet(); rst.initiate(); +if (!TenantMigrationUtil.isFeatureFlagEnabled(rst.getPrimary())) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + rst.stopSet(); + return; +} const primary = rst.getPrimary(); const configDB = primary.getDB("config"); diff --git a/jstests/replsets/tenant_migration_donor_abort_state_transition.js b/jstests/replsets/tenant_migration_donor_abort_state_transition.js index 4b40cc59980..9c16a1adf49 100644 --- a/jstests/replsets/tenant_migration_donor_abort_state_transition.js +++ b/jstests/replsets/tenant_migration_donor_abort_state_transition.js @@ -14,6 +14,10 @@ load("jstests/replsets/libs/tenant_migration_util.js"); const kTenantIdPrefix = "testTenantId"; const tenantMigrationTest = new TenantMigrationTest({name: jsTestName()}); +if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + return; +} /** * Starts a migration and forces the write to insert the donor's state doc to abort on the first few diff --git a/jstests/replsets/tenant_migration_donor_current_op.js b/jstests/replsets/tenant_migration_donor_current_op.js index 55481a20e8c..c820e86a068 100644 --- a/jstests/replsets/tenant_migration_donor_current_op.js +++ b/jstests/replsets/tenant_migration_donor_current_op.js @@ -25,10 +25,9 @@ const migrationStates = { const recipientRst = new ReplSetTest({ nodes: 1, - name: 'donor', + name: 'recipient', nodeOptions: { setParameter: { - enableTenantMigrations: true, // TODO SERVER-51734: Remove the failpoint 'returnResponseOkForRecipientSyncDataCmd'. 'failpoint.returnResponseOkForRecipientSyncDataCmd': tojson({mode: 'alwaysOn'}) } @@ -43,6 +42,11 @@ const kTenantId = 'testTenantId'; (() => { jsTestLog("Testing currentOp output for migration in data sync state"); const tenantMigrationTest = new TenantMigrationTest({name: jsTestName(), recipientRst}); + if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + return; + } + const donorPrimary = tenantMigrationTest.getDonorPrimary(); const migrationId = UUID(); @@ -70,6 +74,10 @@ const kTenantId = 'testTenantId'; (() => { jsTestLog("Testing currentOp output for migration in blocking state"); const tenantMigrationTest = new TenantMigrationTest({name: jsTestName(), recipientRst}); + if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + return; + } const donorPrimary = tenantMigrationTest.getDonorPrimary(); const migrationId = UUID(); @@ -98,6 +106,10 @@ const kTenantId = 'testTenantId'; (() => { jsTestLog("Testing currentOp output for aborted migration"); const tenantMigrationTest = new TenantMigrationTest({name: jsTestName(), recipientRst}); + if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + return; + } const donorPrimary = tenantMigrationTest.getDonorPrimary(); const migrationId = UUID(); @@ -125,6 +137,10 @@ const kTenantId = 'testTenantId'; (() => { jsTestLog("Testing currentOp output for committed migration"); const tenantMigrationTest = new TenantMigrationTest({name: jsTestName(), recipientRst}); + if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + return; + } const donorPrimary = tenantMigrationTest.getDonorPrimary(); const migrationId = UUID(); diff --git a/jstests/replsets/tenant_migration_donor_initial_sync_recovery.js b/jstests/replsets/tenant_migration_donor_initial_sync_recovery.js index 5897bc68806..62408e82106 100644 --- a/jstests/replsets/tenant_migration_donor_initial_sync_recovery.js +++ b/jstests/replsets/tenant_migration_donor_initial_sync_recovery.js @@ -16,6 +16,10 @@ load("jstests/libs/parallelTester.js"); load("jstests/replsets/libs/tenant_migration_test.js"); const tenantMigrationTest = new TenantMigrationTest({name: jsTestName()}); +if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + return; +} const kMaxSleepTimeMS = 1000; const kTenantId = 'testTenantId'; @@ -44,8 +48,7 @@ sleep(Math.random() * kMaxSleepTimeMS); // Add the initial sync node and make sure that it does not step up. const donorRst = tenantMigrationTest.getDonorRst(); -const initialSyncNode = - donorRst.add({rsConfig: {priority: 0, votes: 0}, setParameter: {enableTenantMigrations: true}}); +const initialSyncNode = donorRst.add({rsConfig: {priority: 0, votes: 0}}); donorRst.reInitiate(); jsTestLog("Waiting for initial sync to finish."); diff --git a/jstests/replsets/tenant_migration_donor_interrupt_on_stepdown_and_shutdown.js b/jstests/replsets/tenant_migration_donor_interrupt_on_stepdown_and_shutdown.js index e93795322c4..471f4fe32e6 100644 --- a/jstests/replsets/tenant_migration_donor_interrupt_on_stepdown_and_shutdown.js +++ b/jstests/replsets/tenant_migration_donor_interrupt_on_stepdown_and_shutdown.js @@ -23,6 +23,10 @@ const kTenantId = "testTenantId"; */ function testDonorStartMigrationInterrupt(interruptFunc, verifyCmdResponseFunc) { const tenantMigrationTest = new TenantMigrationTest({name: jsTestName()}); + if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + return; + } const donorRst = tenantMigrationTest.getDonorRst(); const donorPrimary = tenantMigrationTest.getDonorPrimary(); @@ -58,6 +62,10 @@ function testDonorStartMigrationInterrupt(interruptFunc, verifyCmdResponseFunc) */ function testDonorForgetMigrationInterrupt(interruptFunc, verifyCmdResponseFunc) { const tenantMigrationTest = new TenantMigrationTest({name: jsTestName()}); + if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + return; + } const donorRst = tenantMigrationTest.getDonorRst(); const donorPrimary = tenantMigrationTest.getDonorPrimary(); diff --git a/jstests/replsets/tenant_migration_donor_resume_on_stepup_and_restart.js b/jstests/replsets/tenant_migration_donor_resume_on_stepup_and_restart.js index 17537f760d9..3b93fbd37a5 100644 --- a/jstests/replsets/tenant_migration_donor_resume_on_stepup_and_restart.js +++ b/jstests/replsets/tenant_migration_donor_resume_on_stepup_and_restart.js @@ -43,13 +43,17 @@ function assertMigrationCommitsIfDurableStateExists(tenantMigrationTest, migrati * donor using the 'interruptFunc', and asserts that migration eventually commits. */ function testDonorStartMigrationInterrupt(interruptFunc) { - const donorRst = new ReplSetTest( - {nodes: 3, name: "donorRst", nodeOptions: {setParameter: {enableTenantMigrations: true}}}); + const donorRst = new ReplSetTest({nodes: 3, name: "donorRst"}); donorRst.startSet(); donorRst.initiate(); const tenantMigrationTest = new TenantMigrationTest({name: jsTestName(), donorRst}); + if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + donorRst.stopSet(); + return; + } const donorPrimary = tenantMigrationTest.getDonorPrimary(); const migrationId = UUID(); @@ -92,7 +96,6 @@ function testDonorForgetMigrationInterrupt(interruptFunc) { name: "donorRst", nodeOptions: { setParameter: { - enableTenantMigrations: true, tenantMigrationGarbageCollectionDelayMS: kGarbageCollectionDelayMS, ttlMonitorSleepSecs: kTTLMonitorSleepSecs, } @@ -103,7 +106,6 @@ function testDonorForgetMigrationInterrupt(interruptFunc) { name: "recipientRst", nodeOptions: { setParameter: { - enableTenantMigrations: true, // TODO SERVER-51734: Remove the failpoint // 'returnResponseOkForRecipientSyncDataCmd'. 'failpoint.returnResponseOkForRecipientSyncDataCmd': tojson({mode: 'alwaysOn'}), @@ -121,6 +123,12 @@ function testDonorForgetMigrationInterrupt(interruptFunc) { const tenantMigrationTest = new TenantMigrationTest({name: jsTestName(), donorRst, recipientRst}); + if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + donorRst.stopSet(); + recipientRst.stopSet(); + return; + } let donorPrimary = tenantMigrationTest.getDonorPrimary(); const migrationId = UUID(); diff --git a/jstests/replsets/tenant_migration_donor_retry.js b/jstests/replsets/tenant_migration_donor_retry.js index 4bfe59595ae..614e744d424 100644 --- a/jstests/replsets/tenant_migration_donor_retry.js +++ b/jstests/replsets/tenant_migration_donor_retry.js @@ -17,6 +17,10 @@ load("jstests/replsets/libs/tenant_migration_util.js"); const kTenantIdPrefix = "testTenantId"; let testNum = 0; const tenantMigrationTest = new TenantMigrationTest({name: jsTestName()}); +if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + return; +} function makeTenantId() { return kTenantIdPrefix + testNum++; diff --git a/jstests/replsets/tenant_migration_donor_rollback_recovery.js b/jstests/replsets/tenant_migration_donor_rollback_recovery.js index 5db336581d3..74676cecda5 100644 --- a/jstests/replsets/tenant_migration_donor_rollback_recovery.js +++ b/jstests/replsets/tenant_migration_donor_rollback_recovery.js @@ -23,7 +23,6 @@ const recipientRst = new ReplSetTest({ nodes: 1, nodeOptions: { setParameter: { - enableTenantMigrations: true, // TODO SERVER-51734: Remove the failpoint 'returnResponseOkForRecipientSyncDataCmd'. 'failpoint.returnResponseOkForRecipientSyncDataCmd': tojson({mode: 'alwaysOn'}) } @@ -31,6 +30,11 @@ const recipientRst = new ReplSetTest({ }); recipientRst.startSet(); recipientRst.initiate(); +if (!TenantMigrationUtil.isFeatureFlagEnabled(recipientRst.getPrimary())) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + recipientRst.stopSet(); + return; +} function makeMigrationOpts(migrationId, tenantId) { return { @@ -57,7 +61,6 @@ function testRollBack(setUpFunc, rollbackOpsFunc, steadyStateFunc) { settings: {chainingAllowed: false}, nodeOptions: { setParameter: { - enableTenantMigrations: true, // Set the delay before a donor state doc is garbage collected to be short to speed // up the test. tenantMigrationGarbageCollectionDelayMS: kGarbageCollectionDelayMS, diff --git a/jstests/replsets/tenant_migration_donor_startup_recovery.js b/jstests/replsets/tenant_migration_donor_startup_recovery.js index e197d1598f6..d9af905f978 100644 --- a/jstests/replsets/tenant_migration_donor_startup_recovery.js +++ b/jstests/replsets/tenant_migration_donor_startup_recovery.js @@ -19,10 +19,8 @@ const donorRst = new ReplSetTest({ nodes: 1, name: 'donor', nodeOptions: { - setParameter: { - enableTenantMigrations: true, - "failpoint.PrimaryOnlyServiceSkipRebuildingInstances": tojson({mode: "alwaysOn"}) - } + setParameter: + {"failpoint.PrimaryOnlyServiceSkipRebuildingInstances": tojson({mode: "alwaysOn"})} } }); @@ -30,6 +28,11 @@ donorRst.startSet(); donorRst.initiate(); const tenantMigrationTest = new TenantMigrationTest({name: jsTestName(), donorRst}); +if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + donorRst.stopSet(); + return; +} const kMaxSleepTimeMS = 1000; const kTenantId = 'testTenantId'; @@ -68,10 +71,7 @@ sleep(Math.random() * kMaxSleepTimeMS); donorRst.stopSet(null /* signal */, true /*forRestart */); donorRst.startSet({ restart: true, - setParameter: { - enableTenantMigrations: true, - "failpoint.PrimaryOnlyServiceSkipRebuildingInstances": "{'mode':'alwaysOn'}" - } + setParameter: {"failpoint.PrimaryOnlyServiceSkipRebuildingInstances": "{'mode':'alwaysOn'}"} }); donorPrimary = donorRst.getPrimary(); diff --git a/jstests/replsets/tenant_migration_donor_state_machine.js b/jstests/replsets/tenant_migration_donor_state_machine.js index 9c520ee8899..4f172b7dc1b 100644 --- a/jstests/replsets/tenant_migration_donor_state_machine.js +++ b/jstests/replsets/tenant_migration_donor_state_machine.js @@ -61,8 +61,6 @@ const donorRst = new ReplSetTest({ name: "donor", nodeOptions: { setParameter: { - enableTenantMigrations: true, - // Set the delay before a donor state doc is garbage collected to be short to speed up // the test. tenantMigrationGarbageCollectionDelayMS: 3 * 1000, @@ -77,6 +75,11 @@ donorRst.startSet(); donorRst.initiate(); const tenantMigrationTest = new TenantMigrationTest({name: jsTestName(), donorRst}); +if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + donorRst.stopSet(); + return; +} const recipientRst = tenantMigrationTest.getRecipientRst(); const donorPrimary = tenantMigrationTest.getDonorPrimary(); diff --git a/jstests/replsets/tenant_migration_ensure_migration_outcome_visibility_for_blocked_writes.js b/jstests/replsets/tenant_migration_ensure_migration_outcome_visibility_for_blocked_writes.js index 190c0d5b6d2..191f2c82d10 100644 --- a/jstests/replsets/tenant_migration_ensure_migration_outcome_visibility_for_blocked_writes.js +++ b/jstests/replsets/tenant_migration_ensure_migration_outcome_visibility_for_blocked_writes.js @@ -28,7 +28,6 @@ const donorRst = new ReplSetTest({ name: 'donor', nodeOptions: { setParameter: { - enableTenantMigrations: true, tenantMigrationGarbageCollectionDelayMS: kGarbageCollectionDelayMS, ttlMonitorSleepSecs: kTTLMonitorSleepSecs, } @@ -50,6 +49,11 @@ function insertDocument(primaryHost, dbName, collName) { donorRst.initiate(); const tenantMigrationTest = new TenantMigrationTest({name: jsTestName(), donorRst}); + if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + donorRst.stopSet(); + return; + } const migrationId = UUID(); const tenantId = "migrationOutcome-committed"; @@ -107,6 +111,11 @@ function insertDocument(primaryHost, dbName, collName) { donorRst.initiate(); const tenantMigrationTest = new TenantMigrationTest({name: jsTestName(), donorRst}); + if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + donorRst.stopSet(); + return; + } const migrationId = UUID(); const tenantId = "migrationOutcome-aborted"; diff --git a/jstests/replsets/tenant_migration_index_oplog_entries.js b/jstests/replsets/tenant_migration_index_oplog_entries.js index 3eb5c5ae133..a5eda5f8256 100644 --- a/jstests/replsets/tenant_migration_index_oplog_entries.js +++ b/jstests/replsets/tenant_migration_index_oplog_entries.js @@ -8,14 +8,20 @@ "use strict"; load("jstests/libs/fail_point_util.js"); +load("jstests/replsets/libs/tenant_migration_util.js"); const kDbName = "testDb"; const kCollName = "testColl"; const kNs = kDbName + "." + kCollName; -const rst = new ReplSetTest({nodes: [{setParameter: {enableTenantMigrations: true}}]}); +const rst = new ReplSetTest({nodes: 1}); rst.startSet(); rst.initiate(); +if (!TenantMigrationUtil.isFeatureFlagEnabled(rst.getPrimary())) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + rst.stopSet(); + return; +} const primary = rst.getPrimary(); const testDB = primary.getDB(kDbName); diff --git a/jstests/replsets/tenant_migration_invalid_inputs.js b/jstests/replsets/tenant_migration_invalid_inputs.js index ce1d44efb73..016742ab083 100644 --- a/jstests/replsets/tenant_migration_invalid_inputs.js +++ b/jstests/replsets/tenant_migration_invalid_inputs.js @@ -9,10 +9,16 @@ (function() { "use strict"; -const rst = - new ReplSetTest({nodes: 1, nodeOptions: {setParameter: {enableTenantMigrations: true}}}); +load("jstests/replsets/libs/tenant_migration_util.js"); + +const rst = new ReplSetTest({nodes: 1}); rst.startSet(); rst.initiate(); +if (!TenantMigrationUtil.isFeatureFlagEnabled(rst.getPrimary())) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + rst.stopSet(); + return; +} const primary = rst.getPrimary(); const tenantId = "test"; const connectionString = "foo/bar:12345"; diff --git a/jstests/replsets/tenant_migration_large_txn.js b/jstests/replsets/tenant_migration_large_txn.js index a97fc8b9196..fc5ff2a0a79 100644 --- a/jstests/replsets/tenant_migration_large_txn.js +++ b/jstests/replsets/tenant_migration_large_txn.js @@ -18,6 +18,10 @@ load("jstests/replsets/libs/tenant_migration_test.js"); load("jstests/replsets/libs/tenant_migration_util.js"); const tenantMigrationTest = new TenantMigrationTest({name: jsTestName()}); +if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + return; +} const kTenantId = "testTenantId"; const kDbName = tenantMigrationTest.tenantDB(kTenantId, "testDB"); diff --git a/jstests/replsets/tenant_migration_no_failover.js b/jstests/replsets/tenant_migration_no_failover.js index 374f9140ab7..e474d0e0783 100644 --- a/jstests/replsets/tenant_migration_no_failover.js +++ b/jstests/replsets/tenant_migration_no_failover.js @@ -13,6 +13,10 @@ load("jstests/libs/uuid_util.js"); load("jstests/replsets/libs/tenant_migration_test.js"); const tenantMigrationTest = new TenantMigrationTest(jsTestName()); +if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + return; +} const tenantId = "testTenantId"; const dbNames = ["db0", "db1", "db2"]; diff --git a/jstests/replsets/tenant_migration_retryable_write_retry.js b/jstests/replsets/tenant_migration_retryable_write_retry.js index 6e3d8e4648d..5dbc49df7ba 100644 --- a/jstests/replsets/tenant_migration_retryable_write_retry.js +++ b/jstests/replsets/tenant_migration_retryable_write_retry.js @@ -17,8 +17,6 @@ const donorRst = new ReplSetTest({ name: "donor", nodeOptions: { setParameter: { - enableTenantMigrations: true, - // Set the delay before a donor state doc is garbage collected to be short to speed up // the test. tenantMigrationGarbageCollectionDelayMS: 3 * 1000, @@ -33,7 +31,6 @@ const recipientRst = new ReplSetTest({ name: "recipient", nodeOptions: { setParameter: { - enableTenantMigrations: true, // TODO SERVER-51734: Remove the failpoint 'returnResponseOkForRecipientSyncDataCmd'. 'failpoint.returnResponseOkForRecipientSyncDataCmd': tojson({mode: 'alwaysOn'}) } @@ -47,6 +44,12 @@ recipientRst.startSet(); recipientRst.initiate(); const tenantMigrationTest = new TenantMigrationTest({name: jsTestName(), donorRst, recipientRst}); +if (!tenantMigrationTest.isFeatureFlagEnabled()) { + jsTestLog("Skipping test because the tenant migrations feature flag is disabled"); + donorRst.stopSet(); + recipientRst.stopSet(); + return; +} const kTenantId = "testTenantId"; const kDbName = kTenantId + "_" + diff --git a/src/mongo/db/commands/tenant_migration_donor_cmds.cpp b/src/mongo/db/commands/tenant_migration_donor_cmds.cpp index 467e4c4c9c9..ffdfb4c755f 100644 --- a/src/mongo/db/commands/tenant_migration_donor_cmds.cpp +++ b/src/mongo/db/commands/tenant_migration_donor_cmds.cpp @@ -51,7 +51,8 @@ public: Response typedRun(OperationContext* opCtx) { uassert(ErrorCodes::CommandNotSupported, "donorStartMigration command not enabled", - repl::enableTenantMigrations); + repl::feature_flags::gTenantMigrations.isEnabled( + serverGlobalParams.featureCompatibility)); const RequestType& requestBody = request(); @@ -118,7 +119,8 @@ public: void typedRun(OperationContext* opCtx) { uassert(ErrorCodes::CommandNotSupported, "donorForgetMigration command not enabled", - repl::enableTenantMigrations); + repl::feature_flags::gTenantMigrations.isEnabled( + serverGlobalParams.featureCompatibility)); const RequestType& requestBody = request(); diff --git a/src/mongo/db/commands/tenant_migration_recipient_cmds.cpp b/src/mongo/db/commands/tenant_migration_recipient_cmds.cpp index 85e6fd07974..186ce909cc5 100644 --- a/src/mongo/db/commands/tenant_migration_recipient_cmds.cpp +++ b/src/mongo/db/commands/tenant_migration_recipient_cmds.cpp @@ -54,7 +54,8 @@ public: Response typedRun(OperationContext* opCtx) { uassert(ErrorCodes::CommandNotSupported, "recipientSyncData command not enabled", - repl::enableTenantMigrations); + repl::feature_flags::gTenantMigrations.isEnabled( + serverGlobalParams.featureCompatibility)); const auto& cmd = request(); @@ -126,7 +127,8 @@ public: void typedRun(OperationContext* opCtx) { uassert(ErrorCodes::CommandNotSupported, "recipientForgetMigration command not enabled", - repl::enableTenantMigrations); + repl::feature_flags::gTenantMigrations.isEnabled( + serverGlobalParams.featureCompatibility)); } void doCheckAuthorization(OperationContext* opCtx) const {} diff --git a/src/mongo/db/repl/SConscript b/src/mongo/db/repl/SConscript index 98894133ad2..1095830b10b 100644 --- a/src/mongo/db/repl/SConscript +++ b/src/mongo/db/repl/SConscript @@ -11,6 +11,7 @@ env.Library( ], LIBDEPS_PRIVATE=[ '$BUILD_DIR/mongo/client/read_preference', + '$BUILD_DIR/mongo/idl/feature_flag', '$BUILD_DIR/mongo/idl/server_parameter', ] ) diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp index 32ce306829b..1ea29defe74 100644 --- a/src/mongo/db/repl/oplog.cpp +++ b/src/mongo/db/repl/oplog.cpp @@ -258,7 +258,10 @@ void _logOpsInner(OperationContext* opCtx, // entry for renameCollection has 'nss' set to the fromCollection's ns. renameCollection can be // across databases, but a tenant will never be able to rename into a database with a different // prefix, so it is safe to use the fromCollection's db's prefix for this check. - if (repl::enableTenantMigrations) { + // + // We ignore FCV here when checking the feature flag since the FCV may not have been initialized + // yet. This is safe since tenant migrations does not have any upgrade/downgrade behavior. + if (repl::feature_flags::gTenantMigrations.isEnabledAndIgnoreFCV()) { // Skip the check if this is an "abortIndexBuild" oplog entry since it is safe to the abort // an index build on the donor after the blockTimestamp, plus if an index build fails to // commit due to TenantMigrationConflict, we need to be able to abort the index build and diff --git a/src/mongo/db/repl/repl_server_parameters.idl b/src/mongo/db/repl/repl_server_parameters.idl index 289bf286c9a..fea22ddbbc1 100644 --- a/src/mongo/db/repl/repl_server_parameters.idl +++ b/src/mongo/db/repl/repl_server_parameters.idl @@ -324,14 +324,6 @@ server_parameters: cpp_varname: disableSplitHorizonIPCheck default: false - enableTenantMigrations: - description: >- - If true, enables tenant migration commands. - set_at: startup - cpp_vartype: bool - cpp_varname: enableTenantMigrations - default: false - tenantMigrationGarbageCollectionDelayMS: description: >- The amount of time in milliseconds that the donor or recipient should wait before @@ -363,3 +355,10 @@ server_parameters: # defaultBatchSize to use. default: expr: (16 * 1024 * 1024) / 12 * 10 + +feature_flags: + featureFlagTenantMigrations: + description: >- + When enabled, tenant migration commands are supported. + cpp_varname: feature_flags::gTenantMigrations + default: false |