summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEliot Horowitz <eliot@10gen.com>2011-11-21 00:27:20 -0500
committerEliot Horowitz <eliot@10gen.com>2011-11-21 01:02:06 -0500
commitc0588190d401824422ca6c9a0c9744cfcb62e9a1 (patch)
treef69dff298546368debd944598a1ffc2cfca98cd3
parent415486ce5cdc82ab1f8b2f8db92a197535e31d61 (diff)
downloadmongo-c0588190d401824422ca6c9a0c9744cfcb62e9a1.tar.gz
handle non-sharded query not master errors SERVER-4324
-rw-r--r--client/dbclient_rs.cpp25
-rw-r--r--jstests/slowNightly/replica_set_shard_version.js14
-rw-r--r--s/d_state.cpp10
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();