From 0422ef8481f70b919a29cb1a8f874b79689e0f89 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Tue, 21 Oct 2025 09:12:39 -0700 Subject: [PATCH] SERVER-112639 Fold fsync_locked back into fsync (#42833) GitOrigin-RevId: 7aa3095a8baa16e327f74bc66458305e146f3f20 --- bazel/docs/developer_workflow.md | 2 +- .../tasks/compile_tasks.yml | 4 +- src/mongo/db/BUILD.bazel | 2 +- src/mongo/db/commands/BUILD.bazel | 8 -- src/mongo/db/commands/fsync.cpp | 77 ++++++++++++++----- src/mongo/db/commands/fsync.h | 57 ++------------ src/mongo/db/commands/fsync_locked.cpp | 47 ----------- src/mongo/db/commands/fsync_locked.h | 46 ----------- .../db/commands/query_cmd/current_op.cpp | 2 +- src/mongo/db/exec/agg/current_op_stage.cpp | 2 +- src/mongo/db/mongod_main.cpp | 7 +- src/mongo/db/pipeline/BUILD.bazel | 2 +- .../db/service_entry_point_rs_endpoint.cpp | 2 +- .../service_entry_point_shard_role_helpers.h | 3 +- src/mongo/db/ttl/BUILD.bazel | 2 +- src/mongo/db/ttl/ttl_monitor.cpp | 2 +- 16 files changed, 77 insertions(+), 188 deletions(-) delete mode 100644 src/mongo/db/commands/fsync_locked.cpp delete mode 100644 src/mongo/db/commands/fsync_locked.h diff --git a/bazel/docs/developer_workflow.md b/bazel/docs/developer_workflow.md index 6eaf030b0ba..019bb44157f 100644 --- a/bazel/docs/developer_workflow.md +++ b/bazel/docs/developer_workflow.md @@ -87,7 +87,7 @@ Note: This feature is still in development; see https://jira.mongodb.org/browse/ To run clang-tidy via Bazel, do the following: 1. To analyze all code, run `bazel build --config=clang-tidy src/...` -2. To analyze a single target (e.g.: `fsync_locked`), run the following command (note that `_with_debug` suffix on the target): `bazel build --config=clang-tidy src/mongo/db/commands:fsync_locked_with_debug` +2. To analyze a single target (e.g.: `environment_buffer`), run the following command (note that `_with_debug` suffix on the target): `bazel build --config=clang-tidy src/mongo/db/commands:environment_buffer_with_debug` Testing notes: diff --git a/etc/evergreen_yml_components/tasks/compile_tasks.yml b/etc/evergreen_yml_components/tasks/compile_tasks.yml index 04a907fc393..38e6ba8281b 100644 --- a/etc/evergreen_yml_components/tasks/compile_tasks.yml +++ b/etc/evergreen_yml_components/tasks/compile_tasks.yml @@ -119,12 +119,12 @@ tasks: - func: "bazel compile" vars: targets: >- - //src/mongo/db/commands:fsync_locked_with_debug + //src/mongo/base:environment_buffer_with_debug bazel_args: >- --config=evg - func: "verify build output present" vars: - output: bazel-bin/src/mongo/db/commands/libfsync_locked_with_debug.lo + output: bazel-bin/src/mongo/base/libenvironment_buffer_with_debug.lo - name: run_bazel_program tags: ["assigned_to_jira_team_devprod_build", "auxiliary", "bazel_check"] diff --git a/src/mongo/db/BUILD.bazel b/src/mongo/db/BUILD.bazel index 63621b5a033..a4c966cebfb 100644 --- a/src/mongo/db/BUILD.bazel +++ b/src/mongo/db/BUILD.bazel @@ -3064,7 +3064,7 @@ mongo_cc_library( "//src/mongo/db/auth:authprivilege", "//src/mongo/db/auth:security_token_auth", "//src/mongo/db/auth:user_acquisition_stats", - "//src/mongo/db/commands:fsync_locked", + "//src/mongo/db/commands:mongod_fsync", "//src/mongo/db/commands:txn_cmd_request", "//src/mongo/db/commands/server_status:server_status_core", "//src/mongo/db/repl:repl_server_parameters", diff --git a/src/mongo/db/commands/BUILD.bazel b/src/mongo/db/commands/BUILD.bazel index 1735b765d57..ddc7330325f 100644 --- a/src/mongo/db/commands/BUILD.bazel +++ b/src/mongo/db/commands/BUILD.bazel @@ -9,12 +9,6 @@ exports_files( ]), ) -mongo_cc_library( - name = "fsync_locked", - srcs = ["fsync_locked.cpp"], - hdrs = ["fsync_locked.h"], -) - idl_generator( name = "test_commands_enabled_gen", src = "test_commands_enabled.idl", @@ -600,7 +594,6 @@ mongo_cc_library( "fsync.h", ], deps = [ - ":fsync_locked", "//src/mongo/db:commands", "//src/mongo/db:dbdirectclient", "//src/mongo/db/auth", @@ -957,7 +950,6 @@ mongo_cc_library( "buildinfo_common", "core", "create_command", - "fsync_locked", "kill_common", "list_collections_filter", "list_databases_command", diff --git a/src/mongo/db/commands/fsync.cpp b/src/mongo/db/commands/fsync.cpp index a32f01e0cb8..1af5818dd98 100644 --- a/src/mongo/db/commands/fsync.cpp +++ b/src/mongo/db/commands/fsync.cpp @@ -27,13 +27,9 @@ * it in the license file. */ - -// IWYU pragma: no_include "cxxabi.h" #include "mongo/db/commands/fsync.h" #include "mongo/base/error_codes.h" -#include "mongo/base/init.h" // IWYU pragma: keep -#include "mongo/base/initializer.h" #include "mongo/base/status.h" #include "mongo/base/string_data.h" #include "mongo/bson/bsonelement.h" @@ -45,7 +41,6 @@ #include "mongo/db/client.h" #include "mongo/db/commands.h" #include "mongo/db/commands/fsync_gen.h" -#include "mongo/db/commands/fsync_locked.h" #include "mongo/db/commands/test_commands_enabled.h" #include "mongo/db/database_name.h" #include "mongo/db/dbdirectclient.h" @@ -60,6 +55,7 @@ #include "mongo/logv2/log.h" #include "mongo/stdx/condition_variable.h" #include "mongo/util/assert_util.h" +#include "mongo/util/background.h" #include "mongo/util/duration.h" #include "mongo/util/str.h" @@ -70,6 +66,46 @@ #define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kCommand namespace mongo { +namespace { +/** + * Maintains a global read lock while mongod is fsyncLocked. + */ +class FSyncLockThread final : public BackgroundJob { +public: + FSyncLockThread(ServiceContext* serviceContext, + bool allowFsyncFailure, + const Milliseconds deadline) + : BackgroundJob(false), + _serviceContext(serviceContext), + _allowFsyncFailure(allowFsyncFailure), + _deadline(deadline) {} + + std::string name() const override { + return "FSyncLockThread"; + } + + void run() override; + + /** + * Releases the fsync lock for shutdown. + */ + void shutdown(stdx::unique_lock& lk); + +private: + /** + * Wait lastApplied to catch lastWritten so we won't write/apply any oplog when fsync locked. + */ + void _waitUntilLastAppliedCatchupLastWritten(); + +private: + ServiceContext* const _serviceContext; + bool _allowFsyncFailure; + const Milliseconds _deadline; +}; + +// Ensures that only one command is operating on fsyncLock state at a time. As a 'ResourceMutex', +// lock time will be reported for a given user operation. +Lock::ResourceMutex fsyncSingleCommandExclusionMutex("fsyncSingleCommandExclusionMutex"); // Protects access to globalFsyncLockThread and other global fsync state. stdx::mutex fsyncStateMutex; @@ -78,16 +114,6 @@ stdx::mutex fsyncStateMutex; // Must acquire the 'fsyncStateMutex' before accessing. std::unique_ptr globalFsyncLockThread = nullptr; -// Exposed publically via extern in fsync.h. -stdx::mutex oplogWriterLockedFsync; -stdx::mutex oplogApplierLockedFsync; - -namespace { - -// Ensures that only one command is operating on fsyncLock state at a time. As a 'ResourceMutex', -// lock time will be reported for a given user operation. -Lock::ResourceMutex fsyncSingleCommandExclusionMutex("fsyncSingleCommandExclusionMutex"); - class FSyncCore { public: static const char* url() { @@ -283,8 +309,7 @@ private: stdx::mutex _fsyncLockedMutex; bool _fsyncLocked = false; -}; -FSyncCore fsyncCore; +} fsyncCore; class FSyncCommand : public TypedCommand { public: @@ -419,8 +444,6 @@ bool FSyncCore::runFsyncUnlockCommand(OperationContext* opCtx, } } -} // namespace - void FSyncLockThread::shutdown(stdx::unique_lock& stateLock) { if (fsyncCore.getLockCount_inLock() > 0) { LOGV2_WARNING(20469, "Interrupting fsync because the server is shutting down"); @@ -543,9 +566,21 @@ void FSyncLockThread::run() { LOGV2_FATAL(40350, "FSyncLockThread exception", "error"_attr = e.what()); } } +} // namespace -MONGO_INITIALIZER(fsyncLockedForWriting)(InitializerContext* context) { - setLockedForWritingImpl([]() { return fsyncCore.fsyncLocked(); }); +// Exposed publicly via extern in fsync.h. +stdx::mutex oplogWriterLockedFsync; +stdx::mutex oplogApplierLockedFsync; + +bool lockedForWriting() { + return fsyncCore.fsyncLocked(); +} + +void shutdownFsyncLockThread() { + stdx::unique_lock stateLock(fsyncStateMutex); + if (globalFsyncLockThread) { + globalFsyncLockThread->shutdown(stateLock); + } } } // namespace mongo diff --git a/src/mongo/db/commands/fsync.h b/src/mongo/db/commands/fsync.h index ddb74dc3d24..38a55148a69 100644 --- a/src/mongo/db/commands/fsync.h +++ b/src/mongo/db/commands/fsync.h @@ -29,50 +29,21 @@ #pragma once -#include "mongo/db/service_context.h" #include "mongo/stdx/mutex.h" -#include "mongo/util/background.h" +#include "mongo/util/modules.h" -#include -#include +MONGO_MOD_PUBLIC; namespace mongo { +/** + * Returns true if mongod is currently fsyncLocked. + */ +bool lockedForWriting(); /** - * Maintains a global read lock while mongod is fsyncLocked. + * If the fsynclock thread has been created, shut it down. */ -class FSyncLockThread : public BackgroundJob { -public: - FSyncLockThread(ServiceContext* serviceContext, - bool allowFsyncFailure, - const Milliseconds deadline) - : BackgroundJob(false), - _serviceContext(serviceContext), - _allowFsyncFailure(allowFsyncFailure), - _deadline(deadline) {} - - std::string name() const override { - return "FSyncLockThread"; - } - - void run() override; - - /** - * Releases the fsync lock for shutdown. - */ - void shutdown(stdx::unique_lock& lk); - -private: - /** - * Wait lastApplied to catch lastWritten so we won't write/apply any oplog when fsync locked. - */ - void _waitUntilLastAppliedCatchupLastWritten(); - -private: - ServiceContext* const _serviceContext; - bool _allowFsyncFailure; - const Milliseconds _deadline; -}; +void shutdownFsyncLockThread(); /** * This is used to block oplogWriter and should never be acquired by others. @@ -83,16 +54,4 @@ extern stdx::mutex oplogWriterLockedFsync; * This is used to block oplogApplier and should never be acquired by others. */ extern stdx::mutex oplogApplierLockedFsync; - -/** - * Must be taken before accessing globalFsyncLockThread below. - */ -extern stdx::mutex fsyncStateMutex; - -/** - * The FSyncLockThread must be external available for interruption during shutdown. - * Must lock the 'fsyncStateMutex' before accessing. - */ -extern std::unique_ptr globalFsyncLockThread; - } // namespace mongo diff --git a/src/mongo/db/commands/fsync_locked.cpp b/src/mongo/db/commands/fsync_locked.cpp deleted file mode 100644 index d868b822374..00000000000 --- a/src/mongo/db/commands/fsync_locked.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Copyright (C) 2018-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 - * . - * - * 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. - */ - -#include "mongo/db/commands/fsync_locked.h" - -#include -#include - -namespace mongo { -namespace { -std::function lockedForWritingImpl; -} // namespace - -bool lockedForWriting() { - return lockedForWritingImpl(); -} - -void setLockedForWritingImpl(std::function impl) { - lockedForWritingImpl = std::move(impl); -} -} // namespace mongo diff --git a/src/mongo/db/commands/fsync_locked.h b/src/mongo/db/commands/fsync_locked.h deleted file mode 100644 index 89e8f8c55ba..00000000000 --- a/src/mongo/db/commands/fsync_locked.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright (C) 2018-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 - * . - * - * 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 - -namespace mongo { -/** - * Returns true if mongod is currently fsyncLocked. - */ -bool lockedForWriting(); - -/** - * Sets the implementation for lockedForWriting(). Should be done once during startup in a - * MONGO_INITIALIZER. - */ -void setLockedForWritingImpl(std::function impl); - -} // namespace mongo diff --git a/src/mongo/db/commands/query_cmd/current_op.cpp b/src/mongo/db/commands/query_cmd/current_op.cpp index 2d5625aeca5..9081a46e5e7 100644 --- a/src/mongo/db/commands/query_cmd/current_op.cpp +++ b/src/mongo/db/commands/query_cmd/current_op.cpp @@ -38,7 +38,7 @@ #include "mongo/db/auth/privilege.h" #include "mongo/db/auth/resource_pattern.h" #include "mongo/db/commands.h" -#include "mongo/db/commands/fsync_locked.h" +#include "mongo/db/commands/fsync.h" #include "mongo/db/commands/query_cmd/current_op_common.h" #include "mongo/db/commands/query_cmd/run_aggregate.h" #include "mongo/db/database_name.h" diff --git a/src/mongo/db/exec/agg/current_op_stage.cpp b/src/mongo/db/exec/agg/current_op_stage.cpp index 360ac26fb70..3b70b5fed67 100644 --- a/src/mongo/db/exec/agg/current_op_stage.cpp +++ b/src/mongo/db/exec/agg/current_op_stage.cpp @@ -29,7 +29,7 @@ #include "mongo/db/exec/agg/current_op_stage.h" -#include "mongo/db/commands/fsync_locked.h" +#include "mongo/db/commands/fsync.h" #include "mongo/db/exec/agg/document_source_to_stage_registry.h" #include "mongo/db/pipeline/document_source_current_op.h" diff --git a/src/mongo/db/mongod_main.cpp b/src/mongo/db/mongod_main.cpp index 3df07d886bb..1556f6755dd 100644 --- a/src/mongo/db/mongod_main.cpp +++ b/src/mongo/db/mongod_main.cpp @@ -1478,12 +1478,7 @@ void shutdownTask(const ShutdownTaskArgs& shutdownArgs) { BSONObjBuilder shutdownInfoBuilder; // Before doing anything else, ensure fsync is inactive or make it release its GlobalRead lock. - { - stdx::unique_lock stateLock(fsyncStateMutex); - if (globalFsyncLockThread) { - globalFsyncLockThread->shutdown(stateLock); - } - } + shutdownFsyncLockThread(); auto const serviceContext = getGlobalServiceContext(); diff --git a/src/mongo/db/pipeline/BUILD.bazel b/src/mongo/db/pipeline/BUILD.bazel index 5bf563dc04c..e82a0443f11 100644 --- a/src/mongo/db/pipeline/BUILD.bazel +++ b/src/mongo/db/pipeline/BUILD.bazel @@ -825,7 +825,7 @@ mongo_cc_library( "//src/mongo/db:shard_filterer", "//src/mongo/db:shard_role_api", "//src/mongo/db/auth", - "//src/mongo/db/commands:fsync_locked", + "//src/mongo/db/commands:mongod_fsync", "//src/mongo/db/commands:test_commands_enabled", "//src/mongo/db/exec:bucket_unpacker", "//src/mongo/db/exec:projection_executor", diff --git a/src/mongo/db/service_entry_point_rs_endpoint.cpp b/src/mongo/db/service_entry_point_rs_endpoint.cpp index e4732a031a8..15fb84ba383 100644 --- a/src/mongo/db/service_entry_point_rs_endpoint.cpp +++ b/src/mongo/db/service_entry_point_rs_endpoint.cpp @@ -36,7 +36,7 @@ #include "mongo/bson/bsonobjbuilder.h" #include "mongo/db/client.h" #include "mongo/db/commands.h" -#include "mongo/db/commands/fsync_locked.h" +#include "mongo/db/commands/fsync.h" #include "mongo/db/curop.h" #include "mongo/db/global_catalog/catalog_cache/catalog_cache.h" #include "mongo/db/global_catalog/catalog_cache/shard_cannot_refresh_due_to_locks_held_exception.h" diff --git a/src/mongo/db/service_entry_point_shard_role_helpers.h b/src/mongo/db/service_entry_point_shard_role_helpers.h index 933fd96cd34..253c84183ec 100644 --- a/src/mongo/db/service_entry_point_shard_role_helpers.h +++ b/src/mongo/db/service_entry_point_shard_role_helpers.h @@ -28,6 +28,7 @@ */ #pragma once + #include "mongo/base/error_codes.h" #include "mongo/base/status.h" #include "mongo/base/status_with.h" @@ -35,7 +36,7 @@ #include "mongo/bson/bsonobjbuilder.h" #include "mongo/db/client.h" #include "mongo/db/commands.h" -#include "mongo/db/commands/fsync_locked.h" +#include "mongo/db/commands/fsync.h" #include "mongo/db/curop.h" #include "mongo/db/global_catalog/catalog_cache/catalog_cache.h" #include "mongo/db/global_catalog/catalog_cache/shard_cannot_refresh_due_to_locks_held_exception.h" diff --git a/src/mongo/db/ttl/BUILD.bazel b/src/mongo/db/ttl/BUILD.bazel index c62a7c7a426..dfa1822a8ad 100644 --- a/src/mongo/db/ttl/BUILD.bazel +++ b/src/mongo/db/ttl/BUILD.bazel @@ -47,7 +47,7 @@ mongo_cc_library( "//src/mongo/db:server_base", "//src/mongo/db:service_context", "//src/mongo/db:shard_role", - "//src/mongo/db/commands:fsync_locked", + "//src/mongo/db/commands:mongod_fsync", "//src/mongo/db/commands/server_status:server_status_core", "//src/mongo/db/local_catalog:catalog_helpers", "//src/mongo/db/local_catalog:index_key_validate", diff --git a/src/mongo/db/ttl/ttl_monitor.cpp b/src/mongo/db/ttl/ttl_monitor.cpp index 989df6ca201..c89c4fb441d 100644 --- a/src/mongo/db/ttl/ttl_monitor.cpp +++ b/src/mongo/db/ttl/ttl_monitor.cpp @@ -37,7 +37,7 @@ #include "mongo/db/admission/execution_admission_context.h" #include "mongo/db/auth/authorization_session.h" #include "mongo/db/client.h" -#include "mongo/db/commands/fsync_locked.h" +#include "mongo/db/commands/fsync.h" #include "mongo/db/commands/server_status/server_status_metric.h" #include "mongo/db/exec/classic/batched_delete_stage.h" #include "mongo/db/exec/classic/delete_stage.h"