diff options
Diffstat (limited to 'src/mongo/db/index_builds_coordinator.cpp')
-rw-r--r-- | src/mongo/db/index_builds_coordinator.cpp | 95 |
1 files changed, 54 insertions, 41 deletions
diff --git a/src/mongo/db/index_builds_coordinator.cpp b/src/mongo/db/index_builds_coordinator.cpp index 1832e2c7bb7..46ab4fc2191 100644 --- a/src/mongo/db/index_builds_coordinator.cpp +++ b/src/mongo/db/index_builds_coordinator.cpp @@ -118,7 +118,7 @@ void checkShardKeyRestrictions(OperationContext* opCtx, * bypass the index build registration. */ bool shouldBuildIndexesOnEmptyCollectionSinglePhased(OperationContext* opCtx, - Collection* collection, + const Collection* collection, IndexBuildProtocol protocol) { const auto& nss = collection->ns(); invariant(opCtx->lockState()->isCollectionLockedForMode(nss, MODE_X), str::stream() << nss); @@ -500,7 +500,8 @@ StatusWith<std::pair<long long, long long>> IndexBuildsCoordinator::rebuildIndex } auto& collectionCatalog = CollectionCatalog::get(opCtx->getServiceContext()); - Collection* collection = collectionCatalog.lookupCollectionByNamespace(opCtx, nss); + Collection* collection = + collectionCatalog.lookupCollectionByNamespaceForMetadataWrite(opCtx, nss); // Complete the index build. return _runIndexRebuildForRecovery(opCtx, collection, buildUUID, repair); @@ -526,7 +527,8 @@ Status IndexBuildsCoordinator::_startIndexBuildForRecovery(OperationContext* opC } auto& collectionCatalog = CollectionCatalog::get(opCtx->getServiceContext()); - Collection* collection = collectionCatalog.lookupCollectionByNamespace(opCtx, nss); + Collection* collection = + collectionCatalog.lookupCollectionByNamespaceForMetadataWrite(opCtx, nss); auto indexCatalog = collection->getIndexCatalog(); { // These steps are combined into a single WUOW to ensure there are no commits without @@ -647,8 +649,8 @@ Status IndexBuildsCoordinator::_setUpResumeIndexBuild(OperationContext* opCtx, Lock::CollectionLock collLock(opCtx, nssOrUuid, MODE_X); auto& collectionCatalog = CollectionCatalog::get(opCtx->getServiceContext()); - auto collection = - collectionCatalog.lookupCollectionByUUID(opCtx, resumeInfo.getCollectionUUID()); + auto collection = collectionCatalog.lookupCollectionByUUIDForMetadataWrite( + opCtx, resumeInfo.getCollectionUUID()); invariant(collection); auto durableCatalog = DurableCatalog::get(opCtx); @@ -877,12 +879,11 @@ void IndexBuildsCoordinator::applyStartIndexBuild(OperationContext* opCtx, writeConflictRetry(opCtx, "IndexBuildsCoordinator::applyStartIndexBuild", nss.ns(), [&] { WriteUnitOfWork wuow(opCtx); - AutoGetCollection autoColl(opCtx, dbAndUUID, MODE_X); - auto coll = autoColl.getCollection(); + AutoGetCollection coll(opCtx, dbAndUUID, MODE_X); invariant(coll, str::stream() << "Collection with UUID " << collUUID << " was dropped."); - IndexCatalog* indexCatalog = coll->getIndexCatalog(); + IndexCatalog* indexCatalog = coll.getWritableCollection()->getIndexCatalog(); const bool includeUnfinished = false; for (const auto& spec : oplogEntry.indexSpecs) { @@ -1315,8 +1316,8 @@ void IndexBuildsCoordinator::_completeAbort(OperationContext* opCtx, std::shared_ptr<ReplIndexBuildState> replState, IndexBuildAction signalAction, Status reason) { - auto coll = - CollectionCatalog::get(opCtx).lookupCollectionByUUID(opCtx, replState->collectionUUID); + auto coll = CollectionCatalog::get(opCtx).lookupCollectionByUUIDForMetadataWrite( + opCtx, replState->collectionUUID); const NamespaceStringOrUUID dbAndUUID(replState->dbName, replState->collectionUUID); auto nss = coll->ns(); auto replCoord = repl::ReplicationCoordinator::get(opCtx); @@ -1422,7 +1423,7 @@ void IndexBuildsCoordinator::_completeSelfAbort(OperationContext* opCtx, void IndexBuildsCoordinator::_completeAbortForShutdown( OperationContext* opCtx, std::shared_ptr<ReplIndexBuildState> replState, - Collection* collection) { + const Collection* collection) { // Leave it as-if kill -9 happened. Startup recovery will restart the index build. auto isResumable = !replState->lastOpTimeBeforeInterceptors.isNull(); _indexBuildsManager.abortIndexBuildWithoutCleanupForShutdown( @@ -1727,7 +1728,8 @@ void IndexBuildsCoordinator::createIndex(OperationContext* opCtx, const BSONObj& spec, IndexBuildsManager::IndexConstraints indexConstraints, bool fromMigrate) { - auto collection = CollectionCatalog::get(opCtx).lookupCollectionByUUID(opCtx, collectionUUID); + auto collection = + CollectionCatalog::get(opCtx).lookupCollectionByUUIDForMetadataWrite(opCtx, collectionUUID); invariant(collection, str::stream() << "IndexBuildsCoordinator::createIndexes: " << collectionUUID); auto nss = collection->ns(); @@ -1792,7 +1794,8 @@ void IndexBuildsCoordinator::createIndexesOnEmptyCollection(OperationContext* op UUID collectionUUID, const std::vector<BSONObj>& specs, bool fromMigrate) { - auto collection = CollectionCatalog::get(opCtx).lookupCollectionByUUID(opCtx, collectionUUID); + auto collection = + CollectionCatalog::get(opCtx).lookupCollectionByUUIDForMetadataWrite(opCtx, collectionUUID); invariant(collection, str::stream() << collectionUUID); invariant(collection->isEmpty(opCtx), str::stream() << collectionUUID); @@ -1961,7 +1964,7 @@ IndexBuildsCoordinator::_filterSpecsAndRegisterBuild(OperationContext* opCtx, // AutoGetCollection throws an exception if it is unable to look up the collection by UUID. NamespaceStringOrUUID nssOrUuid{dbName.toString(), collectionUUID}; AutoGetCollection autoColl(opCtx, nssOrUuid, MODE_X); - auto collection = autoColl.getCollection(); + const Collection* collection = autoColl.getCollection(); const auto& nss = collection->ns(); // Disallow index builds on drop-pending namespaces (system.drop.*) if we are primary. @@ -2047,15 +2050,12 @@ IndexBuildsCoordinator::PostSetupAction IndexBuildsCoordinator::_setUpIndexBuild const IndexBuildOptions& indexBuildOptions) { const NamespaceStringOrUUID nssOrUuid{replState->dbName, replState->collectionUUID}; - AutoGetCollection autoColl(opCtx, nssOrUuid, MODE_X); - - auto collection = autoColl.getCollection(); - const auto& nss = collection->ns(); - CollectionShardingState::get(opCtx, nss)->checkShardVersionOrThrow(opCtx); + AutoGetCollection collection(opCtx, nssOrUuid, MODE_X); + CollectionShardingState::get(opCtx, collection->ns())->checkShardVersionOrThrow(opCtx); auto replCoord = repl::ReplicationCoordinator::get(opCtx); - const bool replSetAndNotPrimary = - replCoord->getSettings().usingReplSets() && !replCoord->canAcceptWritesFor(opCtx, nss); + const bool replSetAndNotPrimary = replCoord->getSettings().usingReplSets() && + !replCoord->canAcceptWritesFor(opCtx, collection->ns()); // We will not have a start timestamp if we are newly a secondary (i.e. we started as // primary but there was a stepdown). We will be unable to timestamp the initial catalog write, @@ -2075,7 +2075,7 @@ IndexBuildsCoordinator::PostSetupAction IndexBuildsCoordinator::_setUpIndexBuild // writes a no-op just to generate an optime. onInitFn = [&](std::vector<BSONObj>& specs) { if (!(replCoord->getSettings().usingReplSets() && - replCoord->canAcceptWritesFor(opCtx, nss))) { + replCoord->canAcceptWritesFor(opCtx, collection->ns()))) { // Not primary. return Status::OK(); } @@ -2096,7 +2096,7 @@ IndexBuildsCoordinator::PostSetupAction IndexBuildsCoordinator::_setUpIndexBuild opCtx->getServiceContext()->getOpObserver()->onStartIndexBuild( opCtx, - nss, + collection->ns(), replState->collectionUUID, replState->buildUUID, replState->indexSpecs, @@ -2105,12 +2105,13 @@ IndexBuildsCoordinator::PostSetupAction IndexBuildsCoordinator::_setUpIndexBuild return Status::OK(); }; } else { - onInitFn = MultiIndexBlock::makeTimestampedIndexOnInitFn(opCtx, collection); + onInitFn = MultiIndexBlock::makeTimestampedIndexOnInitFn(opCtx, collection.getCollection()); } IndexBuildsManager::SetupOptions options; options.indexConstraints = - repl::ReplicationCoordinator::get(opCtx)->shouldRelaxIndexConstraints(opCtx, nss) + repl::ReplicationCoordinator::get(opCtx)->shouldRelaxIndexConstraints(opCtx, + collection->ns()) ? IndexBuildsManager::IndexConstraints::kRelax : IndexBuildsManager::IndexConstraints::kEnforce; options.protocol = replState->protocol; @@ -2119,8 +2120,12 @@ IndexBuildsCoordinator::PostSetupAction IndexBuildsCoordinator::_setUpIndexBuild if (!replSetAndNotPrimary) { // On standalones and primaries, call setUpIndexBuild(), which makes the initial catalog // write. On primaries, this replicates the startIndexBuild oplog entry. - uassertStatusOK(_indexBuildsManager.setUpIndexBuild( - opCtx, collection, replState->indexSpecs, replState->buildUUID, onInitFn, options)); + uassertStatusOK(_indexBuildsManager.setUpIndexBuild(opCtx, + collection.getWritableCollection(), + replState->indexSpecs, + replState->buildUUID, + onInitFn, + options)); } else { // If we are starting the index build as a secondary, we must suppress calls to write // our initial oplog entry in setUpIndexBuild(). @@ -2134,12 +2139,18 @@ IndexBuildsCoordinator::PostSetupAction IndexBuildsCoordinator::_setUpIndexBuild tsBlock.emplace(opCtx, startTimestamp); } - uassertStatusOK(_indexBuildsManager.setUpIndexBuild( - opCtx, collection, replState->indexSpecs, replState->buildUUID, onInitFn, options)); + uassertStatusOK(_indexBuildsManager.setUpIndexBuild(opCtx, + collection.getWritableCollection(), + replState->indexSpecs, + replState->buildUUID, + onInitFn, + options)); } } catch (DBException& ex) { - _indexBuildsManager.abortIndexBuild( - opCtx, collection, replState->buildUUID, MultiIndexBlock::kNoopOnCleanUpFn); + _indexBuildsManager.abortIndexBuild(opCtx, + collection.getWritableCollection(), + replState->buildUUID, + MultiIndexBlock::kNoopOnCleanUpFn); const auto& status = ex.toStatus(); if (status == ErrorCodes::IndexAlreadyExists || @@ -2294,7 +2305,7 @@ void runOnAlternateContext(OperationContext* opCtx, std::string name, Func func) void IndexBuildsCoordinator::_cleanUpSinglePhaseAfterFailure( OperationContext* opCtx, - Collection* collection, + const Collection* collection, std::shared_ptr<ReplIndexBuildState> replState, const IndexBuildOptions& indexBuildOptions, const Status& status) { @@ -2322,7 +2333,7 @@ void IndexBuildsCoordinator::_cleanUpSinglePhaseAfterFailure( void IndexBuildsCoordinator::_cleanUpTwoPhaseAfterFailure( OperationContext* opCtx, - Collection* collection, + const Collection* collection, std::shared_ptr<ReplIndexBuildState> replState, const IndexBuildOptions& indexBuildOptions, const Status& status) { @@ -2399,8 +2410,8 @@ void IndexBuildsCoordinator::_runIndexBuildInner( // dropped while the index build is still registered for the collection -- until abortIndexBuild // is called. The collection can be renamed, but it is OK for the name to be stale just for // logging purposes. - auto collection = - CollectionCatalog::get(opCtx).lookupCollectionByUUID(opCtx, replState->collectionUUID); + auto collection = CollectionCatalog::get(opCtx).lookupCollectionByUUIDForRead( + opCtx, replState->collectionUUID); invariant(collection, str::stream() << "Collection with UUID " << replState->collectionUUID << " should exist because an index build is in progress: " @@ -2423,11 +2434,12 @@ void IndexBuildsCoordinator::_runIndexBuildInner( status.isA<ErrorCategory::ShutdownError>(), str::stream() << "Unexpected error code during index build cleanup: " << status); if (IndexBuildProtocol::kSinglePhase == replState->protocol) { - _cleanUpSinglePhaseAfterFailure(opCtx, collection, replState, indexBuildOptions, status); + _cleanUpSinglePhaseAfterFailure( + opCtx, collection.get(), replState, indexBuildOptions, status); } else { invariant(IndexBuildProtocol::kTwoPhase == replState->protocol, str::stream() << replState->buildUUID); - _cleanUpTwoPhaseAfterFailure(opCtx, collection, replState, indexBuildOptions, status); + _cleanUpTwoPhaseAfterFailure(opCtx, collection.get(), replState, indexBuildOptions, status); } // Any error that escapes at this point is not fatal and can be handled by the caller. @@ -2743,8 +2755,8 @@ IndexBuildsCoordinator::CommitResult IndexBuildsCoordinator::_insertKeysFromSide } // The collection object should always exist while an index build is registered. - auto collection = - CollectionCatalog::get(opCtx).lookupCollectionByUUID(opCtx, replState->collectionUUID); + auto collection = CollectionCatalog::get(opCtx).lookupCollectionByUUIDForMetadataWrite( + opCtx, replState->collectionUUID); invariant(collection, str::stream() << "Collection not found after relocking. Index build: " << replState->buildUUID @@ -2991,7 +3003,8 @@ std::vector<std::shared_ptr<ReplIndexBuildState>> IndexBuildsCoordinator::_filte return indexBuilds; } -int IndexBuildsCoordinator::getNumIndexesTotal(OperationContext* opCtx, Collection* collection) { +int IndexBuildsCoordinator::getNumIndexesTotal(OperationContext* opCtx, + const Collection* collection) { invariant(collection); const auto& nss = collection->ns(); invariant(opCtx->lockState()->isLocked(), @@ -3006,7 +3019,7 @@ int IndexBuildsCoordinator::getNumIndexesTotal(OperationContext* opCtx, Collecti std::vector<BSONObj> IndexBuildsCoordinator::prepareSpecListForCreate( OperationContext* opCtx, - Collection* collection, + const Collection* collection, const NamespaceString& nss, const std::vector<BSONObj>& indexSpecs) { UncommittedCollections::get(opCtx).invariantHasExclusiveAccessToCollection(opCtx, |