summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoustafa Maher Khalil <m.maher@mongodb.com>2021-11-02 21:56:01 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-11-04 20:27:43 +0000
commit1a99933a489e6620a72899011054352f27e3282a (patch)
tree52d4cb81fb0c25ecbf187cf854248e85045ada7a
parentd54acf1b792de6f7a8b82e49a1e94a7c24c938b0 (diff)
downloadmongo-1a99933a489e6620a72899011054352f27e3282a.tar.gz
SERVER-61198 Log unified statistics for logical and file copy based initial sync
-rw-r--r--src/mongo/db/repl/SConscript1
-rw-r--r--src/mongo/db/repl/initial_syncer.cpp39
-rw-r--r--src/mongo/db/repl/initial_syncer_common_stats.cpp65
-rw-r--r--src/mongo/db/repl/initial_syncer_common_stats.h59
-rw-r--r--src/mongo/db/repl/initial_syncer_test.cpp9
5 files changed, 138 insertions, 35 deletions
diff --git a/src/mongo/db/repl/SConscript b/src/mongo/db/repl/SConscript
index 9a2fdd7a9b6..dbc111fd53c 100644
--- a/src/mongo/db/repl/SConscript
+++ b/src/mongo/db/repl/SConscript
@@ -1170,6 +1170,7 @@ env.Library(
target='initial_syncer',
source=[
'initial_syncer.cpp',
+ 'initial_syncer_common_stats.cpp',
'initial_syncer_factory.cpp',
],
LIBDEPS=[
diff --git a/src/mongo/db/repl/initial_syncer.cpp b/src/mongo/db/repl/initial_syncer.cpp
index f4810d8ce3d..e5ba80ffcb9 100644
--- a/src/mongo/db/repl/initial_syncer.cpp
+++ b/src/mongo/db/repl/initial_syncer.cpp
@@ -51,6 +51,7 @@
#include "mongo/db/namespace_string.h"
#include "mongo/db/repl/all_database_cloner.h"
#include "mongo/db/repl/initial_sync_state.h"
+#include "mongo/db/repl/initial_syncer_common_stats.h"
#include "mongo/db/repl/initial_syncer_factory.h"
#include "mongo/db/repl/member_state.h"
#include "mongo/db/repl/oplog_buffer.h"
@@ -147,28 +148,6 @@ using LockGuard = stdx::lock_guard<Latch>;
// Used to reset the oldest timestamp during initial sync to a non-null timestamp.
const Timestamp kTimestampOne(0, 1);
-// The number of initial sync attempts that have failed since server startup. Each instance of
-// InitialSyncer may run multiple attempts to fulfill an initial sync request that is triggered
-// when InitialSyncer::startup() is called.
-Counter64 initialSyncFailedAttempts;
-
-// The number of initial sync requests that have been requested and failed. Each instance of
-// InitialSyncer (upon successful startup()) corresponds to a single initial sync request.
-// This value does not include the number of times where a InitialSyncer is created successfully
-// but failed in startup().
-Counter64 initialSyncFailures;
-
-// The number of initial sync requests that have been requested and completed successfully. Each
-// instance of InitialSyncer corresponds to a single initial sync request.
-Counter64 initialSyncCompletes;
-
-ServerStatusMetricField<Counter64> displaySSInitialSyncFailedAttempts(
- "repl.initialSync.failedAttempts", &initialSyncFailedAttempts);
-ServerStatusMetricField<Counter64> displaySSInitialSyncFailures("repl.initialSync.failures",
- &initialSyncFailures);
-ServerStatusMetricField<Counter64> displaySSInitialSyncCompleted("repl.initialSync.completed",
- &initialSyncCompletes);
-
ServiceContext::UniqueOperationContext makeOpCtx() {
return cc().makeOperationContext();
}
@@ -436,13 +415,14 @@ BSONObj InitialSyncer::getInitialSyncProgress() const {
// cleared because an initial sync attempt can fail even after initialSyncCompletes is
// incremented, and we also check that initialSyncCompletes is positive because an initial sync
// attempt can also fail before _initialSyncState is initialized.
- if (!_initialSyncState && initialSyncCompletes.get() > 0) {
+ if (!_initialSyncState && initial_sync_common_stats::initialSyncCompletes.get() > 0) {
return BSONObj();
}
return _getInitialSyncProgress_inlock();
}
void InitialSyncer::_appendInitialSyncProgressMinimal_inlock(BSONObjBuilder* bob) const {
+ bob->append("method", "logical");
_stats.append(bob);
if (!_initialSyncState) {
return;
@@ -615,7 +595,7 @@ void InitialSyncer::_tearDown_inlock(OperationContext* opCtx,
"Initial sync done",
"duration"_attr =
duration_cast<Seconds>(_stats.initialSyncEnd - _stats.initialSyncStart));
- initialSyncCompletes.increment();
+ initial_sync_common_stats::initialSyncCompletes.increment();
}
void InitialSyncer::_startInitialSyncAttemptCallback(
@@ -1753,16 +1733,13 @@ void InitialSyncer::_finishInitialSyncAttempt(const StatusWith<OpTimeAndWallTime
++_stats.failedInitialSyncAttempts;
// This increments the number of failed attempts across all initial sync attempts since
// process startup.
- initialSyncFailedAttempts.increment();
+ initial_sync_common_stats::initialSyncFailedAttempts.increment();
}
bool hasRetries = _stats.failedInitialSyncAttempts < _stats.maxFailedInitialSyncAttempts;
- LOGV2(21192,
- "Initial sync status: {status}, initial sync attempt statistics: {statistics}",
- "Initial sync status and statistics",
- "status"_attr = result.isOK() ? "successful" : (hasRetries ? "in_progress" : "failed"),
- "statistics"_attr = redact(_getInitialSyncProgress_inlock()));
+ initial_sync_common_stats::LogInitialSyncAttemptStats(
+ result, hasRetries, _getInitialSyncProgress_inlock());
if (result.isOK()) {
// Scope guard will invoke _finishCallback().
@@ -1783,7 +1760,7 @@ void InitialSyncer::_finishInitialSyncAttempt(const StatusWith<OpTimeAndWallTime
LOGV2_FATAL_CONTINUE(21202,
"The maximum number of retries have been exhausted for initial sync");
- initialSyncFailures.increment();
+ initial_sync_common_stats::initialSyncFailures.increment();
// Scope guard will invoke _finishCallback().
return;
diff --git a/src/mongo/db/repl/initial_syncer_common_stats.cpp b/src/mongo/db/repl/initial_syncer_common_stats.cpp
new file mode 100644
index 00000000000..3d2ec0790d3
--- /dev/null
+++ b/src/mongo/db/repl/initial_syncer_common_stats.cpp
@@ -0,0 +1,65 @@
+/**
+ * Copyright (C) 2021-present MongoDB, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the Server Side Public License, version 1,
+ * as published by MongoDB, Inc.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Server Side Public License for more details.
+ *
+ * You should have received a copy of the Server Side Public License
+ * along with this program. If not, see
+ * <http://www.mongodb.com/licensing/server-side-public-license>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the Server Side Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kReplicationInitialSync
+
+#include "mongo/db/repl/initial_syncer_common_stats.h"
+#include "mongo/db/commands/server_status_metric.h"
+#include "mongo/logv2/log.h"
+
+
+namespace mongo {
+namespace repl {
+namespace initial_sync_common_stats {
+
+Counter64 initialSyncFailedAttempts;
+Counter64 initialSyncFailures;
+Counter64 initialSyncCompletes;
+
+ServerStatusMetricField<Counter64> displaySSInitialSyncFailedAttempts(
+ "repl.initialSync.failedAttempts", &initialSyncFailedAttempts);
+ServerStatusMetricField<Counter64> displaySSInitialSyncFailures("repl.initialSync.failures",
+ &initialSyncFailures);
+ServerStatusMetricField<Counter64> displaySSInitialSyncCompleted("repl.initialSync.completed",
+ &initialSyncCompletes);
+
+void LogInitialSyncAttemptStats(const StatusWith<OpTimeAndWallTime>& attemptResult,
+ bool hasRetries,
+ const BSONObj& stats) {
+ // Don't remove or change this log id as it is ingested to Atlas.
+ LOGV2(21192,
+ "Initial sync status: {status}, initial sync attempt statistics: {statistics}",
+ "Initial sync status and statistics",
+ "status"_attr =
+ attemptResult.isOK() ? "successful" : (hasRetries ? "in_progress" : "failed"),
+ "statistics"_attr = redact(stats));
+}
+
+} // namespace initial_sync_common_stats
+} // namespace repl
+} // namespace mongo
diff --git a/src/mongo/db/repl/initial_syncer_common_stats.h b/src/mongo/db/repl/initial_syncer_common_stats.h
new file mode 100644
index 00000000000..beb8a829bc5
--- /dev/null
+++ b/src/mongo/db/repl/initial_syncer_common_stats.h
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2021-present MongoDB, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the Server Side Public License, version 1,
+ * as published by MongoDB, Inc.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Server Side Public License for more details.
+ *
+ * You should have received a copy of the Server Side Public License
+ * along with this program. If not, see
+ * <http://www.mongodb.com/licensing/server-side-public-license>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the Server Side Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#pragma once
+
+#include "mongo/db/repl/optime.h"
+
+namespace mongo {
+namespace repl {
+namespace initial_sync_common_stats {
+
+// The number of initial sync attempts that have failed since server startup. Each instance of
+// InitialSyncer may run multiple attempts to fulfill an initial sync request that is triggered
+// when InitialSyncer::startup() is called.
+extern Counter64 initialSyncFailedAttempts;
+
+// The number of initial sync requests that have been requested and failed. Each instance of
+// InitialSyncer (upon successful startup()) corresponds to a single initial sync request.
+// This value does not include the number of times where a InitialSyncer is created successfully
+// but failed in startup().
+extern Counter64 initialSyncFailures;
+
+// The number of initial sync requests that have been requested and completed successfully. Each
+// instance of InitialSyncer corresponds to a single initial sync request.
+extern Counter64 initialSyncCompletes;
+
+void LogInitialSyncAttemptStats(const StatusWith<OpTimeAndWallTime>& attemptResult,
+ bool hasRetries,
+ const BSONObj& stats);
+
+} // namespace initial_sync_common_stats
+} // namespace repl
+} // namespace mongo
diff --git a/src/mongo/db/repl/initial_syncer_test.cpp b/src/mongo/db/repl/initial_syncer_test.cpp
index ba220838ef5..e12d15692e1 100644
--- a/src/mongo/db/repl/initial_syncer_test.cpp
+++ b/src/mongo/db/repl/initial_syncer_test.cpp
@@ -4570,7 +4570,8 @@ TEST_F(InitialSyncerTest, GetInitialSyncProgressReturnsCorrectProgress) {
auto progress = initialSyncer->getInitialSyncProgress();
LOGV2(24168, "Progress after first failed response", "progress"_attr = progress);
- ASSERT_EQUALS(progress.nFields(), 11) << progress;
+ ASSERT_EQUALS(progress.nFields(), 12) << progress;
+ ASSERT_EQUALS(progress.getField("method").String(), "logical") << progress;
ASSERT_FALSE(progress.hasField("remainingInitialSyncEstimatedMillis"));
ASSERT_FALSE(progress.hasField("InitialSyncEnd"));
ASSERT_EQUALS(progress.getIntField("failedInitialSyncAttempts"), 0) << progress;
@@ -4638,7 +4639,7 @@ TEST_F(InitialSyncerTest, GetInitialSyncProgressReturnsCorrectProgress) {
auto progress = initialSyncer->getInitialSyncProgress();
LOGV2(24171, "Progress after failure", "progress"_attr = progress);
- ASSERT_EQUALS(progress.nFields(), 11) << progress;
+ ASSERT_EQUALS(progress.nFields(), 12) << progress;
ASSERT_FALSE(progress.hasField("remainingInitialSyncEstimatedMillis"));
ASSERT_FALSE(progress.hasField("InitialSyncEnd"));
ASSERT_EQUALS(progress.getIntField("failedInitialSyncAttempts"), 1) << progress;
@@ -4742,7 +4743,7 @@ TEST_F(InitialSyncerTest, GetInitialSyncProgressReturnsCorrectProgress) {
auto progress = initialSyncer->getInitialSyncProgress();
LOGV2(24173, "Progress after all but last successful response", "progress"_attr = progress);
- ASSERT_EQUALS(progress.nFields(), 13) << progress;
+ ASSERT_EQUALS(progress.nFields(), 14) << progress;
ASSERT_EQUALS(progress.getIntField("failedInitialSyncAttempts"), 1) << progress;
ASSERT_EQUALS(progress.getIntField("maxFailedInitialSyncAttempts"), 2) << progress;
ASSERT_EQUALS(progress["totalInitialSyncElapsedMillis"].type(), NumberLong) << progress;
@@ -4819,7 +4820,7 @@ TEST_F(InitialSyncerTest, GetInitialSyncProgressReturnsCorrectProgress) {
progress = initialSyncer->getInitialSyncProgress();
LOGV2(24175, "Progress at end", "progress"_attr = progress);
- ASSERT_EQUALS(progress.nFields(), 14) << progress;
+ ASSERT_EQUALS(progress.nFields(), 15) << progress;
ASSERT_EQUALS(progress.getIntField("failedInitialSyncAttempts"), 1) << progress;
ASSERT_EQUALS(progress.getIntField("maxFailedInitialSyncAttempts"), 2) << progress;
ASSERT_EQUALS(progress["initialSyncStart"].type(), Date) << progress;