summaryrefslogtreecommitdiff
path: root/src/mongo/db/index_builder.cpp
diff options
context:
space:
mode:
authorMathias Stearn <mathias@10gen.com>2014-07-30 17:34:46 -0400
committerMathias Stearn <mathias@10gen.com>2014-08-13 17:30:25 -0400
commit00913e47de5aced5267e44e82ac9e976bbaac089 (patch)
tree26002b9f1eb4e7b3f295bd2a4cf24a68aa13cad3 /src/mongo/db/index_builder.cpp
parentc610cfe5c58d1f4301f5535d3e166d5d4332bc87 (diff)
downloadmongo-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.cpp49
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;
}