ShardManager::ShardManager( DBConfig * config , string ns , ShardKeyPattern pattern ) : _config( config ) , _ns( ns ) , _key( pattern ){ Shard temp(0); ScopedDbConnection conn( temp.modelServer() ); auto_ptr<DBClientCursor> cursor = conn->query( temp.getNS() , BSON( "ns" << ns ) ); while ( cursor->more() ){ Shard * s = new Shard( this ); BSONObj d = cursor->next(); s->unserialize( d ); _shards.push_back( s ); s->_id = d["_id"].wrap().getOwned(); } conn.done(); if ( _shards.size() == 0 ){ Shard * s = new Shard( this ); s->_ns = ns; s->_min = _key.globalMin(); s->_max = _key.globalMax(); s->_server = config->getPrimary(); s->_markModified(); _shards.push_back( s ); log() << "no shards for:" << ns << " so creating first: " << s->toString() << endl; } _sequenceNumber = ++NextSequenceNumber; }
Shard * Shard::split( const BSONObj& m ){ uassert( "can't split as shard that doesn't have a manager" , _manager ); log(1) << " before split on: " << m << "\n" << "\t self : " << toString() << endl; uassert( "locking namespace on server failed" , lockNamespaceOnServer( getServer() , _ns ) ); Shard * s = new Shard( _manager ); s->_ns = _ns; s->_server = _server; s->_min = m.getOwned(); s->_max = _max; s->_markModified(); _markModified(); _manager->_shards.push_back( s ); _max = m.getOwned(); log(1) << " after split:\n" << "\t left : " << toString() << "\n" << "\t right: "<< s->toString() << endl; _manager->save(); return s; }
bool Shard::moveAndCommit( const string& to , string& errmsg ){ uassert( "can't move shard to its current location!" , to != getServer() ); log() << "moving shard ns: " << _ns << " moving shard: " << toString() << " " << _server << " -> " << to << endl; string from = _server; ServerShardVersion oldVersion = _manager->getVersion( from ); BSONObj filter; { BSONObjBuilder b; getFilter( b ); filter = b.obj(); } ScopedDbConnection fromconn( from ); BSONObj startRes; bool worked = fromconn->runCommand( "admin" , BSON( "moveshard.start" << _ns << "from" << from << "to" << to << "filter" << filter ) , startRes ); if ( ! worked ){ errmsg = (string)"moveshard.start failed: " + startRes.toString(); return false; } // update config db setServer( to ); // need to increment version # for old server Shard * randomShardOnOldServer = _manager->findShardOnServer( from ); if ( randomShardOnOldServer ) randomShardOnOldServer->_markModified(); _manager->save(); 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; }