summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSpencer T Brody <spencer@mongodb.com>2014-12-19 15:16:02 -0500
committerSpencer T Brody <spencer@mongodb.com>2015-01-06 18:02:00 -0500
commit357cf5e9029db85ce36cd6c7ef181edcc142f493 (patch)
tree00a38ad73890c719861e880455f92d58cefdc25e
parent293bf1caf51df5b9cf7c882f2e6312769e1716a2 (diff)
downloadmongo-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.cpp7
-rw-r--r--src/mongo/client/dbclient_rs.h11
-rw-r--r--src/mongo/client/dbclientinterface.h1
-rw-r--r--src/mongo/client/parallel.cpp16
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();