summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Russotto <matthew.russotto@mongodb.com>2021-08-23 20:10:09 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-08-23 20:44:05 +0000
commit11d60e61c61d2db7feb63decb94507611bdd94a3 (patch)
tree1dcc531a919c8acd98ee263bf561f78a36f2c018
parentddbc84d44d03216cc3268f4354acda389a2c8c32 (diff)
downloadmongo-11d60e61c61d2db7feb63decb94507611bdd94a3.tar.gz
SERVER-57812 Make it possible to re-run startup recovery
-rw-r--r--src/mongo/db/startup_recovery.cpp42
-rw-r--r--src/mongo/db/startup_recovery.h10
2 files changed, 46 insertions, 6 deletions
diff --git a/src/mongo/db/startup_recovery.cpp b/src/mongo/db/startup_recovery.cpp
index ff6d18bf0db..2e236863068 100644
--- a/src/mongo/db/startup_recovery.cpp
+++ b/src/mongo/db/startup_recovery.cpp
@@ -65,6 +65,7 @@
namespace mongo {
namespace {
+using startup_recovery::StartupRecoveryMode;
// Exit after repair has started, but before data is repaired.
MONGO_FAIL_POINT_DEFINE(exitBeforeDataRepair);
@@ -423,7 +424,15 @@ void reconcileCatalogAndRebuildUnfinishedIndexes(
* Sets the appropriate flag on the service context decorable 'replSetMemberInStandaloneMode' to
* 'true' if this is a replica set node running in standalone mode, otherwise 'false'.
*/
-void setReplSetMemberInStandaloneMode(OperationContext* opCtx) {
+void setReplSetMemberInStandaloneMode(OperationContext* opCtx, StartupRecoveryMode mode) {
+ if (mode == StartupRecoveryMode::kReplicaSetMember) {
+ setReplSetMemberInStandaloneMode(opCtx->getServiceContext(), false);
+ return;
+ } else if (mode == StartupRecoveryMode::kReplicaSetMemberInStandalone) {
+ setReplSetMemberInStandaloneMode(opCtx->getServiceContext(), true);
+ return;
+ }
+
const repl::ReplSettings& replSettings =
repl::ReplicationCoordinator::get(opCtx)->getSettings();
@@ -483,7 +492,7 @@ void startupRepair(OperationContext* opCtx, StorageEngine* storageEngine) {
fassertNoTrace(4805001, repair::repairDatabase(opCtx, storageEngine, *it));
// This must be set before rebuilding index builds on replicated collections.
- setReplSetMemberInStandaloneMode(opCtx);
+ setReplSetMemberInStandaloneMode(opCtx, StartupRecoveryMode::kAuto);
dbNames.erase(it);
}
@@ -531,7 +540,7 @@ void startupRepair(OperationContext* opCtx, StorageEngine* storageEngine) {
void startupRecoveryReadOnly(OperationContext* opCtx, StorageEngine* storageEngine) {
invariant(!storageGlobalParams.repair);
- setReplSetMemberInStandaloneMode(opCtx);
+ setReplSetMemberInStandaloneMode(opCtx, StartupRecoveryMode::kAuto);
FeatureCompatibilityVersion::initializeForStartup(opCtx);
@@ -544,12 +553,13 @@ void startupRecoveryReadOnly(OperationContext* opCtx, StorageEngine* storageEngi
// Perform routine startup recovery procedure.
void startupRecovery(OperationContext* opCtx,
StorageEngine* storageEngine,
- StorageEngine::LastShutdownState lastShutdownState) {
+ StorageEngine::LastShutdownState lastShutdownState,
+ StartupRecoveryMode mode) {
invariant(!storageGlobalParams.readOnly && !storageGlobalParams.repair);
// Determine whether this is a replica set node running in standalone mode. This must be set
// before determining whether to restart index builds.
- setReplSetMemberInStandaloneMode(opCtx);
+ setReplSetMemberInStandaloneMode(opCtx, mode);
// Initialize FCV before rebuilding indexes that may have features dependent on FCV.
FeatureCompatibilityVersion::initializeForStartup(opCtx);
@@ -614,9 +624,29 @@ void repairAndRecoverDatabases(OperationContext* opCtx,
} else if (storageGlobalParams.readOnly) {
startupRecoveryReadOnly(opCtx, storageEngine);
} else {
- startupRecovery(opCtx, storageEngine, lastShutdownState);
+ startupRecovery(opCtx, storageEngine, lastShutdownState, StartupRecoveryMode::kAuto);
}
}
+/**
+ * Runs startup recovery after system startup, either in replSet mode (will
+ * restart index builds) or replSet standalone mode (will not restart index builds). In no
+ * case will it create an FCV document nor run repair or read-only recovery.
+ */
+void runStartupRecoveryInMode(OperationContext* opCtx,
+ StorageEngine::LastShutdownState lastShutdownState,
+ StartupRecoveryMode mode) {
+ auto const storageEngine = opCtx->getServiceContext()->getStorageEngine();
+ Lock::GlobalWrite lk(opCtx);
+
+ invariant(isWriteableStorageEngine() && !storageGlobalParams.readOnly);
+ invariant(!storageGlobalParams.repair);
+ const auto& replSettings = repl::ReplicationCoordinator::get(opCtx)->getSettings();
+ invariant(replSettings.usingReplSets());
+ invariant(mode == StartupRecoveryMode::kReplicaSetMember ||
+ mode == StartupRecoveryMode::kReplicaSetMemberInStandalone);
+ startupRecovery(opCtx, storageEngine, lastShutdownState, mode);
+}
+
} // namespace startup_recovery
} // namespace mongo
diff --git a/src/mongo/db/startup_recovery.h b/src/mongo/db/startup_recovery.h
index 025c7d4a54e..5bf15c9cdb2 100644
--- a/src/mongo/db/startup_recovery.h
+++ b/src/mongo/db/startup_recovery.h
@@ -41,5 +41,15 @@ namespace startup_recovery {
void repairAndRecoverDatabases(OperationContext* opCtx,
StorageEngine::LastShutdownState lastShutdownState);
+/**
+ * Runs startup recovery after system startup, specifying whether to recover as a replica set
+ * being started in standalone mode (no index build resumption).
+ */
+enum class StartupRecoveryMode { kAuto, kReplicaSetMember, kReplicaSetMemberInStandalone };
+
+void runStartupRecoveryInMode(OperationContext* opCtx,
+ StorageEngine::LastShutdownState lastShutdownState,
+ StartupRecoveryMode mode);
+
} // namespace startup_recovery
} // namespace mongo