diff options
13 files changed, 94 insertions, 45 deletions
diff --git a/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos_and_mixed_shards.yml b/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos_and_mixed_shards.yml index 72ebad3a59e..f8a1525d542 100644 --- a/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos_and_mixed_shards.yml +++ b/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos_and_mixed_shards.yml @@ -142,6 +142,7 @@ selector: - jstests/sharding/refine_collection_shard_key_basic.js - jstests/sharding/move_primary_clone_test.js - jstests/sharding/database_versioning_safe_secondary_reads.js + - jstests/sharding/clone_catalog_data.js # Enable if SERVER-41813 is backported or 4.4 becomes last-stable - jstests/sharding/invalid_system_views_sharded_collection.js diff --git a/jstests/core/views/views_all_commands.js b/jstests/core/views/views_all_commands.js index 2014130b3da..958032cdc01 100644 --- a/jstests/core/views/views_all_commands.js +++ b/jstests/core/views/views_all_commands.js @@ -68,7 +68,7 @@ let viewsCommandTests = { _addShard: {skip: isAnInternalCommand}, - _cloneCatalogData: {skip: isAnInternalCommand}, + _shardsvrCloneCatalogData: {skip: isAnInternalCommand}, _cloneCollectionOptionsFromPrimaryShard: {skip: isAnInternalCommand}, _configsvrAddShard: {skip: isAnInternalCommand}, _configsvrAddShardToZone: {skip: isAnInternalCommand}, @@ -101,7 +101,7 @@ _isSelf: {skip: isAnInternalCommand}, _mergeAuthzCollections: {skip: isAnInternalCommand}, _migrateClone: {skip: isAnInternalCommand}, - _movePrimary: {skip: isAnInternalCommand}, + _shardsvrMovePrimary: {skip: isAnInternalCommand}, _recvChunkAbort: {skip: isAnInternalCommand}, _recvChunkCommit: {skip: isAnInternalCommand}, _recvChunkStart: {skip: isAnInternalCommand}, diff --git a/jstests/sharding/clone_catalog_data.js b/jstests/sharding/clone_catalog_data.js index c2d25fc9d1f..05e922d1d17 100644 --- a/jstests/sharding/clone_catalog_data.js +++ b/jstests/sharding/clone_catalog_data.js @@ -1,7 +1,7 @@ 'use strict'; // Test that the 'cloneCatalogData' command works correctly. -// Eventually, _movePrimary will use this command. +// Eventually, _shardsvrMovePrimary will use this command. (() => { @@ -66,9 +66,9 @@ // Have the other shard clone the DB from the primary. assert.commandWorked(toShard.adminCommand( - {_cloneCatalogData: 'test', from: fromShard.host, writeConcern: {w: "majority"}})); + {_shardsvrCloneCatalogData: 'test', from: fromShard.host, writeConcern: {w: "majority"}})); - // Ask the shard that just called _cloneCatalogData for the collections. + // Ask the shard that just called _shardsvrCloneCatalogData for the collections. res = toShard.getDB('test').runCommand({listCollections: 1}); assert.commandWorked(res); @@ -146,31 +146,38 @@ // Check that the command fails without writeConcern majority. assert.commandFailedWithCode( - toShard.adminCommand({_cloneCatalogData: 'test', from: fromShard.host}), + toShard.adminCommand({_shardsvrCloneCatalogData: 'test', from: fromShard.host}), ErrorCodes.InvalidOptions); // Check that the command fails when attempting to clone the admin database. - assert.commandFailedWithCode( - toShard.adminCommand( - {_cloneCatalogData: 'admin', from: fromShard.host, writeConcern: {w: "majority"}}), - ErrorCodes.InvalidOptions); + assert.commandFailedWithCode(toShard.adminCommand({ + _shardsvrCloneCatalogData: 'admin', + from: fromShard.host, + writeConcern: {w: "majority"} + }), + ErrorCodes.InvalidOptions); // Check that the command fails when attempting to run on the config server. - assert.commandFailedWithCode( - st.configRS.getPrimary().adminCommand( - {_cloneCatalogData: 'test', from: fromShard.host, writeConcern: {w: "majority"}}), - ErrorCodes.NoShardingEnabled); + assert.commandFailedWithCode(st.configRS.getPrimary().adminCommand({ + _shardsvrCloneCatalogData: 'test', + from: fromShard.host, + writeConcern: {w: "majority"} + }), + ErrorCodes.NoShardingEnabled); // Check that the command fails when failing to specify a source. assert.commandFailedWithCode( - toShard.adminCommand({_cloneCatalogData: 'test', from: '', writeConcern: {w: "majority"}}), + toShard.adminCommand( + {_shardsvrCloneCatalogData: 'test', from: '', writeConcern: {w: "majority"}}), ErrorCodes.InvalidOptions); // Check that clone errors when the collection already exists on the destination. - assert.commandFailedWithCode( - toShard.adminCommand( - {_cloneCatalogData: 'test', from: fromShard.host, writeConcern: {w: "majority"}}), - ErrorCodes.NamespaceExists); + assert.commandFailedWithCode(toShard.adminCommand({ + _shardsvrCloneCatalogData: 'test', + from: fromShard.host, + writeConcern: {w: "majority"} + }), + ErrorCodes.NamespaceExists); st.stop(); })(); diff --git a/jstests/sharding/safe_secondary_reads_drop_recreate.js b/jstests/sharding/safe_secondary_reads_drop_recreate.js index 33f0f59b437..86bec870263 100644 --- a/jstests/sharding/safe_secondary_reads_drop_recreate.js +++ b/jstests/sharding/safe_secondary_reads_drop_recreate.js @@ -38,7 +38,7 @@ let testCases = { _addShard: {skip: "primary only"}, - _cloneCatalogData: {skip: "primary only"}, + _shardsvrCloneCatalogData: {skip: "primary only"}, _configsvrAddShard: {skip: "primary only"}, _configsvrAddShardToZone: {skip: "primary only"}, _configsvrBalancerStart: {skip: "primary only"}, @@ -61,7 +61,7 @@ _isSelf: {skip: "does not return user data"}, _mergeAuthzCollections: {skip: "primary only"}, _migrateClone: {skip: "primary only"}, - _movePrimary: {skip: "primary only"}, + _shardsvrMovePrimary: {skip: "primary only"}, _recvChunkAbort: {skip: "primary only"}, _recvChunkCommit: {skip: "primary only"}, _recvChunkStart: {skip: "primary only"}, diff --git a/jstests/sharding/safe_secondary_reads_single_migration_suspend_range_deletion.js b/jstests/sharding/safe_secondary_reads_single_migration_suspend_range_deletion.js index 08904a0bc1b..7809bf4af40 100644 --- a/jstests/sharding/safe_secondary_reads_single_migration_suspend_range_deletion.js +++ b/jstests/sharding/safe_secondary_reads_single_migration_suspend_range_deletion.js @@ -45,7 +45,7 @@ let testCases = { _addShard: {skip: "primary only"}, - _cloneCatalogData: {skip: "primary only"}, + _shardsvrCloneCatalogData: {skip: "primary only"}, _configsvrAddShard: {skip: "primary only"}, _configsvrAddShardToZone: {skip: "primary only"}, _configsvrBalancerStart: {skip: "primary only"}, @@ -68,7 +68,7 @@ _isSelf: {skip: "does not return user data"}, _mergeAuthzCollections: {skip: "primary only"}, _migrateClone: {skip: "primary only"}, - _movePrimary: {skip: "primary only"}, + _shardsvrMovePrimary: {skip: "primary only"}, _recvChunkAbort: {skip: "primary only"}, _recvChunkCommit: {skip: "primary only"}, _recvChunkStart: {skip: "primary only"}, diff --git a/jstests/sharding/safe_secondary_reads_single_migration_waitForDelete.js b/jstests/sharding/safe_secondary_reads_single_migration_waitForDelete.js index a6286881c8e..a405b5c4162 100644 --- a/jstests/sharding/safe_secondary_reads_single_migration_waitForDelete.js +++ b/jstests/sharding/safe_secondary_reads_single_migration_waitForDelete.js @@ -38,7 +38,7 @@ let testCases = { _addShard: {skip: "primary only"}, - _cloneCatalogData: {skip: "primary only"}, + _shardsvrCloneCatalogData: {skip: "primary only"}, _configsvrAddShard: {skip: "primary only"}, _configsvrAddShardToZone: {skip: "primary only"}, _configsvrBalancerStart: {skip: "primary only"}, @@ -61,7 +61,7 @@ _isSelf: {skip: "does not return user data"}, _mergeAuthzCollections: {skip: "primary only"}, _migrateClone: {skip: "primary only"}, - _movePrimary: {skip: "primary only"}, + _shardsvrMovePrimary: {skip: "primary only"}, _recvChunkAbort: {skip: "primary only"}, _recvChunkCommit: {skip: "primary only"}, _recvChunkStart: {skip: "primary only"}, diff --git a/src/mongo/db/s/active_move_primaries_registry.cpp b/src/mongo/db/s/active_move_primaries_registry.cpp index a02da4c899b..dcc15c2ceb6 100644 --- a/src/mongo/db/s/active_move_primaries_registry.cpp +++ b/src/mongo/db/s/active_move_primaries_registry.cpp @@ -73,7 +73,7 @@ StatusWith<ScopedMovePrimary> ActiveMovePrimariesRegistry::registerMovePrimary( boost::optional<NamespaceString> ActiveMovePrimariesRegistry::getActiveMovePrimaryNss() { stdx::lock_guard<stdx::mutex> lk(_mutex); if (_activeMovePrimaryState) { - return _activeMovePrimaryState->requestArgs.get_movePrimary(); + return _activeMovePrimaryState->requestArgs.get_shardsvrMovePrimary(); } return boost::none; @@ -90,7 +90,7 @@ Status ActiveMovePrimariesRegistry::ActiveMovePrimaryState::constructErrorStatus str::stream() << "Unable to start new movePrimary operation because this shard is currently " "moving its primary for namespace " - << requestArgs.get_movePrimary().ns() + << requestArgs.get_shardsvrMovePrimary()->ns() << " to " << requestArgs.getTo()}; } diff --git a/src/mongo/db/s/active_move_primaries_registry_test.cpp b/src/mongo/db/s/active_move_primaries_registry_test.cpp index 52b7d7daf6d..70d7265d66e 100644 --- a/src/mongo/db/s/active_move_primaries_registry_test.cpp +++ b/src/mongo/db/s/active_move_primaries_registry_test.cpp @@ -46,7 +46,7 @@ protected: ShardMovePrimary createMovePrimaryRequest(const NamespaceString& nss) { ShardMovePrimary request; - request.set_movePrimary(std::move(nss)); + request.set_shardsvrMovePrimary(std::move(nss)); request.setTo("shard0001"); return request; diff --git a/src/mongo/db/s/clone_catalog_data_command.cpp b/src/mongo/db/s/clone_catalog_data_command.cpp index a4a3ad7c557..dda7e8e7485 100644 --- a/src/mongo/db/s/clone_catalog_data_command.cpp +++ b/src/mongo/db/s/clone_catalog_data_command.cpp @@ -47,13 +47,14 @@ namespace mongo { namespace { /** - * Currently, _cloneCatalogData will clone all data (including metadata). In the second part of + * Currently, _shardsvrCloneCatalogData will clone all data (including metadata). In the second part + * of * PM-1017 (Introduce Database Versioning in Sharding Config) this command will be changed to only * clone catalog metadata, as the name would suggest. */ class CloneCatalogDataCommand : public BasicCommand { public: - CloneCatalogDataCommand() : BasicCommand("_cloneCatalogData") {} + CloneCatalogDataCommand() : BasicCommand("_shardsvrCloneCatalogData", "_cloneCatalogData") {} AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { return AllowedOnSecondary::kNever; @@ -87,16 +88,17 @@ public: uassertStatusOK(shardingState->canAcceptShardedCommands()); uassert(ErrorCodes::IllegalOperation, - str::stream() << "_cloneCatalogData can only be run on shard servers", + str::stream() << "_shardsvrCloneCatalogData can only be run on shard servers", serverGlobalParams.clusterRole == ClusterRole::ShardServer); uassert(ErrorCodes::InvalidOptions, - str::stream() << "_cloneCatalogData must be called with majority writeConcern, got " - << cmdObj, + str::stream() + << "_shardsvrCloneCatalogData must be called with majority writeConcern, got " + << cmdObj, opCtx->getWriteConcern().wMode == WriteConcernOptions::kMajority); const auto cloneCatalogDataRequest = - CloneCatalogData::parse(IDLParserErrorContext("_cloneCatalogData"), cmdObj); + CloneCatalogData::parse(IDLParserErrorContext("_shardsvrCloneCatalogData"), cmdObj); const auto dbname = cloneCatalogDataRequest.getCommandParameter().toString(); uassert( @@ -112,7 +114,7 @@ public: auto from = cloneCatalogDataRequest.getFrom(); uassert(ErrorCodes::InvalidOptions, - str::stream() << "Can't run _cloneCatalogData without a source", + str::stream() << "Can't run _shardsvrCloneCatalogData without a source", !from.empty()); auto const catalogClient = Grid::get(opCtx)->catalogClient(); diff --git a/src/mongo/db/s/config/configsvr_move_primary_command.cpp b/src/mongo/db/s/config/configsvr_move_primary_command.cpp index f0272e1a92c..eea3b876e46 100644 --- a/src/mongo/db/s/config/configsvr_move_primary_command.cpp +++ b/src/mongo/db/s/config/configsvr_move_primary_command.cpp @@ -181,7 +181,7 @@ public: } ShardMovePrimary shardMovePrimaryRequest; - shardMovePrimaryRequest.set_movePrimary(NamespaceString(dbname)); + shardMovePrimaryRequest.set_shardsvrMovePrimary(NamespaceString(dbname)); shardMovePrimaryRequest.setTo(toShard->getId().toString()); auto cmdResponse = uassertStatusOK(fromShard->runCommandWithFixedRetryAttempts( @@ -192,6 +192,21 @@ public: CommandHelpers::appendPassthroughFields(cmdObj, shardMovePrimaryRequest.toBSON())), Shard::RetryPolicy::kIdempotent)); + // If the `fromShard` is on v4.2 or earlier, it will not recognize the command name + // _shardsvrMovePrimary. We will retry the command with the old name _movePrimary. + if (cmdResponse.commandStatus == ErrorCodes::CommandNotFound) { + ShardMovePrimary legacyShardMovePrimaryRequest; + legacyShardMovePrimaryRequest.set_movePrimary(NamespaceString(dbname)); + legacyShardMovePrimaryRequest.setTo(toShard->getId().toString()); + cmdResponse = uassertStatusOK(fromShard->runCommandWithFixedRetryAttempts( + opCtx, + ReadPreferenceSetting(ReadPreference::PrimaryOnly), + "admin", + CommandHelpers::appendMajorityWriteConcern(CommandHelpers::appendPassthroughFields( + cmdObj, legacyShardMovePrimaryRequest.toBSON())), + Shard::RetryPolicy::kIdempotent)); + } + CommandHelpers::filterCommandReplyForPassthrough(cmdResponse.response, &result); return true; diff --git a/src/mongo/db/s/move_primary_command.cpp b/src/mongo/db/s/move_primary_command.cpp index af7461ad719..58b9deec87d 100644 --- a/src/mongo/db/s/move_primary_command.cpp +++ b/src/mongo/db/s/move_primary_command.cpp @@ -56,7 +56,7 @@ void uassertStatusOKWithWarning(const Status& status) { class MovePrimaryCommand : public BasicCommand { public: - MovePrimaryCommand() : BasicCommand("_movePrimary") {} + MovePrimaryCommand() : BasicCommand("_shardsvrMovePrimary", "_movePrimary") {} std::string help() const override { return "should not be calling this directly"; @@ -100,7 +100,7 @@ public: uassertStatusOK(shardingState->canAcceptShardedCommands()); const auto movePrimaryRequest = - ShardMovePrimary::parse(IDLParserErrorContext("_movePrimary"), cmdObj); + ShardMovePrimary::parse(IDLParserErrorContext("_shardsvrMovePrimary"), cmdObj); const auto dbname = parseNs("", cmdObj); uassert( @@ -113,10 +113,11 @@ public: dbname != NamespaceString::kAdminDb && dbname != NamespaceString::kConfigDb && dbname != NamespaceString::kLocalDb); - uassert(ErrorCodes::InvalidOptions, - str::stream() << "_movePrimary must be called with majority writeConcern, got " - << cmdObj, - opCtx->getWriteConcern().wMode == WriteConcernOptions::kMajority); + uassert( + ErrorCodes::InvalidOptions, + str::stream() << "_shardsvrMovePrimary must be called with majority writeConcern, got " + << cmdObj, + opCtx->getWriteConcern().wMode == WriteConcernOptions::kMajority); uassert(ErrorCodes::InvalidOptions, "you have to specify where you want to move it", diff --git a/src/mongo/db/s/move_primary_source_manager.cpp b/src/mongo/db/s/move_primary_source_manager.cpp index 099c918af6d..aff155b3bb2 100644 --- a/src/mongo/db/s/move_primary_source_manager.cpp +++ b/src/mongo/db/s/move_primary_source_manager.cpp @@ -66,7 +66,7 @@ MovePrimarySourceManager::MovePrimarySourceManager(OperationContext* opCtx, MovePrimarySourceManager::~MovePrimarySourceManager() {} NamespaceString MovePrimarySourceManager::getNss() const { - return _requestArgs.get_movePrimary(); + return _requestArgs.get_shardsvrMovePrimary().get(); } Status MovePrimarySourceManager::clone(OperationContext* opCtx) { @@ -102,7 +102,7 @@ Status MovePrimarySourceManager::clone(OperationContext* opCtx) { auto toShardObj = uassertStatusOK(shardRegistry->getShard(opCtx, _toShard)); BSONObjBuilder cloneCatalogDataCommandBuilder; - cloneCatalogDataCommandBuilder << "_cloneCatalogData" << _dbname << "from" + cloneCatalogDataCommandBuilder << "_shardsvrCloneCatalogData" << _dbname << "from" << fromShardObj->getConnString().toString(); @@ -115,6 +115,24 @@ Status MovePrimarySourceManager::clone(OperationContext* opCtx) { auto cloneCommandStatus = Shard::CommandResponse::getEffectiveStatus(cloneCommandResponse); + // If the `toShard` is on v4.2 or earlier, it will not recognize the command name + // _shardsvrCloneCatalogData. We will retry the command with the old name _cloneCatalogData. + if (cloneCommandStatus == ErrorCodes::CommandNotFound) { + BSONObjBuilder legacyCloneCatalogDataCommandBuilder; + legacyCloneCatalogDataCommandBuilder << "_cloneCatalogData" << _dbname << "from" + << fromShardObj->getConnString().toString(); + + + cloneCommandResponse = toShardObj->runCommandWithFixedRetryAttempts( + opCtx, + ReadPreferenceSetting(ReadPreference::PrimaryOnly), + "admin", + CommandHelpers::appendMajorityWriteConcern(legacyCloneCatalogDataCommandBuilder.obj()), + Shard::RetryPolicy::kIdempotent); + + cloneCommandStatus = Shard::CommandResponse::getEffectiveStatus(cloneCommandResponse); + } + uassertStatusOK(cloneCommandStatus); auto clonedCollsArray = cloneCommandResponse.getValue().response["clonedColls"]; diff --git a/src/mongo/s/request_types/move_primary.idl b/src/mongo/s/request_types/move_primary.idl index 01fd7b6b04e..aa3f0b0b3a2 100644 --- a/src/mongo/s/request_types/move_primary.idl +++ b/src/mongo/s/request_types/move_primary.idl @@ -67,9 +67,14 @@ structs: generate_comparison_operators: true strict: false fields: - _movePrimary: + _shardsvrMovePrimary: type: namespacestring description: "The namespace of the database whose primary shard is to be reassigned." + optional: true + _movePrimary: + type: namespacestring + description: "The deprecated version of this command's name." + optional: true to: type: string description: "The shard serving as the destination for un-sharded collections." |