Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

backport of fix for SERVER-2481

  • Loading branch information...
commit 3337ab497cd55e25fbdbe732e6c40c724add857d 1 parent b3224f5
gregs authored
34 client/dbclient_rs.cpp
View
@@ -544,7 +544,7 @@ namespace mongo {
// checkSlave will try a different slave automatically after a failure
for ( int i=0; i<2; i++ ) {
try {
- return checkSlave()->query(ns,query,nToReturn,nToSkip,fieldsToReturn,queryOptions,batchSize);
+ return checkSlaveQueryResult( checkSlave()->query(ns,query,nToReturn,nToSkip,fieldsToReturn,queryOptions,batchSize) );
}
catch ( DBException &e ) {
log() << "can't query replica set slave " << i << " : " << _slaveHost << e.what() << endl;
@@ -581,6 +581,38 @@ namespace mongo {
assert(0);
}
+ auto_ptr<DBClientCursor> DBClientReplicaSet::checkSlaveQueryResult( auto_ptr<DBClientCursor> result ){
+
+ bool isError = result->hasResultFlag( ResultFlag_ErrSet );
+ if( ! isError ) return result;
+
+ BSONObj error = result->peekOne();
+
+ BSONElement code = error["code"];
+ if( code.eoo() || ! code.isNumber() ){
+ warning() << "no code for error from secondary host " << _slaveHost << ", error was " << error << endl;
+ return result;
+ }
+
+ // We only check for "not master or secondary" errors here
+
+ // If the error code here ever changes, we need to change this code also
+ if( code.Int() == 13436 /* not master or secondary */ ){
+ isntSecondary();
+ throw DBException( str::stream() << "slave " << _slaveHost.toString() << " is no longer secondary", 14812 );
+ }
+
+ return result;
+ }
+
+ void DBClientReplicaSet::isntSecondary() {
+ log() << "slave no longer has secondary status: " << _slaveHost << endl;
+ // Failover to next slave
+ _monitor->notifySlaveFailure( _slaveHost );
+ _slave.reset();
+ }
+
+
void DBClientReplicaSet::isntMaster() {
log() << "got not master for: " << _masterHost << endl;
_monitor->notifyFailure( _masterHost );
6 client/dbclient_rs.h
View
@@ -215,6 +215,9 @@ namespace mongo {
/* this is the callback from our underlying connections to notify us that we got a "not master" error.
*/
void isntMaster();
+ /* this is used to indicate we got a "not master or secondary" error from a secondary.
+ */
+ void isntSecondary();
// ----- status ------
@@ -240,6 +243,9 @@ namespace mongo {
private:
+ // Used to simplify slave-handling logic on errors
+ auto_ptr<DBClientCursor> checkSlaveQueryResult( auto_ptr<DBClientCursor> result );
+
DBClientConnection * checkMaster();
DBClientConnection * checkSlave();
5 client/dbclientcursor.h
View
@@ -86,6 +86,11 @@ namespace mongo {
WARNING: no support for _putBack yet!
*/
void peek(vector<BSONObj>&, int atMost);
+ BSONObj peekOne(){
+ vector<BSONObj> v;
+ peek( v, 1 );
+ return v.size() > 0 ? v[0] : BSONObj();
+ }
/**
iterate the rest of the cursor and return the number if items
Please sign in to comment.
Something went wrong with that request. Please try again.