diff --git a/buildscripts/resmokeconfig/matrix_suites/generated_suites/sharded_retryable_writes_downgrade_last_continuous_new_old_old_new.yml b/buildscripts/resmokeconfig/matrix_suites/generated_suites/sharded_retryable_writes_downgrade_last_continuous_new_old_old_new.yml index 73a28378bf6..e307767423a 100644 --- a/buildscripts/resmokeconfig/matrix_suites/generated_suites/sharded_retryable_writes_downgrade_last_continuous_new_old_old_new.yml +++ b/buildscripts/resmokeconfig/matrix_suites/generated_suites/sharded_retryable_writes_downgrade_last_continuous_new_old_old_new.yml @@ -31,6 +31,7 @@ executor: networkErrorAndTxnOverrideConfig: retryOnNetworkErrors: true overrideRetryAttempts: 3 + runningWithShardStepdowns: true sessionOptions: readConcern: level: majority @@ -117,10 +118,6 @@ selector: exclude_with_any_tags: - assumes_against_mongod_not_mongos - assumes_standalone_mongod - - assumes_no_implicit_collection_creation_after_drop - - assumes_no_implicit_index_creation - - assumes_unsharded_collection - - cannot_create_unique_index_when_using_hashed_shard_key - assumes_read_concern_local - requires_getmore - requires_non_retryable_writes diff --git a/buildscripts/resmokeconfig/matrix_suites/generated_suites/sharded_retryable_writes_downgrade_last_lts_new_old_old_new.yml b/buildscripts/resmokeconfig/matrix_suites/generated_suites/sharded_retryable_writes_downgrade_last_lts_new_old_old_new.yml index 85255bcf38c..7f27ed8113c 100644 --- a/buildscripts/resmokeconfig/matrix_suites/generated_suites/sharded_retryable_writes_downgrade_last_lts_new_old_old_new.yml +++ b/buildscripts/resmokeconfig/matrix_suites/generated_suites/sharded_retryable_writes_downgrade_last_lts_new_old_old_new.yml @@ -31,6 +31,7 @@ executor: networkErrorAndTxnOverrideConfig: retryOnNetworkErrors: true overrideRetryAttempts: 3 + runningWithShardStepdowns: true sessionOptions: readConcern: level: majority @@ -117,10 +118,6 @@ selector: exclude_with_any_tags: - assumes_against_mongod_not_mongos - assumes_standalone_mongod - - assumes_no_implicit_collection_creation_after_drop - - assumes_no_implicit_index_creation - - assumes_unsharded_collection - - cannot_create_unique_index_when_using_hashed_shard_key - assumes_read_concern_local - requires_getmore - requires_non_retryable_writes diff --git a/buildscripts/resmokeconfig/suites/sharded_retryable_writes_downgrade.yml b/buildscripts/resmokeconfig/suites/sharded_retryable_writes_downgrade.yml index 82d90b119b6..9a139baeec4 100644 --- a/buildscripts/resmokeconfig/suites/sharded_retryable_writes_downgrade.yml +++ b/buildscripts/resmokeconfig/suites/sharded_retryable_writes_downgrade.yml @@ -70,11 +70,6 @@ selector: exclude_with_any_tags: - assumes_against_mongod_not_mongos - assumes_standalone_mongod - # Tests tagged with the following will fail because they assume collections are not sharded. - - assumes_no_implicit_collection_creation_after_drop - - assumes_no_implicit_index_creation - - assumes_unsharded_collection - - cannot_create_unique_index_when_using_hashed_shard_key # Tests tagged with the following will fail because commands like `explain` does not support majority read concern - assumes_read_concern_local ## @@ -168,6 +163,7 @@ executor: readPreference: mode: "primary" retryWrites: true + runningWithShardStepdowns: true # We specify nodb so the shell used by each test will attempt to connect after loading the # retry logic in auto_retry_on_network_error.js. nodb: "" diff --git a/jstests/core_sharding/resharding/reshard_collection_basic.js b/jstests/core_sharding/resharding/reshard_collection_basic.js index a98639df5bd..cd51fe1dd49 100644 --- a/jstests/core_sharding/resharding/reshard_collection_basic.js +++ b/jstests/core_sharding/resharding/reshard_collection_basic.js @@ -2,10 +2,10 @@ * Basic tests for reshardCollection. * @tags: [ * uses_atclustertime, - * # Stepdown test coverage is already provided by the resharding FSM suites. - * does_not_support_stepdowns, * # This test performs explicit calls to shardCollection * assumes_unsharded_collection, + * # TODO(SERVER-114426) Remove incompatible_aubsan tag + * incompatible_aubsan * ] */ @@ -20,7 +20,6 @@ const collName = jsTestName(); const dbName = db.getName(); const ns = dbName + "." + collName; const mongos = db.getMongo(); - const numInitialDocs = 500; const reshardCmdTest = new ReshardCollectionCmdTest({ @@ -100,7 +99,8 @@ assert.commandFailedWithCode( zones: [{zone: nonExistingZoneName, min: {newKey: 5}, max: {newKey: 10}}], numInitialChunks: 2, }), - ErrorCodes.ZoneNotFound, + // TODO SERVER-103461 Remove ErrorCodes.CannotCreateChunkDistribution when 9.0 becomes last LTS. + [ErrorCodes.ZoneNotFound, ErrorCodes.CannotCreateChunkDistribution], ); jsTest.log("Fail if zone provided is invalid for storage."); @@ -159,7 +159,7 @@ if (!TestData.implicitlyTrackUnshardedCollectionOnCreation) { } // TODO SERVER-103461 Remove version check when 9.0 becomes last LTS. -const binVersion = assert.commandWorked( +let binVersion = assert.commandWorked( db.adminCommand({ serverStatus: 1, }), @@ -296,19 +296,67 @@ reshardCmdTest.assertReshardCollOk( 3, ); -jsTestLog("Succeed if hashed shard key without hashed prefix and numInitialChunks is respected."); -reshardCmdTest.assertReshardCollOk({reshardCollection: ns, key: {oldKey: 1, newKey: "hashed"}, numInitialChunks: 5}, 5); +// TODO SERVER-103461 Remove version check when 9.0 becomes last LTS. +binVersion = assert.commandWorked( + db.adminCommand({ + serverStatus: 1, + }), +).version; +if (MongoRunner.compareBinVersions(binVersion, "8.2") >= 0) { + jsTestLog("Succeed if hashed shard key without hashed prefix and numInitialChunks is respected."); + reshardCmdTest.assertReshardCollOk( + {reshardCollection: ns, key: {oldKey: 1, newKey: "hashed"}, numInitialChunks: 5}, + 5, + ); -jsTest.log("Succeed reshard to hashed shard key with one chunk per shard."); -assert.commandWorked(db.adminCommand({shardCollection: ns, key: {a: "hashed"}})); -assert.commandWorked( - db.getCollection(collName).insert(Array.from({length: 10000}, () => ({a: new ObjectId(), b: new ObjectId()}))), -); -assert.commandWorked(db.adminCommand({reshardCollection: ns, key: {b: "hashed"}})); + jsTest.log("Succeed reshard to hashed shard key with one chunk per shard."); + assert.commandWorked(db.adminCommand({shardCollection: ns, key: {a: "hashed"}})); + assert.soon(() => { + try { + db.getCollection(collName).insert( + Array.from({length: 10000}, () => ({a: new ObjectId(), b: new ObjectId()})), + ); + return true; + } catch (e) { + if (reshardCmdTest.isStepdownRetryableError(e)) { + return false; + } + throw e; + } + }); -let configDB = db.getSiblingDB("config"); -shardNames.forEach((shardName) => { - let chunks = findChunksUtil.findChunksByNs(configDB, ns, {shard: shardName}); - assert.eq(chunks.itcount(), 1); -}); -db.getCollection(collName).drop(); + assert.commandWorked(db.adminCommand({reshardCollection: ns, key: {b: "hashed"}})); + + let configDB = db.getSiblingDB("config"); + shardNames.forEach((shardName) => { + let chunks = findChunksUtil.findChunksByNs(configDB, ns, {shard: shardName}); + assert.eq(chunks.itcount(), 1); + }); + db.getCollection(collName).drop(); + + jsTest.log("Succeed if 'demoMode' parameter is set to true."); + reshardCmdTest.assertReshardCollOk( + {reshardCollection: ns, key: {newKey: 1}, numInitialChunks: 1, demoMode: true}, + 1, + ); +} + +const featureFlagRelaxedMode = FeatureFlagUtil.isPresentAndEnabled(db, "RelaxedMode"); +if (featureFlagRelaxedMode) { + jsTest.log("Succeed if 'relaxed' parameter is set to true."); + + reshardCmdTest.assertReshardCollOk( + {reshardCollection: ns, key: {newKey: 1}, relaxed: true, numInitialChunks: 1}, + 1, + ); +} + +const featureFlagReshardingVerification = FeatureFlagUtil.isPresentAndEnabled(db, "ReshardingVerification"); +if (featureFlagReshardingVerification) { + jsTest.log("Succeed if 'performVerification' parameter is set to true."); + + reshardCmdTest.assertReshardCollOk( + {reshardCollection: ns, key: {newKey: 1}, performVerification: true, numInitialChunks: 1}, + 1, + ); +} diff --git a/jstests/sharding/libs/reshard_collection_util.js b/jstests/sharding/libs/reshard_collection_util.js index d037effb21e..afd7c2d4206 100644 --- a/jstests/sharding/libs/reshard_collection_util.js +++ b/jstests/sharding/libs/reshard_collection_util.js @@ -227,6 +227,11 @@ export class ReshardCollectionCmdTest { }); } + // Suites that run stepdowns can cause commands to fail due to retryable errors, so in those cases we should retry the command. + isStepdownRetryableError(error) { + return TestData.runningWithShardStepdowns && error.code === ErrorCodes.FailedToSatisfyReadPreference; + } + assertReshardCollOkWithPreset(commandObj, presetReshardedChunks) { if (!this._skipCollectionSetup) { const oldShardKey = {oldKey: 1}; @@ -247,7 +252,17 @@ export class ReshardCollectionCmdTest { commandObj._presetReshardedChunks = presetReshardedChunks; const tempReshardingCollName = this._constructTemporaryReshardingCollName(this._dbName, this._collName); - assert.commandWorked(this._mongos.adminCommand(commandObj)); + assert.soon(() => { + try { + assert.commandWorked(this._mongos.adminCommand(commandObj)); + return true; + } catch (e) { + if (this.isStepdownRetryableError(e)) { + return false; + } + throw e; + } + }); this._verifyShardKey(commandObj.key); @@ -302,7 +317,19 @@ export class ReshardCollectionCmdTest { const tempReshardingCollName = this._constructTemporaryReshardingCollName(this._dbName, this._collName); const startTime = Date.now(); - assert.commandWorked(this._mongos.adminCommand(commandObj)); + + assert.soon(() => { + try { + assert.commandWorked(this._mongos.adminCommand(commandObj)); + return true; + } catch (e) { + if (this.isStepdownRetryableError(e)) { + return false; + } + throw e; + } + }); + const endTime = Date.now(); this._reshardDuration = (endTime - startTime) / 1000; @@ -334,7 +361,17 @@ export class ReshardCollectionCmdTest { // Do not drop the collection if this._skipCollectionSetup is true because the caller owns // the setup/teardown of the collection. if (!this._skipCollectionSetup) { - this._mongos.getDB(this._dbName)[this._collName].drop(); + assert.soon(() => { + try { + this._mongos.getDB(this._dbName)[this._collName].drop(); + return true; + } catch (e) { + if (this.isStepdownRetryableError(e)) { + return false; + } + throw e; + } + }); } this._verifyAllShardingCollectionsRemoved(tempReshardingCollName);