MySQL 8.4.0
Source Code Documentation
open_files_limit.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 2021, 2024, Oracle and/or its affiliates.
4
5This program is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License, version 2.0, as published by the
7Free Software Foundation.
8
9This program is designed to work with certain software (including
10but not limited to OpenSSL) that is licensed under separate terms,
11as designated in a particular file or component or in included license
12documentation. The authors of MySQL hereby grant you an additional
13permission to link the program and your derivative works with the
14separately licensed software that they have either included with
15the program or referenced in the documentation.
16
17This program is distributed in the hope that it will be useful, but WITHOUT
18ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
20for more details.
21
22You should have received a copy of the GNU General Public License along with
23this program; if not, write to the Free Software Foundation, Inc.,
2451 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25
26*****************************************************************************/
27
28/** @file include/detail/fil/open_files_limit.h
29Implementation of innodb_open_files limit management. */
30
31#ifndef detail_fil_open_files_limit_h
32#define detail_fil_open_files_limit_h
33
34#include <atomic>
35
37
38bool fil_open_files_limit_update(size_t &new_max_open_files);
39
40namespace fil {
41namespace detail {
42
44 public:
45 Open_files_limit(size_t limit) : m_limit{limit}, m_old_limit{0} {
47#ifndef UNIV_HOTBACKUP
49#endif
50 }
52#ifndef UNIV_HOTBACKUP
54#endif
55 }
56 size_t get_limit() const { return m_limit.load(); }
57 bool set_desired_limit(size_t desired) {
58 /* Try to reserve right to change the limit. */
59 if (!m_is_change_in_progress.test_and_set()) {
60 /* We have a right to change the limit now. Now we can just store the old
61 limit and set the new desired one. */
62 m_old_limit = m_limit.load();
63 m_limit.store(desired);
64 DEBUG_SYNC_C("fil_open_files_desired_limit_set");
65 return true;
66 }
67 return false;
68 }
70 /* The old value must have been set to a valid value, which must be
71 MINIMUM_VALID_VALUE or more. */
74 }
76 /* The old value must have been set to a valid value, which must be
77 MINIMUM_VALID_VALUE or more. */
79 m_limit.store(m_old_limit);
81 }
82
83 private:
84#ifndef UNIV_HOTBACKUP
86 protected:
87 std::vector<srv::dynamic_procedure_data_t> get_procedures() const override {
91 }
92 std::string get_module_name() const override {
93 return "innodb_open_files_limit";
94 }
95
96 private:
97 static std::string get_procedure_name() {
98 return "innodb_set_open_files_limit";
99 }
100
102 unsigned char *,
103 unsigned char *) {
105 if (!sctx->has_global_grant(STRING_WITH_LEN("SYSTEM_VARIABLES_ADMIN"))
106 .first &&
107 !sctx->check_access(SUPER_ACL)) {
108 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0),
109 "SUPER or SYSTEM_VARIABLES_ADMIN");
110 return 0;
111 }
112 long long new_value_ll = *((long long *)args->args[0]);
113
114 if (new_value_ll < MINIMUM_VALID_VALUE) {
115 /* Complain with an error that the limit was not changed.
116 "Incorrect arguments to ..." */
117 std::string msg = get_procedure_name() +
118 ". New limit value can't be smaller than " +
120 my_error(ER_WRONG_ARGUMENTS, MYF(0), msg.c_str());
121 return 0;
122 }
123 if (new_value_ll > std::numeric_limits<int32_t>::max()) {
124 /* Complain with an error that the limit was not changed.
125 "Incorrect arguments to ..." */
126 std::string msg =
127 get_procedure_name() + ". New limit value can't be larger than " +
128 std::to_string(std::numeric_limits<int32_t>::max()) + ".";
129 my_error(ER_WRONG_ARGUMENTS, MYF(0), msg.c_str());
130 return 0;
131 }
132
133 size_t new_value = static_cast<size_t>(new_value_ll);
134 if (!fil_open_files_limit_update(new_value)) {
135 /* Complain with an error that the limit was not changed. */
136 if (new_value == 0) {
137 my_error(ER_CONCURRENT_PROCEDURE_USAGE, MYF(0),
138 get_procedure_name().c_str(), get_procedure_name().c_str());
139 } else {
140 /* "Incorrect arguments to ..." */
141 std::string msg =
143 ". Cannot update innodb_open_files to "
144 "this value. Not enough files could be closed in last 5 seconds "
145 "or a number of files that cannot be closed would exceed 90% of "
146 "the new limit. Consider setting it above " +
147 std::to_string(new_value) + ".";
148 my_error(ER_WRONG_ARGUMENTS, MYF(0), msg.c_str());
149 }
150 return 0;
151 }
152 return new_value_ll;
153 }
154
155 /** Initialize dynamic procedure innodb_set_open_files_limit */
157 char *message) {
158 if (args->arg_count != 1) {
159 snprintf(message, MYSQL_ERRMSG_SIZE, "Invalid number of arguments.");
160 return true;
161 }
162 if (args->args[0] == nullptr) {
163 snprintf(message, MYSQL_ERRMSG_SIZE,
164 "First argument must not be null.");
165 return true;
166 }
167 if (args->arg_type[0] != INT_RESULT) {
168 snprintf(message, MYSQL_ERRMSG_SIZE, "Invalid first argument type.");
169 return true;
170 }
171 return false;
172 }
173
174 /** Deinitialize dynamic procedure innodb_set_open_files_limit */
176 };
177
179#endif
180
181 /** The maximum limit for opened files. fil_n_files_open should not exceed
182 this. It can be changed dynamically by Fil_system::set_open_files_limit()
183 method. */
184 std::atomic<size_t> m_limit;
185
186 /** The old value of the limit when a change is in progress. It is used in
187 case we need to rollback.*/
189
190 /** Atomic flag stating if a change of the limit is in progress. Used to
191 disallow multiple threads from processing a limit change. */
192 std::atomic_flag m_is_change_in_progress;
193
194 /* Minimum valid value for the open_files_limit setting. */
195 static constexpr int MINIMUM_VALID_VALUE = 10;
196};
197
198} // namespace detail
199} // namespace fil
200
201#endif /* detail_fil_open_files_limit_h */
#define SUPER_ACL
Definition: auth_acls.h:66
A set of THD members describing the current authenticated user.
Definition: sql_security_ctx.h:53
bool check_access(ulong want_access, const std::string &db_name="", bool match_any=false)
Check permission against m_master_access.
Definition: sql_security_ctx.cc:322
std::pair< bool, bool > has_global_grant(const char *priv, size_t priv_len)
Checks if the Current_user has the asked dynamic privilege.
Definition: sql_security_ctx.cc:700
Security_context * security_context() const
Definition: sql_class.h:1324
Definition: open_files_limit.h:85
std::string get_module_name() const override
Definition: open_files_limit.h:92
static bool innodb_set_open_files_limit_init(UDF_INIT *, UDF_ARGS *args, char *message)
Initialize dynamic procedure innodb_set_open_files_limit.
Definition: open_files_limit.h:156
static long long innodb_set_open_files_limit(UDF_INIT *, UDF_ARGS *args, unsigned char *, unsigned char *)
Definition: open_files_limit.h:101
std::vector< srv::dynamic_procedure_data_t > get_procedures() const override
Definition: open_files_limit.h:87
static std::string get_procedure_name()
Definition: open_files_limit.h:97
static void innodb_set_open_files_limit_deinit(UDF_INIT *)
Deinitialize dynamic procedure innodb_set_open_files_limit.
Definition: open_files_limit.h:175
Definition: open_files_limit.h:43
std::atomic_flag m_is_change_in_progress
Atomic flag stating if a change of the limit is in progress.
Definition: open_files_limit.h:192
std::atomic< size_t > m_limit
The maximum limit for opened files.
Definition: open_files_limit.h:184
void revert_desired_limit()
Definition: open_files_limit.h:75
Dynamic_procedures m_dynamic_procedures
Definition: open_files_limit.h:178
static constexpr int MINIMUM_VALID_VALUE
Definition: open_files_limit.h:195
void commit_desired_limit()
Definition: open_files_limit.h:69
size_t get_limit() const
Definition: open_files_limit.h:56
~Open_files_limit()
Definition: open_files_limit.h:51
Open_files_limit(size_t limit)
Definition: open_files_limit.h:45
bool set_desired_limit(size_t desired)
Definition: open_files_limit.h:57
size_t m_old_limit
The old value of the limit when a change is in progress.
Definition: open_files_limit.h:188
Definition: srv0dynamic_procedures.h:90
void unregister()
Unregister dynamic SQL procedure.
Definition: srv0dynamic_procedures.h:138
bool register_procedures()
Register dynamic SQL procedure.
Definition: srv0dynamic_procedures.h:99
thread_local THD * current_thd
Definition: current_thd.cc:26
void my_error(int nr, myf MyFlags,...)
Fill in and print a previously registered error message.
Definition: my_error.cc:216
#define DEBUG_SYNC_C(_sync_point_name_)
Definition: my_sys.h:214
static std::string to_string(const LEX_STRING &str)
Definition: lex_string.h:50
#define MYF(v)
Definition: my_inttypes.h:97
#define MYSQL_ERRMSG_SIZE
Max length of a error message.
Definition: mysql_com.h:881
Definition: ut0tuple.h:57
Definition: open_files_limit.h:40
bool fil_open_files_limit_update(size_t &new_max_open_files)
Definition: fil0fil.cc:3620
Helper for managing dynamic SQL procedures.
#define STRING_WITH_LEN(X)
Definition: string_with_len.h:29
Definition: udf_registration_types.h:48
char ** args
Pointer to argument.
Definition: udf_registration_types.h:51
enum Item_result * arg_type
Pointer to item_results.
Definition: udf_registration_types.h:50
unsigned int arg_count
Number of arguments.
Definition: udf_registration_types.h:49
Information about the result of a user defined function.
Definition: udf_registration_types.h:66
@ INT_RESULT
double
Definition: udf_registration_types.h:43
#define ut_a(EXPR)
Abort execution if EXPR does not evaluate to nonzero.
Definition: ut0dbg.h:93