summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Wlodarek <gregory.wlodarek@mongodb.com>2022-03-09 02:16:55 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-03-09 19:41:56 +0000
commitd563fc234fedf423e55f99bc840ba8188b523603 (patch)
tree9ca16381666f70c0fa1ccf70ec5d03ea093eb04d
parent0f7683455bc06b153f14368a3f05f0b69671717e (diff)
downloadmongo-d563fc234fedf423e55f99bc840ba8188b523603.tar.gz
SERVER-64304 Prevent a server crash due to index builds started when using the --recoverFromOplogAsStandalone startup parameter
-rw-r--r--src/mongo/db/active_index_builds.cpp2
-rw-r--r--src/mongo/db/active_index_builds.h2
-rw-r--r--src/mongo/db/index_builds_coordinator.cpp4
-rw-r--r--src/mongo/db/index_builds_coordinator.h5
-rw-r--r--src/mongo/db/repl/SConscript1
-rw-r--r--src/mongo/db/repl/replication_recovery.cpp13
6 files changed, 21 insertions, 6 deletions
diff --git a/src/mongo/db/active_index_builds.cpp b/src/mongo/db/active_index_builds.cpp
index 9edde200e35..017ca49ecc8 100644
--- a/src/mongo/db/active_index_builds.cpp
+++ b/src/mongo/db/active_index_builds.cpp
@@ -201,7 +201,7 @@ Status ActiveIndexBuilds::registerIndexBuild(
return Status::OK();
}
-size_t ActiveIndexBuilds::getActiveIndexBuilds() {
+size_t ActiveIndexBuilds::getActiveIndexBuilds() const {
stdx::unique_lock<Latch> lk(_mutex);
return _allIndexBuilds.size();
}
diff --git a/src/mongo/db/active_index_builds.h b/src/mongo/db/active_index_builds.h
index 47a276e9ec9..ec4f07f26cf 100644
--- a/src/mongo/db/active_index_builds.h
+++ b/src/mongo/db/active_index_builds.h
@@ -98,7 +98,7 @@ public:
/**
* Get the number of in-progress index builds.
*/
- size_t getActiveIndexBuilds();
+ size_t getActiveIndexBuilds() const;
/**
* When _sleepForTest is true, this function will sleep for 100ms and then check the value
diff --git a/src/mongo/db/index_builds_coordinator.cpp b/src/mongo/db/index_builds_coordinator.cpp
index 9bd1677a4d6..192b8371d84 100644
--- a/src/mongo/db/index_builds_coordinator.cpp
+++ b/src/mongo/db/index_builds_coordinator.cpp
@@ -1509,6 +1509,10 @@ void IndexBuildsCoordinator::restartIndexBuildsForRecovery(
}
}
+bool IndexBuildsCoordinator::noIndexBuildInProgress() const {
+ return activeIndexBuilds.getActiveIndexBuilds() == 0;
+}
+
int IndexBuildsCoordinator::numInProgForDb(StringData db) const {
auto indexBuildFilter = [db](const auto& replState) { return db == replState.dbName; };
auto dbIndexBuilds = activeIndexBuilds.filterIndexBuilds(indexBuildFilter);
diff --git a/src/mongo/db/index_builds_coordinator.h b/src/mongo/db/index_builds_coordinator.h
index 9e4325aecb5..0ae137f047b 100644
--- a/src/mongo/db/index_builds_coordinator.h
+++ b/src/mongo/db/index_builds_coordinator.h
@@ -342,6 +342,11 @@ public:
const CommitQuorumOptions& newCommitQuorum) = 0;
/**
+ * Returns true if there are no index builds in progress.
+ */
+ bool noIndexBuildInProgress() const;
+
+ /**
* Returns the number of index builds that are running on the specified database.
*/
int numInProgForDb(StringData db) const;
diff --git a/src/mongo/db/repl/SConscript b/src/mongo/db/repl/SConscript
index 7d82b153607..499f5de261a 100644
--- a/src/mongo/db/repl/SConscript
+++ b/src/mongo/db/repl/SConscript
@@ -298,6 +298,7 @@ env.Library(
],
LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/base',
+ '$BUILD_DIR/mongo/db/index_builds_coordinator_interface',
'$BUILD_DIR/mongo/db/storage/journal_flusher',
'$BUILD_DIR/mongo/db/storage/storage_control',
'$BUILD_DIR/mongo/db/storage/storage_options',
diff --git a/src/mongo/db/repl/replication_recovery.cpp b/src/mongo/db/repl/replication_recovery.cpp
index 0eff812175e..7d940aaa58f 100644
--- a/src/mongo/db/repl/replication_recovery.cpp
+++ b/src/mongo/db/repl/replication_recovery.cpp
@@ -38,6 +38,7 @@
#include "mongo/db/catalog/document_validation.h"
#include "mongo/db/db_raii.h"
#include "mongo/db/dbdirectclient.h"
+#include "mongo/db/index_builds_coordinator.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/repl/apply_ops.h"
@@ -363,11 +364,15 @@ void ReplicationRecoveryImpl::recoverFromOplogAsStandalone(OperationContext* opC
// Initial sync will reconstruct prepared transactions when it is completely done.
reconstructPreparedTransactions(opCtx, OplogApplication::Mode::kRecovering);
- LOGV2_WARNING(21558,
- "Setting mongod to readOnly mode as a result of specifying "
- "'recoverFromOplogAsStandalone'");
+ // Two-phase index builds are built in the background, which may still be in-progress after
+ // recovering from the oplog. To prevent crashing the server, skip enabling read-only mode.
+ if (IndexBuildsCoordinator::get(opCtx)->noIndexBuildInProgress()) {
+ LOGV2_WARNING(21558,
+ "Setting mongod to readOnly mode as a result of specifying "
+ "'recoverFromOplogAsStandalone'");
- storageGlobalParams.readOnly = true;
+ storageGlobalParams.readOnly = true;
+ }
}
}