diff options
author | Eric Milkie <milkie@10gen.com> | 2014-03-21 10:17:20 -0400 |
---|---|---|
committer | Eric Milkie <milkie@10gen.com> | 2014-03-21 10:17:33 -0400 |
commit | 70c062eb0646506df8979b49c052a54e6e4f9f8e (patch) | |
tree | a73a3994cbbab8856d191ed044e8a783b12ede84 /src/mongo | |
parent | f6713955af2bfe8a2c5f5ac7d0dfcabebbc821c5 (diff) | |
download | mongo-70c062eb0646506df8979b49c052a54e6e4f9f8e.tar.gz |
SERVER-13053 track index builds explicitly instead of using CurOp
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/db/catalog/index_catalog.cpp | 74 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_catalog.h | 19 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_create.cpp | 13 | ||||
-rw-r--r-- | src/mongo/db/commands.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/commands.h | 5 | ||||
-rw-r--r-- | src/mongo/db/commands/collection_to_capped.cpp | 15 | ||||
-rw-r--r-- | src/mongo/db/commands/compact.cpp | 12 | ||||
-rw-r--r-- | src/mongo/db/commands/drop_indexes.cpp | 40 | ||||
-rw-r--r-- | src/mongo/db/commands/rename_collection.cpp | 11 | ||||
-rw-r--r-- | src/mongo/db/commands/test_commands.cpp | 12 | ||||
-rw-r--r-- | src/mongo/db/dbcommands.cpp | 68 | ||||
-rw-r--r-- | src/mongo/db/index_builder.cpp | 20 | ||||
-rw-r--r-- | src/mongo/db/index_builder.h | 12 | ||||
-rw-r--r-- | src/mongo/db/query/runner_yield_policy.h | 1 | ||||
-rw-r--r-- | src/mongo/db/structure/catalog/index_details.h | 3 | ||||
-rw-r--r-- | src/mongo/dbtests/replsettests.cpp | 598 |
16 files changed, 201 insertions, 704 deletions
diff --git a/src/mongo/db/catalog/index_catalog.cpp b/src/mongo/db/catalog/index_catalog.cpp index f8cb911bbf4..4c48863023c 100644 --- a/src/mongo/db/catalog/index_catalog.cpp +++ b/src/mongo/db/catalog/index_catalog.cpp @@ -34,13 +34,13 @@ #include "mongo/db/audit.h" #include "mongo/db/background.h" +#include "mongo/db/catalog/collection.h" #include "mongo/db/catalog/index_create.h" #include "mongo/db/catalog/index_key_validate.h" #include "mongo/db/client.h" #include "mongo/db/clientcursor.h" #include "mongo/db/curop.h" #include "mongo/db/field_ref.h" -#include "mongo/db/index_legacy.h" #include "mongo/db/index/2d_access_method.h" #include "mongo/db/index/btree_access_method.h" #include "mongo/db/index/btree_based_access_method.h" @@ -50,14 +50,15 @@ #include "mongo/db/index/index_access_method.h" #include "mongo/db/index/index_descriptor.h" #include "mongo/db/index/s2_access_method.h" +#include "mongo/db/index_legacy.h" #include "mongo/db/index_names.h" #include "mongo/db/jsobj.h" #include "mongo/db/jsobjmanipulator.h" #include "mongo/db/keypattern.h" +#include "mongo/db/kill_current_op.h" #include "mongo/db/ops/delete.h" #include "mongo/db/query/internal_plans.h" #include "mongo/db/repl/rs.h" // this is ugly -#include "mongo/db/catalog/collection.h" #include "mongo/db/storage/data_file.h" #include "mongo/db/structure/catalog/namespace_details-inl.h" #include "mongo/util/assert_util.h" @@ -322,16 +323,20 @@ namespace mongo { invariant( _details->_catalogFindIndexByName( idxName, true ) >= 0 ); try { - // Set curop description before setting indexBuildInProg, so that there's something - // commands can find and kill as soon as indexBuildInProg is set. Only set this if it's a - // killable index, so we don't overwrite commands in currentOp. - if ( mayInterrupt ) { - cc().curop()->setQuery( spec ); - } + Client& client = cc(); + + _inProgressIndexes[descriptor] = &client; + // buildAnIndex can yield. During a yield, the Collection that owns this + // IndexCatalog can be dropped, which means both the Collection and IndexCatalog + // can be destructed out from under us. The runner used by the index build will + // throw a particular exception when it detects that this occurred. buildAnIndex( _collection, entry, mayInterrupt ); indexBuildBlock.success(); + InProgressIndexesMap::iterator it = _inProgressIndexes.find(descriptor); + _inProgressIndexes.erase(it); + // sanity check int idxNo = _details->_catalogFindIndexByName( idxName, true ); invariant( idxNo < numIndexesReady() ); @@ -339,16 +344,25 @@ namespace mongo { return Status::OK(); } catch ( const AssertionException& exc ) { - log() << "index build failed." - << " spec: " << spec - << " error: " << exc; + // At this point, *this may have been destructed, if we dropped the collection + // while we were yielding. indexBuildBlock will not touch an invalid _collection + // pointer if you call abort() on it. + + log() << "index build failed." << " spec: " << spec << " error: " << exc; if ( shutdownBehavior == SHUTDOWN_LEAVE_DIRTY && exc.getCode() == ErrorCodes::InterruptedAtShutdown ) { indexBuildBlock.abort(); } + else if ( exc.getCode() == ErrorCodes::CursorNotFound ) { + // The cursor was killed because the collection was dropped. No need to clean up. + indexBuildBlock.abort(); + } else { indexBuildBlock.fail(); + + InProgressIndexesMap::iterator it = _inProgressIndexes.find(descriptor); + _inProgressIndexes.erase(it); } ErrorCodes::Error codeToUse = ErrorCodes::fromInt( exc.getCode() ); @@ -1244,7 +1258,6 @@ namespace mongo { return key; } - BSONObj IndexCatalog::_fixIndexSpec( const BSONObj& spec ) { BSONObj o = IndexLegacy::adjustIndexSpecObject( spec ); @@ -1298,4 +1311,41 @@ namespace mongo { return b.obj(); } + + std::vector<BSONObj> + IndexCatalog::killMatchingIndexBuilds(const IndexCatalog::IndexKillCriteria& criteria) { + verify(Lock::somethingWriteLocked()); + std::vector<BSONObj> indexes; + for (InProgressIndexesMap::iterator it = _inProgressIndexes.begin(); + it != _inProgressIndexes.end(); + it++) { + // check criteria + IndexDescriptor* desc = it->first; + Client* client = it->second; + if (!criteria.ns.empty() && (desc->parentNS() != criteria.ns)) { + continue; + } + if (!criteria.name.empty() && (desc->indexName() != criteria.name)) { + continue; + } + if (!criteria.key.isEmpty() && (desc->keyPattern() != criteria.key)) { + continue; + } + indexes.push_back(desc->keyPattern()); + CurOp* op = client->curop(); + log() << "halting index build: " << desc->keyPattern(); + // Note that we can only be here if the background index build in question is + // yielding. The bg index code is set up specially to check for interrupt + // immediately after it recovers from yield, such that no further work is done + // on the index build. Thus this thread does not have to synchronize with the + // bg index operation; we can just assume that it is safe to proceed. + killCurrentOp.kill(op->opNum()); + } + + if (indexes.size() > 0) { + log() << "halted " << indexes.size() << " index build(s)" << endl; + } + + return indexes; + } } diff --git a/src/mongo/db/catalog/index_catalog.h b/src/mongo/db/catalog/index_catalog.h index 3edfabc1548..d1852b13a7a 100644 --- a/src/mongo/db/catalog/index_catalog.h +++ b/src/mongo/db/catalog/index_catalog.h @@ -35,9 +35,11 @@ #include "mongo/db/catalog/index_catalog_entry.h" #include "mongo/db/diskloc.h" #include "mongo/db/jsobj.h" +#include "mongo/platform/unordered_map.h" namespace mongo { + class Client; class Collection; class NamespaceDetails; @@ -157,6 +159,20 @@ namespace mongo { */ vector<BSONObj> getAndClearUnfinishedIndexes(); + + struct IndexKillCriteria { + std::string ns; + std::string name; + BSONObj key; + }; + + /** + * Given some criteria, will search through all in-progress index builds + * and will kill ones that match. (namespace, index name, and/or index key spec) + * Returns the list of index specs that were killed, for use in restarting them later. + */ + std::vector<BSONObj> killMatchingIndexBuilds(const IndexKillCriteria& criteria); + // ---- modify single index /* Updates the expireAfterSeconds field of the given index to the value in newExpireSecs. @@ -243,6 +259,7 @@ namespace mongo { static BSONObj fixIndexKey( const BSONObj& key ); private: + typedef unordered_map<IndexDescriptor*, Client*> InProgressIndexesMap; // creates a new thing, no caching IndexAccessMethod* _createAccessMethod( const IndexDescriptor* desc, @@ -306,6 +323,8 @@ namespace mongo { static const BSONObj _idObj; // { _id : 1 } + // Track in-progress index builds, in order to find and stop them when necessary. + InProgressIndexesMap _inProgressIndexes; }; } diff --git a/src/mongo/db/catalog/index_create.cpp b/src/mongo/db/catalog/index_create.cpp index 9237ca878ae..744ed46d96d 100644 --- a/src/mongo/db/catalog/index_create.cpp +++ b/src/mongo/db/catalog/index_create.cpp @@ -148,7 +148,8 @@ namespace mongo { // TODO: Why is this normal? } else { - uasserted(12585, "cursor gone during bg index; dropDups"); + uasserted(ErrorCodes::CursorNotFound, + "cursor gone during bg index; dropDups"); } break; } @@ -167,11 +168,19 @@ namespace mongo { getDur().commitIfNeeded(); if (shouldYield && yieldPolicy.shouldYield()) { + // Note: yieldAndCheckIfOK checks for interrupt and thus can throw if (!yieldPolicy.yieldAndCheckIfOK(runner.get())) { - uasserted(12584, "cursor gone during bg index"); + uasserted(ErrorCodes::CursorNotFound, "cursor gone during bg index"); break; } + // Checking for interrupt here is necessary because the bg index + // interruptors can only interrupt this index build while they hold + // a write lock, and yieldAndCheckIfOK only checks for + // interrupt prior to yielding our write lock. We need to check the kill flag + // here before another iteration of the loop. + killCurrentOp.checkForInterrupt(); + progress.setTotalWhileRunning( collection->numRecords() ); // Recalculate idxNo if we yielded IndexDescriptor* idx = collection->getIndexCatalog()->findIndexByName( idxName, diff --git a/src/mongo/db/commands.cpp b/src/mongo/db/commands.cpp index 3d95d1df731..ff0a04fcfa8 100644 --- a/src/mongo/db/commands.cpp +++ b/src/mongo/db/commands.cpp @@ -185,7 +185,7 @@ namespace mongo { help << "no help defined"; } - std::vector<BSONObj> Command::stopIndexBuilds(const std::string& dbname, + std::vector<BSONObj> Command::stopIndexBuilds(Database* db, const BSONObj& cmdObj) { return std::vector<BSONObj>(); } diff --git a/src/mongo/db/commands.h b/src/mongo/db/commands.h index bf229ccc42c..fcd1ae12ed0 100644 --- a/src/mongo/db/commands.h +++ b/src/mongo/db/commands.h @@ -31,6 +31,7 @@ namespace mongo { class BSONObj; class BSONObjBuilder; class Client; + class Database; class Timer; namespace mutablebson { @@ -191,8 +192,8 @@ namespace mutablebson { static map<string,Command*> * _webCommands; public: - // Stop all index builds required to run this command and return index builds killed. - virtual std::vector<BSONObj> stopIndexBuilds(const std::string& dbname, + // Stops all index builds required to run this command and returns index builds killed. + virtual std::vector<BSONObj> stopIndexBuilds(Database* db, const BSONObj& cmdObj); static const map<string,Command*>* commandsByBestName() { return _commandsByBestName; } diff --git a/src/mongo/db/commands/collection_to_capped.cpp b/src/mongo/db/commands/collection_to_capped.cpp index 56875312fd3..c4e1f32a6a3 100644 --- a/src/mongo/db/commands/collection_to_capped.cpp +++ b/src/mongo/db/commands/collection_to_capped.cpp @@ -199,19 +199,20 @@ namespace mongo { out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), actions)); } - virtual std::vector<BSONObj> stopIndexBuilds(const std::string& dbname, + virtual std::vector<BSONObj> stopIndexBuilds(Database* db, const BSONObj& cmdObj) { - std::string systemIndexes = dbname+".system.indexes"; std::string coll = cmdObj.firstElement().valuestr(); - std::string ns = dbname + "." + coll; - BSONObj criteria = BSON("ns" << systemIndexes << "op" << "insert" << "insert.ns" << ns); + std::string ns = db->name() + "." + coll; - return IndexBuilder::killMatchingIndexBuilds(criteria); + IndexCatalog::IndexKillCriteria criteria; + criteria.ns = ns; + return IndexBuilder::killMatchingIndexBuilds(db->getCollection(ns), criteria); } bool run(const string& dbname, BSONObj& jsobj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl ) { + Database* db = cc().database(); - stopIndexBuilds(dbname, jsobj); + stopIndexBuilds(db, jsobj); BackgroundOperation::assertNoBgOpInProgForDb(dbname.c_str()); string shortSource = jsobj.getStringField( "convertToCapped" ); @@ -226,8 +227,6 @@ namespace mongo { string shortTmpName = str::stream() << "tmp.convertToCapped." << shortSource; string longTmpName = str::stream() << dbname << "." << shortTmpName; - Database* db = cc().database(); - if ( db->getCollection( longTmpName ) ) { Status status = db->dropCollection( longTmpName ); if ( !status.isOK() ) diff --git a/src/mongo/db/commands/compact.cpp b/src/mongo/db/commands/compact.cpp index 6107a53b44a..b020bf1e4e8 100644 --- a/src/mongo/db/commands/compact.cpp +++ b/src/mongo/db/commands/compact.cpp @@ -73,14 +73,14 @@ namespace mongo { } CompactCmd() : Command("compact") { } - virtual std::vector<BSONObj> stopIndexBuilds(const std::string& dbname, + virtual std::vector<BSONObj> stopIndexBuilds(Database* db, const BSONObj& cmdObj) { - std::string systemIndexes = dbname+".system.indexes"; std::string coll = cmdObj.firstElement().valuestr(); - std::string ns = dbname + "." + coll; - BSONObj criteria = BSON("ns" << systemIndexes << "op" << "insert" << "insert.ns" << ns); + std::string ns = db->name() + "." + coll; - return IndexBuilder::killMatchingIndexBuilds(criteria); + IndexCatalog::IndexKillCriteria criteria; + criteria.ns = ns; + return IndexBuilder::killMatchingIndexBuilds(db->getCollection(ns), criteria); } virtual bool run(const string& db, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { @@ -159,7 +159,7 @@ namespace mongo { log() << "compact " << ns << " begin, options: " << compactOptions.toString(); - std::vector<BSONObj> indexesInProg = stopIndexBuilds(db, cmdObj); + std::vector<BSONObj> indexesInProg = stopIndexBuilds(ctx.db(), cmdObj); StatusWith<CompactStats> status = collection->compact( &compactOptions ); if ( !status.isOK() ) diff --git a/src/mongo/db/commands/drop_indexes.cpp b/src/mongo/db/commands/drop_indexes.cpp index 402ce22b1a4..1acb5da063e 100644 --- a/src/mongo/db/commands/drop_indexes.cpp +++ b/src/mongo/db/commands/drop_indexes.cpp @@ -61,14 +61,11 @@ namespace mongo { out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), actions)); } - virtual std::vector<BSONObj> stopIndexBuilds(const std::string& dbname, + virtual std::vector<BSONObj> stopIndexBuilds(Database* db, const BSONObj& cmdObj) { - std::string systemIndexes = dbname+".system.indexes"; - std::string toDeleteNs = dbname+"."+cmdObj.firstElement().valuestr(); - BSONObjBuilder builder; - builder.append("ns", systemIndexes); - builder.append("op", "insert"); - builder.append("insert.ns", toDeleteNs); + std::string toDeleteNs = db->name() + "." + cmdObj.firstElement().valuestr(); + Collection* collection = db->getCollection(toDeleteNs); + IndexCatalog::IndexKillCriteria criteria; // Get index name to drop BSONElement toDrop = cmdObj.getField("index"); @@ -76,21 +73,19 @@ namespace mongo { if (toDrop.type() == String) { // Kill all in-progress indexes if (strcmp("*", toDrop.valuestr()) == 0) { - BSONObj criteria = builder.done(); - return IndexBuilder::killMatchingIndexBuilds(criteria); + criteria.ns = toDeleteNs; + return IndexBuilder::killMatchingIndexBuilds(collection, criteria); } // Kill an in-progress index by name else { - builder.append("insert.name", toDrop.valuestr()); - BSONObj criteria = builder.done(); - return IndexBuilder::killMatchingIndexBuilds(criteria); + criteria.name = toDrop.valuestr(); + return IndexBuilder::killMatchingIndexBuilds(collection, criteria); } } // Kill an in-progress index build by index key else if (toDrop.type() == Object) { - builder.append("insert.key", toDrop.Obj()); - BSONObj criteria = builder.done(); - return IndexBuilder::killMatchingIndexBuilds(criteria); + criteria.key = toDrop.Obj(); + return IndexBuilder::killMatchingIndexBuilds(collection, criteria); } return std::vector<BSONObj>(); @@ -110,7 +105,7 @@ namespace mongo { return false; } - stopIndexBuilds(dbname, jsobj); + stopIndexBuilds(cc().database(), jsobj); IndexCatalog* indexCatalog = collection->getIndexCatalog(); anObjBuilder.appendNumber("nIndexesWas", indexCatalog->numIndexesTotal() ); @@ -196,13 +191,12 @@ namespace mongo { } CmdReIndex() : Command("reIndex") { } - virtual std::vector<BSONObj> stopIndexBuilds(const std::string& dbname, + virtual std::vector<BSONObj> stopIndexBuilds(Database* db, const BSONObj& cmdObj) { - std::string systemIndexes = dbname + ".system.indexes"; - std::string ns = dbname + '.' + cmdObj["reIndex"].valuestrsafe(); - BSONObj criteria = BSON("ns" << systemIndexes << "op" << "insert" << "insert.ns" << ns); - - return IndexBuilder::killMatchingIndexBuilds(criteria); + std::string ns = db->name() + '.' + cmdObj["reIndex"].valuestrsafe(); + IndexCatalog::IndexKillCriteria criteria; + criteria.ns = ns; + return IndexBuilder::killMatchingIndexBuilds(db->getCollection(ns), criteria); } bool run(const string& dbname , BSONObj& jsobj, int, string& errmsg, BSONObjBuilder& result, bool /*fromRepl*/) { @@ -222,7 +216,7 @@ namespace mongo { BackgroundOperation::assertNoBgOpInProgForNs( toDeleteNs ); - std::vector<BSONObj> indexesInProg = stopIndexBuilds(dbname, jsobj); + std::vector<BSONObj> indexesInProg = stopIndexBuilds(cc().database(), jsobj); list<BSONObj> all; auto_ptr<DBClientCursor> i = db.query( dbname + ".system.indexes" , BSON( "ns" << toDeleteNs ) , 0 , 0 , 0 , QueryOption_SlaveOk ); diff --git a/src/mongo/db/commands/rename_collection.cpp b/src/mongo/db/commands/rename_collection.cpp index b023d876f23..8aaf0052948 100644 --- a/src/mongo/db/commands/rename_collection.cpp +++ b/src/mongo/db/commands/rename_collection.cpp @@ -66,15 +66,16 @@ namespace mongo { help << " example: { renameCollection: foo.a, to: bar.b }"; } - virtual std::vector<BSONObj> stopIndexBuilds(const std::string& dbname, + virtual std::vector<BSONObj> stopIndexBuilds(Database* db, const BSONObj& cmdObj) { string source = cmdObj.getStringField( name.c_str() ); string target = cmdObj.getStringField( "to" ); - BSONObj criteria = BSON("op" << "insert" << "ns" << dbname+".system.indexes" << - "insert.ns" << source); + IndexCatalog::IndexKillCriteria criteria; + criteria.ns = source; + std::vector<BSONObj> prelim = + IndexBuilder::killMatchingIndexBuilds(db->getCollection(source), criteria); - std::vector<BSONObj> prelim = IndexBuilder::killMatchingIndexBuilds(criteria); std::vector<BSONObj> indexes; for (int i = 0; i < static_cast<int>(prelim.size()); i++) { @@ -162,7 +163,7 @@ namespace mongo { { const NamespaceDetails *nsd = nsdetails( source ); - indexesInProg = stopIndexBuilds( dbname, cmdObj ); + indexesInProg = stopIndexBuilds( srcCtx.db(), cmdObj ); capped = nsd->isCapped(); if ( capped ) for( DiskLoc i = nsd->firstExtent(); !i.isNull(); i = i.ext()->xnext ) diff --git a/src/mongo/db/commands/test_commands.cpp b/src/mongo/db/commands/test_commands.cpp index 54b93b13dba..4667f6b7ecc 100644 --- a/src/mongo/db/commands/test_commands.cpp +++ b/src/mongo/db/commands/test_commands.cpp @@ -169,14 +169,14 @@ namespace mongo { const BSONObj& cmdObj, std::vector<Privilege>* out) {} - virtual std::vector<BSONObj> stopIndexBuilds(const std::string& dbname, + virtual std::vector<BSONObj> stopIndexBuilds(Database* db, const BSONObj& cmdObj) { - std::string systemIndexes = dbname + ".system.indexes"; std::string coll = cmdObj[ "emptycapped" ].valuestrsafe(); - std::string ns = dbname + '.' + coll; - BSONObj criteria = BSON("ns" << systemIndexes << "op" << "insert" << "insert.ns" << ns); + std::string ns = db->name() + '.' + coll; - return IndexBuilder::killMatchingIndexBuilds(criteria); + IndexCatalog::IndexKillCriteria criteria; + criteria.ns = ns; + return IndexBuilder::killMatchingIndexBuilds(db->getCollection(ns), criteria); } virtual bool run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool) { @@ -186,7 +186,7 @@ namespace mongo { NamespaceDetails *nsd = nsdetails( ns ); massert( 13429, "emptycapped no such collection", nsd ); - std::vector<BSONObj> indexes = stopIndexBuilds(dbname, cmdObj); + std::vector<BSONObj> indexes = stopIndexBuilds(cc().database(), cmdObj); nsd->emptyCappedCollection( ns.c_str() ); diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp index 89e0bc84572..e9c08fe3ef3 100644 --- a/src/mongo/db/dbcommands.cpp +++ b/src/mongo/db/dbcommands.cpp @@ -170,14 +170,27 @@ namespace mongo { virtual LockType locktype() const { return WRITE; } - virtual std::vector<BSONObj> stopIndexBuilds(const std::string& dbname, + virtual std::vector<BSONObj> stopIndexBuilds(Database* db, const BSONObj& cmdObj) { - std::string systemIndexes = dbname+".system.indexes"; - std::string toDeleteRegex = "^"+dbname+"\\."; - BSONObj criteria = BSON("ns" << systemIndexes << - "op" << "insert" << - "insert.ns" << BSON("$regex" << toDeleteRegex)); - return IndexBuilder::killMatchingIndexBuilds(criteria); + invariant(db); + std::list<std::string> collections; + db->namespaceIndex().getNamespaces(collections, true /* onlyCollections */); + + std::vector<BSONObj> allKilledIndexes; + for (std::list<std::string>::iterator it = collections.begin(); + it != collections.end(); + ++it) { + std::string ns = *it; + + IndexCatalog::IndexKillCriteria criteria; + criteria.ns = ns; + std::vector<BSONObj> killedIndexes = + IndexBuilder::killMatchingIndexBuilds(db->getCollection(ns), criteria); + allKilledIndexes.insert(allKilledIndexes.end(), + killedIndexes.begin(), + killedIndexes.end()); + } + return allKilledIndexes; } CmdDropDatabase() : Command("dropDatabase") {} @@ -192,7 +205,7 @@ namespace mongo { int p = (int) e.number(); if ( p != 1 ) return false; - stopIndexBuilds(dbname, cmdObj); + stopIndexBuilds(cc().database(), cmdObj); dropDatabase(dbname); result.append( "dropped" , dbname ); log() << "dropDatabase " << dbname << " finished" << endl; @@ -224,11 +237,27 @@ namespace mongo { } CmdRepairDatabase() : Command("repairDatabase") {} - virtual std::vector<BSONObj> stopIndexBuilds(const std::string& dbname, + virtual std::vector<BSONObj> stopIndexBuilds(Database* db, const BSONObj& cmdObj) { - std::string systemIndexes = dbname + ".system.indexes"; - BSONObj criteria = BSON("ns" << systemIndexes << "op" << "insert"); - return IndexBuilder::killMatchingIndexBuilds(criteria); + invariant(db); + std::list<std::string> collections; + db->namespaceIndex().getNamespaces(collections, true /* onlyCollections */); + + std::vector<BSONObj> allKilledIndexes; + for (std::list<std::string>::iterator it = collections.begin(); + it != collections.end(); + ++it) { + std::string ns = *it; + + IndexCatalog::IndexKillCriteria criteria; + criteria.ns = ns; + std::vector<BSONObj> killedIndexes = + IndexBuilder::killMatchingIndexBuilds(db->getCollection(ns), criteria); + allKilledIndexes.insert(allKilledIndexes.end(), + killedIndexes.begin(), + killedIndexes.end()); + } + return allKilledIndexes; } bool run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { @@ -241,7 +270,7 @@ namespace mongo { return false; } - std::vector<BSONObj> indexesInProg = stopIndexBuilds(dbname, cmdObj); + std::vector<BSONObj> indexesInProg = stopIndexBuilds(cc().database(), cmdObj); e = cmdObj.getField( "preserveClonedFilesOnFailure" ); bool preserveClonedFilesOnFailure = e.isBoolean() && e.boolean(); @@ -390,14 +419,13 @@ namespace mongo { virtual void help( stringstream& help ) const { help << "drop a collection\n{drop : <collectionName>}"; } virtual LockType locktype() const { return WRITE; } - virtual std::vector<BSONObj> stopIndexBuilds(const std::string& dbname, + virtual std::vector<BSONObj> stopIndexBuilds(Database* db, const BSONObj& cmdObj) { - std::string nsToDrop = dbname + '.' + cmdObj.firstElement().valuestr(); - std::string systemIndexes = dbname+".system.indexes"; - BSONObj criteria = BSON("ns" << systemIndexes << "op" << "insert" << - "insert.ns" << nsToDrop); + std::string nsToDrop = db->name() + '.' + cmdObj.firstElement().valuestr(); - return IndexBuilder::killMatchingIndexBuilds(criteria); + IndexCatalog::IndexKillCriteria criteria; + criteria.ns = nsToDrop; + return IndexBuilder::killMatchingIndexBuilds(db->getCollection(nsToDrop), criteria); } virtual bool run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool) { @@ -420,7 +448,7 @@ namespace mongo { int numIndexes = coll->getIndexCatalog()->numIndexesTotal(); - stopIndexBuilds(dbname, cmdObj); + stopIndexBuilds(cc().database(), cmdObj); result.append( "ns", nsToDrop ); result.append( "nIndexesWas", numIndexes ); diff --git a/src/mongo/db/index_builder.cpp b/src/mongo/db/index_builder.cpp index 4fea406b95d..cb4da4b988f 100644 --- a/src/mongo/db/index_builder.cpp +++ b/src/mongo/db/index_builder.cpp @@ -31,7 +31,6 @@ #include "mongo/db/client.h" #include "mongo/db/curop.h" #include "mongo/db/catalog/database.h" -#include "mongo/db/kill_current_op.h" #include "mongo/db/repl/rs.h" #include "mongo/util/mongoutils/str.h" @@ -84,20 +83,11 @@ namespace mongo { return status; } - std::vector<BSONObj> IndexBuilder::killMatchingIndexBuilds(const BSONObj& criteria) { - verify(Lock::somethingWriteLocked()); - std::vector<BSONObj> indexes; - CurOp* op = NULL; - while ((op = CurOp::getOp(criteria)) != NULL) { - BSONObj index = op->query(); - killCurrentOp.kill(op->opNum()); - indexes.push_back(index); - log() << "halting index build: " << index; - } - if (indexes.size() > 0) { - log() << "halted " << indexes.size() << " index build(s)" << endl; - } - return indexes; + std::vector<BSONObj> + IndexBuilder::killMatchingIndexBuilds(Collection* collection, + const IndexCatalog::IndexKillCriteria& criteria) { + invariant(collection); + return collection->getIndexCatalog()->killMatchingIndexBuilds(criteria); } void IndexBuilder::restoreIndexes(const std::vector<BSONObj>& indexes) { diff --git a/src/mongo/db/index_builder.h b/src/mongo/db/index_builder.h index 621ea8e11cf..c3d042b5cea 100644 --- a/src/mongo/db/index_builder.h +++ b/src/mongo/db/index_builder.h @@ -30,6 +30,7 @@ #include <string> +#include "mongo/db/catalog/index_catalog.h" #include "mongo/db/client.h" #include "mongo/db/jsobj.h" #include "mongo/util/background.h" @@ -39,6 +40,8 @@ */ namespace mongo { + class Collection; + class IndexBuilder : public BackgroundJob { public: IndexBuilder(const BSONObj& index); @@ -54,10 +57,13 @@ namespace mongo { Status build( Client::Context& context ) const; /** - * Kill all in-progress indexes matching criteria and, optionally, store them in the - * indexes list. + * Kill all in-progress indexes matching criteria, if non-empty: + * index ns, index name, and/or index key spec. + * Returns a vector of the indexes that were killed. */ - static std::vector<BSONObj> killMatchingIndexBuilds(const BSONObj& criteria); + static std::vector<BSONObj> + killMatchingIndexBuilds(Collection* collection, + const IndexCatalog::IndexKillCriteria& criteria); /** * Retry all index builds in the list. Builds each index in a separate thread. If ns does diff --git a/src/mongo/db/query/runner_yield_policy.h b/src/mongo/db/query/runner_yield_policy.h index 66169958db2..f1db033d093 100644 --- a/src/mongo/db/query/runner_yield_policy.h +++ b/src/mongo/db/query/runner_yield_policy.h @@ -77,6 +77,7 @@ namespace mongo { runner->collection()->cursorCache()->registerRunner( _runnerYielding ); + // Note that this call checks for interrupt, and thus can throw if interrupt flag is set staticYield(micros, record); if ( runner->collection() ) { diff --git a/src/mongo/db/structure/catalog/index_details.h b/src/mongo/db/structure/catalog/index_details.h index ef64d1487aa..8d1d39d3db0 100644 --- a/src/mongo/db/structure/catalog/index_details.h +++ b/src/mongo/db/structure/catalog/index_details.h @@ -93,9 +93,6 @@ namespace mongo { int keyPatternOffset( const string& key ) const; bool inKeyPattern( const string& key ) const { return keyPatternOffset( key ) >= 0; } - /* true if the specified key is in the index */ - bool hasKey(const BSONObj& key); - // returns name of this index's storage area (database.collection.$index) string indexNamespace() const { return indexNamespaceFromObj(info.obj()); diff --git a/src/mongo/dbtests/replsettests.cpp b/src/mongo/dbtests/replsettests.cpp index c97c77da565..b363d3f7f1e 100644 --- a/src/mongo/dbtests/replsettests.cpp +++ b/src/mongo/dbtests/replsettests.cpp @@ -206,597 +206,6 @@ namespace ReplSetTests { BackgroundSyncTest* Base::_bgsync = NULL; replset::SyncTail* Base::_tailer = NULL; - class IndexBuildThread : public BackgroundJob { - public: - IndexBuildThread(const BSONObj index) : - _done(false), _index(index.getOwned()), _client(NULL), _curop(NULL) { - } - - std::string name() const { - return "index build helper"; - } - - void run() { - std::string ns = nsToDatabase(_index.getStringField("ns"))+".system.indexes"; - - Client::initThread("in progress idx build"); - Client::WriteContext ctx(ns); - { - boost::mutex::scoped_lock lk(_mtx); - _client = currentClient.get(); - } - - // This spins to mimic the db building an index. Yield the read lock so that other - // dbs can be opened (which requires the write lock) - while (true) { - dbtemprelease temp; - sleepmillis(10); - boost::mutex::scoped_lock lk(_mtx); - if (_curop) { - if (_curop->killPendingStrict()) { - break; - } - } - } - mongo::unittest::log() << "index build ending" << endl; - killCurrentOp.notifyAllWaiters(); - cc().shutdown(); - - boost::mutex::scoped_lock lk(_mtx); - _done = true; - } - - // Make sure the test doesn't end while this "index build" is still spinning - void finish() { - while (true) { - sleepmillis(10); - boost::mutex::scoped_lock lk(_mtx); - if (_curop) break; - } - - _curop->kill(); - - while (!finished()) { - sleepmillis(10); - } - } - - bool finished() { - boost::mutex::scoped_lock lk(_mtx); - return _done; - } - - CurOp* curop() { - { - boost::mutex::scoped_lock lk(_mtx); - if (_curop != NULL) { - return _curop; - } - } - - while (true) { - sleepmillis(10); - boost::mutex::scoped_lock lk(_mtx); - if (_client) break; - } - - boost::mutex::scoped_lock lk(_mtx); - // On the first time through, make sure the curop is set up correctly - _client->curop()->reset(HostAndPort::me(), dbInsert); - _client->curop()->enter(_client->getContext()); - _client->curop()->setQuery(_index); - - - _curop = _client->curop(); - return _curop; - } - - private: - bool _done; - BSONObj _index; - Client* _client; - CurOp* _curop; - // Mutex protects all other members of this class, except _index which is - // set in the constructor and never subsequently changed - boost::mutex _mtx; - }; - - class TestDropDB : public Base { - public: - void run() { - drop(); - - std::string dbname = nsToDatabase(ns()); - Command *dropDB = Command::findCommand("dropDatabase"); - BSONObj cmdObj = BSON("dropDatabase" << 1); - - BSONObj indexOp1 = BSON("ns" << ns() << "name" << "foo_1" << "key" << - BSON("foo" << 1)); - BSONObj indexOp2 = BSON("ns" << (dbname+".something.else") << "name" << "baz_1" << - "key" << BSON("baz" << 1)); - // Different database - foo - BSONObj indexOp3 = BSON("ns" << "foo.something.else" << "name" << "baz_1" << - "key" << BSON("baz" << 1)); - // Different database - unittestsx - BSONObj indexOp4 = BSON("ns" << (dbname+"x.something.else") << "name" << "baz_1" << - "key" << BSON("baz" << 1)); - // Different database - xunittests - BSONObj indexOp5 = BSON("ns" << ("x"+dbname+".something.else") << "name" << "baz_1" << - "key" << BSON("baz" << 1)); - - IndexBuildThread t1(indexOp1); - IndexBuildThread t2(indexOp2); - IndexBuildThread t3(indexOp3); - IndexBuildThread t4(indexOp4); - IndexBuildThread t5(indexOp5); - - t1.go(); - t2.go(); - t3.go(); - t4.go(); - t5.go(); - - ASSERT(!t1.curop()->killPending()); - ASSERT(!t2.curop()->killPending()); - ASSERT(!t3.curop()->killPending()); - ASSERT(!t4.curop()->killPending()); - ASSERT(!t5.curop()->killPending()); - - { - Lock::DBWrite lk(ns()); - dropDB->stopIndexBuilds(dbname, cmdObj); - } - sleepsecs(1); - - ASSERT(t1.finished()); - ASSERT(t2.finished()); - ASSERT(!t3.finished()); - ASSERT(!t4.finished()); - ASSERT(!t5.finished()); - - t3.finish(); - t4.finish(); - t5.finish(); - } - }; - - class TestDrop : public Base { - public: - void run() { - drop(); - - std::string dbname = nsToDatabase(ns()); - Command *drop = Command::findCommand("drop"); - - BSONObj indexOp1 = BSON("ns" << ns() << "name" << "foo_1" << - "key" << BSON("foo" << 1)); - BSONObj indexOp2 = BSON("ns" << ns() << "name" << "bar_1" << - "key" << BSON("bar" << 1) << "background" << true); - // Different collection - BSONObj indexOp3 = BSON("ns" << (dbname+".something.else") << "name" << "baz_1" << - "key" << BSON("baz" << 1)); - - IndexBuildThread t1(indexOp1); - IndexBuildThread t2(indexOp2); - IndexBuildThread t3(indexOp3); - - t1.go(); - t2.go(); - t3.go(); - - ASSERT(!t1.curop()->killPending()); - ASSERT(!t2.curop()->killPending()); - ASSERT(!t3.curop()->killPending()); - - std::string coll(strchr(ns(), '.')+1); - BSONObj cmdObj = BSON("drop" << coll); - { - Lock::DBWrite lk(ns()); - drop->stopIndexBuilds(dbname, cmdObj); - } - sleepsecs(1); - - ASSERT(t1.finished()); - ASSERT(t2.finished()); - ASSERT(!t3.finished()); - - t3.finish(); - } - }; - - class TestDropIndexes : public Base { - - void testDropIndexes1() { - drop(); - - std::string dbname = nsToDatabase(ns()); - Command *c = Command::findCommand("dropIndexes"); - - BSONObj indexOp1 = BSON("ns" << ns() << "name" << "x_1" << "key" << BSON("x" << 1)); - BSONObj indexOp2 = BSON("ns" << ns() << "name" << "y_1" << "key" << BSON("y" << 1)); - BSONObj indexOp3 = BSON("ns" << ns() << "name" << "z_1" << "key" << BSON("z" << 1)); - - std::string coll(strchr(ns(), '.')+1); - BSONObj cmd1 = BSON("dropIndexes" << coll << "index" << "*"); - - IndexBuildThread t1(indexOp1); - IndexBuildThread t2(indexOp2); - IndexBuildThread t3(indexOp3); - - t1.go(); - t2.go(); - t3.go(); - - ASSERT(!t1.curop()->killPending()); - ASSERT(!t2.curop()->killPending()); - ASSERT(!t3.curop()->killPending()); - { - Lock::DBWrite lk(ns()); - c->stopIndexBuilds(dbname, cmd1); - } - sleepsecs(1); - - ASSERT(t1.finished()); - ASSERT(t2.finished()); - ASSERT(t3.finished()); - } - - void testDropIndexes2() { - drop(); - - std::string dbname = nsToDatabase(ns()); - Command *c = Command::findCommand("dropIndexes"); - - BSONObj indexOp1 = BSON("ns" << ns() << "name" << "x_1" << "key" << BSON("x" << 1)); - BSONObj indexOp2 = BSON("ns" << ns() << "name" << "y_1" << "key" << BSON("y" << 1)); - BSONObj indexOp3 = BSON("ns" << ns() << "name" << "z_1" << "key" << BSON("z" << 1)); - - std::string coll(strchr(ns(), '.')+1); - BSONObj cmd2 = BSON("dropIndexes" << coll << "index" << "y_1"); - - IndexBuildThread t1(indexOp1); - IndexBuildThread t2(indexOp2); - IndexBuildThread t3(indexOp3); - - t1.go(); - t2.go(); - t3.go(); - - ASSERT(!t1.curop()->killPending()); - ASSERT(!t2.curop()->killPending()); - ASSERT(!t3.curop()->killPending()); - { - Lock::DBWrite lk(ns()); - c->stopIndexBuilds(dbname, cmd2); - } - sleepsecs(1); - - ASSERT(!t1.finished()); - ASSERT(t2.finished()); - ASSERT(!t3.finished()); - - t1.finish(); - t3.finish(); - } - - void testDropIndexes3() { - drop(); - - std::string dbname = nsToDatabase(ns()); - std::string coll(strchr(ns(), '.')+1); - BSONObj cmd3 = BSON("dropIndexes" << coll << "index" << BSON("z" << 1)); - Command *c = Command::findCommand("dropIndexes"); - - BSONObj indexOp1 = BSON("ns" << ns() << "name" << "x_1" << "key" << BSON("x" << 1)); - BSONObj indexOp2 = BSON("ns" << ns() << "name" << "y_1" << "key" << BSON("y" << 1)); - BSONObj indexOp3 = BSON("ns" << ns() << "name" << "z_1" << "key" << BSON("z" << 1)); - - IndexBuildThread t1(indexOp1); - IndexBuildThread t2(indexOp2); - IndexBuildThread t3(indexOp3); - - t1.go(); - t2.go(); - t3.go(); - - ASSERT(!t1.curop()->killPending()); - ASSERT(!t2.curop()->killPending()); - ASSERT(!t3.curop()->killPending()); - { - Lock::DBWrite lk(ns()); - c->stopIndexBuilds(dbname, cmd3); - } - sleepsecs(1); - - ASSERT(!t1.finished()); - ASSERT(!t2.finished()); - ASSERT(t3.finished()); - - t1.finish(); - t2.finish(); - } - - public: - void run() { - testDropIndexes1(); - testDropIndexes2(); - testDropIndexes3(); - } - }; - - class TestRename : public Base { - public: - void run() { - drop(); - - std::string dbname = nsToDatabase(ns()); - std::string coll(strchr(ns(), '.')+1); - BSONObj cmdObj = BSON("renameCollection" << ns() << "to" << dbname+".bar"); - Command *c = Command::findCommand("renameCollection"); - - BSONObj indexOp1 = BSON("ns" << ns() << "name" << "x_1" << "key" << BSON("x" << 1)); - BSONObj indexOp2 = BSON("ns" << ns() << "name" << "y_1" << "key" << BSON("y" << 1)); - BSONObj indexOp3 = BSON("ns" << (dbname+".bar") << "name" << "z_1" << "key" << - BSON("z" << 1)); - BSONObj indexOp4 = BSON("ns" << ("x."+coll) << "name" << "z_1" << "key" << - BSON("z" << 1)); - - IndexBuildThread t1(indexOp1); - IndexBuildThread t2(indexOp2); - IndexBuildThread t3(indexOp3); - IndexBuildThread t4(indexOp4); - - t1.go(); - t2.go(); - t3.go(); - t4.go(); - - ASSERT(!t1.curop()->killPending()); - ASSERT(!t2.curop()->killPending()); - ASSERT(!t3.curop()->killPending()); - ASSERT(!t4.curop()->killPending()); - - std::vector<BSONObj> indexes; - { - Lock::DBWrite lk(ns()); - indexes = c->stopIndexBuilds(dbname, cmdObj); - } - - ASSERT(t1.finished()); - ASSERT(t2.finished()); - ASSERT(!t3.finished()); - ASSERT(!t4.finished()); - - t3.finish(); - t4.finish(); - - // Build indexes - IndexBuilder::restoreIndexes(indexes); - - DBDirectClient cli; - time_t max = time(0)+10; - // assert.soon - while (time(0) < max) { - std::string ns = dbname+".system.indexes"; - if (cli.count(ns) == 3) { - return; - } - }; - - ASSERT(false); - } - }; - - class TestReIndex : public Base { - public: - void run() { - drop(); - - std::string dbname = nsToDatabase(ns()); - std::string coll(strchr(ns(), '.')+1); - BSONObj cmdObj = BSON("reIndex" << coll); - Command *c = Command::findCommand("reIndex"); - - DBDirectClient cli; - int originalIndexCount = cli.count(dbname+".system.indexes"); - - BSONObj indexOp1 = BSON("ns" << ns() << "name" << "foo_1" << - "key" << BSON("foo" << 1)); - BSONObj indexOp2 = BSON("ns" << (dbname+".something.else") << "name" << "baz_1" << - "key" << BSON("baz" << 1)); - - IndexBuildThread t1(indexOp1); - IndexBuildThread t2(indexOp2); - - t1.go(); - t2.go(); - - ASSERT(!t1.curop()->killPending()); - ASSERT(!t2.curop()->killPending()); - - { - Lock::DBWrite lk(ns()); - std::vector<BSONObj> indexes = c->stopIndexBuilds(dbname, cmdObj); - ASSERT_EQUALS(1U, indexes.size()); - IndexBuilder::restoreIndexes(indexes); - } - ASSERT(!t2.finished()); - t2.finish(); - - time_t max = time(0)+10; - // assert.soon(t1.finished()) - while (time(0) < max) { - std::string ns = dbname+".system.indexes"; - if (static_cast<int>(cli.count(ns)) == originalIndexCount+2) { - return; - } - }; - - ASSERT(false); - } - }; - - class TestTruncateCapped : public Base { - public: - void run() { - drop(); - - std::string dbname = nsToDatabase(ns()); - std::string coll(strchr(ns(), '.')+1); - BSONObj cmdObj = BSON("emptycapped" << coll); - Command *c = Command::findCommand("emptycapped"); - - BSONObj indexOp1 = BSON("ns" << ns() << "name" << "foo_1" << - "key" << BSON("foo" << 1)); - BSONObj indexOp2 = BSON("ns" << (dbname+".something.else") << "name" << "baz_1" << - "key" << BSON("baz" << 1)); - - IndexBuildThread t1(indexOp1); - IndexBuildThread t2(indexOp2); - - t1.go(); - t2.go(); - - ASSERT(!t1.curop()->killPending()); - ASSERT(!t2.curop()->killPending()); - { - Lock::DBWrite lk(ns()); - c->stopIndexBuilds(dbname, cmdObj); - } - sleepsecs(1); - - ASSERT(t1.finished()); - ASSERT(!t2.finished()); - - t2.finish(); - } - }; - - class TestCompact : public Base { - public: - void run() { - drop(); - - std::string dbname = nsToDatabase(ns()); - std::string coll(strchr(ns(), '.')+1); - BSONObj cmdObj = BSON("compact" << coll); - Command *c = Command::findCommand("compact"); - DBDirectClient cli; - int originalIndexCount = cli.count(dbname+".system.indexes"); - - BSONObj indexOp1 = BSON("ns" << ns() << "name" << "foo_1" << - "key" << BSON("foo" << 1)); - BSONObj indexOp2 = BSON("ns" << (dbname+".something.else") << "name" << "baz_1" << - "key" << BSON("baz" << 1)); - - IndexBuildThread t1(indexOp1); - IndexBuildThread t2(indexOp2); - - t1.go(); - t2.go(); - - ASSERT(!t1.curop()->killPending()); - ASSERT(!t2.curop()->killPending()); - { - Lock::DBWrite lk(ns()); - std::vector<BSONObj> indexes = c->stopIndexBuilds(dbname, cmdObj); - IndexBuilder::restoreIndexes(indexes); - } - ASSERT(!t2.finished()); - t2.finish(); - - time_t max = time(0)+10; - // assert.soon(t1.finished()) - while (time(0) < max) { - std::string ns = dbname+".system.indexes"; - if (static_cast<int>(cli.count(ns)) == originalIndexCount+2) { - return; - } - }; - - ASSERT(false); - } - }; - - class TestRepair : public Base { - public: - void run() { - drop(); - - std::string dbname = nsToDatabase(ns()); - Command *c = Command::findCommand("repairDatabase"); - BSONObj cmdObj = BSON("repairDatabase" << 1); - DBDirectClient cli; - int originalIndexCount = cli.count(dbname+".system.indexes"); - - BSONObj indexOp1 = BSON("ns" << ns() << "name" << "foo_1" << "key" << - BSON("foo" << 1)); - BSONObj indexOp2 = BSON("ns" << (dbname+".something.else") << "name" << "baz_1" << - "key" << BSON("baz" << 1)); - // Different database - foo - BSONObj indexOp3 = BSON("ns" << "foo.something.else" << "name" << "baz_1" << - "key" << BSON("baz" << 1)); - // Different database - unittestsx - BSONObj indexOp4 = BSON("ns" << (dbname+"x.something.else") << "name" << "baz_1" << - "key" << BSON("baz" << 1)); - // Different database - xunittests - BSONObj indexOp5 = BSON("ns" << ("x"+dbname+".something.else") << "name" << "baz_1" << - "key" << BSON("baz" << 1)); - - IndexBuildThread t1(indexOp1); - IndexBuildThread t2(indexOp2); - IndexBuildThread t3(indexOp3); - IndexBuildThread t4(indexOp4); - IndexBuildThread t5(indexOp5); - - t1.go(); - t2.go(); - t3.go(); - t4.go(); - t5.go(); - - ASSERT(!t1.curop()->killPending()); - ASSERT(!t2.curop()->killPending()); - ASSERT(!t3.curop()->killPending()); - ASSERT(!t4.curop()->killPending()); - ASSERT(!t5.curop()->killPending()); - - std::vector<BSONObj> indexes; - { - Lock::DBWrite lk(ns()); - indexes = c->stopIndexBuilds(dbname, cmdObj); - } - sleepsecs(1); - - ASSERT(t1.finished()); - ASSERT(t2.finished()); - ASSERT(!t3.finished()); - ASSERT(!t4.finished()); - ASSERT(!t5.finished()); - - IndexBuilder::restoreIndexes(indexes); - - ASSERT(!t3.finished()); - ASSERT(!t4.finished()); - ASSERT(!t5.finished()); - - t3.finish(); - t4.finish(); - t5.finish(); - - time_t max = time(0)+10; - // assert.soon(t1.finished() && t2.finished()) - while (time(0) < max) { - std::string ns = dbname+".system.indexes"; - if (static_cast<int>(cli.count(ns)) == originalIndexCount+4) { - return; - } - }; - - ASSERT(false); - } - }; - class MockInitialSync : public replset::InitialSync { int step; public: @@ -1173,13 +582,6 @@ namespace ReplSetTests { add< CappedUpdate >(); add< CappedInsert >(); add< TestRSSync >(); - add< TestDropDB >(); - add< TestDrop >(); - add< TestDropIndexes >(); - add< TestTruncateCapped >(); - add< TestReIndex >(); - add< TestRepair >(); - add< TestCompact >(); } } myall; } |