summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/db/catalog/index_catalog.cpp74
-rw-r--r--src/mongo/db/catalog/index_catalog.h19
-rw-r--r--src/mongo/db/catalog/index_create.cpp13
-rw-r--r--src/mongo/db/commands.cpp2
-rw-r--r--src/mongo/db/commands.h5
-rw-r--r--src/mongo/db/commands/collection_to_capped.cpp15
-rw-r--r--src/mongo/db/commands/compact.cpp12
-rw-r--r--src/mongo/db/commands/drop_indexes.cpp40
-rw-r--r--src/mongo/db/commands/rename_collection.cpp11
-rw-r--r--src/mongo/db/commands/test_commands.cpp12
-rw-r--r--src/mongo/db/dbcommands.cpp68
-rw-r--r--src/mongo/db/index_builder.cpp20
-rw-r--r--src/mongo/db/index_builder.h12
-rw-r--r--src/mongo/db/query/runner_yield_policy.h1
-rw-r--r--src/mongo/db/structure/catalog/index_details.h3
-rw-r--r--src/mongo/dbtests/replsettests.cpp598
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;
}