diff options
author | Eliot Horowitz <eliot@10gen.com> | 2011-11-21 00:27:20 -0500 |
---|---|---|
committer | Eliot Horowitz <eliot@10gen.com> | 2011-11-21 01:02:06 -0500 |
commit | c0588190d401824422ca6c9a0c9744cfcb62e9a1 (patch) | |
tree | f69dff298546368debd944598a1ffc2cfca98cd3 | |
parent | 415486ce5cdc82ab1f8b2f8db92a197535e31d61 (diff) | |
download | mongo-c0588190d401824422ca6c9a0c9744cfcb62e9a1.tar.gz |
handle non-sharded query not master errors SERVER-4324
-rw-r--r-- | client/dbclient_rs.cpp | 25 | ||||
-rw-r--r-- | jstests/slowNightly/replica_set_shard_version.js | 14 | ||||
-rw-r--r-- | s/d_state.cpp | 10 |
3 files changed, 46 insertions, 3 deletions
diff --git a/client/dbclient_rs.cpp b/client/dbclient_rs.cpp index a0bd349818c..c57a52dd593 100644 --- a/client/dbclient_rs.cpp +++ b/client/dbclient_rs.cpp @@ -809,10 +809,14 @@ namespace mongo { bool DBClientReplicaSet::call( Message &toSend, Message &response, bool assertOk , string * actualServer ) { + const char * ns = 0; + if ( toSend.operation() == dbQuery ) { // TODO: might be possible to do this faster by changing api DbMessage dm( toSend ); QueryMessage qm( dm ); + ns = qm.ns; + if ( qm.queryOptions & QueryOption_SlaveOk ) { for ( int i=0; i<3; i++ ) { try { @@ -833,7 +837,26 @@ namespace mongo { DBClientConnection* m = checkMaster(); if ( actualServer ) *actualServer = m->getServerAddress(); - return m->call( toSend , response , assertOk ); + + if ( ! m->call( toSend , response , assertOk ) ) + return false; + + if ( ns ) { + QueryResult * res = (QueryResult*)response.singleData(); + if ( res->nReturned == 1 ) { + BSONObj x(res->data() ); + if ( str::contains( ns , "$cmd" ) ) { + if ( isNotMasterErrorString( x["errmsg"] ) ) + isntMaster(); + } + else { + if ( isNotMasterErrorString( getErrField( x ) ) ) + isntMaster(); + } + } + } + + return true; } } diff --git a/jstests/slowNightly/replica_set_shard_version.js b/jstests/slowNightly/replica_set_shard_version.js index 7b155550f25..ca456dcc177 100644 --- a/jstests/slowNightly/replica_set_shard_version.js +++ b/jstests/slowNightly/replica_set_shard_version.js @@ -44,8 +44,20 @@ printjson( coll.findOne() ) end = new Date(); -print( "time to work: " + ( ( end.getTime() - start.getTime() ) / 1000 ) + " seconds" ); +print( "time to work for primary: " + ( ( end.getTime() - start.getTime() ) / 1000 ) + " seconds" ); assert.gt( 3 , iteratioons ); + +// now check secondary + +sadmin.runCommand({ replSetStepDown : 3000, force : true }) +other = new Mongo( mongosA.host ); +other.setSlaveOk( true ); +other = other.getCollection( jsTestName() + ".coll" ); + +print( "eliot: " + tojson( other.findOne() ) ); + + + st.stop() diff --git a/s/d_state.cpp b/s/d_state.cpp index 393df986533..4c53098052d 100644 --- a/s/d_state.cpp +++ b/s/d_state.cpp @@ -29,7 +29,7 @@ #include "../db/commands.h" #include "../db/jsobj.h" #include "../db/db.h" - +#include "../db/replutil.h" #include "../client/connpool.h" #include "../util/queue.h" @@ -396,6 +396,7 @@ namespace mongo { help << " example: { setShardVersion : 'alleyinsider.foo' , version : 1 , configdb : '' } "; } + virtual bool slaveOk() const { return true; } virtual LockType locktype() const { return NONE; } bool checkConfigOrInit( const string& configdb , bool authoritative , string& errmsg , BSONObjBuilder& result , bool locked=false ) const { @@ -492,6 +493,13 @@ namespace mongo { return true; } + // we can run on a slave up to here + if ( ! isMaster( "admin" ) ) { + result.append( "errmsg" , "not master" ); + result.append( "note" , "from post init in setShardVersion" ); + return false; + } + // step 2 string ns = cmdObj["setShardVersion"].valuestrsafe(); |