diff options
author | Mathias Stearn <mathias@10gen.com> | 2014-07-30 17:34:46 -0400 |
---|---|---|
committer | Mathias Stearn <mathias@10gen.com> | 2014-08-13 17:30:25 -0400 |
commit | 00913e47de5aced5267e44e82ac9e976bbaac089 (patch) | |
tree | 26002b9f1eb4e7b3f295bd2a4cf24a68aa13cad3 /src/mongo/db/index_builder.cpp | |
parent | c610cfe5c58d1f4301f5535d3e166d5d4332bc87 (diff) | |
download | mongo-00913e47de5aced5267e44e82ac9e976bbaac089.tar.gz |
SERVER-13951 Split index building in to UnitOfWork-sized stages
All index builds now go through the MultiIndexBuilder as its API was already
close to ideal. The following tickets have also been addressed by this commit:
SERVER-14710 Remove dropDups
SERVER-12309 Cloner build indexes in parallel
SERVER-14737 Initial sync uses bg index building
SERVER-9135 fast index build for initial sync
SERVER-2747 can't kill index in phase 2
SERVER-8917 check error code rather than assuming all errors are dups
SERVER-14820 compact enforces unique while claiming not to
SERVER-14746 IndexRebuilder should be foreground and fail fatally
Diffstat (limited to 'src/mongo/db/index_builder.cpp')
-rw-r--r-- | src/mongo/db/index_builder.cpp | 49 |
1 files changed, 41 insertions, 8 deletions
diff --git a/src/mongo/db/index_builder.cpp b/src/mongo/db/index_builder.cpp index 5398c5f3b5c..d2ba234e5ee 100644 --- a/src/mongo/db/index_builder.cpp +++ b/src/mongo/db/index_builder.cpp @@ -36,6 +36,7 @@ #include "mongo/db/curop.h" #include "mongo/db/catalog/database.h" #include "mongo/db/catalog/database_holder.h" +#include "mongo/db/catalog/index_create.h" #include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/repl/rs.h" #include "mongo/db/operation_context_impl.h" @@ -73,7 +74,7 @@ namespace mongo { Database* db = dbHolder().get(&txn, ns.db().toString()); - Status status = build(&txn, db); + Status status = build(&txn, db, true); if ( !status.isOK() ) { log() << "IndexBuilder could not build index: " << status.toString(); } @@ -82,24 +83,56 @@ namespace mongo { cc().shutdown(); } - Status IndexBuilder::build(OperationContext* txn, Database* db) const { + Status IndexBuilder::buildInForeground(OperationContext* txn, Database* db) const { + return build(txn, db, false); + } + + Status IndexBuilder::build(OperationContext* txn, + Database* db, + bool allowBackgroundBuilding) const { const string ns = _index["ns"].String(); Collection* c = db->getCollection( txn, ns ); if ( !c ) { + WriteUnitOfWork wunit(txn->recoveryUnit()); c = db->getOrCreateCollection( txn, ns ); verify(c); + wunit.commit(); } // Show which index we're building in the curop display. txn->getCurOp()->setQuery(_index); - Status status = c->getIndexCatalog()->createIndex( txn, - _index, - true, - IndexCatalog::SHUTDOWN_LEAVE_DIRTY ); - if ( status.code() == ErrorCodes::IndexAlreadyExists ) - return Status::OK(); + + MultiIndexBlock indexer(txn, c); + indexer.allowInterruption(); + if (allowBackgroundBuilding) + indexer.allowBackgroundBuilding(); + + Status status = Status::OK(); + try { + status = indexer.init(_index); + if ( status.code() == ErrorCodes::IndexAlreadyExists ) + return Status::OK(); + + if (status.isOK()) + status = indexer.insertAllDocumentsInCollection(); + + if (status.isOK()) { + WriteUnitOfWork wunit(txn->recoveryUnit()); + indexer.commit(); + wunit.commit(); + } + } + catch (const DBException& e) { + status = e.toStatus(); + } + + if (status.code() == ErrorCodes::InterruptedAtShutdown) { + // leave it as-if kill -9 happened. This will be handled on restart. + indexer.abortWithoutCleanup(); + } + return status; } |