diff options
-rw-r--r-- | src/mongo/db/index_builds_coordinator.cpp | 37 | ||||
-rw-r--r-- | src/mongo/db/repl_index_build_state.cpp | 39 | ||||
-rw-r--r-- | src/mongo/db/repl_index_build_state.h | 7 |
3 files changed, 47 insertions, 36 deletions
diff --git a/src/mongo/db/index_builds_coordinator.cpp b/src/mongo/db/index_builds_coordinator.cpp index f220b3a18a3..497e954be10 100644 --- a/src/mongo/db/index_builds_coordinator.cpp +++ b/src/mongo/db/index_builds_coordinator.cpp @@ -1746,42 +1746,7 @@ Status IndexBuildsCoordinator::_registerIndexBuild( std::find(existingIndexBuild->indexNames.begin(), existingIndexBuild->indexNames.end(), name)) { - - str::stream ss; - ss << "Index build conflict: " << replIndexBuildState->buildUUID - << ": There's already an index with name '" << name - << "' being built on the collection " - << " ( " << replIndexBuildState->collectionUUID - << " ) under an existing index build: " << existingIndexBuild->buildUUID; - auto aborted = false; - IndexBuildState existingIndexBuildState; - { - // We have to lock the mutex in order to read the committed/aborted state. - stdx::unique_lock<Latch> lkExisting(existingIndexBuild->mutex); - existingIndexBuildState = existingIndexBuild->indexBuildState; - } - ss << " index build state: " << existingIndexBuildState.toString(); - if (auto ts = existingIndexBuildState.getTimestamp()) { - ss << ", timestamp: " << ts->toString(); - } - if (existingIndexBuildState.isAborted()) { - if (auto abortReason = existingIndexBuildState.getAbortReason()) { - ss << ", abort reason: " << abortReason.get(); - } - aborted = true; - } - std::string msg = ss; - LOGV2(20661, - "Index build conflict. There's already an index with the same name being " - "built under an existing index build", - "buildUUID"_attr = replIndexBuildState->buildUUID, - "existingBuildUUID"_attr = existingIndexBuild->buildUUID, - "index"_attr = name, - "collectionUUID"_attr = replIndexBuildState->collectionUUID); - if (aborted) { - return {ErrorCodes::IndexBuildAborted, msg}; - } - return Status(ErrorCodes::IndexBuildAlreadyInProgress, msg); + return existingIndexBuild->onConflictWithNewIndexBuild(*replIndexBuildState, name); } } } diff --git a/src/mongo/db/repl_index_build_state.cpp b/src/mongo/db/repl_index_build_state.cpp index 1bcf3786ec5..cac5c6992d1 100644 --- a/src/mongo/db/repl_index_build_state.cpp +++ b/src/mongo/db/repl_index_build_state.cpp @@ -379,6 +379,45 @@ boost::optional<IndexBuildAction> ReplIndexBuildState::getNextActionNoWait() con return future.get(); } +Status ReplIndexBuildState::onConflictWithNewIndexBuild(const ReplIndexBuildState& otherIndexBuild, + const std::string& otherIndexName) const { + str::stream ss; + ss << "Index build conflict: " << otherIndexBuild.buildUUID + << ": There's already an index with name '" << otherIndexName + << "' being built on the collection " + << " ( " << otherIndexBuild.collectionUUID + << " ) under an existing index build: " << buildUUID; + auto aborted = false; + IndexBuildState existingIndexBuildState; + { + // We have to lock the mutex in order to read the committed/aborted state. + stdx::unique_lock<Latch> lk(mutex); + existingIndexBuildState = indexBuildState; + } + ss << " index build state: " << existingIndexBuildState.toString(); + if (auto ts = existingIndexBuildState.getTimestamp()) { + ss << ", timestamp: " << ts->toString(); + } + if (existingIndexBuildState.isAborted()) { + if (auto abortReason = existingIndexBuildState.getAbortReason()) { + ss << ", abort reason: " << abortReason.get(); + } + aborted = true; + } + std::string msg = ss; + LOGV2(20661, + "Index build conflict. There's already an index with the same name being " + "built under an existing index build", + "buildUUID"_attr = otherIndexBuild.buildUUID, + "existingBuildUUID"_attr = buildUUID, + "index"_attr = otherIndexName, + "collectionUUID"_attr = otherIndexBuild.collectionUUID); + if (aborted) { + return {ErrorCodes::IndexBuildAborted, msg}; + } + return Status(ErrorCodes::IndexBuildAlreadyInProgress, msg); +} + bool ReplIndexBuildState::isResumable() const { stdx::unique_lock<Latch> lk(mutex); return !_lastOpTimeBeforeInterceptors.isNull(); diff --git a/src/mongo/db/repl_index_build_state.h b/src/mongo/db/repl_index_build_state.h index 6777b1078fd..9bac45a6edc 100644 --- a/src/mongo/db/repl_index_build_state.h +++ b/src/mongo/db/repl_index_build_state.h @@ -343,6 +343,13 @@ public: boost::optional<IndexBuildAction> getNextActionNoWait() const; /** + * Called when we are trying to add a new index build 'other' that conflicts with this one. + * Returns a status that reflects whether this index build has been aborted or still active. + */ + Status onConflictWithNewIndexBuild(const ReplIndexBuildState& otherIndexBuild, + const std::string& otherIndexName) const; + + /** * Accessor and mutator for last optime in the oplog before the interceptors were installed. * This supports resumable index builds. */ |