diff options
author | Eric Milkie <milkie@10gen.com> | 2014-11-04 11:19:36 -0500 |
---|---|---|
committer | Eric Milkie <milkie@10gen.com> | 2014-11-04 11:25:12 -0500 |
commit | f91d3efd69a154d46a73caf2e6b5a5f632b56061 (patch) | |
tree | cb551720094e5066931322d296854a6890d25325 /src/mongo/db/index_builder.cpp | |
parent | 072190514e64dca8e6fd36ecbb636d16b4b41263 (diff) | |
download | mongo-f91d3efd69a154d46a73caf2e6b5a5f632b56061.tar.gz |
SERVER-14860 allow bg index builds on secondaries with doc-level-locking storage engines
Diffstat (limited to 'src/mongo/db/index_builder.cpp')
-rw-r--r-- | src/mongo/db/index_builder.cpp | 43 |
1 files changed, 29 insertions, 14 deletions
diff --git a/src/mongo/db/index_builder.cpp b/src/mongo/db/index_builder.cpp index b219d78f759..42117012aa9 100644 --- a/src/mongo/db/index_builder.cpp +++ b/src/mongo/db/index_builder.cpp @@ -40,6 +40,7 @@ #include "mongo/db/catalog/index_create.h" #include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/operation_context_impl.h" +#include "mongo/util/assert_util.h" #include "mongo/util/log.h" #include "mongo/util/mongoutils/str.h" @@ -76,27 +77,29 @@ namespace mongo { Database* db = dbHolder().get(&txn, ns.db().toString()); - Status status = _build(&txn, db, true); + Status status = _build(&txn, db, true, &dlk); if ( !status.isOK() ) { error() << "IndexBuilder could not build index: " << status.toString(); + fassert(28555, ErrorCodes::isInterruption(status.code())); } txn.getClient()->shutdown(); } Status IndexBuilder::buildInForeground(OperationContext* txn, Database* db) const { - return _build(txn, db, false); + return _build(txn, db, false, NULL); } Status IndexBuilder::_build(OperationContext* txn, Database* db, - bool allowBackgroundBuilding) const { - const string ns = _index["ns"].String(); + bool allowBackgroundBuilding, + Lock::DBLock* dbLock) const { + const NamespaceString ns(_index["ns"].String()); - Collection* c = db->getCollection( txn, ns ); + Collection* c = db->getCollection( txn, ns.ns() ); if ( !c ) { WriteUnitOfWork wunit(txn); - c = db->getOrCreateCollection( txn, ns ); + c = db->getOrCreateCollection( txn, ns.ns() ); verify(c); wunit.commit(); } @@ -116,14 +119,21 @@ namespace mongo { if ( status.code() == ErrorCodes::IndexAlreadyExists ) return Status::OK(); - if (allowBackgroundBuilding) { - descriptor = indexer.registerIndexBuild(); - } + if (status.isOK()) { + if (allowBackgroundBuilding) { + descriptor = indexer.registerIndexBuild(); + invariant(dbLock); + dbLock->relockWithMode(MODE_IX); + } - if (status.isOK()) + Lock::CollectionLock colLock(txn->lockState(), ns.ns(), MODE_IX); status = indexer.insertAllDocumentsInCollection(); + } if (status.isOK()) { + if (allowBackgroundBuilding) { + dbLock->relockWithMode(MODE_X); + } WriteUnitOfWork wunit(txn); indexer.commit(); wunit.commit(); @@ -132,15 +142,20 @@ namespace mongo { catch (const DBException& e) { status = e.toStatus(); } - + + if (allowBackgroundBuilding) { + dbLock->relockWithMode(MODE_X); + Database* db = dbHolder().get(txn, ns.db()); + fassert(28553, db); + fassert(28554, db->getCollection(txn, ns.ns())); + indexer.unregisterIndexBuild(descriptor); + } + if (status.code() == ErrorCodes::InterruptedAtShutdown) { // leave it as-if kill -9 happened. This will be handled on restart. indexer.abortWithoutCleanup(); } - if (allowBackgroundBuilding) { - indexer.unregisterIndexBuild(descriptor); - } return status; } |