summaryrefslogtreecommitdiff
path: root/src/mongo/db/index_builds_coordinator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/index_builds_coordinator.cpp')
-rw-r--r--src/mongo/db/index_builds_coordinator.cpp80
1 files changed, 36 insertions, 44 deletions
diff --git a/src/mongo/db/index_builds_coordinator.cpp b/src/mongo/db/index_builds_coordinator.cpp
index b31c30b9178..8b036be359e 100644
--- a/src/mongo/db/index_builds_coordinator.cpp
+++ b/src/mongo/db/index_builds_coordinator.cpp
@@ -662,50 +662,42 @@ void IndexBuildsCoordinator::applyCommitIndexBuild(OperationContext* opCtx,
<< buildUUID,
!opCtx->recoveryUnit()->getCommitTimestamp().isNull());
- auto indexBuildsCoord = IndexBuildsCoordinator::get(opCtx);
- auto swReplState = indexBuildsCoord->_getIndexBuild(buildUUID);
- if (swReplState == ErrorCodes::NoSuchKey) {
- // If the index build was not found, we must restart the build. For some reason the index
- // build has already been aborted on this node. This is possible in certain infrequent race
- // conditions with stepdown, shutdown, and user interruption.
- // Also, it can be because, when this node was previously in
- // initial sync state and this index build was in progress on sync source. And, initial sync
- // does not start the in progress index builds.
- LOGV2(20653,
- "Could not find an active index build with UUID {buildUUID} while processing a "
- "commitIndexBuild oplog entry. Restarting the index build on "
- "collection {nss} ({collUUID}) at optime {opCtx_recoveryUnit_getCommitTimestamp}",
- "buildUUID"_attr = buildUUID,
- "nss"_attr = nss,
- "collUUID"_attr = collUUID,
- "opCtx_recoveryUnit_getCommitTimestamp"_attr =
- opCtx->recoveryUnit()->getCommitTimestamp());
-
- IndexBuildsCoordinator::IndexBuildOptions indexBuildOptions;
- indexBuildOptions.replSetAndNotPrimaryAtStart = true;
-
- // This spawns a new thread and returns immediately.
- auto fut = uassertStatusOK(indexBuildsCoord->startIndexBuild(
- opCtx,
- nss.db().toString(),
- collUUID,
- oplogEntry.indexSpecs,
- buildUUID,
- /* This oplog entry is only replicated for two-phase index builds */
- IndexBuildProtocol::kTwoPhase,
- indexBuildOptions));
-
- // In certain optimized cases that return early, the future will already be set, and the
- // index build will already have been torn-down. Any subsequent calls to look up the index
- // build will fail immediately without any error information.
- if (fut.isReady()) {
- // Throws if there were errors building the index.
- fut.get();
- return;
- }
- }
-
- auto replState = uassertStatusOK(indexBuildsCoord->_getIndexBuild(buildUUID));
+ // There is a possibility that we cannot find an active index build with the given build UUID.
+ // This can be the case when the index already exists or was dropped on the sync source before
+ // the collection was cloned during initial sync. The oplog code will ignore the NoSuchKey
+ // error code.
+ //
+ // Case 1: Index already exists:
+ // +-----------------------------------------+--------------------------------+
+ // | Sync Target | Sync Source |
+ // +-----------------------------------------+--------------------------------+
+ // | | startIndexBuild 'x' at TS: 1. |
+ // | Start oplog fetcher at TS: 2. | |
+ // | | commitIndexBuild 'x' at TS: 2. |
+ // | Begin cloning the collection. | |
+ // | Index 'x' is listed as ready, build it. | |
+ // | Finish cloning the collection. | |
+ // | Start the oplog replay phase. | |
+ // | Apply commitIndexBuild 'x'. | |
+ // | --- Index build not found --- | |
+ // +-----------------------------------------+--------------------------------+
+ //
+ // Case 2: Sync source dropped the index:
+ // +--------------------------------+--------------------------------+
+ // | Sync Target | Sync Source |
+ // +--------------------------------+--------------------------------+
+ // | | startIndexBuild 'x' at TS: 1. |
+ // | Start oplog fetcher at TS: 2. | |
+ // | | commitIndexBuild 'x' at TS: 2. |
+ // | | dropIndex 'x' at TS: 3. |
+ // | Begin cloning the collection. | |
+ // | No user indexes to build. | |
+ // | Finish cloning the collection. | |
+ // | Start the oplog replay phase. | |
+ // | Apply commitIndexBuild 'x'. | |
+ // | --- Index build not found --- | |
+ // +--------------------------------+--------------------------------+
+ auto replState = uassertStatusOK(_getIndexBuild(buildUUID));
// Retry until we are able to put the index build in the kPrepareCommit state. None of the
// conditions for retrying are common or expected to be long-lived, so we believe this to be