diff options
author | Gregory Wlodarek <gregory.wlodarek@mongodb.com> | 2022-03-10 19:21:16 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-03-10 19:46:33 +0000 |
commit | c084c1aafe116e90afcc1e6db35fd574f387311f (patch) | |
tree | b69fea5acf8720a830960c7911a0d35d9af89e88 | |
parent | f07124df698a81e7e67023da45e8fad4d44e7628 (diff) | |
download | mongo-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.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/active_index_builds.h | 5 | ||||
-rw-r--r-- | src/mongo/db/index_builds_coordinator.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/index_builds_coordinator.h | 5 | ||||
-rw-r--r-- | src/mongo/db/repl/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/repl/replication_recovery.cpp | 13 |
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) { |