summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2019-08-22 11:19:27 -0400
committerBenety Goh <benety@mongodb.com>2019-08-22 11:20:51 -0400
commit8a285153c1729dd9dcb417f1dccfa8593d25fe7e (patch)
treebc66f4b671ee6b63067fa559b0963aea44478062 /src/mongo
parent2fb73bcd2515cd8d566fecc5b23ee9f6970b1716 (diff)
downloadmongo-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.cpp13
-rw-r--r--src/mongo/db/index/index_build_interceptor.h9
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;