diff options
Diffstat (limited to 's')
-rw-r--r-- | s/client.cpp | 56 | ||||
-rw-r--r-- | s/commands_public.cpp | 2 | ||||
-rw-r--r-- | s/shard_version.cpp | 17 | ||||
-rw-r--r-- | s/strategy_single.cpp | 13 |
4 files changed, 55 insertions, 33 deletions
diff --git a/s/client.cpp b/s/client.cpp index 9058b31..493a8fb 100644 --- a/s/client.cpp +++ b/s/client.cpp @@ -18,7 +18,7 @@ #include "pch.h" #include "server.h" - +#include "../util/scopeguard.h" #include "../db/commands.h" #include "../db/dbmessage.h" #include "../db/stats/counters.h" @@ -140,28 +140,31 @@ namespace mongo { // handle single server if ( shards->size() == 1 ) { string theShard = *(shards->begin() ); - - ShardConnection conn( theShard , "" ); + + BSONObj res; bool ok = false; - try{ - ok = conn->runCommand( "admin" , options , res ); - } - catch( std::exception &e ){ - - warning() << "could not get last error from shard " << theShard << causedBy( e ) << endl; - - // Catch everything that happens here, since we need to ensure we return our connection when we're - // finished. - conn.done(); + { + ShardConnection conn( theShard , "" ); + try { + ok = conn->runCommand( "admin" , options , res ); + } + catch( std::exception &e ) { - return false; - } + warning() << "could not get last error from shard " << theShard << causedBy( e ) << endl; + + // Catch everything that happens here, since we need to ensure we return our connection when we're + // finished. + conn.done(); + + return false; + } - res = res.getOwned(); - conn.done(); + res = res.getOwned(); + conn.done(); + } _addWriteBack( writebacks , res ); @@ -171,16 +174,16 @@ namespace mongo { if ( temp == theShard ) continue; - ShardConnection conn( temp , "" ); - try { + ShardConnection conn( temp , "" ); + ON_BLOCK_EXIT_OBJ( conn, &ShardConnection::done ); _addWriteBack( writebacks , conn->getLastErrorDetailed() ); + } catch( std::exception &e ){ warning() << "could not clear last error from shard " << temp << causedBy( e ) << endl; } - - conn.done(); + } clearSinceLastGetError(); @@ -224,11 +227,12 @@ namespace mongo { for ( set<string>::iterator i = shards->begin(); i != shards->end(); i++ ) { string theShard = *i; bbb.append( theShard ); - ShardConnection conn( theShard , "" ); + boost::scoped_ptr<ShardConnection> conn; BSONObj res; bool ok = false; try { - ok = conn->runCommand( "admin" , options , res ); + conn.reset( new ShardConnection( theShard , "" ) ); // constructor can throw if shard is down + ok = (*conn)->runCommand( "admin" , options , res ); shardRawGLE.append( theShard , res ); } catch( std::exception &e ){ @@ -237,7 +241,7 @@ namespace mongo { // responses. warning() << "could not get last error from a shard " << theShard << causedBy( e ) << endl; - conn.done(); + conn->done(); return false; } @@ -245,7 +249,7 @@ namespace mongo { _addWriteBack( writebacks, res ); string temp = DBClientWithCommands::getLastErrorString( res ); - if ( conn->type() != ConnectionString::SYNC && ( ok == false || temp.size() ) ) { + if ( (*conn)->type() != ConnectionString::SYNC && ( ok == false || temp.size() ) ) { errors.push_back( temp ); errorObjects.push_back( res ); } @@ -258,7 +262,7 @@ namespace mongo { updatedExistingStat = -1; } - conn.done(); + conn->done(); } bbb.done(); diff --git a/s/commands_public.cpp b/s/commands_public.cpp index 23dd7fe..c8914ea 100644 --- a/s/commands_public.cpp +++ b/s/commands_public.cpp @@ -83,7 +83,7 @@ namespace mongo { bool ok = conn->runCommand( db , cmdObj , res , passOptions() ? options : 0 ); if ( ! ok && res["code"].numberInt() == StaleConfigInContextCode ) { conn.done(); - throw StaleConfigException("foo","command failed because of stale config"); + throw StaleConfigException( res["ns"].toString(), "command failed because of stale config" ); } result.appendElements( res ); conn.done(); diff --git a/s/shard_version.cpp b/s/shard_version.cpp index 9c55019..3fdd243 100644 --- a/s/shard_version.cpp +++ b/s/shard_version.cpp @@ -62,6 +62,7 @@ namespace mongo { } void setInitialized( DBClientBase * conn ){ + // At this point, conn may be deleted, *do not access* scoped_lock lk( _mutex ); _init.insert( conn ); } @@ -145,7 +146,10 @@ namespace mongo { LOG(2) << "initial sharding settings : " << cmd << endl; bool ok = conn->runCommand( "admin" , cmd , result ); + + // Conn may be deleted here - *do not access again* - css is an exception, since just uses ptr address connectionShardStatus.setInitialized( conn ); + conn = NULL; // HACK for backwards compatibility with v1.8.x, v2.0.0 and v2.0.1 // Result is false, but will still initialize serverID and configdb @@ -221,6 +225,8 @@ namespace mongo { << endl; BSONObj result; + // Save the server address, cannot access if fails + string serverAddress = conn->getServerAddress(); if ( setShardVersion( *conn , ns , version , authoritative , result ) ) { // success! LOG(1) << " setShardVersion success: " << result << endl; @@ -228,13 +234,16 @@ namespace mongo { return true; } + // At this point, it is no longer safe to use the pointer to conn, we do not know its state + conn = NULL; + LOG(1) << " setShardVersion failed!\n" << result << endl; if ( result["need_authoritative"].trueValue() ) massert( 10428 , "need_authoritative set but in authoritative mode already" , ! authoritative ); if ( ! authoritative ) { - checkShardVersion( *conn , ns , 1 , tryNumber + 1 ); + checkShardVersion( conn_in , ns , 1 , tryNumber + 1 ); return true; } @@ -252,13 +261,13 @@ namespace mongo { const int maxNumTries = 7; if ( tryNumber < maxNumTries ) { LOG( tryNumber < ( maxNumTries / 2 ) ? 1 : 0 ) - << "going to retry checkShardVersion host: " << conn->getServerAddress() << " " << result << endl; + << "going to retry checkShardVersion host: " << serverAddress << " " << result << endl; sleepmillis( 10 * tryNumber ); - checkShardVersion( *conn , ns , true , tryNumber + 1 ); + checkShardVersion( conn_in , ns , true , tryNumber + 1 ); return true; } - string errmsg = str::stream() << "setShardVersion failed host: " << conn->getServerAddress() << " " << result; + string errmsg = str::stream() << "setShardVersion failed host: " << serverAddress << " " << result; log() << " " << errmsg << endl; massert( 10429 , errmsg , 0 ); return true; diff --git a/s/strategy_single.cpp b/s/strategy_single.cpp index fc206e5..a91ac2c 100644 --- a/s/strategy_single.cpp +++ b/s/strategy_single.cpp @@ -21,6 +21,7 @@ #include "cursors.h" #include "../client/connpool.h" #include "../db/commands.h" +#include "grid.h" namespace mongo { @@ -68,7 +69,15 @@ namespace mongo { throw e; loops--; - log() << "retrying command: " << q.query << endl; + log() << "retrying command: " << q.query << " (" << loops << " attempts remain)" << endl; + if( loops < 4 ){ + // In newer versions, can just use forceRemoteCheckShardVersion + DBConfigPtr conf = grid.getDBConfig( e.getns() ); + if ( conf ){ + conf->reload(); + conf->getChunkManagerIfExists( e.getns(), true, true ); + } + } ShardConnection::checkMyConnectionVersions( e.getns() ); } catch ( AssertionException& e ) { @@ -192,7 +201,7 @@ namespace mongo { for ( unsigned i=0; i<shards.size(); i++ ) { Shard shard = shards[i]; ScopedDbConnection conn( shard ); - BSONObj temp = conn->findOne( r.getns() , BSONObj() ); + BSONObj temp = conn->findOne( r.getns() , q.query ); if ( temp["inprog"].isABSONObj() ) { BSONObjIterator i( temp["inprog"].Obj() ); while ( i.more() ) { |