diff options
author | Andy Schwerin <schwerin@mongodb.com> | 2015-10-02 17:44:17 -0400 |
---|---|---|
committer | Andy Schwerin <schwerin@mongodb.com> | 2015-10-06 12:45:03 -0400 |
commit | 9267d348b98e3be67a85f219ba184c35f35fc309 (patch) | |
tree | 2f5453f78ff8b15207f9c9df0fc0fffb1f42cb4f | |
parent | d9f2d8fda800fdc2cbd2be30413412c19a24f97a (diff) | |
download | mongo-9267d348b98e3be67a85f219ba184c35f35fc309.tar.gz |
SERVER-20743 Combine target selection and command execution in ShardRegistry.
Also, properly set the metadata field on all commands dispatched through ShardRegistry.
28 files changed, 378 insertions, 290 deletions
diff --git a/src/mongo/client/read_preference.cpp b/src/mongo/client/read_preference.cpp index da94f18ff9e..1ab5c5c13e1 100644 --- a/src/mongo/client/read_preference.cpp +++ b/src/mongo/client/read_preference.cpp @@ -114,6 +114,9 @@ TagSet TagSet::primaryOnly() { ReadPreferenceSetting::ReadPreferenceSetting(ReadPreference pref, TagSet tags) : pref(std::move(pref)), tags(std::move(tags)) {} +ReadPreferenceSetting::ReadPreferenceSetting(ReadPreference pref) + : ReadPreferenceSetting(pref, defaultTagSetForMode(pref)) {} + StatusWith<ReadPreferenceSetting> ReadPreferenceSetting::fromBSON(const BSONObj& readPrefObj) { std::string modeStr; auto modeExtractStatus = bsonExtractStringField(readPrefObj, kModeFieldName, &modeStr); diff --git a/src/mongo/client/read_preference.h b/src/mongo/client/read_preference.h index 161cfc0f241..57177c69345 100644 --- a/src/mongo/client/read_preference.h +++ b/src/mongo/client/read_preference.h @@ -121,8 +121,7 @@ struct ReadPreferenceSetting { */ ReadPreferenceSetting(ReadPreference pref, TagSet tags); - // TODO: remove when StatusWith supports non-default constructible types (SERVER-18007) - ReadPreferenceSetting() = default; + explicit ReadPreferenceSetting(ReadPreference pref); inline bool equals(const ReadPreferenceSetting& other) const { return (pref == other.pref) && (tags == other.tags); @@ -148,8 +147,8 @@ struct ReadPreferenceSetting { */ static StatusWith<ReadPreferenceSetting> fromBSON(const BSONObj& readPrefSettingObj); - ReadPreference pref{ReadPreference::PrimaryOnly}; - TagSet tags{TagSet::primaryOnly()}; + ReadPreference pref; + TagSet tags; }; } // namespace mongo diff --git a/src/mongo/client/read_preference_test.cpp b/src/mongo/client/read_preference_test.cpp index bbd55e5bfb8..447f37d51ca 100644 --- a/src/mongo/client/read_preference_test.cpp +++ b/src/mongo/client/read_preference_test.cpp @@ -102,7 +102,7 @@ TEST(ReadPreferenceSetting, Roundtrip) { << "ca") << BSON("foo" << "bar"))))); - checkRoundtrip(ReadPreferenceSetting()); + checkRoundtrip(ReadPreferenceSetting(ReadPreference::PrimaryOnly)); checkRoundtrip(ReadPreferenceSetting(ReadPreference::PrimaryPreferred, TagSet())); diff --git a/src/mongo/db/repl/data_replicator.cpp b/src/mongo/db/repl/data_replicator.cpp index 13a39524b03..fc457104fce 100644 --- a/src/mongo/db/repl/data_replicator.cpp +++ b/src/mongo/db/repl/data_replicator.cpp @@ -45,6 +45,7 @@ #include "mongo/db/repl/optime.h" #include "mongo/db/repl/sync_source_selector.h" #include "mongo/rpc/metadata/repl_set_metadata.h" +#include "mongo/rpc/metadata/server_selection_metadata.h" #include "mongo/stdx/functional.h" #include "mongo/stdx/thread.h" #include "mongo/util/assert_util.h" @@ -386,7 +387,8 @@ Status DatabasesCloner::start() { log() << "starting cloning of all databases"; // Schedule listDatabase command which will kick off the database cloner per result db. - Request listDBsReq(_source, "admin", BSON("listDatabases" << true), BSON("$secondaryOk" << 1)); + Request listDBsReq( + _source, "admin", BSON("listDatabases" << true), BSON(rpc::kSecondaryOkFieldName << 1)); CBHStatus s = _exec->scheduleRemoteCommand( listDBsReq, stdx::bind(&DatabasesCloner::_onListDatabaseFinish, this, stdx::placeholders::_1)); diff --git a/src/mongo/rpc/metadata/server_selection_metadata.cpp b/src/mongo/rpc/metadata/server_selection_metadata.cpp index a4fbbde3fca..e865c676931 100644 --- a/src/mongo/rpc/metadata/server_selection_metadata.cpp +++ b/src/mongo/rpc/metadata/server_selection_metadata.cpp @@ -43,11 +43,11 @@ namespace mongo { namespace rpc { -namespace { - const char kSecondaryOkFieldName[] = "$secondaryOk"; const char kReadPreferenceFieldName[] = "$readPreference"; +namespace { + const char kQueryOptionsFieldName[] = "$queryOptions"; const char kDollarQueryWrapper[] = "$query"; diff --git a/src/mongo/rpc/metadata/server_selection_metadata.h b/src/mongo/rpc/metadata/server_selection_metadata.h index 1f345af9a19..279d47a0803 100644 --- a/src/mongo/rpc/metadata/server_selection_metadata.h +++ b/src/mongo/rpc/metadata/server_selection_metadata.h @@ -44,6 +44,18 @@ class StatusWith; namespace rpc { /** + * Symbolic constant for the "$secondaryOk" metadata field. This field should be of boolean or + * numeric type, and is treated as a boolean. + */ +extern const char kSecondaryOkFieldName[]; + +/** + * Symbolic constant for the "$readPreference" metadata field. The field should be of Object type + * when present. + */ +extern const char kReadPreferenceFieldName[]; + +/** * This class comprises the request metadata fields that concern server selection, that is, * the conditions on which servers can execute this operation. */ diff --git a/src/mongo/s/balance.cpp b/src/mongo/s/balance.cpp index 8bc9ba55bac..be7785b1366 100644 --- a/src/mongo/s/balance.cpp +++ b/src/mongo/s/balance.cpp @@ -226,11 +226,12 @@ bool Balancer::_checkOIDs(OperationContext* txn) { continue; } - const auto shardHost = uassertStatusOK( - s->getTargeter()->findHost({ReadPreference::PrimaryOnly, TagSet::primaryOnly()})); - - BSONObj f = uassertStatusOK( - grid.shardRegistry()->runCommand(txn, shardHost, "admin", BSON("features" << 1))); + BSONObj f = uassertStatusOK(grid.shardRegistry()->runCommandOnShard( + txn, + s, + ReadPreferenceSetting{ReadPreference::PrimaryOnly}, + "admin", + BSON("features" << 1))); if (f["oidMachine"].isNumber()) { int x = f["oidMachine"].numberInt(); if (oids.count(x) == 0) { @@ -239,16 +240,21 @@ bool Balancer::_checkOIDs(OperationContext* txn) { log() << "error: 2 machines have " << x << " as oid machine piece: " << shardId << " and " << oids[x]; - uassertStatusOK(grid.shardRegistry()->runCommand( - txn, shardHost, "admin", BSON("features" << 1 << "oidReset" << 1))); + uassertStatusOK(grid.shardRegistry()->runCommandOnShard( + txn, + s, + ReadPreferenceSetting{ReadPreference::PrimaryOnly}, + "admin", + BSON("features" << 1 << "oidReset" << 1))); const auto otherShard = grid.shardRegistry()->getShard(txn, oids[x]); if (otherShard) { - const auto otherShardHost = uassertStatusOK(otherShard->getTargeter()->findHost( - {ReadPreference::PrimaryOnly, TagSet::primaryOnly()})); - - uassertStatusOK(grid.shardRegistry()->runCommand( - txn, otherShardHost, "admin", BSON("features" << 1 << "oidReset" << 1))); + uassertStatusOK(grid.shardRegistry()->runCommandOnShard( + txn, + otherShard, + ReadPreferenceSetting{ReadPreference::PrimaryOnly}, + "admin", + BSON("features" << 1 << "oidReset" << 1))); } return false; diff --git a/src/mongo/s/balancer_policy.cpp b/src/mongo/s/balancer_policy.cpp index b07119bdad5..8864a0b298b 100644 --- a/src/mongo/s/balancer_policy.cpp +++ b/src/mongo/s/balancer_policy.cpp @@ -69,16 +69,12 @@ namespace { std::string retrieveShardMongoDVersion(OperationContext* txn, ShardId shardId, ShardRegistry* shardRegistry) { - auto shard = shardRegistry->getShard(txn, shardId); - if (!shard) { - uassertStatusOK({ErrorCodes::ShardNotFound, "Shard not found"}); - } - - auto shardHost = uassertStatusOK( - shard->getTargeter()->findHost({ReadPreference::PrimaryOnly, TagSet::primaryOnly()})); - BSONObj serverStatus = uassertStatusOK( - shardRegistry->runCommand(txn, shardHost, "admin", BSON("serverStatus" << 1))); + shardRegistry->runCommandOnShard(txn, + shardId, + ReadPreferenceSetting{ReadPreference::PrimaryOnly}, + "admin", + BSON("serverStatus" << 1))); BSONElement versionElement = serverStatus["version"]; if (versionElement.type() != String) { uassertStatusOK({ErrorCodes::NoSuchKey, "version field not found in serverStatus"}); diff --git a/src/mongo/s/catalog/catalog_manager_common.cpp b/src/mongo/s/catalog/catalog_manager_common.cpp index 6d9e19d69c6..92f9f6def61 100644 --- a/src/mongo/s/catalog/catalog_manager_common.cpp +++ b/src/mongo/s/catalog/catalog_manager_common.cpp @@ -97,22 +97,14 @@ StatusWith<ShardType> validateHostAsShard(OperationContext* txn, return {ErrorCodes::BadValue, "shard name cannot be empty"}; } - auto shardConn = shardRegistry->createConnection(connectionString); + const std::shared_ptr<Shard> shardConn{shardRegistry->createConnection(connectionString)}; invariant(shardConn); - auto shardHostStatus = - shardConn->getTargeter()->findHost({ReadPreference::PrimaryOnly, TagSet::primaryOnly()}); - if (!shardHostStatus.isOK()) { - return shardHostStatus.getStatus(); - } - - const HostAndPort& shardHost = shardHostStatus.getValue(); - - StatusWith<BSONObj> cmdStatus{ErrorCodes::InternalError, "uninitialized value"}; + const ReadPreferenceSetting readPref{ReadPreference::PrimaryOnly}; // Is it mongos? - cmdStatus = - shardRegistry->runCommandForAddShard(txn, shardHost, "admin", BSON("isdbgrid" << 1)); + auto cmdStatus = shardRegistry->runCommandForAddShard( + txn, shardConn, readPref, "admin", BSON("isdbgrid" << 1)); if (!cmdStatus.isOK()) { return cmdStatus.getStatus(); } @@ -123,8 +115,8 @@ StatusWith<ShardType> validateHostAsShard(OperationContext* txn, } // Is it a replica set? - cmdStatus = - shardRegistry->runCommandForAddShard(txn, shardHost, "admin", BSON("isMaster" << 1)); + cmdStatus = shardRegistry->runCommandForAddShard( + txn, shardConn, readPref, "admin", BSON("isMaster" << 1)); if (!cmdStatus.isOK()) { return cmdStatus.getStatus(); } @@ -158,7 +150,7 @@ StatusWith<ShardType> validateHostAsShard(OperationContext* txn, // Is it a mongos config server? cmdStatus = shardRegistry->runCommandForAddShard( - txn, shardHost, "admin", BSON("replSetGetStatus" << 1)); + txn, shardConn, readPref, "admin", BSON("replSetGetStatus" << 1)); if (!cmdStatus.isOK()) { return cmdStatus.getStatus(); } @@ -219,8 +211,8 @@ StatusWith<ShardType> validateHostAsShard(OperationContext* txn, if (hostSet.find(host) == hostSet.end()) { return {ErrorCodes::OperationFailed, str::stream() << "in seed list " << connectionString.toString() << ", host " - << host << " does not belong to replica set " - << foundSetName}; + << host << " does not belong to replica set " << foundSetName + << "; found " << resIsMaster.toString()}; } } } @@ -256,19 +248,16 @@ StatusWith<ShardType> validateHostAsShard(OperationContext* txn, */ StatusWith<std::vector<std::string>> getDBNamesListFromShard( OperationContext* txn, ShardRegistry* shardRegistry, const ConnectionString& connectionString) { - auto shardConn = shardRegistry->createConnection(connectionString); + const std::shared_ptr<Shard> shardConn{ + shardRegistry->createConnection(connectionString).release()}; invariant(shardConn); - auto shardHostStatus = - shardConn->getTargeter()->findHost({ReadPreference::PrimaryOnly, TagSet::primaryOnly()}); - if (!shardHostStatus.isOK()) { - return shardHostStatus.getStatus(); - } - - const HostAndPort& shardHost = shardHostStatus.getValue(); - auto cmdStatus = - shardRegistry->runCommandForAddShard(txn, shardHost, "admin", BSON("listDatabases" << 1)); + shardRegistry->runCommandForAddShard(txn, + shardConn, + ReadPreferenceSetting{ReadPreference::PrimaryOnly}, + "admin", + BSON("listDatabases" << 1)); if (!cmdStatus.isOK()) { return cmdStatus.getStatus(); } diff --git a/src/mongo/s/catalog/dist_lock_catalog_impl.cpp b/src/mongo/s/catalog/dist_lock_catalog_impl.cpp index a227397ce77..87c41729056 100644 --- a/src/mongo/s/catalog/dist_lock_catalog_impl.cpp +++ b/src/mongo/s/catalog/dist_lock_catalog_impl.cpp @@ -36,7 +36,6 @@ #include "mongo/base/status_with.h" #include "mongo/bson/util/bson_extract.h" #include "mongo/client/read_preference.h" -#include "mongo/client/remote_command_targeter.h" #include "mongo/db/lasterror.h" #include "mongo/db/query/find_and_modify_request.h" #include "mongo/db/repl/read_concern_args.h" @@ -155,17 +154,8 @@ DistLockCatalogImpl::DistLockCatalogImpl(ShardRegistry* shardRegistry, DistLockCatalogImpl::~DistLockCatalogImpl() = default; StatusWith<LockpingsType> DistLockCatalogImpl::getPing(StringData processID) { - auto targetStatus = _client->getConfigShard()->getTargeter()->findHost(kReadPref); - - if (!targetStatus.isOK()) { - return targetStatus.getStatus(); - } - - auto findResult = _findOnConfig(targetStatus.getValue(), - _lockPingNS, - BSON(LockpingsType::process() << processID), - BSONObj(), - 1); + auto findResult = _findOnConfig( + kReadPref, _lockPingNS, BSON(LockpingsType::process() << processID), BSONObj(), 1); if (!findResult.isOK()) { return findResult.getStatus(); @@ -335,14 +325,7 @@ Status DistLockCatalogImpl::unlock(const OID& lockSessionID) { } StatusWith<DistLockCatalog::ServerInfo> DistLockCatalogImpl::getServerInfo() { - auto targetStatus = _client->getConfigShard()->getTargeter()->findHost(kReadPref); - - if (!targetStatus.isOK()) { - return targetStatus.getStatus(); - } - - auto resultStatus = - _client->runCommandOnConfig(targetStatus.getValue(), "admin", BSON("serverStatus" << 1)); + auto resultStatus = _client->runCommandOnConfig(kReadPref, "admin", BSON("serverStatus" << 1)); if (!resultStatus.isOK()) { return resultStatus.getStatus(); @@ -374,14 +357,8 @@ StatusWith<DistLockCatalog::ServerInfo> DistLockCatalogImpl::getServerInfo() { } StatusWith<LocksType> DistLockCatalogImpl::getLockByTS(const OID& lockSessionID) { - auto targetStatus = _client->getConfigShard()->getTargeter()->findHost(kReadPref); - - if (!targetStatus.isOK()) { - return targetStatus.getStatus(); - } - - auto findResult = _findOnConfig( - targetStatus.getValue(), _locksNS, BSON(LocksType::lockID(lockSessionID)), BSONObj(), 1); + auto findResult = + _findOnConfig(kReadPref, _locksNS, BSON(LocksType::lockID(lockSessionID)), BSONObj(), 1); if (!findResult.isOK()) { return findResult.getStatus(); @@ -406,14 +383,8 @@ StatusWith<LocksType> DistLockCatalogImpl::getLockByTS(const OID& lockSessionID) } StatusWith<LocksType> DistLockCatalogImpl::getLockByName(StringData name) { - auto targetStatus = _client->getConfigShard()->getTargeter()->findHost(kReadPref); - - if (!targetStatus.isOK()) { - return targetStatus.getStatus(); - } - - auto findResult = _findOnConfig( - targetStatus.getValue(), _locksNS, BSON(LocksType::name() << name), BSONObj(), 1); + auto findResult = + _findOnConfig(kReadPref, _locksNS, BSON(LocksType::name() << name), BSONObj(), 1); if (!findResult.isOK()) { return findResult.getStatus(); @@ -455,13 +426,14 @@ Status DistLockCatalogImpl::stopPing(StringData processId) { return findAndModifyStatus.getStatus(); } -StatusWith<vector<BSONObj>> DistLockCatalogImpl::_findOnConfig(const HostAndPort& host, - const NamespaceString& nss, - const BSONObj& query, - const BSONObj& sort, - boost::optional<long long> limit) { +StatusWith<vector<BSONObj>> DistLockCatalogImpl::_findOnConfig( + const ReadPreferenceSetting& readPref, + const NamespaceString& nss, + const BSONObj& query, + const BSONObj& sort, + boost::optional<long long> limit) { repl::ReadConcernArgs readConcern(boost::none, repl::ReadConcernLevel::kMajorityReadConcern); - auto result = _client->exhaustiveFindOnConfigNode(host, nss, query, sort, limit, readConcern); + auto result = _client->exhaustiveFindOnConfig(readPref, nss, query, sort, limit, readConcern); if (!result.isOK()) { return result.getStatus(); diff --git a/src/mongo/s/catalog/dist_lock_catalog_impl.h b/src/mongo/s/catalog/dist_lock_catalog_impl.h index 85c9837ba73..a38aaf088f7 100644 --- a/src/mongo/s/catalog/dist_lock_catalog_impl.h +++ b/src/mongo/s/catalog/dist_lock_catalog_impl.h @@ -40,10 +40,10 @@ namespace mongo { -struct HostAndPort; class NamespaceString; -class RemoteCommandTargeter; class ShardRegistry; +struct HostAndPort; +struct ReadPreferenceSetting; class DistLockCatalogImpl final : public DistLockCatalog { public: @@ -81,7 +81,7 @@ public: virtual Status stopPing(StringData processId) override; private: - StatusWith<std::vector<BSONObj>> _findOnConfig(const HostAndPort& host, + StatusWith<std::vector<BSONObj>> _findOnConfig(const ReadPreferenceSetting& readPref, const NamespaceString& nss, const BSONObj& query, const BSONObj& sort, diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp index c9238e52cfa..e4e323316d7 100644 --- a/src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp +++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp @@ -1126,21 +1126,14 @@ StatusWith<OpTimePair<vector<BSONObj>>> CatalogManagerReplicaSet::_exhaustiveFin Status lastStatus = Status::OK(); for (int retry = 0; retry < kMaxReadRetry; retry++) { - const auto configShard = grid.shardRegistry()->getShard(txn, "config"); - const auto readHost = configShard->getTargeter()->findHost(kConfigReadSelector); - if (!readHost.isOK()) { - return readHost.getStatus(); - } - - repl::ReadConcernArgs readConcern(grid.shardRegistry()->getConfigOpTime(), - repl::ReadConcernLevel::kMajorityReadConcern); + repl::ReadConcernArgs readConcern{grid.shardRegistry()->getConfigOpTime(), + repl::ReadConcernLevel::kMajorityReadConcern}; - auto result = grid.shardRegistry()->exhaustiveFindOnConfigNode( - readHost.getValue(), nss, query, sort, limit, readConcern); + auto result = grid.shardRegistry()->exhaustiveFindOnConfig( + kConfigReadSelector, nss, query, sort, limit, readConcern); if (ErrorCodes::isNetworkError(result.getStatus().code())) { lastStatus = result.getStatus(); - configShard->getTargeter()->markHostUnreachable(readHost.getValue()); continue; } @@ -1168,18 +1161,10 @@ bool CatalogManagerReplicaSet::_runReadCommand(OperationContext* txn, BSONObjBuilder* result) { Status lastStatus = Status::OK(); for (int retry = 0; retry < kMaxReadRetry; retry++) { - auto targeter = grid.shardRegistry()->getShard(txn, "config")->getTargeter(); - auto target = targeter->findHost(settings); - if (!target.isOK()) { - return Command::appendCommandStatus(*result, target.getStatus()); - } - - auto resultStatus = - grid.shardRegistry()->runCommandOnConfig(target.getValue(), dbname, cmdObj); + auto resultStatus = grid.shardRegistry()->runCommandOnConfig(settings, dbname, cmdObj); if (ErrorCodes::isNetworkError(resultStatus.getStatus().code())) { lastStatus = resultStatus.getStatus(); - targeter->markHostUnreachable(target.getValue()); continue; } diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set_add_shard_test.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set_add_shard_test.cpp index 6408997d55c..d5cded88dca 100644 --- a/src/mongo/s/catalog/replset/catalog_manager_replica_set_add_shard_test.cpp +++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set_add_shard_test.cpp @@ -37,6 +37,7 @@ #include "mongo/db/commands.h" #include "mongo/db/query/lite_parsed_query.h" #include "mongo/rpc/metadata/repl_set_metadata.h" +#include "mongo/rpc/metadata/server_selection_metadata.h" #include "mongo/s/catalog/replset/catalog_manager_replica_set.h" #include "mongo/s/catalog/replset/catalog_manager_replica_set_test_fixture.h" #include "mongo/s/catalog/type_changelog.h" @@ -215,7 +216,8 @@ TEST_F(AddShardTest, AddShardStandalone) { // in the previous call, in the config server metadata onFindCommand([&](const RemoteCommandRequest& request) { ASSERT_EQ(request.target, configHost); - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.toString(), DatabaseType::ConfigNS); @@ -233,7 +235,8 @@ TEST_F(AddShardTest, AddShardStandalone) { onFindCommand([this](const RemoteCommandRequest& request) { const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.toString(), DatabaseType::ConfigNS); - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); auto query = assertGet(LiteParsedQuery::makeFromFindCommand(nss, request.cmdObj, false)); @@ -329,7 +332,8 @@ TEST_F(AddShardTest, AddShardStandaloneGenerateName) { // in the previous call, in the config server metadata onFindCommand([&](const RemoteCommandRequest& request) { ASSERT_EQ(request.target, configHost); - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.toString(), DatabaseType::ConfigNS); @@ -345,7 +349,8 @@ TEST_F(AddShardTest, AddShardStandaloneGenerateName) { }); onFindCommand([this](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.toString(), DatabaseType::ConfigNS); @@ -366,7 +371,8 @@ TEST_F(AddShardTest, AddShardStandaloneGenerateName) { // New name is being generated for the new shard onFindCommand([this, &existingShard](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.toString(), ShardType::ConfigNS); auto query = assertGet(LiteParsedQuery::makeFromFindCommand(nss, request.cmdObj, false)); diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set_drop_coll_test.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set_drop_coll_test.cpp index 32d2ffddef7..9bf0a35041c 100644 --- a/src/mongo/s/catalog/replset/catalog_manager_replica_set_drop_coll_test.cpp +++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set_drop_coll_test.cpp @@ -35,6 +35,7 @@ #include "mongo/db/namespace_string.h" #include "mongo/db/query/lite_parsed_query.h" #include "mongo/rpc/metadata/repl_set_metadata.h" +#include "mongo/rpc/metadata/server_selection_metadata.h" #include "mongo/s/catalog/dist_lock_manager_mock.h" #include "mongo/s/catalog/replset/catalog_manager_replica_set.h" #include "mongo/s/catalog/replset/catalog_manager_replica_set_test_fixture.h" @@ -105,8 +106,6 @@ public: ASSERT_EQ(_configHost, request.target); ASSERT_EQ("config", request.dbname); - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); - BSONObj expectedCmd(fromjson(R"({ delete: "chunks", deletes: [{ q: { ns: "test.user" }, limit: 0 }], diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set_log_action_test.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set_log_action_test.cpp index 25144113704..a169cac4b76 100644 --- a/src/mongo/s/catalog/replset/catalog_manager_replica_set_log_action_test.cpp +++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set_log_action_test.cpp @@ -35,6 +35,7 @@ #include "mongo/executor/network_interface_mock.h" #include "mongo/executor/task_executor.h" #include "mongo/rpc/metadata/repl_set_metadata.h" +#include "mongo/rpc/metadata/server_selection_metadata.h" #include "mongo/s/catalog/replset/catalog_manager_replica_set.h" #include "mongo/s/catalog/replset/catalog_manager_replica_set_test_fixture.h" #include "mongo/s/catalog/type_actionlog.h" diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set_remove_shard_test.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set_remove_shard_test.cpp index 3a1857eee58..5a15c4da606 100644 --- a/src/mongo/s/catalog/replset/catalog_manager_replica_set_remove_shard_test.cpp +++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set_remove_shard_test.cpp @@ -38,6 +38,7 @@ #include "mongo/executor/network_interface_mock.h" #include "mongo/executor/task_executor.h" #include "mongo/rpc/metadata/repl_set_metadata.h" +#include "mongo/rpc/metadata/server_selection_metadata.h" #include "mongo/s/catalog/replset/catalog_manager_replica_set.h" #include "mongo/s/catalog/replset/catalog_manager_replica_set_test_fixture.h" #include "mongo/s/catalog/type_chunk.h" @@ -172,7 +173,8 @@ TEST_F(RemoveShardTest, RemoveShardStartDraining) { // Respond to request to reload information about existing shards onFindCommand([&](const RemoteCommandRequest& request) { ASSERT_EQUALS(configHost, request.target); - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); auto query = assertGet(LiteParsedQuery::makeFromFindCommand(nss, request.cmdObj, false)); @@ -348,7 +350,8 @@ TEST_F(RemoveShardTest, RemoveShardCompletion) { // Respond to request to reload information about existing shards onFindCommand([&](const RemoteCommandRequest& request) { ASSERT_EQUALS(configHost, request.target); - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); auto query = assertGet(LiteParsedQuery::makeFromFindCommand(nss, request.cmdObj, false)); diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set_shard_collection_test.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set_shard_collection_test.cpp index df0ab0697d2..a28192ec0b1 100644 --- a/src/mongo/s/catalog/replset/catalog_manager_replica_set_shard_collection_test.cpp +++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set_shard_collection_test.cpp @@ -40,6 +40,7 @@ #include "mongo/executor/network_interface_mock.h" #include "mongo/executor/task_executor.h" #include "mongo/rpc/metadata/repl_set_metadata.h" +#include "mongo/rpc/metadata/server_selection_metadata.h" #include "mongo/s/catalog/dist_lock_manager_mock.h" #include "mongo/s/catalog/replset/catalog_manager_replica_set.h" #include "mongo/s/catalog/replset/catalog_manager_replica_set_test_fixture.h" @@ -82,7 +83,9 @@ public: void expectGetDatabase(const DatabaseType& expectedDb) { onFindCommand([&](const RemoteCommandRequest& request) { ASSERT_EQUALS(configHost, request.target); - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS( + BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(DatabaseType::ConfigNS, nss.ns()); @@ -152,7 +155,9 @@ public: void expectReloadChunks(const std::string& ns, const vector<ChunkType>& chunks) { onFindCommand([&](const RemoteCommandRequest& request) { ASSERT_EQUALS(configHost, request.target); - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS( + BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.ns(), ChunkType::ConfigNS); @@ -212,7 +217,9 @@ public: void expectReloadCollection(const CollectionType& collection) { onFindCommand([&](const RemoteCommandRequest& request) { ASSERT_EQUALS(configHost, request.target); - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS( + BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.ns(), CollectionType::ConfigNS); @@ -238,7 +245,9 @@ public: void expectLoadNewestChunk(const string& ns, const ChunkType& chunk) { onFindCommand([&](const RemoteCommandRequest& request) { ASSERT_EQUALS(configHost, request.target); - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS( + BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.ns(), ChunkType::ConfigNS); @@ -760,7 +769,7 @@ TEST_F(ShardCollectionTest, withInitialData) { ASSERT_EQUALS(0, request.cmdObj["maxSplitPoints"].numberLong()); ASSERT_EQUALS(0, request.cmdObj["maxChunkObjects"].numberLong()); - ASSERT_EQUALS(rpc::makeEmptyMetadata(), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1), request.metadata); return BSON("ok" << 1 << "splitKeys" << BSON_ARRAY(splitPoint0 << splitPoint1 << splitPoint2 << splitPoint3)); diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp index f8dd2b959bf..44c414e239c 100644 --- a/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp +++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp @@ -39,6 +39,7 @@ #include "mongo/executor/network_interface_mock.h" #include "mongo/executor/task_executor.h" #include "mongo/rpc/metadata/repl_set_metadata.h" +#include "mongo/rpc/metadata/server_selection_metadata.h" #include "mongo/s/catalog/dist_lock_manager_mock.h" #include "mongo/s/catalog/replset/catalog_manager_replica_set.h" #include "mongo/s/catalog/replset/catalog_manager_replica_set_test_fixture.h" @@ -95,7 +96,8 @@ TEST_F(CatalogManagerReplSetTest, GetCollectionExisting) { onFindWithMetadataCommand([this, &expectedColl, newOpTime]( const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.ns(), CollectionType::ConfigNS); @@ -155,7 +157,8 @@ TEST_F(CatalogManagerReplSetTest, GetDatabaseExisting) { const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.ns(), DatabaseType::ConfigNS); - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); auto query = assertGet(LiteParsedQuery::makeFromFindCommand(nss, request.cmdObj, false)); @@ -330,7 +333,8 @@ TEST_F(CatalogManagerReplSetTest, GetAllShardsValid) { }); onFindCommand([this, &s1, &s2, &s3](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.ns(), ShardType::ConfigNS); @@ -429,7 +433,8 @@ TEST_F(CatalogManagerReplSetTest, GetChunksForNSWithSortAndLimit) { onFindWithMetadataCommand([this, &chunksQuery, chunkA, chunkB, newOpTime]( const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.ns(), ChunkType::ConfigNS); @@ -476,7 +481,8 @@ TEST_F(CatalogManagerReplSetTest, GetChunksForNSNoSortNoLimit) { }); onFindCommand([this, &chunksQuery](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.ns(), ChunkType::ConfigNS); @@ -554,7 +560,8 @@ TEST_F(CatalogManagerReplSetTest, RunUserManagementReadCommand) { }); onCommand([](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); ASSERT_EQUALS("test", request.dbname); ASSERT_EQUALS(BSON("usersInfo" << 1), request.cmdObj); @@ -762,7 +769,8 @@ TEST_F(CatalogManagerReplSetTest, GetGlobalSettingsBalancerDoc) { }); onFindCommand([this, st1](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.ns(), SettingsType::ConfigNS); @@ -795,7 +803,8 @@ TEST_F(CatalogManagerReplSetTest, GetGlobalSettingsChunkSizeDoc) { }); onFindCommand([this, st1](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.ns(), SettingsType::ConfigNS); @@ -825,7 +834,8 @@ TEST_F(CatalogManagerReplSetTest, GetGlobalSettingsInvalidDoc) { }); onFindCommand([this](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.ns(), SettingsType::ConfigNS); @@ -857,7 +867,8 @@ TEST_F(CatalogManagerReplSetTest, GetGlobalSettingsNonExistent) { }); onFindCommand([this](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.ns(), SettingsType::ConfigNS); @@ -919,7 +930,8 @@ TEST_F(CatalogManagerReplSetTest, GetCollectionsValidResultsNoDb) { onFindWithMetadataCommand([this, coll1, coll2, coll3, newOpTime]( const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.ns(), CollectionType::ConfigNS); @@ -976,7 +988,8 @@ TEST_F(CatalogManagerReplSetTest, GetCollectionsValidResultsWithDb) { }); onFindCommand([this, coll1, coll2](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.ns(), CollectionType::ConfigNS); @@ -1027,7 +1040,8 @@ TEST_F(CatalogManagerReplSetTest, GetCollectionsInvalidCollectionType) { const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.ns(), CollectionType::ConfigNS); - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); auto query = assertGet(LiteParsedQuery::makeFromFindCommand(nss, request.cmdObj, false)); @@ -1070,7 +1084,8 @@ TEST_F(CatalogManagerReplSetTest, GetDatabasesForShardValid) { }); onFindCommand([this, dbt1, dbt2](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.ns(), DatabaseType::ConfigNS); @@ -1144,7 +1159,8 @@ TEST_F(CatalogManagerReplSetTest, GetTagsForCollection) { }); onFindCommand([this, tagA, tagB](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.ns(), TagsType::ConfigNS); @@ -1231,7 +1247,8 @@ TEST_F(CatalogManagerReplSetTest, GetTagForChunkOneTagFound) { }); onFindCommand([this, chunk](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.ns(), TagsType::ConfigNS); @@ -1276,7 +1293,8 @@ TEST_F(CatalogManagerReplSetTest, GetTagForChunkNoTagFound) { }); onFindCommand([this, chunk](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.ns(), TagsType::ConfigNS); @@ -1318,7 +1336,8 @@ TEST_F(CatalogManagerReplSetTest, GetTagForChunkInvalidTagDoc) { }); onFindCommand([this, chunk](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(nss.ns(), TagsType::ConfigNS); @@ -1502,7 +1521,8 @@ TEST_F(CatalogManagerReplSetTest, createDatabaseSuccess) { onFindCommand([&](const RemoteCommandRequest& request) { ASSERT_EQUALS(configHost, request.target); - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); auto query = assertGet(LiteParsedQuery::makeFromFindCommand(nss, request.cmdObj, false)); @@ -1549,7 +1569,8 @@ TEST_F(CatalogManagerReplSetTest, createDatabaseSuccess) { onFindCommand([&](const RemoteCommandRequest& request) { ASSERT_EQUALS(configHost, request.target); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); ASSERT_EQ(DatabaseType::ConfigNS, nss.ns()); checkReadConcern(request.cmdObj, Timestamp(0, 0), repl::OpTime::kUninitializedTerm); return vector<BSONObj>{}; @@ -1563,7 +1584,7 @@ TEST_F(CatalogManagerReplSetTest, createDatabaseSuccess) { ASSERT_EQUALS("listDatabases", cmdName); ASSERT_FALSE(request.cmdObj.hasField(repl::ReadConcernArgs::kReadConcernFieldName)); - ASSERT_EQUALS(rpc::makeEmptyMetadata(), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1), request.metadata); return BSON("ok" << 1 << "totalSize" << 10); }); @@ -1576,7 +1597,7 @@ TEST_F(CatalogManagerReplSetTest, createDatabaseSuccess) { ASSERT_EQUALS("listDatabases", cmdName); ASSERT_FALSE(request.cmdObj.hasField(repl::ReadConcernArgs::kReadConcernFieldName)); - ASSERT_EQUALS(rpc::makeEmptyMetadata(), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1), request.metadata); return BSON("ok" << 1 << "totalSize" << 1); }); @@ -1588,7 +1609,7 @@ TEST_F(CatalogManagerReplSetTest, createDatabaseSuccess) { string cmdName = request.cmdObj.firstElement().fieldName(); ASSERT_EQUALS("listDatabases", cmdName); - ASSERT_EQUALS(rpc::makeEmptyMetadata(), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1), request.metadata); return BSON("ok" << 1 << "totalSize" << 100); }); @@ -1664,7 +1685,8 @@ TEST_F(CatalogManagerReplSetTest, createDatabaseDBExists) { }); onFindCommand([this, dbname](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); auto query = assertGet(LiteParsedQuery::makeFromFindCommand(nss, request.cmdObj, false)); @@ -1703,7 +1725,8 @@ TEST_F(CatalogManagerReplSetTest, createDatabaseDBExistsDifferentCase) { }); onFindCommand([this, dbname, dbnameDiffCase](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); auto query = assertGet(LiteParsedQuery::makeFromFindCommand(nss, request.cmdObj, false)); @@ -1742,7 +1765,8 @@ TEST_F(CatalogManagerReplSetTest, createDatabaseNoShards) { // Report no databases with the same name already exist onFindCommand([this, dbname](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(DatabaseType::ConfigNS, nss.ns()); checkReadConcern(request.cmdObj, Timestamp(0, 0), repl::OpTime::kUninitializedTerm); @@ -1751,7 +1775,8 @@ TEST_F(CatalogManagerReplSetTest, createDatabaseNoShards) { // Report no shards exist onFindCommand([this](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); auto query = assertGet(LiteParsedQuery::makeFromFindCommand(nss, request.cmdObj, false)); @@ -1790,7 +1815,8 @@ TEST_F(CatalogManagerReplSetTest, createDatabaseDuplicateKeyOnInsert) { onFindCommand([&](const RemoteCommandRequest& request) { ASSERT_EQUALS(configHost, request.target); - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); auto query = assertGet(LiteParsedQuery::makeFromFindCommand(nss, request.cmdObj, false)); @@ -1835,7 +1861,8 @@ TEST_F(CatalogManagerReplSetTest, createDatabaseDuplicateKeyOnInsert) { // Report no databases with the same name already exist onFindCommand([&](const RemoteCommandRequest& request) { ASSERT_EQUALS(configHost, request.target); - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(DatabaseType::ConfigNS, nss.ns()); checkReadConcern(request.cmdObj, Timestamp(0, 0), repl::OpTime::kUninitializedTerm); @@ -1850,7 +1877,7 @@ TEST_F(CatalogManagerReplSetTest, createDatabaseDuplicateKeyOnInsert) { ASSERT_EQUALS("listDatabases", cmdName); ASSERT_FALSE(request.cmdObj.hasField(repl::ReadConcernArgs::kReadConcernFieldName)); - ASSERT_EQUALS(rpc::makeEmptyMetadata(), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1), request.metadata); return BSON("ok" << 1 << "totalSize" << 10); }); @@ -1863,7 +1890,7 @@ TEST_F(CatalogManagerReplSetTest, createDatabaseDuplicateKeyOnInsert) { ASSERT_EQUALS("listDatabases", cmdName); ASSERT_FALSE(request.cmdObj.hasField(repl::ReadConcernArgs::kReadConcernFieldName)); - ASSERT_EQUALS(rpc::makeEmptyMetadata(), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1), request.metadata); return BSON("ok" << 1 << "totalSize" << 1); }); @@ -1876,7 +1903,7 @@ TEST_F(CatalogManagerReplSetTest, createDatabaseDuplicateKeyOnInsert) { ASSERT_EQUALS("listDatabases", cmdName); ASSERT_FALSE(request.cmdObj.hasField(repl::ReadConcernArgs::kReadConcernFieldName)); - ASSERT_EQUALS(rpc::makeEmptyMetadata(), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1), request.metadata); return BSON("ok" << 1 << "totalSize" << 100); }); @@ -1946,7 +1973,8 @@ TEST_F(CatalogManagerReplSetTest, EnableShardingNoDBExists) { // Query to find if db already exists in config. onFindCommand([this](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); ASSERT_EQ(DatabaseType::ConfigNS, nss.toString()); @@ -1972,7 +2000,7 @@ TEST_F(CatalogManagerReplSetTest, EnableShardingNoDBExists) { ASSERT_EQ("admin", request.dbname); ASSERT_EQ(BSON("listDatabases" << 1), request.cmdObj); - ASSERT_EQUALS(rpc::makeEmptyMetadata(), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1), request.metadata); return fromjson(R"({ databases: [], @@ -2177,7 +2205,9 @@ TEST_F(CatalogManagerReplSetTest, BasicReadAfterOpTime) { onCommandWithMetadata([this, &newOpTime, &lastOpTime](const RemoteCommandRequest& request) { ASSERT_EQUALS("test", request.dbname); - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS( + BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); ASSERT_EQ(string("dummy"), request.cmdObj.firstElementFieldName()); checkReadConcern(request.cmdObj, lastOpTime.getTimestamp(), lastOpTime.getTerm()); @@ -2212,7 +2242,8 @@ TEST_F(CatalogManagerReplSetTest, ReadAfterOpTimeShouldNotGoBack) { onCommandWithMetadata([this, &newOpTime, &highestOpTime](const RemoteCommandRequest& request) { ASSERT_EQUALS("test", request.dbname); - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); ASSERT_EQ(string("dummy"), request.cmdObj.firstElementFieldName()); checkReadConcern(request.cmdObj, highestOpTime.getTimestamp(), highestOpTime.getTerm()); @@ -2240,7 +2271,8 @@ TEST_F(CatalogManagerReplSetTest, ReadAfterOpTimeShouldNotGoBack) { onCommandWithMetadata([this, &oldOpTime, &highestOpTime](const RemoteCommandRequest& request) { ASSERT_EQUALS("test", request.dbname); - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); ASSERT_EQ(string("dummy"), request.cmdObj.firstElementFieldName()); checkReadConcern(request.cmdObj, highestOpTime.getTimestamp(), highestOpTime.getTerm()); @@ -2264,7 +2296,8 @@ TEST_F(CatalogManagerReplSetTest, ReadAfterOpTimeShouldNotGoBack) { onCommandWithMetadata([this, &oldOpTime, &highestOpTime](const RemoteCommandRequest& request) { ASSERT_EQUALS("test", request.dbname); - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); ASSERT_EQ(string("dummy"), request.cmdObj.firstElementFieldName()); checkReadConcern(request.cmdObj, highestOpTime.getTimestamp(), highestOpTime.getTerm()); @@ -2289,21 +2322,22 @@ TEST_F(CatalogManagerReplSetTest, ReadAfterOpTimeFindThenCmd) { OpTime highestOpTime; const OpTime newOpTime(Timestamp(7, 6), 5); - onFindWithMetadataCommand( - [this, &newOpTime, &highestOpTime](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); - checkReadConcern(request.cmdObj, highestOpTime.getTimestamp(), highestOpTime.getTerm()); + onFindWithMetadataCommand([this, &newOpTime, &highestOpTime]( + const RemoteCommandRequest& request) { + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); + checkReadConcern(request.cmdObj, highestOpTime.getTimestamp(), highestOpTime.getTerm()); - ReplSetMetadata metadata(10, repl::OpTime(), newOpTime, 100, 30); - BSONObjBuilder builder; - metadata.writeToMetadata(&builder); + ReplSetMetadata metadata(10, repl::OpTime(), newOpTime, 100, 30); + BSONObjBuilder builder; + metadata.writeToMetadata(&builder); - SettingsType settings; - settings.setKey("chunksize"); - settings.setChunkSizeMB(2); + SettingsType settings; + settings.setKey("chunksize"); + settings.setChunkSizeMB(2); - return std::make_tuple(vector<BSONObj>{settings.toBSON()}, builder.obj()); - }); + return std::make_tuple(vector<BSONObj>{settings.toBSON()}, builder.obj()); + }); future1.timed_get(kFutureTimeout); @@ -2321,7 +2355,8 @@ TEST_F(CatalogManagerReplSetTest, ReadAfterOpTimeFindThenCmd) { onCommand([this, &oldOpTime, &highestOpTime](const RemoteCommandRequest& request) { ASSERT_EQUALS("test", request.dbname); - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); ASSERT_EQ(string("dummy"), request.cmdObj.firstElementFieldName()); checkReadConcern(request.cmdObj, highestOpTime.getTimestamp(), highestOpTime.getTerm()); @@ -2348,7 +2383,8 @@ TEST_F(CatalogManagerReplSetTest, ReadAfterOpTimeCmdThenFind) { onCommandWithMetadata([this, &newOpTime, &highestOpTime](const RemoteCommandRequest& request) { ASSERT_EQUALS("test", request.dbname); - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); ASSERT_EQ(string("dummy"), request.cmdObj.firstElementFieldName()); checkReadConcern(request.cmdObj, highestOpTime.getTimestamp(), highestOpTime.getTerm()); @@ -2372,7 +2408,8 @@ TEST_F(CatalogManagerReplSetTest, ReadAfterOpTimeCmdThenFind) { const OpTime oldOpTime(Timestamp(3, 10), 5); onFindCommand([this, &oldOpTime, &highestOpTime](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); ASSERT_EQ(string("find"), request.cmdObj.firstElementFieldName()); checkReadConcern(request.cmdObj, highestOpTime.getTimestamp(), highestOpTime.getTerm()); diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set_test_fixture.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set_test_fixture.cpp index 7096b781f8b..6d3231d06b1 100644 --- a/src/mongo/s/catalog/replset/catalog_manager_replica_set_test_fixture.cpp +++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set_test_fixture.cpp @@ -45,6 +45,7 @@ #include "mongo/executor/network_interface_mock.h" #include "mongo/executor/thread_pool_task_executor_test_fixture.h" #include "mongo/rpc/metadata/repl_set_metadata.h" +#include "mongo/rpc/metadata/server_selection_metadata.h" #include "mongo/s/catalog/dist_lock_manager_mock.h" #include "mongo/s/catalog/replset/catalog_manager_replica_set.h" #include "mongo/s/catalog/type_changelog.h" diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set_upgrade_test.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set_upgrade_test.cpp index 1eed5931b1f..7aa61c476c5 100644 --- a/src/mongo/s/catalog/replset/catalog_manager_replica_set_upgrade_test.cpp +++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set_upgrade_test.cpp @@ -34,6 +34,7 @@ #include "mongo/bson/json.h" #include "mongo/client/remote_command_targeter_mock.h" #include "mongo/rpc/metadata/repl_set_metadata.h" +#include "mongo/rpc/metadata/server_selection_metadata.h" #include "mongo/s/catalog/config_server_version.h" #include "mongo/s/catalog/replset/catalog_manager_replica_set.h" #include "mongo/s/catalog/replset/catalog_manager_replica_set_test_fixture.h" @@ -58,7 +59,8 @@ TEST_F(CatalogManagerReplSetTestFixture, UpgradeNotNeeded) { launchAsync([this] { ASSERT_OK(catalogManager()->initConfigVersion(operationContext())); }); onFindCommand([this](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); ASSERT_EQ(HostAndPort("config:123"), request.target); ASSERT_EQ("config", request.dbname); @@ -352,7 +354,8 @@ TEST_F(CatalogManagerReplSetTestFixture, InitVersionDuplicateKeyNoOpAfterRetry) // Retry starts here onFindCommand([this](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); ASSERT_EQ(HostAndPort("config:123"), request.target); ASSERT_EQ("config", request.dbname); @@ -483,7 +486,8 @@ TEST_F(CatalogManagerReplSetTestFixture, InitVersionDuplicateKeyTooNewAfterRetry // Retry starts here onFindCommand([this](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); ASSERT_EQ(HostAndPort("config:123"), request.target); ASSERT_EQ("config", request.dbname); @@ -568,7 +572,8 @@ TEST_F(CatalogManagerReplSetTestFixture, InitVersionUpsertNoMatchNoOpAfterRetry) // Retry starts here onFindCommand([this](const RemoteCommandRequest& request) { - ASSERT_EQUALS(BSON(rpc::kReplSetMetadataFieldName << 1), request.metadata); + ASSERT_EQUALS(BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1), + request.metadata); ASSERT_EQ(HostAndPort("config:123"), request.target); ASSERT_EQ("config", request.dbname); diff --git a/src/mongo/s/chunk.cpp b/src/mongo/s/chunk.cpp index 8102eb1a013..e50ce3ccddd 100644 --- a/src/mongo/s/chunk.cpp +++ b/src/mongo/s/chunk.cpp @@ -309,11 +309,12 @@ void Chunk::pickSplitVector(OperationContext* txn, BSONObj cmdObj = cmd.obj(); const auto primaryShard = grid.shardRegistry()->getShard(txn, getShardId()); - auto targetStatus = - primaryShard->getTargeter()->findHost({ReadPreference::PrimaryPreferred, TagSet{}}); - uassertStatusOK(targetStatus); - - auto result = grid.shardRegistry()->runCommand(txn, targetStatus.getValue(), "admin", cmdObj); + auto result = grid.shardRegistry()->runCommandOnShard( + txn, + primaryShard, + ReadPreferenceSetting{ReadPreference::PrimaryPreferred}, + "admin", + cmdObj); uassertStatusOK(result.getStatus()); uassertStatusOK(Command::getStatusFromCommandResult(result.getValue())); diff --git a/src/mongo/s/chunk_manager.cpp b/src/mongo/s/chunk_manager.cpp index 2531b74ea7e..b6720e81451 100644 --- a/src/mongo/s/chunk_manager.cpp +++ b/src/mongo/s/chunk_manager.cpp @@ -356,13 +356,13 @@ void ChunkManager::calcInitSplitsAndShards(OperationContext* txn, if (!initPoints || !initPoints->size()) { // discover split points const auto primaryShard = grid.shardRegistry()->getShard(txn, primaryShardId); - auto targetStatus = - primaryShard->getTargeter()->findHost({ReadPreference::PrimaryPreferred, TagSet{}}); - uassertStatusOK(targetStatus); - - NamespaceString nss(getns()); - auto result = grid.shardRegistry()->runCommand( - txn, targetStatus.getValue(), nss.db().toString(), BSON("count" << nss.coll())); + const NamespaceString nss{getns()}; + auto result = grid.shardRegistry()->runCommandOnShard( + txn, + primaryShard, + ReadPreferenceSetting{ReadPreference::PrimaryPreferred}, + nss.db().toString(), + BSON("count" << nss.coll())); long long numObjects = 0; uassertStatusOK(result.getStatus()); diff --git a/src/mongo/s/client/shard_registry.cpp b/src/mongo/s/client/shard_registry.cpp index e9ace5db1a4..83bf79d470e 100644 --- a/src/mongo/s/client/shard_registry.cpp +++ b/src/mongo/s/client/shard_registry.cpp @@ -44,6 +44,7 @@ #include "mongo/rpc/get_status_from_command_result.h" #include "mongo/rpc/metadata/config_server_metadata.h" #include "mongo/rpc/metadata/repl_set_metadata.h" +#include "mongo/rpc/metadata/server_selection_metadata.h" #include "mongo/s/catalog/catalog_manager.h" #include "mongo/s/catalog/type_shard.h" #include "mongo/s/client/shard.h" @@ -71,6 +72,20 @@ const Seconds kConfigCommandTimeout{30}; const int kNotMasterNumRetries = 3; const Milliseconds kNotMasterRetryInterval{500}; const BSONObj kReplMetadata(BSON(rpc::kReplSetMetadataFieldName << 1)); +const BSONObj kReplSecondaryOkMetadata{ + BSON(rpc::kSecondaryOkFieldName << 1 << rpc::kReplSetMetadataFieldName << 1)}; +const BSONObj kSecondaryOkMetadata{BSON(rpc::kSecondaryOkFieldName << 1)}; + +void updateReplSetMonitor(const std::shared_ptr<RemoteCommandTargeter>& targeter, + const HostAndPort& remoteHost, + const Status& remoteCommandStatus) { + if (ErrorCodes::NotMaster == remoteCommandStatus) { + targeter->markHostNotMaster(remoteHost); + } else if (ErrorCodes::isNetworkError(remoteCommandStatus.code())) { + targeter->markHostUnreachable(remoteHost); + } +} + } // unnamed namespace ShardRegistry::ShardRegistry(std::unique_ptr<RemoteCommandTargeterFactory> targeterFactory, @@ -329,13 +344,19 @@ OpTime ShardRegistry::getConfigOpTime() { return _configOpTime; } -StatusWith<ShardRegistry::QueryResponse> ShardRegistry::exhaustiveFindOnConfigNode( - const HostAndPort& host, +StatusWith<ShardRegistry::QueryResponse> ShardRegistry::exhaustiveFindOnConfig( + const ReadPreferenceSetting& readPref, const NamespaceString& nss, const BSONObj& query, const BSONObj& sort, boost::optional<long long> limit, boost::optional<repl::ReadConcernArgs> readConcern) { + const auto targeter = getConfigShard()->getTargeter(); + const auto host = targeter->findHost(readPref); + if (!host.isOK()) { + return host.getStatus(); + } + // If for some reason the callback never gets invoked, we will return this status Status status = Status(ErrorCodes::InternalError, "Internal error running find command"); QueryResponse response; @@ -391,8 +412,13 @@ StatusWith<ShardRegistry::QueryResponse> ShardRegistry::exhaustiveFindOnConfigNo BSONObjBuilder findCmdBuilder; lpq->asFindCommand(&findCmdBuilder); - QueryFetcher fetcher( - _executor.get(), host, nss, findCmdBuilder.done(), fetcherCallback, kReplMetadata); + QueryFetcher fetcher(_executor.get(), + host.getValue(), + nss, + findCmdBuilder.done(), + fetcherCallback, + readPref.pref == ReadPreference::PrimaryOnly ? kReplMetadata + : kReplSecondaryOkMetadata); Status scheduleStatus = fetcher.schedule(); if (!scheduleStatus.isOK()) { @@ -401,6 +427,8 @@ StatusWith<ShardRegistry::QueryResponse> ShardRegistry::exhaustiveFindOnConfigNo fetcher.wait(); + updateReplSetMonitor(targeter, host.getValue(), status); + if (!status.isOK()) { return status; } @@ -410,12 +438,19 @@ StatusWith<ShardRegistry::QueryResponse> ShardRegistry::exhaustiveFindOnConfigNo return response; } -StatusWith<BSONObj> ShardRegistry::runCommand(OperationContext* txn, - const HostAndPort& host, - const std::string& dbName, - const BSONObj& cmdObj) { - auto response = - _runCommandWithMetadata(_executor.get(), host, dbName, cmdObj, rpc::makeEmptyMetadata()); +StatusWith<BSONObj> ShardRegistry::runCommandOnShard(OperationContext* txn, + const std::shared_ptr<Shard>& shard, + const ReadPreferenceSetting& readPref, + const std::string& dbName, + const BSONObj& cmdObj) { + auto response = _runCommandWithMetadata(_executor.get(), + shard, + readPref, + dbName, + cmdObj, + readPref.pref == ReadPreference::PrimaryOnly + ? rpc::makeEmptyMetadata() + : kSecondaryOkMetadata); if (!response.isOK()) { return response.getStatus(); } @@ -423,12 +458,32 @@ StatusWith<BSONObj> ShardRegistry::runCommand(OperationContext* txn, return response.getValue().response; } +StatusWith<BSONObj> ShardRegistry::runCommandOnShard(OperationContext* txn, + ShardId shardId, + const ReadPreferenceSetting& readPref, + const std::string& dbName, + const BSONObj& cmdObj) { + auto shard = getShard(txn, shardId); + if (!shard) { + return {ErrorCodes::ShardNotFound, str::stream() << "shard " << shardId << " not found"}; + } + return runCommandOnShard(txn, shard, readPref, dbName, cmdObj); +} + + StatusWith<BSONObj> ShardRegistry::runCommandForAddShard(OperationContext* txn, - const HostAndPort& host, + const std::shared_ptr<Shard>& shard, + const ReadPreferenceSetting& readPref, const std::string& dbName, const BSONObj& cmdObj) { - auto status = _runCommandWithMetadata( - _executorForAddShard.get(), host, dbName, cmdObj, rpc::makeEmptyMetadata()); + auto status = _runCommandWithMetadata(_executorForAddShard.get(), + shard, + readPref, + dbName, + cmdObj, + readPref.pref == ReadPreference::PrimaryOnly + ? rpc::makeEmptyMetadata() + : kSecondaryOkMetadata); if (!status.isOK()) { return status.getStatus(); } @@ -436,10 +491,16 @@ StatusWith<BSONObj> ShardRegistry::runCommandForAddShard(OperationContext* txn, return status.getValue().response; } -StatusWith<BSONObj> ShardRegistry::runCommandOnConfig(const HostAndPort& host, +StatusWith<BSONObj> ShardRegistry::runCommandOnConfig(const ReadPreferenceSetting& readPref, const std::string& dbName, const BSONObj& cmdObj) { - auto response = _runCommandWithMetadata(_executor.get(), host, dbName, cmdObj, kReplMetadata); + auto response = _runCommandWithMetadata( + _executor.get(), + getConfigShard(), + readPref, + dbName, + cmdObj, + readPref.pref == ReadPreference::PrimaryOnly ? kReplMetadata : kReplSecondaryOkMetadata); if (!response.isOK()) { return response.getStatus(); @@ -451,9 +512,8 @@ StatusWith<BSONObj> ShardRegistry::runCommandOnConfig(const HostAndPort& host, StatusWith<BSONObj> ShardRegistry::runCommandOnConfigWithNotMasterRetries(const std::string& dbname, const BSONObj& cmdObj) { - auto configShard = getConfigShard(); auto response = _runCommandWithNotMasterRetries( - _executor.get(), configShard->getTargeter(), dbname, cmdObj, kReplMetadata); + _executor.get(), getConfigShard(), dbname, cmdObj, kReplMetadata); if (!response.isOK()) { return response.getStatus(); @@ -471,7 +531,7 @@ StatusWith<BSONObj> ShardRegistry::runCommandWithNotMasterRetries(OperationConte invariant(!shard->isConfig()); auto response = _runCommandWithNotMasterRetries( - _executor.get(), shard->getTargeter(), dbname, cmdObj, rpc::makeEmptyMetadata()); + _executor.get(), shard, dbname, cmdObj, rpc::makeEmptyMetadata()); if (!response.isOK()) { return response.getStatus(); } @@ -481,28 +541,15 @@ StatusWith<BSONObj> ShardRegistry::runCommandWithNotMasterRetries(OperationConte StatusWith<ShardRegistry::CommandResponse> ShardRegistry::_runCommandWithNotMasterRetries( TaskExecutor* executor, - const std::shared_ptr<RemoteCommandTargeter>& targeter, + const std::shared_ptr<Shard>& shard, const std::string& dbname, const BSONObj& cmdObj, const BSONObj& metadata) { - const ReadPreferenceSetting readPref(ReadPreference::PrimaryOnly, TagSet{}); + const ReadPreferenceSetting readPref{ReadPreference::PrimaryOnly}; for (int i = 0; i < kNotMasterNumRetries; ++i) { - auto target = targeter->findHost(readPref); - if (!target.isOK()) { - if (ErrorCodes::NotMaster == target.getStatus()) { - if (i == kNotMasterNumRetries - 1) { - // If we're out of retries don't bother sleeping, just return. - return target.getStatus(); - } - sleepmillis(durationCount<Milliseconds>(kNotMasterRetryInterval)); - continue; - } - return target.getStatus(); - } - auto response = - _runCommandWithMetadata(executor, target.getValue(), dbname, cmdObj, metadata); + _runCommandWithMetadata(executor, shard, readPref, dbname, cmdObj, metadata); if (!response.isOK()) { return response.getStatus(); } @@ -510,7 +557,6 @@ StatusWith<ShardRegistry::CommandResponse> ShardRegistry::_runCommandWithNotMast Status commandStatus = getStatusFromCommandResult(response.getValue().response); if (ErrorCodes::NotMaster == commandStatus || ErrorCodes::NotMasterNoSlaveOkCode == commandStatus) { - targeter->markHostNotMaster(target.getValue()); if (i == kNotMasterNumRetries - 1) { // If we're out of retries don't bother sleeping, just return. return commandStatus; @@ -527,14 +573,22 @@ StatusWith<ShardRegistry::CommandResponse> ShardRegistry::_runCommandWithNotMast StatusWith<ShardRegistry::CommandResponse> ShardRegistry::_runCommandWithMetadata( TaskExecutor* executor, - const HostAndPort& host, + const std::shared_ptr<Shard>& shard, + const ReadPreferenceSetting& readPref, const std::string& dbName, const BSONObj& cmdObj, const BSONObj& metadata) { + auto targeter = shard->getTargeter(); + auto host = targeter->findHost(readPref); + if (!host.isOK()) { + return host.getStatus(); + } + + executor::RemoteCommandRequest request( + host.getValue(), dbName, cmdObj, metadata, kConfigCommandTimeout); StatusWith<executor::RemoteCommandResponse> responseStatus = Status(ErrorCodes::InternalError, "Internal error running command"); - executor::RemoteCommandRequest request(host, dbName, cmdObj, metadata, kConfigCommandTimeout); auto callStatus = executor->scheduleRemoteCommand(request, [&responseStatus](const RemoteCommandCallbackArgs& args) { @@ -547,11 +601,13 @@ StatusWith<ShardRegistry::CommandResponse> ShardRegistry::_runCommandWithMetadat // Block until the command is carried out executor->wait(callStatus.getValue()); + updateReplSetMonitor(targeter, host.getValue(), responseStatus.getStatus()); if (!responseStatus.isOK()) { return responseStatus.getStatus(); } auto response = responseStatus.getValue(); + updateReplSetMonitor(targeter, host.getValue(), getStatusFromCommandResult(response.data)); CommandResponse cmdResponse; cmdResponse.response = response.data; diff --git a/src/mongo/s/client/shard_registry.h b/src/mongo/s/client/shard_registry.h index 611c78aae56..2780d9fe8c3 100644 --- a/src/mongo/s/client/shard_registry.h +++ b/src/mongo/s/client/shard_registry.h @@ -50,6 +50,7 @@ class OperationContext; class RemoteCommandTargeterFactory; class Shard; class ShardType; +struct ReadPreferenceSetting; template <typename T> class StatusWith; @@ -191,16 +192,16 @@ public: repl::OpTime getConfigOpTime(); /** - * Executes 'find' command against the specified host and fetches *all* the results that - * the host will return until there are no more or until an error is returned. - * "host" must refer to a config server. + * Executes 'find' command against a config server matching the given read preference, and + * fetches *all* the results that the host will return until there are no more or until an error + * is returned. * * Returns either the complete set of results or an error, never partial results. * * Note: should never be used outside of CatalogManagerReplicaSet or DistLockCatalogImpl. */ - StatusWith<QueryResponse> exhaustiveFindOnConfigNode( - const HostAndPort& host, + StatusWith<QueryResponse> exhaustiveFindOnConfig( + const ReadPreferenceSetting& readPref, const NamespaceString& nss, const BSONObj& query, const BSONObj& sort, @@ -208,29 +209,38 @@ public: boost::optional<repl::ReadConcernArgs> readConcern); /** - * Runs a command against the specified host and returns the result. It is the responsibility - * of the caller to check the returned BSON for command-specific failures. + * Runs a command against a host belonging to the specified shard and matching the given + * readPref, and returns the result. It is the responsibility of the caller to check the + * returned BSON for command-specific failures. */ - StatusWith<BSONObj> runCommand(OperationContext* txn, - const HostAndPort& host, - const std::string& dbName, - const BSONObj& cmdObj); + StatusWith<BSONObj> runCommandOnShard(OperationContext* txn, + const std::shared_ptr<Shard>& shard, + const ReadPreferenceSetting& readPref, + const std::string& dbName, + const BSONObj& cmdObj); + StatusWith<BSONObj> runCommandOnShard(OperationContext* txn, + ShardId shardId, + const ReadPreferenceSetting& readPref, + const std::string& dbName, + const BSONObj& cmdObj); + /** - * Same as runCommand above but used for talking to nodes that are not yet in the ShardRegistry. + * Same as runCommandOnShard above but used for talking to nodes that are not yet in the + * ShardRegistry. */ StatusWith<BSONObj> runCommandForAddShard(OperationContext* txn, - const HostAndPort& host, + const std::shared_ptr<Shard>& shard, + const ReadPreferenceSetting& readPref, const std::string& dbName, const BSONObj& cmdObj); /** - * Runs a command against the specified host and returns the result. It is the responsibility - * of the caller to check the returned BSON for command-specific failures. - * - * "host" must refer to a config server node. + * Runs a command against a config server that matches the given read preference, and returns + * the result. It is the responsibility of the caller to check the returned BSON for + * command-specific failures. */ - StatusWith<BSONObj> runCommandOnConfig(const HostAndPort& host, + StatusWith<BSONObj> runCommandOnConfig(const ReadPreferenceSetting& readPref, const std::string& dbname, const BSONObj& cmdObj); @@ -282,17 +292,17 @@ private: * of the caller to check the returned BSON for command-specific failures. */ StatusWith<CommandResponse> _runCommandWithMetadata(executor::TaskExecutor* executor, - const HostAndPort& host, + const std::shared_ptr<Shard>& shard, + const ReadPreferenceSetting& readPref, const std::string& dbName, const BSONObj& cmdObj, const BSONObj& metadata); - StatusWith<CommandResponse> _runCommandWithNotMasterRetries( - executor::TaskExecutor* executor, - const std::shared_ptr<RemoteCommandTargeter>& targeter, - const std::string& dbname, - const BSONObj& cmdObj, - const BSONObj& metadata); + StatusWith<CommandResponse> _runCommandWithNotMasterRetries(executor::TaskExecutor* executor, + const std::shared_ptr<Shard>& shard, + const std::string& dbname, + const BSONObj& cmdObj, + const BSONObj& metadata); // Factory to obtain remote command targeters for shards const std::unique_ptr<RemoteCommandTargeterFactory> _targeterFactory; diff --git a/src/mongo/s/commands/cluster_fsync_cmd.cpp b/src/mongo/s/commands/cluster_fsync_cmd.cpp index cd4d182a2f3..0f4cea8c754 100644 --- a/src/mongo/s/commands/cluster_fsync_cmd.cpp +++ b/src/mongo/s/commands/cluster_fsync_cmd.cpp @@ -91,11 +91,12 @@ public: continue; } - const auto shardHost = uassertStatusOK( - s->getTargeter()->findHost({ReadPreference::PrimaryOnly, TagSet::primaryOnly()})); - - BSONObj x = uassertStatusOK( - grid.shardRegistry()->runCommand(txn, shardHost, "admin", BSON("fsync" << 1))); + BSONObj x = uassertStatusOK(grid.shardRegistry()->runCommandOnShard( + txn, + s, + ReadPreferenceSetting{ReadPreference::PrimaryOnly}, + "admin", + BSON("fsync" << 1))); sub.append(s->getId(), x); diff --git a/src/mongo/s/commands/cluster_list_databases_cmd.cpp b/src/mongo/s/commands/cluster_list_databases_cmd.cpp index 0ef56e359f9..891ccb8fd4a 100644 --- a/src/mongo/s/commands/cluster_list_databases_cmd.cpp +++ b/src/mongo/s/commands/cluster_list_databases_cmd.cpp @@ -99,11 +99,12 @@ public: continue; } - const auto shardHost = uassertStatusOK(s->getTargeter()->findHost( - {ReadPreference::PrimaryPreferred, TagSet::primaryOnly()})); - - BSONObj x = uassertStatusOK(grid.shardRegistry()->runCommand( - txn, shardHost, "admin", BSON("listDatabases" << 1))); + BSONObj x = uassertStatusOK(grid.shardRegistry()->runCommandOnShard( + txn, + s, + ReadPreferenceSetting{ReadPreference::PrimaryPreferred}, + "admin", + BSON("listDatabases" << 1))); BSONObjIterator j(x["databases"].Obj()); while (j.more()) { diff --git a/src/mongo/s/query/async_results_merger_test.cpp b/src/mongo/s/query/async_results_merger_test.cpp index 75dfe2a2876..70e5d0e69a3 100644 --- a/src/mongo/s/query/async_results_merger_test.cpp +++ b/src/mongo/s/query/async_results_merger_test.cpp @@ -37,6 +37,7 @@ #include "mongo/executor/network_interface_mock.h" #include "mongo/executor/task_executor.h" #include "mongo/executor/thread_pool_task_executor_test_fixture.h" +#include "mongo/rpc/metadata/server_selection_metadata.h" #include "mongo/stdx/memory.h" #include "mongo/unittest/unittest.h" @@ -1037,7 +1038,7 @@ TEST_F(AsyncResultsMergerTest, SendsSecondaryOkAsMetadata) { ASSERT_FALSE(arm->ready()); BSONObj cmdRequestMetadata = getFirstPendingRequest().metadata; - ASSERT_EQ(cmdRequestMetadata, BSON("$secondaryOk" << 1)); + ASSERT_EQ(cmdRequestMetadata, BSON(rpc::kSecondaryOkFieldName << 1)); std::vector<CursorResponse> responses; std::vector<BSONObj> batch1 = {fromjson("{_id: 1}")}; diff --git a/src/mongo/s/shard_util.cpp b/src/mongo/s/shard_util.cpp index 46afc889bc5..8b7ced7748e 100644 --- a/src/mongo/s/shard_util.cpp +++ b/src/mongo/s/shard_util.cpp @@ -42,19 +42,12 @@ namespace shardutil { StatusWith<long long> retrieveTotalShardSize(OperationContext* txn, ShardId shardId, ShardRegistry* shardRegistry) { - auto shard = shardRegistry->getShard(txn, shardId); - if (!shard) { - return {ErrorCodes::ShardNotFound, str::stream() << "shard " << shardId << " not found"}; - } - - auto shardHostStatus = - shard->getTargeter()->findHost({ReadPreference::PrimaryPreferred, TagSet::primaryOnly()}); - if (!shardHostStatus.isOK()) { - return shardHostStatus.getStatus(); - } - - auto listDatabasesStatus = shardRegistry->runCommand( - txn, shardHostStatus.getValue(), "admin", BSON("listDatabases" << 1)); + auto listDatabasesStatus = + shardRegistry->runCommandOnShard(txn, + shardId, + ReadPreferenceSetting{ReadPreference::PrimaryPreferred}, + "admin", + BSON("listDatabases" << 1)); if (!listDatabasesStatus.isOK()) { return listDatabasesStatus.getStatus(); } |