diff options
author | Benety Goh <benety@mongodb.com> | 2019-08-22 11:19:27 -0400 |
---|---|---|
committer | Benety Goh <benety@mongodb.com> | 2019-08-22 11:20:51 -0400 |
commit | 8a285153c1729dd9dcb417f1dccfa8593d25fe7e (patch) | |
tree | bc66f4b671ee6b63067fa559b0963aea44478062 /src/mongo | |
parent | 2fb73bcd2515cd8d566fecc5b23ee9f6970b1716 (diff) | |
download | mongo-8a285153c1729dd9dcb417f1dccfa8593d25fe7e.tar.gz |
SERVER-42869 use shared_ptr to manage side writes counter in IndexBuildInterceptor
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/db/index/index_build_interceptor.cpp | 13 | ||||
-rw-r--r-- | src/mongo/db/index/index_build_interceptor.h | 9 |
2 files changed, 15 insertions, 7 deletions
diff --git a/src/mongo/db/index/index_build_interceptor.cpp b/src/mongo/db/index/index_build_interceptor.cpp index 417bb04d411..8a02c8ef46c 100644 --- a/src/mongo/db/index/index_build_interceptor.cpp +++ b/src/mongo/db/index/index_build_interceptor.cpp @@ -58,7 +58,8 @@ MONGO_FAIL_POINT_DEFINE(hangDuringIndexBuildDrainYield); IndexBuildInterceptor::IndexBuildInterceptor(OperationContext* opCtx, IndexCatalogEntry* entry) : _indexCatalogEntry(entry), _sideWritesTable( - opCtx->getServiceContext()->getStorageEngine()->makeTemporaryRecordStore(opCtx)) { + opCtx->getServiceContext()->getStorageEngine()->makeTemporaryRecordStore(opCtx)), + _sideWritesCounter(std::make_shared<AtomicWord<long long>>()) { if (entry->descriptor()->unique()) { _duplicateKeyTracker = std::make_unique<DuplicateKeyTracker>(opCtx, entry); @@ -127,7 +128,7 @@ Status IndexBuildInterceptor::drainWritesIntoIndex(OperationContext* opCtx, // Force the progress meter to log at the end of every batch. By default, the progress meter // only logs after a large number of calls to hit(), but since we use such large batch sizes, // progress would rarely be displayed. - progress->reset(_sideWritesCounter.load() - appliedAtStart /* total */, + progress->reset(_sideWritesCounter->load() - appliedAtStart /* total */, 3 /* secondsBetween */, 1 /* checkInterval */); @@ -217,7 +218,7 @@ Status IndexBuildInterceptor::drainWritesIntoIndex(OperationContext* opCtx, _tryYield(opCtx); // Account for more writes coming in during a batch. - progress->setTotalWhileRunning(_sideWritesCounter.loadRelaxed() - appliedAtStart); + progress->setTotalWhileRunning(_sideWritesCounter->loadRelaxed() - appliedAtStart); return Status::OK(); }; @@ -344,7 +345,7 @@ bool IndexBuildInterceptor::areAllWritesApplied(OperationContext* opCtx) const { // The table is empty only when all writes are applied. if (!record) { - auto writesRecorded = _sideWritesCounter.load(); + auto writesRecorded = _sideWritesCounter->load(); if (writesRecorded != _numApplied) { const std::string message = str::stream() << "The number of side writes recorded does not match the number " @@ -422,12 +423,12 @@ Status IndexBuildInterceptor::sideWrite(OperationContext* opCtx, } } - _sideWritesCounter.fetchAndAdd(toInsert.size()); + _sideWritesCounter->fetchAndAdd(toInsert.size()); // This insert may roll back, but not necessarily from inserting into this table. If other write // operations outside this table and in the same transaction are rolled back, this counter also // needs to be rolled back. opCtx->recoveryUnit()->onRollback( - [this, size = toInsert.size()] { _sideWritesCounter.fetchAndSubtract(size); }); + [this, size = toInsert.size()] { _sideWritesCounter->fetchAndSubtract(size); }); std::vector<Record> records; for (auto& doc : toInsert) { diff --git a/src/mongo/db/index/index_build_interceptor.h b/src/mongo/db/index/index_build_interceptor.h index a9b36131ed5..4bdaaebf6f0 100644 --- a/src/mongo/db/index/index_build_interceptor.h +++ b/src/mongo/db/index/index_build_interceptor.h @@ -29,6 +29,8 @@ #pragma once +#include <memory> + #include "mongo/db/index/duplicate_key_tracker.h" #include "mongo/db/index/index_access_method.h" #include "mongo/db/index/multikey_paths.h" @@ -155,7 +157,12 @@ private: int64_t _numApplied{0}; - AtomicWord<long long> _sideWritesCounter{0}; + // This allows the counter to be used in a RecoveryUnit rollback handler where the + // IndexBuildInterceptor is no longer available (e.g. due to index build cleanup). If there are + // additional fields that have to be referenced in commit/rollback handlers, this counter should + // be moved to a new IndexBuildsInterceptor::InternalState structure that will be managed as a + // shared resource. + std::shared_ptr<AtomicWord<long long>> _sideWritesCounter; mutable stdx::mutex _multikeyPathMutex; boost::optional<MultikeyPaths> _multikeyPaths; |