diff options
author | Benety Goh <benety@mongodb.com> | 2019-11-08 16:25:40 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2019-11-08 16:25:40 +0000 |
commit | 02cef2152d32e04f6f8149dd7923f977b417ffb2 (patch) | |
tree | 3a000b043cd51f21b6fd29e018713cbb315dbdcc /src/mongo/db | |
parent | 4b92498a94f42790d2f6a3f26a965acb1de4702f (diff) | |
download | mongo-02cef2152d32e04f6f8149dd7923f977b417ffb2.tar.gz |
SERVER-44393 split IndexBuildsCoordinator::_buildIndex() into hybrid index build phases
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/index_builds_coordinator.cpp | 48 | ||||
-rw-r--r-- | src/mongo/db/index_builds_coordinator.h | 49 |
2 files changed, 97 insertions, 0 deletions
diff --git a/src/mongo/db/index_builds_coordinator.cpp b/src/mongo/db/index_builds_coordinator.cpp index aea56abc00b..a1bed562111 100644 --- a/src/mongo/db/index_builds_coordinator.cpp +++ b/src/mongo/db/index_builds_coordinator.cpp @@ -1248,6 +1248,22 @@ void IndexBuildsCoordinator::_buildIndex( std::shared_ptr<ReplIndexBuildState> replState, const IndexBuildOptions& indexBuildOptions, boost::optional<Lock::CollectionLock>* exclusiveCollectionLock) { + _scanCollectionAndInsertKeysIntoSorter(opCtx, dbAndUUID, replState, exclusiveCollectionLock); + auto nss = _insertKeysFromSideTablesWithoutBlockingWrites(opCtx, dbAndUUID, replState); + auto commitIndexBuildTimestamp = _waitForCommitOrAbort(opCtx, nss, replState); + _insertKeysFromSideTablesAndCommit(opCtx, + dbAndUUID, + replState, + indexBuildOptions, + exclusiveCollectionLock, + commitIndexBuildTimestamp); +} + +void IndexBuildsCoordinator::_scanCollectionAndInsertKeysIntoSorter( + OperationContext* opCtx, + const NamespaceStringOrUUID& dbAndUUID, + std::shared_ptr<ReplIndexBuildState> replState, + boost::optional<Lock::CollectionLock>* exclusiveCollectionLock) { { auto nss = CollectionCatalog::get(opCtx).lookupNSSByUUID(replState->collectionUUID); @@ -1290,7 +1306,16 @@ void IndexBuildsCoordinator::_buildIndex( log() << "Hanging after dumping inserts from bulk builder"; hangAfterIndexBuildDumpsInsertsFromBulk.pauseWhileSet(); } +} +/** + * Second phase is extracting the sorted keys and writing them into the new index table. + * Looks up collection namespace while holding locks. + */ +NamespaceString IndexBuildsCoordinator::_insertKeysFromSideTablesWithoutBlockingWrites( + OperationContext* opCtx, + const NamespaceStringOrUUID& dbAndUUID, + std::shared_ptr<ReplIndexBuildState> replState) { // Perform the first drain while holding an intent lock. { opCtx->recoveryUnit()->abandonSnapshot(); @@ -1330,6 +1355,16 @@ void IndexBuildsCoordinator::_buildIndex( hangAfterIndexBuildSecondDrain.pauseWhileSet(); } + return nss; +} + +/** + * Waits for commit or abort signal from primary. + */ +Timestamp IndexBuildsCoordinator::_waitForCommitOrAbort( + OperationContext* opCtx, + const NamespaceString& nss, + std::shared_ptr<ReplIndexBuildState> replState) { Timestamp commitIndexBuildTimestamp; if (shouldWaitForCommitOrAbort(opCtx, nss, *replState)) { log() << "Index build waiting for commit or abort before completing final phase: " @@ -1361,7 +1396,20 @@ void IndexBuildsCoordinator::_buildIndex( invariant(!replState->isCommitReady, replState->buildUUID.toString()); } } + return commitIndexBuildTimestamp; +} +/** + * Third phase is catching up on all the writes that occurred during the first two phases. + * Accepts a commit timestamp for the index (null if not available). + */ +void IndexBuildsCoordinator::_insertKeysFromSideTablesAndCommit( + OperationContext* opCtx, + const NamespaceStringOrUUID& dbAndUUID, + std::shared_ptr<ReplIndexBuildState> replState, + const IndexBuildOptions& indexBuildOptions, + boost::optional<Lock::CollectionLock>* exclusiveCollectionLock, + const Timestamp& commitIndexBuildTimestamp) { // Need to return the collection lock back to exclusive mode, to complete the index build. opCtx->recoveryUnit()->abandonSnapshot(); exclusiveCollectionLock->emplace(opCtx, dbAndUUID, MODE_X); diff --git a/src/mongo/db/index_builds_coordinator.h b/src/mongo/db/index_builds_coordinator.h index 0cc29db2155..3c909c3f2c9 100644 --- a/src/mongo/db/index_builds_coordinator.h +++ b/src/mongo/db/index_builds_coordinator.h @@ -419,6 +419,55 @@ protected: std::shared_ptr<ReplIndexBuildState> replState, const IndexBuildOptions& indexBuildOptions, boost::optional<Lock::CollectionLock>* collLock); + + /** + * First phase is the collection scan and insertion of the keys into the sorter. + */ + void _scanCollectionAndInsertKeysIntoSorter( + OperationContext* opCtx, + const NamespaceStringOrUUID& dbAndUUID, + std::shared_ptr<ReplIndexBuildState> replState, + boost::optional<Lock::CollectionLock>* exclusiveCollectionLock); + + /** + * Second phase is extracting the sorted keys and writing them into the new index table. + * On completion, this function returns the namespace of the collection, which may have changed + * after the previous phase. The namespace is used in two phase index builds to determine the + * current replication state in _waitForCommitOrAbort(). + */ + NamespaceString _insertKeysFromSideTablesWithoutBlockingWrites( + OperationContext* opCtx, + const NamespaceStringOrUUID& dbAndUUID, + std::shared_ptr<ReplIndexBuildState> replState); + + /** + * Waits for commit or abort signal from primary. + * + * On completion, this function returns a timestamp, which may be null, that may be used to + * update the mdb catalog as we commit the index build. The commit index build timestamp is + * obtained from a commitIndexBuild oplog entry during secondary oplog application. + * This function returns a null timestamp on receiving a abortIndexBuild oplog entry; or if we + * are currently a primary, in which case we do not need to wait any external signal to commit + * the index build. + */ + Timestamp _waitForCommitOrAbort(OperationContext* opCtx, + const NamespaceString& nss, + std::shared_ptr<ReplIndexBuildState> replState); + + /** + * Third phase is catching up on all the writes that occurred during the first two phases. + * Accepts a commit timestamp for the index, which could be null. See _waitForCommitOrAbort() + * comments. This timestamp is used only for committing the index, which sets the ready flag to + * true, to the catalog; it is not used for the catch-up writes during the final drain phase. + */ + void _insertKeysFromSideTablesAndCommit( + OperationContext* opCtx, + const NamespaceStringOrUUID& dbAndUUID, + std::shared_ptr<ReplIndexBuildState> replState, + const IndexBuildOptions& indexBuildOptions, + boost::optional<Lock::CollectionLock>* exclusiveCollectionLock, + const Timestamp& commitIndexBuildTimestamp); + /** * Returns total number of indexes in collection, including unfinished/in-progress indexes. * |