diff options
Diffstat (limited to 'src/mongo/db/index_builder.cpp')
-rw-r--r-- | src/mongo/db/index_builder.cpp | 265 |
1 files changed, 131 insertions, 134 deletions
diff --git a/src/mongo/db/index_builder.cpp b/src/mongo/db/index_builder.cpp index 9a7927ba0b9..34cece9f97f 100644 --- a/src/mongo/db/index_builder.cpp +++ b/src/mongo/db/index_builder.cpp @@ -47,179 +47,176 @@ namespace mongo { - using std::endl; +using std::endl; - AtomicUInt32 IndexBuilder::_indexBuildCount; +AtomicUInt32 IndexBuilder::_indexBuildCount; namespace { - // Synchronization tools when replication spawns a background index in a new thread. - // The bool is 'true' when a new background index has started in a new thread but the - // parent thread has not yet synchronized with it. - bool _bgIndexStarting(false); - stdx::mutex _bgIndexStartingMutex; - stdx::condition_variable _bgIndexStartingCondVar; - - void _setBgIndexStarting() { - stdx::lock_guard<stdx::mutex> lk(_bgIndexStartingMutex); - invariant(_bgIndexStarting == false); - _bgIndexStarting = true; - _bgIndexStartingCondVar.notify_one(); - } -} // namespace +// Synchronization tools when replication spawns a background index in a new thread. +// The bool is 'true' when a new background index has started in a new thread but the +// parent thread has not yet synchronized with it. +bool _bgIndexStarting(false); +stdx::mutex _bgIndexStartingMutex; +stdx::condition_variable _bgIndexStartingCondVar; + +void _setBgIndexStarting() { + stdx::lock_guard<stdx::mutex> lk(_bgIndexStartingMutex); + invariant(_bgIndexStarting == false); + _bgIndexStarting = true; + _bgIndexStartingCondVar.notify_one(); +} +} // namespace - IndexBuilder::IndexBuilder(const BSONObj& index) : - BackgroundJob(true /* self-delete */), _index(index.getOwned()), - _name(str::stream() << "repl index builder " << _indexBuildCount.addAndFetch(1)) { - } +IndexBuilder::IndexBuilder(const BSONObj& index) + : BackgroundJob(true /* self-delete */), + _index(index.getOwned()), + _name(str::stream() << "repl index builder " << _indexBuildCount.addAndFetch(1)) {} - IndexBuilder::~IndexBuilder() {} +IndexBuilder::~IndexBuilder() {} - std::string IndexBuilder::name() const { - return _name; - } +std::string IndexBuilder::name() const { + return _name; +} - void IndexBuilder::run() { - Client::initThread(name().c_str()); - LOG(2) << "IndexBuilder building index " << _index; +void IndexBuilder::run() { + Client::initThread(name().c_str()); + LOG(2) << "IndexBuilder building index " << _index; - OperationContextImpl txn; - txn.lockState()->setIsBatchWriter(true); + OperationContextImpl txn; + txn.lockState()->setIsBatchWriter(true); - AuthorizationSession::get(txn.getClient())->grantInternalAuthorization(); + AuthorizationSession::get(txn.getClient())->grantInternalAuthorization(); - { - stdx::lock_guard<Client> lk(*txn.getClient()); - CurOp::get(txn)->setOp_inlock(dbInsert); - } - NamespaceString ns(_index["ns"].String()); + { + stdx::lock_guard<Client> lk(*txn.getClient()); + CurOp::get(txn)->setOp_inlock(dbInsert); + } + NamespaceString ns(_index["ns"].String()); - ScopedTransaction transaction(&txn, MODE_IX); - Lock::DBLock dlk(txn.lockState(), ns.db(), MODE_X); - OldClientContext ctx(&txn, ns.getSystemIndexesCollection()); + ScopedTransaction transaction(&txn, MODE_IX); + Lock::DBLock dlk(txn.lockState(), ns.db(), MODE_X); + OldClientContext ctx(&txn, ns.getSystemIndexesCollection()); - Database* db = dbHolder().get(&txn, ns.db().toString()); + Database* db = dbHolder().get(&txn, ns.db().toString()); - Status status = _build(&txn, db, true, &dlk); - if ( !status.isOK() ) { - error() << "IndexBuilder could not build index: " << status.toString(); - fassert(28555, ErrorCodes::isInterruption(status.code())); - } + Status status = _build(&txn, db, true, &dlk); + if (!status.isOK()) { + error() << "IndexBuilder could not build index: " << status.toString(); + fassert(28555, ErrorCodes::isInterruption(status.code())); } +} - Status IndexBuilder::buildInForeground(OperationContext* txn, Database* db) const { - return _build(txn, db, false, NULL); - } +Status IndexBuilder::buildInForeground(OperationContext* txn, Database* db) const { + return _build(txn, db, false, NULL); +} - void IndexBuilder::waitForBgIndexStarting() { - stdx::unique_lock<stdx::mutex> lk(_bgIndexStartingMutex); - while (_bgIndexStarting == false) { - _bgIndexStartingCondVar.wait(lk); - } - // Reset for next time. - _bgIndexStarting = false; +void IndexBuilder::waitForBgIndexStarting() { + stdx::unique_lock<stdx::mutex> lk(_bgIndexStartingMutex); + while (_bgIndexStarting == false) { + _bgIndexStartingCondVar.wait(lk); } + // Reset for next time. + _bgIndexStarting = false; +} - Status IndexBuilder::_build(OperationContext* txn, - Database* db, - bool allowBackgroundBuilding, - Lock::DBLock* dbLock) const { - const NamespaceString ns(_index["ns"].String()); +Status IndexBuilder::_build(OperationContext* txn, + Database* db, + bool allowBackgroundBuilding, + Lock::DBLock* dbLock) const { + const NamespaceString ns(_index["ns"].String()); - Collection* c = db->getCollection( ns.ns() ); - if ( !c ) { - while (true) { - try { - WriteUnitOfWork wunit(txn); - c = db->getOrCreateCollection( txn, ns.ns() ); - verify(c); - wunit.commit(); - break; - } - catch (const WriteConflictException& wce) { - LOG(2) << "WriteConflictException while creating collection in IndexBuilder" - << ", retrying."; - txn->recoveryUnit()->abandonSnapshot(); - continue; - } + Collection* c = db->getCollection(ns.ns()); + if (!c) { + while (true) { + try { + WriteUnitOfWork wunit(txn); + c = db->getOrCreateCollection(txn, ns.ns()); + verify(c); + wunit.commit(); + break; + } catch (const WriteConflictException& wce) { + LOG(2) << "WriteConflictException while creating collection in IndexBuilder" + << ", retrying."; + txn->recoveryUnit()->abandonSnapshot(); + continue; } } + } - { - stdx::lock_guard<Client> lk(*txn->getClient()); - // Show which index we're building in the curop display. - CurOp::get(txn)->setQuery_inlock(_index); - } + { + stdx::lock_guard<Client> lk(*txn->getClient()); + // Show which index we're building in the curop display. + CurOp::get(txn)->setQuery_inlock(_index); + } - bool haveSetBgIndexStarting = false; - while (true) { - Status status = Status::OK(); - try { - MultiIndexBlock indexer(txn, c); - indexer.allowInterruption(); + bool haveSetBgIndexStarting = false; + while (true) { + Status status = Status::OK(); + try { + MultiIndexBlock indexer(txn, c); + indexer.allowInterruption(); - if (allowBackgroundBuilding) - indexer.allowBackgroundBuilding(); + if (allowBackgroundBuilding) + indexer.allowBackgroundBuilding(); - try { - status = indexer.init(_index); - if ( status.code() == ErrorCodes::IndexAlreadyExists ) { - if (allowBackgroundBuilding) { - // Must set this in case anyone is waiting for this build. - _setBgIndexStarting(); - } - return Status::OK(); + try { + status = indexer.init(_index); + if (status.code() == ErrorCodes::IndexAlreadyExists) { + if (allowBackgroundBuilding) { + // Must set this in case anyone is waiting for this build. + _setBgIndexStarting(); } + return Status::OK(); + } - if (status.isOK()) { - if (allowBackgroundBuilding) { - if (!haveSetBgIndexStarting) { - _setBgIndexStarting(); - haveSetBgIndexStarting = true; - } - invariant(dbLock); - dbLock->relockWithMode(MODE_IX); + if (status.isOK()) { + if (allowBackgroundBuilding) { + if (!haveSetBgIndexStarting) { + _setBgIndexStarting(); + haveSetBgIndexStarting = true; } - - Lock::CollectionLock colLock(txn->lockState(), ns.ns(), MODE_IX); - status = indexer.insertAllDocumentsInCollection(); + invariant(dbLock); + dbLock->relockWithMode(MODE_IX); } - if (status.isOK()) { - if (allowBackgroundBuilding) { - dbLock->relockWithMode(MODE_X); - } - WriteUnitOfWork wunit(txn); - indexer.commit(); - wunit.commit(); - } - } - catch (const DBException& e) { - status = e.toStatus(); + Lock::CollectionLock colLock(txn->lockState(), ns.ns(), MODE_IX); + status = indexer.insertAllDocumentsInCollection(); } - if (allowBackgroundBuilding) { - dbLock->relockWithMode(MODE_X); - Database* reloadDb = dbHolder().get(txn, ns.db()); - fassert(28553, reloadDb); - fassert(28554, reloadDb->getCollection(ns.ns())); + if (status.isOK()) { + if (allowBackgroundBuilding) { + dbLock->relockWithMode(MODE_X); + } + WriteUnitOfWork wunit(txn); + 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(); - } + if (allowBackgroundBuilding) { + dbLock->relockWithMode(MODE_X); + Database* reloadDb = dbHolder().get(txn, ns.db()); + fassert(28553, reloadDb); + fassert(28554, reloadDb->getCollection(ns.ns())); } - catch (const WriteConflictException& wce) { - status = wce.toStatus(); + + if (status.code() == ErrorCodes::InterruptedAtShutdown) { + // leave it as-if kill -9 happened. This will be handled on restart. + indexer.abortWithoutCleanup(); } + } catch (const WriteConflictException& wce) { + status = wce.toStatus(); + } - if (status.code() != ErrorCodes::WriteConflict) - return status; + if (status.code() != ErrorCodes::WriteConflict) + return status; - LOG(2) << "WriteConflictException while creating index in IndexBuilder, retrying."; - txn->recoveryUnit()->abandonSnapshot(); - } + LOG(2) << "WriteConflictException while creating index in IndexBuilder, retrying."; + txn->recoveryUnit()->abandonSnapshot(); } } +} |