diff options
author | Kristina <kristina@10gen.com> | 2013-01-02 10:41:44 -0500 |
---|---|---|
committer | Kristina <kristina@10gen.com> | 2013-01-02 10:44:58 -0500 |
commit | e04a7396ea753ea6dbff89028c11ed689868d707 (patch) | |
tree | 042038ef3865de5de48df3afd18740f1d1b2c37a /src/mongo | |
parent | 43cc1547aaf72146f937d3ae72325807539a4199 (diff) | |
download | mongo-e04a7396ea753ea6dbff89028c11ed689868d707.tar.gz |
SERVER-2771 Revert command handling
This reverts commit e733331c7edb8871ba2dc58f20fbd2f40bf3adda.
This reverts commit ccf86a0fdbe7f9c9a45e8fad0410a7eef777fea2.
This reverts commit 7962e49b40c2bf344187df4c6fdd857c2255d759.
This reverts commit c5e5e6b9c0d9609234afd1390984d08f6055801b.
This reverts commit 325ec6e4d66dfdc075b47a804314eec8f7ea3eb2.
This reverts commit 283fc0d291c196232cebc8b964178037aa71f943.
This reverts commit 2f21426abe2d75487c91fb361154261969d303cd.
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/SConscript | 4 | ||||
-rw-r--r-- | src/mongo/db/cloner.cpp | 31 | ||||
-rw-r--r-- | src/mongo/db/commands.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/commands.h | 3 | ||||
-rw-r--r-- | src/mongo/db/compact.cpp | 15 | ||||
-rw-r--r-- | src/mongo/db/curop.cpp | 54 | ||||
-rw-r--r-- | src/mongo/db/curop.h | 9 | ||||
-rw-r--r-- | src/mongo/db/dbcommands.cpp | 115 | ||||
-rw-r--r-- | src/mongo/db/index_builder.cpp | 74 | ||||
-rw-r--r-- | src/mongo/db/index_builder.h | 59 | ||||
-rw-r--r-- | src/mongo/db/index_rebuilder.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/index_update.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/index_update.h | 1 | ||||
-rw-r--r-- | src/mongo/db/oplog.cpp | 14 | ||||
-rw-r--r-- | src/mongo/db/pdfile.cpp | 10 | ||||
-rw-r--r-- | src/mongo/dbtests/replsettests.cpp | 568 |
16 files changed, 39 insertions, 931 deletions
diff --git a/src/mongo/SConscript b/src/mongo/SConscript index 768bb87e336..70bb7a877df 100644 --- a/src/mongo/SConscript +++ b/src/mongo/SConscript @@ -392,7 +392,6 @@ serverOnlyFiles = [ "db/curop.cpp", "db/queryoptimizercursorimpl.cpp", "db/extsort.cpp", "db/index.cpp", - "db/index_builder.cpp", "db/index_update.cpp", "db/index_rebuilder.cpp", "db/scanandorder.cpp", @@ -411,7 +410,6 @@ serverOnlyFiles = [ "db/curop.cpp", "db/ops/update.cpp", "db/ops/update_internal.cpp", "db/dbcommands.cpp", - "db/compact.cpp", "db/dbcommands_admin.cpp", # most commands are only for mongod @@ -561,7 +559,7 @@ everythingButMongodAndMongosFiles = [ ] env.StaticLibrary("notmongodormongos", everythingButMongodAndMongosFiles) -mongodOnlyFiles = [ "db/db.cpp", "db/commands/touch.cpp" ] +mongodOnlyFiles = [ "db/db.cpp", "db/compact.cpp", "db/commands/touch.cpp" ] # ----- TARGETS ------ diff --git a/src/mongo/db/cloner.cpp b/src/mongo/db/cloner.cpp index 755cd9bbf02..43f4f457e71 100644 --- a/src/mongo/db/cloner.cpp +++ b/src/mongo/db/cloner.cpp @@ -20,16 +20,11 @@ #include "mongo/base/init.h" #include "mongo/base/status.h" -#include "mongo/bson/mutable/mutable_bson.h" -#include "mongo/bson/mutable/mutable_bson_algo.h" -#include "mongo/bson/mutable/mutable_bson_builder.h" -#include "mongo/bson/mutable/mutable_bson_heap.h" #include "mongo/bson/util/builder.h" #include "mongo/db/cloner.h" #include "mongo/db/commands.h" #include "mongo/db/commands/rename_collection.h" #include "mongo/db/db.h" -#include "mongo/db/index_builder.h" #include "mongo/db/instance.h" #include "mongo/db/jsobj.h" #include "mongo/db/kill_current_op.h" @@ -852,29 +847,6 @@ namespace mongo { virtual void help( stringstream &help ) const { help << " example: { renameCollection: foo.a, to: bar.b }"; } - - virtual std::vector<BSONObj> stopIndexBuilds(const std::string& dbname, 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); - - std::vector<BSONObj> prelim = IndexBuilder::killMatchingIndexBuilds(criteria); - std::vector<BSONObj> indexes; - - for (int i = 0; i < static_cast<int>(prelim.size()); i++) { - // Change the ns - BSONObj stripped = prelim[i].removeField("ns"); - BSONObjBuilder builder; - builder.appendElements(stripped); - builder.append("ns", target); - indexes.push_back(builder.done()); - } - - return indexes; - } - virtual bool run(const string& dbname, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { string source = cmdObj.getStringField( name.c_str() ); string target = cmdObj.getStringField( "to" ); @@ -908,12 +880,10 @@ namespace mongo { bool capped = false; long long size = 0; - std::vector<BSONObj> indexesInProg; { Client::Context ctx( source ); NamespaceDetails *nsd = nsdetails( source ); uassert( 10026 , "source namespace does not exist", nsd ); - indexesInProg = stopIndexBuilds(dbname, cmdObj); capped = nsd->isCapped(); if ( capped ) for( DiskLoc i = nsd->firstExtent; !i.isNull(); i = i.ext()->xnext ) @@ -999,7 +969,6 @@ namespace mongo { { Client::Context ctx( source ); dropCollection( source, errmsg, result ); - IndexBuilder::restoreIndexes(targetIndexes, indexesInProg); } return true; } diff --git a/src/mongo/db/commands.cpp b/src/mongo/db/commands.cpp index 399f8ac4d6c..919630d33fc 100644 --- a/src/mongo/db/commands.cpp +++ b/src/mongo/db/commands.cpp @@ -165,10 +165,6 @@ namespace mongo { help << "no help defined";
}
- std::vector<BSONObj> Command::stopIndexBuilds(const std::string& dbname, const BSONObj& cmdObj) {
- return std::vector<BSONObj>();
- }
-
Command* Command::findCommand( const string& name ) {
map<string,Command*>::iterator i = _commands->find( name );
if ( i == _commands->end() )
diff --git a/src/mongo/db/commands.h b/src/mongo/db/commands.h index dff53069471..3ae7c1d6200 100644 --- a/src/mongo/db/commands.h +++ b/src/mongo/db/commands.h @@ -154,9 +154,6 @@ namespace mongo { static map<string,Command*> * _webCommands; public: - // Stop all index builds required to run this command and return indexes killed. - virtual std::vector<BSONObj> stopIndexBuilds(const std::string& dbname, const BSONObj& cmdObj); - static const map<string,Command*>* commandsByBestName() { return _commandsByBestName; } static const map<string,Command*>* webCommands() { return _webCommands; } /** @return if command was found */ diff --git a/src/mongo/db/compact.cpp b/src/mongo/db/compact.cpp index f0045874b57..d103362c3a8 100644 --- a/src/mongo/db/compact.cpp +++ b/src/mongo/db/compact.cpp @@ -33,7 +33,6 @@ #include "mongo/db/curop-inl.h" #include "mongo/db/extsort.h" #include "mongo/db/index.h" -#include "mongo/db/index_builder.h" #include "mongo/db/index_update.h" #include "mongo/db/jsobj.h" #include "mongo/db/kill_current_op.h" @@ -366,15 +365,6 @@ namespace mongo { virtual bool requiresAuth() { return true; } CompactCmd() : Command("compact") { } - virtual std::vector<BSONObj> stopIndexBuilds(const std::string& dbname, 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); - - return IndexBuilder::killMatchingIndexBuilds(criteria); - } - virtual bool run(const string& db, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { string coll = cmdObj.firstElement().valuestr(); if( coll.empty() || db.empty() ) { @@ -425,13 +415,8 @@ namespace mongo { verify( pb >= 0 && pb <= 1024 * 1024 ); } - std::vector<BSONObj> indexesInProg = stopIndexBuilds(db, cmdObj); - bool validate = !cmdObj.hasElement("validate") || cmdObj["validate"].trueValue(); // default is true at the moment bool ok = compact(ns, errmsg, validate, result, pf, pb); - - IndexBuilder::restoreIndexes(db+".system.indexes", indexesInProg); - return ok; } }; diff --git a/src/mongo/db/curop.cpp b/src/mongo/db/curop.cpp index eab765b398c..c815f7b5623 100644 --- a/src/mongo/db/curop.cpp +++ b/src/mongo/db/curop.cpp @@ -26,9 +26,9 @@ namespace mongo { // todo : move more here - CurOp::CurOp( Client * client , CurOp * wrapped ) : - _client(client), - _wrapped(wrapped) + CurOp::CurOp( Client * client , CurOp * wrapped ) : + _client(client), + _wrapped(wrapped) { if ( _wrapped ) _client->_curOp = this; @@ -67,38 +67,6 @@ namespace mongo { _active = true; // this should be last for ui clarity } - CurOp* CurOp::getOp(const BSONObj& criteria) { - Matcher matcher(criteria); - Client& me = cc(); - - scoped_lock client_lock(Client::clientsMutex); - for (std::set<Client*>::iterator it = Client::clients.begin(); - it != Client::clients.end(); - it++) { - - Client *client = *it; - verify(client); - - CurOp* curop = client->curop(); - if (client == &me || curop == NULL) { - continue; - } - - if ( !curop->active() ) - continue; - - if ( curop->killPendingStrict() ) - continue; - - BSONObj info = curop->info(); - if (matcher.matches(info)) { - return curop; - } - } - - return NULL; - } - void CurOp::reset( const HostAndPort& remote, int op ) { reset(); if( _remote != remote ) { @@ -107,7 +75,7 @@ namespace mongo { } _op = op; } - + ProgressMeter& CurOp::setMessage(const char * msg, std::string name, unsigned long long progressMeterTotal, @@ -150,7 +118,7 @@ namespace mongo { _dbprofile = std::max( context->_db ? context->_db->getProfilingLevel() : 0 , _dbprofile ); } - + void CurOp::leave( Client::Context * context ) { } @@ -189,13 +157,13 @@ namespace mongo { if ( _client ) { b.append( "desc" , _client->desc() ); - if ( _client->_threadId.size() ) + if ( _client->_threadId.size() ) b.append( "threadId" , _client->_threadId ); if ( _client->_connectionId ) b.appendNumber( "connectionId" , _client->_connectionId ); _client->_ls.reportState(b); } - + if ( ! _message.empty() ) { if ( _progressMeter.isActive() ) { StringBuilder buf; @@ -211,9 +179,9 @@ namespace mongo { } } - if( killPending() ) + if( killPending() ) b.append("killPending", true); - + b.append( "numYields" , _numYields ); b.append( "lockStats" , _lockStat.report() ); @@ -221,12 +189,12 @@ namespace mongo { } void CurOp::setKillWaiterFlags() { - for (size_t i = 0; i < _notifyList.size(); ++i) + for (size_t i = 0; i < _notifyList.size(); ++i) *(_notifyList[i]) = true; _notifyList.clear(); } - void CurOp::kill(bool* pNotifyFlag /* = NULL */) { + void CurOp::kill(bool* pNotifyFlag /* = NULL */) { _killPending.store(1); if (pNotifyFlag) { _notifyList.push_back(pNotifyFlag); diff --git a/src/mongo/db/curop.h b/src/mongo/db/curop.h index 04c916119b9..8721484b684 100644 --- a/src/mongo/db/curop.h +++ b/src/mongo/db/curop.h @@ -245,15 +245,6 @@ namespace mongo { LockStat& lockStat() { return _lockStat; } void setKillWaiterFlags(); - - /** - * Find a currently running operation matching the given criteria. This assumes that you're - * going to kill the operation, so it must be called multiple times to get multiple matching - * operations. - * @param criteria the search to do against the infoNoauth() BSONObj - * @return a pointer to a matching op or NULL if no ops match - */ - static CurOp* getOp(const BSONObj& criteria); private: friend class Client; void _reset(); diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp index 52d268681eb..c1961a2f896 100644 --- a/src/mongo/db/dbcommands.cpp +++ b/src/mongo/db/dbcommands.cpp @@ -37,7 +37,6 @@ #include "mongo/db/commands.h" #include "mongo/db/db.h" #include "mongo/db/dur_stats.h" -#include "mongo/db/index_builder.h" #include "mongo/db/index_update.h" #include "mongo/db/instance.h" #include "mongo/db/introspect.h" @@ -371,16 +370,6 @@ namespace mongo { virtual bool lockGlobally() const { return true; } virtual LockType locktype() const { return WRITE; } - - virtual std::vector<BSONObj> stopIndexBuilds(const std::string& dbname, 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); - } - CmdDropDatabase() : Command("dropDatabase") {} bool run(const string& dbname, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { // disallow dropping the config database @@ -393,7 +382,6 @@ namespace mongo { int p = (int) e.number(); if ( p != 1 ) return false; - stopIndexBuilds(dbname, cmdObj); dropDatabase(dbname); result.append( "dropped" , dbname ); log() << "dropDatabase " << dbname << " finished" << endl; @@ -424,36 +412,19 @@ namespace mongo { out->push_back(Privilege(dbname, actions)); } CmdRepairDatabase() : Command("repairDatabase") {} - - virtual std::vector<BSONObj> stopIndexBuilds(const std::string& dbname, const BSONObj& cmdObj) { - std::string systemIndexes = dbname+".system.indexes"; - BSONObj criteria = BSON("ns" << systemIndexes << "op" << "insert"); - return IndexBuilder::killMatchingIndexBuilds(criteria); - } - bool run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { BSONElement e = cmdObj.firstElement(); log() << "repairDatabase " << dbname << endl; int p = (int) e.number(); - - std::vector<BSONObj> indexesInProg; if ( p != 1 ) { errmsg = "bad option"; return false; } - - std::vector<BSONObj> indexes = stopIndexBuilds(dbname, cmdObj); - e = cmdObj.getField( "preserveClonedFilesOnFailure" ); bool preserveClonedFilesOnFailure = e.isBoolean() && e.boolean(); e = cmdObj.getField( "backupOriginalFiles" ); bool backupOriginalFiles = e.isBoolean() && e.boolean(); - bool ok = - repairDatabase( dbname, errmsg, preserveClonedFilesOnFailure, backupOriginalFiles ); - - IndexBuilder::restoreIndexes(dbname+".system.indexes", indexesInProg); - - return ok; + return repairDatabase( dbname, errmsg, preserveClonedFilesOnFailure, backupOriginalFiles ); } } cmdRepairDatabase; @@ -584,16 +555,6 @@ 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, 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); - - return IndexBuilder::killMatchingIndexBuilds(criteria); - } - virtual bool run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool) { string nsToDrop = dbname + '.' + cmdObj.firstElement().valuestr(); NamespaceDetails *d = nsdetails(nsToDrop); @@ -603,12 +564,7 @@ namespace mongo { errmsg = "ns not found"; return false; } - - uassert(10039, "can't drop collection with reserved $ character in name", - strchr(nsToDrop.c_str(), '$') == 0); - - stopIndexBuilds(dbname, cmdObj); - + uassert( 10039 , "can't drop collection with reserved $ character in name", strchr(nsToDrop.c_str(), '$') == 0 ); dropCollection( nsToDrop, errmsg, result ); return true; } @@ -730,41 +686,6 @@ namespace mongo { actions.addAction(ActionType::dropIndexes); out->push_back(Privilege(parseNs(dbname, cmdObj), actions)); } - - virtual std::vector<BSONObj> stopIndexBuilds(const std::string& dbname, 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); - - // Get index name to drop - BSONElement toDrop = cmdObj.getField("index"); - - if (toDrop.type() == String) { - // Kill all in-progress indexes - if (strcmp("*", toDrop.valuestr()) == 0) { - BSONObj criteria = builder.done(); - return IndexBuilder::killMatchingIndexBuilds(criteria); - } - // Kill an in-progress index by name - else { - builder.append("insert.name", toDrop.valuestr()); - BSONObj criteria = builder.done(); - return IndexBuilder::killMatchingIndexBuilds(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); - } - - return std::vector<BSONObj>(); - } - CmdDropIndexes() : Command("dropIndexes", false, "deleteIndexes") { } bool run(const string& dbname, BSONObj& jsobj, int, string& errmsg, BSONObjBuilder& anObjBuilder, bool /*fromRepl*/) { BSONElement e = jsobj.firstElement(); @@ -773,8 +694,6 @@ namespace mongo { if ( !cmdLine.quiet ) tlog() << "CMD: dropIndexes " << toDeleteNs << endl; if ( d ) { - stopIndexBuilds(dbname, jsobj); - BSONElement f = jsobj.getField("index"); if ( f.type() == String ) { return dropIndexes( d, toDeleteNs.c_str(), f.valuestr(), errmsg, anObjBuilder, false ); @@ -820,15 +739,6 @@ namespace mongo { out->push_back(Privilege(parseNs(dbname, cmdObj), actions)); } CmdReIndex() : Command("reIndex") { } - - virtual std::vector<BSONObj> stopIndexBuilds(const std::string& dbname, 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); - } - bool run(const string& dbname , BSONObj& jsobj, int, string& errmsg, BSONObjBuilder& result, bool /*fromRepl*/) { static DBDirectClient db; @@ -843,9 +753,6 @@ namespace mongo { return false; } - std::vector<BSONObj> indexesInProg; - stopIndexBuilds(dbname, jsobj); - list<BSONObj> all; auto_ptr<DBClientCursor> i = db.query( dbname + ".system.indexes" , BSON( "ns" << toDeleteNs ) , 0 , 0 , 0 , QueryOption_SlaveOk ); BSONObjBuilder b; @@ -872,8 +779,6 @@ namespace mongo { result.append( "nIndexes" , (int)all.size() ); result.appendArray( "indexes" , b.obj() ); - - IndexBuilder::restoreIndexes(dbname+".system.indexes", indexesInProg); return true; } } cmdReIndex; @@ -1939,29 +1844,13 @@ namespace mongo { virtual void addRequiredPrivileges(const std::string& dbname, const BSONObj& cmdObj, std::vector<Privilege>* out) {} - - virtual std::vector<BSONObj> stopIndexBuilds(const std::string& dbname, 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); - - return IndexBuilder::killMatchingIndexBuilds(criteria); - } - virtual bool run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool) { string coll = cmdObj[ "emptycapped" ].valuestrsafe(); uassert( 13428, "emptycapped must specify a collection", !coll.empty() ); string ns = dbname + "." + coll; NamespaceDetails *nsd = nsdetails( ns ); massert( 13429, "emptycapped no such collection", nsd ); - - std::vector<BSONObj> indexes = stopIndexBuilds(dbname, cmdObj); - nsd->emptyCappedCollection( ns.c_str() ); - - IndexBuilder::restoreIndexes(dbname+".system.indexes", indexes); - return true; } }; diff --git a/src/mongo/db/index_builder.cpp b/src/mongo/db/index_builder.cpp deleted file mode 100644 index 090fbcd4508..00000000000 --- a/src/mongo/db/index_builder.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Copyright (C) 2012 10gen Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "mongo/db/index_builder.h" - -#include "mongo/db/client.h" -#include "mongo/db/kill_current_op.h" -#include "mongo/db/repl/rs.h" -#include "mongo/util/mongoutils/str.h" - -namespace mongo { - - AtomicUInt IndexBuilder::_indexBuildCount = 0; - - IndexBuilder::IndexBuilder(const std::string ns, const BSONObj index) : - BackgroundJob(true /* self-delete */), _ns(ns), _index(index.getOwned()), - _name(str::stream() << "repl index builder " << (_indexBuildCount++).get()) { - } - - IndexBuilder::~IndexBuilder() {} - - std::string IndexBuilder::name() const { - return _name; - } - - void IndexBuilder::run() { - LOG(2) << "building index " << _index << " on " << _ns << endl; - Client::initThread(name().c_str()); - replLocalAuth(); - - Client::WriteContext ctx(_ns); - build(); - - cc().shutdown(); - } - - void IndexBuilder::build() const { - theDataFileMgr.insert(_ns.c_str(), _index.objdata(), _index.objsize(), - true /* mayInterrupt */); - } - - std::vector<BSONObj> IndexBuilder::killMatchingIndexBuilds(const BSONObj& criteria) { - std::vector<BSONObj> indexes; - CurOp* op = NULL; - while ((op = CurOp::getOp(criteria)) != NULL) { - BSONObj index = op->query(); - killCurrentOp.blockingKill(op->opNum()); - indexes.push_back(index); - } - return indexes; - } - - void IndexBuilder::restoreIndexes(const std::string& ns, const std::vector<BSONObj>& indexes) { - for (int i = 0; i < static_cast<int>(indexes.size()); i++) { - IndexBuilder* indexBuilder = new IndexBuilder(ns, indexes[i]); - // This looks like a memory leak, but indexBuilder deletes itself when it finishes - indexBuilder->go(); - } - } -} - diff --git a/src/mongo/db/index_builder.h b/src/mongo/db/index_builder.h deleted file mode 100644 index 0b5de273c84..00000000000 --- a/src/mongo/db/index_builder.h +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Copyright (C) 2012 10gen Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#pragma once - -#include <string> - -#include "mongo/db/jsobj.h" -#include "mongo/util/background.h" - -/** - * Forks off a thread to build an index. - */ -namespace mongo { - - class IndexBuilder : public BackgroundJob { - public: - IndexBuilder(const std::string ns, const BSONObj index); - virtual ~IndexBuilder(); - - virtual void run(); - virtual std::string name() const; - - void build() const; - - /** - * Kill all in-progress indexes matching criteria and, optionally, store them in the - * indexes list. - */ - static std::vector<BSONObj> killMatchingIndexBuilds(const BSONObj& criteria); - - /** - * Retry all index builds in the list. Builds each index in a separate thread. If ns does - * not match the ns field in the indexes list, the BSONObj's ns field is changed before the - * index is built (to handle rename). - */ - static void restoreIndexes(const std::string& ns, const std::vector<BSONObj>& indexes); - - private: - const std::string _ns; - const BSONObj _index; - std::string _name; - static AtomicUInt _indexBuildCount; - }; - -} diff --git a/src/mongo/db/index_rebuilder.cpp b/src/mongo/db/index_rebuilder.cpp index 72e79ebc8df..716c582f0d5 100644 --- a/src/mongo/db/index_rebuilder.cpp +++ b/src/mongo/db/index_rebuilder.cpp @@ -107,6 +107,11 @@ namespace mongo { // forever. Thus, we're assuming no journaling will happen between now and the entry being // re-written. + // We need to force a foreground index build to prevent replication from replaying an + // incompatible op (like a drop) during a yield. + // TODO: once commands can interrupt/wait for index builds, this can be removed. + indexObj = indexObj.removeField("background"); + try { const std::string ns = dbName + ".system.indexes"; theDataFileMgr.insert(ns.c_str(), indexObj.objdata(), indexObj.objsize(), false, true); diff --git a/src/mongo/db/index_update.cpp b/src/mongo/db/index_update.cpp index 815f600afcd..c38a3ccf4c7 100644 --- a/src/mongo/db/index_update.cpp +++ b/src/mongo/db/index_update.cpp @@ -548,10 +548,8 @@ namespace mongo { void buildAnIndex(const std::string& ns, NamespaceDetails* d, IndexDetails& idx, + bool background, bool mayInterrupt) { - - bool background = idx.info.obj()["background"].trueValue(); - tlog() << "build index " << ns << ' ' << idx.keyPattern() << ( background ? " background" : "" ) << endl; Timer t; unsigned long long n; diff --git a/src/mongo/db/index_update.h b/src/mongo/db/index_update.h index d0f3bd0608e..ad71d293ce0 100644 --- a/src/mongo/db/index_update.h +++ b/src/mongo/db/index_update.h @@ -34,6 +34,7 @@ namespace mongo { void buildAnIndex(const std::string& ns, NamespaceDetails *d, IndexDetails& idx, + bool background, bool mayInterrupt); // add index keys for a newly inserted record diff --git a/src/mongo/db/oplog.cpp b/src/mongo/db/oplog.cpp index 15f9bfc40ee..aee37a521a7 100644 --- a/src/mongo/db/oplog.cpp +++ b/src/mongo/db/oplog.cpp @@ -26,7 +26,6 @@ #include "mongo/db/auth/action_type.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/commands.h" -#include "mongo/db/index_builder.h" #include "mongo/db/index_update.h" #include "mongo/db/instance.h" #include "mongo/db/ops/update.h" @@ -767,16 +766,9 @@ namespace mongo { const char *p = strchr(ns, '.'); if ( p && strcmp(p, ".system.indexes") == 0 ) { - if (o["background"].trueValue()) { - IndexBuilder* builder = new IndexBuilder(ns, o); - // This spawns a new thread and returns immediately. - builder->go(); - } - else { - IndexBuilder builder(ns, o); - // Finish the foreground build before returning - builder.build(); - } + // updates aren't allowed for indexes -- so we will do a regular insert. if index already + // exists, that is ok. + theDataFileMgr.insert(ns, (void*) o.objdata(), o.objsize()); } else { // do upserts for inserts as we might get replayed more than once diff --git a/src/mongo/db/pdfile.cpp b/src/mongo/db/pdfile.cpp index 3872e83ea57..086ca11c15d 100644 --- a/src/mongo/db/pdfile.cpp +++ b/src/mongo/db/pdfile.cpp @@ -1428,6 +1428,14 @@ namespace mongo { uassert( 13143 , "can't create index on system.indexes" , tabletoidxns.find( ".system.indexes" ) == string::npos ); BSONObj info = loc.obj(); + bool background = info["background"].trueValue(); + if (background && !isMasterNs(tabletoidxns.c_str())) { + /* don't do background indexing on slaves. there are nuances. this could be added later + but requires more code. + */ + log() << "info: indexing in foreground on this replica; was a background index build on the primary" << endl; + background = false; + } // The total number of indexes right before we write to the collection int oldNIndexes = -1; @@ -1449,7 +1457,7 @@ namespace mongo { try { getDur().writingInt(tableToIndex->indexBuildsInProgress) += 1; - buildAnIndex(tabletoidxns, tableToIndex, idx, mayInterrupt); + buildAnIndex(tabletoidxns, tableToIndex, idx, background, mayInterrupt); } catch (DBException& e) { // save our error msg string as an exception or dropIndexes will overwrite our message diff --git a/src/mongo/dbtests/replsettests.cpp b/src/mongo/dbtests/replsettests.cpp index 6d5fe966a34..f3afd5870e1 100644 --- a/src/mongo/dbtests/replsettests.cpp +++ b/src/mongo/dbtests/replsettests.cpp @@ -18,19 +18,17 @@ */ #include "pch.h" +#include "../db/repl.h" + +#include "../db/db.h" +#include "../db/instance.h" +#include "../db/json.h" #include "dbtests.h" +#include "../db/oplog.h" -#include "mongo/db/db.h" -#include "mongo/db/index_builder.h" -#include "mongo/db/instance.h" -#include "mongo/db/json.h" -#include "mongo/db/kill_current_op.h" -#include "mongo/db/oplog.h" -#include "mongo/db/repl.h" #include "mongo/db/repl/rs.h" #include "mongo/db/repl/bgsync.h" -#include "mongo/util/time_support.h" namespace mongo { void createOplog(); @@ -177,553 +175,6 @@ namespace ReplSetTests { DBDirectClient Base::client_; - 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); - _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 (!_curop || !_curop->killPendingStrict()) { - dbtemprelease temp; - sleepmillis(0); - } - - killCurrentOp.notifyAllWaiters(); - cc().shutdown(); - _done = true; - } - - // Make sure the test doesn't end while this "index build" is still spinning - void finish() { - while (!_curop) { - sleepmillis(0); - } - - _curop->kill(); - - while (!_done) { - sleepmillis(0); - } - } - - bool finished() { - return _done; - } - - CurOp* curop() { - if (_curop != NULL) { - return _curop; - } - - while (_client == NULL) { - sleepmillis(0); - } - - // 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; - }; - - 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()); - - 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); - 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()); - - 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()); - - 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()); - - 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 = c->stopIndexBuilds(dbname, cmdObj); - - ASSERT(t1.finished()); - ASSERT(t2.finished()); - ASSERT(!t3.finished()); - ASSERT(!t4.finished()); - - t3.finish(); - t4.finish(); - - // Build indexes - IndexBuilder::restoreIndexes(dbname+".system.indexes", 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()); - - std::vector<BSONObj> indexes = c->stopIndexBuilds(dbname, cmdObj); - ASSERT_EQUALS(1U, indexes.size()); - IndexBuilder::restoreIndexes(dbname+".system.indexes", 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()); - - 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()); - - std::vector<BSONObj> indexes = c->stopIndexBuilds(dbname, cmdObj); - IndexBuilder::restoreIndexes(dbname+".system.indexes", 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 = c->stopIndexBuilds(dbname, cmdObj); - - sleepsecs(1); - - ASSERT(t1.finished()); - ASSERT(t2.finished()); - ASSERT(!t3.finished()); - ASSERT(!t4.finished()); - ASSERT(!t5.finished()); - - IndexBuilder::restoreIndexes(dbname+".system.indexes", 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: @@ -1097,13 +548,6 @@ namespace ReplSetTests { add< CappedUpdate >(); add< CappedInsert >(); add< TestRSSync >(); - add< TestDropDB >(); - add< TestDrop >(); - add< TestDropIndexes >(); - add< TestTruncateCapped >(); - add< TestReIndex >(); - add< TestRepair >(); - add< TestCompact >(); } } myall; } |