diff options
author | Ben Caimano <ben.caimano@10gen.com> | 2019-07-22 14:35:57 -0400 |
---|---|---|
committer | Ben Caimano <ben.caimano@10gen.com> | 2019-07-26 11:30:20 -0400 |
commit | edcd0b9a2254cbac3d843be28f373a4f0f3024b4 (patch) | |
tree | d218eeab9e08e2a058e3513de85e85a3cc6711e9 | |
parent | 18f395d8ccdbe1c07edd528fab2b174a8858a139 (diff) | |
download | mongo-edcd0b9a2254cbac3d843be28f373a4f0f3024b4.tar.gz |
SERVER-42125 Omit passive members from RSM connection strings
(cherry picked from commit e68d63e7b048ac8b5accdd7c99dba66089859753)
-rw-r--r-- | src/mongo/client/replica_set_change_notifier.cpp | 10 | ||||
-rw-r--r-- | src/mongo/client/replica_set_change_notifier.h | 5 | ||||
-rw-r--r-- | src/mongo/client/replica_set_monitor.cpp | 38 | ||||
-rw-r--r-- | src/mongo/client/replica_set_monitor_internal.h | 7 | ||||
-rw-r--r-- | src/mongo/client/replica_set_monitor_internal_test.cpp | 15 | ||||
-rw-r--r-- | src/mongo/s/sharding_task_executor_pool_controller.cpp | 2 |
6 files changed, 41 insertions, 36 deletions
diff --git a/src/mongo/client/replica_set_change_notifier.cpp b/src/mongo/client/replica_set_change_notifier.cpp index 9e8526979a9..cf6c5b2d90b 100644 --- a/src/mongo/client/replica_set_change_notifier.cpp +++ b/src/mongo/client/replica_set_change_notifier.cpp @@ -79,7 +79,7 @@ void ReplicaSetChangeNotifier::onPossibleSet(ConnectionString connectionString) auto& state = _replicaSetStates[name]; ++state.generation; - state.connStr = connectionString; + state.connStr = std::move(connectionString); state.primary = {}; return state; @@ -94,7 +94,8 @@ void ReplicaSetChangeNotifier::onPossibleSet(ConnectionString connectionString) } void ReplicaSetChangeNotifier::onConfirmedSet(ConnectionString connectionString, - HostAndPort primary) { + HostAndPort primary, + std::set<HostAndPort> passives) { LOG(2) << "Signaling confirmed set " << connectionString << " with primary " << primary; const auto& name = connectionString.getSetName(); @@ -104,8 +105,9 @@ void ReplicaSetChangeNotifier::onConfirmedSet(ConnectionString connectionString, auto& state = _replicaSetStates[name]; ++state.generation; - state.connStr = connectionString; - state.primary = primary; + state.connStr = std::move(connectionString); + state.primary = std::move(primary); + state.passives = std::move(passives); return state; }(); diff --git a/src/mongo/client/replica_set_change_notifier.h b/src/mongo/client/replica_set_change_notifier.h index fdfd0a50c8b..de61d5dc504 100644 --- a/src/mongo/client/replica_set_change_notifier.h +++ b/src/mongo/client/replica_set_change_notifier.h @@ -71,7 +71,9 @@ public: /** * Notify every listener that a scan completed and found a new primary or config */ - void onConfirmedSet(ConnectionString connectionString, HostAndPort primary); + void onConfirmedSet(ConnectionString connectionString, + HostAndPort primary, + std::set<HostAndPort> passives); /** * Notify every listener that a ReplicaSet is no longer in use and drop the State @@ -169,6 +171,7 @@ using ReplicaSetChangeListenerHandle = ReplicaSetChangeNotifier::ListenerHandle; struct ReplicaSetChangeNotifier::State { ConnectionString connStr; HostAndPort primary; + std::set<HostAndPort> passives; int64_t generation = 0; }; diff --git a/src/mongo/client/replica_set_monitor.cpp b/src/mongo/client/replica_set_monitor.cpp index 033d2608210..753b358badf 100644 --- a/src/mongo/client/replica_set_monitor.cpp +++ b/src/mongo/client/replica_set_monitor.cpp @@ -679,7 +679,7 @@ void Refresher::receivedIsMaster(const HostAndPort& from, // and if this refresher has yet to find the replica set master, we add hosts listed in // the reply to the list of possible replica set members. if (!_scan->foundUpMaster) { - _scan->possibleNodes.insert(reply.normalHosts.begin(), reply.normalHosts.end()); + _scan->possibleNodes.insert(reply.members.begin(), reply.members.end()); } } else { error() << "replset name mismatch: expected \"" << _set->name << "\", " @@ -803,35 +803,32 @@ Status Refresher::receivedIsMasterFromMaster(const HostAndPort& from, const IsMa } // Check if the master agrees with our current list of nodes. - // REMINDER: both _set->nodes and reply.normalHosts are sorted. - if (_set->nodes.size() != reply.normalHosts.size() || - !std::equal( - _set->nodes.begin(), _set->nodes.end(), reply.normalHosts.begin(), hostsEqual)) { + // REMINDER: both _set->nodes and reply.members are sorted. + if (_set->nodes.size() != reply.members.size() || + !std::equal(_set->nodes.begin(), _set->nodes.end(), reply.members.begin(), hostsEqual)) { LOG(2) << "Adjusting nodes in our view of replica set " << _set->name << " based on master reply: " << redact(reply.raw); // remove non-members from _set->nodes _set->nodes.erase( - std::remove_if(_set->nodes.begin(), _set->nodes.end(), HostNotIn(reply.normalHosts)), + std::remove_if(_set->nodes.begin(), _set->nodes.end(), HostNotIn(reply.members)), _set->nodes.end()); // add new members to _set->nodes - for (std::set<HostAndPort>::const_iterator it = reply.normalHosts.begin(); - it != reply.normalHosts.end(); - ++it) { - _set->findOrCreateNode(*it); + for (auto& host : reply.members) { + _set->findOrCreateNode(host); } // replace hostToScan queue with untried normal hosts. can both add and remove // hosts from the queue. _scan->hostsToScan.clear(); - _scan->enqueAllUntriedHosts(reply.normalHosts, _set->rand); + _scan->enqueAllUntriedHosts(reply.members, _set->rand); if (!_scan->waitingFor.empty()) { // make sure we don't wait for any hosts that aren't considered members std::set<HostAndPort> newWaitingFor; - std::set_intersection(reply.normalHosts.begin(), - reply.normalHosts.end(), + std::set_intersection(reply.members.begin(), + reply.members.end(), _scan->waitingFor.begin(), _scan->waitingFor.end(), std::inserter(newWaitingFor, newWaitingFor.end())); @@ -839,18 +836,18 @@ Status Refresher::receivedIsMasterFromMaster(const HostAndPort& from, const IsMa } } - bool changedHosts = reply.normalHosts != _set->seedNodes; + bool changedHosts = reply.members != _set->seedNodes; bool changedPrimary = reply.host != _set->lastSeenMaster; if (changedHosts || changedPrimary) { ++_set->seedGen; - _set->seedNodes = reply.normalHosts; + _set->seedNodes = reply.members; _set->seedConnStr = _set->confirmedConnectionString(); // LogLevel can be pretty low, since replica set reconfiguration should be pretty rare // and we want to record our changes log() << "Confirmed replica set for " << _set->name << " is " << _set->seedConnStr; - _set->notifier->onConfirmedSet(_set->seedConnStr, reply.host); + _set->notifier->onConfirmedSet(_set->seedConnStr, reply.host, reply.passives); } // Update our working string @@ -875,7 +872,7 @@ void Refresher::receivedIsMasterBeforeFoundMaster(const IsMasterReply& reply) { invariant(!reply.isMaster); // Add everyone this host claims is in the set to possibleNodes. - _scan->possibleNodes.insert(reply.normalHosts.begin(), reply.normalHosts.end()); + _scan->possibleNodes.insert(reply.members.begin(), reply.members.end()); // If this node thinks the primary is someone we haven't tried, make that the next // hostToScan. @@ -918,12 +915,13 @@ void IsMasterReply::parse(const BSONObj& obj) { primary = primaryString.empty() ? HostAndPort() : HostAndPort(primaryString); // both hosts and passives, but not arbiters, are considered "normal hosts" - normalHosts.clear(); + members.clear(); BSONForEach(host, raw.getObjectField("hosts")) { - normalHosts.insert(HostAndPort(host.String())); + members.insert(HostAndPort(host.String())); } BSONForEach(host, raw.getObjectField("passives")) { - normalHosts.insert(HostAndPort(host.String())); + members.insert(HostAndPort(host.String())); + passives.insert(HostAndPort(host.String())); } tags = raw.getObjectField("tags"); diff --git a/src/mongo/client/replica_set_monitor_internal.h b/src/mongo/client/replica_set_monitor_internal.h index c4a90b47d79..67cc9ac73ab 100644 --- a/src/mongo/client/replica_set_monitor_internal.h +++ b/src/mongo/client/replica_set_monitor_internal.h @@ -70,9 +70,10 @@ struct ReplicaSetMonitor::IsMasterReply { bool secondary; bool hidden; int configVersion{}; - OID electionId; // Set if this isMaster reply is from the primary - HostAndPort primary; // empty if not present - std::set<HostAndPort> normalHosts; // both "hosts" and "passives" + OID electionId; // Set if this isMaster reply is from the primary + HostAndPort primary; // empty if not present + std::set<HostAndPort> members; // both "hosts" and "passives" + std::set<HostAndPort> passives; BSONObj tags; int minWireVersion{}; int maxWireVersion{}; diff --git a/src/mongo/client/replica_set_monitor_internal_test.cpp b/src/mongo/client/replica_set_monitor_internal_test.cpp index 6017dd9eee4..b796dff516c 100644 --- a/src/mongo/client/replica_set_monitor_internal_test.cpp +++ b/src/mongo/client/replica_set_monitor_internal_test.cpp @@ -394,7 +394,7 @@ TEST_F(IsMasterReplyTest, IsMasterReplyRSNotInitiated) { ASSERT_EQUALS(imr.configVersion, 0); ASSERT(!imr.electionId.isSet()); ASSERT(imr.primary.empty()); - ASSERT(imr.normalHosts.empty()); + ASSERT(imr.members.empty()); ASSERT(imr.tags.isEmpty()); } @@ -441,7 +441,7 @@ TEST_F(IsMasterReplyTest, IsMasterReplyRSPrimary) { ASSERT_EQUALS(imr.secondary, false); ASSERT_EQUALS(imr.isMaster, true); ASSERT_EQUALS(imr.primary.toString(), HostAndPort("mongo.example:3000").toString()); - ASSERT(imr.normalHosts.count(HostAndPort("mongo.example:3000"))); + ASSERT(imr.members.count(HostAndPort("mongo.example:3000"))); ASSERT(imr.tags.isEmpty()); } @@ -491,8 +491,9 @@ TEST_F(IsMasterReplyTest, IsMasterReplyPassiveSecondary) { ASSERT_EQUALS(imr.secondary, true); ASSERT_EQUALS(imr.isMaster, false); ASSERT_EQUALS(imr.primary.toString(), HostAndPort("mongo.example:3000").toString()); - ASSERT(imr.normalHosts.count(HostAndPort("mongo.example:3000"))); - ASSERT(imr.normalHosts.count(HostAndPort("mongo.example:3001"))); + ASSERT(imr.members.count(HostAndPort("mongo.example:3000"))); + ASSERT(imr.members.count(HostAndPort("mongo.example:3001"))); + ASSERT(imr.passives.count(HostAndPort("mongo.example:3001"))); ASSERT(imr.tags.isEmpty()); ASSERT(!imr.electionId.isSet()); } @@ -543,7 +544,7 @@ TEST_F(IsMasterReplyTest, IsMasterReplyHiddenSecondary) { ASSERT_EQUALS(imr.secondary, true); ASSERT_EQUALS(imr.isMaster, false); ASSERT_EQUALS(imr.primary.toString(), HostAndPort("mongo.example:3000").toString()); - ASSERT(imr.normalHosts.count(HostAndPort("mongo.example:3000"))); + ASSERT(imr.members.count(HostAndPort("mongo.example:3000"))); ASSERT(imr.tags.isEmpty()); ASSERT(!imr.electionId.isSet()); } @@ -596,8 +597,8 @@ TEST_F(IsMasterReplyTest, IsMasterSecondaryWithTags) { ASSERT_EQUALS(imr.secondary, true); ASSERT_EQUALS(imr.isMaster, false); ASSERT_EQUALS(imr.primary.toString(), HostAndPort("mongo.example:3000").toString()); - ASSERT(imr.normalHosts.count(HostAndPort("mongo.example:3000"))); - ASSERT(imr.normalHosts.count(HostAndPort("mongo.example:3001"))); + ASSERT(imr.members.count(HostAndPort("mongo.example:3000"))); + ASSERT(imr.members.count(HostAndPort("mongo.example:3001"))); ASSERT(imr.tags.hasElement("dc")); ASSERT(imr.tags.hasElement("use")); ASSERT(!imr.electionId.isSet()); diff --git a/src/mongo/s/sharding_task_executor_pool_controller.cpp b/src/mongo/s/sharding_task_executor_pool_controller.cpp index a077700b6cd..ffcdd6cd82b 100644 --- a/src/mongo/s/sharding_task_executor_pool_controller.cpp +++ b/src/mongo/s/sharding_task_executor_pool_controller.cpp @@ -221,7 +221,7 @@ auto ShardingTaskExecutorPoolController::updateHost(PoolId id, const HostState& // If the pool isn't in a groupData, we can return now auto groupData = poolData.groupData.lock(); - if (!groupData) { + if (!groupData || groupData->state.passives.count(poolData.host)) { return {{poolData.host}, poolData.isAbleToShutdown}; } |