void IndexRebuilder::run() { Client::initThread(name().c_str()); ON_BLOCK_EXIT_OBJ(cc(), &Client::shutdown); cc().getAuthorizationSession()->grantInternalAuthorization(); std::vector<std::string> dbNames; globalStorageEngine->listDatabases( &dbNames ); try { std::list<std::string> collNames; for (std::vector<std::string>::const_iterator dbName = dbNames.begin(); dbName < dbNames.end(); dbName++) { OperationContextImpl txn; Client::ReadContext ctx(&txn, *dbName); Database* db = ctx.ctx().db(); db->getDatabaseCatalogEntry()->getCollectionNamespaces(&collNames); } checkNS(collNames); } catch (const DBException& e) { warning() << "Index rebuilding did not complete: " << e.what() << endl; } boost::unique_lock<boost::mutex> lk(repl::ReplSet::rss.mtx); repl::ReplSet::rss.indexRebuildDone = true; repl::ReplSet::rss.cond.notify_all(); LOG(1) << "checking complete" << endl; }
void IndexRebuilder::run() { Client::initThread(name().c_str()); ON_BLOCK_EXIT_OBJ(cc(), &Client::shutdown); cc().getAuthorizationSession()->grantInternalAuthorization(); std::vector<std::string> dbNames; getDatabaseNames(dbNames); try { std::list<std::string> collNames; for (std::vector<std::string>::const_iterator dbName = dbNames.begin(); dbName < dbNames.end(); dbName++) { Client::ReadContext ctx(*dbName); Database* db = cc().database(); db->namespaceIndex().getNamespaces(collNames, /* onlyCollections */ true); } checkNS(collNames); } catch (const DBException&) { warning() << "index rebuilding did not complete" << endl; } boost::unique_lock<boost::mutex> lk(ReplSet::rss.mtx); ReplSet::rss.indexRebuildDone = true; ReplSet::rss.cond.notify_all(); LOG(1) << "checking complete" << endl; }
bool ClientInfo::getLastError( const string& dbName, const BSONObj& options, BSONObjBuilder& result, string& errmsg, bool fromWriteBackListener) { set<string> * shards = getPrev(); if ( shards->size() == 0 ) { result.appendNull( "err" ); return true; } vector<WBInfo> writebacks; // // TODO: These branches should be collapsed into a single codepath // // handle single server if ( shards->size() == 1 ) { string theShard = *(shards->begin() ); BSONObj res; bool ok = false; { LOG(5) << "gathering response for gle from: " << theShard << endl; ShardConnection conn( theShard , "" ); try { ok = conn->runCommand( dbName , options , res ); } catch( std::exception &e ) { string message = str::stream() << "could not get last error from shard " << theShard << causedBy( e ); warning() << message << endl; errmsg = message; // 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(); } _addWriteBack( writebacks , res ); LOG(4) << "gathering writebacks from " << sinceLastGetError().size() << " hosts for" << " gle (" << theShard << ")" << endl; // hit other machines just to block for ( set<string>::const_iterator i=sinceLastGetError().begin(); i!=sinceLastGetError().end(); ++i ) { string temp = *i; if ( temp == theShard ) continue; LOG(5) << "gathering writebacks for single-shard gle from: " << temp << endl; 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; } } clearSinceLastGetError(); LOG(4) << "checking " << writebacks.size() << " writebacks for" << " gle (" << theShard << ")" << endl; if ( writebacks.size() ){ vector<BSONObj> v = _handleWriteBacks( writebacks , fromWriteBackListener ); if ( v.size() == 0 && fromWriteBackListener ) { // ok } else { // this will usually be 1 // it can be greater than 1 if a write to a different shard // than the last write op had a writeback // all we're going to report is the first // since that's the current write // but we block for all verify( v.size() >= 1 ); result.appendElements( v[0] ); result.appendElementsUnique( res ); result.append( "writebackGLE" , v[0] ); result.append( "initialGLEHost" , theShard ); } } else { result.append( "singleShard" , theShard ); result.appendElements( res ); } return ok; } BSONArrayBuilder bbb( result.subarrayStart( "shards" ) ); BSONObjBuilder shardRawGLE; long long n = 0; int updatedExistingStat = 0; // 0 is none, -1 has but false, 1 has true // hit each shard vector<string> errors; vector<BSONObj> errorObjects; for ( set<string>::iterator i = shards->begin(); i != shards->end(); i++ ) { string theShard = *i; bbb.append( theShard ); LOG(5) << "gathering a response for gle from: " << theShard << endl; boost::scoped_ptr<ShardConnection> conn; BSONObj res; bool ok = false; try { conn.reset( new ShardConnection( theShard , "" ) ); // constructor can throw if shard is down ok = (*conn)->runCommand( dbName , options , res ); shardRawGLE.append( theShard , res ); } catch( std::exception &e ){ // Safe to return here, since we haven't started any extra processing yet, just collecting // responses. string message = str::stream() << "could not get last error from a shard " << theShard << causedBy( e ); warning() << message << endl; errmsg = message; if (conn) conn->done(); return false; } _addWriteBack( writebacks, res ); string temp = DBClientWithCommands::getLastErrorString( res ); if ( (*conn)->type() != ConnectionString::SYNC && ( ok == false || temp.size() ) ) { errors.push_back( temp ); errorObjects.push_back( res ); } n += res["n"].numberLong(); if ( res["updatedExisting"].type() ) { if ( res["updatedExisting"].trueValue() ) updatedExistingStat = 1; else if ( updatedExistingStat == 0 ) updatedExistingStat = -1; } conn->done(); } bbb.done(); result.append( "shardRawGLE" , shardRawGLE.obj() ); result.appendNumber( "n" , n ); if ( updatedExistingStat ) result.appendBool( "updatedExisting" , updatedExistingStat > 0 ); LOG(4) << "gathering writebacks from " << sinceLastGetError().size() << " hosts for" << " gle (" << shards->size() << " shards)" << endl; // hit other machines just to block for ( set<string>::const_iterator i=sinceLastGetError().begin(); i!=sinceLastGetError().end(); ++i ) { string temp = *i; if ( shards->count( temp ) ) continue; LOG(5) << "gathering writebacks for multi-shard gle from: " << temp << endl; ShardConnection conn( temp , "" ); try { _addWriteBack( writebacks, conn->getLastErrorDetailed() ); } catch( std::exception &e ){ warning() << "could not clear last error from a shard " << temp << causedBy( e ) << endl; } conn.done(); } clearSinceLastGetError(); LOG(4) << "checking " << writebacks.size() << " writebacks for" << " gle (" << shards->size() << " shards)" << endl; if ( errors.size() == 0 ) { result.appendNull( "err" ); _handleWriteBacks( writebacks , fromWriteBackListener ); return true; } result.append( "err" , errors[0].c_str() ); { // errs BSONArrayBuilder all( result.subarrayStart( "errs" ) ); for ( unsigned i=0; i<errors.size(); i++ ) { all.append( errors[i].c_str() ); } all.done(); } { // errObjects BSONArrayBuilder all( result.subarrayStart( "errObjects" ) ); for ( unsigned i=0; i<errorObjects.size(); i++ ) { all.append( errorObjects[i] ); } all.done(); } _handleWriteBacks( writebacks , fromWriteBackListener ); return true; }