bool run(const string& dbname, BSONObj& jsobj, int, string& errmsg, BSONObjBuilder& anObjBuilder, bool /*fromRepl*/) { BSONElement e = jsobj.firstElement(); const string toDeleteNs = dbname + '.' + e.valuestr(); if (!serverGlobalParams.quiet) { MONGO_TLOG(0) << "CMD: dropIndexes " << toDeleteNs << endl; } Lock::DBWrite dbXLock(dbname); Client::Context ctx(toDeleteNs); Collection* collection = cc().database()->getCollection( toDeleteNs ); if ( ! collection ) { errmsg = "ns not found"; return false; } stopIndexBuilds(cc().database(), jsobj); IndexCatalog* indexCatalog = collection->getIndexCatalog(); anObjBuilder.appendNumber("nIndexesWas", indexCatalog->numIndexesTotal() ); BSONElement f = jsobj.getField("index"); if ( f.type() == String ) { string indexToDelete = f.valuestr(); if ( indexToDelete == "*" ) { Status s = indexCatalog->dropAllIndexes( false ); if ( !s.isOK() ) { appendCommandStatus( anObjBuilder, s ); return false; } anObjBuilder.append("msg", "non-_id indexes dropped for collection"); return true; } IndexDescriptor* desc = collection->getIndexCatalog()->findIndexByName( indexToDelete ); if ( desc == NULL ) { errmsg = str::stream() << "index not found with name [" << indexToDelete << "]"; return false; } if ( desc->isIdIndex() ) { errmsg = "cannot drop _id index"; return false; } Status s = indexCatalog->dropIndex( desc ); if ( !s.isOK() ) { appendCommandStatus( anObjBuilder, s ); return false; } return true; } if ( f.type() == Object ) { IndexDescriptor* desc = collection->getIndexCatalog()->findIndexByKeyPattern( f.embeddedObject() ); if ( desc == NULL ) { errmsg = "can't find index with key:"; errmsg += f.embeddedObject().toString(); return false; } if ( desc->isIdIndex() ) { errmsg = "cannot drop _id index"; return false; } Status s = indexCatalog->dropIndex( desc ); if ( !s.isOK() ) { appendCommandStatus( anObjBuilder, s ); return false; } return true; } errmsg = "invalid index name spec"; return false; }
void IndexRebuilder::checkNS(const std::list<std::string>& nsToCheck) { bool firstTime = true; for (std::list<std::string>::const_iterator it = nsToCheck.begin(); it != nsToCheck.end(); ++it) { string ns = *it; LOG(3) << "IndexRebuilder::checkNS: " << ns; OperationContextImpl txn; // XXX??? // This write lock is held throughout the index building process // for this namespace. Client::WriteContext ctx(&txn, ns); Collection* collection = ctx.ctx().db()->getCollection( &txn, ns ); if ( collection == NULL ) continue; IndexCatalog* indexCatalog = collection->getIndexCatalog(); if ( collection->ns().isOplog() && indexCatalog->numIndexesTotal() > 0 ) { warning() << ns << " had illegal indexes, removing"; indexCatalog->dropAllIndexes(&txn, true); continue; } vector<BSONObj> indexesToBuild = indexCatalog->getAndClearUnfinishedIndexes(&txn); // The indexes have now been removed from system.indexes, so the only record is // in-memory. If there is a journal commit between now and when insert() rewrites // the entry and the db crashes before the new system.indexes entry is journalled, // the index will be lost forever. Thus, we're assuming no journaling will happen // between now and the entry being re-written. if ( indexesToBuild.size() == 0 ) { continue; } log() << "found " << indexesToBuild.size() << " interrupted index build(s) on " << ns; if (firstTime) { log() << "note: restart the server with --noIndexBuildRetry to skip index rebuilds"; firstTime = false; } if (!serverGlobalParams.indexBuildRetry) { log() << " not rebuilding interrupted indexes"; continue; } // TODO: these can/should/must be done in parallel for ( size_t i = 0; i < indexesToBuild.size(); i++ ) { BSONObj indexObj = indexesToBuild[i]; log() << "going to rebuild: " << indexObj; Status status = indexCatalog->createIndex(&txn, indexObj, false); if ( !status.isOK() ) { log() << "building index failed: " << status.toString() << " index: " << indexObj; } } } }
bool wrappedRun(OperationContext* txn, const string& dbname, BSONObj& jsobj, string& errmsg, BSONObjBuilder& anObjBuilder) { const std::string coll = jsobj.firstElement().valuestrsafe(); if (coll.empty()) { errmsg = "no collection name specified"; return false; } const std::string toDeleteNs = dbname + '.' + coll; if (!serverGlobalParams.quiet) { LOG(0) << "CMD: dropIndexes " << toDeleteNs << endl; } Client::Context ctx(txn, toDeleteNs); Database* db = ctx.db(); Collection* collection = db->getCollection( txn, toDeleteNs ); if ( ! collection ) { errmsg = "ns not found"; return false; } stopIndexBuilds(txn, db, jsobj); IndexCatalog* indexCatalog = collection->getIndexCatalog(); anObjBuilder.appendNumber("nIndexesWas", indexCatalog->numIndexesTotal(txn) ); BSONElement f = jsobj.getField("index"); if ( f.type() == String ) { string indexToDelete = f.valuestr(); if ( indexToDelete == "*" ) { Status s = indexCatalog->dropAllIndexes(txn, false); if ( !s.isOK() ) { appendCommandStatus( anObjBuilder, s ); return false; } anObjBuilder.append("msg", "non-_id indexes dropped for collection"); return true; } IndexDescriptor* desc = collection->getIndexCatalog()->findIndexByName( txn, indexToDelete ); if ( desc == NULL ) { errmsg = str::stream() << "index not found with name [" << indexToDelete << "]"; return false; } if ( desc->isIdIndex() ) { errmsg = "cannot drop _id index"; return false; } Status s = indexCatalog->dropIndex(txn, desc); if ( !s.isOK() ) { appendCommandStatus( anObjBuilder, s ); return false; } return true; } if ( f.type() == Object ) { IndexDescriptor* desc = collection->getIndexCatalog()->findIndexByKeyPattern( txn, f.embeddedObject() ); if ( desc == NULL ) { errmsg = "can't find index with key:"; errmsg += f.embeddedObject().toString(); return false; } if ( desc->isIdIndex() ) { errmsg = "cannot drop _id index"; return false; } Status s = indexCatalog->dropIndex(txn, desc); if ( !s.isOK() ) { appendCommandStatus( anObjBuilder, s ); return false; } return true; } errmsg = "invalid index name spec"; return false; }