diff options
-rw-r--r-- | src/mongo/db/repl/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/repl/initial_syncer.cpp | 39 | ||||
-rw-r--r-- | src/mongo/db/repl/initial_syncer_common_stats.cpp | 65 | ||||
-rw-r--r-- | src/mongo/db/repl/initial_syncer_common_stats.h | 59 | ||||
-rw-r--r-- | src/mongo/db/repl/initial_syncer_test.cpp | 9 |
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; |