diff options
author | Samy Lanka <samy.lanka@mongodb.com> | 2020-07-31 07:20:47 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-08-04 08:33:16 +0000 |
commit | 2fc36d0b12d1c44893a5f3c1fe0ac8fb0125a071 (patch) | |
tree | 735ccccb879cd841d19f953282f1e74a27a21bd1 /src/mongo/db/index/index_build_interceptor.cpp | |
parent | 4b967fd6c5e679b33922a4d287755ea987dc882c (diff) | |
download | mongo-2fc36d0b12d1c44893a5f3c1fe0ac8fb0125a071.tar.gz |
SERVER-48417 Reconstruct in-memory state when resuming index build
Diffstat (limited to 'src/mongo/db/index/index_build_interceptor.cpp')
-rw-r--r-- | src/mongo/db/index/index_build_interceptor.cpp | 55 |
1 files changed, 46 insertions, 9 deletions
diff --git a/src/mongo/db/index/index_build_interceptor.cpp b/src/mongo/db/index/index_build_interceptor.cpp index 1ab952d3640..f569fc00e46 100644 --- a/src/mongo/db/index/index_build_interceptor.cpp +++ b/src/mongo/db/index/index_build_interceptor.cpp @@ -83,25 +83,62 @@ bool IndexBuildInterceptor::typeCanFastpathMultikeyUpdates(IndexType indexType) return (indexType == INDEX_BTREE); } +void IndexBuildInterceptor::_initializeMultiKeyPaths(IndexCatalogEntry* entry) { + // `mergeMultikeyPaths` is sensitive to the two inputs having the same multikey + // "shape". Initialize `_multikeyPaths` with the right shape from the IndexCatalogEntry. + auto indexType = entry->descriptor()->getIndexType(); + if (typeCanFastpathMultikeyUpdates(indexType)) { + auto numFields = entry->descriptor()->getNumFields(); + _multikeyPaths = MultikeyPaths{}; + auto it = _multikeyPaths->begin(); + _multikeyPaths->insert(it, numFields, {}); + } +} + IndexBuildInterceptor::IndexBuildInterceptor(OperationContext* opCtx, IndexCatalogEntry* entry) : _indexCatalogEntry(entry), _sideWritesTable( opCtx->getServiceContext()->getStorageEngine()->makeTemporaryRecordStore(opCtx)), - _skippedRecordTracker(entry), + _skippedRecordTracker(opCtx, entry, boost::none), _sideWritesCounter(std::make_shared<AtomicWord<long long>>()) { if (entry->descriptor()->unique()) { _duplicateKeyTracker = std::make_unique<DuplicateKeyTracker>(opCtx, entry); } - // `mergeMultikeyPaths` is sensitive to the two inputs having the same multikey - // "shape". Initialize `_multikeyPaths` with the right shape from the IndexCatalogEntry. - auto indexType = entry->descriptor()->getIndexType(); - if (typeCanFastpathMultikeyUpdates(indexType)) { - auto numFields = entry->descriptor()->getNumFields(); - _multikeyPaths = MultikeyPaths{}; - auto it = _multikeyPaths->begin(); - _multikeyPaths->insert(it, numFields, {}); + + _initializeMultiKeyPaths(entry); +} + +IndexBuildInterceptor::IndexBuildInterceptor(OperationContext* opCtx, + IndexCatalogEntry* entry, + StringData sideWritesIdent, + boost::optional<StringData> duplicateKeyTrackerIdent, + boost::optional<StringData> skippedRecordTrackerIdent) + : _indexCatalogEntry(entry), + _skippedRecordTracker(opCtx, entry, skippedRecordTrackerIdent), + _sideWritesCounter(std::make_shared<AtomicWord<long long>>()) { + + _sideWritesTable = + opCtx->getServiceContext()->getStorageEngine()->makeTemporaryRecordStoreFromExistingIdent( + opCtx, sideWritesIdent); + auto finalizeTableOnFailure = makeGuard([&] { + _sideWritesTable->finalizeTemporaryTable(opCtx, + TemporaryRecordStore::FinalizationAction::kDelete); + }); + + auto dupKeyTrackerIdentExists = duplicateKeyTrackerIdent ? true : false; + uassert(ErrorCodes::BadValue, + str::stream() << "Resume info must contain the duplicate key tracker ident [" + << duplicateKeyTrackerIdent + << "] if and only if the index is unique: " << entry->descriptor(), + entry->descriptor()->unique() == dupKeyTrackerIdentExists); + if (duplicateKeyTrackerIdent) { + _duplicateKeyTracker = + std::make_unique<DuplicateKeyTracker>(opCtx, entry, duplicateKeyTrackerIdent.get()); } + + _initializeMultiKeyPaths(entry); + finalizeTableOnFailure.dismiss(); } void IndexBuildInterceptor::finalizeTemporaryTables( |