diff options
author | Spencer T Brody <spencer@mongodb.com> | 2014-12-19 15:16:02 -0500 |
---|---|---|
committer | Spencer T Brody <spencer@mongodb.com> | 2015-01-06 18:02:00 -0500 |
commit | 357cf5e9029db85ce36cd6c7ef181edcc142f493 (patch) | |
tree | 00a38ad73890c719861e880455f92d58cefdc25e | |
parent | 293bf1caf51df5b9cf7c882f2e6312769e1716a2 (diff) | |
download | mongo-357cf5e9029db85ce36cd6c7ef181edcc142f493.tar.gz |
SERVER-16237 Don't check shard version if the replica set monitor knows the primary is down
-rw-r--r-- | src/mongo/client/dbclient_rs.cpp | 7 | ||||
-rw-r--r-- | src/mongo/client/dbclient_rs.h | 11 | ||||
-rw-r--r-- | src/mongo/client/dbclientinterface.h | 1 | ||||
-rw-r--r-- | src/mongo/client/parallel.cpp | 16 |
4 files changed, 34 insertions, 1 deletions
diff --git a/src/mongo/client/dbclient_rs.cpp b/src/mongo/client/dbclient_rs.cpp index 29942ea4bf0..9311bf3d76b 100644 --- a/src/mongo/client/dbclient_rs.cpp +++ b/src/mongo/client/dbclient_rs.cpp @@ -178,6 +178,13 @@ namespace { return rsm->getServerAddress(); } + HostAndPort DBClientReplicaSet::getSuspectedPrimaryHostAndPort() const { + if (!_master) { + return HostAndPort(); + } + return _master->getServerHostAndPort(); + } + void DBClientReplicaSet::setRunCommandHook(DBClientWithCommands::RunCommandHookFunc func) { // Set the hooks in both our sub-connections and in ourselves. if (_master) { diff --git a/src/mongo/client/dbclient_rs.h b/src/mongo/client/dbclient_rs.h index cbd1ff01438..f77dcd8fc28 100644 --- a/src/mongo/client/dbclient_rs.h +++ b/src/mongo/client/dbclient_rs.h @@ -133,6 +133,17 @@ namespace mongo { // ----- informational ---- + /** + * Gets the replica set name of the set we are connected to. + */ + const std::string& getSetName() const { return _setName; } + + /** + * Returns the HostAndPort of the server this connection believes belongs to the primary, + * or returns an empty HostAndPort if it doesn't know about a current primary. + */ + HostAndPort getSuspectedPrimaryHostAndPort() const; + double getSoTimeout() const { return _so_timeout; } string toString() const { return getServerAddress(); } diff --git a/src/mongo/client/dbclientinterface.h b/src/mongo/client/dbclientinterface.h index 8ac36ea15b4..6f05fce5637 100644 --- a/src/mongo/client/dbclientinterface.h +++ b/src/mongo/client/dbclientinterface.h @@ -1309,6 +1309,7 @@ namespace mongo { } string getServerAddress() const { return _serverString; } + const HostAndPort& getServerHostAndPort() const { return _server; } virtual void killCursor( long long cursorID ); virtual bool callRead( Message& toSend , Message& response ) { return call( toSend , response ); } diff --git a/src/mongo/client/parallel.cpp b/src/mongo/client/parallel.cpp index 4316c0ef29a..8ef983abc53 100644 --- a/src/mongo/client/parallel.cpp +++ b/src/mongo/client/parallel.cpp @@ -22,6 +22,8 @@ #include "mongo/client/connpool.h" #include "mongo/client/dbclientcursor.h" +#include "mongo/client/dbclient_rs.h" +#include "mongo/client/replica_set_monitor.h" #include "mongo/db/dbmessage.h" #include "mongo/db/query/lite_parsed_query.h" #include "mongo/s/chunk.h" @@ -571,8 +573,20 @@ namespace mongo { bool allowShardVersionFailure = rawConn->type() == ConnectionString::SET && DBClientReplicaSet::isSecondaryQuery( _qSpec.ns(), _qSpec.query(), _qSpec.options() ); + bool connIsDown = rawConn->isFailed(); + if (allowShardVersionFailure && !connIsDown) { + // If the replica set connection believes that it has a valid primary that is up, + // confirm that the replica set monitor agrees that the suspected primary is indeed up. + const DBClientReplicaSet* replConn = dynamic_cast<const DBClientReplicaSet*>(rawConn); + ReplicaSetMonitorPtr rsMonitor = ReplicaSetMonitor::get(replConn->getSetName()); + if (!rsMonitor->isHostUp(replConn->getSuspectedPrimaryHostAndPort())) { + connIsDown = true; + } + } - if ( allowShardVersionFailure && rawConn->isFailed() ) { + if (allowShardVersionFailure && connIsDown) { + // If we're doing a secondary-allowed query and the primary is down, don't attempt to + // set the shard version. state->conn->donotCheckVersion(); |