summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Caimano <ben.caimano@10gen.com>2019-07-22 14:35:57 -0400
committerBen Caimano <ben.caimano@10gen.com>2019-07-26 11:30:20 -0400
commitedcd0b9a2254cbac3d843be28f373a4f0f3024b4 (patch)
treed218eeab9e08e2a058e3513de85e85a3cc6711e9
parent18f395d8ccdbe1c07edd528fab2b174a8858a139 (diff)
downloadmongo-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.cpp10
-rw-r--r--src/mongo/client/replica_set_change_notifier.h5
-rw-r--r--src/mongo/client/replica_set_monitor.cpp38
-rw-r--r--src/mongo/client/replica_set_monitor_internal.h7
-rw-r--r--src/mongo/client/replica_set_monitor_internal_test.cpp15
-rw-r--r--src/mongo/s/sharding_task_executor_pool_controller.cpp2
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};
}