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