MySQL 26.7.0
Source Code Documentation
resource_monitor.h
Go to the documentation of this file.
1// Copyright (c) 2026, Oracle and/or its affiliates.
2//
3// This program is free software; you can redistribute it and/or modify
4// it under the terms of the GNU General Public License, version 2.0,
5// as published by the Free Software Foundation.
6//
7// This program is designed to work with certain software (including
8// but not limited to OpenSSL) that is licensed under separate terms,
9// as designated in a particular file or component or in included license
10// documentation. The authors of MySQL hereby grant you an additional
11// permission to link the program and your derivative works with the
12// separately licensed software that they have either included with
13// the program or referenced in the documentation.
14//
15// This program is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License, version 2.0, for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with this program; if not, write to the Free Software
22// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
23
24#ifndef MYSQL_CSA_RESOURCE_MONITOR_H
25#define MYSQL_CSA_RESOURCE_MONITOR_H
26
27#include <mysql/psi/psi_stage.h>
28#include <array>
29#include <atomic>
30#include <chrono>
31#include <memory>
32#include <string>
33#include <unordered_map>
35
36namespace mysql::csa {
37
38struct Resource_entry;
39struct Locked_resource;
40
41class Resource_instance_monitor;
43 std::reference_wrapper<Resource_instance_monitor>;
44
45/// @brief Manages per-channel resources for the Change Stream Applier (CSA).
46/// Allows registering named resources and locking/releasing them.
47/// @details This class provides a registry for named resources, each with a
48/// configurable limit on maximum available units. Resources can be acquired
49/// (locked) using blocking (infinite wait) or non-blocking methods (try lock),
50/// and released. It is designed for concurrent access, using atomic operations
51/// for counts and spinning with sleep for waiting. One instance is
52/// created per channel via Resource_monitor::get(instance_id).
53///
54/// Usage assumptions:
55/// 1. To avoid deadlocks between locking applier resources by different threads
56/// and transaction locks, a resource for a transaction should be locked before
57/// this transaction starts.
58/// 2. All resources must be registered before first call to concurrent methods
59/// (register_resource is non-concurrent)
60///
61/// Main functions:
62/// - register_resource - for named resource registraction
63/// - acquire_resource - get resource lock object (releases at destruction)
64///
65/// Key concepts of resource acquisition:
66/// - Each resource has a 'limit' (maximum available units) set at registration.
67/// - 'available' tracks current free units.
68/// - For requests <= limit, standard semaphore-like behavior (wait for
69/// available >= amount).
70/// - For requests > limit, wait for available equal to limit
71/// - All waiting uses spinning with a constant sleep (1ms) to avoid
72/// indefinite blocks.
73/// - Suitable for resources like channel memory limit in the applier.
74///
76 public:
77 /// @brief Registers a named resource with the given limit (maximum
78 /// available)
79 /// @param name The name of the resource.
80 /// @param limit The maximum available count for this resource.
81 /// @param stage Optional PSI stage to set during waiting for lock.
82 void register_resource(const std::string &name, std::size_t limit,
83 PSI_stage_info *stage = nullptr);
84
85 /// @brief Function locks resource and returns resource guard that will
86 /// release the resource if locked upon destruction
87 /// @param name The name of the resource.
88 /// @param amount The amount to lock.
89 /// @return Locked_resource object
90 Locked_resource acquire_resource(const std::string &name, std::size_t amount);
91
92 /// @brief Releases the specified amount of the named resource. Wait-free.
93 /// @param name The name of the resource.
94 /// @param amount The amount to release.
95 void release_resource(const std::string &name, std::size_t amount);
96
97 /// @brief Waits until the requested resource amount is available or returns
98 /// an error. Wait-free in case resource is available in the first check.
99 /// @param name The name of the resource.
100 /// @param amount The amount to lock.
101 /// @return True when successfully locked. False if exited before obtaining.
102 bool lock_resource(const std::string &name, std::size_t amount);
103
104 /// @brief Releases the specified amount of the named resource. Wait-free.
105 /// @param resource Resource handle
106 /// @param amount The amount to release.
107 static void release_resource(Resource_entry &resource, std::size_t amount);
108
109 /// @brief Waits until the requested resource amount is available or returns
110 /// an error. Wait-free in case resource is available in the first check.
111 /// @param resource Resource handle
112 /// @param amount The amount to lock.
113 /// @return True when successfully locked. False if exited before obtaining.
114 static bool lock_resource(Resource_entry &resource, std::size_t amount);
115
117
118 private:
119 /// Internal function that optimistically tries to lock resource without
120 /// spinning. Performs a single atomic attempt: subtracts the amount and
121 /// succeeds if the previous available was >= amount or == limit (even for
122 /// amount > limit). Wait-free; rolls back on failure.
123 /// @param resource_entry Resource handle
124 /// @param amount Amount of the resource to lock
125 /// @return True on success, false when could not lock resource.
126 static bool try_lock_resource_internal(Resource_entry &resource_entry,
127 std::size_t amount);
128
130 std::unordered_map<std::string, std::unique_ptr<Resource_entry>>;
132};
133
134/// @brief Singleton Resource Monitor for all channels/instances.
135/// Provides one Resource_instance_monitor per channel.
137 public:
138 /// @brief Get the Resource_instance_monitor for the given channel/instance
139 /// ID.
140 /// @param instance_id The ID of the channel/instance.
141 /// @return Reference to the Resource_instance_monitor.
142 static Resource_instance_monitor &get(std::size_t instance_id);
143
144 protected:
145 Resource_monitor() = default;
146
149
150 /// Instances for separate channels, may be accessed concurrently between
151 /// channel threads
153};
154
155/// Resource guard class, used to check if resource was successfully locked and
156/// release resource in destructor
158 public:
159 /// Default construct
160 Locked_resource() = default;
161 /// Construct
162 /// @param resource Resource handle
163 /// @param requested The requested amount
164 /// @param locked True if successfully locked
165 Locked_resource(Resource_entry *resource, std::size_t requested, bool locked);
166 /// Check if resource is locked
167 bool is_locked() const;
168 /// Unlocks resource if locked
170
171 // disable copy-move semantics
173 Locked_resource &operator=(Locked_resource &&) noexcept = delete;
175 Locked_resource &operator=(const Locked_resource &) = delete;
176
177 private:
178 /// Resource handle
180 /// Requested amount
181 std::size_t m_requested_amount{0};
182 /// True if successfully locked
183 bool m_is_locked{false};
184};
185
186/// @brief Entry for a named resource, managing available count and
187/// synchronization.
189 /// Currently available amount of the resource
190 std::atomic<long long> m_available{0};
191 /// Resource limit
192 std::atomic<long long> m_limit{0};
193 /// Waiting stage set only if the requested amount is higher than currently
194 /// available and thread waits for the resource to be released
196 /// Default constructible
197 Resource_entry() = default;
198};
199
200} // namespace mysql::csa
201
202#endif // MYSQL_CSA_RESOURCE_MONITOR_H
Manages per-channel resources for the Change Stream Applier (CSA).
Definition: resource_monitor.h:75
static bool try_lock_resource_internal(Resource_entry &resource_entry, std::size_t amount)
Internal function that optimistically tries to lock resource without spinning.
Definition: resource_monitor.cpp:100
Locked_resource acquire_resource(const std::string &name, std::size_t amount)
Function locks resource and returns resource guard that will release the resource if locked upon dest...
Definition: resource_monitor.cpp:78
void register_resource(const std::string &name, std::size_t limit, PSI_stage_info *stage=nullptr)
Registers a named resource with the given limit (maximum available)
Definition: resource_monitor.cpp:40
void release_resource(const std::string &name, std::size_t amount)
Releases the specified amount of the named resource.
Definition: resource_monitor.cpp:112
Resource_map m_resources
Definition: resource_monitor.h:131
bool lock_resource(const std::string &name, std::size_t amount)
Waits until the requested resource amount is available or returns an error.
Definition: resource_monitor.cpp:89
std::unordered_map< std::string, std::unique_ptr< Resource_entry > > Resource_map
Definition: resource_monitor.h:130
Singleton Resource Monitor for all channels/instances.
Definition: resource_monitor.h:136
static Instances_map m_instances
Instances for separate channels, may be accessed concurrently between channel threads.
Definition: resource_monitor.h:152
static Resource_instance_monitor & get(std::size_t instance_id)
Get the Resource_instance_monitor for the given channel/instance ID.
Definition: resource_monitor.cpp:35
std::array< Resource_instance_monitor, scheduler::Constants::max_instances > Instances_map
Definition: resource_monitor.h:148
Definition: channel.cpp:28
std::reference_wrapper< Resource_instance_monitor > Resource_instance_monitor_ref
Definition: resource_monitor.h:43
noexcept
The return type for any call_and_catch(f, args...) call where f(args...) returns Type.
Definition: call_and_catch.h:76
Performance schema instrumentation interface.
case opt name
Definition: sslopt-case.h:29
Stage instrument information.
Definition: psi_stage_bits.h:74
Resource guard class, used to check if resource was successfully locked and release resource in destr...
Definition: resource_monitor.h:157
std::size_t m_requested_amount
Requested amount.
Definition: resource_monitor.h:181
Locked_resource()=default
Default construct.
~Locked_resource()
Unlocks resource if locked.
Definition: resource_monitor.cpp:131
bool m_is_locked
True if successfully locked.
Definition: resource_monitor.h:183
Resource_entry * m_resource
Resource handle.
Definition: resource_monitor.h:179
bool is_locked() const
Check if resource is locked.
Definition: resource_monitor.cpp:129
Locked_resource(Locked_resource &&) noexcept=delete
Entry for a named resource, managing available count and synchronization.
Definition: resource_monitor.h:188
PSI_stage_info * m_stage
Waiting stage set only if the requested amount is higher than currently available and thread waits fo...
Definition: resource_monitor.h:195
Resource_entry()=default
Default constructible.
std::atomic< long long > m_limit
Resource limit.
Definition: resource_monitor.h:192
std::atomic< long long > m_available
Currently available amount of the resource.
Definition: resource_monitor.h:190
static constexpr unsigned int max_instances
The maximum number of scheduler instances supported This value should be aligned with the 'MAX_CHANNE...
Definition: constants.h:34