diff options
author | Gregory Noma <gregory.noma@gmail.com> | 2020-08-06 12:18:10 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-08-06 16:36:01 +0000 |
commit | 6522e78360de316c46700bc51f34d3bf0b551e34 (patch) | |
tree | 721623b3428a62df469b892cd713821220f88e89 /src | |
parent | ffc257fed4a67caece86c93f9e216d32856cd303 (diff) | |
download | mongo-6522e78360de316c46700bc51f34d3bf0b551e34.tar.gz |
SERVER-49528 Retrieve resumable index build information before stopping index builds for rollback
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/catalog/index_builds_manager.cpp | 15 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_builds_manager.h | 14 | ||||
-rw-r--r-- | src/mongo/db/catalog/multi_index_block.cpp | 29 | ||||
-rw-r--r-- | src/mongo/db/catalog/multi_index_block.h | 15 |
4 files changed, 60 insertions, 13 deletions
diff --git a/src/mongo/db/catalog/index_builds_manager.cpp b/src/mongo/db/catalog/index_builds_manager.cpp index 714bc55c71e..e3d1c3925ad 100644 --- a/src/mongo/db/catalog/index_builds_manager.cpp +++ b/src/mongo/db/catalog/index_builds_manager.cpp @@ -343,7 +343,10 @@ bool IndexBuildsManager::abortIndexBuildWithoutCleanupForRollback(OperationConte "Index build aborted without cleanup for rollback", "buildUUID"_attr = buildUUID); - builder.getValue()->abortWithoutCleanupForRollback(opCtx); + if (auto resumeInfo = builder.getValue()->abortWithoutCleanupForRollback(opCtx)) { + _resumeInfos.push_back(std::move(*resumeInfo)); + } + return true; } @@ -462,4 +465,12 @@ StatusWith<int> IndexBuildsManager::_moveRecordToLostAndFound(OperationContext* }); } -} // namespace mongo
\ No newline at end of file +std::vector<ResumeIndexInfo> IndexBuildsManager::getResumeInfos() const { + return std::move(_resumeInfos); +} + +void IndexBuildsManager::clearResumeInfos() { + _resumeInfos.clear(); +} + +} // namespace mongo diff --git a/src/mongo/db/catalog/index_builds_manager.h b/src/mongo/db/catalog/index_builds_manager.h index 0c70c8f72d0..773a4892d69 100644 --- a/src/mongo/db/catalog/index_builds_manager.h +++ b/src/mongo/db/catalog/index_builds_manager.h @@ -185,6 +185,17 @@ public: */ void verifyNoIndexBuilds_forTestOnly(); + /** + * Returns the information to resume each resumable index build that was aborted for rollback. + */ + std::vector<ResumeIndexInfo> getResumeInfos() const; + + /** + * Clears the vector that was used to store the information to resume each resumable index + * build after rollback. + */ + void clearResumeInfos(); + private: /** * Creates and registers a new builder in the _builders map, mapped by the provided buildUUID. @@ -203,6 +214,9 @@ private: // taken on and information passed to and from index builds. std::map<UUID, std::unique_ptr<MultiIndexBlock>> _builders; + // The information to resume each resumable index build that was aborted for rollback. + std::vector<ResumeIndexInfo> _resumeInfos; + /** * Deletes record containing duplicate keys and insert it into a local lost and found collection * titled "local.system.lost_and_found.<original collection UUID>". Returns the size of the diff --git a/src/mongo/db/catalog/multi_index_block.cpp b/src/mongo/db/catalog/multi_index_block.cpp index 84db90365cb..4d8b2d55983 100644 --- a/src/mongo/db/catalog/multi_index_block.cpp +++ b/src/mongo/db/catalog/multi_index_block.cpp @@ -711,8 +711,9 @@ Status MultiIndexBlock::checkConstraints(OperationContext* opCtx) { return Status::OK(); } -void MultiIndexBlock::abortWithoutCleanupForRollback(OperationContext* opCtx) { - _abortWithoutCleanup(opCtx, false /* shutdown */); +boost::optional<ResumeIndexInfo> MultiIndexBlock::abortWithoutCleanupForRollback( + OperationContext* opCtx) { + return _abortWithoutCleanup(opCtx, false /* shutdown */); } void MultiIndexBlock::abortWithoutCleanupForShutdown(OperationContext* opCtx) { @@ -792,7 +793,8 @@ void MultiIndexBlock::setIndexBuildMethod(IndexBuildMethod indexBuildMethod) { _method = indexBuildMethod; } -void MultiIndexBlock::_abortWithoutCleanup(OperationContext* opCtx, bool shutdown) { +boost::optional<ResumeIndexInfo> MultiIndexBlock::_abortWithoutCleanup(OperationContext* opCtx, + bool shutdown) { invariant(!_buildIsCleanedUp); UninterruptibleLockGuard noInterrupt(opCtx->lockState()); // Lock if it's not already locked, to ensure storage engine cannot be destructed out from @@ -803,10 +805,19 @@ void MultiIndexBlock::_abortWithoutCleanup(OperationContext* opCtx, bool shutdow } auto action = TemporaryRecordStore::FinalizationAction::kDelete; + boost::optional<ResumeIndexInfo> resumeInfo; - if (_shouldWriteStateToDisk(opCtx, shutdown)) { - _writeStateToDisk(opCtx); - action = TemporaryRecordStore::FinalizationAction::kKeep; + if (_isResumable(opCtx)) { + if (shutdown) { + _writeStateToDisk(opCtx); + + // TODO (SERVER-48419): Keep the temporary tables unconditionally of shutdown once + // rollback uses the resume information. + action = TemporaryRecordStore::FinalizationAction::kKeep; + } else { + resumeInfo = ResumeIndexInfo::parse( + IDLParserErrorContext("MultiIndexBlock::getResumeInfo"), _constructStateObject()); + } } for (auto& index : _indexes) { @@ -814,10 +825,12 @@ void MultiIndexBlock::_abortWithoutCleanup(OperationContext* opCtx, bool shutdow } _buildIsCleanedUp = true; + + return resumeInfo; } -bool MultiIndexBlock::_shouldWriteStateToDisk(OperationContext* opCtx, bool shutdown) const { - return shutdown && _buildUUID && !_buildIsCleanedUp && _method == IndexBuildMethod::kHybrid && +bool MultiIndexBlock::_isResumable(OperationContext* opCtx) const { + return _buildUUID && !_buildIsCleanedUp && _method == IndexBuildMethod::kHybrid && opCtx->getServiceContext()->getStorageEngine()->supportsResumableIndexBuilds(); } diff --git a/src/mongo/db/catalog/multi_index_block.h b/src/mongo/db/catalog/multi_index_block.h index dd588e58921..465e7f82d64 100644 --- a/src/mongo/db/catalog/multi_index_block.h +++ b/src/mongo/db/catalog/multi_index_block.h @@ -268,9 +268,12 @@ public: * not perform any storage engine writes. May delete internal tables, but this is not * transactional. * + * If the indexes being built were resumable, returns the information to resume them. + * Otherwise, returns boost::none. + * * This should only be used during rollback. */ - void abortWithoutCleanupForRollback(OperationContext* opCtx); + boost::optional<ResumeIndexInfo> abortWithoutCleanupForRollback(OperationContext* opCtx); /** * May be called at any time after construction but before a successful commit(). Suppresses @@ -302,9 +305,15 @@ private: InsertDeleteOptions options; }; - void _abortWithoutCleanup(OperationContext* opCtx, bool shutdown); + /** + * This function should be used for shutdown and rollback. When called for shutdown, writes the + * resumable index build state to disk if resuamble index builds are supported. When called for + * rollback, returns the information to resume the index build if resuamble index builds are + * supported. + */ + boost::optional<ResumeIndexInfo> _abortWithoutCleanup(OperationContext* opCtx, bool shutdown); - bool _shouldWriteStateToDisk(OperationContext* opCtx, bool shutdown) const; + bool _isResumable(OperationContext* opCtx) const; void _writeStateToDisk(OperationContext* opCtx) const; |