summaryrefslogtreecommitdiff
path: root/s
diff options
context:
space:
mode:
Diffstat (limited to 's')
-rw-r--r--s/client.cpp56
-rw-r--r--s/commands_public.cpp2
-rw-r--r--s/shard_version.cpp17
-rw-r--r--s/strategy_single.cpp13
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() ) {