diff options
Diffstat (limited to 'src/mongo/db/s/resharding/resharding_metrics.cpp')
-rw-r--r-- | src/mongo/db/s/resharding/resharding_metrics.cpp | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/src/mongo/db/s/resharding/resharding_metrics.cpp b/src/mongo/db/s/resharding/resharding_metrics.cpp index 5fabcb00e9e..9f8ada073ca 100644 --- a/src/mongo/db/s/resharding/resharding_metrics.cpp +++ b/src/mongo/db/s/resharding/resharding_metrics.cpp @@ -67,6 +67,20 @@ const auto getMetrics = ServiceContext::declareDecoration<MetricsPtr>(); const auto reshardingMetricsRegisterer = ServiceContext::ConstructorActionRegisterer{ "ReshardingMetrics", [](ServiceContext* ctx) { getMetrics(ctx) = std::make_unique<ReshardingMetrics>(ctx); }}; + +/** + * Given a constant rate of time per unit of work: + * totalTime / totalWork == elapsedTime / elapsedWork + * Solve for remaining time. + * remainingTime := totalTime - elapsedTime + * == (totalWork * (elapsedTime / elapsedWork)) - elapsedTime + * == elapsedTime * (totalWork / elapsedWork - 1) + */ +Milliseconds remainingTime(Milliseconds elapsedTime, double elapsedWork, double totalWork) { + elapsedWork = std::min(elapsedWork, totalWork); + double remainingMsec = 1.0 * elapsedTime.count() * (totalWork / elapsedWork - 1); + return Milliseconds(Milliseconds::rep(remainingMsec)); +} } // namespace ReshardingMetrics* ReshardingMetrics::get(ServiceContext* ctx) noexcept { @@ -242,28 +256,28 @@ void ReshardingMetrics::OperationMetrics::append(BSONObjBuilder* bob, Role role) return durationCount<Seconds>(interval.duration()); }; - auto estimateRemainingOperationTime = [&]() -> int64_t { - if (bytesCopied == 0 && oplogEntriesApplied == 0) - return -1; - else if (oplogEntriesApplied == 0) { - invariant(bytesCopied > 0); + auto remainingMsec = [&]() -> boost::optional<Milliseconds> { + if (oplogEntriesApplied > 0) { + // All fetched oplogEntries must be applied. Some of them already have been. + return remainingTime( + applyingOplogEntries.duration(), oplogEntriesApplied, oplogEntriesFetched); + } + if (bytesCopied > 0) { // Until the time to apply batches of oplog entries is measured, we assume that applying // all of them will take as long as copying did. - const auto elapsedCopyTime = getElapsedTime(copyingDocuments); - const auto approxTimeToCopy = - elapsedCopyTime * std::max((int64_t)0, bytesToCopy / bytesCopied - 1); - return elapsedCopyTime + 2 * approxTimeToCopy; - } else { - invariant(oplogEntriesApplied > 0); - const auto approxTimeToApply = getElapsedTime(applyingOplogEntries) * - std::max((int64_t)0, oplogEntriesFetched / oplogEntriesApplied - 1); - return approxTimeToApply; + return remainingTime(copyingDocuments.duration(), bytesCopied, 2 * bytesToCopy); } - }; + return {}; + }(); + const std::string kIntervalSuffix = role == Role::kAll ? "Millis" : ""; bob->append(kOpTimeElapsed + kIntervalSuffix, getElapsedTime(runningOperation)); - bob->append(kOpTimeRemaining + kIntervalSuffix, estimateRemainingOperationTime()); + + bob->append(kOpTimeRemaining + kIntervalSuffix, + !remainingMsec ? int64_t{-1} /** -1 is a specified integer null value */ + : role == Role::kAll ? durationCount<Milliseconds>(*remainingMsec) + : durationCount<Seconds>(*remainingMsec)); if (role == Role::kAll || role == Role::kRecipient) { bob->append(kDocumentsToCopy, documentsToCopy); |