From c30e80145ef04cc9d4cffca06f1b168746f1633e Mon Sep 17 00:00:00 2001 From: Eliot Horowitz Date: Mon, 6 Apr 2009 16:31:09 -0400 Subject: Sharding: moveshard now is mulit-mongos safe --- s/d_logic.cpp | 8 +++++++- s/shard.cpp | 56 +++++++++++++++++++++++++++++++++----------------------- 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/s/d_logic.cpp b/s/d_logic.cpp index 9fe57f17872..7b639b78b83 100644 --- a/s/d_logic.cpp +++ b/s/d_logic.cpp @@ -291,7 +291,13 @@ namespace mongo { // now we're locked myVersions[ns] = newVersion; - + NSVersions * versions = clientShardVersions.get(); + if ( ! versions ){ + versions = new NSVersions(); + clientShardVersions.reset( versions ); + } + (*versions)[ns] = newVersion; + BSONObj res; bool ok; diff --git a/s/shard.cpp b/s/shard.cpp index 99e64ed3d1a..ffbac9509ca 100644 --- a/s/shard.cpp +++ b/s/shard.cpp @@ -126,14 +126,8 @@ namespace mongo { log() << "moving shard ns: " << _ns << " moving shard: " << toString() << " " << _server << " -> " << to << endl; string from = _server; - - lockNamespaceOnServer( from , _ns ); + ServerShardVersion oldVersion = _manager->getVersion( from ); - // copyCollection - ScopedDbConnection toconn( to ); - BSONObj cloneRes; - - BSONObj filter; { BSONObjBuilder b; @@ -141,17 +135,20 @@ namespace mongo { filter = b.obj(); } - bool worked = toconn->runCommand( _manager->_config->getName().c_str() , - BSON( "cloneCollection" << _ns << - "from" << from << - "query" << filter - ) , - cloneRes - ); + ScopedDbConnection fromconn( from ); + + BSONObj startRes; + bool worked = fromconn->runCommand( "admin" , + BSON( "moveshard.start" << _ns << + "from" << from << + "to" << to << + "filter" << filter + ) , + startRes + ); - toconn.done(); if ( ! worked ){ - errmsg = (string)"cloneCollection failed: " + cloneRes.toString(); + errmsg = (string)"moveshard.start failed: " + startRes.toString(); return false; } @@ -165,16 +162,29 @@ namespace mongo { _manager->save(); - // delete old data - ScopedDbConnection fromconn( from ); - fromconn->remove( _ns.c_str() , filter ); - string removeerror = fromconn->getLastError(); - fromconn.done(); - if ( removeerror.size() ){ - errmsg = (string)"error removing old data:" + removeerror; + BSONObj finishRes; + { + + ServerShardVersion newVersion = _manager->getVersion( from ); + uassert( "version has to be higher" , newVersion > oldVersion ); + + BSONObjBuilder b; + b << "moveshard.finish" << _ns; + b << "to" << to; + b.appendTimestamp( "newVersion" , newVersion ); + b.append( startRes["finishToken"] ); + + worked = fromconn->runCommand( "admin" , + b.done() , + finishRes ); + } + + if ( ! worked ){ + errmsg = (string)"moveshard.finish failed: " + finishRes.toString(); return false; } + fromconn.done(); return true; } -- cgit v1.2.1