summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Wlodarek <gregory.wlodarek@mongodb.com>2022-03-10 19:21:16 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-03-10 19:46:33 +0000
commitc084c1aafe116e90afcc1e6db35fd574f387311f (patch)
treeb69fea5acf8720a830960c7911a0d35d9af89e88
parentf07124df698a81e7e67023da45e8fad4d44e7628 (diff)
downloadmongo-c084c1aafe116e90afcc1e6db35fd574f387311f.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.cpp5
-rw-r--r--src/mongo/db/active_index_builds.h5
-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, 29 insertions, 4 deletions
diff --git a/src/mongo/db/active_index_builds.cpp b/src/mongo/db/active_index_builds.cpp
index bfacd4a7b95..017ca49ecc8 100644
--- a/src/mongo/db/active_index_builds.cpp
+++ b/src/mongo/db/active_index_builds.cpp
@@ -201,6 +201,11 @@ Status ActiveIndexBuilds::registerIndexBuild(
return Status::OK();
}
+size_t ActiveIndexBuilds::getActiveIndexBuilds() const {
+ stdx::unique_lock<Latch> lk(_mutex);
+ return _allIndexBuilds.size();
+}
+
void ActiveIndexBuilds::sleepIfNecessary_forTestOnly() const {
stdx::unique_lock<Latch> lk(_mutex);
while (_sleepForTest) {
diff --git a/src/mongo/db/active_index_builds.h b/src/mongo/db/active_index_builds.h
index 5ee2c010b5d..ec4f07f26cf 100644
--- a/src/mongo/db/active_index_builds.h
+++ b/src/mongo/db/active_index_builds.h
@@ -96,6 +96,11 @@ public:
Status registerIndexBuild(std::shared_ptr<ReplIndexBuildState> replIndexBuildState);
/**
+ * Get the number of in-progress index builds.
+ */
+ size_t getActiveIndexBuilds() const;
+
+ /**
* When _sleepForTest is true, this function will sleep for 100ms and then check the value
* of _sleepForTest again.
*/
diff --git a/src/mongo/db/index_builds_coordinator.cpp b/src/mongo/db/index_builds_coordinator.cpp
index 44c3ba76d90..ec74fb548ee 100644
--- a/src/mongo/db/index_builds_coordinator.cpp
+++ b/src/mongo/db/index_builds_coordinator.cpp
@@ -1467,6 +1467,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 a899477ca17..27e8f0dc432 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 f473cd1cdcc..358864a92cb 100644
--- a/src/mongo/db/repl/SConscript
+++ b/src/mongo/db/repl/SConscript
@@ -273,6 +273,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 2af2027aaec..6c6ccfc7b67 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"
@@ -356,10 +357,14 @@ void ReplicationRecoveryImpl::recoverFromOplogAsStandalone(OperationContext* opC
reconstructPreparedTransactions(opCtx, OplogApplication::Mode::kRecovering);
- LOGV2_WARNING(21558,
- "Setting mongod to readOnly mode as a result of specifying "
- "'recoverFromOplogAsStandalone'");
- storageGlobalParams.readOnly = true;
+ // 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;
+ }
}
void ReplicationRecoveryImpl::recoverFromOplogUpTo(OperationContext* opCtx, Timestamp endPoint) {