1 /* Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved.
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 also distributed 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 included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23 /**
24 @file
25 Definitions of all server's session or global variables.
26
27 How to add new variables:
28
29 1. copy one of the existing variables, and edit the declaration.
30 2. if you need special behavior on assignment or additional checks
31 use ON_CHECK and ON_UPDATE callbacks.
32 3. *Don't* add new Sys_var classes or uncle Occam will come
33 with his razor to haunt you at nights
34
35 Note - all storage engine variables (for example myisam_whatever)
36 should go into the corresponding storage engine sources
37 (for example in storage/myisam/ha_myisam.cc) !
38 */
39
40 #include "sql/sys_vars.h"
41
42 #include "my_config.h"
43
44 #include <assert.h>
45 #include <limits.h>
46 #include <math.h>
47 #include <stdint.h>
48 #include <stdio.h>
49 #include <sys/stat.h>
50 #include <zlib.h>
51 #include <atomic>
52 #include <limits>
53
54 #include "include/compression.h"
55
56 #include "my_loglevel.h"
57 #include "mysql/components/services/log_builtins.h"
58 #include "mysql/components/services/log_shared.h"
59 #include "mysql_com.h"
60 #include "sql/protocol.h"
61 #include "sql/rpl_trx_tracking.h"
62 #ifdef HAVE_SYS_TIME_H
63 #include <sys/time.h>
64 #endif
65 #ifdef HAVE_UNISTD_H
66 #include <unistd.h>
67 #endif
68 #include <algorithm>
69 #include <map>
70 #include <utility>
71
72 #include "ft_global.h"
73 #include "libbinlogevents/include/binlog_event.h"
74 #include "m_string.h"
75 #include "my_aes.h" // my_aes_opmode_names
76 #include "my_command.h"
77 #include "my_compiler.h"
78 #include "my_dbug.h"
79 #include "my_dir.h"
80 #include "my_double2ulonglong.h"
81 #include "my_io.h"
82 #include "my_macros.h"
83 #include "my_sqlcommand.h"
84 #include "my_thread.h"
85 #include "my_thread_local.h"
86 #include "my_time.h"
87 #include "myisam.h" // myisam_flush
88 #include "mysql/components/services/log_builtins.h"
89 #include "mysql/plugin_group_replication.h"
90 #include "mysql/psi/mysql_mutex.h"
91 #include "mysql_version.h"
92 #include "sql/auth/auth_acls.h"
93 #include "sql/auth/auth_common.h" // validate_user_plugins
94 #include "sql/binlog.h" // mysql_bin_log
95 #include "sql/clone_handler.h"
96 #include "sql/conn_handler/connection_handler_impl.h" // Per_thread_connection_handler
97 #include "sql/conn_handler/connection_handler_manager.h" // Connection_handler_manager
98 #include "sql/conn_handler/socket_connection.h" // MY_BIND_ALL_ADDRESSES
99 #include "sql/derror.h" // read_texts
100 #include "sql/discrete_interval.h"
101 #include "sql/events.h" // Events
102 #include "sql/hostname_cache.h" // host_cache_resize
103 #include "sql/log.h"
104 #include "sql/log_event.h" // MAX_MAX_ALLOWED_PACKET
105 #include "sql/mdl.h"
106 #include "sql/my_decimal.h"
107 #include "sql/opt_trace_context.h"
108 #include "sql/options_mysqld.h"
109 #include "sql/protocol_classic.h"
110 #include "sql/psi_memory_key.h"
111 #include "sql/query_options.h"
112 #include "sql/rpl_group_replication.h" // is_group_replication_running
113 #include "sql/rpl_info_factory.h" // Rpl_info_factory
114 #include "sql/rpl_info_handler.h" // INFO_REPOSITORY_TABLE
115 #include "sql/rpl_log_encryption.h"
116 #include "sql/rpl_mi.h" // Master_info
117 #include "sql/rpl_msr.h" // channel_map
118 #include "sql/rpl_mts_submode.h" // MTS_PARALLEL_TYPE_DB_NAME
119 #include "sql/rpl_rli.h" // Relay_log_info
120 #include "sql/rpl_slave.h" // SLAVE_THD_TYPE
121 #include "sql/rpl_write_set_handler.h" // transaction_write_set_hashing_algorithms
122 #include "sql/server_component/log_builtins_filter_imp.h" // until we have pluggable variables
123 #include "sql/server_component/log_builtins_imp.h"
124 #include "sql/session_tracker.h"
125 #include "sql/sp_head.h" // SP_PSI_STATEMENT_INFO_COUNT
126 #include "sql/sql_backup_lock.h" // is_instance_backup_locked
127 #include "sql/sql_lex.h"
128 #include "sql/sql_locale.h" // my_locale_by_number
129 #include "sql/sql_parse.h" // killall_non_super_threads
130 #include "sql/sql_tmp_table.h" // internal_tmp_mem_storage_engine_names
131 #include "sql/ssl_acceptor_context_operator.h"
132 #include "sql/system_variables.h"
133 #include "sql/table_cache.h" // Table_cache_manager
134 #include "sql/transaction.h" // trans_commit_stmt
135 #include "sql/transaction_info.h"
136 #include "sql/xa.h"
137 #include "template_utils.h" // pointer_cast
138 #include "thr_lock.h"
139 #ifdef _WIN32
140 #include "sql/named_pipe.h"
141 #endif
142
143 #ifdef WITH_LOCK_ORDER
144 #include "sql/debug_lock_order.h"
145 #endif /* WITH_LOCK_ORDER */
146
147 #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
148 #include "storage/perfschema/pfs_server.h"
149 #endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
150
151 TYPELIB bool_typelib = {array_elements(bool_values) - 1, "", bool_values,
152 nullptr};
153
update_buffer_size(THD *,KEY_CACHE * key_cache,ptrdiff_t offset MY_ATTRIBUTE ((unused)),ulonglong new_value)154 static bool update_buffer_size(THD *, KEY_CACHE *key_cache,
155 ptrdiff_t offset MY_ATTRIBUTE((unused)),
156 ulonglong new_value) {
157 bool error = false;
158 DBUG_ASSERT(offset == offsetof(KEY_CACHE, param_buff_size));
159
160 if (new_value == 0) {
161 if (key_cache == dflt_key_cache) {
162 my_error(ER_WARN_CANT_DROP_DEFAULT_KEYCACHE, MYF(0));
163 return true;
164 }
165
166 if (key_cache->key_cache_inited) // If initied
167 {
168 /*
169 Move tables using this key cache to the default key cache
170 and clear the old key cache.
171 */
172 key_cache->in_init = true;
173 mysql_mutex_unlock(&LOCK_global_system_variables);
174 key_cache->param_buff_size = 0;
175 ha_resize_key_cache(key_cache);
176 ha_change_key_cache(key_cache, dflt_key_cache);
177 /*
178 We don't delete the key cache as some running threads my still be in
179 the key cache code with a pointer to the deleted (empty) key cache
180 */
181 mysql_mutex_lock(&LOCK_global_system_variables);
182 key_cache->in_init = false;
183 }
184 return error;
185 }
186
187 key_cache->param_buff_size = new_value;
188
189 /* If key cache didn't exist initialize it, else resize it */
190 key_cache->in_init = true;
191 mysql_mutex_unlock(&LOCK_global_system_variables);
192
193 if (!key_cache->key_cache_inited)
194 error = ha_init_key_cache(nullptr, key_cache);
195 else
196 error = ha_resize_key_cache(key_cache);
197
198 mysql_mutex_lock(&LOCK_global_system_variables);
199 key_cache->in_init = false;
200
201 return error;
202 }
203
update_keycache_param(THD *,KEY_CACHE * key_cache,ptrdiff_t offset,ulonglong new_value)204 static bool update_keycache_param(THD *, KEY_CACHE *key_cache, ptrdiff_t offset,
205 ulonglong new_value) {
206 bool error = false;
207 DBUG_ASSERT(offset != offsetof(KEY_CACHE, param_buff_size));
208
209 keycache_var(key_cache, offset) = new_value;
210
211 key_cache->in_init = true;
212 mysql_mutex_unlock(&LOCK_global_system_variables);
213 error = ha_resize_key_cache(key_cache);
214
215 mysql_mutex_lock(&LOCK_global_system_variables);
216 key_cache->in_init = false;
217
218 return error;
219 }
220
221 /**
222 Check if REPLICATION_APPLIER granted. Throw SQL error if not.
223
224 Use this when setting session variables that are to be protected within
225 replication applier context.
226
227 @note For compatibility we also accept SUPER.
228
229 @retval true failure
230 @retval false success
231
232 @param self the system variable to set value for
233 @param thd the session context
234 @param setv the SET operations metadata
235 */
check_session_admin_or_replication_applier(sys_var * self MY_ATTRIBUTE ((unused)),THD * thd,set_var * setv)236 static bool check_session_admin_or_replication_applier(
237 sys_var *self MY_ATTRIBUTE((unused)), THD *thd, set_var *setv) {
238 DBUG_ASSERT(self->scope() != sys_var::GLOBAL);
239 Security_context *sctx = thd->security_context();
240 if ((setv->type == OPT_SESSION || setv->type == OPT_DEFAULT) &&
241 !sctx->has_global_grant(STRING_WITH_LEN("REPLICATION_APPLIER")).first &&
242 !sctx->has_global_grant(STRING_WITH_LEN("SESSION_VARIABLES_ADMIN"))
243 .first &&
244 !sctx->has_global_grant(STRING_WITH_LEN("SYSTEM_VARIABLES_ADMIN"))
245 .first &&
246 !sctx->check_access(SUPER_ACL)) {
247 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0),
248 "SUPER, SYSTEM_VARIABLES_ADMIN, SESSION_VARIABLES_ADMIN or "
249 "REPLICATION_APPLIER");
250 return true;
251 }
252 return false;
253 }
254
255 /**
256 Check if SESSION_VARIABLES_ADMIN granted. Throw SQL error if not.
257
258 Use this when setting session variables that are sensitive and should
259 be protected.
260
261 We also accept SYSTEM_VARIABLES_ADMIN since it doesn't make a lot of
262 sense to be allowed to set the global variable and not the session ones.
263
264 @note For compatibility we also accept SUPER.
265
266 @retval true failure
267 @retval false success
268
269 @param self the system variable to set value for
270 @param thd the session context
271 @param setv the SET operations metadata
272 */
check_session_admin(sys_var * self MY_ATTRIBUTE ((unused)),THD * thd,set_var * setv)273 static bool check_session_admin(sys_var *self MY_ATTRIBUTE((unused)), THD *thd,
274 set_var *setv) {
275 DBUG_ASSERT(self->scope() !=
276 sys_var::GLOBAL); // don't abuse check_session_admin()
277 Security_context *sctx = thd->security_context();
278 if ((setv->type == OPT_SESSION || setv->type == OPT_DEFAULT) &&
279 !sctx->has_global_grant(STRING_WITH_LEN("SESSION_VARIABLES_ADMIN"))
280 .first &&
281 !sctx->has_global_grant(STRING_WITH_LEN("SYSTEM_VARIABLES_ADMIN"))
282 .first &&
283 !sctx->check_access(SUPER_ACL)) {
284 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0),
285 "SUPER, SYSTEM_VARIABLES_ADMIN or SESSION_VARIABLES_ADMIN");
286 return true;
287 }
288 return false;
289 }
290
291 /*
292 The rule for this file: everything should be 'static'. When a sys_var
293 variable or a function from this file is - in very rare cases - needed
294 elsewhere it should be explicitly declared 'export' here to show that it's
295 not a mistakenly forgotten 'static' keyword.
296 */
297 #define export /* not static */
298
299 #ifdef WITH_LOCK_ORDER
300
301 #define LO_TRAILING_PROPERTIES \
302 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(NULL), ON_UPDATE(NULL), NULL, \
303 sys_var::PARSE_EARLY
304
305 static Sys_var_bool Sys_lo_enabled("lock_order", "Enable the lock order.",
306 READ_ONLY GLOBAL_VAR(lo_param.m_enabled),
307 CMD_LINE(OPT_ARG), DEFAULT(false),
308 LO_TRAILING_PROPERTIES);
309
310 static Sys_var_charptr Sys_lo_out_dir("lock_order_output_directory",
311 "Lock order output directory.",
312 READ_ONLY GLOBAL_VAR(lo_param.m_out_dir),
313 CMD_LINE(OPT_ARG), IN_FS_CHARSET,
314 DEFAULT(nullptr), LO_TRAILING_PROPERTIES);
315
316 static Sys_var_charptr Sys_lo_dep_1(
317 "lock_order_dependencies", "Lock order dependencies file.",
318 READ_ONLY GLOBAL_VAR(lo_param.m_dependencies_1), CMD_LINE(OPT_ARG),
319 IN_FS_CHARSET, DEFAULT(nullptr), LO_TRAILING_PROPERTIES);
320
321 static Sys_var_charptr Sys_lo_dep_2(
322 "lock_order_extra_dependencies", "Lock order extra dependencies file.",
323 READ_ONLY GLOBAL_VAR(lo_param.m_dependencies_2), CMD_LINE(OPT_ARG),
324 IN_FS_CHARSET, DEFAULT(nullptr), LO_TRAILING_PROPERTIES);
325
326 static Sys_var_bool Sys_lo_print_txt("lock_order_print_txt",
327 "Print the lock_order.txt file.",
328 READ_ONLY GLOBAL_VAR(lo_param.m_print_txt),
329 CMD_LINE(OPT_ARG), DEFAULT(false),
330 LO_TRAILING_PROPERTIES);
331
332 static Sys_var_bool Sys_lo_trace_loop(
333 "lock_order_trace_loop", "Enable tracing for all loops.",
334 READ_ONLY GLOBAL_VAR(lo_param.m_trace_loop), CMD_LINE(OPT_ARG),
335 DEFAULT(false), LO_TRAILING_PROPERTIES);
336
337 static Sys_var_bool Sys_lo_debug_loop(
338 "lock_order_debug_loop", "Enable debugging for all loops.",
339 READ_ONLY GLOBAL_VAR(lo_param.m_debug_loop), CMD_LINE(OPT_ARG),
340 DEFAULT(false), LO_TRAILING_PROPERTIES);
341
342 static Sys_var_bool Sys_lo_trace_missing_arc(
343 "lock_order_trace_missing_arc", "Enable tracing for all missing arcs.",
344 READ_ONLY GLOBAL_VAR(lo_param.m_trace_missing_arc), CMD_LINE(OPT_ARG),
345 DEFAULT(true), LO_TRAILING_PROPERTIES);
346
347 static Sys_var_bool Sys_lo_debug_missing_arc(
348 "lock_order_debug_missing_arc", "Enable debugging for all missing arcs.",
349 READ_ONLY GLOBAL_VAR(lo_param.m_debug_missing_arc), CMD_LINE(OPT_ARG),
350 DEFAULT(false), LO_TRAILING_PROPERTIES);
351
352 static Sys_var_bool Sys_lo_trace_missing_unlock(
353 "lock_order_trace_missing_unlock", "Enable tracing for all missing unlocks",
354 READ_ONLY GLOBAL_VAR(lo_param.m_trace_missing_unlock), CMD_LINE(OPT_ARG),
355 DEFAULT(true), LO_TRAILING_PROPERTIES);
356
357 static Sys_var_bool Sys_lo_debug_missing_unlock(
358 "lock_order_debug_missing_unlock",
359 "Enable debugging for all missing unlocks",
360 READ_ONLY GLOBAL_VAR(lo_param.m_debug_missing_unlock), CMD_LINE(OPT_ARG),
361 DEFAULT(false), LO_TRAILING_PROPERTIES);
362
363 static Sys_var_bool Sys_lo_trace_missing_key(
364 "lock_order_trace_missing_key",
365 "Enable trace for missing performance schema keys",
366 READ_ONLY GLOBAL_VAR(lo_param.m_trace_missing_key), CMD_LINE(OPT_ARG),
367 DEFAULT(false), LO_TRAILING_PROPERTIES);
368
369 static Sys_var_bool Sys_lo_debug_missing_key(
370 "lock_order_debug_missing_key",
371 "Enable debugging for missing performance schema keys",
372 READ_ONLY GLOBAL_VAR(lo_param.m_debug_missing_key), CMD_LINE(OPT_ARG),
373 DEFAULT(false), LO_TRAILING_PROPERTIES);
374
375 #endif /* WITH_LOCK_ORDER */
376
377 #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
378
379 #define PFS_TRAILING_PROPERTIES \
380 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(NULL), ON_UPDATE(NULL), NULL, \
381 sys_var::PARSE_EARLY
382
383 static Sys_var_bool Sys_pfs_enabled("performance_schema",
384 "Enable the performance schema.",
385 READ_ONLY GLOBAL_VAR(pfs_param.m_enabled),
386 CMD_LINE(OPT_ARG), DEFAULT(true),
387 PFS_TRAILING_PROPERTIES);
388
389 static Sys_var_charptr Sys_pfs_instrument(
390 "performance_schema_instrument",
391 "Default startup value for a performance schema instrument.",
392 READ_ONLY NOT_VISIBLE GLOBAL_VAR(pfs_param.m_pfs_instrument),
393 CMD_LINE(OPT_ARG, OPT_PFS_INSTRUMENT), IN_FS_CHARSET, DEFAULT(""),
394 PFS_TRAILING_PROPERTIES);
395
396 static Sys_var_bool Sys_pfs_consumer_events_stages_current(
397 "performance_schema_consumer_events_stages_current",
398 "Default startup value for the events_stages_current consumer.",
399 READ_ONLY NOT_VISIBLE
400 GLOBAL_VAR(pfs_param.m_consumer_events_stages_current_enabled),
401 CMD_LINE(OPT_ARG), DEFAULT(false), PFS_TRAILING_PROPERTIES);
402
403 static Sys_var_bool Sys_pfs_consumer_events_stages_history(
404 "performance_schema_consumer_events_stages_history",
405 "Default startup value for the events_stages_history consumer.",
406 READ_ONLY NOT_VISIBLE
407 GLOBAL_VAR(pfs_param.m_consumer_events_stages_history_enabled),
408 CMD_LINE(OPT_ARG), DEFAULT(false), PFS_TRAILING_PROPERTIES);
409
410 static Sys_var_bool Sys_pfs_consumer_events_stages_history_long(
411 "performance_schema_consumer_events_stages_history_long",
412 "Default startup value for the events_stages_history_long consumer.",
413 READ_ONLY NOT_VISIBLE
414 GLOBAL_VAR(pfs_param.m_consumer_events_stages_history_long_enabled),
415 CMD_LINE(OPT_ARG), DEFAULT(false), PFS_TRAILING_PROPERTIES);
416
417 static Sys_var_bool Sys_pfs_consumer_events_statements_current(
418 "performance_schema_consumer_events_statements_current",
419 "Default startup value for the events_statements_current consumer.",
420 READ_ONLY NOT_VISIBLE
421 GLOBAL_VAR(pfs_param.m_consumer_events_statements_current_enabled),
422 CMD_LINE(OPT_ARG), DEFAULT(true), PFS_TRAILING_PROPERTIES);
423
424 static Sys_var_bool Sys_pfs_consumer_events_statements_history(
425 "performance_schema_consumer_events_statements_history",
426 "Default startup value for the events_statements_history consumer.",
427 READ_ONLY NOT_VISIBLE
428 GLOBAL_VAR(pfs_param.m_consumer_events_statements_history_enabled),
429 CMD_LINE(OPT_ARG), DEFAULT(true), PFS_TRAILING_PROPERTIES);
430
431 static Sys_var_bool Sys_pfs_consumer_events_statements_history_long(
432 "performance_schema_consumer_events_statements_history_long",
433 "Default startup value for the events_statements_history_long consumer.",
434 READ_ONLY NOT_VISIBLE
435 GLOBAL_VAR(pfs_param.m_consumer_events_statements_history_long_enabled),
436 CMD_LINE(OPT_ARG), DEFAULT(false), PFS_TRAILING_PROPERTIES);
437
438 static Sys_var_bool Sys_pfs_consumer_events_transactions_current(
439 "performance_schema_consumer_events_transactions_current",
440 "Default startup value for the events_transactions_current consumer.",
441 READ_ONLY NOT_VISIBLE
442 GLOBAL_VAR(pfs_param.m_consumer_events_transactions_current_enabled),
443 CMD_LINE(OPT_ARG), DEFAULT(true), PFS_TRAILING_PROPERTIES);
444
445 static Sys_var_bool Sys_pfs_consumer_events_transactions_history(
446 "performance_schema_consumer_events_transactions_history",
447 "Default startup value for the events_transactions_history consumer.",
448 READ_ONLY NOT_VISIBLE
449 GLOBAL_VAR(pfs_param.m_consumer_events_transactions_history_enabled),
450 CMD_LINE(OPT_ARG), DEFAULT(true), PFS_TRAILING_PROPERTIES);
451
452 static Sys_var_bool Sys_pfs_consumer_events_transactions_history_long(
453 "performance_schema_consumer_events_transactions_history_long",
454 "Default startup value for the events_transactions_history_long consumer.",
455 READ_ONLY NOT_VISIBLE GLOBAL_VAR(
456 pfs_param.m_consumer_events_transactions_history_long_enabled),
457 CMD_LINE(OPT_ARG), DEFAULT(false), PFS_TRAILING_PROPERTIES);
458
459 static Sys_var_bool Sys_pfs_consumer_events_waits_current(
460 "performance_schema_consumer_events_waits_current",
461 "Default startup value for the events_waits_current consumer.",
462 READ_ONLY NOT_VISIBLE
463 GLOBAL_VAR(pfs_param.m_consumer_events_waits_current_enabled),
464 CMD_LINE(OPT_ARG), DEFAULT(false), PFS_TRAILING_PROPERTIES);
465
466 static Sys_var_bool Sys_pfs_consumer_events_waits_history(
467 "performance_schema_consumer_events_waits_history",
468 "Default startup value for the events_waits_history consumer.",
469 READ_ONLY NOT_VISIBLE
470 GLOBAL_VAR(pfs_param.m_consumer_events_waits_history_enabled),
471 CMD_LINE(OPT_ARG), DEFAULT(false), PFS_TRAILING_PROPERTIES);
472
473 static Sys_var_bool Sys_pfs_consumer_events_waits_history_long(
474 "performance_schema_consumer_events_waits_history_long",
475 "Default startup value for the events_waits_history_long consumer.",
476 READ_ONLY NOT_VISIBLE
477 GLOBAL_VAR(pfs_param.m_consumer_events_waits_history_long_enabled),
478 CMD_LINE(OPT_ARG), DEFAULT(false), PFS_TRAILING_PROPERTIES);
479
480 static Sys_var_bool Sys_pfs_consumer_global_instrumentation(
481 "performance_schema_consumer_global_instrumentation",
482 "Default startup value for the global_instrumentation consumer.",
483 READ_ONLY NOT_VISIBLE
484 GLOBAL_VAR(pfs_param.m_consumer_global_instrumentation_enabled),
485 CMD_LINE(OPT_ARG), DEFAULT(true), PFS_TRAILING_PROPERTIES);
486
487 static Sys_var_bool Sys_pfs_consumer_thread_instrumentation(
488 "performance_schema_consumer_thread_instrumentation",
489 "Default startup value for the thread_instrumentation consumer.",
490 READ_ONLY NOT_VISIBLE
491 GLOBAL_VAR(pfs_param.m_consumer_thread_instrumentation_enabled),
492 CMD_LINE(OPT_ARG), DEFAULT(true), PFS_TRAILING_PROPERTIES);
493
494 static Sys_var_bool Sys_pfs_consumer_statement_digest(
495 "performance_schema_consumer_statements_digest",
496 "Default startup value for the statements_digest consumer.",
497 READ_ONLY NOT_VISIBLE
498 GLOBAL_VAR(pfs_param.m_consumer_statement_digest_enabled),
499 CMD_LINE(OPT_ARG), DEFAULT(true), PFS_TRAILING_PROPERTIES);
500
501 static Sys_var_long Sys_pfs_events_waits_history_long_size(
502 "performance_schema_events_waits_history_long_size",
503 "Number of rows in EVENTS_WAITS_HISTORY_LONG."
504 " Use 0 to disable, -1 for automated sizing.",
505 READ_ONLY GLOBAL_VAR(pfs_param.m_events_waits_history_long_sizing),
506 CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024 * 1024),
507 DEFAULT(PFS_AUTOSIZE_VALUE), BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
508
509 static Sys_var_long Sys_pfs_events_waits_history_size(
510 "performance_schema_events_waits_history_size",
511 "Number of rows per thread in EVENTS_WAITS_HISTORY."
512 " Use 0 to disable, -1 for automated sizing.",
513 READ_ONLY GLOBAL_VAR(pfs_param.m_events_waits_history_sizing),
514 CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024), DEFAULT(PFS_AUTOSIZE_VALUE),
515 BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
516
517 static Sys_var_ulong Sys_pfs_max_cond_classes(
518 "performance_schema_max_cond_classes",
519 "Maximum number of condition instruments.",
520 READ_ONLY GLOBAL_VAR(pfs_param.m_cond_class_sizing), CMD_LINE(REQUIRED_ARG),
521 VALID_RANGE(0, 1024), DEFAULT(PFS_MAX_COND_CLASS), BLOCK_SIZE(1),
522 PFS_TRAILING_PROPERTIES);
523
524 static Sys_var_long Sys_pfs_max_cond_instances(
525 "performance_schema_max_cond_instances",
526 "Maximum number of instrumented condition objects."
527 " Use 0 to disable, -1 for automated scaling.",
528 READ_ONLY GLOBAL_VAR(pfs_param.m_cond_sizing), CMD_LINE(REQUIRED_ARG),
529 VALID_RANGE(-1, 1024 * 1024), DEFAULT(PFS_AUTOSCALE_VALUE), BLOCK_SIZE(1),
530 PFS_TRAILING_PROPERTIES);
531
532 static Sys_var_long Sys_pfs_max_program_instances(
533 "performance_schema_max_program_instances",
534 "Maximum number of instrumented programs."
535 " Use 0 to disable, -1 for automated scaling.",
536 READ_ONLY GLOBAL_VAR(pfs_param.m_program_sizing), CMD_LINE(REQUIRED_ARG),
537 VALID_RANGE(-1, 1024 * 1024), DEFAULT(PFS_AUTOSCALE_VALUE), BLOCK_SIZE(1),
538 PFS_TRAILING_PROPERTIES);
539
540 static constexpr int num_prepared_stmt_limit = 4 * 1024 * 1024;
541
542 static Sys_var_long Sys_pfs_max_prepared_stmt_instances(
543 "performance_schema_max_prepared_statements_instances",
544 "Maximum number of instrumented prepared statements."
545 " Use 0 to disable, -1 for automated scaling.",
546 READ_ONLY GLOBAL_VAR(pfs_param.m_prepared_stmt_sizing),
547 CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, num_prepared_stmt_limit),
548 DEFAULT(PFS_AUTOSCALE_VALUE), BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
549
550 static Sys_var_ulong Sys_pfs_max_file_classes(
551 "performance_schema_max_file_classes",
552 "Maximum number of file instruments.",
553 READ_ONLY GLOBAL_VAR(pfs_param.m_file_class_sizing), CMD_LINE(REQUIRED_ARG),
554 VALID_RANGE(0, 1024), DEFAULT(PFS_MAX_FILE_CLASS), BLOCK_SIZE(1),
555 PFS_TRAILING_PROPERTIES);
556
557 static Sys_var_ulong Sys_pfs_max_file_handles(
558 "performance_schema_max_file_handles",
559 "Maximum number of opened instrumented files.",
560 READ_ONLY GLOBAL_VAR(pfs_param.m_file_handle_sizing),
561 CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024 * 1024),
562 DEFAULT(PFS_MAX_FILE_HANDLE), BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
563
564 static Sys_var_long Sys_pfs_max_file_instances(
565 "performance_schema_max_file_instances",
566 "Maximum number of instrumented files."
567 " Use 0 to disable, -1 for automated scaling.",
568 READ_ONLY GLOBAL_VAR(pfs_param.m_file_sizing), CMD_LINE(REQUIRED_ARG),
569 VALID_RANGE(-1, 1024 * 1024), DEFAULT(PFS_AUTOSCALE_VALUE), BLOCK_SIZE(1),
570 PFS_TRAILING_PROPERTIES);
571
572 static Sys_var_long Sys_pfs_max_sockets(
573 "performance_schema_max_socket_instances",
574 "Maximum number of opened instrumented sockets."
575 " Use 0 to disable, -1 for automated scaling.",
576 READ_ONLY GLOBAL_VAR(pfs_param.m_socket_sizing), CMD_LINE(REQUIRED_ARG),
577 VALID_RANGE(-1, 1024 * 1024), DEFAULT(PFS_AUTOSCALE_VALUE), BLOCK_SIZE(1),
578 PFS_TRAILING_PROPERTIES);
579
580 static Sys_var_ulong Sys_pfs_max_socket_classes(
581 "performance_schema_max_socket_classes",
582 "Maximum number of socket instruments.",
583 READ_ONLY GLOBAL_VAR(pfs_param.m_socket_class_sizing),
584 CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024), DEFAULT(PFS_MAX_SOCKET_CLASS),
585 BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
586
587 static Sys_var_ulong Sys_pfs_max_mutex_classes(
588 "performance_schema_max_mutex_classes",
589 "Maximum number of mutex instruments.",
590 READ_ONLY GLOBAL_VAR(pfs_param.m_mutex_class_sizing),
591 CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024), DEFAULT(PFS_MAX_MUTEX_CLASS),
592 BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
593
594 static Sys_var_long Sys_pfs_max_mutex_instances(
595 "performance_schema_max_mutex_instances",
596 "Maximum number of instrumented MUTEX objects."
597 " Use 0 to disable, -1 for automated scaling.",
598 READ_ONLY GLOBAL_VAR(pfs_param.m_mutex_sizing), CMD_LINE(REQUIRED_ARG),
599 VALID_RANGE(-1, 100 * 1024 * 1024), DEFAULT(PFS_AUTOSCALE_VALUE),
600 BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
601
602 static Sys_var_ulong Sys_pfs_max_rwlock_classes(
603 "performance_schema_max_rwlock_classes",
604 "Maximum number of rwlock instruments.",
605 READ_ONLY GLOBAL_VAR(pfs_param.m_rwlock_class_sizing),
606 CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024), DEFAULT(PFS_MAX_RWLOCK_CLASS),
607 BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
608
609 static Sys_var_long Sys_pfs_max_rwlock_instances(
610 "performance_schema_max_rwlock_instances",
611 "Maximum number of instrumented RWLOCK objects."
612 " Use 0 to disable, -1 for automated scaling.",
613 READ_ONLY GLOBAL_VAR(pfs_param.m_rwlock_sizing), CMD_LINE(REQUIRED_ARG),
614 VALID_RANGE(-1, 100 * 1024 * 1024), DEFAULT(PFS_AUTOSCALE_VALUE),
615 BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
616
617 static Sys_var_long Sys_pfs_max_table_handles(
618 "performance_schema_max_table_handles",
619 "Maximum number of opened instrumented tables."
620 " Use 0 to disable, -1 for automated scaling.",
621 READ_ONLY GLOBAL_VAR(pfs_param.m_table_sizing), CMD_LINE(REQUIRED_ARG),
622 VALID_RANGE(-1, 1024 * 1024), DEFAULT(PFS_AUTOSCALE_VALUE), BLOCK_SIZE(1),
623 PFS_TRAILING_PROPERTIES);
624
625 static Sys_var_long Sys_pfs_max_table_instances(
626 "performance_schema_max_table_instances",
627 "Maximum number of instrumented tables."
628 " Use 0 to disable, -1 for automated scaling.",
629 READ_ONLY GLOBAL_VAR(pfs_param.m_table_share_sizing),
630 CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024 * 1024),
631 DEFAULT(PFS_AUTOSCALE_VALUE), BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
632
633 static Sys_var_long Sys_pfs_max_table_lock_stat(
634 "performance_schema_max_table_lock_stat",
635 "Maximum number of lock statistics for instrumented tables."
636 " Use 0 to disable, -1 for automated scaling.",
637 READ_ONLY GLOBAL_VAR(pfs_param.m_table_lock_stat_sizing),
638 CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024 * 1024),
639 DEFAULT(PFS_AUTOSCALE_VALUE), BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
640
641 static Sys_var_long Sys_pfs_max_index_stat(
642 "performance_schema_max_index_stat",
643 "Maximum number of index statistics for instrumented tables."
644 " Use 0 to disable, -1 for automated scaling.",
645 READ_ONLY GLOBAL_VAR(pfs_param.m_index_stat_sizing), CMD_LINE(REQUIRED_ARG),
646 VALID_RANGE(-1, 1024 * 1024), DEFAULT(PFS_AUTOSCALE_VALUE), BLOCK_SIZE(1),
647 PFS_TRAILING_PROPERTIES);
648
649 static Sys_var_ulong Sys_pfs_max_thread_classes(
650 "performance_schema_max_thread_classes",
651 "Maximum number of thread instruments.",
652 READ_ONLY GLOBAL_VAR(pfs_param.m_thread_class_sizing),
653 CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024), DEFAULT(PFS_MAX_THREAD_CLASS),
654 BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
655
656 static Sys_var_long Sys_pfs_max_thread_instances(
657 "performance_schema_max_thread_instances",
658 "Maximum number of instrumented threads."
659 " Use 0 to disable, -1 for automated scaling.",
660 READ_ONLY GLOBAL_VAR(pfs_param.m_thread_sizing), CMD_LINE(REQUIRED_ARG),
661 VALID_RANGE(-1, 1024 * 1024), DEFAULT(PFS_AUTOSCALE_VALUE), BLOCK_SIZE(1),
662 PFS_TRAILING_PROPERTIES);
663
664 static Sys_var_long Sys_pfs_setup_actors_size(
665 "performance_schema_setup_actors_size",
666 "Maximum number of rows in SETUP_ACTORS."
667 " Use 0 to disable, -1 for automated scaling.",
668 READ_ONLY GLOBAL_VAR(pfs_param.m_setup_actor_sizing),
669 CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024 * 1024),
670 DEFAULT(PFS_AUTOSCALE_VALUE), BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
671
672 static Sys_var_long Sys_pfs_setup_objects_size(
673 "performance_schema_setup_objects_size",
674 "Maximum number of rows in SETUP_OBJECTS."
675 " Use 0 to disable, -1 for automated scaling.",
676 READ_ONLY GLOBAL_VAR(pfs_param.m_setup_object_sizing),
677 CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024 * 1024),
678 DEFAULT(PFS_AUTOSCALE_VALUE), BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
679
680 static Sys_var_long Sys_pfs_accounts_size(
681 "performance_schema_accounts_size",
682 "Maximum number of instrumented user@host accounts."
683 " Use 0 to disable, -1 for automated scaling.",
684 READ_ONLY GLOBAL_VAR(pfs_param.m_account_sizing), CMD_LINE(REQUIRED_ARG),
685 VALID_RANGE(-1, 1024 * 1024), DEFAULT(PFS_AUTOSCALE_VALUE), BLOCK_SIZE(1),
686 PFS_TRAILING_PROPERTIES);
687
688 static Sys_var_long Sys_pfs_hosts_size(
689 "performance_schema_hosts_size",
690 "Maximum number of instrumented hosts."
691 " Use 0 to disable, -1 for automated scaling.",
692 READ_ONLY GLOBAL_VAR(pfs_param.m_host_sizing), CMD_LINE(REQUIRED_ARG),
693 VALID_RANGE(-1, 1024 * 1024), DEFAULT(PFS_AUTOSCALE_VALUE), BLOCK_SIZE(1),
694 PFS_TRAILING_PROPERTIES);
695
696 static Sys_var_long Sys_pfs_users_size(
697 "performance_schema_users_size",
698 "Maximum number of instrumented users."
699 " Use 0 to disable, -1 for automated scaling.",
700 READ_ONLY GLOBAL_VAR(pfs_param.m_user_sizing), CMD_LINE(REQUIRED_ARG),
701 VALID_RANGE(-1, 1024 * 1024), DEFAULT(PFS_AUTOSCALE_VALUE), BLOCK_SIZE(1),
702 PFS_TRAILING_PROPERTIES);
703
704 static Sys_var_ulong Sys_pfs_max_stage_classes(
705 "performance_schema_max_stage_classes",
706 "Maximum number of stage instruments.",
707 READ_ONLY GLOBAL_VAR(pfs_param.m_stage_class_sizing),
708 CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024), DEFAULT(PFS_MAX_STAGE_CLASS),
709 BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
710
711 static Sys_var_long Sys_pfs_events_stages_history_long_size(
712 "performance_schema_events_stages_history_long_size",
713 "Number of rows in EVENTS_STAGES_HISTORY_LONG."
714 " Use 0 to disable, -1 for automated sizing.",
715 READ_ONLY GLOBAL_VAR(pfs_param.m_events_stages_history_long_sizing),
716 CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024 * 1024),
717 DEFAULT(PFS_AUTOSIZE_VALUE), BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
718
719 static Sys_var_long Sys_pfs_events_stages_history_size(
720 "performance_schema_events_stages_history_size",
721 "Number of rows per thread in EVENTS_STAGES_HISTORY."
722 " Use 0 to disable, -1 for automated sizing.",
723 READ_ONLY GLOBAL_VAR(pfs_param.m_events_stages_history_sizing),
724 CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024), DEFAULT(PFS_AUTOSIZE_VALUE),
725 BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
726
727 /**
728 Variable performance_schema_max_statement_classes.
729 The default number of statement classes is the sum of:
730 - COM_END for all regular "statement/com/...",
731 - 1 for "statement/com/new_packet", for unknown enum_server_command
732 - 1 for "statement/com/Error", for invalid enum_server_command
733 - SQLCOM_END for all regular "statement/sql/...",
734 - 1 for "statement/sql/error", for invalid enum_sql_command.
735 - SP_PSI_STATEMENT_INFO_COUNT for "statement/sp/...".
736 - CLONE_PSI_STATEMENT_COUNT for "statement/clone/...".
737 - 1 for "statement/rpl/relay_log", for replicated statements.
738 - 1 for "statement/scheduler/event", for scheduled events.
739 */
740 static Sys_var_ulong Sys_pfs_max_statement_classes(
741 "performance_schema_max_statement_classes",
742 "Maximum number of statement instruments.",
743 READ_ONLY GLOBAL_VAR(pfs_param.m_statement_class_sizing),
744 CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 256),
745 DEFAULT((ulong)SQLCOM_END + (ulong)COM_END + 5 +
746 SP_PSI_STATEMENT_INFO_COUNT + CLONE_PSI_STATEMENT_COUNT),
747 BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
748
749 static Sys_var_long Sys_pfs_events_statements_history_long_size(
750 "performance_schema_events_statements_history_long_size",
751 "Number of rows in EVENTS_STATEMENTS_HISTORY_LONG."
752 " Use 0 to disable, -1 for automated sizing.",
753 READ_ONLY GLOBAL_VAR(pfs_param.m_events_statements_history_long_sizing),
754 CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024 * 1024),
755 DEFAULT(PFS_AUTOSIZE_VALUE), BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
756
757 static Sys_var_long Sys_pfs_events_statements_history_size(
758 "performance_schema_events_statements_history_size",
759 "Number of rows per thread in EVENTS_STATEMENTS_HISTORY."
760 " Use 0 to disable, -1 for automated sizing.",
761 READ_ONLY GLOBAL_VAR(pfs_param.m_events_statements_history_sizing),
762 CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024), DEFAULT(PFS_AUTOSIZE_VALUE),
763 BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
764
765 static Sys_var_ulong Sys_pfs_statement_stack_size(
766 "performance_schema_max_statement_stack",
767 "Number of rows per thread in EVENTS_STATEMENTS_CURRENT.",
768 READ_ONLY GLOBAL_VAR(pfs_param.m_statement_stack_sizing),
769 CMD_LINE(REQUIRED_ARG), VALID_RANGE(1, 256),
770 DEFAULT(PFS_STATEMENTS_STACK_SIZE), BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
771
772 static Sys_var_ulong Sys_pfs_max_memory_classes(
773 "performance_schema_max_memory_classes",
774 "Maximum number of memory pool instruments.",
775 READ_ONLY GLOBAL_VAR(pfs_param.m_memory_class_sizing),
776 CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024), DEFAULT(PFS_MAX_MEMORY_CLASS),
777 BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
778
779 static Sys_var_long Sys_pfs_digest_size(
780 "performance_schema_digests_size",
781 "Size of the statement digest."
782 " Use 0 to disable, -1 for automated sizing.",
783 READ_ONLY GLOBAL_VAR(pfs_param.m_digest_sizing), CMD_LINE(REQUIRED_ARG),
784 VALID_RANGE(-1, 1024 * 1024), DEFAULT(PFS_AUTOSIZE_VALUE), BLOCK_SIZE(1),
785 PFS_TRAILING_PROPERTIES);
786
787 static Sys_var_long Sys_pfs_events_transactions_history_long_size(
788 "performance_schema_events_transactions_history_long_size",
789 "Number of rows in EVENTS_TRANSACTIONS_HISTORY_LONG."
790 " Use 0 to disable, -1 for automated sizing.",
791 READ_ONLY GLOBAL_VAR(pfs_param.m_events_transactions_history_long_sizing),
792 CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024 * 1024),
793 DEFAULT(PFS_AUTOSIZE_VALUE), BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
794
795 static Sys_var_long Sys_pfs_events_transactions_history_size(
796 "performance_schema_events_transactions_history_size",
797 "Number of rows per thread in EVENTS_TRANSACTIONS_HISTORY."
798 " Use 0 to disable, -1 for automated sizing.",
799 READ_ONLY GLOBAL_VAR(pfs_param.m_events_transactions_history_sizing),
800 CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024), DEFAULT(PFS_AUTOSIZE_VALUE),
801 BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
802
803 static Sys_var_long Sys_pfs_max_digest_length(
804 "performance_schema_max_digest_length",
805 "Maximum length considered for digest text, when stored in "
806 "performance_schema tables.",
807 READ_ONLY GLOBAL_VAR(pfs_param.m_max_digest_length), CMD_LINE(REQUIRED_ARG),
808 VALID_RANGE(0, 1024 * 1024), DEFAULT(1024), BLOCK_SIZE(1),
809 PFS_TRAILING_PROPERTIES);
810
811 static Sys_var_ulong Sys_pfs_max_digest_sample_age(
812 "performance_schema_max_digest_sample_age",
813 "The time in seconds after which a previous query sample is considered old."
814 " When the value is 0, queries are sampled once."
815 " When the value is greater than zero, queries are re sampled if the"
816 " last sample is more than performance_schema_max_digest_sample_age "
817 "seconds old.",
818 GLOBAL_VAR(pfs_param.m_max_digest_sample_age), CMD_LINE(REQUIRED_ARG),
819 VALID_RANGE(0, 1024 * 1024), DEFAULT(60), BLOCK_SIZE(1),
820 PFS_TRAILING_PROPERTIES);
821
822 static Sys_var_long Sys_pfs_connect_attrs_size(
823 "performance_schema_session_connect_attrs_size",
824 "Size of session attribute string buffer per thread."
825 " Use 0 to disable, -1 for automated sizing.",
826 READ_ONLY GLOBAL_VAR(pfs_param.m_session_connect_attrs_sizing),
827 CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024 * 1024),
828 DEFAULT(PFS_AUTOSIZE_VALUE), BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
829
830 static Sys_var_long Sys_pfs_max_metadata_locks(
831 "performance_schema_max_metadata_locks",
832 "Maximum number of metadata locks."
833 " Use 0 to disable, -1 for automated scaling.",
834 READ_ONLY GLOBAL_VAR(pfs_param.m_metadata_lock_sizing),
835 CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 100 * 1024 * 1024),
836 DEFAULT(PFS_AUTOSCALE_VALUE), BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
837
838 static Sys_var_long Sys_pfs_max_sql_text_length(
839 "performance_schema_max_sql_text_length",
840 "Maximum length of displayed sql text.",
841 READ_ONLY GLOBAL_VAR(pfs_param.m_max_sql_text_length),
842 CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024 * 1024), DEFAULT(1024),
843 BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
844
845 static Sys_var_long Sys_pfs_error_size(
846 "performance_schema_error_size", "Number of server errors instrumented.",
847 READ_ONLY GLOBAL_VAR(pfs_param.m_error_sizing), CMD_LINE(REQUIRED_ARG),
848 VALID_RANGE(0, 1024 * 1024), DEFAULT(PFS_MAX_GLOBAL_SERVER_ERRORS),
849 BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
850
851 #endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
852
853 static Sys_var_ulong Sys_auto_increment_increment(
854 "auto_increment_increment",
855 "Auto-increment columns are incremented by this",
856 HINT_UPDATEABLE SESSION_VAR(auto_increment_increment), CMD_LINE(OPT_ARG),
857 VALID_RANGE(1, 65535), DEFAULT(1), BLOCK_SIZE(1), NO_MUTEX_GUARD,
858 IN_BINLOG);
859
860 static Sys_var_ulong Sys_auto_increment_offset(
861 "auto_increment_offset",
862 "Offset added to Auto-increment columns. Used when "
863 "auto-increment-increment != 1",
864 HINT_UPDATEABLE SESSION_VAR(auto_increment_offset), CMD_LINE(OPT_ARG),
865 VALID_RANGE(1, 65535), DEFAULT(1), BLOCK_SIZE(1), NO_MUTEX_GUARD,
866 IN_BINLOG);
867
868 static Sys_var_bool Sys_windowing_use_high_precision(
869 "windowing_use_high_precision",
870 "For SQL window functions, determines whether to enable inversion "
871 "optimization for moving window frames also for floating values.",
872 HINT_UPDATEABLE SESSION_VAR(windowing_use_high_precision),
873 CMD_LINE(OPT_ARG), DEFAULT(true));
874
875 static Sys_var_uint Sys_cte_max_recursion_depth(
876 "cte_max_recursion_depth",
877 "Abort a recursive common table expression "
878 "if it does more than this number of iterations.",
879 HINT_UPDATEABLE SESSION_VAR(cte_max_recursion_depth),
880 CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, UINT_MAX32), DEFAULT(1000),
881 BLOCK_SIZE(1));
882
883 static Sys_var_bool Sys_automatic_sp_privileges(
884 "automatic_sp_privileges",
885 "Creating and dropping stored procedures alters ACLs",
886 GLOBAL_VAR(sp_automatic_privileges), CMD_LINE(OPT_ARG), DEFAULT(true));
887
888 static Sys_var_ulong Sys_back_log(
889 "back_log",
890 "The number of outstanding connection requests "
891 "MySQL can have. This comes into play when the main MySQL thread "
892 "gets very many connection requests in a very short time",
893 READ_ONLY GLOBAL_VAR(back_log), CMD_LINE(REQUIRED_ARG),
894 VALID_RANGE(0, 65535), DEFAULT(0), BLOCK_SIZE(1));
895
896 static Sys_var_charptr Sys_basedir(
897 "basedir",
898 "Path to installation directory. All paths are "
899 "usually resolved relative to this",
900 READ_ONLY NON_PERSIST GLOBAL_VAR(mysql_home_ptr),
901 CMD_LINE(REQUIRED_ARG, 'b'), IN_FS_CHARSET, DEFAULT(nullptr));
902
903 static Sys_var_charptr Sys_default_authentication_plugin(
904 "default_authentication_plugin",
905 "The default authentication plugin "
906 "used by the server to hash the password.",
907 READ_ONLY NON_PERSIST GLOBAL_VAR(default_auth_plugin),
908 CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET, DEFAULT("caching_sha2_password"));
909
910 static PolyLock_mutex Plock_default_password_lifetime(
911 &LOCK_default_password_lifetime);
912 static Sys_var_uint Sys_default_password_lifetime(
913 "default_password_lifetime",
914 "The number of days after which the "
915 "password will expire.",
916 GLOBAL_VAR(default_password_lifetime), CMD_LINE(REQUIRED_ARG),
917 VALID_RANGE(0, UINT_MAX16), DEFAULT(0), BLOCK_SIZE(1),
918 &Plock_default_password_lifetime);
919
920 static Sys_var_charptr Sys_my_bind_addr(
921 "bind_address",
922 "IP address(es) to bind to. Syntax: address[,address]...,"
923 " where address can be an IPv4 address, IPv6 address,"
924 " host name or one of the wildcard values *, ::, 0.0.0.0."
925 " In case more than one address is specified in a"
926 " comma-separated list, wildcard values are not allowed."
927 " Every address can have optional network namespace separated"
928 " by the delimiter / from the address value. E.g., the following value"
929 " 192.168.1.1/red,172.16.1.1/green,193.168.1.1 specifies three IP"
930 " addresses to listen for incoming TCP connections two of that have"
931 " to be placed in corresponding namespaces: the address 192.168.1.1"
932 " must be placed into the namespace red and the address 172.16.1.1"
933 " must be placed into the namespace green. Using of network namespace"
934 " requires its support from underlying Operating System. Attempt to specify"
935 " a network namespace for a platform that doesn't support it results in"
936 " error during socket creation.",
937 READ_ONLY NON_PERSIST GLOBAL_VAR(my_bind_addr_str), CMD_LINE(REQUIRED_ARG),
938 IN_FS_CHARSET, DEFAULT(MY_BIND_ALL_ADDRESSES));
939
940 static Sys_var_charptr Sys_admin_addr(
941 "admin_address",
942 "IP address to bind to for service connection. Address can be an IPv4"
943 " address, IPv6 address, or host name. Wildcard values *, ::, 0.0.0.0"
944 " are not allowed. Address value can have following optional network"
945 " namespace separated by the delimiter / from the address value."
946 " E.g., the following value 192.168.1.1/red specifies IP addresses to"
947 " listen for incoming TCP connections that have to be placed into"
948 " the namespace 'red'. Using of network namespace requires its support"
949 " from underlying Operating System. Attempt to specify a network namespace"
950 " for a platform that doesn't support it results in error during socket"
951 " creation.",
952 READ_ONLY NON_PERSIST GLOBAL_VAR(my_admin_bind_addr_str),
953 CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET, DEFAULT(nullptr));
954
955 static Sys_var_uint Sys_admin_port(
956 "admin_port",
957 "Port number to use for service connection,"
958 " built-in default (" STRINGIFY_ARG(MYSQL_ADMIN_PORT) ")",
959 READ_ONLY NON_PERSIST GLOBAL_VAR(mysqld_admin_port), CMD_LINE(REQUIRED_ARG),
960 VALID_RANGE(0, 65535), DEFAULT(MYSQL_ADMIN_PORT), BLOCK_SIZE(1));
961
962 static Sys_var_bool Sys_use_separate_thread_for_admin(
963 "create_admin_listener_thread",
964 "Use a dedicated thread for listening incoming connections on admin"
965 " interface",
966 READ_ONLY NON_PERSIST GLOBAL_VAR(listen_admin_interface_in_separate_thread),
967 CMD_LINE(OPT_ARG), DEFAULT(false));
968
969 static Sys_var_bool Sys_password_require_current(
970 "password_require_current",
971 "Current password is needed to be specified in order to change it",
972 GLOBAL_VAR(password_require_current), CMD_LINE(OPT_ARG), DEFAULT(false));
973
974 /**
975 Checks,
976 if there exists at least a partial revoke on a database at the time
977 of turning OFF the system variable "@@partial_revokes". If it does then
978 throw error.
979 if there exists at least a DB grant with wildcard entry at the time of
980 turning ON the system variable "@@partial_revokes". If it does then
981 throw error.
982
983 @retval true failure
984 @retval false success
985
986 @param self the system variable to set value for
987 @param thd the session context
988 @param setv the SET operations metadata
989 */
check_partial_revokes(sys_var * self,THD * thd,set_var * setv)990 static bool check_partial_revokes(sys_var *self, THD *thd, set_var *setv) {
991 if (is_partial_revoke_exists(thd) && setv->save_result.ulonglong_value == 0) {
992 my_error(ER_PARTIAL_REVOKES_EXIST, MYF(0), self->name.str);
993 return true;
994 }
995 return false;
996 }
997
998 /** Sets the changed value to the corresponding atomic system variable */
partial_revokes_update(sys_var *,THD *,enum_var_type)999 static bool partial_revokes_update(sys_var *, THD *, enum_var_type) {
1000 set_mysqld_partial_revokes(opt_partial_revokes);
1001 return false;
1002 }
1003
1004 static Sys_var_bool Sys_partial_revokes(
1005 "partial_revokes",
1006 "Access of database objects can be restricted, "
1007 "even if user has global privileges granted.",
1008 GLOBAL_VAR(opt_partial_revokes), CMD_LINE(OPT_ARG),
1009 DEFAULT(DEFAULT_PARTIAL_REVOKES), NO_MUTEX_GUARD, IN_BINLOG,
1010 ON_CHECK(check_partial_revokes), ON_UPDATE(partial_revokes_update), nullptr,
1011 sys_var::PARSE_EARLY);
1012
fix_binlog_cache_size(sys_var *,THD * thd,enum_var_type)1013 static bool fix_binlog_cache_size(sys_var *, THD *thd, enum_var_type) {
1014 check_binlog_cache_size(thd);
1015 return false;
1016 }
1017
fix_binlog_stmt_cache_size(sys_var *,THD * thd,enum_var_type)1018 static bool fix_binlog_stmt_cache_size(sys_var *, THD *thd, enum_var_type) {
1019 check_binlog_stmt_cache_size(thd);
1020 return false;
1021 }
1022
1023 static Sys_var_ulong Sys_binlog_cache_size(
1024 "binlog_cache_size",
1025 "The size of the transactional cache for "
1026 "updates to transactional engines for the binary log. "
1027 "If you often use transactions containing many statements, "
1028 "you can increase this to get more performance",
1029 GLOBAL_VAR(binlog_cache_size), CMD_LINE(REQUIRED_ARG),
1030 VALID_RANGE(IO_SIZE, ULONG_MAX), DEFAULT(32768), BLOCK_SIZE(IO_SIZE),
1031 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
1032 ON_UPDATE(fix_binlog_cache_size));
1033
1034 static Sys_var_ulong Sys_binlog_stmt_cache_size(
1035 "binlog_stmt_cache_size",
1036 "The size of the statement cache for "
1037 "updates to non-transactional engines for the binary log. "
1038 "If you often use statements updating a great number of rows, "
1039 "you can increase this to get more performance",
1040 GLOBAL_VAR(binlog_stmt_cache_size), CMD_LINE(REQUIRED_ARG),
1041 VALID_RANGE(IO_SIZE, ULONG_MAX), DEFAULT(32768), BLOCK_SIZE(IO_SIZE),
1042 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
1043 ON_UPDATE(fix_binlog_stmt_cache_size));
1044
1045 static Sys_var_int32 Sys_binlog_max_flush_queue_time(
1046 "binlog_max_flush_queue_time",
1047 "The maximum time that the binary log group commit will keep reading"
1048 " transactions before it flush the transactions to the binary log (and"
1049 " optionally sync, depending on the value of sync_binlog).",
1050 GLOBAL_VAR(opt_binlog_max_flush_queue_time),
1051 CMD_LINE(REQUIRED_ARG, OPT_BINLOG_MAX_FLUSH_QUEUE_TIME),
1052 VALID_RANGE(0, 100000), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD,
1053 NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr), DEPRECATED_VAR(""));
1054
1055 static Sys_var_long Sys_binlog_group_commit_sync_delay(
1056 "binlog_group_commit_sync_delay",
1057 "The number of microseconds the server waits for the "
1058 "binary log group commit sync queue to fill before "
1059 "continuing. Default: 0. Min: 0. Max: 1000000.",
1060 GLOBAL_VAR(opt_binlog_group_commit_sync_delay), CMD_LINE(REQUIRED_ARG),
1061 VALID_RANGE(0, 1000000 /* max 1 sec */), DEFAULT(0), BLOCK_SIZE(1),
1062 NO_MUTEX_GUARD, NOT_IN_BINLOG);
1063
1064 static Sys_var_ulong Sys_binlog_group_commit_sync_no_delay_count(
1065 "binlog_group_commit_sync_no_delay_count",
1066 "If there are this many transactions in the commit sync "
1067 "queue and the server is waiting for more transactions "
1068 "to be enqueued (as set using --binlog-group-commit-sync-delay), "
1069 "the commit procedure resumes.",
1070 GLOBAL_VAR(opt_binlog_group_commit_sync_no_delay_count),
1071 CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 100000 /* max connections */),
1072 DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG);
1073
check_outside_trx(sys_var *,THD * thd,set_var * var)1074 static bool check_outside_trx(sys_var *, THD *thd, set_var *var) {
1075 if (thd->in_active_multi_stmt_transaction()) {
1076 my_error(ER_VARIABLE_NOT_SETTABLE_IN_TRANSACTION, MYF(0),
1077 var->var->name.str);
1078 return true;
1079 }
1080 if (!thd->owned_gtid_is_empty()) {
1081 char buf[Gtid::MAX_TEXT_LENGTH + 1];
1082 if (thd->owned_gtid.sidno > 0)
1083 thd->owned_gtid.to_string(thd->owned_sid, buf);
1084 else
1085 strcpy(buf, "ANONYMOUS");
1086 my_error(ER_CANT_SET_VARIABLE_WHEN_OWNING_GTID, MYF(0), var->var->name.str,
1087 buf);
1088 return true;
1089 }
1090 return false;
1091 }
1092
check_session_admin_outside_trx_outside_sf(sys_var * self,THD * thd,set_var * var)1093 static bool check_session_admin_outside_trx_outside_sf(sys_var *self, THD *thd,
1094 set_var *var) {
1095 if (thd->in_sub_stmt) {
1096 my_error(ER_VARIABLE_NOT_SETTABLE_IN_SF_OR_TRIGGER, MYF(0),
1097 var->var->name.str);
1098 return true;
1099 }
1100 if (check_outside_trx(self, thd, var)) return true;
1101 if (self->scope() != sys_var::GLOBAL)
1102 return check_session_admin(self, thd, var);
1103 return false;
1104 }
1105
check_explicit_defaults_for_timestamp(sys_var * self,THD * thd,set_var * var)1106 static bool check_explicit_defaults_for_timestamp(sys_var *self, THD *thd,
1107 set_var *var) {
1108 // Deprecation warning if switching OFF explicit_defaults_for_timestamp
1109 if (thd->variables.explicit_defaults_for_timestamp) {
1110 if (!var->save_result.ulonglong_value)
1111 push_warning_printf(thd, Sql_condition::SL_WARNING,
1112 ER_WARN_DEPRECATED_SYNTAX,
1113 ER_THD(thd, ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT),
1114 self->name.str);
1115 }
1116 if (thd->in_sub_stmt) {
1117 my_error(ER_VARIABLE_NOT_SETTABLE_IN_SF_OR_TRIGGER, MYF(0),
1118 var->var->name.str);
1119 return true;
1120 }
1121 if (thd->in_active_multi_stmt_transaction()) {
1122 my_error(ER_VARIABLE_NOT_SETTABLE_IN_TRANSACTION, MYF(0),
1123 var->var->name.str);
1124 return true;
1125 }
1126 return false;
1127 }
1128
1129 /**
1130 Check-function to @@GTID_NEXT system variable.
1131
1132 @param self a pointer to the sys_var, i.e. gtid_next
1133 @param thd a reference to THD object
1134 @param var a pointer to the set_var created by the parser.
1135
1136 @return @c false if the change is allowed, otherwise @c true.
1137 */
1138
check_gtid_next(sys_var * self,THD * thd,set_var * var)1139 static bool check_gtid_next(sys_var *self, THD *thd, set_var *var) {
1140 bool is_prepared_trx =
1141 thd->get_transaction()->xid_state()->has_state(XID_STATE::XA_PREPARED);
1142
1143 if (thd->in_sub_stmt) {
1144 my_error(ER_VARIABLE_NOT_SETTABLE_IN_SF_OR_TRIGGER, MYF(0),
1145 var->var->name.str);
1146 return true;
1147 }
1148 if (!is_prepared_trx && thd->in_active_multi_stmt_transaction()) {
1149 my_error(ER_VARIABLE_NOT_SETTABLE_IN_TRANSACTION, MYF(0),
1150 var->var->name.str);
1151 return true;
1152 }
1153 return check_session_admin_or_replication_applier(self, thd, var);
1154 }
1155
check_session_admin_outside_trx_outside_sf_outside_sp(sys_var * self,THD * thd,set_var * var)1156 static bool check_session_admin_outside_trx_outside_sf_outside_sp(
1157 sys_var *self, THD *thd, set_var *var) {
1158 if (check_session_admin_outside_trx_outside_sf(self, thd, var)) return true;
1159 if (thd->lex->sphead) {
1160 my_error(ER_VARIABLE_NOT_SETTABLE_IN_SP, MYF(0), var->var->name.str);
1161 return true;
1162 }
1163 return false;
1164 }
1165
binlog_format_check(sys_var * self,THD * thd,set_var * var)1166 static bool binlog_format_check(sys_var *self, THD *thd, set_var *var) {
1167 if (check_session_admin(self, thd, var)) return true;
1168
1169 if (var->type == OPT_GLOBAL || var->type == OPT_PERSIST) {
1170 /*
1171 SET @@global.binlog_format and SET @@persist.binlog_format must be
1172 disallowed if any replication channel has open temporary table(s).
1173 Otherwise DROP TEMPORARY TABLE is written into binary log on slave
1174 (which disobeys the simple rule: When @@session.binlog_format=
1175 ROW/MIXED, the server must not write CREATE/DROP TEMPORARY TABLE
1176 to the binary log) in the following case:
1177 slave> SET @@global.binlog_format=STATEMENT;
1178 slave> START SLAVE;
1179 master> CREATE TEMPORARY TABLE t1(a INT);
1180 slave> [wait for t1 to replicate]
1181 slave> STOP SLAVE;
1182 slave> SET @@global.binlog_format=ROW / SET @@persist.binlog_format=ROW
1183 master> DROP TEMPORARY TABLE t1;
1184 slave> START SLAVE;
1185 Note: SET @@persist_only.binlog_format is not disallowed if any
1186 replication channel has temporary table(s), since unlike PERSIST,
1187 PERSIST_ONLY does not modify the runtime global system variable value.
1188
1189 SET @@global.binlog_format and SET @@persist.binlog_format must be
1190 disallowed if any replication channel applier is running, because
1191 SET @@global.binlog_format does not take effect when any replication
1192 channel applier is running. SET @@global.binlog_format takes effect
1193 on the channel until its applier is (re)starting.
1194 Note: SET @@persist_only.binlog_format is not disallowed if any
1195 replication channel applier is running, since unlike PERSIST,
1196 PERSIST_ONLY does not modify the runtime global system variable value.
1197 */
1198 enum_slave_channel_status slave_channel_status =
1199 has_any_slave_channel_open_temp_table_or_is_its_applier_running();
1200 if (slave_channel_status == SLAVE_CHANNEL_APPLIER_IS_RUNNING) {
1201 my_error(ER_RUNNING_APPLIER_PREVENTS_SWITCH_GLOBAL_BINLOG_FORMAT, MYF(0));
1202 return true;
1203 } else if (slave_channel_status == SLAVE_CHANNEL_HAS_OPEN_TEMPORARY_TABLE) {
1204 my_error(ER_TEMP_TABLE_PREVENTS_SWITCH_GLOBAL_BINLOG_FORMAT, MYF(0));
1205 return true;
1206 }
1207 }
1208
1209 if (!var->is_global_persist()) {
1210 /*
1211 SET @@session.binlog_format must be disallowed if the session has open
1212 temporary table(s). Otherwise DROP TEMPORARY TABLE is written into
1213 binary log (which disobeys the simple rule: When
1214 @@session.binlog_format=ROW/MIXED, the server must not write
1215 CREATE/DROP TEMPORARY TABLE to the binary log) in the following case:
1216 SET @@session.binlog_format=STATEMENT;
1217 CREATE TEMPORARY TABLE t1 (a INT);
1218 SET @@session.binlog_format=ROW;
1219 DROP TEMPORARY TABLE t1;
1220 And more, if binlog_format=ROW/MIXED and the session has open temporary
1221 table(s), these CREATE TEMPORARY TABLE are not written into the binlog,
1222 so we can not switch to STATEMENT.
1223 */
1224 if (thd->temporary_tables) {
1225 my_error(ER_TEMP_TABLE_PREVENTS_SWITCH_SESSION_BINLOG_FORMAT, MYF(0));
1226 return true;
1227 }
1228
1229 /*
1230 if in a stored function/trigger, it's too late to change mode
1231 */
1232 if (thd->in_sub_stmt) {
1233 my_error(ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT, MYF(0));
1234 return true;
1235 }
1236 /*
1237 Make the session variable 'binlog_format' read-only inside a transaction.
1238 */
1239 if (thd->in_active_multi_stmt_transaction()) {
1240 my_error(ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT, MYF(0));
1241 return true;
1242 }
1243 }
1244
1245 /*
1246 If moving to statement format, and binlog_row_value_options is set,
1247 generate a warning.
1248 */
1249 if (var->save_result.ulonglong_value == BINLOG_FORMAT_STMT) {
1250 if ((var->is_global_persist() &&
1251 global_system_variables.binlog_row_value_options != 0) ||
1252 (!var->is_global_persist() &&
1253 thd->variables.binlog_row_value_options != 0)) {
1254 push_warning_printf(thd, Sql_condition::SL_WARNING,
1255 ER_WARN_BINLOG_PARTIAL_UPDATES_DISABLED,
1256 ER_THD(thd, ER_WARN_BINLOG_PARTIAL_UPDATES_DISABLED),
1257 "binlog_format=STATEMENT", "PARTIAL_JSON");
1258 }
1259 }
1260
1261 return false;
1262 }
1263
fix_binlog_format_after_update(sys_var *,THD * thd,enum_var_type type)1264 static bool fix_binlog_format_after_update(sys_var *, THD *thd,
1265 enum_var_type type) {
1266 if (type == OPT_SESSION) thd->reset_current_stmt_binlog_format_row();
1267 return false;
1268 }
1269
prevent_global_rbr_exec_mode_idempotent(sys_var * self,THD *,set_var * var)1270 static bool prevent_global_rbr_exec_mode_idempotent(sys_var *self, THD *,
1271 set_var *var) {
1272 if (var->is_global_persist()) {
1273 my_error(ER_LOCAL_VARIABLE, MYF(0), self->name.str);
1274 return true;
1275 }
1276 return false;
1277 }
1278
1279 static Sys_var_test_flag Sys_core_file("core_file",
1280 "write a core-file on crashes",
1281 TEST_CORE_ON_SIGNAL);
1282
1283 static Sys_var_enum Sys_binlog_format(
1284 "binlog_format",
1285 "What form of binary logging the master will "
1286 "use: either ROW for row-based binary logging, STATEMENT "
1287 "for statement-based binary logging, or MIXED. MIXED is statement-"
1288 "based binary logging except for those statements where only row-"
1289 "based is correct: those which involve user-defined functions (i.e. "
1290 "UDFs) or the UUID() function; for those, row-based binary logging is "
1291 "automatically used. If NDBCLUSTER is enabled and binlog-format is "
1292 "MIXED, the format switches to row-based and back implicitly per each "
1293 "query accessing an NDBCLUSTER table",
1294 SESSION_VAR(binlog_format), CMD_LINE(REQUIRED_ARG, OPT_BINLOG_FORMAT),
1295 binlog_format_names, DEFAULT(BINLOG_FORMAT_ROW), NO_MUTEX_GUARD,
1296 NOT_IN_BINLOG, ON_CHECK(binlog_format_check),
1297 ON_UPDATE(fix_binlog_format_after_update));
1298
1299 static const char *rbr_exec_mode_names[] = {"STRICT", "IDEMPOTENT", nullptr};
1300 static Sys_var_enum rbr_exec_mode(
1301 "rbr_exec_mode",
1302 "Modes for how row events should be executed. Legal values "
1303 "are STRICT (default) and IDEMPOTENT. In IDEMPOTENT mode, "
1304 "the server will not throw errors for operations that are idempotent. "
1305 "In STRICT mode, server will throw errors for the operations that "
1306 "cause a conflict.",
1307 SESSION_VAR(rbr_exec_mode_options), NO_CMD_LINE, rbr_exec_mode_names,
1308 DEFAULT(RBR_EXEC_MODE_STRICT), NO_MUTEX_GUARD, NOT_IN_BINLOG,
1309 ON_CHECK(prevent_global_rbr_exec_mode_idempotent), ON_UPDATE(nullptr));
1310
check_binlog_row_image(sys_var * self MY_ATTRIBUTE ((unused)),THD * thd,set_var * var)1311 static bool check_binlog_row_image(sys_var *self MY_ATTRIBUTE((unused)),
1312 THD *thd, set_var *var) {
1313 DBUG_TRACE;
1314 if (check_session_admin(self, thd, var)) return true;
1315 if (var->save_result.ulonglong_value == BINLOG_ROW_IMAGE_FULL) {
1316 if ((var->is_global_persist() &&
1317 global_system_variables.binlog_row_value_options != 0) ||
1318 (!var->is_global_persist() &&
1319 thd->variables.binlog_row_value_options != 0)) {
1320 push_warning_printf(
1321 thd, Sql_condition::SL_WARNING,
1322 ER_WARN_BINLOG_PARTIAL_UPDATES_SUGGESTS_PARTIAL_IMAGES,
1323 ER_THD(thd, ER_WARN_BINLOG_PARTIAL_UPDATES_SUGGESTS_PARTIAL_IMAGES),
1324 "binlog_row_image=FULL", "PARTIAL_JSON");
1325 }
1326 }
1327 return false;
1328 }
1329
1330 static const char *binlog_row_image_names[] = {"MINIMAL", "NOBLOB", "FULL",
1331 NullS};
1332 static Sys_var_enum Sys_binlog_row_image(
1333 "binlog_row_image",
1334 "Controls whether rows should be logged in 'FULL', 'NOBLOB' or "
1335 "'MINIMAL' formats. 'FULL', means that all columns in the before "
1336 "and after image are logged. 'NOBLOB', means that mysqld avoids logging "
1337 "blob columns whenever possible (e.g. blob column was not changed or "
1338 "is not part of primary key). 'MINIMAL', means that a PK equivalent (PK "
1339 "columns or full row if there is no PK in the table) is logged in the "
1340 "before image, and only changed columns are logged in the after image. "
1341 "(Default: FULL).",
1342 SESSION_VAR(binlog_row_image), CMD_LINE(REQUIRED_ARG),
1343 binlog_row_image_names, DEFAULT(BINLOG_ROW_IMAGE_FULL), NO_MUTEX_GUARD,
1344 NOT_IN_BINLOG, ON_CHECK(check_binlog_row_image), ON_UPDATE(nullptr));
1345
1346 static const char *binlog_row_metadata_names[] = {"MINIMAL", "FULL", NullS};
1347 static Sys_var_enum Sys_binlog_row_metadata(
1348 "binlog_row_metadata",
1349 "Controls whether metadata is logged using FULL or MINIMAL format. "
1350 "FULL causes all metadata to be logged; MINIMAL means that only "
1351 "metadata actually required by slave is logged. Default: MINIMAL.",
1352 GLOBAL_VAR(binlog_row_metadata), CMD_LINE(REQUIRED_ARG),
1353 binlog_row_metadata_names, DEFAULT(BINLOG_ROW_METADATA_MINIMAL),
1354 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr));
1355
check_binlog_trx_compression(sys_var * self MY_ATTRIBUTE ((unused)),THD * thd,set_var * var)1356 static bool check_binlog_trx_compression(sys_var *self MY_ATTRIBUTE((unused)),
1357 THD *thd, set_var *var) {
1358 DBUG_TRACE;
1359 if (check_session_admin(self, thd, var)) return true;
1360
1361 if (!var->is_global_persist() && thd->in_active_multi_stmt_transaction()) {
1362 my_error(ER_VARIABLE_NOT_SETTABLE_IN_TRANSACTION, MYF(0),
1363 var->var->name.str);
1364 return true;
1365 }
1366 return false;
1367 }
1368
1369 static Sys_var_bool Sys_binlog_trx_compression(
1370 "binlog_transaction_compression",
1371 "Whether to compress transactions or not. Transactions are compressed "
1372 "using the ZSTD compression algorythm.",
1373 SESSION_VAR(binlog_trx_compression), CMD_LINE(OPT_ARG), DEFAULT(false),
1374 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_binlog_trx_compression));
1375
1376 #include "libbinlogevents/include/compression/zstd.h"
1377 static Sys_var_uint Sys_binlog_transaction_compression_level_zstd(
1378 "binlog_transaction_compression_level_zstd",
1379 "Specifies the transaction compression level for ZSTD "
1380 "transaction compression in the binary log.",
1381 SESSION_VAR(binlog_trx_compression_level_zstd), CMD_LINE(REQUIRED_ARG),
1382 VALID_RANGE(1, 22),
1383 DEFAULT(binary_log::transaction::compression::Zstd_comp::
1384 DEFAULT_COMPRESSION_LEVEL),
1385 BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG,
1386 ON_CHECK(check_binlog_trx_compression), ON_UPDATE(NULL));
1387
on_session_track_gtids_update(sys_var *,THD * thd,enum_var_type)1388 static bool on_session_track_gtids_update(sys_var *, THD *thd, enum_var_type) {
1389 thd->session_tracker.get_tracker(SESSION_GTIDS_TRACKER)->update(thd);
1390 return false;
1391 }
1392
1393 static const char *session_track_gtids_names[] = {"OFF", "OWN_GTID",
1394 "ALL_GTIDS", NullS};
1395 static Sys_var_enum Sys_session_track_gtids(
1396 "session_track_gtids",
1397 "Controls the amount of global transaction ids to be "
1398 "included in the response packet sent by the server."
1399 "(Default: OFF).",
1400 SESSION_VAR(session_track_gtids), CMD_LINE(REQUIRED_ARG),
1401 session_track_gtids_names, DEFAULT(OFF), NO_MUTEX_GUARD, NOT_IN_BINLOG,
1402 ON_CHECK(check_outside_trx), ON_UPDATE(on_session_track_gtids_update));
1403
binlog_direct_check(sys_var * self,THD * thd,set_var * var)1404 static bool binlog_direct_check(sys_var *self, THD *thd, set_var *var) {
1405 if (check_session_admin(self, thd, var)) return true;
1406
1407 if (var->is_global_persist()) return false;
1408
1409 /*
1410 Makes the session variable 'binlog_direct_non_transactional_updates'
1411 read-only if within a procedure, trigger or function.
1412 */
1413 if (thd->in_sub_stmt) {
1414 my_error(ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_DIRECT, MYF(0));
1415 return true;
1416 }
1417 /*
1418 Makes the session variable 'binlog_direct_non_transactional_updates'
1419 read-only inside a transaction.
1420 */
1421 if (thd->in_active_multi_stmt_transaction()) {
1422 my_error(ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT, MYF(0));
1423 return true;
1424 }
1425
1426 return false;
1427 }
1428
1429 static Sys_var_bool Sys_binlog_direct(
1430 "binlog_direct_non_transactional_updates",
1431 "Causes updates to non-transactional engines using statement format to "
1432 "be written directly to binary log. Before using this option make sure "
1433 "that there are no dependencies between transactional and "
1434 "non-transactional tables such as in the statement INSERT INTO t_myisam "
1435 "SELECT * FROM t_innodb; otherwise, slaves may diverge from the master.",
1436 SESSION_VAR(binlog_direct_non_trans_update), CMD_LINE(OPT_ARG),
1437 DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG,
1438 ON_CHECK(binlog_direct_check));
1439
1440 /**
1441 This variable is read only to users. It can be enabled or disabled
1442 only at mysqld startup. This variable is used by User thread and
1443 as well as by replication slave applier thread to apply relay_log.
1444 Slave applier thread enables/disables this option based on
1445 relay_log's from replication master versions. There is possibility of
1446 slave applier thread and User thread to have different setting for
1447 explicit_defaults_for_timestamp, hence this options is defined as
1448 SESSION_VAR rather than GLOBAL_VAR.
1449 */
1450 static Sys_var_bool Sys_explicit_defaults_for_timestamp(
1451 "explicit_defaults_for_timestamp",
1452 "This option causes CREATE TABLE to create all TIMESTAMP columns "
1453 "as NULL with DEFAULT NULL attribute, Without this option, "
1454 "TIMESTAMP columns are NOT NULL and have implicit DEFAULT clauses. "
1455 "The old behavior is deprecated. "
1456 "The variable can only be set by users having the SUPER privilege.",
1457 SESSION_VAR(explicit_defaults_for_timestamp), CMD_LINE(OPT_ARG),
1458 DEFAULT(true), NO_MUTEX_GUARD, NOT_IN_BINLOG,
1459 ON_CHECK(check_explicit_defaults_for_timestamp));
1460
repository_check(sys_var * self,THD * thd,set_var * var,SLAVE_THD_TYPE thread_mask)1461 static bool repository_check(sys_var *self, THD *thd, set_var *var,
1462 SLAVE_THD_TYPE thread_mask) {
1463 bool ret = false;
1464 if (check_session_admin_outside_trx_outside_sf(self, thd, var)) return true;
1465 Master_info *mi;
1466 int running = 0;
1467 const char *msg = nullptr;
1468 bool rpl_info_option = static_cast<uint>(var->save_result.ulonglong_value);
1469
1470 /* don't convert if the repositories are same */
1471 if (rpl_info_option == (thread_mask == SLAVE_THD_IO ? opt_mi_repository_id
1472 : opt_rli_repository_id))
1473 return false;
1474
1475 channel_map.wrlock();
1476
1477 /* Repository conversion not possible, when multiple channels exist */
1478 if (channel_map.get_num_instances(true) > 1) {
1479 msg = "Repository conversion is possible when only default channel exists";
1480 my_error(ER_CHANGE_RPL_INFO_REPOSITORY_FAILURE, MYF(0), msg);
1481 channel_map.unlock();
1482 return true;
1483 }
1484
1485 mi = channel_map.get_default_channel_mi();
1486
1487 if (mi != nullptr) {
1488 mi->channel_wrlock();
1489 lock_slave_threads(mi);
1490 init_thread_mask(&running, mi, false);
1491 if (!running) {
1492 switch (thread_mask) {
1493 case SLAVE_THD_IO:
1494 if (Rpl_info_factory::change_mi_repository(
1495 mi, static_cast<uint>(var->save_result.ulonglong_value),
1496 &msg)) {
1497 ret = true;
1498 my_error(ER_CHANGE_RPL_INFO_REPOSITORY_FAILURE, MYF(0), msg);
1499 }
1500 break;
1501 case SLAVE_THD_SQL:
1502 mts_recovery_groups(mi->rli);
1503 if (!mi->rli->is_mts_recovery()) {
1504 if (Rpl_info_factory::reset_workers(mi->rli) ||
1505 Rpl_info_factory::change_rli_repository(
1506 mi->rli,
1507 static_cast<uint>(var->save_result.ulonglong_value),
1508 &msg)) {
1509 ret = true;
1510 my_error(ER_CHANGE_RPL_INFO_REPOSITORY_FAILURE, MYF(0), msg);
1511 }
1512 } else
1513 LogErr(WARNING_LEVEL, ER_RPL_REPO_HAS_GAPS);
1514 break;
1515 default:
1516 assert(0);
1517 break;
1518 }
1519 } else {
1520 ret = true;
1521 my_error(ER_SLAVE_CHANNEL_MUST_STOP, MYF(0), mi->get_channel());
1522 }
1523 unlock_slave_threads(mi);
1524 mi->channel_unlock();
1525 }
1526 channel_map.unlock();
1527 return ret;
1528 }
1529
relay_log_info_repository_check(sys_var * self,THD * thd,set_var * var)1530 static bool relay_log_info_repository_check(sys_var *self, THD *thd,
1531 set_var *var) {
1532 return repository_check(self, thd, var, SLAVE_THD_SQL);
1533 }
1534
master_info_repository_check(sys_var * self,THD * thd,set_var * var)1535 static bool master_info_repository_check(sys_var *self, THD *thd,
1536 set_var *var) {
1537 return repository_check(self, thd, var, SLAVE_THD_IO);
1538 }
1539
relay_log_info_repository_update(sys_var *,THD * thd,enum_var_type)1540 static bool relay_log_info_repository_update(sys_var *, THD *thd,
1541 enum_var_type) {
1542 if (opt_rli_repository_id == INFO_REPOSITORY_FILE) {
1543 push_warning_printf(
1544 thd, Sql_condition::SL_WARNING, ER_WARN_DEPRECATED_SYNTAX,
1545 ER_THD(thd, ER_WARN_DEPRECATED_SYNTAX), "FILE", "'TABLE'");
1546 }
1547 return false;
1548 }
1549
master_info_repository_update(sys_var *,THD * thd,enum_var_type)1550 static bool master_info_repository_update(sys_var *, THD *thd, enum_var_type) {
1551 if (opt_mi_repository_id == INFO_REPOSITORY_FILE) {
1552 push_warning_printf(
1553 thd, Sql_condition::SL_WARNING, ER_WARN_DEPRECATED_SYNTAX,
1554 ER_THD(thd, ER_WARN_DEPRECATED_SYNTAX), "FILE", "'TABLE'");
1555 }
1556 return false;
1557 }
1558
1559 static const char *repository_names[] = {"FILE", "TABLE",
1560 #ifndef DBUG_OFF
1561 "DUMMY",
1562 #endif
1563 nullptr};
1564
1565 ulong opt_mi_repository_id = INFO_REPOSITORY_TABLE;
1566 static Sys_var_enum Sys_mi_repository(
1567 "master_info_repository",
1568 "Defines the type of the repository for the master information.",
1569 GLOBAL_VAR(opt_mi_repository_id), CMD_LINE(REQUIRED_ARG), repository_names,
1570 DEFAULT(INFO_REPOSITORY_TABLE), NO_MUTEX_GUARD, NOT_IN_BINLOG,
1571 ON_CHECK(master_info_repository_check),
1572 ON_UPDATE(master_info_repository_update));
1573
1574 ulong opt_rli_repository_id = INFO_REPOSITORY_TABLE;
1575 static Sys_var_enum Sys_rli_repository(
1576 "relay_log_info_repository",
1577 "Defines the type of the repository for the relay log information "
1578 "and associated workers.",
1579 GLOBAL_VAR(opt_rli_repository_id), CMD_LINE(REQUIRED_ARG), repository_names,
1580 DEFAULT(INFO_REPOSITORY_TABLE), NO_MUTEX_GUARD, NOT_IN_BINLOG,
1581 ON_CHECK(relay_log_info_repository_check),
1582 ON_UPDATE(relay_log_info_repository_update));
1583
1584 static Sys_var_bool Sys_binlog_rows_query(
1585 "binlog_rows_query_log_events",
1586 "Allow writing of Rows_query_log events into binary log.",
1587 SESSION_VAR(binlog_rows_query_log_events), CMD_LINE(OPT_ARG),
1588 DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG,
1589 ON_CHECK(check_session_admin));
1590
1591 static Sys_var_bool Sys_binlog_order_commits(
1592 "binlog_order_commits",
1593 "Issue internal commit calls in the same order as transactions are"
1594 " written to the binary log. Default is to order commits.",
1595 GLOBAL_VAR(opt_binlog_order_commits), CMD_LINE(OPT_ARG), DEFAULT(true));
1596
1597 static Sys_var_ulong Sys_bulk_insert_buff_size(
1598 "bulk_insert_buffer_size",
1599 "Size of tree cache used in bulk "
1600 "insert optimisation. Note that this is a limit per thread!",
1601 HINT_UPDATEABLE SESSION_VAR(bulk_insert_buff_size), CMD_LINE(REQUIRED_ARG),
1602 VALID_RANGE(0, ULONG_MAX), DEFAULT(8192 * 1024), BLOCK_SIZE(1),
1603 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_session_admin));
1604
1605 static Sys_var_charptr Sys_character_sets_dir(
1606 "character_sets_dir", "Directory where character sets are",
1607 READ_ONLY NON_PERSIST GLOBAL_VAR(charsets_dir), CMD_LINE(REQUIRED_ARG),
1608 IN_FS_CHARSET, DEFAULT(nullptr));
1609
check_not_null(sys_var *,THD *,set_var * var)1610 static bool check_not_null(sys_var *, THD *, set_var *var) {
1611 return var->value && var->value->is_null();
1612 }
1613
1614 /**
1615 Check storage engine is not empty and log warning.
1616
1617 Checks if default_storage_engine or default_tmp_storage_engine is set
1618 empty and return true. This method also logs warning if the
1619 storage engine set is a disabled storage engine specified in
1620 disabled_storage_engines.
1621
1622 @param self pointer to system variable object.
1623 @param thd Connection handle.
1624 @param var pointer to set variable object.
1625
1626 @return true if the set variable is empty.
1627 false if the set variable is not empty.
1628 */
check_storage_engine(sys_var * self,THD * thd,set_var * var)1629 static bool check_storage_engine(sys_var *self, THD *thd, set_var *var) {
1630 if (check_not_null(self, thd, var)) return true;
1631
1632 if (!opt_initialize && !opt_noacl) {
1633 char buff[STRING_BUFFER_USUAL_SIZE];
1634 String str(buff, sizeof(buff), system_charset_info), *res;
1635 LEX_CSTRING se_name;
1636
1637 if (var->value) {
1638 res = var->value->val_str(&str);
1639 lex_cstring_set(&se_name, res->ptr());
1640 } else {
1641 // Use the default value defined by sys_var.
1642 lex_cstring_set(&se_name,
1643 pointer_cast<const char *>(
1644 down_cast<Sys_var_plugin *>(self)->global_value_ptr(
1645 thd, nullptr)));
1646 }
1647
1648 plugin_ref plugin;
1649 if ((plugin = ha_resolve_by_name(nullptr, &se_name, false))) {
1650 handlerton *hton = plugin_data<handlerton *>(plugin);
1651 if (ha_is_storage_engine_disabled(hton))
1652 LogErr(WARNING_LEVEL, ER_DISABLED_STORAGE_ENGINE_AS_DEFAULT,
1653 self->name.str, se_name.str);
1654 plugin_unlock(nullptr, plugin);
1655 }
1656 }
1657 return false;
1658 }
1659
check_charset(sys_var *,THD * thd,set_var * var)1660 static bool check_charset(sys_var *, THD *thd, set_var *var) {
1661 if (!var->value) return false;
1662
1663 char buff[STRING_BUFFER_USUAL_SIZE];
1664 if (var->value->result_type() == STRING_RESULT) {
1665 String str(buff, sizeof(buff), system_charset_info), *res;
1666 if (!(res = var->value->val_str(&str)))
1667 var->save_result.ptr = nullptr;
1668 else {
1669 ErrConvString err(res); /* Get utf8 '\0' terminated string */
1670 if (!(var->save_result.ptr =
1671 get_charset_by_csname(err.ptr(), MY_CS_PRIMARY, MYF(0))) &&
1672 !(var->save_result.ptr = get_old_charset_by_name(err.ptr()))) {
1673 my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), err.ptr());
1674 return true;
1675 }
1676 warn_on_deprecated_charset(
1677 thd, static_cast<const CHARSET_INFO *>(var->save_result.ptr),
1678 err.ptr());
1679 }
1680 } else // INT_RESULT
1681 {
1682 int csno = (int)var->value->val_int();
1683 if (!(var->save_result.ptr = get_charset(csno, MYF(0)))) {
1684 my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), llstr(csno, buff));
1685 return true;
1686 }
1687 warn_on_deprecated_charset(
1688 thd, static_cast<const CHARSET_INFO *>(var->save_result.ptr),
1689 static_cast<const CHARSET_INFO *>(var->save_result.ptr)->name);
1690 }
1691 return false;
1692 }
check_charset_not_null(sys_var * self,THD * thd,set_var * var)1693 static bool check_charset_not_null(sys_var *self, THD *thd, set_var *var) {
1694 return check_charset(self, thd, var) || check_not_null(self, thd, var);
1695 }
1696
1697 namespace {
1698 struct Get_name {
Get_name__anon9d05e1790111::Get_name1699 explicit Get_name(const CHARSET_INFO *ci) : m_ci(ci) {}
get_name__anon9d05e1790111::Get_name1700 const uchar *get_name() const {
1701 return pointer_cast<const uchar *>(m_ci->name);
1702 }
1703 const CHARSET_INFO *m_ci;
1704 };
1705
1706 struct Get_csname {
Get_csname__anon9d05e1790111::Get_csname1707 explicit Get_csname(const CHARSET_INFO *ci) : m_ci(ci) {}
get_name__anon9d05e1790111::Get_csname1708 const uchar *get_name() const {
1709 return pointer_cast<const uchar *>(m_ci->csname);
1710 }
1711 const CHARSET_INFO *m_ci;
1712 };
1713
1714 } // namespace
1715
1716 static CHARSET_INFO *charset_system_default = &my_charset_utf8_general_ci;
1717
1718 static Sys_var_struct<CHARSET_INFO, Get_csname> Sys_character_set_system(
1719 "character_set_system",
1720 "The character set used by the server "
1721 "for storing identifiers",
1722 READ_ONLY NON_PERSIST GLOBAL_VAR(system_charset_info), NO_CMD_LINE,
1723 DEFAULT(&charset_system_default));
1724
1725 static Sys_var_struct<CHARSET_INFO, Get_csname> Sys_character_set_server(
1726 "character_set_server", "The default character set",
1727 SESSION_VAR(collation_server), NO_CMD_LINE, DEFAULT(&default_charset_info),
1728 NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_charset_not_null));
1729
check_charset_db(sys_var * self,THD * thd,set_var * var)1730 static bool check_charset_db(sys_var *self, THD *thd, set_var *var) {
1731 if (check_session_admin(self, thd, var)) return true;
1732 if (check_charset_not_null(self, thd, var)) return true;
1733 if (!var->value) // = DEFAULT
1734 var->save_result.ptr = thd->db_charset;
1735 return false;
1736 }
update_deprecated(sys_var * self,THD * thd,enum_var_type)1737 static bool update_deprecated(sys_var *self, THD *thd, enum_var_type) {
1738 push_warning_printf(
1739 thd, Sql_condition::SL_WARNING, ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT,
1740 ER_THD(thd, ER_WARN_DEPRECATED_SYSVAR_UPDATE), self->name.str);
1741 return false;
1742 }
1743 static Sys_var_struct<CHARSET_INFO, Get_csname> Sys_character_set_database(
1744 "character_set_database", " The character set used by the default database",
1745 SESSION_VAR(collation_database), NO_CMD_LINE,
1746 DEFAULT(&default_charset_info), NO_MUTEX_GUARD, IN_BINLOG,
1747 ON_CHECK(check_charset_db), ON_UPDATE(update_deprecated));
1748
check_cs_client(sys_var * self,THD * thd,set_var * var)1749 static bool check_cs_client(sys_var *self, THD *thd, set_var *var) {
1750 if (check_charset_not_null(self, thd, var)) return true;
1751
1752 // We don't currently support any variable-width character set with a minumum
1753 // length greater than 1. If we ever do, we have to revisit
1754 // is_supported_parser_charset(). See Item_func_statement_digest::val_str()
1755 // and Item_func_statement_digest_text::val_str().
1756 return (static_cast<const CHARSET_INFO *>(var->save_result.ptr))->mbminlen >
1757 1;
1758 }
fix_thd_charset(sys_var *,THD * thd,enum_var_type type)1759 static bool fix_thd_charset(sys_var *, THD *thd, enum_var_type type) {
1760 if (type == OPT_SESSION) thd->update_charset();
1761 return false;
1762 }
1763 static Sys_var_struct<CHARSET_INFO, Get_csname> Sys_character_set_client(
1764 "character_set_client",
1765 "The character set for statements "
1766 "that arrive from the client",
1767 SESSION_VAR(character_set_client), NO_CMD_LINE,
1768 DEFAULT(&default_charset_info), NO_MUTEX_GUARD, IN_BINLOG,
1769 ON_CHECK(check_cs_client), ON_UPDATE(fix_thd_charset));
1770
1771 static Sys_var_struct<CHARSET_INFO, Get_csname> Sys_character_set_connection(
1772 "character_set_connection",
1773 "The character set used for "
1774 "literals that do not have a character set introducer and for "
1775 "number-to-string conversion",
1776 SESSION_VAR(collation_connection), NO_CMD_LINE,
1777 DEFAULT(&default_charset_info), NO_MUTEX_GUARD, IN_BINLOG,
1778 ON_CHECK(check_charset_not_null), ON_UPDATE(fix_thd_charset));
1779
1780 static Sys_var_struct<CHARSET_INFO, Get_csname> Sys_character_set_results(
1781 "character_set_results",
1782 "The character set used for returning "
1783 "query results to the client",
1784 SESSION_VAR(character_set_results), NO_CMD_LINE,
1785 DEFAULT(&default_charset_info), NO_MUTEX_GUARD, NOT_IN_BINLOG,
1786 ON_CHECK(check_charset));
1787
check_cs_filesystem(sys_var * self,THD * thd,set_var * var)1788 static bool check_cs_filesystem(sys_var *self, THD *thd, set_var *var) {
1789 if (check_session_admin(self, thd, var)) return true;
1790 if (check_charset_not_null(self, thd, var)) return true;
1791
1792 return false;
1793 }
1794
1795 static Sys_var_struct<CHARSET_INFO, Get_csname> Sys_character_set_filesystem(
1796 "character_set_filesystem", "The filesystem character set",
1797 SESSION_VAR(character_set_filesystem), NO_CMD_LINE,
1798 DEFAULT(&character_set_filesystem), NO_MUTEX_GUARD, NOT_IN_BINLOG,
1799 ON_CHECK(check_cs_filesystem), ON_UPDATE(fix_thd_charset));
1800
1801 static const char *completion_type_names[] = {"NO_CHAIN", "CHAIN", "RELEASE",
1802 nullptr};
1803 static Sys_var_enum Sys_completion_type(
1804 "completion_type",
1805 "The transaction completion type, one of "
1806 "NO_CHAIN, CHAIN, RELEASE",
1807 SESSION_VAR(completion_type), CMD_LINE(REQUIRED_ARG), completion_type_names,
1808 DEFAULT(0));
1809
check_collation_not_null(sys_var * self,THD * thd,set_var * var)1810 static bool check_collation_not_null(sys_var *self, THD *thd, set_var *var) {
1811 if (!var->value) return false;
1812
1813 char buff[STRING_BUFFER_USUAL_SIZE];
1814 if (var->value->result_type() == STRING_RESULT) {
1815 String str(buff, sizeof(buff), system_charset_info), *res;
1816 if (!(res = var->value->val_str(&str)))
1817 var->save_result.ptr = nullptr;
1818 else {
1819 ErrConvString err(res); /* Get utf8 '\0'-terminated string */
1820 if (!(var->save_result.ptr = get_charset_by_name(err.ptr(), MYF(0)))) {
1821 my_error(ER_UNKNOWN_COLLATION, MYF(0), err.ptr());
1822 return true;
1823 }
1824 }
1825 } else // INT_RESULT
1826 {
1827 int csno = (int)var->value->val_int();
1828 if (!(var->save_result.ptr = get_charset(csno, MYF(0)))) {
1829 my_error(ER_UNKNOWN_COLLATION, MYF(0), llstr(csno, buff));
1830 return true;
1831 }
1832 }
1833 if (var->save_result.ptr) {
1834 warn_on_deprecated_collation(
1835 thd, static_cast<const CHARSET_INFO *>(var->save_result.ptr));
1836 }
1837
1838 return check_not_null(self, thd, var);
1839 }
1840 static Sys_var_struct<CHARSET_INFO, Get_name> Sys_collation_connection(
1841 "collation_connection",
1842 "The collation of the connection "
1843 "character set",
1844 SESSION_VAR(collation_connection), NO_CMD_LINE,
1845 DEFAULT(&default_charset_info), NO_MUTEX_GUARD, IN_BINLOG,
1846 ON_CHECK(check_collation_not_null), ON_UPDATE(fix_thd_charset));
1847
check_collation_db(sys_var * self,THD * thd,set_var * var)1848 static bool check_collation_db(sys_var *self, THD *thd, set_var *var) {
1849 if (check_collation_not_null(self, thd, var)) return true;
1850 if (!var->value) // = DEFAULT
1851 var->save_result.ptr = thd->db_charset;
1852 return false;
1853 }
1854 static Sys_var_struct<CHARSET_INFO, Get_name> Sys_collation_database(
1855 "collation_database",
1856 "The collation of the database "
1857 "character set",
1858 SESSION_VAR(collation_database), NO_CMD_LINE,
1859 DEFAULT(&default_charset_info), NO_MUTEX_GUARD, IN_BINLOG,
1860 ON_CHECK(check_collation_db), ON_UPDATE(update_deprecated));
1861
1862 static Sys_var_struct<CHARSET_INFO, Get_name> Sys_collation_server(
1863 "collation_server", "The server default collation",
1864 SESSION_VAR(collation_server), NO_CMD_LINE, DEFAULT(&default_charset_info),
1865 NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_collation_not_null));
1866
1867 static const char *concurrent_insert_names[] = {"NEVER", "AUTO", "ALWAYS",
1868 nullptr};
1869 static Sys_var_enum Sys_concurrent_insert(
1870 "concurrent_insert",
1871 "Use concurrent insert with MyISAM. Possible "
1872 "values are NEVER, AUTO, ALWAYS",
1873 GLOBAL_VAR(myisam_concurrent_insert), CMD_LINE(OPT_ARG),
1874 concurrent_insert_names, DEFAULT(1));
1875
1876 static Sys_var_ulong Sys_connect_timeout(
1877 "connect_timeout",
1878 "The number of seconds the mysqld server is waiting for a connect "
1879 "packet before responding with 'Bad handshake'",
1880 GLOBAL_VAR(connect_timeout), CMD_LINE(REQUIRED_ARG),
1881 VALID_RANGE(2, LONG_TIMEOUT), DEFAULT(CONNECT_TIMEOUT), BLOCK_SIZE(1));
1882
1883 static Sys_var_ulong Sys_information_schema_stats_expiry(
1884 "information_schema_stats_expiry",
1885 "The number of seconds after which mysqld server will fetch "
1886 "data from storage engine and replace the data in cache.",
1887 SESSION_VAR(information_schema_stats_expiry), CMD_LINE(REQUIRED_ARG),
1888 VALID_RANGE(0, LONG_TIMEOUT), DEFAULT(24 * 60 * 60), BLOCK_SIZE(1));
1889
1890 static Sys_var_charptr Sys_datadir(
1891 "datadir", "Path to the database root directory",
1892 READ_ONLY NON_PERSIST GLOBAL_VAR(mysql_real_data_home_ptr),
1893 CMD_LINE(REQUIRED_ARG, 'h'), IN_FS_CHARSET, DEFAULT(mysql_real_data_home));
1894
1895 #ifndef DBUG_OFF
1896 static Sys_var_dbug Sys_dbug("debug", "Debug log", sys_var::SESSION,
1897 CMD_LINE(OPT_ARG, '#'), DEFAULT(""),
1898 NO_MUTEX_GUARD, NOT_IN_BINLOG,
1899 ON_CHECK(check_session_admin));
1900 #endif
1901
1902 /**
1903 @todo
1904 When updating myisam_delay_key_write, we should do a 'flush tables'
1905 of all MyISAM tables to ensure that they are reopen with the
1906 new attribute.
1907 */
fix_delay_key_write(sys_var *,THD *,enum_var_type)1908 export bool fix_delay_key_write(sys_var *, THD *, enum_var_type) {
1909 switch (delay_key_write_options) {
1910 case DELAY_KEY_WRITE_NONE:
1911 myisam_delay_key_write = false;
1912 break;
1913 case DELAY_KEY_WRITE_ON:
1914 myisam_delay_key_write = true;
1915 break;
1916 case DELAY_KEY_WRITE_ALL:
1917 myisam_delay_key_write = true;
1918 ha_open_options |= HA_OPEN_DELAY_KEY_WRITE;
1919 break;
1920 }
1921 return false;
1922 }
1923 static const char *delay_key_write_names[] = {"OFF", "ON", "ALL", NullS};
1924 static Sys_var_enum Sys_delay_key_write(
1925 "delay_key_write", "Type of DELAY_KEY_WRITE",
1926 GLOBAL_VAR(delay_key_write_options), CMD_LINE(OPT_ARG),
1927 delay_key_write_names, DEFAULT(DELAY_KEY_WRITE_ON), NO_MUTEX_GUARD,
1928 NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(fix_delay_key_write));
1929
1930 static Sys_var_ulong Sys_delayed_insert_limit(
1931 "delayed_insert_limit",
1932 "After inserting delayed_insert_limit rows, the INSERT DELAYED "
1933 "handler will check if there are any SELECT statements pending. "
1934 "If so, it allows these to execute before continuing. "
1935 "This variable is deprecated along with INSERT DELAYED.",
1936 GLOBAL_VAR(delayed_insert_limit), CMD_LINE(REQUIRED_ARG),
1937 VALID_RANGE(1, ULONG_MAX), DEFAULT(DELAYED_LIMIT), BLOCK_SIZE(1),
1938 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr),
1939 DEPRECATED_VAR(""));
1940
1941 static Sys_var_ulong Sys_delayed_insert_timeout(
1942 "delayed_insert_timeout",
1943 "How long a INSERT DELAYED thread should wait for INSERT statements "
1944 "before terminating. "
1945 "This variable is deprecated along with INSERT DELAYED.",
1946 GLOBAL_VAR(delayed_insert_timeout), CMD_LINE(REQUIRED_ARG),
1947 VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(DELAYED_WAIT_TIMEOUT), BLOCK_SIZE(1),
1948 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr),
1949 DEPRECATED_VAR(""));
1950
1951 static Sys_var_ulong Sys_delayed_queue_size(
1952 "delayed_queue_size",
1953 "What size queue (in rows) should be allocated for handling INSERT "
1954 "DELAYED. If the queue becomes full, any client that does INSERT "
1955 "DELAYED will wait until there is room in the queue again. "
1956 "This variable is deprecated along with INSERT DELAYED.",
1957 GLOBAL_VAR(delayed_queue_size), CMD_LINE(REQUIRED_ARG),
1958 VALID_RANGE(1, ULONG_MAX), DEFAULT(DELAYED_QUEUE_SIZE), BLOCK_SIZE(1),
1959 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr),
1960 DEPRECATED_VAR(""));
1961
1962 static const char *event_scheduler_names[] = {"OFF", "ON", "DISABLED", NullS};
event_scheduler_check(sys_var *,THD *,set_var * var)1963 static bool event_scheduler_check(sys_var *, THD *, set_var *var) {
1964 /* DISABLED is only accepted on the command line */
1965 if (var->save_result.ulonglong_value == Events::EVENTS_DISABLED) return true;
1966 if (Events::opt_event_scheduler == Events::EVENTS_DISABLED) {
1967 my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
1968 "--event-scheduler=DISABLED or --skip-grant-tables");
1969 return true;
1970 }
1971 return false;
1972 }
event_scheduler_update(sys_var *,THD *,enum_var_type)1973 static bool event_scheduler_update(sys_var *, THD *, enum_var_type) {
1974 int err_no = 0;
1975 ulong opt_event_scheduler_value = Events::opt_event_scheduler;
1976 mysql_mutex_unlock(&LOCK_global_system_variables);
1977 /*
1978 Events::start() is heavyweight. In particular it creates a new THD,
1979 which takes LOCK_global_system_variables internally.
1980 Thus we have to release it here.
1981 We need to re-take it before returning, though.
1982
1983 Note that since we release LOCK_global_system_variables before calling
1984 start/stop, there is a possibility that the server variable
1985 can become out of sync with the real event scheduler state.
1986
1987 This can happen with two concurrent statments if the first gets
1988 interrupted after start/stop but before retaking
1989 LOCK_global_system_variables. However, this problem should be quite
1990 rare and it's difficult to avoid it without opening up possibilities
1991 for deadlocks. See bug#51160.
1992 */
1993 bool ret = opt_event_scheduler_value == Events::EVENTS_ON
1994 ? Events::start(&err_no)
1995 : Events::stop();
1996 mysql_mutex_lock(&LOCK_global_system_variables);
1997 if (ret) {
1998 Events::opt_event_scheduler = Events::EVENTS_OFF;
1999 my_error(ER_EVENT_SET_VAR_ERROR, MYF(0), err_no);
2000 }
2001 return ret;
2002 }
2003
2004 static Sys_var_enum Sys_event_scheduler(
2005 "event_scheduler",
2006 "Enable the event scheduler. Possible values are "
2007 "ON, OFF, and DISABLED (keep the event scheduler completely "
2008 "deactivated, it cannot be activated run-time)",
2009 GLOBAL_VAR(Events::opt_event_scheduler), CMD_LINE(OPT_ARG),
2010 event_scheduler_names, DEFAULT(Events::EVENTS_ON), NO_MUTEX_GUARD,
2011 NOT_IN_BINLOG, ON_CHECK(event_scheduler_check),
2012 ON_UPDATE(event_scheduler_update));
2013
check_expire_logs_days(sys_var *,THD *,set_var * var)2014 static bool check_expire_logs_days(sys_var *, THD *, set_var *var) {
2015 ulonglong expire_logs_days_value = var->save_result.ulonglong_value;
2016
2017 if (expire_logs_days_value && binlog_expire_logs_seconds) {
2018 my_error(ER_BINLOG_EXPIRE_LOG_DAYS_AND_SECS_USED_TOGETHER, MYF(0));
2019 return true;
2020 }
2021 return false;
2022 }
2023
check_expire_logs_seconds(sys_var *,THD *,set_var * var)2024 static bool check_expire_logs_seconds(sys_var *, THD *, set_var *var) {
2025 ulonglong expire_logs_seconds_value = var->save_result.ulonglong_value;
2026
2027 if (expire_logs_days && expire_logs_seconds_value) {
2028 my_error(ER_EXPIRE_LOGS_DAYS_IGNORED, MYF(0));
2029 return true;
2030 }
2031 return false;
2032 }
2033
2034 static Sys_var_ulong Sys_expire_logs_days(
2035 "expire_logs_days",
2036 "If non-zero, binary logs will be purged after expire_logs_days "
2037 "days; If this option alone is set on the command line or in a "
2038 "configuration file, it overrides the default value for "
2039 "binlog-expire-logs-seconds. If both options are set to nonzero values, "
2040 "binlog-expire-logs-seconds takes priority. Possible purges happen at "
2041 "startup and at binary log rotation.",
2042 GLOBAL_VAR(expire_logs_days), CMD_LINE(REQUIRED_ARG, OPT_EXPIRE_LOGS_DAYS),
2043 VALID_RANGE(0, 99), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD,
2044 NOT_IN_BINLOG, ON_CHECK(check_expire_logs_days), ON_UPDATE(nullptr),
2045 DEPRECATED_VAR("binlog_expire_logs_seconds"));
2046
2047 static Sys_var_ulong Sys_binlog_expire_logs_seconds(
2048 "binlog_expire_logs_seconds",
2049 "If non-zero, binary logs will be purged after binlog_expire_logs_seconds"
2050 " seconds; If both this option and expire_logs_days are set to non-zero"
2051 " values, this option takes priority. Purges happen at"
2052 " startup and at binary log rotation.",
2053 GLOBAL_VAR(binlog_expire_logs_seconds),
2054 CMD_LINE(REQUIRED_ARG, OPT_BINLOG_EXPIRE_LOGS_SECONDS),
2055 VALID_RANGE(0, 0xFFFFFFFF), DEFAULT(2592000), BLOCK_SIZE(1), NO_MUTEX_GUARD,
2056 NOT_IN_BINLOG, ON_CHECK(check_expire_logs_seconds), ON_UPDATE(nullptr));
2057
2058 static Sys_var_bool Sys_flush(
2059 "flush", "Flush MyISAM tables to disk between SQL commands",
2060 GLOBAL_VAR(myisam_flush), CMD_LINE(OPT_ARG), DEFAULT(false));
2061
2062 static Sys_var_ulong Sys_flush_time(
2063 "flush_time",
2064 "A dedicated thread is created to flush all tables at the "
2065 "given interval",
2066 GLOBAL_VAR(flush_time), CMD_LINE(REQUIRED_ARG),
2067 VALID_RANGE(0, LONG_TIMEOUT), DEFAULT(0), BLOCK_SIZE(1));
2068
check_ftb_syntax(sys_var *,THD *,set_var * var)2069 static bool check_ftb_syntax(sys_var *, THD *, set_var *var) {
2070 return ft_boolean_check_syntax_string(
2071 (uchar *)(var->save_result.string_value.str));
2072 }
2073 /// @todo make SESSION_VAR (usability enhancement and a fix for a race
2074 /// condition)
2075 static Sys_var_charptr Sys_ft_boolean_syntax(
2076 "ft_boolean_syntax",
2077 "List of operators for "
2078 "MATCH ... AGAINST ( ... IN BOOLEAN MODE)",
2079 GLOBAL_VAR(ft_boolean_syntax), CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET,
2080 DEFAULT(DEFAULT_FTB_SYNTAX), NO_MUTEX_GUARD, NOT_IN_BINLOG,
2081 ON_CHECK(check_ftb_syntax));
2082
2083 static Sys_var_ulong Sys_ft_max_word_len(
2084 "ft_max_word_len",
2085 "The maximum length of the word to be included in a FULLTEXT index. "
2086 "Note: FULLTEXT indexes must be rebuilt after changing this variable",
2087 READ_ONLY GLOBAL_VAR(ft_max_word_len), CMD_LINE(REQUIRED_ARG),
2088 VALID_RANGE(10, HA_FT_MAXCHARLEN), DEFAULT(HA_FT_MAXCHARLEN),
2089 BLOCK_SIZE(1));
2090
2091 static Sys_var_ulong Sys_ft_min_word_len(
2092 "ft_min_word_len",
2093 "The minimum length of the word to be included in a FULLTEXT index. "
2094 "Note: FULLTEXT indexes must be rebuilt after changing this variable",
2095 READ_ONLY GLOBAL_VAR(ft_min_word_len), CMD_LINE(REQUIRED_ARG),
2096 VALID_RANGE(1, HA_FT_MAXCHARLEN), DEFAULT(4), BLOCK_SIZE(1));
2097
2098 /// @todo make it an updatable SESSION_VAR
2099 static Sys_var_ulong Sys_ft_query_expansion_limit(
2100 "ft_query_expansion_limit",
2101 "Number of best matches to use for query expansion",
2102 READ_ONLY GLOBAL_VAR(ft_query_expansion_limit), CMD_LINE(REQUIRED_ARG),
2103 VALID_RANGE(0, 1000), DEFAULT(20), BLOCK_SIZE(1));
2104
2105 static Sys_var_charptr Sys_ft_stopword_file(
2106 "ft_stopword_file", "Use stopwords from this file instead of built-in list",
2107 READ_ONLY NON_PERSIST GLOBAL_VAR(ft_stopword_file), CMD_LINE(REQUIRED_ARG),
2108 IN_FS_CHARSET, DEFAULT(nullptr));
2109
check_init_string(sys_var *,THD *,set_var * var)2110 static bool check_init_string(sys_var *, THD *, set_var *var) {
2111 if (var->save_result.string_value.str == nullptr) {
2112 var->save_result.string_value.str = const_cast<char *>("");
2113 var->save_result.string_value.length = 0;
2114 }
2115 return false;
2116 }
2117 static PolyLock_rwlock PLock_sys_init_connect(&LOCK_sys_init_connect);
2118 static Sys_var_lexstring Sys_init_connect(
2119 "init_connect",
2120 "Command(s) that are executed for each "
2121 "new connection",
2122 GLOBAL_VAR(opt_init_connect), CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET,
2123 DEFAULT(""), &PLock_sys_init_connect, NOT_IN_BINLOG,
2124 ON_CHECK(check_init_string));
2125
2126 static Sys_var_charptr Sys_init_file(
2127 "init_file", "Read SQL commands from this file at startup",
2128 READ_ONLY NON_PERSIST GLOBAL_VAR(opt_init_file), CMD_LINE(REQUIRED_ARG),
2129 IN_FS_CHARSET, DEFAULT(nullptr));
2130
2131 static PolyLock_rwlock PLock_sys_init_slave(&LOCK_sys_init_slave);
2132 static Sys_var_lexstring Sys_init_slave(
2133 "init_slave",
2134 "Command(s) that are executed by a slave server "
2135 "each time the SQL thread starts",
2136 GLOBAL_VAR(opt_init_slave), CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET,
2137 DEFAULT(""), &PLock_sys_init_slave, NOT_IN_BINLOG,
2138 ON_CHECK(check_init_string));
2139
2140 static Sys_var_ulong Sys_interactive_timeout(
2141 "interactive_timeout",
2142 "The number of seconds the server waits for activity on an interactive "
2143 "connection before closing it",
2144 SESSION_VAR(net_interactive_timeout), CMD_LINE(REQUIRED_ARG),
2145 VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(NET_WAIT_TIMEOUT), BLOCK_SIZE(1));
2146
2147 static Sys_var_ulong Sys_join_buffer_size(
2148 "join_buffer_size", "The size of the buffer that is used for full joins",
2149 HINT_UPDATEABLE SESSION_VAR(join_buff_size), CMD_LINE(REQUIRED_ARG),
2150 VALID_RANGE(128, ULONG_MAX), DEFAULT(256 * 1024), BLOCK_SIZE(128));
2151
2152 static Sys_var_keycache Sys_key_buffer_size(
2153 "key_buffer_size",
2154 "The size of the buffer used for "
2155 "index blocks for MyISAM tables. Increase this to get better index "
2156 "handling (for all reads and multiple writes) to as much as you can "
2157 "afford",
2158 KEYCACHE_VAR(param_buff_size), CMD_LINE(REQUIRED_ARG, OPT_KEY_BUFFER_SIZE),
2159 VALID_RANGE(0, SIZE_T_MAX), DEFAULT(KEY_CACHE_SIZE), BLOCK_SIZE(IO_SIZE),
2160 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
2161 ON_UPDATE(update_buffer_size));
2162
2163 static Sys_var_keycache Sys_key_cache_block_size(
2164 "key_cache_block_size", "The default size of key cache blocks",
2165 KEYCACHE_VAR(param_block_size),
2166 CMD_LINE(REQUIRED_ARG, OPT_KEY_CACHE_BLOCK_SIZE),
2167 VALID_RANGE(512, 1024 * 16), DEFAULT(KEY_CACHE_BLOCK_SIZE), BLOCK_SIZE(512),
2168 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
2169 ON_UPDATE(update_keycache_param));
2170
2171 static Sys_var_keycache Sys_key_cache_division_limit(
2172 "key_cache_division_limit",
2173 "The minimum percentage of warm blocks in key cache",
2174 KEYCACHE_VAR(param_division_limit),
2175 CMD_LINE(REQUIRED_ARG, OPT_KEY_CACHE_DIVISION_LIMIT), VALID_RANGE(1, 100),
2176 DEFAULT(100), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG,
2177 ON_CHECK(nullptr), ON_UPDATE(update_keycache_param));
2178
2179 static Sys_var_keycache Sys_key_cache_age_threshold(
2180 "key_cache_age_threshold",
2181 "This characterizes the number of "
2182 "hits a hot block has to be untouched until it is considered aged "
2183 "enough to be downgraded to a warm block. This specifies the "
2184 "percentage ratio of that number of hits to the total number of "
2185 "blocks in key cache",
2186 KEYCACHE_VAR(param_age_threshold),
2187 CMD_LINE(REQUIRED_ARG, OPT_KEY_CACHE_AGE_THRESHOLD),
2188 VALID_RANGE(100, ULONG_MAX), DEFAULT(300), BLOCK_SIZE(100), NO_MUTEX_GUARD,
2189 NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(update_keycache_param));
2190
2191 static Sys_var_bool Sys_large_files_support(
2192 "large_files_support",
2193 "Whether mysqld was compiled with options for large file support",
2194 READ_ONLY NON_PERSIST GLOBAL_VAR(opt_large_files), NO_CMD_LINE,
2195 DEFAULT(sizeof(my_off_t) > 4));
2196
2197 static Sys_var_uint Sys_large_page_size(
2198 "large_page_size",
2199 "If large page support is enabled, this shows the size of memory pages",
2200 READ_ONLY NON_PERSIST GLOBAL_VAR(opt_large_page_size), NO_CMD_LINE,
2201 VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1));
2202
2203 static Sys_var_bool Sys_large_pages("large_pages",
2204 "Enable support for large pages",
2205 READ_ONLY GLOBAL_VAR(opt_large_pages),
2206 IF_WIN(NO_CMD_LINE, CMD_LINE(OPT_ARG)),
2207 DEFAULT(false));
2208
2209 static Sys_var_charptr Sys_language(
2210 "lc_messages_dir", "Directory where error messages are",
2211 READ_ONLY NON_PERSIST GLOBAL_VAR(lc_messages_dir_ptr),
2212 CMD_LINE(REQUIRED_ARG, OPT_LC_MESSAGES_DIRECTORY), IN_FS_CHARSET,
2213 DEFAULT(nullptr));
2214
2215 static Sys_var_bool Sys_local_infile("local_infile",
2216 "Enable LOAD DATA LOCAL INFILE",
2217 GLOBAL_VAR(opt_local_infile),
2218 CMD_LINE(OPT_ARG), DEFAULT(false));
2219
2220 static Sys_var_ulong Sys_lock_wait_timeout(
2221 "lock_wait_timeout",
2222 "Timeout in seconds to wait for a lock before returning an error.",
2223 HINT_UPDATEABLE SESSION_VAR(lock_wait_timeout), CMD_LINE(REQUIRED_ARG),
2224 VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(LONG_TIMEOUT), BLOCK_SIZE(1));
2225
2226 #ifdef HAVE_MLOCKALL
2227 static Sys_var_bool Sys_locked_in_memory(
2228 "locked_in_memory", "Whether mysqld was locked in memory with --memlock",
2229 READ_ONLY NON_PERSIST GLOBAL_VAR(locked_in_memory), NO_CMD_LINE,
2230 DEFAULT(false));
2231 #endif
2232
2233 /* this says NO_CMD_LINE, as command-line option takes a string, not a bool */
2234 static Sys_var_bool Sys_log_bin("log_bin", "Whether the binary log is enabled",
2235 READ_ONLY NON_PERSIST GLOBAL_VAR(opt_bin_log),
2236 NO_CMD_LINE, DEFAULT(true));
2237
transaction_write_set_check(sys_var * self,THD * thd,set_var * var)2238 static bool transaction_write_set_check(sys_var *self, THD *thd, set_var *var) {
2239 if (check_session_admin(self, thd, var)) return true;
2240 // Can't change the algorithm when group replication is enabled.
2241 if (is_group_replication_running()) {
2242 my_message(
2243 ER_GROUP_REPLICATION_RUNNING,
2244 "The write set algorithm cannot be changed when Group replication"
2245 " is running.",
2246 MYF(0));
2247 return true;
2248 }
2249
2250 if ((var->is_global_persist()) &&
2251 global_system_variables.binlog_format != BINLOG_FORMAT_ROW) {
2252 my_error(ER_PREVENTS_VARIABLE_WITHOUT_RBR, MYF(0), var->var->name.str);
2253 return true;
2254 }
2255
2256 if (var->type == OPT_SESSION &&
2257 thd->variables.binlog_format != BINLOG_FORMAT_ROW) {
2258 my_error(ER_PREVENTS_VARIABLE_WITHOUT_RBR, MYF(0), var->var->name.str);
2259 return true;
2260 }
2261 /*
2262 if in a stored function/trigger, it's too late to change
2263 */
2264 if (thd->in_sub_stmt) {
2265 my_error(ER_VARIABLE_NOT_SETTABLE_IN_TRANSACTION, MYF(0),
2266 var->var->name.str);
2267 return true;
2268 }
2269 /*
2270 Make the session variable 'transaction_write_set_extraction' read-only
2271 inside a transaction.
2272 */
2273 if (thd->in_active_multi_stmt_transaction()) {
2274 my_error(ER_VARIABLE_NOT_SETTABLE_IN_TRANSACTION, MYF(0),
2275 var->var->name.str);
2276 return true;
2277 }
2278 /*
2279 Disallow changing variable 'transaction_write_set_extraction' while
2280 binlog_transaction_dependency_tracking is different from COMMIT_ORDER.
2281 */
2282 if (mysql_bin_log.m_dependency_tracker.m_opt_tracking_mode !=
2283 DEPENDENCY_TRACKING_COMMIT_ORDER) {
2284 my_error(ER_WRONG_USAGE, MYF(0),
2285 "transaction_write_set_extraction (changed)",
2286 "binlog_transaction_dependency_tracking (!= COMMIT_ORDER)");
2287 return true;
2288 }
2289
2290 return false;
2291 }
2292
2293 static Sys_var_enum Sys_extract_write_set(
2294 "transaction_write_set_extraction",
2295 "This option is used to let the server know when to "
2296 "extract the write set which will be used for various purposes. ",
2297 SESSION_VAR(transaction_write_set_extraction), CMD_LINE(OPT_ARG),
2298 transaction_write_set_hashing_algorithms, DEFAULT(HASH_ALGORITHM_XXHASH64),
2299 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(transaction_write_set_check),
2300 ON_UPDATE(nullptr));
2301
2302 static Sys_var_ulong Sys_rpl_stop_slave_timeout(
2303 "rpl_stop_slave_timeout",
2304 "Timeout in seconds to wait for slave to stop before returning a "
2305 "warning.",
2306 GLOBAL_VAR(rpl_stop_slave_timeout), CMD_LINE(REQUIRED_ARG),
2307 VALID_RANGE(2, LONG_TIMEOUT), DEFAULT(LONG_TIMEOUT), BLOCK_SIZE(1));
2308
2309 static Sys_var_enum Sys_binlog_error_action(
2310 "binlog_error_action",
2311 "When statements cannot be written to the binary log due to a fatal "
2312 "error, the server can either ignore the error and let the master "
2313 "continue, or abort.",
2314 GLOBAL_VAR(binlog_error_action), CMD_LINE(REQUIRED_ARG),
2315 binlog_error_action_list, DEFAULT(ABORT_SERVER));
2316
2317 static Sys_var_bool Sys_trust_function_creators(
2318 "log_bin_trust_function_creators",
2319 "If set to FALSE (the default), then when --log-bin is used, creation "
2320 "of a stored function (or trigger) is allowed only to users having the "
2321 "SUPER privilege and only if this stored function (trigger) may not "
2322 "break binary logging. Note that if ALL connections to this server "
2323 "ALWAYS use row-based binary logging, the security issues do not "
2324 "exist and the binary logging cannot break, so you can safely set "
2325 "this to TRUE",
2326 GLOBAL_VAR(trust_function_creators), CMD_LINE(OPT_ARG), DEFAULT(false));
2327
2328 static Sys_var_bool Sys_check_proxy_users(
2329 "check_proxy_users",
2330 "If set to FALSE (the default), then proxy user identity will not be "
2331 "mapped for authentication plugins which support mapping from grant "
2332 "tables. When set to TRUE, users associated with authentication "
2333 "plugins which signal proxy user mapping should be done according to "
2334 "GRANT PROXY privilege definition.",
2335 GLOBAL_VAR(check_proxy_users), CMD_LINE(OPT_ARG), DEFAULT(false));
2336
2337 static Sys_var_bool Sys_mysql_native_password_proxy_users(
2338 "mysql_native_password_proxy_users",
2339 "If set to FALSE (the default), then the mysql_native_password "
2340 "plugin will not signal for authenticated users to be checked for "
2341 "mapping "
2342 "to proxy users. When set to TRUE, the plugin will flag associated "
2343 "authenticated accounts to be mapped to proxy users when the server "
2344 "option "
2345 "check_proxy_users is enabled.",
2346 GLOBAL_VAR(mysql_native_password_proxy_users), CMD_LINE(OPT_ARG),
2347 DEFAULT(false));
2348
2349 static Sys_var_bool Sys_sha256_password_proxy_users(
2350 "sha256_password_proxy_users",
2351 "If set to FALSE (the default), then the sha256_password authentication "
2352 "plugin will not signal for authenticated users to be checked for "
2353 "mapping "
2354 "to proxy users. When set to TRUE, the plugin will flag associated "
2355 "authenticated accounts to be mapped to proxy users when the server "
2356 "option "
2357 "check_proxy_users is enabled.",
2358 GLOBAL_VAR(sha256_password_proxy_users), CMD_LINE(OPT_ARG), DEFAULT(false));
2359
check_log_bin_use_v1_row_events(sys_var *,THD * thd,set_var * var)2360 static bool check_log_bin_use_v1_row_events(sys_var *, THD *thd, set_var *var) {
2361 if (var->save_result.ulonglong_value == 1 &&
2362 global_system_variables.binlog_row_value_options != 0)
2363 push_warning_printf(thd, Sql_condition::SL_WARNING,
2364 ER_WARN_BINLOG_V1_ROW_EVENTS_DISABLED,
2365 ER_THD(thd, ER_WARN_BINLOG_V1_ROW_EVENTS_DISABLED),
2366 "binlog_row_value_options=PARTIAL_JSON");
2367 return false;
2368 }
2369
2370 static Sys_var_bool Sys_log_bin_use_v1_row_events(
2371 "log_bin_use_v1_row_events",
2372 "If equal to 1 then version 1 row events are written to a row based "
2373 "binary log. If equal to 0, then the latest version of events are "
2374 "written. "
2375 "This option is useful during some upgrades.",
2376 NON_PERSIST GLOBAL_VAR(log_bin_use_v1_row_events),
2377 CMD_LINE(OPT_ARG, OPT_LOG_BIN_USE_V1_ROW_EVENTS), DEFAULT(false),
2378 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_log_bin_use_v1_row_events),
2379 ON_UPDATE(nullptr), DEPRECATED_VAR(""));
2380
2381 static Sys_var_charptr Sys_log_error(
2382 "log_error", "Error log file",
2383 READ_ONLY NON_PERSIST GLOBAL_VAR(log_error_dest),
2384 CMD_LINE(OPT_ARG, OPT_LOG_ERROR), IN_FS_CHARSET,
2385 DEFAULT(disabled_my_option), NO_MUTEX_GUARD, NOT_IN_BINLOG,
2386 ON_CHECK(nullptr), ON_UPDATE(nullptr), nullptr, sys_var::PARSE_EARLY);
2387
check_log_error_services(sys_var * self,THD * thd,set_var * var)2388 static bool check_log_error_services(sys_var *self, THD *thd, set_var *var) {
2389 // test whether syntax is OK and services exist
2390 size_t pos;
2391
2392 if (var->save_result.string_value.str == nullptr) return true;
2393
2394 if (log_builtins_error_stack(var->save_result.string_value.str, true, &pos) <
2395 0) {
2396 push_warning_printf(
2397 thd, Sql_condition::SL_WARNING, ER_CANT_SET_ERROR_LOG_SERVICE,
2398 ER_THD(thd, ER_CANT_SET_ERROR_LOG_SERVICE), self->name.str,
2399 &((char *)var->save_result.string_value.str)[pos]);
2400 return true;
2401 } else if (strlen(var->save_result.string_value.str) < 1) {
2402 push_warning_printf(
2403 thd, Sql_condition::SL_WARNING, ER_EMPTY_PIPELINE_FOR_ERROR_LOG_SERVICE,
2404 ER_THD(thd, ER_EMPTY_PIPELINE_FOR_ERROR_LOG_SERVICE), self->name.str);
2405 }
2406
2407 return false;
2408 }
2409
fix_log_error_services(sys_var * self MY_ATTRIBUTE ((unused)),THD * thd,enum_var_type type MY_ATTRIBUTE ((unused)))2410 static bool fix_log_error_services(sys_var *self MY_ATTRIBUTE((unused)),
2411 THD *thd,
2412 enum_var_type type MY_ATTRIBUTE((unused))) {
2413 // syntax is OK and services exist; try to initialize them!
2414 size_t pos;
2415 if (log_builtins_error_stack(opt_log_error_services, false, &pos) < 0) {
2416 if (pos < strlen(opt_log_error_services)) /* purecov: begin inspected */
2417 push_warning_printf(
2418 thd, Sql_condition::SL_WARNING, ER_CANT_START_ERROR_LOG_SERVICE,
2419 ER_THD(thd, ER_CANT_START_ERROR_LOG_SERVICE), self->name.str,
2420 &((char *)opt_log_error_services)[pos]);
2421 return true; /* purecov: end */
2422 }
2423
2424 return false;
2425 }
2426
2427 static Sys_var_charptr Sys_log_error_services(
2428 "log_error_services",
2429 "Services that should be called when an error event is received",
2430 PERSIST_AS_READONLY GLOBAL_VAR(opt_log_error_services),
2431 CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET,
2432 DEFAULT(LOG_ERROR_SERVICES_DEFAULT), NO_MUTEX_GUARD, NOT_IN_BINLOG,
2433 ON_CHECK(check_log_error_services), ON_UPDATE(fix_log_error_services));
2434
check_log_error_suppression_list(sys_var * self,THD * thd,set_var * var)2435 static bool check_log_error_suppression_list(sys_var *self, THD *thd,
2436 set_var *var) {
2437 int i;
2438
2439 if (var->save_result.string_value.str == nullptr) return true;
2440
2441 if ((i = log_builtins_filter_parse_suppression_list(
2442 var->save_result.string_value.str, false)) < 0) {
2443 push_warning_printf(
2444 thd, Sql_condition::SL_WARNING, ER_CANT_SET_ERROR_SUPPRESSION_LIST,
2445 ER_THD(thd, ER_CANT_SET_ERROR_SUPPRESSION_LIST), self->name.str,
2446 &((char *)var->save_result.string_value.str)[-(i + 1)]);
2447 return true;
2448 }
2449
2450 return false;
2451 }
2452
fix_log_error_suppression_list(sys_var * self MY_ATTRIBUTE ((unused)),THD * thd MY_ATTRIBUTE ((unused)),enum_var_type type MY_ATTRIBUTE ((unused)))2453 static bool fix_log_error_suppression_list(
2454 sys_var *self MY_ATTRIBUTE((unused)), THD *thd MY_ATTRIBUTE((unused)),
2455 enum_var_type type MY_ATTRIBUTE((unused))) {
2456 // syntax is OK and errcodes have messages; try to make filter rules for
2457 // them!
2458 int rr = log_builtins_filter_parse_suppression_list(
2459 opt_log_error_suppression_list, true);
2460 return (rr < 0) ? true : false;
2461 }
2462
2463 static Sys_var_charptr Sys_log_error_suppression_list(
2464 "log_error_suppression_list",
2465 "Comma-separated list of error-codes. Error messages corresponding to "
2466 "these codes will not be included in the error log. Only events with a "
2467 "severity of Warning or Information can be suppressed; events with "
2468 "System "
2469 "or Error severity will always be included. Requires the filter "
2470 "\'log_filter_internal\' to be set in @@global.log_error_services, which "
2471 "is the default.",
2472 PERSIST_AS_READONLY GLOBAL_VAR(opt_log_error_suppression_list),
2473 CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET, DEFAULT(""), NO_MUTEX_GUARD,
2474 NOT_IN_BINLOG, ON_CHECK(check_log_error_suppression_list),
2475 ON_UPDATE(fix_log_error_suppression_list));
2476
2477 static Sys_var_bool Sys_log_queries_not_using_indexes(
2478 "log_queries_not_using_indexes",
2479 "Log queries that are executed without benefit of any index to the "
2480 "slow log if it is open",
2481 GLOBAL_VAR(opt_log_queries_not_using_indexes), CMD_LINE(OPT_ARG),
2482 DEFAULT(false));
2483
2484 static Sys_var_bool Sys_log_slow_admin_statements(
2485 "log_slow_admin_statements",
2486 "Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements "
2487 "to "
2488 "the slow log if it is open.",
2489 GLOBAL_VAR(opt_log_slow_admin_statements), CMD_LINE(OPT_ARG),
2490 DEFAULT(false));
2491
2492 static Sys_var_bool Sys_log_slow_slave_statements(
2493 "log_slow_slave_statements",
2494 "Log slow statements executed by slave thread to the slow log if it is "
2495 "open.",
2496 GLOBAL_VAR(opt_log_slow_slave_statements), CMD_LINE(OPT_ARG),
2497 DEFAULT(false));
2498
update_log_throttle_queries_not_using_indexes(sys_var *,THD * thd,enum_var_type)2499 static bool update_log_throttle_queries_not_using_indexes(sys_var *, THD *thd,
2500 enum_var_type) {
2501 // Check if we should print a summary of any suppressed lines to the slow
2502 // log now since opt_log_throttle_queries_not_using_indexes was changed.
2503 log_throttle_qni.flush(thd);
2504 return false;
2505 }
2506
2507 static Sys_var_ulong Sys_log_throttle_queries_not_using_indexes(
2508 "log_throttle_queries_not_using_indexes",
2509 "Log at most this many 'not using index' warnings per minute to the "
2510 "slow log. Any further warnings will be condensed into a single "
2511 "summary line. A value of 0 disables throttling. "
2512 "Option has no effect unless --log_queries_not_using_indexes is set.",
2513 GLOBAL_VAR(opt_log_throttle_queries_not_using_indexes),
2514 CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, ULONG_MAX), DEFAULT(0),
2515 BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
2516 ON_UPDATE(update_log_throttle_queries_not_using_indexes));
2517
update_log_error_verbosity(sys_var *,THD *,enum_var_type)2518 static bool update_log_error_verbosity(sys_var *, THD *, enum_var_type) {
2519 return (log_builtins_filter_update_verbosity(log_error_verbosity) < 0);
2520 }
2521
2522 static Sys_var_ulong Sys_log_error_verbosity(
2523 "log_error_verbosity",
2524 "How detailed the error log should be. "
2525 "1, log errors only. "
2526 "2, log errors and warnings. "
2527 "3, log errors, warnings, and notes. "
2528 "Messages sent to the client are unaffected by this setting.",
2529 PERSIST_AS_READONLY GLOBAL_VAR(log_error_verbosity), CMD_LINE(REQUIRED_ARG),
2530 VALID_RANGE(1, 3), DEFAULT(2), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG,
2531 ON_CHECK(nullptr), ON_UPDATE(update_log_error_verbosity));
2532
2533 static Sys_var_enum Sys_log_timestamps(
2534 "log_timestamps",
2535 "UTC to timestamp log files in zulu time, for more concise timestamps "
2536 "and easier correlation of logs from servers from multiple time zones, "
2537 "or SYSTEM to use the system's local time. "
2538 "This affects only log files, not log tables, as the timestamp columns "
2539 "of the latter can be converted at will.",
2540 GLOBAL_VAR(opt_log_timestamps), CMD_LINE(REQUIRED_ARG),
2541 timestamp_type_names, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG);
2542
2543 static Sys_var_bool Sys_log_statements_unsafe_for_binlog(
2544 "log_statements_unsafe_for_binlog",
2545 "Log statements considered unsafe when using statement based binary "
2546 "logging.",
2547 GLOBAL_VAR(opt_log_unsafe_statements), CMD_LINE(OPT_ARG), DEFAULT(true));
2548
update_cached_long_query_time(sys_var *,THD * thd,enum_var_type type)2549 static bool update_cached_long_query_time(sys_var *, THD *thd,
2550 enum_var_type type) {
2551 if (type == OPT_SESSION)
2552 thd->variables.long_query_time =
2553 double2ulonglong(thd->variables.long_query_time_double * 1e6);
2554 else
2555 global_system_variables.long_query_time =
2556 double2ulonglong(global_system_variables.long_query_time_double * 1e6);
2557 return false;
2558 }
2559
2560 static Sys_var_double Sys_long_query_time(
2561 "long_query_time",
2562 "Log all queries that have taken more than long_query_time seconds "
2563 "to execute to file. The argument will be treated as a decimal value "
2564 "with microsecond precision",
2565 SESSION_VAR(long_query_time_double), CMD_LINE(REQUIRED_ARG),
2566 VALID_RANGE(0, LONG_TIMEOUT), DEFAULT(10), NO_MUTEX_GUARD, NOT_IN_BINLOG,
2567 ON_CHECK(nullptr), ON_UPDATE(update_cached_long_query_time));
2568
fix_low_prio_updates(sys_var *,THD * thd,enum_var_type type)2569 static bool fix_low_prio_updates(sys_var *, THD *thd, enum_var_type type) {
2570 if (type == OPT_SESSION) {
2571 thd->update_lock_default =
2572 (thd->variables.low_priority_updates ? TL_WRITE_LOW_PRIORITY
2573 : TL_WRITE);
2574 thd->insert_lock_default =
2575 (thd->variables.low_priority_updates ? TL_WRITE_LOW_PRIORITY
2576 : TL_WRITE_CONCURRENT_INSERT);
2577 } else
2578 thr_upgraded_concurrent_insert_lock =
2579 (global_system_variables.low_priority_updates ? TL_WRITE_LOW_PRIORITY
2580 : TL_WRITE);
2581 return false;
2582 }
2583 static Sys_var_bool Sys_low_priority_updates(
2584 "low_priority_updates",
2585 "INSERT/DELETE/UPDATE has lower priority than selects",
2586 SESSION_VAR(low_priority_updates), CMD_LINE(OPT_ARG), DEFAULT(false),
2587 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
2588 ON_UPDATE(fix_low_prio_updates));
2589
2590 static Sys_var_bool Sys_lower_case_file_system(
2591 "lower_case_file_system",
2592 "Case sensitivity of file names on the file system where the "
2593 "data directory is located",
2594 READ_ONLY NON_PERSIST GLOBAL_VAR(lower_case_file_system), NO_CMD_LINE,
2595 DEFAULT(false));
2596
2597 static Sys_var_uint Sys_lower_case_table_names(
2598 "lower_case_table_names",
2599 "If set to 1 table names are stored in lowercase on disk and table "
2600 "names will be case-insensitive. Should be set to 2 if you are using "
2601 "a case insensitive file system",
2602 READ_ONLY GLOBAL_VAR(lower_case_table_names),
2603 CMD_LINE(OPT_ARG, OPT_LOWER_CASE_TABLE_NAMES), VALID_RANGE(0, 2),
2604 #ifdef FN_NO_CASE_SENSE
2605 DEFAULT(1),
2606 #else
2607 DEFAULT(0),
2608 #endif
2609 BLOCK_SIZE(1));
2610
session_readonly(sys_var * self,THD *,set_var * var)2611 static bool session_readonly(sys_var *self, THD *, set_var *var) {
2612 if (var->is_global_persist()) return false;
2613 my_error(ER_VARIABLE_IS_READONLY, MYF(0), "SESSION", self->name.str,
2614 "GLOBAL");
2615 return true;
2616 }
2617
check_max_allowed_packet(sys_var * self,THD * thd,set_var * var)2618 static bool check_max_allowed_packet(sys_var *self, THD *thd, set_var *var) {
2619 longlong val;
2620 if (session_readonly(self, thd, var)) return true;
2621
2622 val = var->save_result.ulonglong_value;
2623 if (val < (longlong)global_system_variables.net_buffer_length) {
2624 push_warning_printf(thd, Sql_condition::SL_WARNING, WARN_OPTION_BELOW_LIMIT,
2625 ER_THD(thd, WARN_OPTION_BELOW_LIMIT),
2626 "max_allowed_packet", "net_buffer_length");
2627 }
2628 return false;
2629 }
2630
2631 static Sys_var_ulong Sys_max_allowed_packet(
2632 "max_allowed_packet",
2633 "Max packet length to send to or receive from the server",
2634 SESSION_VAR(max_allowed_packet), CMD_LINE(REQUIRED_ARG),
2635 VALID_RANGE(1024, 1024 * 1024 * 1024), DEFAULT(64 * 1024 * 1024),
2636 BLOCK_SIZE(1024), NO_MUTEX_GUARD, NOT_IN_BINLOG,
2637 ON_CHECK(check_max_allowed_packet));
2638
2639 static Sys_var_ulong Sys_slave_max_allowed_packet(
2640 "slave_max_allowed_packet",
2641 "The maximum packet length to sent successfully from the master to "
2642 "slave.",
2643 GLOBAL_VAR(slave_max_allowed_packet), CMD_LINE(REQUIRED_ARG),
2644 VALID_RANGE(1024, MAX_MAX_ALLOWED_PACKET), DEFAULT(MAX_MAX_ALLOWED_PACKET),
2645 BLOCK_SIZE(1024));
2646
2647 static Sys_var_ulonglong Sys_max_binlog_cache_size(
2648 "max_binlog_cache_size", "Sets the total size of the transactional cache",
2649 GLOBAL_VAR(max_binlog_cache_size), CMD_LINE(REQUIRED_ARG),
2650 VALID_RANGE(IO_SIZE, ULLONG_MAX), DEFAULT((ULLONG_MAX / IO_SIZE) * IO_SIZE),
2651 BLOCK_SIZE(IO_SIZE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
2652 ON_UPDATE(fix_binlog_cache_size));
2653
2654 static Sys_var_ulonglong Sys_max_binlog_stmt_cache_size(
2655 "max_binlog_stmt_cache_size", "Sets the total size of the statement cache",
2656 GLOBAL_VAR(max_binlog_stmt_cache_size), CMD_LINE(REQUIRED_ARG),
2657 VALID_RANGE(IO_SIZE, ULLONG_MAX), DEFAULT((ULLONG_MAX / IO_SIZE) * IO_SIZE),
2658 BLOCK_SIZE(IO_SIZE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
2659 ON_UPDATE(fix_binlog_stmt_cache_size));
2660
fix_max_binlog_size(sys_var *,THD *,enum_var_type)2661 static bool fix_max_binlog_size(sys_var *, THD *, enum_var_type) {
2662 mysql_bin_log.set_max_size(max_binlog_size);
2663 /*
2664 For multisource replication, this max size is set to all relay logs
2665 per channel. So, run through them
2666 */
2667 if (!max_relay_log_size) {
2668 Master_info *mi = nullptr;
2669
2670 channel_map.wrlock();
2671 for (mi_map::iterator it = channel_map.begin(); it != channel_map.end();
2672 it++) {
2673 mi = it->second;
2674 if (mi != nullptr) mi->rli->relay_log.set_max_size(max_binlog_size);
2675 }
2676 channel_map.unlock();
2677 }
2678 return false;
2679 }
2680 static Sys_var_ulong Sys_max_binlog_size(
2681 "max_binlog_size",
2682 "Binary log will be rotated automatically when the size exceeds this "
2683 "value. Will also apply to relay logs if max_relay_log_size is 0",
2684 GLOBAL_VAR(max_binlog_size), CMD_LINE(REQUIRED_ARG),
2685 VALID_RANGE(IO_SIZE, 1024 * 1024L * 1024L), DEFAULT(1024 * 1024L * 1024L),
2686 BLOCK_SIZE(IO_SIZE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
2687 ON_UPDATE(fix_max_binlog_size));
2688
2689 static Sys_var_ulong Sys_max_connections(
2690 "max_connections", "The number of simultaneous clients allowed",
2691 GLOBAL_VAR(max_connections), CMD_LINE(REQUIRED_ARG), VALID_RANGE(1, 100000),
2692 DEFAULT(MAX_CONNECTIONS_DEFAULT), BLOCK_SIZE(1), NO_MUTEX_GUARD,
2693 NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr), nullptr,
2694 /* max_connections is used as a sizing hint by the performance schema. */
2695 sys_var::PARSE_EARLY);
2696
2697 static Sys_var_ulong Sys_max_connect_errors(
2698 "max_connect_errors",
2699 "If there is more than this number of interrupted connections from "
2700 "a host this host will be blocked from further connections",
2701 GLOBAL_VAR(max_connect_errors), CMD_LINE(REQUIRED_ARG),
2702 VALID_RANGE(1, ULONG_MAX), DEFAULT(100), BLOCK_SIZE(1));
2703
2704 static Sys_var_long Sys_max_digest_length(
2705 "max_digest_length", "Maximum length considered for digest text.",
2706 READ_ONLY GLOBAL_VAR(max_digest_length), CMD_LINE(REQUIRED_ARG),
2707 VALID_RANGE(0, 1024 * 1024), DEFAULT(1024), BLOCK_SIZE(1));
2708
check_max_delayed_threads(sys_var *,THD *,set_var * var)2709 static bool check_max_delayed_threads(sys_var *, THD *, set_var *var) {
2710 return (!var->is_global_persist()) && var->save_result.ulonglong_value != 0 &&
2711 var->save_result.ulonglong_value !=
2712 global_system_variables.max_insert_delayed_threads;
2713 }
2714
2715 // Alias for max_delayed_threads
2716 static Sys_var_ulong Sys_max_insert_delayed_threads(
2717 "max_insert_delayed_threads",
2718 "Don't start more than this number of threads to handle INSERT "
2719 "DELAYED statements. If set to zero INSERT DELAYED will be not used. "
2720 "This variable is deprecated along with INSERT DELAYED.",
2721 SESSION_VAR(max_insert_delayed_threads), NO_CMD_LINE, VALID_RANGE(0, 16384),
2722 DEFAULT(20), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG,
2723 ON_CHECK(check_max_delayed_threads), ON_UPDATE(nullptr),
2724 DEPRECATED_VAR(""));
2725
2726 static Sys_var_ulong Sys_max_delayed_threads(
2727 "max_delayed_threads",
2728 "Don't start more than this number of threads to handle INSERT "
2729 "DELAYED statements. If set to zero INSERT DELAYED will be not used. "
2730 "This variable is deprecated along with INSERT DELAYED.",
2731 SESSION_VAR(max_insert_delayed_threads), CMD_LINE(REQUIRED_ARG),
2732 VALID_RANGE(0, 16384), DEFAULT(20), BLOCK_SIZE(1), NO_MUTEX_GUARD,
2733 NOT_IN_BINLOG, ON_CHECK(check_max_delayed_threads), ON_UPDATE(nullptr),
2734 DEPRECATED_VAR(""));
2735
2736 static Sys_var_ulong Sys_max_error_count(
2737 "max_error_count", "Max number of errors/warnings to store for a statement",
2738 HINT_UPDATEABLE SESSION_VAR(max_error_count), CMD_LINE(REQUIRED_ARG),
2739 VALID_RANGE(0, 65535), DEFAULT(DEFAULT_ERROR_COUNT), BLOCK_SIZE(1));
2740
2741 static Sys_var_ulonglong Sys_max_heap_table_size(
2742 "max_heap_table_size",
2743 "Don't allow creation of heap tables bigger than this",
2744 HINT_UPDATEABLE SESSION_VAR(max_heap_table_size), CMD_LINE(REQUIRED_ARG),
2745 VALID_RANGE(16384, (ulonglong) ~(intptr)0), DEFAULT(16 * 1024 * 1024),
2746 BLOCK_SIZE(1024));
2747
2748 // relies on DBUG_ASSERT(sizeof(my_thread_id) == 4);
2749 static Sys_var_uint Sys_pseudo_thread_id(
2750 "pseudo_thread_id", "This variable is for internal server use",
2751 SESSION_ONLY(pseudo_thread_id), NO_CMD_LINE, VALID_RANGE(0, UINT_MAX32),
2752 DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD, IN_BINLOG,
2753 ON_CHECK(check_session_admin));
2754
fix_max_join_size(sys_var * self,THD * thd,enum_var_type type)2755 static bool fix_max_join_size(sys_var *self, THD *thd, enum_var_type type) {
2756 System_variables *sv = (self->is_global_persist(type))
2757 ? &global_system_variables
2758 : &thd->variables;
2759 if (sv->max_join_size == HA_POS_ERROR)
2760 sv->option_bits |= OPTION_BIG_SELECTS;
2761 else
2762 sv->option_bits &= ~OPTION_BIG_SELECTS;
2763 return false;
2764 }
2765 static Sys_var_harows Sys_max_join_size(
2766 "max_join_size",
2767 "Joins that are probably going to read more than max_join_size "
2768 "records return an error",
2769 HINT_UPDATEABLE SESSION_VAR(max_join_size), CMD_LINE(REQUIRED_ARG),
2770 VALID_RANGE(1, HA_POS_ERROR), DEFAULT(HA_POS_ERROR), BLOCK_SIZE(1),
2771 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
2772 ON_UPDATE(fix_max_join_size));
2773
2774 static Sys_var_ulong Sys_max_seeks_for_key(
2775 "max_seeks_for_key",
2776 "Limit assumed max number of seeks when looking up rows based on a key",
2777 HINT_UPDATEABLE SESSION_VAR(max_seeks_for_key), CMD_LINE(REQUIRED_ARG),
2778 VALID_RANGE(1, ULONG_MAX), DEFAULT(ULONG_MAX), BLOCK_SIZE(1));
2779
2780 static Sys_var_ulong Sys_max_length_for_sort_data(
2781 "max_length_for_sort_data",
2782 "This variable is deprecated and will be removed in a future release.",
2783 HINT_UPDATEABLE SESSION_VAR(max_length_for_sort_data),
2784 CMD_LINE(REQUIRED_ARG), VALID_RANGE(4, 8192 * 1024L), DEFAULT(4096),
2785 BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
2786 ON_UPDATE(nullptr), DEPRECATED_VAR(""));
2787
2788 static Sys_var_ulong Sys_max_points_in_geometry(
2789 "max_points_in_geometry", "Maximum number of points in a geometry",
2790 HINT_UPDATEABLE SESSION_VAR(max_points_in_geometry), CMD_LINE(OPT_ARG),
2791 VALID_RANGE(3, 1024 * 1024L), DEFAULT(64 * 1024), BLOCK_SIZE(1));
2792
2793 static PolyLock_mutex PLock_prepared_stmt_count(&LOCK_prepared_stmt_count);
2794
2795 static Sys_var_ulong Sys_max_prepared_stmt_count(
2796 "max_prepared_stmt_count",
2797 "Maximum number of prepared statements in the server",
2798 GLOBAL_VAR(max_prepared_stmt_count), CMD_LINE(REQUIRED_ARG),
2799 VALID_RANGE(0, num_prepared_stmt_limit), DEFAULT(16382), BLOCK_SIZE(1),
2800 &PLock_prepared_stmt_count, NOT_IN_BINLOG, ON_CHECK(nullptr),
2801 ON_UPDATE(nullptr), nullptr,
2802 /* max_prepared_stmt_count is used as a sizing hint by the performance
2803 schema. */
2804 sys_var::PARSE_EARLY);
2805
fix_max_relay_log_size(sys_var *,THD *,enum_var_type)2806 static bool fix_max_relay_log_size(sys_var *, THD *, enum_var_type) {
2807 Master_info *mi = nullptr;
2808
2809 channel_map.wrlock();
2810 for (mi_map::iterator it = channel_map.begin(); it != channel_map.end();
2811 it++) {
2812 mi = it->second;
2813
2814 if (mi != nullptr)
2815 mi->rli->relay_log.set_max_size(max_relay_log_size ? max_relay_log_size
2816 : max_binlog_size);
2817 }
2818 channel_map.unlock();
2819 return false;
2820 }
2821 static Sys_var_ulong Sys_max_relay_log_size(
2822 "max_relay_log_size",
2823 "If non-zero: relay log will be rotated automatically when the "
2824 "size exceeds this value; if zero: when the size "
2825 "exceeds max_binlog_size",
2826 GLOBAL_VAR(max_relay_log_size), CMD_LINE(REQUIRED_ARG),
2827 VALID_RANGE(0, 1024L * 1024 * 1024), DEFAULT(0), BLOCK_SIZE(IO_SIZE),
2828 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
2829 ON_UPDATE(fix_max_relay_log_size));
2830
2831 static Sys_var_ulong Sys_max_sort_length(
2832 "max_sort_length",
2833 "The number of bytes to use when sorting long values with PAD SPACE "
2834 "collations (only the first max_sort_length bytes of each value are "
2835 "used; the rest are ignored)",
2836 HINT_UPDATEABLE SESSION_VAR(max_sort_length), CMD_LINE(REQUIRED_ARG),
2837 VALID_RANGE(4, 8192 * 1024L), DEFAULT(1024), BLOCK_SIZE(1));
2838
2839 static Sys_var_ulong Sys_max_sp_recursion_depth(
2840 "max_sp_recursion_depth", "Maximum stored procedure recursion depth",
2841 SESSION_VAR(max_sp_recursion_depth), CMD_LINE(OPT_ARG), VALID_RANGE(0, 255),
2842 DEFAULT(0), BLOCK_SIZE(1));
2843
2844 // non-standard session_value_ptr() here
2845 static Sys_var_max_user_conn Sys_max_user_connections(
2846 "max_user_connections",
2847 "The maximum number of active connections for a single user "
2848 "(0 = no limit)",
2849 SESSION_VAR(max_user_connections), CMD_LINE(REQUIRED_ARG),
2850 VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD,
2851 NOT_IN_BINLOG, ON_CHECK(session_readonly));
2852
2853 static Sys_var_ulong Sys_max_write_lock_count(
2854 "max_write_lock_count",
2855 "After this many write locks, allow some read locks to run in between",
2856 GLOBAL_VAR(max_write_lock_count), CMD_LINE(REQUIRED_ARG),
2857 VALID_RANGE(1, ULONG_MAX), DEFAULT(ULONG_MAX), BLOCK_SIZE(1));
2858
2859 static Sys_var_ulong Sys_min_examined_row_limit(
2860 "min_examined_row_limit",
2861 "Don't write queries to slow log that examine fewer rows "
2862 "than that",
2863 SESSION_VAR(min_examined_row_limit), CMD_LINE(REQUIRED_ARG),
2864 VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1));
2865
2866 #ifdef _WIN32
2867 static Sys_var_bool Sys_named_pipe("named_pipe", "Enable the named pipe (NT)",
2868 READ_ONLY NON_PERSIST
2869 GLOBAL_VAR(opt_enable_named_pipe),
2870 CMD_LINE(OPT_ARG), DEFAULT(false));
2871
2872 static PolyLock_rwlock PLock_named_pipe_full_access_group(
2873 &LOCK_named_pipe_full_access_group);
check_named_pipe_full_access_group(sys_var * self,THD * thd,set_var * var)2874 static bool check_named_pipe_full_access_group(sys_var *self, THD *thd,
2875 set_var *var) {
2876 if (!var->value) return false; // DEFAULT is ok
2877
2878 if (!is_valid_named_pipe_full_access_group(
2879 var->save_result.string_value.str)) {
2880 my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), self->name.str,
2881 var->save_result.string_value.str);
2882 return true;
2883 }
2884 return false;
2885 }
fix_named_pipe_full_access_group(sys_var *,THD *,enum_var_type)2886 static bool fix_named_pipe_full_access_group(sys_var *, THD *, enum_var_type) {
2887 return update_named_pipe_full_access_group(named_pipe_full_access_group);
2888 }
2889 static Sys_var_charptr Sys_named_pipe_full_access_group(
2890 "named_pipe_full_access_group",
2891 "Name of Windows group granted full access to the named pipe",
2892 GLOBAL_VAR(named_pipe_full_access_group),
2893 CMD_LINE(REQUIRED_ARG, OPT_NAMED_PIPE_FULL_ACCESS_GROUP), IN_FS_CHARSET,
2894 DEFAULT(DEFAULT_NAMED_PIPE_FULL_ACCESS_GROUP),
2895 &PLock_named_pipe_full_access_group, NOT_IN_BINLOG,
2896 ON_CHECK(check_named_pipe_full_access_group),
2897 ON_UPDATE(fix_named_pipe_full_access_group));
2898 #endif
2899
check_net_buffer_length(sys_var * self,THD * thd,set_var * var)2900 static bool check_net_buffer_length(sys_var *self, THD *thd, set_var *var) {
2901 longlong val;
2902 if (session_readonly(self, thd, var)) return true;
2903
2904 val = var->save_result.ulonglong_value;
2905 if (val > (longlong)global_system_variables.max_allowed_packet) {
2906 push_warning_printf(thd, Sql_condition::SL_WARNING, WARN_OPTION_BELOW_LIMIT,
2907 ER_THD(thd, WARN_OPTION_BELOW_LIMIT),
2908 "max_allowed_packet", "net_buffer_length");
2909 }
2910 return false;
2911 }
2912 static Sys_var_ulong Sys_net_buffer_length(
2913 "net_buffer_length", "Buffer length for TCP/IP and socket communication",
2914 SESSION_VAR(net_buffer_length), CMD_LINE(REQUIRED_ARG),
2915 VALID_RANGE(1024, 1024 * 1024), DEFAULT(16384), BLOCK_SIZE(1024),
2916 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_net_buffer_length));
2917
fix_net_read_timeout(sys_var * self,THD * thd,enum_var_type type)2918 static bool fix_net_read_timeout(sys_var *self, THD *thd, enum_var_type type) {
2919 if (!self->is_global_persist(type)) {
2920 // net_buffer_length is a specific property for the classic protocols
2921 if (!thd->is_classic_protocol()) {
2922 my_error(ER_PLUGGABLE_PROTOCOL_COMMAND_NOT_SUPPORTED, MYF(0));
2923 return true;
2924 }
2925 my_net_set_read_timeout(thd->get_protocol_classic()->get_net(),
2926 thd->variables.net_read_timeout);
2927 }
2928 return false;
2929 }
2930 static Sys_var_ulong Sys_net_read_timeout(
2931 "net_read_timeout",
2932 "Number of seconds to wait for more data from a connection before "
2933 "aborting the read",
2934 SESSION_VAR(net_read_timeout), CMD_LINE(REQUIRED_ARG),
2935 VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(NET_READ_TIMEOUT), BLOCK_SIZE(1),
2936 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
2937 ON_UPDATE(fix_net_read_timeout));
2938
fix_net_write_timeout(sys_var * self,THD * thd,enum_var_type type)2939 static bool fix_net_write_timeout(sys_var *self, THD *thd, enum_var_type type) {
2940 if (!self->is_global_persist(type)) {
2941 // net_read_timeout is a specific property for the classic protocols
2942 if (!thd->is_classic_protocol()) {
2943 my_error(ER_PLUGGABLE_PROTOCOL_COMMAND_NOT_SUPPORTED, MYF(0));
2944 return true;
2945 }
2946 my_net_set_write_timeout(thd->get_protocol_classic()->get_net(),
2947 thd->variables.net_write_timeout);
2948 }
2949 return false;
2950 }
2951 static Sys_var_ulong Sys_net_write_timeout(
2952 "net_write_timeout",
2953 "Number of seconds to wait for a block to be written to a connection "
2954 "before aborting the write",
2955 SESSION_VAR(net_write_timeout), CMD_LINE(REQUIRED_ARG),
2956 VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(NET_WRITE_TIMEOUT), BLOCK_SIZE(1),
2957 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
2958 ON_UPDATE(fix_net_write_timeout));
2959
fix_net_retry_count(sys_var * self,THD * thd,enum_var_type type)2960 static bool fix_net_retry_count(sys_var *self, THD *thd, enum_var_type type) {
2961 if (!self->is_global_persist(type)) {
2962 // net_write_timeout is a specific property for the classic protocols
2963 if (!thd->is_classic_protocol()) {
2964 my_error(ER_PLUGGABLE_PROTOCOL_COMMAND_NOT_SUPPORTED, MYF(0));
2965 return true;
2966 }
2967 thd->get_protocol_classic()->get_net()->retry_count =
2968 thd->variables.net_retry_count;
2969 }
2970 return false;
2971 }
2972 static Sys_var_ulong Sys_net_retry_count(
2973 "net_retry_count",
2974 "If a read on a communication port is interrupted, retry this "
2975 "many times before giving up",
2976 SESSION_VAR(net_retry_count), CMD_LINE(REQUIRED_ARG),
2977 VALID_RANGE(1, ULONG_MAX), DEFAULT(MYSQLD_NET_RETRY_COUNT), BLOCK_SIZE(1),
2978 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
2979 ON_UPDATE(fix_net_retry_count));
2980
2981 static Sys_var_bool Sys_new_mode("new",
2982 "Use very new possible \"unsafe\" functions",
2983 SESSION_VAR(new_mode), CMD_LINE(OPT_ARG, 'n'),
2984 DEFAULT(false));
2985
2986 static Sys_var_bool Sys_old_mode("old", "Use compatible behavior",
2987 READ_ONLY GLOBAL_VAR(old_mode),
2988 CMD_LINE(OPT_ARG), DEFAULT(false));
2989
2990 static Sys_var_bool Sys_old_alter_table("old_alter_table",
2991 "Use old, non-optimized alter table",
2992 SESSION_VAR(old_alter_table),
2993 CMD_LINE(OPT_ARG), DEFAULT(false));
2994
2995 static Sys_var_ulong Sys_open_files_limit(
2996 "open_files_limit",
2997 "If this is not 0, then mysqld will use this value to reserve file "
2998 "descriptors to use with setrlimit(). If this value is 0 then mysqld "
2999 "will reserve max_connections*5 or max_connections + table_open_cache*2 "
3000 "(whichever is larger) number of file descriptors",
3001 READ_ONLY GLOBAL_VAR(open_files_limit), CMD_LINE(REQUIRED_ARG),
3002 VALID_RANGE(0, OS_FILE_LIMIT), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD,
3003 NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr), nullptr,
3004 /* open_files_limit is used as a sizing hint by the performance schema. */
3005 sys_var::PARSE_EARLY);
3006
3007 /// @todo change to enum
3008 static Sys_var_ulong Sys_optimizer_prune_level(
3009 "optimizer_prune_level",
3010 "Controls the heuristic(s) applied during query optimization to prune "
3011 "less-promising partial plans from the optimizer search space. "
3012 "Meaning: 0 - do not apply any heuristic, thus perform exhaustive "
3013 "search; 1 - prune plans based on number of retrieved rows",
3014 HINT_UPDATEABLE SESSION_VAR(optimizer_prune_level), CMD_LINE(REQUIRED_ARG),
3015 VALID_RANGE(0, 1), DEFAULT(1), BLOCK_SIZE(1));
3016
3017 static Sys_var_ulong Sys_optimizer_search_depth(
3018 "optimizer_search_depth",
3019 "Maximum depth of search performed by the query optimizer. Values "
3020 "larger than the number of relations in a query result in better "
3021 "query plans, but take longer to compile a query. Values smaller "
3022 "than the number of tables in a relation result in faster "
3023 "optimization, but may produce very bad query plans. If set to 0, "
3024 "the system will automatically pick a reasonable value",
3025 HINT_UPDATEABLE SESSION_VAR(optimizer_search_depth), CMD_LINE(REQUIRED_ARG),
3026 VALID_RANGE(0, MAX_TABLES + 1), DEFAULT(MAX_TABLES + 1), BLOCK_SIZE(1));
3027
3028 static Sys_var_ulong Sys_range_optimizer_max_mem_size(
3029 "range_optimizer_max_mem_size",
3030 "Maximum amount of memory used by the range optimizer "
3031 "to allocate predicates during range analysis. "
3032 "The larger the number, more memory may be consumed during "
3033 "range analysis. If the value is too low to completed range "
3034 "optimization of a query, index range scan will not be "
3035 "considered for this query. A value of 0 means range optimizer "
3036 "does not have any cap on memory. ",
3037 HINT_UPDATEABLE SESSION_VAR(range_optimizer_max_mem_size),
3038 CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, ULONG_MAX), DEFAULT(8388608),
3039 BLOCK_SIZE(1));
3040
limit_parser_max_mem_size(sys_var *,THD * thd,set_var * var)3041 static bool limit_parser_max_mem_size(sys_var *, THD *thd, set_var *var) {
3042 if (var->is_global_persist()) return false;
3043 ulonglong val = var->save_result.ulonglong_value;
3044 if (val > global_system_variables.parser_max_mem_size) {
3045 if (thd->security_context()->check_access(SUPER_ACL)) return false;
3046 var->save_result.ulonglong_value =
3047 global_system_variables.parser_max_mem_size;
3048 return throw_bounds_warning(thd, "parser_max_mem_size",
3049 true, // fixed
3050 true, // is_unsigned
3051 val);
3052 }
3053 return false;
3054 }
3055
3056 constexpr size_t max_mem_sz = std::numeric_limits<size_t>::max();
3057
3058 static Sys_var_ulonglong Sys_histogram_generation_max_mem_size(
3059 "histogram_generation_max_mem_size",
3060 "Maximum amount of memory available for generating histograms",
3061 SESSION_VAR(histogram_generation_max_mem_size), CMD_LINE(REQUIRED_ARG),
3062 VALID_RANGE(1000000, max_mem_sz), DEFAULT(20000000), BLOCK_SIZE(1),
3063 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_session_admin),
3064 ON_UPDATE(nullptr));
3065
3066 /*
3067 Need at least 400Kb to get through bootstrap.
3068 Need at least 8Mb to get through mtr check testcase, which does
3069 SELECT * FROM INFORMATION_SCHEMA.VIEWS
3070 */
3071 static Sys_var_ulonglong Sys_parser_max_mem_size(
3072 "parser_max_mem_size", "Maximum amount of memory available to the parser",
3073 SESSION_VAR(parser_max_mem_size), CMD_LINE(REQUIRED_ARG),
3074 VALID_RANGE(10 * 1000 * 1000, max_mem_sz), DEFAULT(max_mem_sz),
3075 BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG,
3076 ON_CHECK(limit_parser_max_mem_size), ON_UPDATE(nullptr));
3077
3078 /*
3079 There is no call on Sys_var_integer::do_check() for 'set xxx=default';
3080 The predefined default for parser_max_mem_size is "infinite".
3081 Update it in case we have seen option maximum-parser-max-mem-size
3082 Also update global_system_variables, so 'SELECT parser_max_mem_size'
3083 reports correct data.
3084 */
update_parser_max_mem_size()3085 export void update_parser_max_mem_size() {
3086 const ulonglong max_max = max_system_variables.parser_max_mem_size;
3087 if (max_max == max_mem_sz) return;
3088 // In case parser-max-mem-size is also set:
3089 const ulonglong new_val =
3090 std::min(max_max, global_system_variables.parser_max_mem_size);
3091 Sys_parser_max_mem_size.update_default(new_val);
3092 global_system_variables.parser_max_mem_size = new_val;
3093 }
3094
3095 /**
3096 @note
3097 @b BEWARE! These must have the same order as the \#defines in sql_const.h!
3098 */
3099 static const char *optimizer_switch_names[] = {
3100 "index_merge",
3101 "index_merge_union",
3102 "index_merge_sort_union",
3103 "index_merge_intersection",
3104 "engine_condition_pushdown",
3105 "index_condition_pushdown",
3106 "mrr",
3107 "mrr_cost_based",
3108 "block_nested_loop",
3109 "batched_key_access",
3110 "materialization",
3111 "semijoin",
3112 "loosescan",
3113 "firstmatch",
3114 "duplicateweedout",
3115 "subquery_materialization_cost_based",
3116 "use_index_extensions",
3117 "condition_fanout_filter",
3118 "derived_merge",
3119 "use_invisible_indexes",
3120 "skip_scan",
3121 "hash_join",
3122 "subquery_to_derived",
3123 "prefer_ordering_index",
3124 "default",
3125 NullS};
3126 static Sys_var_flagset Sys_optimizer_switch(
3127 "optimizer_switch",
3128 "optimizer_switch=option=val[,option=val...], where option is one of "
3129 "{index_merge, index_merge_union, index_merge_sort_union, "
3130 "index_merge_intersection, engine_condition_pushdown, "
3131 "index_condition_pushdown, mrr, mrr_cost_based"
3132 ", materialization, semijoin, loosescan, firstmatch, duplicateweedout,"
3133 " subquery_materialization_cost_based, skip_scan,"
3134 " block_nested_loop, batched_key_access, use_index_extensions,"
3135 " condition_fanout_filter, derived_merge, hash_join,"
3136 " subquery_to_derived, prefer_ordering_index} and val is one of "
3137 "{on, off, default}",
3138 HINT_UPDATEABLE SESSION_VAR(optimizer_switch), CMD_LINE(REQUIRED_ARG),
3139 optimizer_switch_names, DEFAULT(OPTIMIZER_SWITCH_DEFAULT), NO_MUTEX_GUARD,
3140 NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr));
3141
3142 static Sys_var_bool Sys_var_end_markers_in_json(
3143 "end_markers_in_json",
3144 "In JSON output (\"EXPLAIN FORMAT=JSON\" and optimizer trace), "
3145 "if variable is set to 1, repeats the structure's key (if it has one) "
3146 "near the closing bracket",
3147 HINT_UPDATEABLE SESSION_VAR(end_markers_in_json), CMD_LINE(OPT_ARG),
3148 DEFAULT(false));
3149
3150 static Sys_var_flagset Sys_optimizer_trace(
3151 "optimizer_trace",
3152 "Controls tracing of the Optimizer:"
3153 " optimizer_trace=option=val[,option=val...], where option is one of"
3154 " {enabled, one_line}"
3155 " and val is one of {on, default}",
3156 SESSION_VAR(optimizer_trace), CMD_LINE(REQUIRED_ARG),
3157 Opt_trace_context::flag_names, DEFAULT(Opt_trace_context::FLAG_DEFAULT));
3158 // @see set_var::is_var_optimizer_trace()
3159 export sys_var *Sys_optimizer_trace_ptr = &Sys_optimizer_trace;
3160
3161 /**
3162 Note how "misc" is not here: it is not accessible to the user; disabling
3163 "misc" would disable the top object, which would make an empty trace.
3164 */
3165 static Sys_var_flagset Sys_optimizer_trace_features(
3166 "optimizer_trace_features",
3167 "Enables/disables tracing of selected features of the Optimizer:"
3168 " optimizer_trace_features=option=val[,option=val...], where option is "
3169 "one "
3170 "of"
3171 " {greedy_search, range_optimizer, dynamic_range, repeated_subselect}"
3172 " and val is one of {on, off, default}",
3173 SESSION_VAR(optimizer_trace_features), CMD_LINE(REQUIRED_ARG),
3174 Opt_trace_context::feature_names,
3175 DEFAULT(Opt_trace_context::default_features));
3176
3177 /** Delete all old optimizer traces */
optimizer_trace_update(sys_var *,THD * thd,enum_var_type)3178 static bool optimizer_trace_update(sys_var *, THD *thd, enum_var_type) {
3179 thd->opt_trace.reset();
3180 return false;
3181 }
3182
3183 static Sys_var_long Sys_optimizer_trace_offset(
3184 "optimizer_trace_offset",
3185 "Offset of first optimizer trace to show; see manual",
3186 SESSION_VAR(optimizer_trace_offset), CMD_LINE(REQUIRED_ARG),
3187 VALID_RANGE(LONG_MIN, LONG_MAX), DEFAULT(-1), BLOCK_SIZE(1), NO_MUTEX_GUARD,
3188 NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(optimizer_trace_update));
3189
3190 static Sys_var_long Sys_optimizer_trace_limit(
3191 "optimizer_trace_limit", "Maximum number of shown optimizer traces",
3192 SESSION_VAR(optimizer_trace_limit), CMD_LINE(REQUIRED_ARG),
3193 VALID_RANGE(0, LONG_MAX), DEFAULT(1), BLOCK_SIZE(1), NO_MUTEX_GUARD,
3194 NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(optimizer_trace_update));
3195
3196 static Sys_var_ulong Sys_optimizer_trace_max_mem_size(
3197 "optimizer_trace_max_mem_size",
3198 "Maximum allowed cumulated size of stored optimizer traces",
3199 SESSION_VAR(optimizer_trace_max_mem_size), CMD_LINE(REQUIRED_ARG),
3200 VALID_RANGE(0, ULONG_MAX), DEFAULT(1024 * 1024), BLOCK_SIZE(1));
3201
3202 static Sys_var_charptr Sys_pid_file(
3203 "pid_file", "Pid file used by safe_mysqld",
3204 READ_ONLY NON_PERSIST GLOBAL_VAR(pidfile_name_ptr), CMD_LINE(REQUIRED_ARG),
3205 IN_FS_CHARSET, DEFAULT(pidfile_name));
3206
3207 static Sys_var_charptr Sys_plugin_dir(
3208 "plugin_dir", "Directory for plugins",
3209 READ_ONLY NON_PERSIST GLOBAL_VAR(opt_plugin_dir_ptr),
3210 CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET, DEFAULT(nullptr));
3211
3212 static Sys_var_uint Sys_port(
3213 "port",
3214 "Port number to use for connection or 0 to default to, "
3215 "my.cnf, $MYSQL_TCP_PORT, "
3216 #if MYSQL_PORT_DEFAULT == 0
3217 "/etc/services, "
3218 #endif
3219 "built-in default (" STRINGIFY_ARG(MYSQL_PORT) "), whatever comes first",
3220 READ_ONLY NON_PERSIST GLOBAL_VAR(mysqld_port), CMD_LINE(REQUIRED_ARG, 'P'),
3221 VALID_RANGE(0, 65535), DEFAULT(0), BLOCK_SIZE(1));
3222
3223 static Sys_var_ulong Sys_preload_buff_size(
3224 "preload_buffer_size",
3225 "The size of the buffer that is allocated when preloading indexes",
3226 SESSION_VAR(preload_buff_size), CMD_LINE(REQUIRED_ARG),
3227 VALID_RANGE(1024, 1024 * 1024 * 1024), DEFAULT(32768), BLOCK_SIZE(1));
3228
3229 static Sys_var_uint Sys_protocol_version(
3230 "protocol_version",
3231 "The version of the client/server protocol used by the MySQL server",
3232 READ_ONLY NON_PERSIST GLOBAL_VAR(protocol_version), NO_CMD_LINE,
3233 VALID_RANGE(0, ~0), DEFAULT(PROTOCOL_VERSION), BLOCK_SIZE(1));
3234
3235 static Sys_var_proxy_user Sys_proxy_user(
3236 "proxy_user", "The proxy user account name used when logging in",
3237 IN_SYSTEM_CHARSET);
3238
3239 static Sys_var_external_user Sys_external_user(
3240 "external_user", "The external user account used when logging in",
3241 IN_SYSTEM_CHARSET);
3242
3243 static Sys_var_ulong Sys_read_buff_size(
3244 "read_buffer_size",
3245 "Each thread that does a sequential scan allocates a buffer of "
3246 "this size for each table it scans. If you do many sequential scans, "
3247 "you may want to increase this value",
3248 HINT_UPDATEABLE SESSION_VAR(read_buff_size), CMD_LINE(REQUIRED_ARG),
3249 VALID_RANGE(IO_SIZE * 2, INT_MAX32), DEFAULT(128 * 1024),
3250 BLOCK_SIZE(IO_SIZE));
3251
check_read_only(sys_var *,THD * thd,set_var *)3252 static bool check_read_only(sys_var *, THD *thd, set_var *) {
3253 /* Prevent self dead-lock */
3254 if (thd->locked_tables_mode || thd->in_active_multi_stmt_transaction()) {
3255 my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
3256 return true;
3257 }
3258 return false;
3259 }
3260
check_require_secure_transport(sys_var *,THD *,set_var * var MY_ATTRIBUTE ((unused)))3261 static bool check_require_secure_transport(
3262 sys_var *, THD *, set_var *var MY_ATTRIBUTE((unused))) {
3263 #if !defined(_WIN32)
3264 /*
3265 always allow require_secure_transport to be enabled on
3266 Linux, as socket is secure.
3267 */
3268 return false;
3269 #else
3270 /*
3271 check whether SSL or shared memory transports are enabled before
3272 turning require_secure_transport ON, otherwise no connections will
3273 be allowed on Windows.
3274 */
3275
3276 if (!var->save_result.ulonglong_value) return false;
3277 if (have_ssl() || opt_enable_shared_memory) return false;
3278 /* reject if SSL and shared memory are both disabled: */
3279 my_error(ER_NO_SECURE_TRANSPORTS_CONFIGURED, MYF(0));
3280 return true;
3281
3282 #endif
3283 }
3284
fix_read_only(sys_var * self,THD * thd,enum_var_type)3285 static bool fix_read_only(sys_var *self, THD *thd, enum_var_type) {
3286 bool result = true;
3287 bool new_read_only = read_only; // make a copy before releasing a mutex
3288 DBUG_TRACE;
3289
3290 if (read_only == false || read_only == opt_readonly) {
3291 if (opt_super_readonly && !read_only) {
3292 opt_super_readonly = false;
3293 super_read_only = false;
3294 }
3295 opt_readonly = read_only;
3296 return false;
3297 }
3298
3299 if (check_read_only(self, thd, nullptr)) // just in case
3300 goto end;
3301
3302 if (thd->global_read_lock.is_acquired()) {
3303 /*
3304 This connection already holds the global read lock.
3305 This can be the case with:
3306 - FLUSH TABLES WITH READ LOCK
3307 - SET GLOBAL READ_ONLY = 1
3308 */
3309 if (opt_super_readonly && !read_only) {
3310 opt_super_readonly = false;
3311 super_read_only = false;
3312 }
3313 opt_readonly = read_only;
3314 return false;
3315 }
3316
3317 /*
3318 READ_ONLY=1 prevents write locks from being taken on tables and
3319 blocks transactions from committing. We therefore should make sure
3320 that no such events occur while setting the read_only variable.
3321 This is a 2 step process:
3322 [1] lock_global_read_lock()
3323 Prevents connections from obtaining new write locks on
3324 tables. Note that we can still have active rw transactions.
3325 [2] make_global_read_lock_block_commit()
3326 Prevents transactions from committing.
3327 */
3328
3329 read_only = opt_readonly;
3330 mysql_mutex_unlock(&LOCK_global_system_variables);
3331
3332 if (thd->global_read_lock.lock_global_read_lock(thd))
3333 goto end_with_mutex_unlock;
3334
3335 if ((result = thd->global_read_lock.make_global_read_lock_block_commit(thd)))
3336 goto end_with_read_lock;
3337
3338 /* Change the opt_readonly system variable, safe because the lock is held */
3339 opt_readonly = new_read_only;
3340
3341 result = false;
3342
3343 end_with_read_lock:
3344 /* Release the lock */
3345 thd->global_read_lock.unlock_global_read_lock(thd);
3346 end_with_mutex_unlock:
3347 mysql_mutex_lock(&LOCK_global_system_variables);
3348 end:
3349 read_only = opt_readonly;
3350 return result;
3351 }
3352
fix_super_read_only(sys_var *,THD * thd,enum_var_type type)3353 static bool fix_super_read_only(sys_var *, THD *thd, enum_var_type type) {
3354 DBUG_TRACE;
3355
3356 /* return if no changes: */
3357 if (super_read_only == opt_super_readonly) return false;
3358
3359 /* return immediately if turning super_read_only OFF: */
3360 if (super_read_only == false) {
3361 opt_super_readonly = false;
3362 return false;
3363 }
3364 bool result = true;
3365 bool new_super_read_only =
3366 super_read_only; /* make a copy before releasing a mutex */
3367
3368 /* set read_only to ON if it is OFF, letting fix_read_only()
3369 handle its own locking needs
3370 */
3371 if (!opt_readonly) {
3372 read_only = true;
3373 if ((result = fix_read_only(nullptr, thd, type))) goto end;
3374 }
3375
3376 /* if we already have global read lock, set super_read_only
3377 and return immediately:
3378 */
3379 if (thd->global_read_lock.is_acquired()) {
3380 opt_super_readonly = super_read_only;
3381 return false;
3382 }
3383
3384 /* now we're turning ON super_read_only: */
3385 super_read_only = opt_super_readonly;
3386 mysql_mutex_unlock(&LOCK_global_system_variables);
3387
3388 if (thd->global_read_lock.lock_global_read_lock(thd))
3389 goto end_with_mutex_unlock;
3390
3391 if ((result = thd->global_read_lock.make_global_read_lock_block_commit(thd)))
3392 goto end_with_read_lock;
3393 opt_super_readonly = new_super_read_only;
3394 result = false;
3395
3396 end_with_read_lock:
3397 /* Release the lock */
3398 thd->global_read_lock.unlock_global_read_lock(thd);
3399 end_with_mutex_unlock:
3400 mysql_mutex_lock(&LOCK_global_system_variables);
3401 end:
3402 super_read_only = opt_super_readonly;
3403 return result;
3404 }
3405
3406 static Sys_var_bool Sys_require_secure_transport(
3407 "require_secure_transport",
3408 "When this option is enabled, connections attempted using insecure "
3409 "transport will be rejected. Secure transports are SSL/TLS, "
3410 "Unix socket or Shared Memory (on Windows).",
3411 GLOBAL_VAR(opt_require_secure_transport), CMD_LINE(OPT_ARG), DEFAULT(false),
3412 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_require_secure_transport),
3413 ON_UPDATE(nullptr));
3414
3415 /**
3416 The read_only boolean is always equal to the opt_readonly boolean except
3417 during fix_read_only(); when that function is entered, opt_readonly is
3418 the pre-update value and read_only is the post-update value.
3419 fix_read_only() compares them and runs needed operations for the
3420 transition (especially when transitioning from false to true) and
3421 synchronizes both booleans in the end.
3422 */
3423 static Sys_var_bool Sys_readonly(
3424 "read_only",
3425 "Make all non-temporary tables read-only, with the exception for "
3426 "replication (slave) threads and users with the SUPER privilege",
3427 GLOBAL_VAR(read_only), CMD_LINE(OPT_ARG), DEFAULT(false), NO_MUTEX_GUARD,
3428 NOT_IN_BINLOG, ON_CHECK(check_read_only), ON_UPDATE(fix_read_only));
3429
3430 /**
3431 Setting super_read_only to ON triggers read_only to also be set to ON.
3432 */
3433 static Sys_var_bool Sys_super_readonly(
3434 "super_read_only",
3435 "Make all non-temporary tables read-only, with the exception for "
3436 "replication (slave) threads. Users with the SUPER privilege are "
3437 "affected, unlike read_only. Setting super_read_only to ON "
3438 "also sets read_only to ON.",
3439 GLOBAL_VAR(super_read_only), CMD_LINE(OPT_ARG), DEFAULT(false),
3440 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
3441 ON_UPDATE(fix_super_read_only));
3442
3443 // Small lower limit to be able to test MRR
3444 static Sys_var_ulong Sys_read_rnd_buff_size(
3445 "read_rnd_buffer_size",
3446 "When reading rows in sorted order after a sort, the rows are read "
3447 "through this buffer to avoid a disk seeks",
3448 HINT_UPDATEABLE SESSION_VAR(read_rnd_buff_size), CMD_LINE(REQUIRED_ARG),
3449 VALID_RANGE(1, INT_MAX32), DEFAULT(256 * 1024), BLOCK_SIZE(1));
3450
3451 static Sys_var_ulong Sys_div_precincrement(
3452 "div_precision_increment",
3453 "Precision of the result of '/' "
3454 "operator will be increased on that value",
3455 HINT_UPDATEABLE SESSION_VAR(div_precincrement), CMD_LINE(REQUIRED_ARG),
3456 VALID_RANGE(0, DECIMAL_MAX_SCALE), DEFAULT(4), BLOCK_SIZE(1));
3457
3458 static Sys_var_uint Sys_eq_range_index_dive_limit(
3459 "eq_range_index_dive_limit",
3460 "The optimizer will use existing index statistics instead of "
3461 "doing index dives for equality ranges if the number of equality "
3462 "ranges for the index is larger than or equal to this number. "
3463 "If set to 0, index dives are always used.",
3464 HINT_UPDATEABLE SESSION_VAR(eq_range_index_dive_limit),
3465 CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, UINT_MAX32), DEFAULT(200),
3466 BLOCK_SIZE(1));
3467
3468 static Sys_var_ulong Sys_range_alloc_block_size(
3469 "range_alloc_block_size",
3470 "Allocation block size for storing ranges during optimization",
3471 HINT_UPDATEABLE SESSION_VAR(range_alloc_block_size), CMD_LINE(REQUIRED_ARG),
3472 VALID_RANGE(RANGE_ALLOC_BLOCK_SIZE, UINT32_MAX),
3473 DEFAULT(RANGE_ALLOC_BLOCK_SIZE), BLOCK_SIZE(1024));
3474
fix_thd_mem_root(sys_var * self,THD * thd,enum_var_type type)3475 static bool fix_thd_mem_root(sys_var *self, THD *thd, enum_var_type type) {
3476 if (!self->is_global_persist(type))
3477 thd->mem_root->set_block_size(thd->variables.query_alloc_block_size);
3478 return false;
3479 }
3480 static Sys_var_ulong Sys_query_alloc_block_size(
3481 "query_alloc_block_size",
3482 "Allocation block size for query parsing and execution",
3483 SESSION_VAR(query_alloc_block_size), CMD_LINE(REQUIRED_ARG),
3484 VALID_RANGE(1024, UINT_MAX32), DEFAULT(QUERY_ALLOC_BLOCK_SIZE),
3485 BLOCK_SIZE(1024), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
3486 ON_UPDATE(fix_thd_mem_root));
3487
3488 static Sys_var_ulong Sys_query_prealloc_size(
3489 "query_prealloc_size", "Persistent buffer for query parsing and execution",
3490 SESSION_VAR(query_prealloc_size), CMD_LINE(REQUIRED_ARG),
3491 VALID_RANGE(QUERY_ALLOC_PREALLOC_SIZE, ULONG_MAX),
3492 DEFAULT(QUERY_ALLOC_PREALLOC_SIZE), BLOCK_SIZE(1024), NO_MUTEX_GUARD,
3493 NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(fix_thd_mem_root));
3494
3495 #if defined(_WIN32)
3496 static Sys_var_bool Sys_shared_memory(
3497 "shared_memory", "Enable the shared memory",
3498 READ_ONLY NON_PERSIST GLOBAL_VAR(opt_enable_shared_memory),
3499 CMD_LINE(OPT_ARG), DEFAULT(false));
3500
3501 static Sys_var_charptr Sys_shared_memory_base_name(
3502 "shared_memory_base_name", "Base name of shared memory",
3503 READ_ONLY NON_PERSIST GLOBAL_VAR(shared_memory_base_name),
3504 CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET, DEFAULT(0));
3505 #endif
3506
3507 // this has to be NO_CMD_LINE as the command-line option has a different name
3508 static Sys_var_bool Sys_skip_external_locking(
3509 "skip_external_locking", "Don't use system (external) locking",
3510 READ_ONLY NON_PERSIST GLOBAL_VAR(my_disable_locking), NO_CMD_LINE,
3511 DEFAULT(true));
3512
3513 static Sys_var_bool Sys_skip_networking(
3514 "skip_networking", "Don't allow connection with TCP/IP",
3515 READ_ONLY NON_PERSIST GLOBAL_VAR(opt_disable_networking), CMD_LINE(OPT_ARG),
3516 DEFAULT(false));
3517
3518 static Sys_var_bool Sys_skip_name_resolve(
3519 "skip_name_resolve",
3520 "Don't resolve hostnames. All hostnames are IP's or 'localhost'.",
3521 READ_ONLY GLOBAL_VAR(opt_skip_name_resolve),
3522 CMD_LINE(OPT_ARG, OPT_SKIP_RESOLVE), DEFAULT(false));
3523
3524 static Sys_var_bool Sys_skip_show_database(
3525 "skip_show_database", "Don't allow 'SHOW DATABASE' commands",
3526 READ_ONLY GLOBAL_VAR(opt_skip_show_db), CMD_LINE(OPT_ARG), DEFAULT(false));
3527
3528 static Sys_var_charptr Sys_socket(
3529 "socket", "Socket file to use for connection",
3530 READ_ONLY NON_PERSIST GLOBAL_VAR(mysqld_unix_port), CMD_LINE(REQUIRED_ARG),
3531 IN_FS_CHARSET, DEFAULT(nullptr));
3532
3533 static Sys_var_ulong Sys_thread_stack(
3534 "thread_stack", "The stack size for each thread",
3535 READ_ONLY GLOBAL_VAR(my_thread_stack_size), CMD_LINE(REQUIRED_ARG),
3536 #if defined(__clang__) && defined(HAVE_UBSAN)
3537 // DEFAULT_THREAD_STACK is multiplied by 3 for clang/UBSAN
3538 // We need to increase the minimum value as well.
3539 VALID_RANGE(DEFAULT_THREAD_STACK / 2, ULONG_MAX),
3540 #else
3541 VALID_RANGE(128 * 1024, ULONG_MAX),
3542 #endif
3543 DEFAULT(DEFAULT_THREAD_STACK), BLOCK_SIZE(1024));
3544
3545 static Sys_var_charptr Sys_tmpdir(
3546 "tmpdir",
3547 "Path for temporary files. Several paths may "
3548 "be specified, separated by a "
3549 #if defined(_WIN32)
3550 "semicolon (;)"
3551 #else
3552 "colon (:)"
3553 #endif
3554 ", in this case they are used in a round-robin fashion",
3555 READ_ONLY NON_PERSIST GLOBAL_VAR(opt_mysql_tmpdir),
3556 CMD_LINE(REQUIRED_ARG, 't'), IN_FS_CHARSET, DEFAULT(nullptr));
3557
fix_trans_mem_root(sys_var * self,THD * thd,enum_var_type type)3558 static bool fix_trans_mem_root(sys_var *self, THD *thd, enum_var_type type) {
3559 if (!self->is_global_persist(type))
3560 thd->get_transaction()->init_mem_root_defaults(
3561 thd->variables.trans_alloc_block_size,
3562 thd->variables.trans_prealloc_size);
3563 return false;
3564 }
3565 static Sys_var_ulong Sys_trans_alloc_block_size(
3566 "transaction_alloc_block_size",
3567 "Allocation block size for transactions to be stored in binary log",
3568 SESSION_VAR(trans_alloc_block_size), CMD_LINE(REQUIRED_ARG),
3569 VALID_RANGE(1024, 128 * 1024), DEFAULT(QUERY_ALLOC_BLOCK_SIZE),
3570 BLOCK_SIZE(1024), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
3571 ON_UPDATE(fix_trans_mem_root));
3572
3573 static Sys_var_ulong Sys_trans_prealloc_size(
3574 "transaction_prealloc_size",
3575 "Persistent buffer for transactions to be stored in binary log",
3576 SESSION_VAR(trans_prealloc_size), CMD_LINE(REQUIRED_ARG),
3577 VALID_RANGE(1024, 128 * 1024), DEFAULT(TRANS_ALLOC_PREALLOC_SIZE),
3578 BLOCK_SIZE(1024), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
3579 ON_UPDATE(fix_trans_mem_root));
3580
3581 static const char *thread_handling_names[] = {
3582 "one-thread-per-connection", "no-threads", "loaded-dynamically", nullptr};
3583 static Sys_var_enum Sys_thread_handling(
3584 "thread_handling",
3585 "Define threads usage for handling queries, one of "
3586 "one-thread-per-connection, no-threads, loaded-dynamically",
3587 READ_ONLY GLOBAL_VAR(Connection_handler_manager::thread_handling),
3588 CMD_LINE(REQUIRED_ARG), thread_handling_names, DEFAULT(0));
3589
3590 static Sys_var_charptr Sys_secure_file_priv(
3591 "secure_file_priv",
3592 "Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
3593 "within specified directory",
3594 READ_ONLY NON_PERSIST GLOBAL_VAR(opt_secure_file_priv),
3595 CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET,
3596 DEFAULT(DEFAULT_SECURE_FILE_PRIV_DIR));
3597
fix_server_id(sys_var *,THD * thd,enum_var_type)3598 static bool fix_server_id(sys_var *, THD *thd, enum_var_type) {
3599 // server_id is 'MYSQL_PLUGIN_IMPORT ulong'
3600 // So we cast here, rather than change its type.
3601 server_id_supplied = true;
3602 thd->server_id = static_cast<uint32>(server_id);
3603 return false;
3604 }
3605 static Sys_var_ulong Sys_server_id(
3606 "server_id",
3607 "Uniquely identifies the server instance in the community of "
3608 "replication partners",
3609 GLOBAL_VAR(server_id), CMD_LINE(REQUIRED_ARG, OPT_SERVER_ID),
3610 VALID_RANGE(0, UINT_MAX32), DEFAULT(1), BLOCK_SIZE(1), NO_MUTEX_GUARD,
3611 NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(fix_server_id));
3612
3613 static Sys_var_charptr Sys_server_uuid(
3614 "server_uuid", "Uniquely identifies the server instance in the universe",
3615 READ_ONLY NON_PERSIST GLOBAL_VAR(server_uuid_ptr), NO_CMD_LINE,
3616 IN_FS_CHARSET, DEFAULT(server_uuid));
3617
3618 static Sys_var_uint Sys_server_id_bits(
3619 "server_id_bits", "Set number of significant bits in server-id",
3620 GLOBAL_VAR(opt_server_id_bits), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 32),
3621 DEFAULT(32), BLOCK_SIZE(1));
3622
3623 static Sys_var_int32 Sys_regexp_time_limit(
3624 "regexp_time_limit",
3625 "Timeout for regular expressions matches, in steps of the match "
3626 "engine, typically on the order of milliseconds.",
3627 GLOBAL_VAR(opt_regexp_time_limit), CMD_LINE(REQUIRED_ARG),
3628 VALID_RANGE(0, INT32_MAX), DEFAULT(32), BLOCK_SIZE(1));
3629
3630 static Sys_var_int32 Sys_regexp_stack_limit(
3631 "regexp_stack_limit", "Stack size limit for regular expressions matches",
3632 GLOBAL_VAR(opt_regexp_stack_limit), CMD_LINE(REQUIRED_ARG),
3633 VALID_RANGE(0, INT32_MAX), DEFAULT(8000000), BLOCK_SIZE(1));
3634
3635 static Sys_var_bool Sys_slave_compressed_protocol(
3636 "slave_compressed_protocol", "Use compression on master/slave protocol",
3637 GLOBAL_VAR(opt_slave_compressed_protocol), CMD_LINE(OPT_ARG),
3638 DEFAULT(false));
3639
3640 static const char *slave_exec_mode_names[] = {"STRICT", "IDEMPOTENT", nullptr};
3641 static Sys_var_enum Slave_exec_mode(
3642 "slave_exec_mode",
3643 "Modes for how replication events should be executed. Legal values "
3644 "are STRICT (default) and IDEMPOTENT. In IDEMPOTENT mode, "
3645 "replication will not stop for operations that are idempotent. "
3646 "In STRICT mode, replication will stop on any unexpected difference "
3647 "between the master and the slave",
3648 GLOBAL_VAR(slave_exec_mode_options), CMD_LINE(REQUIRED_ARG),
3649 slave_exec_mode_names, DEFAULT(RBR_EXEC_MODE_STRICT));
3650
3651 const char *slave_type_conversions_name[] = {
3652 "ALL_LOSSY", "ALL_NON_LOSSY", "ALL_UNSIGNED", "ALL_SIGNED", nullptr};
3653 static Sys_var_set Slave_type_conversions(
3654 "slave_type_conversions",
3655 "Set of slave type conversions that are enabled. Legal values are:"
3656 " ALL_LOSSY to enable lossy conversions,"
3657 " ALL_NON_LOSSY to enable non-lossy conversions,"
3658 " ALL_UNSIGNED to treat all integer column type data to be unsigned "
3659 "values, and"
3660 " ALL_SIGNED to treat all integer column type data to be signed values."
3661 " Default treatment is ALL_SIGNED. If ALL_SIGNED and ALL_UNSIGNED both "
3662 "are"
3663 " specified, ALL_SIGNED will take higher priority than ALL_UNSIGNED."
3664 " If the variable is assigned the empty set, no conversions are"
3665 " allowed and it is expected that the types match exactly.",
3666 GLOBAL_VAR(slave_type_conversions_options), CMD_LINE(REQUIRED_ARG),
3667 slave_type_conversions_name, DEFAULT(0));
3668
3669 static Sys_var_bool Sys_slave_sql_verify_checksum(
3670 "slave_sql_verify_checksum",
3671 "Force checksum verification of replication events after reading them "
3672 "from relay log. Note: Events are always checksum-verified by slave on "
3673 "receiving them from the network before writing them to the relay "
3674 "log. Enabled by default.",
3675 GLOBAL_VAR(opt_slave_sql_verify_checksum), CMD_LINE(OPT_ARG),
3676 DEFAULT(true));
3677
check_not_null_not_empty(sys_var * self,THD * thd,set_var * var)3678 static bool check_not_null_not_empty(sys_var *self, THD *thd, set_var *var) {
3679 String str, *res;
3680 /* null value is not allowed */
3681 if (check_not_null(self, thd, var)) return true;
3682
3683 /** empty value ('') is not allowed */
3684 res = var->value ? var->value->val_str(&str) : nullptr;
3685 if (res && res->is_empty()) return true;
3686
3687 return false;
3688 }
3689
check_slave_stopped(sys_var * self,THD * thd,set_var * var)3690 static bool check_slave_stopped(sys_var *self, THD *thd, set_var *var) {
3691 bool result = false;
3692 Master_info *mi = nullptr;
3693
3694 if (check_not_null_not_empty(self, thd, var)) return true;
3695
3696 channel_map.wrlock();
3697
3698 for (mi_map::iterator it = channel_map.begin(); it != channel_map.end();
3699 it++) {
3700 mi = it->second;
3701 if (mi) {
3702 mysql_mutex_lock(&mi->rli->run_lock);
3703 if (mi->rli->slave_running) {
3704 my_error(ER_SLAVE_SQL_THREAD_MUST_STOP, MYF(0));
3705 result = true;
3706 }
3707 mysql_mutex_unlock(&mi->rli->run_lock);
3708 }
3709 }
3710 channel_map.unlock();
3711 return result;
3712 }
3713
3714 static const char *slave_rows_search_algorithms_names[] = {
3715 "TABLE_SCAN", "INDEX_SCAN", "HASH_SCAN", nullptr};
3716 static Sys_var_set Slave_rows_search_algorithms(
3717 "slave_rows_search_algorithms",
3718 "Set of searching algorithms that the slave will use while "
3719 "searching for records from the storage engine to either "
3720 "updated or deleted them. Possible values are: INDEX_SCAN, "
3721 "TABLE_SCAN and HASH_SCAN. Any combination is allowed, and "
3722 "the slave will always pick the most suitable algorithm for "
3723 "any given scenario. "
3724 "(Default: INDEX_SCAN, HASH_SCAN).",
3725 GLOBAL_VAR(slave_rows_search_algorithms_options),
3726 CMD_LINE(REQUIRED_ARG, OPT_SLAVE_ROWS_SEARCH_ALGORITHMS),
3727 slave_rows_search_algorithms_names,
3728 DEFAULT(SLAVE_ROWS_INDEX_SCAN | SLAVE_ROWS_HASH_SCAN), NO_MUTEX_GUARD,
3729 NOT_IN_BINLOG, ON_CHECK(check_not_null_not_empty), ON_UPDATE(nullptr),
3730 DEPRECATED_VAR(""));
3731
3732 static const char *mts_parallel_type_names[] = {"DATABASE", "LOGICAL_CLOCK",
3733 nullptr};
3734 static Sys_var_enum Mts_parallel_type(
3735 "slave_parallel_type",
3736 "Specifies if the slave will use database partitioning "
3737 "or information from master to parallelize transactions."
3738 "(Default: DATABASE).",
3739 PERSIST_AS_READONLY GLOBAL_VAR(mts_parallel_option), CMD_LINE(REQUIRED_ARG),
3740 mts_parallel_type_names, DEFAULT(MTS_PARALLEL_TYPE_DB_NAME), NO_MUTEX_GUARD,
3741 NOT_IN_BINLOG, ON_CHECK(check_slave_stopped), ON_UPDATE(nullptr));
3742
check_binlog_transaction_dependency_tracking(sys_var *,THD *,set_var * var)3743 static bool check_binlog_transaction_dependency_tracking(sys_var *, THD *,
3744 set_var *var) {
3745 if (global_system_variables.transaction_write_set_extraction ==
3746 HASH_ALGORITHM_OFF &&
3747 var->save_result.ulonglong_value != DEPENDENCY_TRACKING_COMMIT_ORDER) {
3748 my_error(ER_WRONG_USAGE, MYF(0),
3749 "binlog_transaction_dependency_tracking (!= COMMIT_ORDER)",
3750 "transaction_write_set_extraction (= OFF)");
3751
3752 return true;
3753 }
3754 return false;
3755 }
3756
update_binlog_transaction_dependency_tracking(sys_var *,THD *,enum_var_type)3757 static bool update_binlog_transaction_dependency_tracking(sys_var *, THD *,
3758 enum_var_type) {
3759 /*
3760 m_opt_tracking_mode is read and written in an atomic way based
3761 on the value of m_opt_tracking_mode_value that is associated
3762 with the sys_var variable.
3763 */
3764 set_mysqld_opt_tracking_mode();
3765
3766 /*
3767 the writeset_history_start needs to be set to 0 whenever there is a
3768 change in the transaction dependency source so that WS and COMMIT
3769 transition smoothly.
3770 */
3771 mysql_bin_log.m_dependency_tracker.tracking_mode_changed();
3772 return false;
3773 }
3774
3775 static PolyLock_mutex PLock_slave_trans_dep_tracker(
3776 &LOCK_slave_trans_dep_tracker);
3777 static const char *opt_binlog_transaction_dependency_tracking_names[] = {
3778 "COMMIT_ORDER", "WRITESET", "WRITESET_SESSION", NullS};
3779 static Sys_var_enum Binlog_transaction_dependency_tracking(
3780 "binlog_transaction_dependency_tracking",
3781 "Selects the source of dependency information from which to "
3782 "assess which transactions can be executed in parallel by the "
3783 "slave's multi-threaded applier. "
3784 "Possible values are COMMIT_ORDER, WRITESET and WRITESET_SESSION.",
3785 GLOBAL_VAR(mysql_bin_log.m_dependency_tracker.m_opt_tracking_mode_value),
3786 CMD_LINE(REQUIRED_ARG), opt_binlog_transaction_dependency_tracking_names,
3787 DEFAULT(DEPENDENCY_TRACKING_COMMIT_ORDER), &PLock_slave_trans_dep_tracker,
3788 NOT_IN_BINLOG, ON_CHECK(check_binlog_transaction_dependency_tracking),
3789 ON_UPDATE(update_binlog_transaction_dependency_tracking));
3790 static Sys_var_ulong Binlog_transaction_dependency_history_size(
3791 "binlog_transaction_dependency_history_size",
3792 "Maximum number of rows to keep in the writeset history.",
3793 GLOBAL_VAR(mysql_bin_log.m_dependency_tracker.get_writeset()
3794 ->m_opt_max_history_size),
3795 CMD_LINE(REQUIRED_ARG, 0), VALID_RANGE(1, 1000000), DEFAULT(25000),
3796 BLOCK_SIZE(1), &PLock_slave_trans_dep_tracker, NOT_IN_BINLOG,
3797 ON_CHECK(nullptr), ON_UPDATE(nullptr));
3798
3799 static Sys_var_bool Sys_slave_preserve_commit_order(
3800 "slave_preserve_commit_order",
3801 "Force slave workers to make commits in the same order as on the master. "
3802 "Disabled by default.",
3803 PERSIST_AS_READONLY GLOBAL_VAR(opt_slave_preserve_commit_order),
3804 CMD_LINE(OPT_ARG, OPT_SLAVE_PRESERVE_COMMIT_ORDER), DEFAULT(false),
3805 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_slave_stopped),
3806 ON_UPDATE(nullptr));
3807
global_update(THD *,set_var * var)3808 bool Sys_var_charptr::global_update(THD *, set_var *var) {
3809 char *new_val, *ptr = var->save_result.string_value.str;
3810 size_t len = var->save_result.string_value.length;
3811 if (ptr) {
3812 new_val = (char *)my_memdup(key_memory_Sys_var_charptr_value, ptr, len + 1,
3813 MYF(MY_WME));
3814 if (!new_val) return true;
3815 new_val[len] = 0;
3816 } else
3817 new_val = nullptr;
3818 if (flags & ALLOCATED) my_free(global_var(char *));
3819 flags |= ALLOCATED;
3820 global_var(char *) = new_val;
3821 return false;
3822 }
3823
global_update(THD * thd,set_var * var)3824 bool Sys_var_enum_binlog_checksum::global_update(THD *thd, set_var *var) {
3825 bool check_purge = false;
3826
3827 /*
3828 SET binlog_checksome command should ignore 'read-only' and
3829 'super_read_only' options so that it can update 'mysql.gtid_executed'
3830 replication repository table.
3831 */
3832 thd->set_skip_readonly_check();
3833 mysql_mutex_lock(mysql_bin_log.get_log_lock());
3834 if (mysql_bin_log.is_open()) {
3835 bool alg_changed =
3836 (binlog_checksum_options != (uint)var->save_result.ulonglong_value);
3837 if (alg_changed)
3838 mysql_bin_log.checksum_alg_reset =
3839 (uint8)var->save_result.ulonglong_value;
3840 mysql_bin_log.rotate(true, &check_purge);
3841 if (alg_changed)
3842 mysql_bin_log.checksum_alg_reset =
3843 binary_log::BINLOG_CHECKSUM_ALG_UNDEF; // done
3844 } else {
3845 binlog_checksum_options =
3846 static_cast<ulong>(var->save_result.ulonglong_value);
3847 }
3848 DBUG_ASSERT(binlog_checksum_options == var->save_result.ulonglong_value);
3849 DBUG_ASSERT(mysql_bin_log.checksum_alg_reset ==
3850 binary_log::BINLOG_CHECKSUM_ALG_UNDEF);
3851 mysql_mutex_unlock(mysql_bin_log.get_log_lock());
3852
3853 if (check_purge) mysql_bin_log.purge();
3854
3855 return false;
3856 }
3857
session_update(THD * thd,set_var * var)3858 bool Sys_var_gtid_next::session_update(THD *thd, set_var *var) {
3859 DBUG_TRACE;
3860 char buf[Gtid::MAX_TEXT_LENGTH + 1];
3861 // Get the value
3862 String str(buf, sizeof(buf), &my_charset_latin1);
3863 char *res = nullptr;
3864 if (!var->value) {
3865 // set session gtid_next= default
3866 DBUG_ASSERT(var->save_result.string_value.str);
3867 DBUG_ASSERT(var->save_result.string_value.length);
3868 res = var->save_result.string_value.str;
3869 } else if (var->value->val_str(&str))
3870 res = var->value->val_str(&str)->c_ptr_safe();
3871 if (!res) {
3872 my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.str, "NULL");
3873 return true;
3874 }
3875 global_sid_lock->rdlock();
3876 Gtid_specification spec;
3877 if (spec.parse(global_sid_map, res) != RETURN_STATUS_OK) {
3878 global_sid_lock->unlock();
3879 return true;
3880 }
3881
3882 bool ret = set_gtid_next(thd, spec);
3883 // set_gtid_next releases global_sid_lock
3884 return ret;
3885 }
3886
3887 #ifdef HAVE_GTID_NEXT_LIST
session_update(THD * thd,set_var * var)3888 bool Sys_var_gtid_set::session_update(THD *thd, set_var *var) {
3889 DBUG_TRACE;
3890 Gtid_set_or_null *gsn = (Gtid_set_or_null *)session_var_ptr(thd);
3891 char *value = var->save_result.string_value.str;
3892 if (value == NULL)
3893 gsn->set_null();
3894 else {
3895 Gtid_set *gs = gsn->set_non_null(global_sid_map);
3896 if (gs == NULL) {
3897 my_error(ER_OUT_OF_RESOURCES, MYF(0)); // allocation failed
3898 return true;
3899 }
3900 /*
3901 If string begins with '+', add to the existing set, otherwise
3902 replace existing set.
3903 */
3904 while (isspace(*value)) value++;
3905 if (*value == '+')
3906 value++;
3907 else
3908 gs->clear();
3909 // Add specified set of groups to Gtid_set.
3910 global_sid_lock->rdlock();
3911 enum_return_status ret = gs->add_gtid_text(value);
3912 global_sid_lock->unlock();
3913 if (ret != RETURN_STATUS_OK) {
3914 gsn->set_null();
3915 return true;
3916 }
3917 }
3918 return false;
3919 }
3920 #endif // HAVE_GTID_NEXT_LIST
3921
3922 /**
3923 This function shall issue a deprecation warning
3924 if the new gtid mode is set to GTID_MODE_ON and
3925 there is at least one replication channel with
3926 IGNORE_SERVER_IDS configured (i.e., not empty).
3927
3928 The caller must have acquired a lock on the
3929 channel_map object before calling this function.
3930
3931 The warning emitted is: ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT .
3932
3933 @param thd The current session thread context.
3934 @param oldmode The old value of @@global.gtid_mode.
3935 @param newmode The new value for @@global.gtid_mode.
3936
3937 */
issue_deprecation_warnings_gtid_mode(THD * thd,Gtid_mode::value_type oldmode MY_ATTRIBUTE ((unused)),Gtid_mode::value_type newmode)3938 static void issue_deprecation_warnings_gtid_mode(
3939 THD *thd, Gtid_mode::value_type oldmode MY_ATTRIBUTE((unused)),
3940 Gtid_mode::value_type newmode) {
3941 channel_map.assert_some_lock();
3942
3943 /*
3944 Check that if changing to gtid_mode=on no channel is configured
3945 to ignore server ids. If it is, issue a deprecation warning.
3946 */
3947 if (newmode == Gtid_mode::ON) {
3948 for (mi_map::iterator it = channel_map.begin(); it != channel_map.end();
3949 it++) {
3950 Master_info *mi = it->second;
3951 if (mi != nullptr && mi->is_ignore_server_ids_configured()) {
3952 push_warning_printf(
3953 thd, Sql_condition::SL_WARNING, ER_WARN_DEPRECATED_SYNTAX,
3954 ER_THD(thd, ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT),
3955 "CHANGE MASTER TO ... IGNORE_SERVER_IDS='...' "
3956 "(when @@GLOBAL.GTID_MODE = ON)");
3957
3958 break; // Only push one warning
3959 }
3960 }
3961 }
3962 }
3963
3964 /**
3965 This function shall be called whenever the global scope
3966 of gtid_mode var is updated.
3967
3968 It checks some preconditions and also emits deprecation
3969 warnings conditionally when changing the value.
3970
3971 Deprecation warnings are emitted after error conditions
3972 have been checked and only if there is no error raised.
3973 */
global_update(THD * thd,set_var * var)3974 bool Sys_var_gtid_mode::global_update(THD *thd, set_var *var) {
3975 DBUG_TRACE;
3976 bool ret = true;
3977
3978 /*
3979 SET binlog_checksome command should ignore 'read-only' and
3980 'super_read_only' options so that it can update 'mysql.gtid_executed'
3981 replication repository table.
3982 */
3983 thd->set_skip_readonly_check();
3984 /*
3985 Hold lock_log so that:
3986 - other transactions are not flushed while gtid_mode is changed;
3987 - gtid_mode is not changed while some other thread is rotating
3988 the binlog.
3989
3990 Hold channel_map lock so that:
3991 - gtid_mode is not changed during the execution of some
3992 replication command; particularly CHANGE MASTER. CHANGE MASTER
3993 checks if GTID_MODE is compatible with AUTO_POSITION, and
3994 later it actually updates the in-memory structure for
3995 AUTO_POSITION. If gtid_mode was changed between these calls,
3996 auto_position could be set incompatible with gtid_mode.
3997
3998 Hold global_sid_lock.wrlock so that:
3999 - other transactions cannot acquire ownership of any gtid.
4000
4001 Hold Gtid_mode::lock so that all places that don't want to hold
4002 any of the other locks, but want to read gtid_mode, don't need
4003 to take the other locks.
4004 */
4005
4006 auto new_gtid_mode =
4007 static_cast<Gtid_mode::value_type>(var->save_result.ulonglong_value);
4008
4009 if (Gtid_mode::lock.trywrlock()) {
4010 my_error(ER_CANT_SET_GTID_MODE, MYF(0), Gtid_mode::to_string(new_gtid_mode),
4011 "there is a concurrent operation that disallows changes to "
4012 "@@GLOBAL.GTID_MODE");
4013 return ret;
4014 }
4015
4016 channel_map.wrlock();
4017 mysql_mutex_lock(mysql_bin_log.get_log_lock());
4018 global_sid_lock->wrlock();
4019 int lock_count = 4;
4020
4021 auto old_gtid_mode = global_gtid_mode.get();
4022 DBUG_ASSERT(new_gtid_mode <= Gtid_mode::ON);
4023
4024 DBUG_PRINT("info", ("old_gtid_mode=%d new_gtid_mode=%d", old_gtid_mode,
4025 new_gtid_mode));
4026
4027 if (new_gtid_mode == old_gtid_mode) goto end;
4028
4029 // Can only change one step at a time.
4030 /*
4031 Change gtid_mode value without checking for one step change during
4032 server startup.
4033 */
4034 if (mysqld_server_started &&
4035 abs((int)new_gtid_mode - (int)old_gtid_mode) > 1) {
4036 my_error(ER_GTID_MODE_CAN_ONLY_CHANGE_ONE_STEP_AT_A_TIME, MYF(0));
4037 goto err;
4038 }
4039
4040 // Not allowed with slave_sql_skip_counter
4041 DBUG_PRINT("info", ("sql_slave_skip_counter=%d", sql_slave_skip_counter));
4042 if (new_gtid_mode == Gtid_mode::ON && sql_slave_skip_counter > 0) {
4043 my_error(ER_CANT_SET_GTID_MODE, MYF(0), "ON",
4044 "@@GLOBAL.SQL_SLAVE_SKIP_COUNTER is greater than zero");
4045 goto err;
4046 }
4047
4048 if (new_gtid_mode != Gtid_mode::ON && replicate_same_server_id &&
4049 opt_log_slave_updates && opt_bin_log) {
4050 std::stringstream ss;
4051
4052 ss << "replicate_same_server_id is set together with log_slave_updates"
4053 << " and log_bin. Thus, any anonymous transactions"
4054 << " would circulate infinitely in case this server is part of a"
4055 << " circular replication topology";
4056
4057 my_error(ER_CANT_SET_GTID_MODE, MYF(0), Gtid_mode::to_string(new_gtid_mode),
4058 ss.str().c_str());
4059 goto err;
4060 }
4061
4062 // Cannot set OFF when some channel uses AUTO_POSITION.
4063 if (new_gtid_mode == Gtid_mode::OFF) {
4064 for (mi_map::iterator it = channel_map.begin(); it != channel_map.end();
4065 it++) {
4066 Master_info *mi = it->second;
4067 DBUG_PRINT("info", ("auto_position for channel '%s' is %d",
4068 mi->get_channel(), mi->is_auto_position()));
4069 if (mi != nullptr && mi->is_auto_position()) {
4070 char buf[1024];
4071 snprintf(buf, sizeof(buf),
4072 "replication channel '%.192s' is configured "
4073 "in AUTO_POSITION mode. Execute "
4074 "CHANGE MASTER TO MASTER_AUTO_POSITION = 0 "
4075 "FOR CHANNEL '%.192s' before you set "
4076 "@@GLOBAL.GTID_MODE = OFF.",
4077 mi->get_channel(), mi->get_channel());
4078 my_error(ER_CANT_SET_GTID_MODE, MYF(0), "OFF", buf);
4079 goto err;
4080 }
4081 }
4082 }
4083
4084 // Can't set GTID_MODE != ON when group replication is enabled.
4085 if (is_group_replication_running()) {
4086 DBUG_ASSERT(old_gtid_mode == Gtid_mode::ON);
4087 DBUG_ASSERT(new_gtid_mode == Gtid_mode::ON_PERMISSIVE);
4088 my_error(ER_CANT_SET_GTID_MODE, MYF(0), Gtid_mode::to_string(new_gtid_mode),
4089 "group replication requires @@GLOBAL.GTID_MODE=ON");
4090 goto err;
4091 }
4092
4093 // Compatible with ongoing transactions.
4094 DBUG_PRINT("info", ("anonymous_ownership_count=%d owned_gtids->is_empty=%d",
4095 gtid_state->get_anonymous_ownership_count(),
4096 gtid_state->get_owned_gtids()->is_empty()));
4097 gtid_state->get_owned_gtids()->dbug_print("global owned_gtids");
4098 if (new_gtid_mode == Gtid_mode::ON &&
4099 gtid_state->get_anonymous_ownership_count() > 0) {
4100 my_error(ER_CANT_SET_GTID_MODE, MYF(0), "ON",
4101 "there are ongoing, anonymous transactions. Before "
4102 "setting @@GLOBAL.GTID_MODE = ON, wait until "
4103 "SHOW STATUS LIKE 'ANONYMOUS_TRANSACTION_COUNT' "
4104 "shows zero on all servers. Then wait for all "
4105 "existing, anonymous transactions to replicate to "
4106 "all slaves, and then execute "
4107 "SET @@GLOBAL.GTID_MODE = ON on all servers. "
4108 "See the Manual for details");
4109 goto err;
4110 }
4111
4112 if (new_gtid_mode == Gtid_mode::OFF &&
4113 !gtid_state->get_owned_gtids()->is_empty()) {
4114 my_error(ER_CANT_SET_GTID_MODE, MYF(0), "OFF",
4115 "there are ongoing transactions that have a GTID. "
4116 "Before you set @@GLOBAL.GTID_MODE = OFF, wait "
4117 "until SELECT @@GLOBAL.GTID_OWNED is empty on all "
4118 "servers. Then wait for all GTID-transactions to "
4119 "replicate to all servers, and then execute "
4120 "SET @@GLOBAL.GTID_MODE = OFF on all servers. "
4121 "See the Manual for details");
4122 goto err;
4123 }
4124
4125 // Compatible with ongoing GTID-violating transactions
4126 DBUG_PRINT("info",
4127 ("automatic_gtid_violating_transaction_count=%d",
4128 gtid_state->get_automatic_gtid_violating_transaction_count()));
4129 if (new_gtid_mode >= Gtid_mode::ON_PERMISSIVE &&
4130 gtid_state->get_automatic_gtid_violating_transaction_count() > 0) {
4131 my_error(ER_CANT_SET_GTID_MODE, MYF(0), "ON_PERMISSIVE",
4132 "there are ongoing transactions that use "
4133 "GTID_NEXT = 'AUTOMATIC', which violate GTID "
4134 "consistency. Adjust your workload to be "
4135 "GTID-consistent before setting "
4136 "@@GLOBAL.GTID_MODE = ON_PERMISSIVE. "
4137 "See the Manual for "
4138 "@@GLOBAL.ENFORCE_GTID_CONSISTENCY for details");
4139 goto err;
4140 }
4141
4142 // Compatible with ENFORCE_GTID_CONSISTENCY.
4143 if (new_gtid_mode == Gtid_mode::ON &&
4144 get_gtid_consistency_mode() != GTID_CONSISTENCY_MODE_ON) {
4145 my_error(ER_CANT_SET_GTID_MODE, MYF(0), "ON",
4146 "ENFORCE_GTID_CONSISTENCY is not ON");
4147 goto err;
4148 }
4149
4150 // Can't set GTID_MODE=OFF with ongoing calls to
4151 // WAIT_FOR_EXECUTED_GTID_SET or
4152 // WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS.
4153 DBUG_PRINT("info",
4154 ("gtid_wait_count=%d", gtid_state->get_gtid_wait_count() > 0));
4155 if (new_gtid_mode == Gtid_mode::OFF &&
4156 gtid_state->get_gtid_wait_count() > 0) {
4157 my_error(ER_CANT_SET_GTID_MODE, MYF(0), "OFF",
4158 "there are ongoing calls to "
4159 "WAIT_FOR_EXECUTED_GTID_SET or "
4160 "WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS. Before you set "
4161 "@@GLOBAL.GTID_MODE = OFF, ensure that no other "
4162 "client is waiting for GTID-transactions to be "
4163 "committed");
4164 goto err;
4165 }
4166
4167 // Update the mode
4168 global_var(ulong) = new_gtid_mode;
4169 global_gtid_mode.set(new_gtid_mode);
4170 global_sid_lock->unlock();
4171 lock_count = 3;
4172
4173 // Generate note in log
4174 LogErr(SYSTEM_LEVEL, ER_CHANGED_GTID_MODE,
4175 Gtid_mode::to_string(old_gtid_mode),
4176 Gtid_mode::to_string(new_gtid_mode));
4177
4178 // Rotate
4179 {
4180 bool dont_care = false;
4181 if (mysql_bin_log.rotate(true, &dont_care)) goto err;
4182 }
4183
4184 end:
4185 /* handle deprecations warning */
4186 issue_deprecation_warnings_gtid_mode(thd, old_gtid_mode, new_gtid_mode);
4187
4188 ret = false;
4189 err:
4190 DBUG_ASSERT(lock_count >= 0);
4191 DBUG_ASSERT(lock_count <= 4);
4192 if (lock_count == 4) global_sid_lock->unlock();
4193 mysql_mutex_unlock(mysql_bin_log.get_log_lock());
4194 channel_map.unlock();
4195 Gtid_mode::lock.unlock();
4196 return ret;
4197 }
4198
global_update(THD * thd,set_var * var)4199 bool Sys_var_enforce_gtid_consistency::global_update(THD *thd, set_var *var) {
4200 DBUG_TRACE;
4201 bool ret = true;
4202
4203 /*
4204 Hold global_sid_lock.wrlock so that other transactions cannot
4205 acquire ownership of any gtid.
4206 */
4207 global_sid_lock->wrlock();
4208
4209 DBUG_PRINT("info", ("var->save_result.ulonglong_value=%llu",
4210 var->save_result.ulonglong_value));
4211 enum_gtid_consistency_mode new_mode =
4212 (enum_gtid_consistency_mode)var->save_result.ulonglong_value;
4213 enum_gtid_consistency_mode old_mode = get_gtid_consistency_mode();
4214 auto gtid_mode = global_gtid_mode.get();
4215
4216 DBUG_ASSERT(new_mode <= GTID_CONSISTENCY_MODE_WARN);
4217
4218 DBUG_PRINT("info", ("old enforce_gtid_consistency=%d "
4219 "new enforce_gtid_consistency=%d "
4220 "gtid_mode=%d ",
4221 old_mode, new_mode, gtid_mode));
4222
4223 if (new_mode == old_mode) goto end;
4224
4225 // Can't turn off GTID-consistency when GTID_MODE=ON.
4226 if (new_mode != GTID_CONSISTENCY_MODE_ON && gtid_mode == Gtid_mode::ON) {
4227 my_error(ER_GTID_MODE_ON_REQUIRES_ENFORCE_GTID_CONSISTENCY_ON, MYF(0));
4228 goto err;
4229 }
4230 // If there are ongoing GTID-violating transactions, and we are
4231 // moving from OFF->ON, WARN->ON, or OFF->WARN, generate warning
4232 // or error accordingly.
4233 if (new_mode == GTID_CONSISTENCY_MODE_ON ||
4234 (old_mode == GTID_CONSISTENCY_MODE_OFF &&
4235 new_mode == GTID_CONSISTENCY_MODE_WARN)) {
4236 DBUG_PRINT("info",
4237 ("automatic_gtid_violating_transaction_count=%d "
4238 "anonymous_gtid_violating_transaction_count=%d",
4239 gtid_state->get_automatic_gtid_violating_transaction_count(),
4240 gtid_state->get_anonymous_gtid_violating_transaction_count()));
4241 if (gtid_state->get_automatic_gtid_violating_transaction_count() > 0 ||
4242 gtid_state->get_anonymous_gtid_violating_transaction_count() > 0) {
4243 if (new_mode == GTID_CONSISTENCY_MODE_ON) {
4244 my_error(
4245 ER_CANT_ENFORCE_GTID_CONSISTENCY_WITH_ONGOING_GTID_VIOLATING_TX,
4246 MYF(0));
4247 goto err;
4248 } else {
4249 push_warning(
4250 thd, Sql_condition::SL_WARNING,
4251 ER_ENFORCE_GTID_CONSISTENCY_WARN_WITH_ONGOING_GTID_VIOLATING_TX,
4252 ER_THD(
4253 thd,
4254 ER_ENFORCE_GTID_CONSISTENCY_WARN_WITH_ONGOING_GTID_VIOLATING_TX));
4255 }
4256 }
4257 }
4258
4259 // Update the mode
4260 global_var(ulong) = new_mode;
4261
4262 // Generate note in log
4263 LogErr(INFORMATION_LEVEL, ER_CHANGED_ENFORCE_GTID_CONSISTENCY,
4264 get_gtid_consistency_mode_string(old_mode),
4265 get_gtid_consistency_mode_string(new_mode));
4266
4267 end:
4268 ret = false;
4269 err:
4270 global_sid_lock->unlock();
4271 return ret;
4272 }
4273
4274 static Sys_var_enum_binlog_checksum Binlog_checksum_enum(
4275 "binlog_checksum",
4276 "Type of BINLOG_CHECKSUM_ALG. Include checksum for "
4277 "log events in the binary log. Possible values are NONE and CRC32; "
4278 "default is CRC32.",
4279 GLOBAL_VAR(binlog_checksum_options), CMD_LINE(REQUIRED_ARG),
4280 binlog_checksum_type_names, DEFAULT(binary_log::BINLOG_CHECKSUM_ALG_CRC32),
4281 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_outside_trx));
4282
4283 static Sys_var_bool Sys_master_verify_checksum(
4284 "master_verify_checksum",
4285 "Force checksum verification of logged events in binary log before "
4286 "sending them to slaves or printing them in output of SHOW BINLOG "
4287 "EVENTS. "
4288 "Disabled by default.",
4289 GLOBAL_VAR(opt_master_verify_checksum), CMD_LINE(OPT_ARG), DEFAULT(false));
4290
4291 static Sys_var_ulong Sys_slow_launch_time(
4292 "slow_launch_time",
4293 "If creating the thread takes longer than this value (in seconds), "
4294 "the Slow_launch_threads counter will be incremented",
4295 GLOBAL_VAR(slow_launch_time), CMD_LINE(REQUIRED_ARG),
4296 VALID_RANGE(0, LONG_TIMEOUT), DEFAULT(2), BLOCK_SIZE(1));
4297
4298 static Sys_var_ulong Sys_sort_buffer(
4299 "sort_buffer_size",
4300 "Each thread that needs to do a sort allocates a buffer of this size",
4301 HINT_UPDATEABLE SESSION_VAR(sortbuff_size), CMD_LINE(REQUIRED_ARG),
4302 VALID_RANGE(MIN_SORT_MEMORY, ULONG_MAX), DEFAULT(DEFAULT_SORT_MEMORY),
4303 BLOCK_SIZE(1));
4304
4305 /**
4306 Check sql modes strict_mode, 'NO_ZERO_DATE', 'NO_ZERO_IN_DATE' and
4307 'ERROR_FOR_DIVISION_BY_ZERO' are used together. If only subset of it
4308 is set then warning is reported.
4309
4310 @param sql_mode sql mode.
4311 @param thd Current thread
4312 */
check_sub_modes_of_strict_mode(sql_mode_t & sql_mode,THD * thd)4313 static void check_sub_modes_of_strict_mode(sql_mode_t &sql_mode, THD *thd) {
4314 const sql_mode_t strict_modes =
4315 (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES);
4316
4317 const sql_mode_t new_strict_submodes =
4318 (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
4319 MODE_ERROR_FOR_DIVISION_BY_ZERO);
4320
4321 const sql_mode_t strict_modes_set = (sql_mode & strict_modes);
4322 const sql_mode_t new_strict_submodes_set = (sql_mode & new_strict_submodes);
4323
4324 if (((strict_modes_set | new_strict_submodes_set) != 0) &&
4325 ((new_strict_submodes_set != new_strict_submodes) ||
4326 (strict_modes_set == 0))) {
4327 if (thd)
4328 push_warning(thd, Sql_condition::SL_WARNING, ER_SQL_MODE_MERGED,
4329 ER_THD(thd, ER_SQL_MODE_MERGED));
4330 else
4331 LogErr(WARNING_LEVEL, ER_SQL_MODE_MERGED_WITH_STRICT_MODE);
4332 }
4333 }
4334
expand_sql_mode(sql_mode_t sql_mode,THD * thd)4335 export sql_mode_t expand_sql_mode(sql_mode_t sql_mode, THD *thd) {
4336 if (sql_mode & MODE_ANSI) {
4337 /*
4338 Note that we dont set
4339 MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | MODE_NO_FIELD_OPTIONS
4340 to allow one to get full use of MySQL in this mode.
4341 */
4342 sql_mode |= (MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
4343 MODE_IGNORE_SPACE | MODE_ONLY_FULL_GROUP_BY);
4344 }
4345 if (sql_mode & MODE_TRADITIONAL)
4346 sql_mode |= (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES |
4347 MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
4348 MODE_ERROR_FOR_DIVISION_BY_ZERO | MODE_NO_ENGINE_SUBSTITUTION);
4349
4350 check_sub_modes_of_strict_mode(sql_mode, thd);
4351 return sql_mode;
4352 }
check_sql_mode(sys_var *,THD * thd,set_var * var)4353 static bool check_sql_mode(sys_var *, THD *thd, set_var *var) {
4354 sql_mode_t candidate_mode =
4355 expand_sql_mode(var->save_result.ulonglong_value, thd);
4356
4357 if (candidate_mode & ~(MODE_ALLOWED_MASK | MODE_IGNORED_MASK)) {
4358 my_error(ER_UNSUPPORTED_SQL_MODE, MYF(0),
4359 candidate_mode & ~(MODE_ALLOWED_MASK | MODE_IGNORED_MASK));
4360 return true; // mode seems never supported before
4361 }
4362
4363 if (candidate_mode & ~MODE_ALLOWED_MASK) {
4364 if (thd->variables.pseudo_slave_mode && // (1)
4365 thd->lex->sphead == nullptr) { // (2)
4366 /*
4367 (1): catch the auto-generated SET SQL_MODE calls in the output of
4368 mysqlbinlog,
4369 (2): but ignore the other ones (e.g. nested SET SQL_MODE calls in
4370 SBR-invoked trigger calls).
4371 */
4372 push_warning_printf(
4373 thd, Sql_condition::SL_WARNING, ER_WARN_REMOVED_SQL_MODE,
4374 ER_THD(thd, ER_WARN_REMOVED_SQL_MODE),
4375 static_cast<uint>(candidate_mode & ~MODE_ALLOWED_MASK));
4376 // ignore obsolete mode flags in case this is an old mysqlbinlog:
4377 candidate_mode &= MODE_ALLOWED_MASK;
4378 } else {
4379 my_error(ER_UNSUPPORTED_SQL_MODE, MYF(0),
4380 candidate_mode & ~MODE_ALLOWED_MASK);
4381 return true; // error on obsolete mode flags
4382 }
4383 }
4384
4385 if (candidate_mode & MODE_PAD_CHAR_TO_FULL_LENGTH) {
4386 push_warning_printf(
4387 thd, Sql_condition::SL_WARNING, ER_WARN_DEPRECATED_SQLMODE,
4388 ER_THD(thd, ER_WARN_DEPRECATED_SQLMODE), "PAD_CHAR_TO_FULL_LENGTH");
4389 }
4390
4391 var->save_result.ulonglong_value = candidate_mode;
4392 return false;
4393 }
fix_sql_mode(sys_var * self,THD * thd,enum_var_type type)4394 static bool fix_sql_mode(sys_var *self, THD *thd, enum_var_type type) {
4395 if (!self->is_global_persist(type)) {
4396 /* Update thd->server_status */
4397 if (thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)
4398 thd->server_status |= SERVER_STATUS_NO_BACKSLASH_ESCAPES;
4399 else
4400 thd->server_status &= ~SERVER_STATUS_NO_BACKSLASH_ESCAPES;
4401 }
4402 return false;
4403 }
4404 /*
4405 WARNING: When adding new SQL modes don't forget to update the
4406 tables definitions that stores it's value (ie: mysql.event, mysql.routines,
4407 mysql.triggers)
4408 */
4409 static const char *sql_mode_names[] = {"REAL_AS_FLOAT",
4410 "PIPES_AS_CONCAT",
4411 "ANSI_QUOTES",
4412 "IGNORE_SPACE",
4413 "NOT_USED",
4414 "ONLY_FULL_GROUP_BY",
4415 "NO_UNSIGNED_SUBTRACTION",
4416 "NO_DIR_IN_CREATE",
4417 "NOT_USED_9",
4418 "NOT_USED_10",
4419 "NOT_USED_11",
4420 "NOT_USED_12",
4421 "NOT_USED_13",
4422 "NOT_USED_14",
4423 "NOT_USED_15",
4424 "NOT_USED_16",
4425 "NOT_USED_17",
4426 "NOT_USED_18",
4427 "ANSI",
4428 "NO_AUTO_VALUE_ON_ZERO",
4429 "NO_BACKSLASH_ESCAPES",
4430 "STRICT_TRANS_TABLES",
4431 "STRICT_ALL_TABLES",
4432 "NO_ZERO_IN_DATE",
4433 "NO_ZERO_DATE",
4434 "ALLOW_INVALID_DATES",
4435 "ERROR_FOR_DIVISION_BY_ZERO",
4436 "TRADITIONAL",
4437 "NOT_USED_29",
4438 "HIGH_NOT_PRECEDENCE",
4439 "NO_ENGINE_SUBSTITUTION",
4440 "PAD_CHAR_TO_FULL_LENGTH",
4441 "TIME_TRUNCATE_FRACTIONAL",
4442 nullptr};
sql_mode_string_representation(THD * thd,sql_mode_t sql_mode,LEX_STRING * ls)4443 export bool sql_mode_string_representation(THD *thd, sql_mode_t sql_mode,
4444 LEX_STRING *ls) {
4445 set_to_string(thd, ls, sql_mode, sql_mode_names);
4446 return ls->str == nullptr;
4447 }
sql_mode_quoted_string_representation(THD * thd,sql_mode_t sql_mode,LEX_STRING * ls)4448 export bool sql_mode_quoted_string_representation(THD *thd, sql_mode_t sql_mode,
4449 LEX_STRING *ls) {
4450 set_to_string(thd, ls, sql_mode, sql_mode_names, true);
4451 return ls->str == nullptr;
4452 }
4453 /*
4454 sql_mode should *not* be IN_BINLOG: even though it is written to the binlog,
4455 the slave ignores the MODE_NO_DIR_IN_CREATE variable, so slave's value
4456 differs from master's (see log_event.cc: Query_log_event::do_apply_event()).
4457 */
4458 static Sys_var_set Sys_sql_mode(
4459 "sql_mode",
4460 "Syntax: sql-mode=mode[,mode[,mode...]]. See the manual for the "
4461 "complete list of valid sql modes",
4462 HINT_UPDATEABLE SESSION_VAR(sql_mode), CMD_LINE(REQUIRED_ARG),
4463 sql_mode_names,
4464 DEFAULT(MODE_NO_ENGINE_SUBSTITUTION | MODE_ONLY_FULL_GROUP_BY |
4465 MODE_STRICT_TRANS_TABLES | MODE_NO_ZERO_IN_DATE |
4466 MODE_NO_ZERO_DATE | MODE_ERROR_FOR_DIVISION_BY_ZERO),
4467 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_sql_mode),
4468 ON_UPDATE(fix_sql_mode));
4469
4470 static Sys_var_ulong Sys_max_execution_time(
4471 "max_execution_time",
4472 "Kill SELECT statement that takes over the specified number of "
4473 "milliseconds",
4474 HINT_UPDATEABLE SESSION_VAR(max_execution_time), CMD_LINE(REQUIRED_ARG),
4475 VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1));
4476
update_fips_mode(sys_var *,THD *,enum_var_type)4477 static bool update_fips_mode(sys_var *, THD *, enum_var_type) {
4478 char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
4479 if (set_fips_mode(opt_ssl_fips_mode, ssl_err_string) != 1) {
4480 opt_ssl_fips_mode = get_fips_mode();
4481 my_error(ER_SSL_FIPS_MODE_ERROR, MYF(0), "Openssl is not fips enabled");
4482 return true;
4483 } else {
4484 return false;
4485 }
4486 }
4487
4488 static const char *ssl_fips_mode_names[] = {"OFF", "ON", "STRICT", nullptr};
4489 static Sys_var_enum Sys_ssl_fips_mode(
4490 "ssl_fips_mode",
4491 "SSL FIPS mode (applies only for OpenSSL); "
4492 "permitted values are: OFF, ON, STRICT",
4493 GLOBAL_VAR(opt_ssl_fips_mode), CMD_LINE(REQUIRED_ARG, OPT_SSL_FIPS_MODE),
4494 ssl_fips_mode_names, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
4495 ON_CHECK(nullptr), ON_UPDATE(update_fips_mode), nullptr);
4496
4497 static Sys_var_bool Sys_auto_generate_certs(
4498 "auto_generate_certs",
4499 "Auto generate SSL certificates at server startup if --ssl is set to "
4500 "ON and none of the other SSL system variables are specified and "
4501 "certificate/key files are not present in data directory.",
4502 READ_ONLY NON_PERSIST GLOBAL_VAR(opt_auto_generate_certs),
4503 CMD_LINE(OPT_ARG), DEFAULT(true), NO_MUTEX_GUARD, NOT_IN_BINLOG,
4504 ON_CHECK(nullptr), ON_UPDATE(nullptr), nullptr);
4505
4506 // why ENUM and not BOOL ?
4507 static const char *updatable_views_with_limit_names[] = {"NO", "YES", nullptr};
4508 static Sys_var_enum Sys_updatable_views_with_limit(
4509 "updatable_views_with_limit",
4510 "YES = Don't issue an error message (warning only) if a VIEW without "
4511 "presence of a key of the underlying table is used in queries with a "
4512 "LIMIT clause for updating. NO = Prohibit update of a VIEW, which "
4513 "does not contain a key of the underlying table and the query uses "
4514 "a LIMIT clause (usually get from GUI tools)",
4515 HINT_UPDATEABLE SESSION_VAR(updatable_views_with_limit),
4516 CMD_LINE(REQUIRED_ARG), updatable_views_with_limit_names, DEFAULT(true));
4517
4518 static char *system_time_zone_ptr;
4519 static Sys_var_charptr Sys_system_time_zone(
4520 "system_time_zone", "The server system time zone",
4521 READ_ONLY NON_PERSIST GLOBAL_VAR(system_time_zone_ptr), NO_CMD_LINE,
4522 IN_FS_CHARSET, DEFAULT(system_time_zone));
4523
4524 static Sys_var_ulong Sys_table_def_size(
4525 "table_definition_cache", "The number of cached table definitions",
4526 GLOBAL_VAR(table_def_size),
4527 CMD_LINE(REQUIRED_ARG, OPT_TABLE_DEFINITION_CACHE),
4528 VALID_RANGE(TABLE_DEF_CACHE_MIN, 512 * 1024),
4529 DEFAULT(TABLE_DEF_CACHE_DEFAULT), BLOCK_SIZE(1), NO_MUTEX_GUARD,
4530 NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr), nullptr,
4531 /* table_definition_cache is used as a sizing hint by the performance
4532 schema. */
4533 sys_var::PARSE_EARLY);
4534
4535 static Sys_var_ulong Sys_schema_def_size(
4536 "schema_definition_cache", "The number of cached schema definitions",
4537 GLOBAL_VAR(schema_def_size), CMD_LINE(REQUIRED_ARG),
4538 VALID_RANGE(SCHEMA_DEF_CACHE_MIN, 512 * 1024),
4539 DEFAULT(SCHEMA_DEF_CACHE_DEFAULT), BLOCK_SIZE(1));
4540
4541 static Sys_var_ulong Sys_tablespace_def_size(
4542 "tablespace_definition_cache",
4543 "The number of cached tablespace definitions",
4544 GLOBAL_VAR(tablespace_def_size), CMD_LINE(REQUIRED_ARG),
4545 VALID_RANGE(TABLESPACE_DEF_CACHE_MIN, 512 * 1024),
4546 DEFAULT(TABLESPACE_DEF_CACHE_DEFAULT), BLOCK_SIZE(1));
4547
4548 static Sys_var_ulong Sys_stored_program_def_size(
4549 "stored_program_definition_cache",
4550 "The number of cached stored program definitions",
4551 GLOBAL_VAR(stored_program_def_size), CMD_LINE(REQUIRED_ARG),
4552 VALID_RANGE(STORED_PROGRAM_DEF_CACHE_MIN, 512 * 1024),
4553 DEFAULT(STORED_PROGRAM_DEF_CACHE_DEFAULT), BLOCK_SIZE(1));
4554
fix_table_cache_size(sys_var *,THD *,enum_var_type)4555 static bool fix_table_cache_size(sys_var *, THD *, enum_var_type) {
4556 /*
4557 table_open_cache parameter is a soft limit for total number of objects
4558 in all table cache instances. Once this value is updated we need to
4559 update value of a per-instance soft limit on table cache size.
4560 */
4561 table_cache_size_per_instance = table_cache_size / table_cache_instances;
4562 return false;
4563 }
4564
4565 static Sys_var_ulong Sys_table_cache_size(
4566 "table_open_cache",
4567 "The number of cached open tables "
4568 "(total for all table cache instances)",
4569 GLOBAL_VAR(table_cache_size), CMD_LINE(REQUIRED_ARG),
4570 VALID_RANGE(1, 512 * 1024), DEFAULT(TABLE_OPEN_CACHE_DEFAULT),
4571 BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
4572 ON_UPDATE(fix_table_cache_size), nullptr,
4573 /* table_open_cache is used as a sizing hint by the performance schema. */
4574 sys_var::PARSE_EARLY);
4575
4576 static Sys_var_ulong Sys_table_cache_instances(
4577 "table_open_cache_instances", "The number of table cache instances",
4578 READ_ONLY GLOBAL_VAR(table_cache_instances), CMD_LINE(REQUIRED_ARG),
4579 VALID_RANGE(1, Table_cache_manager::MAX_TABLE_CACHES),
4580 DEFAULT(Table_cache_manager::DEFAULT_MAX_TABLE_CACHES), BLOCK_SIZE(1),
4581 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr),
4582 nullptr,
4583 /*
4584 table_open_cache is used as a sizing hint by the performance schema,
4585 and 'table_open_cache' is a prefix of 'table_open_cache_instances'.
4586 Is is better to keep these options together, to avoid confusing
4587 handle_options() with partial name matches.
4588 */
4589 sys_var::PARSE_EARLY);
4590
4591 /**
4592 Modify the thread size cache size.
4593 */
4594
modify_thread_cache_size(sys_var *,THD *,enum_var_type)4595 static inline bool modify_thread_cache_size(sys_var *, THD *, enum_var_type) {
4596 if (Connection_handler_manager::thread_handling ==
4597 Connection_handler_manager::SCHEDULER_ONE_THREAD_PER_CONNECTION) {
4598 Per_thread_connection_handler::modify_thread_cache_size(
4599 Per_thread_connection_handler::max_blocked_pthreads);
4600 }
4601 return false;
4602 }
4603
4604 static Sys_var_ulong Sys_thread_cache_size(
4605 "thread_cache_size", "How many threads we should keep in a cache for reuse",
4606 GLOBAL_VAR(Per_thread_connection_handler::max_blocked_pthreads),
4607 CMD_LINE(REQUIRED_ARG, OPT_THREAD_CACHE_SIZE), VALID_RANGE(0, 16384),
4608 DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, nullptr,
4609 ON_UPDATE(modify_thread_cache_size));
4610
4611 /**
4612 Function to check if the 'next' transaction isolation level
4613 can be changed.
4614
4615 @param[in] thd Thread handler.
4616 @param[in] var A pointer to set_var holding the specified list of
4617 system variable names.
4618
4619 @retval false Success.
4620 @retval true Error.
4621 */
check_transaction_isolation(sys_var *,THD * thd,set_var * var)4622 static bool check_transaction_isolation(sys_var *, THD *thd, set_var *var) {
4623 if (var->type == OPT_DEFAULT &&
4624 (thd->in_active_multi_stmt_transaction() || thd->in_sub_stmt)) {
4625 DBUG_ASSERT(thd->in_multi_stmt_transaction_mode() || thd->in_sub_stmt);
4626 my_error(ER_CANT_CHANGE_TX_CHARACTERISTICS, MYF(0));
4627 return true;
4628 }
4629 return false;
4630 }
4631
4632 /**
4633 This function sets the session variable thd->variables.transaction_isolation
4634 to reflect changes to @@session.transaction_isolation.
4635
4636 @param[in] thd Thread handler.
4637 @param[in] var A pointer to the set_var.
4638
4639 @retval false Success.
4640 @retval true Error.
4641 */
session_update(THD * thd,set_var * var)4642 bool Sys_var_transaction_isolation::session_update(THD *thd, set_var *var) {
4643 if (var->type == OPT_SESSION && Sys_var_enum::session_update(thd, var))
4644 return true;
4645 if (var->type == OPT_DEFAULT ||
4646 !(thd->in_active_multi_stmt_transaction() || thd->in_sub_stmt)) {
4647 /*
4648 Update the isolation level of the next transaction.
4649 I.e. if one did:
4650 COMMIT;
4651 SET SESSION ISOLATION LEVEL ...
4652 BEGIN; <-- this transaction has the new isolation
4653 Note, that in case of:
4654 COMMIT;
4655 SET TRANSACTION ISOLATION LEVEL ...
4656 SET SESSION ISOLATION LEVEL ...
4657 BEGIN; <-- the session isolation level is used, not the
4658 result of SET TRANSACTION statement.
4659
4660 When we are in a trigger/function the transaction is already
4661 started. Adhering to above behavior, the SET TRANSACTION would
4662 fail when run from within trigger/function. And SET SESSION
4663 TRANSACTION would always succeed making the characteristics
4664 effective for the next transaction that starts.
4665 */
4666 enum_tx_isolation tx_isol;
4667 tx_isol = (enum_tx_isolation)var->save_result.ulonglong_value;
4668 bool one_shot = (var->type == OPT_DEFAULT);
4669 return set_tx_isolation(thd, tx_isol, one_shot);
4670 }
4671 return false;
4672 }
4673
4674 // NO_CMD_LINE
4675 static Sys_var_transaction_isolation Sys_transaction_isolation(
4676 "transaction_isolation", "Default transaction isolation level",
4677 UNTRACKED_DEFAULT SESSION_VAR(transaction_isolation), NO_CMD_LINE,
4678 tx_isolation_names, DEFAULT(ISO_REPEATABLE_READ), NO_MUTEX_GUARD,
4679 NOT_IN_BINLOG, ON_CHECK(check_transaction_isolation));
4680
4681 /**
4682 Function to check if the state of 'transaction_read_only' can be changed.
4683 The state cannot be changed if there is already a transaction in progress.
4684
4685 @param[in] thd Thread handler
4686 @param[in] var A pointer to set_var holding the specified list of
4687 system variable names.
4688
4689 @retval false Success.
4690 @retval true Error.
4691 */
check_transaction_read_only(sys_var *,THD * thd,set_var * var)4692 static bool check_transaction_read_only(sys_var *, THD *thd, set_var *var) {
4693 if (var->type == OPT_DEFAULT &&
4694 (thd->in_active_multi_stmt_transaction() || thd->in_sub_stmt)) {
4695 DBUG_ASSERT(thd->in_multi_stmt_transaction_mode() || thd->in_sub_stmt);
4696 my_error(ER_CANT_CHANGE_TX_CHARACTERISTICS, MYF(0));
4697 return true;
4698 }
4699 return false;
4700 }
4701
4702 /**
4703 This function sets the session variable thd->variables.transaction_read_only
4704 to reflect changes to @@session.transaction_read_only.
4705
4706 @param[in] thd Thread handler.
4707 @param[in] var A pointer to the set_var.
4708
4709 @retval false Success.
4710 */
session_update(THD * thd,set_var * var)4711 bool Sys_var_transaction_read_only::session_update(THD *thd, set_var *var) {
4712 if (var->type == OPT_SESSION && Sys_var_bool::session_update(thd, var))
4713 return true;
4714 if (var->type == OPT_DEFAULT ||
4715 !(thd->in_active_multi_stmt_transaction() || thd->in_sub_stmt)) {
4716 // @see Sys_var_transaction_isolation::session_update() above for the
4717 // rules.
4718 thd->tx_read_only = var->save_result.ulonglong_value;
4719
4720 if (thd->variables.session_track_transaction_info > TX_TRACK_NONE) {
4721 TX_TRACKER_GET(tst);
4722
4723 if (var->type == OPT_DEFAULT)
4724 tst->set_read_flags(thd,
4725 thd->tx_read_only ? TX_READ_ONLY : TX_READ_WRITE);
4726 else
4727 tst->set_read_flags(thd, TX_READ_INHERIT);
4728 }
4729 }
4730 return false;
4731 }
4732
4733 static Sys_var_transaction_read_only Sys_transaction_read_only(
4734 "transaction_read_only",
4735 "Set default transaction access mode to read only.",
4736 UNTRACKED_DEFAULT SESSION_VAR(transaction_read_only), NO_CMD_LINE,
4737 DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
4738 ON_CHECK(check_transaction_read_only));
4739
4740 static Sys_var_ulonglong Sys_tmp_table_size(
4741 "tmp_table_size",
4742 "If an internal in-memory temporary table in the MEMORY storage engine "
4743 "exceeds this size, MySQL will automatically convert it to an on-disk "
4744 "table",
4745 HINT_UPDATEABLE SESSION_VAR(tmp_table_size), CMD_LINE(REQUIRED_ARG),
4746 VALID_RANGE(1024, (ulonglong) ~(intptr)0), DEFAULT(16 * 1024 * 1024),
4747 BLOCK_SIZE(1));
4748
4749 static char *server_version_ptr;
4750 static Sys_var_version Sys_version(
4751 "version", "Server version",
4752 READ_ONLY NON_PERSIST GLOBAL_VAR(server_version_ptr), NO_CMD_LINE,
4753 IN_SYSTEM_CHARSET, DEFAULT(server_version));
4754
4755 static char *server_version_comment_ptr;
4756 static Sys_var_charptr Sys_version_comment(
4757 "version_comment", "version_comment",
4758 READ_ONLY NON_PERSIST GLOBAL_VAR(server_version_comment_ptr), NO_CMD_LINE,
4759 IN_SYSTEM_CHARSET, DEFAULT(MYSQL_COMPILATION_COMMENT_SERVER));
4760
4761 static char *server_version_compile_machine_ptr;
4762 static Sys_var_charptr Sys_version_compile_machine(
4763 "version_compile_machine", "version_compile_machine",
4764 READ_ONLY NON_PERSIST GLOBAL_VAR(server_version_compile_machine_ptr),
4765 NO_CMD_LINE, IN_SYSTEM_CHARSET, DEFAULT(MACHINE_TYPE));
4766
4767 static char *server_version_compile_os_ptr;
4768 static Sys_var_charptr Sys_version_compile_os(
4769 "version_compile_os", "version_compile_os",
4770 READ_ONLY NON_PERSIST GLOBAL_VAR(server_version_compile_os_ptr),
4771 NO_CMD_LINE, IN_SYSTEM_CHARSET, DEFAULT(SYSTEM_TYPE));
4772
4773 static const char *server_version_compile_zlib_ptr = ZLIB_VERSION;
4774 static Sys_var_charptr Sys_version_compile_zlib(
4775 "version_compile_zlib", "version_compile_zlib",
4776 READ_ONLY NON_PERSIST GLOBAL_VAR(server_version_compile_zlib_ptr),
4777 NO_CMD_LINE, IN_SYSTEM_CHARSET, DEFAULT(ZLIB_VERSION));
4778
4779 static Sys_var_ulong Sys_net_wait_timeout(
4780 "wait_timeout",
4781 "The number of seconds the server waits for activity on a "
4782 "connection before closing it",
4783 SESSION_VAR(net_wait_timeout), CMD_LINE(REQUIRED_ARG),
4784 VALID_RANGE(1, IF_WIN(INT_MAX32 / 1000, LONG_TIMEOUT)),
4785 DEFAULT(NET_WAIT_TIMEOUT), BLOCK_SIZE(1));
4786
4787 static Sys_var_plugin Sys_default_storage_engine(
4788 "default_storage_engine", "The default storage engine for new tables",
4789 SESSION_VAR(table_plugin), NO_CMD_LINE, MYSQL_STORAGE_ENGINE_PLUGIN,
4790 DEFAULT(&default_storage_engine), NO_MUTEX_GUARD, NOT_IN_BINLOG,
4791 ON_CHECK(check_storage_engine));
4792
4793 const char *internal_tmp_mem_storage_engine_names[] = {"MEMORY", "TempTable",
4794 nullptr};
4795 static Sys_var_enum Sys_internal_tmp_mem_storage_engine(
4796 "internal_tmp_mem_storage_engine",
4797 "The default storage engine for in-memory internal temporary tables.",
4798 HINT_UPDATEABLE SESSION_VAR(internal_tmp_mem_storage_engine),
4799 CMD_LINE(REQUIRED_ARG), internal_tmp_mem_storage_engine_names,
4800 DEFAULT(TMP_TABLE_TEMPTABLE));
4801
4802 static Sys_var_ulonglong Sys_temptable_max_ram(
4803 "temptable_max_ram",
4804 "Maximum amount of memory (in bytes) the TempTable storage engine is "
4805 "allowed to allocate from the main memory (RAM) before starting to "
4806 "store data on disk.",
4807 GLOBAL_VAR(temptable_max_ram), CMD_LINE(REQUIRED_ARG),
4808 VALID_RANGE(2 << 20 /* 2 MiB */, ULLONG_MAX), DEFAULT(1 << 30 /* 1 GiB */),
4809 BLOCK_SIZE(1));
4810
4811 static Sys_var_bool Sys_temptable_use_mmap("temptable_use_mmap",
4812 "Use mmap files for temptables",
4813 GLOBAL_VAR(temptable_use_mmap),
4814 CMD_LINE(OPT_ARG), DEFAULT(true));
4815
4816 static Sys_var_plugin Sys_default_tmp_storage_engine(
4817 "default_tmp_storage_engine",
4818 "The default storage engine for new explicit temporary tables",
4819 HINT_UPDATEABLE SESSION_VAR(temp_table_plugin), NO_CMD_LINE,
4820 MYSQL_STORAGE_ENGINE_PLUGIN, DEFAULT(&default_tmp_storage_engine),
4821 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_storage_engine));
4822
4823 #if defined(ENABLED_DEBUG_SYNC)
4824 /*
4825 Variable can be set for the session only.
4826
4827 This could be changed later. Then we need to have a global array of
4828 actions in addition to the thread local ones. SET GLOBAL would
4829 manage the global array, SET [SESSION] the local array. A sync point
4830 would need to look for a local and a global action. Setting and
4831 executing of global actions need to be protected by a mutex.
4832
4833 The purpose of global actions could be to allow synchronizing with
4834 connectionless threads that cannot execute SET statements.
4835 */
4836 static Sys_var_debug_sync Sys_debug_sync("debug_sync", "Debug Sync Facility",
4837 sys_var::ONLY_SESSION, NO_CMD_LINE,
4838 DEFAULT(nullptr), NO_MUTEX_GUARD,
4839 NOT_IN_BINLOG,
4840 ON_CHECK(check_session_admin));
4841 #endif /* defined(ENABLED_DEBUG_SYNC) */
4842
fix_autocommit(sys_var * self,THD * thd,enum_var_type type)4843 static bool fix_autocommit(sys_var *self, THD *thd, enum_var_type type) {
4844 if (self->is_global_persist(type)) {
4845 if (global_system_variables.option_bits & OPTION_AUTOCOMMIT)
4846 global_system_variables.option_bits &= ~OPTION_NOT_AUTOCOMMIT;
4847 else
4848 global_system_variables.option_bits |= OPTION_NOT_AUTOCOMMIT;
4849 return false;
4850 }
4851
4852 if (thd->variables.option_bits & OPTION_AUTOCOMMIT &&
4853 thd->variables.option_bits &
4854 OPTION_NOT_AUTOCOMMIT) { // activating autocommit
4855
4856 if (trans_commit_stmt(thd) || trans_commit(thd)) {
4857 thd->variables.option_bits &= ~OPTION_AUTOCOMMIT;
4858 return true;
4859 }
4860 /*
4861 Don't close thread tables or release metadata locks: if we do so, we
4862 risk releasing locks/closing tables of expressions used to assign
4863 other variables, as in:
4864 set @var=my_stored_function1(), @@autocommit=1, @var2=(select max(a)
4865 from my_table), ...
4866 The locks will be released at statement end anyway, as SET
4867 statement that assigns autocommit is marked to commit
4868 transaction implicitly at the end (@sa stmt_causes_implicitcommit()).
4869 */
4870 thd->variables.option_bits &= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
4871 thd->get_transaction()->reset_unsafe_rollback_flags(
4872 Transaction_ctx::SESSION);
4873 thd->server_status |= SERVER_STATUS_AUTOCOMMIT;
4874 return false;
4875 }
4876
4877 if (!(thd->variables.option_bits & OPTION_AUTOCOMMIT) &&
4878 !(thd->variables.option_bits &
4879 OPTION_NOT_AUTOCOMMIT)) { // disabling autocommit
4880
4881 thd->get_transaction()->reset_unsafe_rollback_flags(
4882 Transaction_ctx::SESSION);
4883 thd->server_status &= ~SERVER_STATUS_AUTOCOMMIT;
4884 thd->variables.option_bits |= OPTION_NOT_AUTOCOMMIT;
4885 return false;
4886 }
4887
4888 return false; // autocommit value wasn't changed
4889 }
4890 static Sys_var_bit Sys_autocommit("autocommit", "autocommit",
4891 SESSION_VAR(option_bits), NO_CMD_LINE,
4892 OPTION_AUTOCOMMIT, DEFAULT(true),
4893 NO_MUTEX_GUARD, NOT_IN_BINLOG,
4894 ON_CHECK(nullptr), ON_UPDATE(fix_autocommit));
4895 export sys_var *Sys_autocommit_ptr = &Sys_autocommit; // for sql_yacc.yy
4896
4897 static Sys_var_bool Sys_big_tables(
4898 "big_tables",
4899 "Allow big result sets by saving all "
4900 "temporary sets on file (Solves most 'table full' errors)",
4901 HINT_UPDATEABLE SESSION_VAR(big_tables), CMD_LINE(OPT_ARG), DEFAULT(false));
4902
4903 static Sys_var_bit Sys_big_selects("sql_big_selects", "sql_big_selects",
4904 HINT_UPDATEABLE SESSION_VAR(option_bits),
4905 NO_CMD_LINE, OPTION_BIG_SELECTS,
4906 DEFAULT(false));
4907
4908 static Sys_var_bit Sys_log_off("sql_log_off", "sql_log_off",
4909 SESSION_VAR(option_bits), NO_CMD_LINE,
4910 OPTION_LOG_OFF, DEFAULT(false), NO_MUTEX_GUARD,
4911 NOT_IN_BINLOG, ON_CHECK(check_session_admin));
4912
4913 /**
4914 This function sets the session variable thd->variables.sql_log_bin
4915 to reflect changes to @@session.sql_log_bin.
4916
4917 @param thd Current thread
4918 @param[in] type The type either session or global.
4919
4920 @return @c false.
4921 */
fix_sql_log_bin_after_update(sys_var *,THD * thd,enum_var_type type MY_ATTRIBUTE ((unused)))4922 static bool fix_sql_log_bin_after_update(
4923 sys_var *, THD *thd, enum_var_type type MY_ATTRIBUTE((unused))) {
4924 DBUG_ASSERT(type == OPT_SESSION);
4925
4926 if (thd->variables.sql_log_bin)
4927 thd->variables.option_bits |= OPTION_BIN_LOG;
4928 else
4929 thd->variables.option_bits &= ~OPTION_BIN_LOG;
4930
4931 return false;
4932 }
4933
4934 /**
4935 This function checks if the sql_log_bin can be changed,
4936 what is possible if:
4937 - the user is a super user;
4938 - the set is not called from within a function/trigger;
4939 - there is no on-going transaction.
4940
4941 @param thd Current thread
4942 @param[in] self A pointer to the sys_var, i.e. Sys_log_binlog.
4943 @param[in] var A pointer to the set_var created by the parser.
4944
4945 @return @c false if the change is allowed, otherwise @c true.
4946 */
check_sql_log_bin(sys_var * self,THD * thd,set_var * var)4947 static bool check_sql_log_bin(sys_var *self, THD *thd, set_var *var) {
4948 if (check_session_admin(self, thd, var)) return true;
4949
4950 if (var->is_global_persist()) return true;
4951
4952 /* If in a stored function/trigger, it's too late to change sql_log_bin. */
4953 if (thd->in_sub_stmt) {
4954 my_error(ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN, MYF(0));
4955 return true;
4956 }
4957 /* Make the session variable 'sql_log_bin' read-only inside a transaction.
4958 */
4959 if (thd->in_active_multi_stmt_transaction()) {
4960 my_error(ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SQL_LOG_BIN, MYF(0));
4961 return true;
4962 }
4963
4964 return false;
4965 }
4966
4967 static Sys_var_bool Sys_log_binlog(
4968 "sql_log_bin", "Controls whether logging to the binary log is done",
4969 SESSION_ONLY(sql_log_bin), NO_CMD_LINE, DEFAULT(true), NO_MUTEX_GUARD,
4970 NOT_IN_BINLOG, ON_CHECK(check_sql_log_bin),
4971 ON_UPDATE(fix_sql_log_bin_after_update));
4972
4973 static Sys_var_bit Sys_transaction_allow_batching(
4974 "transaction_allow_batching", "transaction_allow_batching",
4975 SESSION_ONLY(option_bits), NO_CMD_LINE, OPTION_ALLOW_BATCH, DEFAULT(false));
4976
4977 static Sys_var_bit Sys_sql_warnings("sql_warnings", "sql_warnings",
4978 SESSION_VAR(option_bits), NO_CMD_LINE,
4979 OPTION_WARNINGS, DEFAULT(false));
4980
4981 static Sys_var_bit Sys_sql_notes("sql_notes", "sql_notes",
4982 SESSION_VAR(option_bits), NO_CMD_LINE,
4983 OPTION_SQL_NOTES, DEFAULT(true));
4984
4985 static Sys_var_bit Sys_auto_is_null("sql_auto_is_null", "sql_auto_is_null",
4986 HINT_UPDATEABLE SESSION_VAR(option_bits),
4987 NO_CMD_LINE, OPTION_AUTO_IS_NULL,
4988 DEFAULT(false), NO_MUTEX_GUARD, IN_BINLOG);
4989
4990 static Sys_var_bit Sys_safe_updates("sql_safe_updates", "sql_safe_updates",
4991 HINT_UPDATEABLE SESSION_VAR(option_bits),
4992 NO_CMD_LINE, OPTION_SAFE_UPDATES,
4993 DEFAULT(false));
4994
4995 static Sys_var_bit Sys_buffer_results("sql_buffer_result", "sql_buffer_result",
4996 HINT_UPDATEABLE SESSION_VAR(option_bits),
4997 NO_CMD_LINE, OPTION_BUFFER_RESULT,
4998 DEFAULT(false));
4999
5000 static Sys_var_bit Sys_quote_show_create("sql_quote_show_create",
5001 "sql_quote_show_create",
5002 SESSION_VAR(option_bits), NO_CMD_LINE,
5003 OPTION_QUOTE_SHOW_CREATE,
5004 DEFAULT(true));
5005
5006 static Sys_var_bit Sys_foreign_key_checks(
5007 "foreign_key_checks", "foreign_key_checks",
5008 HINT_UPDATEABLE SESSION_VAR(option_bits), NO_CMD_LINE,
5009 REVERSE(OPTION_NO_FOREIGN_KEY_CHECKS), DEFAULT(true), NO_MUTEX_GUARD,
5010 IN_BINLOG);
5011
5012 static Sys_var_bit Sys_unique_checks("unique_checks", "unique_checks",
5013 HINT_UPDATEABLE SESSION_VAR(option_bits),
5014 NO_CMD_LINE,
5015 REVERSE(OPTION_RELAXED_UNIQUE_CHECKS),
5016 DEFAULT(true), NO_MUTEX_GUARD, IN_BINLOG);
5017
5018 #ifdef ENABLED_PROFILING
5019 static Sys_var_bit Sys_profiling("profiling", "profiling",
5020 SESSION_VAR(option_bits), NO_CMD_LINE,
5021 OPTION_PROFILING, DEFAULT(false),
5022 NO_MUTEX_GUARD, NOT_IN_BINLOG,
5023 ON_CHECK(nullptr), ON_UPDATE(nullptr),
5024 DEPRECATED_VAR(""));
5025
5026 static Sys_var_ulong Sys_profiling_history_size(
5027 "profiling_history_size", "Limit of query profiling memory",
5028 SESSION_VAR(profiling_history_size), CMD_LINE(REQUIRED_ARG),
5029 VALID_RANGE(0, 100), DEFAULT(15), BLOCK_SIZE(1), NO_MUTEX_GUARD,
5030 NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr), DEPRECATED_VAR(""));
5031 #endif
5032
5033 static Sys_var_harows Sys_select_limit(
5034 "sql_select_limit",
5035 "The maximum number of rows to return from SELECT statements",
5036 HINT_UPDATEABLE SESSION_VAR(select_limit), NO_CMD_LINE,
5037 VALID_RANGE(0, HA_POS_ERROR), DEFAULT(HA_POS_ERROR), BLOCK_SIZE(1));
5038
update_timestamp(THD * thd,set_var * var)5039 static bool update_timestamp(THD *thd, set_var *var) {
5040 if (var->value) {
5041 double intpart;
5042 double fractpart = modf(var->save_result.double_value, &intpart);
5043 double micros = fractpart * 1000000.0;
5044 // Double multiplication, and conversion to integral may yield
5045 // 1000000 rather than 999999.
5046 struct timeval tmp;
5047 tmp.tv_sec = llrint(intpart);
5048 tmp.tv_usec = std::min(llrint(micros), 999999LL);
5049 thd->set_time(&tmp);
5050 } else // SET timestamp=DEFAULT
5051 {
5052 thd->user_time.tv_sec = 0;
5053 thd->user_time.tv_usec = 0;
5054 }
5055 return false;
5056 }
read_timestamp(THD * thd)5057 static double read_timestamp(THD *thd) {
5058 return (double)thd->start_time.tv_sec +
5059 (double)thd->start_time.tv_usec / 1000000;
5060 }
5061
check_timestamp(sys_var *,THD *,set_var * var)5062 static bool check_timestamp(sys_var *, THD *, set_var *var) {
5063 double val;
5064
5065 if (!var->value) return false;
5066
5067 val = var->save_result.double_value;
5068 if (val != 0 && // this is how you set the default value
5069 (val < TIMESTAMP_MIN_VALUE || val > TIMESTAMP_MAX_VALUE)) {
5070 ErrConvString prm(val);
5071 my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "timestamp", prm.ptr());
5072 return true;
5073 }
5074 return false;
5075 }
5076
5077 static Sys_var_session_special_double Sys_timestamp(
5078 "timestamp", "Set the time for this client",
5079 HINT_UPDATEABLE sys_var::ONLY_SESSION, NO_CMD_LINE, VALID_RANGE(0, 0),
5080 BLOCK_SIZE(1), NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_timestamp),
5081 ON_UPDATE(update_timestamp), ON_READ(read_timestamp));
5082
update_last_insert_id(THD * thd,set_var * var)5083 static bool update_last_insert_id(THD *thd, set_var *var) {
5084 if (!var->value) {
5085 my_error(ER_NO_DEFAULT, MYF(0), var->var->name.str);
5086 return true;
5087 }
5088 thd->first_successful_insert_id_in_prev_stmt =
5089 var->save_result.ulonglong_value;
5090 return false;
5091 }
read_last_insert_id(THD * thd)5092 static ulonglong read_last_insert_id(THD *thd) {
5093 return thd->read_first_successful_insert_id_in_prev_stmt();
5094 }
5095 static Sys_var_session_special Sys_last_insert_id(
5096 "last_insert_id", "The value to be returned from LAST_INSERT_ID()",
5097 sys_var::ONLY_SESSION, NO_CMD_LINE, VALID_RANGE(0, ULLONG_MAX),
5098 BLOCK_SIZE(1), NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(nullptr),
5099 ON_UPDATE(update_last_insert_id), ON_READ(read_last_insert_id));
5100
5101 // alias for last_insert_id(), Sybase-style
5102 static Sys_var_session_special Sys_identity(
5103 "identity", "Synonym for the last_insert_id variable",
5104 sys_var::ONLY_SESSION, NO_CMD_LINE, VALID_RANGE(0, ULLONG_MAX),
5105 BLOCK_SIZE(1), NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(nullptr),
5106 ON_UPDATE(update_last_insert_id), ON_READ(read_last_insert_id));
5107
5108 /*
5109 insert_id should *not* be marked as written to the binlog (i.e., it
5110 should *not* be IN_BINLOG), because we want any statement that
5111 refers to insert_id explicitly to be unsafe. (By "explicitly", we
5112 mean using @@session.insert_id, whereas insert_id is used
5113 "implicitly" when NULL value is inserted into an auto_increment
5114 column).
5115
5116 We want statements referring explicitly to @@session.insert_id to be
5117 unsafe, because insert_id is modified internally by the slave sql
5118 thread when NULL values are inserted in an AUTO_INCREMENT column.
5119 This modification interfers with the value of the
5120 @@session.insert_id variable if @@session.insert_id is referred
5121 explicitly by an insert statement (as is seen by executing "SET
5122 @@session.insert_id=0; CREATE TABLE t (a INT, b INT KEY
5123 AUTO_INCREMENT); INSERT INTO t(a) VALUES (@@session.insert_id);" in
5124 statement-based logging mode: t will be different on master and
5125 slave).
5126 */
update_insert_id(THD * thd,set_var * var)5127 static bool update_insert_id(THD *thd, set_var *var) {
5128 if (!var->value) {
5129 my_error(ER_NO_DEFAULT, MYF(0), var->var->name.str);
5130 return true;
5131 }
5132 thd->force_one_auto_inc_interval(var->save_result.ulonglong_value);
5133 return false;
5134 }
5135
read_insert_id(THD * thd)5136 static ulonglong read_insert_id(THD *thd) {
5137 return thd->auto_inc_intervals_forced.minimum();
5138 }
5139 static Sys_var_session_special Sys_insert_id(
5140 "insert_id",
5141 "The value to be used by the following INSERT "
5142 "or ALTER TABLE statement when inserting an AUTO_INCREMENT value",
5143 HINT_UPDATEABLE sys_var::ONLY_SESSION, NO_CMD_LINE,
5144 VALID_RANGE(0, ULLONG_MAX), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG,
5145 ON_CHECK(nullptr), ON_UPDATE(update_insert_id), ON_READ(read_insert_id));
5146
update_rand_seed1(THD * thd,set_var * var)5147 static bool update_rand_seed1(THD *thd, set_var *var) {
5148 if (!var->value) {
5149 my_error(ER_NO_DEFAULT, MYF(0), var->var->name.str);
5150 return true;
5151 }
5152 thd->rand.seed1 = (ulong)var->save_result.ulonglong_value;
5153 return false;
5154 }
read_rand_seed(THD *)5155 static ulonglong read_rand_seed(THD *) { return 0; }
5156 static Sys_var_session_special Sys_rand_seed1(
5157 "rand_seed1",
5158 "Sets the internal state of the RAND() "
5159 "generator for replication purposes",
5160 sys_var::ONLY_SESSION, NO_CMD_LINE, VALID_RANGE(0, ULONG_MAX),
5161 BLOCK_SIZE(1), NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(nullptr),
5162 ON_UPDATE(update_rand_seed1), ON_READ(read_rand_seed));
5163
update_rand_seed2(THD * thd,set_var * var)5164 static bool update_rand_seed2(THD *thd, set_var *var) {
5165 if (!var->value) {
5166 my_error(ER_NO_DEFAULT, MYF(0), var->var->name.str);
5167 return true;
5168 }
5169 thd->rand.seed2 = (ulong)var->save_result.ulonglong_value;
5170 return false;
5171 }
5172 static Sys_var_session_special Sys_rand_seed2(
5173 "rand_seed2",
5174 "Sets the internal state of the RAND() "
5175 "generator for replication purposes",
5176 sys_var::ONLY_SESSION, NO_CMD_LINE, VALID_RANGE(0, ULONG_MAX),
5177 BLOCK_SIZE(1), NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(nullptr),
5178 ON_UPDATE(update_rand_seed2), ON_READ(read_rand_seed));
5179
read_error_count(THD * thd)5180 static ulonglong read_error_count(THD *thd) {
5181 return thd->get_stmt_da()->error_count(thd);
5182 }
5183 // this really belongs to the SHOW STATUS
5184 static Sys_var_session_special Sys_error_count(
5185 "error_count",
5186 "The number of errors that resulted from the "
5187 "last statement that generated messages",
5188 READ_ONLY sys_var::ONLY_SESSION, NO_CMD_LINE, VALID_RANGE(0, ULLONG_MAX),
5189 BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
5190 ON_UPDATE(nullptr), ON_READ(read_error_count));
5191
read_warning_count(THD * thd)5192 static ulonglong read_warning_count(THD *thd) {
5193 return thd->get_stmt_da()->warn_count(thd);
5194 }
5195 // this really belongs to the SHOW STATUS
5196 static Sys_var_session_special Sys_warning_count(
5197 "warning_count",
5198 "The number of errors, warnings, and notes "
5199 "that resulted from the last statement that generated messages",
5200 READ_ONLY sys_var::ONLY_SESSION, NO_CMD_LINE, VALID_RANGE(0, ULLONG_MAX),
5201 BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
5202 ON_UPDATE(nullptr), ON_READ(read_warning_count));
5203
5204 static Sys_var_ulong Sys_default_week_format(
5205 "default_week_format", "The default week format used by WEEK() functions",
5206 SESSION_VAR(default_week_format), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 7),
5207 DEFAULT(0), BLOCK_SIZE(1));
5208
5209 static Sys_var_ulong Sys_group_concat_max_len(
5210 "group_concat_max_len",
5211 "The maximum length of the result of function GROUP_CONCAT()",
5212 HINT_UPDATEABLE SESSION_VAR(group_concat_max_len), CMD_LINE(REQUIRED_ARG),
5213 VALID_RANGE(4, ULONG_MAX), DEFAULT(1024), BLOCK_SIZE(1));
5214
5215 static char *glob_hostname_ptr;
5216 static Sys_var_charptr Sys_hostname(
5217 "hostname", "Server host name",
5218 READ_ONLY NON_PERSIST GLOBAL_VAR(glob_hostname_ptr), NO_CMD_LINE,
5219 IN_FS_CHARSET, DEFAULT(glob_hostname));
5220
5221 static Sys_var_charptr Sys_repl_report_host(
5222 "report_host",
5223 "Hostname or IP of the slave to be reported to the master during "
5224 "slave registration. Will appear in the output of SHOW SLAVE HOSTS. "
5225 "Leave unset if you do not want the slave to register itself with the "
5226 "master. Note that it is not sufficient for the master to simply read "
5227 "the IP of the slave off the socket once the slave connects. Due to "
5228 "NAT and other routing issues, that IP may not be valid for connecting "
5229 "to the slave from the master or other hosts",
5230 READ_ONLY GLOBAL_VAR(report_host), CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET,
5231 DEFAULT(nullptr));
5232
5233 static Sys_var_charptr Sys_repl_report_user(
5234 "report_user",
5235 "The account user name of the slave to be reported to the master "
5236 "during slave registration",
5237 READ_ONLY GLOBAL_VAR(report_user), CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET,
5238 DEFAULT(nullptr));
5239
5240 static Sys_var_charptr Sys_repl_report_password(
5241 "report_password",
5242 "The account password of the slave to be reported to the master "
5243 "during slave registration",
5244 READ_ONLY GLOBAL_VAR(report_password), CMD_LINE(REQUIRED_ARG),
5245 IN_FS_CHARSET, DEFAULT(nullptr));
5246
5247 static Sys_var_uint Sys_repl_report_port(
5248 "report_port",
5249 "Port for connecting to slave reported to the master during slave "
5250 "registration. Set it only if the slave is listening on a non-default "
5251 "port or if you have a special tunnel from the master or other clients "
5252 "to the slave. If not sure, leave this option unset",
5253 READ_ONLY GLOBAL_VAR(report_port), CMD_LINE(REQUIRED_ARG),
5254 VALID_RANGE(0, 65535), DEFAULT(0), BLOCK_SIZE(1));
5255
5256 static Sys_var_bool Sys_keep_files_on_create(
5257 "keep_files_on_create",
5258 "Don't overwrite stale .MYD and .MYI even if no directory is specified",
5259 SESSION_VAR(keep_files_on_create), CMD_LINE(OPT_ARG), DEFAULT(false));
5260
5261 static char *license;
5262 static Sys_var_charptr Sys_license("license",
5263 "The type of license the server has",
5264 READ_ONLY NON_PERSIST GLOBAL_VAR(license),
5265 NO_CMD_LINE, IN_SYSTEM_CHARSET,
5266 DEFAULT(STRINGIFY_ARG(LICENSE)));
5267
check_log_path(sys_var * self,THD *,set_var * var)5268 static bool check_log_path(sys_var *self, THD *, set_var *var) {
5269 if (!var->value) return false; // DEFAULT is ok
5270
5271 if (!var->save_result.string_value.str) return true;
5272
5273 if (!is_valid_log_name(var->save_result.string_value.str,
5274 var->save_result.string_value.length)) {
5275 my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), self->name.str,
5276 var->save_result.string_value.str);
5277 return true;
5278 }
5279
5280 if (var->save_result.string_value.length > FN_REFLEN) { // path is too long
5281 my_error(ER_PATH_LENGTH, MYF(0), self->name.str);
5282 return true;
5283 }
5284
5285 char path[FN_REFLEN];
5286 size_t path_length = unpack_filename(path, var->save_result.string_value.str);
5287
5288 if (!path_length) return true;
5289
5290 if (!is_filename_allowed(var->save_result.string_value.str,
5291 var->save_result.string_value.length, true)) {
5292 my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), self->name.str,
5293 var->save_result.string_value.str);
5294 return true;
5295 }
5296
5297 MY_STAT f_stat;
5298
5299 if (my_stat(path, &f_stat, MYF(0))) {
5300 if (!MY_S_ISREG(f_stat.st_mode) || !(f_stat.st_mode & MY_S_IWRITE))
5301 return true; // not a regular writable file
5302 return false;
5303 }
5304
5305 (void)dirname_part(path, var->save_result.string_value.str, &path_length);
5306
5307 if (var->save_result.string_value.length - path_length >=
5308 FN_LEN) { // filename is too long
5309 my_error(ER_PATH_LENGTH, MYF(0), self->name.str);
5310 return true;
5311 }
5312
5313 if (!path_length) // no path is good path (remember, relative to datadir)
5314 return false;
5315
5316 if (my_access(path, (F_OK | W_OK))) return true; // directory is not writable
5317
5318 return false;
5319 }
5320
fix_general_log_file(sys_var *,THD *,enum_var_type)5321 static bool fix_general_log_file(sys_var *, THD *, enum_var_type) {
5322 bool res;
5323
5324 if (!opt_general_logname) // SET ... = DEFAULT
5325 {
5326 char buff[FN_REFLEN];
5327 opt_general_logname = my_strdup(
5328 key_memory_LOG_name, make_query_log_name(buff, QUERY_LOG_GENERAL),
5329 MYF(MY_FAE + MY_WME));
5330 if (!opt_general_logname) return true;
5331 }
5332
5333 res = query_logger.set_log_file(QUERY_LOG_GENERAL);
5334
5335 if (opt_general_log) {
5336 mysql_mutex_unlock(&LOCK_global_system_variables);
5337
5338 if (!res)
5339 res = query_logger.reopen_log_file(QUERY_LOG_GENERAL);
5340 else
5341 query_logger.deactivate_log_handler(QUERY_LOG_GENERAL);
5342
5343 mysql_mutex_lock(&LOCK_global_system_variables);
5344 }
5345
5346 if (res) opt_general_log = false;
5347
5348 return res;
5349 }
5350
5351 static Sys_var_charptr Sys_general_log_path(
5352 "general_log_file", "Log connections and queries to given file",
5353 GLOBAL_VAR(opt_general_logname), CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET,
5354 DEFAULT(nullptr), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_log_path),
5355 ON_UPDATE(fix_general_log_file));
5356
fix_slow_log_file(sys_var *,THD * thd MY_ATTRIBUTE ((unused)),enum_var_type)5357 static bool fix_slow_log_file(sys_var *, THD *thd MY_ATTRIBUTE((unused)),
5358 enum_var_type) {
5359 bool res;
5360
5361 DEBUG_SYNC(thd, "log_fix_slow_log_holds_sysvar_lock");
5362
5363 if (!opt_slow_logname) // SET ... = DEFAULT
5364 {
5365 char buff[FN_REFLEN];
5366 opt_slow_logname = my_strdup(key_memory_LOG_name,
5367 make_query_log_name(buff, QUERY_LOG_SLOW),
5368 MYF(MY_FAE + MY_WME));
5369 if (!opt_slow_logname) return true;
5370 }
5371
5372 res = query_logger.set_log_file(QUERY_LOG_SLOW);
5373
5374 DEBUG_SYNC(thd, "log_fix_slow_log_released_logger_lock");
5375
5376 if (opt_slow_log) {
5377 mysql_mutex_unlock(&LOCK_global_system_variables);
5378
5379 DEBUG_SYNC(thd, "log_fix_slow_log_released_sysvar_lock");
5380
5381 if (!res)
5382 res = query_logger.reopen_log_file(QUERY_LOG_SLOW);
5383 else
5384 query_logger.deactivate_log_handler(QUERY_LOG_SLOW);
5385
5386 mysql_mutex_lock(&LOCK_global_system_variables);
5387 }
5388
5389 if (res) opt_slow_log = false;
5390
5391 return res;
5392 }
5393 static Sys_var_charptr Sys_slow_log_path(
5394 "slow_query_log_file",
5395 "Log slow queries to given log file. "
5396 "Defaults logging to hostname-slow.log. Must be enabled to activate "
5397 "other slow log options",
5398 GLOBAL_VAR(opt_slow_logname), CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET,
5399 DEFAULT(nullptr), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_log_path),
5400 ON_UPDATE(fix_slow_log_file));
5401
5402 static Sys_var_have Sys_have_compress(
5403 "have_compress", "have_compress",
5404 READ_ONLY NON_PERSIST GLOBAL_VAR(have_compress), NO_CMD_LINE);
5405
5406 static Sys_var_have Sys_have_dlopen(
5407 "have_dynamic_loading", "have_dynamic_loading",
5408 READ_ONLY NON_PERSIST GLOBAL_VAR(have_dlopen), NO_CMD_LINE);
5409
5410 static Sys_var_have Sys_have_geometry(
5411 "have_geometry", "have_geometry",
5412 READ_ONLY NON_PERSIST GLOBAL_VAR(have_geometry), NO_CMD_LINE);
5413
have_ssl_func(THD * thd MY_ATTRIBUTE ((unused)))5414 static SHOW_COMP_OPTION have_ssl_func(THD *thd MY_ATTRIBUTE((unused))) {
5415 return have_ssl() ? SHOW_OPTION_YES : SHOW_OPTION_DISABLED;
5416 }
5417
5418 enum SHOW_COMP_OPTION Sys_var_have_func::dummy_;
5419
5420 static Sys_var_have_func Sys_have_openssl("have_openssl", "have_openssl",
5421 have_ssl_func);
5422
5423 static Sys_var_have Sys_have_profiling(
5424 "have_profiling", "have_profiling",
5425 READ_ONLY NON_PERSIST GLOBAL_VAR(have_profiling), NO_CMD_LINE,
5426 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr),
5427 DEPRECATED_VAR(""));
5428
5429 static Sys_var_have Sys_have_query_cache(
5430 "have_query_cache",
5431 "have_query_cache. "
5432 "This variable is deprecated and will be removed in a future release.",
5433 READ_ONLY NON_PERSIST GLOBAL_VAR(have_query_cache), NO_CMD_LINE,
5434 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr),
5435 DEPRECATED_VAR(""));
5436
5437 static Sys_var_have Sys_have_rtree_keys(
5438 "have_rtree_keys", "have_rtree_keys",
5439 READ_ONLY NON_PERSIST GLOBAL_VAR(have_rtree_keys), NO_CMD_LINE);
5440
5441 static Sys_var_have_func Sys_have_ssl("have_ssl", "have_ssl", have_ssl_func);
5442
5443 static Sys_var_have Sys_have_symlink(
5444 "have_symlink", "have_symlink",
5445 READ_ONLY NON_PERSIST GLOBAL_VAR(have_symlink), NO_CMD_LINE);
5446
5447 static Sys_var_have Sys_have_statement_timeout(
5448 "have_statement_timeout", "have_statement_timeout",
5449 READ_ONLY NON_PERSIST GLOBAL_VAR(have_statement_timeout), NO_CMD_LINE);
5450
fix_general_log_state(sys_var *,THD * thd,enum_var_type)5451 static bool fix_general_log_state(sys_var *, THD *thd, enum_var_type) {
5452 bool new_state = opt_general_log, res = false;
5453
5454 if (query_logger.is_log_file_enabled(QUERY_LOG_GENERAL) == new_state)
5455 return false;
5456
5457 mysql_mutex_unlock(&LOCK_global_system_variables);
5458
5459 if (!new_state) {
5460 query_logger.deactivate_log_handler(QUERY_LOG_GENERAL);
5461 } else {
5462 res = query_logger.activate_log_handler(thd, QUERY_LOG_GENERAL);
5463 }
5464
5465 mysql_mutex_lock(&LOCK_global_system_variables);
5466
5467 if (res) opt_general_log = false;
5468
5469 return res;
5470 }
5471 static Sys_var_bool Sys_general_log(
5472 "general_log",
5473 "Log connections and queries to a table or log file. "
5474 "Defaults to logging to a file hostname.log, "
5475 "or if --log-output=TABLE is used, to a table mysql.general_log.",
5476 GLOBAL_VAR(opt_general_log), CMD_LINE(OPT_ARG), DEFAULT(false),
5477 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
5478 ON_UPDATE(fix_general_log_state));
5479
5480 static Sys_var_bool Sys_log_raw(
5481 "log_raw",
5482 "Log to general log before any rewriting of the query. For use in "
5483 "debugging, not production as sensitive information may be logged.",
5484 GLOBAL_VAR(opt_general_log_raw), CMD_LINE(OPT_ARG), DEFAULT(false),
5485 NO_MUTEX_GUARD, NOT_IN_BINLOG);
5486
fix_slow_log_state(sys_var *,THD * thd,enum_var_type)5487 static bool fix_slow_log_state(sys_var *, THD *thd, enum_var_type) {
5488 bool new_state = opt_slow_log, res = false;
5489
5490 if (query_logger.is_log_file_enabled(QUERY_LOG_SLOW) == new_state)
5491 return false;
5492
5493 mysql_mutex_unlock(&LOCK_global_system_variables);
5494
5495 if (!new_state) {
5496 query_logger.deactivate_log_handler(QUERY_LOG_SLOW);
5497 } else {
5498 res = query_logger.activate_log_handler(thd, QUERY_LOG_SLOW);
5499 }
5500
5501 mysql_mutex_lock(&LOCK_global_system_variables);
5502
5503 if (res) opt_slow_log = false;
5504
5505 return res;
5506 }
5507 static Sys_var_bool Sys_slow_query_log(
5508 "slow_query_log",
5509 "Log slow queries to a table or log file. Defaults logging to a file "
5510 "hostname-slow.log or a table mysql.slow_log if --log-output=TABLE is "
5511 "used. Must be enabled to activate other slow log options",
5512 GLOBAL_VAR(opt_slow_log), CMD_LINE(OPT_ARG), DEFAULT(false), NO_MUTEX_GUARD,
5513 NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(fix_slow_log_state));
5514
check_slow_log_extra(sys_var *,THD * thd,set_var *)5515 static bool check_slow_log_extra(sys_var *, THD *thd, set_var *) {
5516 // If FILE is not one of the log-targets, succeed but warn!
5517 if (!(log_output_options & LOG_FILE))
5518 push_warning(
5519 thd, Sql_condition::SL_WARNING,
5520 ER_SLOW_LOG_MODE_IGNORED_WHEN_NOT_LOGGING_TO_FILE,
5521 ER_THD(thd, ER_SLOW_LOG_MODE_IGNORED_WHEN_NOT_LOGGING_TO_FILE));
5522
5523 return false;
5524 }
5525
5526 static Sys_var_bool Sys_slow_log_extra(
5527 "log_slow_extra",
5528 "Print more attributes to the slow query log file. Has no effect on "
5529 "logging to table.",
5530 GLOBAL_VAR(opt_log_slow_extra), CMD_LINE(OPT_ARG), DEFAULT(false),
5531 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_slow_log_extra),
5532 ON_UPDATE(nullptr));
5533
check_not_empty_set(sys_var *,THD *,set_var * var)5534 static bool check_not_empty_set(sys_var *, THD *, set_var *var) {
5535 return var->save_result.ulonglong_value == 0;
5536 }
fix_log_output(sys_var *,THD *,enum_var_type)5537 static bool fix_log_output(sys_var *, THD *, enum_var_type) {
5538 query_logger.set_handlers(static_cast<uint>(log_output_options));
5539 return false;
5540 }
5541
5542 static const char *log_output_names[] = {"NONE", "FILE", "TABLE", nullptr};
5543
5544 static Sys_var_set Sys_log_output(
5545 "log_output",
5546 "Syntax: log-output=value[,value...], "
5547 "where \"value\" could be TABLE, FILE or NONE",
5548 GLOBAL_VAR(log_output_options), CMD_LINE(REQUIRED_ARG), log_output_names,
5549 DEFAULT(LOG_FILE), NO_MUTEX_GUARD, NOT_IN_BINLOG,
5550 ON_CHECK(check_not_empty_set), ON_UPDATE(fix_log_output));
5551
5552 static Sys_var_bool Sys_log_slave_updates(
5553 "log_slave_updates",
5554 "Tells the slave to log the updates from "
5555 "the slave thread to the binary log.",
5556 READ_ONLY GLOBAL_VAR(opt_log_slave_updates),
5557 CMD_LINE(OPT_ARG, OPT_LOG_SLAVE_UPDATES), DEFAULT(1));
5558
5559 static Sys_var_charptr Sys_relay_log(
5560 "relay_log", "The location and name to use for relay logs",
5561 READ_ONLY NON_PERSIST GLOBAL_VAR(opt_relay_logname), CMD_LINE(REQUIRED_ARG),
5562 IN_FS_CHARSET, DEFAULT(nullptr));
5563
5564 /*
5565 Uses NO_CMD_LINE since the --relay-log-index option set
5566 opt_relaylog_index_name variable and computes a value for the
5567 relay_log_index variable.
5568 */
5569 static Sys_var_charptr Sys_relay_log_index(
5570 "relay_log_index",
5571 "The location and name to use for the file "
5572 "that keeps a list of the last relay logs",
5573 READ_ONLY NON_PERSIST GLOBAL_VAR(relay_log_index), NO_CMD_LINE,
5574 IN_FS_CHARSET, DEFAULT(nullptr));
5575
5576 /*
5577 Uses NO_CMD_LINE since the --log-bin-index option set
5578 opt_binlog_index_name variable and computes a value for the
5579 log_bin_index variable.
5580 */
5581 static Sys_var_charptr Sys_binlog_index(
5582 "log_bin_index", "File that holds the names for last binary log files.",
5583 READ_ONLY NON_PERSIST GLOBAL_VAR(log_bin_index), NO_CMD_LINE, IN_FS_CHARSET,
5584 DEFAULT(nullptr));
5585
5586 static Sys_var_charptr Sys_relay_log_basename(
5587 "relay_log_basename",
5588 "The full path of the relay log file names, excluding the extension.",
5589 READ_ONLY NON_PERSIST GLOBAL_VAR(relay_log_basename), NO_CMD_LINE,
5590 IN_FS_CHARSET, DEFAULT(nullptr));
5591
5592 static Sys_var_charptr Sys_log_bin_basename(
5593 "log_bin_basename",
5594 "The full path of the binary log file names, excluding the extension.",
5595 READ_ONLY NON_PERSIST GLOBAL_VAR(log_bin_basename), NO_CMD_LINE,
5596 IN_FS_CHARSET, DEFAULT(nullptr));
5597
5598 static Sys_var_charptr Sys_relay_log_info_file(
5599 "relay_log_info_file",
5600 "The location and name of the file that "
5601 "remembers where the SQL replication thread is in the relay logs",
5602 READ_ONLY NON_PERSIST GLOBAL_VAR(relay_log_info_file),
5603 CMD_LINE(REQUIRED_ARG, OPT_RELAY_LOG_INFO_FILE), IN_FS_CHARSET,
5604 DEFAULT(nullptr), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
5605 ON_UPDATE(nullptr), DEPRECATED_VAR(""));
5606
5607 static Sys_var_bool Sys_relay_log_purge(
5608 "relay_log_purge",
5609 "if disabled - do not purge relay logs. "
5610 "if enabled - purge them as soon as they are no more needed",
5611 GLOBAL_VAR(relay_log_purge), CMD_LINE(OPT_ARG), DEFAULT(true));
5612
5613 static Sys_var_bool Sys_relay_log_recovery(
5614 "relay_log_recovery",
5615 "Enables automatic relay log recovery "
5616 "right after the database startup, which means that the IO Thread "
5617 "starts re-fetching from the master right after the last transaction "
5618 "processed",
5619 READ_ONLY GLOBAL_VAR(relay_log_recovery), CMD_LINE(OPT_ARG),
5620 DEFAULT(false));
5621
5622 static Sys_var_ulong Sys_rpl_read_size(
5623 "rpl_read_size",
5624 "The size for reads done from the binlog and relay log. "
5625 "It must be a multiple of 4kb. Making it larger might help with IO "
5626 "stalls while reading these files when they are not in the OS buffer "
5627 "cache",
5628 GLOBAL_VAR(rpl_read_size), CMD_LINE(REQUIRED_ARG),
5629 VALID_RANGE(IO_SIZE * 2, ULONG_MAX), DEFAULT(IO_SIZE * 2),
5630 BLOCK_SIZE(IO_SIZE));
5631
5632 static Sys_var_bool Sys_slave_allow_batching(
5633 "slave_allow_batching", "Allow slave to batch requests",
5634 GLOBAL_VAR(opt_slave_allow_batching), CMD_LINE(OPT_ARG), DEFAULT(false));
5635
5636 static Sys_var_charptr Sys_slave_load_tmpdir(
5637 "slave_load_tmpdir",
5638 "The location where the slave should put "
5639 "its temporary files when replicating a LOAD DATA INFILE command",
5640 READ_ONLY NON_PERSIST GLOBAL_VAR(slave_load_tmpdir), CMD_LINE(REQUIRED_ARG),
5641 IN_FS_CHARSET, DEFAULT(nullptr));
5642
fix_slave_net_timeout(sys_var *,THD * thd,enum_var_type)5643 static bool fix_slave_net_timeout(sys_var *, THD *thd, enum_var_type) {
5644 DEBUG_SYNC(thd, "fix_slave_net_timeout");
5645 Master_info *mi;
5646
5647 /* @TODO: slave net timeout is for all channels, but does this make
5648 sense?
5649 */
5650
5651 /*
5652 Here we have lock on LOCK_global_system_variables and we need
5653 lock on channel_map lock. In START_SLAVE handler, we take these
5654 two locks in different order. This can lead to DEADLOCKs. See
5655 BUG#14236151 for more details.
5656 So we release lock on LOCK_global_system_variables before acquiring
5657 lock on channel_map lock. But this could lead to isolation issues
5658 between multiple setters. Hence introducing secondary guard
5659 for this global variable and releasing the lock here and acquiring
5660 locks back again at the end of this function.
5661 */
5662 mysql_mutex_unlock(&LOCK_slave_net_timeout);
5663 mysql_mutex_unlock(&LOCK_global_system_variables);
5664 channel_map.wrlock();
5665
5666 for (mi_map::iterator it = channel_map.begin(); it != channel_map.end();
5667 it++) {
5668 mi = it->second;
5669
5670 DBUG_PRINT("info", ("slave_net_timeout=%u mi->heartbeat_period=%.3f",
5671 slave_net_timeout, (mi ? mi->heartbeat_period : 0.0)));
5672 if (mi != nullptr && slave_net_timeout < mi->heartbeat_period)
5673 push_warning(thd, Sql_condition::SL_WARNING,
5674 ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX,
5675 ER_THD(thd, ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX));
5676 }
5677
5678 channel_map.unlock();
5679 mysql_mutex_lock(&LOCK_global_system_variables);
5680 mysql_mutex_lock(&LOCK_slave_net_timeout);
5681 return false;
5682 }
5683 static PolyLock_mutex PLock_slave_net_timeout(&LOCK_slave_net_timeout);
5684 static Sys_var_uint Sys_slave_net_timeout(
5685 "slave_net_timeout",
5686 "Number of seconds to wait for more data "
5687 "from a master/slave connection before aborting the read",
5688 GLOBAL_VAR(slave_net_timeout), CMD_LINE(REQUIRED_ARG),
5689 VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(SLAVE_NET_TIMEOUT), BLOCK_SIZE(1),
5690 &PLock_slave_net_timeout, NOT_IN_BINLOG, ON_CHECK(nullptr),
5691 ON_UPDATE(fix_slave_net_timeout));
5692
check_slave_skip_counter(sys_var *,THD *,set_var *)5693 static bool check_slave_skip_counter(sys_var *, THD *, set_var *) {
5694 /*
5695 @todo: move this check into the set function and hold the lock on
5696 Gtid_mode::lock until the operation has completed, so that we are
5697 sure a concurrent connection does not change gtid_mode between
5698 check and fix.
5699 */
5700 if (global_gtid_mode.get() == Gtid_mode::ON) {
5701 my_error(ER_SQL_SLAVE_SKIP_COUNTER_NOT_SETTABLE_IN_GTID_MODE, MYF(0));
5702 return true;
5703 }
5704
5705 return false;
5706 }
5707
5708 static PolyLock_mutex PLock_sql_slave_skip_counter(
5709 &LOCK_sql_slave_skip_counter);
5710 static Sys_var_uint Sys_slave_skip_counter(
5711 "sql_slave_skip_counter", "sql_slave_skip_counter",
5712 GLOBAL_VAR(sql_slave_skip_counter), NO_CMD_LINE, VALID_RANGE(0, UINT_MAX),
5713 DEFAULT(0), BLOCK_SIZE(1), &PLock_sql_slave_skip_counter, NOT_IN_BINLOG,
5714 ON_CHECK(check_slave_skip_counter));
5715
5716 static Sys_var_charptr Sys_slave_skip_errors(
5717 "slave_skip_errors",
5718 "Tells the slave thread to continue "
5719 "replication when a query event returns an error from the "
5720 "provided list",
5721 READ_ONLY GLOBAL_VAR(opt_slave_skip_errors), CMD_LINE(REQUIRED_ARG),
5722 IN_SYSTEM_CHARSET, DEFAULT(nullptr));
5723
5724 static Sys_var_ulonglong Sys_relay_log_space_limit(
5725 "relay_log_space_limit", "Maximum space to use for all relay logs",
5726 READ_ONLY GLOBAL_VAR(relay_log_space_limit), CMD_LINE(REQUIRED_ARG),
5727 VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1));
5728
5729 static Sys_var_uint Sys_sync_relaylog_period(
5730 "sync_relay_log",
5731 "Synchronously flush relay log to disk after "
5732 "every #th event. Use 0 to disable synchronous flushing",
5733 GLOBAL_VAR(sync_relaylog_period), CMD_LINE(REQUIRED_ARG),
5734 VALID_RANGE(0, UINT_MAX), DEFAULT(10000), BLOCK_SIZE(1));
5735
5736 static Sys_var_uint Sys_sync_relayloginfo_period(
5737 "sync_relay_log_info",
5738 "Synchronously flush relay log info "
5739 "to disk after every #th transaction. Use 0 to disable "
5740 "synchronous flushing",
5741 GLOBAL_VAR(sync_relayloginfo_period), CMD_LINE(REQUIRED_ARG),
5742 VALID_RANGE(0, UINT_MAX), DEFAULT(10000), BLOCK_SIZE(1));
5743
5744 static Sys_var_uint Sys_checkpoint_mts_period(
5745 "slave_checkpoint_period",
5746 "Gather workers' activities to "
5747 "Update progress status of Multi-threaded slave and flush "
5748 "the relay log info to disk after every #th milli-seconds.",
5749 GLOBAL_VAR(opt_mts_checkpoint_period), CMD_LINE(REQUIRED_ARG),
5750 #ifndef DBUG_OFF
5751 VALID_RANGE(0, UINT_MAX), DEFAULT(300), BLOCK_SIZE(1));
5752 #else
5753 VALID_RANGE(1, UINT_MAX), DEFAULT(300), BLOCK_SIZE(1));
5754 #endif /* DBUG_OFF */
5755
5756 static Sys_var_uint Sys_checkpoint_mts_group(
5757 "slave_checkpoint_group",
5758 "Maximum number of processed transactions by Multi-threaded slave "
5759 "before a checkpoint operation is called to update progress status.",
5760 GLOBAL_VAR(opt_mts_checkpoint_group), CMD_LINE(REQUIRED_ARG),
5761 #ifndef DBUG_OFF
5762 VALID_RANGE(1, MTS_MAX_BITS_IN_GROUP), DEFAULT(512), BLOCK_SIZE(1));
5763 #else
5764 VALID_RANGE(32, MTS_MAX_BITS_IN_GROUP), DEFAULT(512), BLOCK_SIZE(8));
5765 #endif /* DBUG_OFF */
5766
5767 static Sys_var_uint Sys_sync_binlog_period(
5768 "sync_binlog",
5769 "Synchronously flush binary log to disk after"
5770 " every #th write to the file. Use 0 to disable synchronous"
5771 " flushing",
5772 GLOBAL_VAR(sync_binlog_period), CMD_LINE(REQUIRED_ARG),
5773 VALID_RANGE(0, UINT_MAX), DEFAULT(1), BLOCK_SIZE(1));
5774
5775 static Sys_var_uint Sys_sync_masterinfo_period(
5776 "sync_master_info",
5777 "Synchronously flush master info to disk "
5778 "after every #th event. Use 0 to disable synchronous flushing",
5779 GLOBAL_VAR(sync_masterinfo_period), CMD_LINE(REQUIRED_ARG),
5780 VALID_RANGE(0, UINT_MAX), DEFAULT(10000), BLOCK_SIZE(1));
5781
5782 static Sys_var_ulonglong Sys_var_original_commit_timestamp(
5783 "original_commit_timestamp",
5784 "The time when the current transaction was committed on the originating "
5785 "replication master, measured in microseconds since the epoch.",
5786 SESSION_ONLY(original_commit_timestamp), NO_CMD_LINE,
5787 VALID_RANGE(0, MAX_COMMIT_TIMESTAMP_VALUE),
5788 DEFAULT(MAX_COMMIT_TIMESTAMP_VALUE), BLOCK_SIZE(1), NO_MUTEX_GUARD,
5789 IN_BINLOG, ON_CHECK(check_session_admin_or_replication_applier));
5790
5791 static Sys_var_ulong Sys_slave_trans_retries(
5792 "slave_transaction_retries",
5793 "Number of times the slave SQL "
5794 "thread will retry a transaction in case it failed with a deadlock "
5795 "or elapsed lock wait timeout, before giving up and stopping",
5796 GLOBAL_VAR(slave_trans_retries), CMD_LINE(REQUIRED_ARG),
5797 VALID_RANGE(0, ULONG_MAX), DEFAULT(10), BLOCK_SIZE(1));
5798
5799 static Sys_var_ulong Sys_slave_parallel_workers(
5800 "slave_parallel_workers",
5801 "Number of worker threads for executing events in parallel ",
5802 PERSIST_AS_READONLY GLOBAL_VAR(opt_mts_slave_parallel_workers),
5803 CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, MTS_MAX_WORKERS), DEFAULT(0),
5804 BLOCK_SIZE(1));
5805
5806 static Sys_var_ulonglong Sys_mts_pending_jobs_size_max(
5807 "slave_pending_jobs_size_max",
5808 "Max size of Slave Worker queues holding not yet applied events. "
5809 "The least possible value must be not less than the master side "
5810 "max_allowed_packet.",
5811 GLOBAL_VAR(opt_mts_pending_jobs_size_max), CMD_LINE(REQUIRED_ARG),
5812 VALID_RANGE(1024, (ulonglong) ~(intptr)0), DEFAULT(128 * 1024 * 1024),
5813 BLOCK_SIZE(1024), ON_CHECK(nullptr));
5814
check_locale(sys_var * self,THD * thd,set_var * var)5815 static bool check_locale(sys_var *self, THD *thd, set_var *var) {
5816 if (!var->value) return false;
5817
5818 MY_LOCALE *locale;
5819 char buff[STRING_BUFFER_USUAL_SIZE];
5820 if (var->value->result_type() == INT_RESULT) {
5821 int lcno = (int)var->value->val_int();
5822 if (!(locale = my_locale_by_number(lcno))) {
5823 my_error(ER_UNKNOWN_LOCALE, MYF(0), llstr(lcno, buff));
5824 return true;
5825 }
5826 if (check_not_null(self, thd, var)) return true;
5827 } else // STRING_RESULT
5828 {
5829 String str(buff, sizeof(buff), system_charset_info), *res;
5830 if (!(res = var->value->val_str(&str)))
5831 return true;
5832 else if (!(locale = my_locale_by_name(thd, res->ptr(), res->length()))) {
5833 ErrConvString err(res);
5834 my_error(ER_UNKNOWN_LOCALE, MYF(0), err.ptr());
5835 return true;
5836 }
5837 }
5838
5839 var->save_result.ptr = locale;
5840
5841 if (!locale->errmsgs->is_loaded()) {
5842 mysql_mutex_lock(&LOCK_error_messages);
5843 if (!locale->errmsgs->is_loaded() && locale->errmsgs->read_texts()) {
5844 push_warning_printf(thd, Sql_condition::SL_WARNING, ER_UNKNOWN_ERROR,
5845 "Can't process error message file for locale '%s'",
5846 locale->name);
5847 mysql_mutex_unlock(&LOCK_error_messages);
5848 return true;
5849 }
5850 mysql_mutex_unlock(&LOCK_error_messages);
5851 }
5852 return false;
5853 }
5854
5855 namespace {
5856 struct Get_locale_name {
Get_locale_name__anon9d05e1790211::Get_locale_name5857 explicit Get_locale_name(const MY_LOCALE *ml) : m_ml(ml) {}
get_name__anon9d05e1790211::Get_locale_name5858 const uchar *get_name() const {
5859 return pointer_cast<const uchar *>(m_ml->name);
5860 }
5861 const MY_LOCALE *m_ml;
5862 };
5863 } // namespace
5864
5865 static Sys_var_struct<MY_LOCALE, Get_locale_name> Sys_lc_messages(
5866 "lc_messages", "Set the language used for the error messages",
5867 SESSION_VAR(lc_messages), NO_CMD_LINE, DEFAULT(&my_default_lc_messages),
5868 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_locale));
5869
5870 static Sys_var_struct<MY_LOCALE, Get_locale_name> Sys_lc_time_names(
5871 "lc_time_names",
5872 "Set the language used for the month "
5873 "names and the days of the week",
5874 SESSION_VAR(lc_time_names), NO_CMD_LINE, DEFAULT(&my_default_lc_time_names),
5875 NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_locale));
5876
5877 static Sys_var_tz Sys_time_zone("time_zone", "time_zone",
5878 HINT_UPDATEABLE SESSION_VAR(time_zone),
5879 NO_CMD_LINE, DEFAULT(&default_tz),
5880 NO_MUTEX_GUARD, IN_BINLOG);
5881
fix_host_cache_size(sys_var *,THD *,enum_var_type)5882 static bool fix_host_cache_size(sys_var *, THD *, enum_var_type) {
5883 hostname_cache_resize(host_cache_size);
5884 return false;
5885 }
5886
5887 static Sys_var_uint Sys_host_cache_size(
5888 "host_cache_size",
5889 "How many host names should be cached to avoid resolving.",
5890 GLOBAL_VAR(host_cache_size), CMD_LINE(REQUIRED_ARG, OPT_HOST_CACHE_SIZE),
5891 VALID_RANGE(0, 65536), DEFAULT(HOST_CACHE_SIZE), BLOCK_SIZE(1),
5892 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
5893 ON_UPDATE(fix_host_cache_size));
5894
5895 const Sys_var_multi_enum::ALIAS enforce_gtid_consistency_aliases[] = {
5896 {"OFF", 0}, {"ON", 1}, {"WARN", 2},
5897 {"FALSE", 0}, {"TRUE", 1}, {nullptr, 0}};
5898 static Sys_var_enforce_gtid_consistency Sys_enforce_gtid_consistency(
5899 "enforce_gtid_consistency",
5900 "Prevents execution of statements that would be impossible to log "
5901 "in a transactionally safe manner. Currently, the disallowed "
5902 "statements include CREATE TEMPORARY TABLE inside transactions, "
5903 "all updates to non-transactional tables, and CREATE TABLE ... SELECT.",
5904 PERSIST_AS_READONLY GLOBAL_VAR(_gtid_consistency_mode),
5905 CMD_LINE(OPT_ARG, OPT_ENFORCE_GTID_CONSISTENCY),
5906 enforce_gtid_consistency_aliases, 3,
5907 DEFAULT(3 /*position of "FALSE" in enforce_gtid_consistency_aliases*/),
5908 DEFAULT(GTID_CONSISTENCY_MODE_ON), NO_MUTEX_GUARD, NOT_IN_BINLOG,
5909 ON_CHECK(check_session_admin_outside_trx_outside_sf_outside_sp));
fixup_enforce_gtid_consistency_command_line(char * value_arg)5910 const char *fixup_enforce_gtid_consistency_command_line(char *value_arg) {
5911 return Sys_enforce_gtid_consistency.fixup_command_line(value_arg);
5912 }
5913
5914 static Sys_var_bool Sys_binlog_gtid_simple_recovery(
5915 "binlog_gtid_simple_recovery",
5916 "If this option is enabled, the server does not open more than "
5917 "two binary logs when initializing GTID_PURGED and "
5918 "GTID_EXECUTED, either during server restart or when binary "
5919 "logs are being purged. Enabling this option is useful when "
5920 "the server has already generated many binary logs without "
5921 "GTID events (e.g., having GTID_MODE = OFF). Note: If this "
5922 "option is enabled, GLOBAL.GTID_EXECUTED and "
5923 "GLOBAL.GTID_PURGED may be initialized wrongly in two cases: "
5924 "(1) All binary logs were generated by MySQL 5.7.5 or older, "
5925 "and GTID_MODE was ON for some binary logs but OFF for the "
5926 "newest binary log. (2) The oldest existing binary log was "
5927 "generated by MySQL 5.7.5 or older, and SET GTID_PURGED was "
5928 "issued after the oldest binary log was generated. If a wrong "
5929 "set is computed in one of case (1) or case (2), it will "
5930 "remain wrong even if the server is later restarted with this "
5931 "option disabled.",
5932 READ_ONLY GLOBAL_VAR(binlog_gtid_simple_recovery), CMD_LINE(OPT_ARG),
5933 DEFAULT(true));
5934
5935 static Sys_var_ulong Sys_sp_cache_size(
5936 "stored_program_cache",
5937 "The soft upper limit for number of cached stored routines for "
5938 "one connection.",
5939 GLOBAL_VAR(stored_program_cache_size), CMD_LINE(REQUIRED_ARG),
5940 VALID_RANGE(16, 512 * 1024), DEFAULT(256), BLOCK_SIZE(1));
5941
check_pseudo_slave_mode(sys_var * self,THD * thd,set_var * var)5942 static bool check_pseudo_slave_mode(sys_var *self, THD *thd, set_var *var) {
5943 if (check_session_admin_or_replication_applier(self, thd, var)) return true;
5944 if (check_outside_trx(self, thd, var)) return true;
5945 longlong previous_val = thd->variables.pseudo_slave_mode;
5946 longlong val = (longlong)var->save_result.ulonglong_value;
5947 bool rli_fake = false;
5948
5949 rli_fake = thd->rli_fake ? true : false;
5950
5951 if (rli_fake) {
5952 if (!val) {
5953 thd->rli_fake->end_info();
5954 delete thd->rli_fake;
5955 thd->rli_fake = nullptr;
5956 } else if (previous_val && val)
5957 goto ineffective;
5958 else if (!previous_val && val)
5959 push_warning(thd, Sql_condition::SL_WARNING, ER_WRONG_VALUE_FOR_VAR,
5960 "'pseudo_slave_mode' is already ON.");
5961 } else {
5962 if (!previous_val && !val)
5963 goto ineffective;
5964 else if (previous_val && !val)
5965 push_warning(thd, Sql_condition::SL_WARNING, ER_WRONG_VALUE_FOR_VAR,
5966 "Slave applier execution mode not active, "
5967 "statement ineffective.");
5968 }
5969 goto end;
5970
5971 ineffective:
5972 push_warning(thd, Sql_condition::SL_WARNING, ER_WRONG_VALUE_FOR_VAR,
5973 "'pseudo_slave_mode' change was ineffective.");
5974
5975 end:
5976 return false;
5977 }
5978 static Sys_var_bool Sys_pseudo_slave_mode(
5979 "pseudo_slave_mode",
5980 "SET pseudo_slave_mode= 0,1 are commands that mysqlbinlog "
5981 "adds to beginning and end of binary log dumps. While zero "
5982 "value indeed disables, the actual enabling of the slave "
5983 "applier execution mode is done implicitly when a "
5984 "Format_description_event is sent through the session.",
5985 SESSION_ONLY(pseudo_slave_mode), NO_CMD_LINE, DEFAULT(false),
5986 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_pseudo_slave_mode));
5987
5988 #ifdef HAVE_GTID_NEXT_LIST
check_gtid_next_list(sys_var * self,THD * thd,set_var * var)5989 static bool check_gtid_next_list(sys_var *self, THD *thd, set_var *var) {
5990 DBUG_TRACE;
5991 my_error(ER_NOT_SUPPORTED_YET, MYF(0), "GTID_NEXT_LIST");
5992 if (check_session_admin_outside_trx_outside_sf_outside_sp(self, thd, var))
5993 return true;
5994 /*
5995 @todo: move this check into the set function and hold the lock on
5996 Gtid_mode::lock until the operation has completed, so that we are
5997 sure a concurrent connection does not change gtid_mode between
5998 check and fix - if we ever implement this variable.
5999 */
6000 if (global_gtid_mode.get() == Gtid_mode::OFF &&
6001 var->save_result.string_value.str != NULL)
6002 my_error(ER_CANT_SET_GTID_NEXT_LIST_TO_NON_NULL_WHEN_GTID_MODE_IS_OFF,
6003 MYF(0));
6004 return false;
6005 }
6006
update_gtid_next_list(sys_var * self,THD * thd,enum_var_type type)6007 static bool update_gtid_next_list(sys_var *self, THD *thd, enum_var_type type) {
6008 DBUG_ASSERT(type == OPT_SESSION);
6009 if (thd->get_gtid_next_list() != NULL)
6010 return gtid_acquire_ownership_multiple(thd) != 0 ? true : false;
6011 return false;
6012 }
6013
6014 static Sys_var_gtid_set Sys_gtid_next_list(
6015 "gtid_next_list",
6016 "Before re-executing a transaction that contains multiple "
6017 "Global Transaction Identifiers, this variable must be set "
6018 "to the set of all re-executed transactions.",
6019 SESSION_ONLY(gtid_next_list), NO_CMD_LINE, DEFAULT(NULL), NO_MUTEX_GUARD,
6020 NOT_IN_BINLOG, ON_CHECK(check_gtid_next_list),
6021 ON_UPDATE(update_gtid_next_list));
6022 export sys_var *Sys_gtid_next_list_ptr = &Sys_gtid_next_list;
6023 #endif // HAVE_GTID_NEXT_LIST
6024
6025 static Sys_var_gtid_next Sys_gtid_next(
6026 "gtid_next",
6027 "Specifies the Global Transaction Identifier for the following "
6028 "transaction.",
6029 SESSION_ONLY(gtid_next), NO_CMD_LINE, DEFAULT("AUTOMATIC"), NO_MUTEX_GUARD,
6030 NOT_IN_BINLOG, ON_CHECK(check_gtid_next));
6031 export sys_var *Sys_gtid_next_ptr = &Sys_gtid_next;
6032
6033 static Sys_var_gtid_executed Sys_gtid_executed(
6034 "gtid_executed",
6035 "The global variable contains the set of GTIDs in the "
6036 "binary log. The session variable contains the set of GTIDs "
6037 "in the current, ongoing transaction.");
6038
check_gtid_purged(sys_var * self,THD * thd,set_var * var)6039 static bool check_gtid_purged(sys_var *self, THD *thd, set_var *var) {
6040 DBUG_TRACE;
6041
6042 /*
6043 GTID_PURGED must not be set / updated when GR is running (it goes against
6044 the whole purpose of update everywhere replication).
6045 */
6046 if (is_group_replication_running()) {
6047 my_error(ER_UPDATE_GTID_PURGED_WITH_GR, MYF(0));
6048 return true;
6049 }
6050
6051 if (!var->value ||
6052 check_session_admin_outside_trx_outside_sf_outside_sp(self, thd, var))
6053 return true;
6054
6055 if (var->value->result_type() != STRING_RESULT ||
6056 !var->save_result.string_value.str)
6057 return true;
6058
6059 return false;
6060 }
6061
global_update(THD * thd,set_var * var)6062 bool Sys_var_gtid_purged::global_update(THD *thd, set_var *var) {
6063 DBUG_TRACE;
6064 bool error = false;
6065
6066 global_sid_lock->wrlock();
6067
6068 /*
6069 ensures the commit of the transaction started when saving the
6070 purged gtid set in the table
6071 */
6072 thd->lex->autocommit = true;
6073
6074 /*
6075 SET GITD_PURGED command should ignore 'read-only' and 'super_read_only'
6076 options so that it can update 'mysql.gtid_executed' replication repository
6077 table.
6078 */
6079 thd->set_skip_readonly_check();
6080 char *previous_gtid_executed = nullptr, *previous_gtid_purged = nullptr,
6081 *current_gtid_executed = nullptr, *current_gtid_purged = nullptr;
6082 gtid_state->get_executed_gtids()->to_string(&previous_gtid_executed);
6083 gtid_state->get_lost_gtids()->to_string(&previous_gtid_purged);
6084 Gtid_set gtid_set(global_sid_map, global_sid_lock);
6085 bool starts_with_plus = false;
6086 enum_return_status ret = gtid_set.add_gtid_text(
6087 var->save_result.string_value.str, nullptr, &starts_with_plus);
6088
6089 if (ret != RETURN_STATUS_OK) {
6090 error = true;
6091 goto end;
6092 }
6093 ret = gtid_state->add_lost_gtids(>id_set, starts_with_plus);
6094 if (ret != RETURN_STATUS_OK) {
6095 error = true;
6096 goto end;
6097 }
6098 gtid_state->get_executed_gtids()->to_string(¤t_gtid_executed);
6099 gtid_state->get_lost_gtids()->to_string(¤t_gtid_purged);
6100
6101 // Log messages saying that GTID_PURGED and GTID_EXECUTED were changed.
6102 LogErr(SYSTEM_LEVEL, ER_GTID_PURGED_WAS_UPDATED, previous_gtid_purged,
6103 current_gtid_purged);
6104 LogErr(SYSTEM_LEVEL, ER_GTID_EXECUTED_WAS_UPDATED, previous_gtid_executed,
6105 current_gtid_executed);
6106
6107 end:
6108 global_sid_lock->unlock();
6109 my_free(previous_gtid_executed);
6110 my_free(previous_gtid_purged);
6111 my_free(current_gtid_executed);
6112 my_free(current_gtid_purged);
6113 return error;
6114 }
6115
6116 Gtid_set *gtid_purged;
6117 static Sys_var_gtid_purged Sys_gtid_purged(
6118 "gtid_purged",
6119 "The set of GTIDs that existed in previous, purged binary logs.",
6120 GLOBAL_VAR(gtid_purged), NO_CMD_LINE, DEFAULT(nullptr), NO_MUTEX_GUARD,
6121 NOT_IN_BINLOG, ON_CHECK(check_gtid_purged));
6122 export sys_var *Sys_gtid_purged_ptr = &Sys_gtid_purged;
6123
6124 static Sys_var_gtid_owned Sys_gtid_owned(
6125 "gtid_owned",
6126 "The global variable lists all GTIDs owned by all threads. "
6127 "The session variable lists all GTIDs owned by the current thread.");
6128
6129 static Sys_var_gtid_mode Sys_gtid_mode(
6130 "gtid_mode",
6131 "Controls whether Global Transaction Identifiers (GTIDs) are "
6132 "enabled. Can be OFF, OFF_PERMISSIVE, ON_PERMISSIVE, or ON. OFF "
6133 "means that no transaction has a GTID. OFF_PERMISSIVE means that "
6134 "new transactions (committed in a client session using "
6135 "GTID_NEXT='AUTOMATIC') are not assigned any GTID, and "
6136 "replicated transactions are allowed to have or not have a "
6137 "GTID. ON_PERMISSIVE means that new transactions are assigned a "
6138 "GTID, and replicated transactions are allowed to have or not "
6139 "have a GTID. ON means that all transactions have a GTID. "
6140 "ON is required on a master before any slave can use "
6141 "MASTER_AUTO_POSITION=1. To safely switch from OFF to ON, first "
6142 "set all servers to OFF_PERMISSIVE, then set all servers to "
6143 "ON_PERMISSIVE, then wait for all transactions without a GTID to "
6144 "be replicated and executed on all servers, and finally set all "
6145 "servers to GTID_MODE = ON.",
6146 PERSIST_AS_READONLY GLOBAL_VAR(Gtid_mode::sysvar_mode),
6147 CMD_LINE(REQUIRED_ARG), Gtid_mode::names, DEFAULT(Gtid_mode::DEFAULT),
6148 NO_MUTEX_GUARD, NOT_IN_BINLOG,
6149 ON_CHECK(check_session_admin_outside_trx_outside_sf_outside_sp));
6150
6151 static Sys_var_uint Sys_gtid_executed_compression_period(
6152 "gtid_executed_compression_period",
6153 "When binlog is disabled, "
6154 "a background thread wakes up to compress the gtid_executed table "
6155 "every gtid_executed_compression_period transactions, as a "
6156 "special case, if variable is 0, the thread never wakes up "
6157 "to compress the gtid_executed table.",
6158 GLOBAL_VAR(gtid_executed_compression_period), CMD_LINE(OPT_ARG),
6159 VALID_RANGE(0, UINT_MAX32), DEFAULT(1000), BLOCK_SIZE(1));
6160
6161 static Sys_var_bool Sys_disconnect_on_expired_password(
6162 "disconnect_on_expired_password",
6163 "Give clients that don't signal password expiration support execution "
6164 "time "
6165 "error(s) instead of connection error",
6166 READ_ONLY GLOBAL_VAR(disconnect_on_expired_password), CMD_LINE(OPT_ARG),
6167 DEFAULT(true));
6168
6169 static Sys_var_bool Sys_validate_user_plugins(
6170 "validate_user_plugins",
6171 "Turns on additional validation of authentication plugins assigned "
6172 "to user accounts. ",
6173 READ_ONLY NOT_VISIBLE GLOBAL_VAR(validate_user_plugins), CMD_LINE(OPT_ARG),
6174 DEFAULT(true), NO_MUTEX_GUARD, NOT_IN_BINLOG);
6175
6176 static Sys_var_enum Sys_block_encryption_mode(
6177 "block_encryption_mode", "mode for AES_ENCRYPT/AES_DECRYPT",
6178 SESSION_VAR(my_aes_mode), CMD_LINE(REQUIRED_ARG), my_aes_opmode_names,
6179 DEFAULT(my_aes_128_ecb));
6180
check_track_session_sys_vars(sys_var *,THD * thd,set_var * var)6181 static bool check_track_session_sys_vars(sys_var *, THD *thd, set_var *var) {
6182 DBUG_TRACE;
6183 return thd->session_tracker.get_tracker(SESSION_SYSVARS_TRACKER)
6184 ->check(thd, var);
6185 return false;
6186 }
6187
update_track_session_sys_vars(sys_var *,THD * thd,enum_var_type type)6188 static bool update_track_session_sys_vars(sys_var *, THD *thd,
6189 enum_var_type type) {
6190 DBUG_TRACE;
6191 /* Populate map only for session variable. */
6192 if (type == OPT_SESSION)
6193 return thd->session_tracker.get_tracker(SESSION_SYSVARS_TRACKER)
6194 ->update(thd);
6195 return false;
6196 }
6197
6198 static Sys_var_charptr Sys_track_session_sys_vars(
6199 "session_track_system_variables",
6200 "Track changes in registered system variables.",
6201 SESSION_VAR(track_sysvars_ptr), CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET,
6202 DEFAULT("time_zone,autocommit,character_set_client,character_set_results,"
6203 "character_set_connection"),
6204 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_track_session_sys_vars),
6205 ON_UPDATE(update_track_session_sys_vars));
6206
update_session_track_schema(sys_var *,THD * thd,enum_var_type)6207 static bool update_session_track_schema(sys_var *, THD *thd, enum_var_type) {
6208 DBUG_TRACE;
6209 return thd->session_tracker.get_tracker(CURRENT_SCHEMA_TRACKER)->update(thd);
6210 }
6211
6212 static Sys_var_bool Sys_session_track_schema(
6213 "session_track_schema", "Track changes to the 'default schema'.",
6214 SESSION_VAR(session_track_schema), CMD_LINE(OPT_ARG), DEFAULT(true),
6215 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
6216 ON_UPDATE(update_session_track_schema));
6217
update_session_track_tx_info(sys_var *,THD * thd,enum_var_type)6218 static bool update_session_track_tx_info(sys_var *, THD *thd, enum_var_type) {
6219 DBUG_TRACE;
6220 TX_TRACKER_GET(tst);
6221 return tst->update(thd);
6222 }
6223
6224 static const char *session_track_transaction_info_names[] = {
6225 "OFF", "STATE", "CHARACTERISTICS", NullS};
6226
6227 static Sys_var_enum Sys_session_track_transaction_info(
6228 "session_track_transaction_info",
6229 "Track changes to the transaction attributes. OFF to disable; "
6230 "STATE to track just transaction state (Is there an active transaction? "
6231 "Does it have any data? etc.); CHARACTERISTICS to track transaction "
6232 "state "
6233 "and report all statements needed to start a transaction with the same "
6234 "characteristics (isolation level, read only/read write, snapshot - "
6235 "but not any work done / data modified within the transaction).",
6236 SESSION_VAR(session_track_transaction_info), CMD_LINE(REQUIRED_ARG),
6237 session_track_transaction_info_names, DEFAULT(OFF), NO_MUTEX_GUARD,
6238 NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(update_session_track_tx_info));
6239
update_session_track_state_change(sys_var *,THD * thd,enum_var_type)6240 static bool update_session_track_state_change(sys_var *, THD *thd,
6241 enum_var_type) {
6242 DBUG_TRACE;
6243 return thd->session_tracker.get_tracker(SESSION_STATE_CHANGE_TRACKER)
6244 ->update(thd);
6245 }
6246
6247 static Sys_var_bool Sys_session_track_state_change(
6248 "session_track_state_change", "Track changes to the 'session state'.",
6249 SESSION_VAR(session_track_state_change), CMD_LINE(OPT_ARG), DEFAULT(false),
6250 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
6251 ON_UPDATE(update_session_track_state_change));
6252
handle_offline_mode(sys_var *,THD * thd,enum_var_type)6253 static bool handle_offline_mode(sys_var *, THD *thd, enum_var_type) {
6254 DBUG_TRACE;
6255 DEBUG_SYNC(thd, "after_lock_offline_mode_acquire");
6256
6257 if (mysqld_offline_mode()) {
6258 // Unlock the global system varaible lock as kill holds LOCK_thd_data.
6259 mysql_mutex_unlock(&LOCK_global_system_variables);
6260 killall_non_super_threads(thd);
6261 mysql_mutex_lock(&LOCK_global_system_variables);
6262 }
6263
6264 return false;
6265 }
6266
6267 static Sys_var_bool Sys_offline_mode(
6268 "offline_mode", "Make the server into offline mode",
6269 GLOBAL_VAR(offline_mode), CMD_LINE(OPT_ARG), DEFAULT(false), NO_MUTEX_GUARD,
6270 NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(handle_offline_mode));
6271
6272 static Sys_var_bool Sys_avoid_temporal_upgrade(
6273 "avoid_temporal_upgrade",
6274 "When this option is enabled, the pre-5.6.4 temporal types are "
6275 "not upgraded to the new format for ALTER TABLE requests "
6276 "ADD/CHANGE/MODIFY"
6277 " COLUMN, ADD INDEX or FORCE operation. "
6278 "This variable is deprecated and will be removed in a future release.",
6279 GLOBAL_VAR(avoid_temporal_upgrade),
6280 CMD_LINE(OPT_ARG, OPT_AVOID_TEMPORAL_UPGRADE), DEFAULT(false),
6281 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr),
6282 DEPRECATED_VAR(""));
6283
6284 static Sys_var_bool Sys_show_old_temporals(
6285 "show_old_temporals",
6286 "When this option is enabled, the pre-5.6.4 temporal types will "
6287 "be marked in the 'SHOW CREATE TABLE' and 'INFORMATION_SCHEMA.COLUMNS' "
6288 "table as a comment in COLUMN_TYPE field. "
6289 "This variable is deprecated and will be removed in a future release.",
6290 SESSION_VAR(show_old_temporals), CMD_LINE(OPT_ARG, OPT_SHOW_OLD_TEMPORALS),
6291 DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
6292 ON_UPDATE(nullptr), DEPRECATED_VAR(""));
6293
6294 static Sys_var_charptr Sys_disabled_storage_engines(
6295 "disabled_storage_engines",
6296 "Limit CREATE TABLE for the storage engines listed",
6297 READ_ONLY GLOBAL_VAR(opt_disabled_storage_engines), CMD_LINE(REQUIRED_ARG),
6298 IN_SYSTEM_CHARSET, DEFAULT(""));
6299
6300 static Sys_var_bool Sys_persisted_globals_load(
6301 PERSISTED_GLOBALS_LOAD,
6302 "When this option is enabled, config file mysqld-auto.cnf is read "
6303 "and applied to server, else this file is ignored even if present.",
6304 READ_ONLY NON_PERSIST GLOBAL_VAR(persisted_globals_load), CMD_LINE(OPT_ARG),
6305 DEFAULT(true), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
6306 ON_UPDATE(nullptr));
6307
sysvar_check_authid_string(sys_var *,THD * thd,set_var * var)6308 static bool sysvar_check_authid_string(sys_var *, THD *thd, set_var *var) {
6309 /*
6310 Since mandatory_roles is similar to a GRANT role statement without a
6311 GRANT ADMIN privilege, setting this variable requires both the
6312 ROLE_ADMIN and the SYSTEM_VARIABLES_ADMIN.
6313 */
6314 Security_context *sctx = thd->security_context();
6315 DBUG_ASSERT(sctx != nullptr);
6316 if (sctx && !sctx->has_global_grant(STRING_WITH_LEN("ROLE_ADMIN")).first) {
6317 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0),
6318 "SYSTEM_VARIABLES_ADMIN or SUPER privileges, as well as the "
6319 "ROLE_ADMIN");
6320 /* No privilege access error */
6321 return true;
6322 }
6323 if (var->save_result.string_value.str == nullptr) {
6324 var->save_result.string_value.str = const_cast<char *>("");
6325 var->save_result.string_value.length = 0;
6326 }
6327 return check_authorization_id_string(thd, var->save_result.string_value);
6328 }
6329
sysvar_update_mandatory_roles(sys_var *,THD *,enum_var_type)6330 static bool sysvar_update_mandatory_roles(sys_var *, THD *, enum_var_type) {
6331 update_mandatory_roles();
6332 return false;
6333 }
6334
6335 static PolyLock_mutex PLock_sys_mandatory_roles(&LOCK_mandatory_roles);
6336 static Sys_var_lexstring Sys_mandatory_roles(
6337 "mandatory_roles",
6338 "All the specified roles are always considered granted to every user and "
6339 "they"
6340 " can't be revoked. Mandatory roles still require activation unless they "
6341 "are made into "
6342 "default roles. The granted roles will not be visible in the "
6343 "mysql.role_edges"
6344 " table.",
6345 GLOBAL_VAR(opt_mandatory_roles), CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET,
6346 DEFAULT(""), &PLock_sys_mandatory_roles, NOT_IN_BINLOG,
6347 ON_CHECK(sysvar_check_authid_string),
6348 ON_UPDATE(sysvar_update_mandatory_roles));
6349
6350 static Sys_var_bool Sys_always_activate_granted_roles(
6351 "activate_all_roles_on_login",
6352 "Automatically set all granted roles as active after the user has "
6353 "authenticated successfully.",
6354 GLOBAL_VAR(opt_always_activate_granted_roles), CMD_LINE(OPT_ARG),
6355 DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr),
6356 ON_UPDATE(nullptr));
6357
6358 static PolyLock_mutex plock_sys_password_history(&LOCK_password_history);
6359 static Sys_var_uint Sys_password_history(
6360 "password_history",
6361 "The number of old passwords to check in the history."
6362 " Set to 0 (the default) to turn the checks off",
6363 GLOBAL_VAR(global_password_history), CMD_LINE(REQUIRED_ARG),
6364 VALID_RANGE(0, UINT_MAX32), DEFAULT(0), BLOCK_SIZE(1),
6365 &plock_sys_password_history);
6366
6367 static PolyLock_mutex plock_sys_password_reuse_interval(
6368 &LOCK_password_reuse_interval);
6369 static Sys_var_uint Sys_password_reuse_interval(
6370 "password_reuse_interval",
6371 "The minimum number of days that need to pass before a password can "
6372 "be reused. Set to 0 (the default) to turn the checks off",
6373 GLOBAL_VAR(global_password_reuse_interval), CMD_LINE(REQUIRED_ARG),
6374 VALID_RANGE(0, UINT_MAX32), DEFAULT(0), BLOCK_SIZE(1),
6375 &plock_sys_password_reuse_interval);
6376
check_resultset_metadata(sys_var *,THD * thd,set_var * var)6377 static bool check_resultset_metadata(sys_var *, THD *thd, set_var *var) {
6378 /*
6379 Set @@resultset_metadata to the value other than FULL only if
6380 the client supports it.
6381 */
6382 if (var->save_result.ulonglong_value != RESULTSET_METADATA_FULL &&
6383 !thd->get_protocol()->has_client_capability(
6384 CLIENT_OPTIONAL_RESULTSET_METADATA)) {
6385 my_error(ER_CLIENT_DOES_NOT_SUPPORT, MYF(0), "optional metadata transfer");
6386 return true;
6387 }
6388 return false;
6389 }
6390
6391 static const char *resultset_metadata_names[] = {"NONE", "FULL", NullS};
6392
6393 static Sys_var_enum Sys_resultset_metadata(
6394 "resultset_metadata",
6395 "Controls what meatadata the server will send to the client: "
6396 "either FULL (default) for all metadata, NONE for no metadata.",
6397 SESSION_ONLY(resultset_metadata), NO_CMD_LINE, resultset_metadata_names,
6398 DEFAULT(static_cast<ulong>(RESULTSET_METADATA_FULL)), NO_MUTEX_GUARD,
6399 NOT_IN_BINLOG, ON_CHECK(check_resultset_metadata), ON_UPDATE(nullptr));
6400
check_binlog_row_value_options(sys_var * self,THD * thd,set_var * var)6401 static bool check_binlog_row_value_options(sys_var *self, THD *thd,
6402 set_var *var) {
6403 DBUG_TRACE;
6404 if (check_session_admin_outside_trx_outside_sf_outside_sp(self, thd, var))
6405 return true;
6406 if (var->save_result.ulonglong_value != 0) {
6407 const char *msg = nullptr;
6408 int code = ER_WARN_BINLOG_PARTIAL_UPDATES_DISABLED;
6409 if (!mysql_bin_log.is_open())
6410 msg = "the binary log is closed";
6411 else if (!var->is_global_persist()) {
6412 if (!thd->variables.sql_log_bin)
6413 msg = "the binary log is disabled";
6414 else if (thd->variables.binlog_format == BINLOG_FORMAT_STMT)
6415 msg = "binlog_format=STATEMENT";
6416 else if (log_bin_use_v1_row_events) {
6417 msg = "binlog_row_value_options=PARTIAL_JSON";
6418 code = ER_WARN_BINLOG_V1_ROW_EVENTS_DISABLED;
6419 } else if (thd->variables.binlog_row_image == BINLOG_ROW_IMAGE_FULL) {
6420 msg = "binlog_row_image=FULL";
6421 code = ER_WARN_BINLOG_PARTIAL_UPDATES_SUGGESTS_PARTIAL_IMAGES;
6422 }
6423 } else {
6424 if (global_system_variables.binlog_format == BINLOG_FORMAT_STMT)
6425 msg = "binlog_format=STATEMENT";
6426 else if (log_bin_use_v1_row_events) {
6427 msg = "binlog_row_value_options=PARTIAL_JSON";
6428 code = ER_WARN_BINLOG_V1_ROW_EVENTS_DISABLED;
6429 } else if (global_system_variables.binlog_row_image ==
6430 BINLOG_ROW_IMAGE_FULL) {
6431 msg = "binlog_row_image=FULL";
6432 code = ER_WARN_BINLOG_PARTIAL_UPDATES_SUGGESTS_PARTIAL_IMAGES;
6433 }
6434 }
6435 if (msg) {
6436 switch (code) {
6437 case ER_WARN_BINLOG_PARTIAL_UPDATES_DISABLED:
6438 push_warning_printf(
6439 thd, Sql_condition::SL_WARNING, code,
6440 ER_THD(thd, ER_WARN_BINLOG_PARTIAL_UPDATES_DISABLED), msg,
6441 "PARTIAL_JSON");
6442 break;
6443 case ER_WARN_BINLOG_PARTIAL_UPDATES_SUGGESTS_PARTIAL_IMAGES:
6444 push_warning_printf(
6445 thd, Sql_condition::SL_WARNING, code,
6446 ER_THD(thd,
6447 ER_WARN_BINLOG_PARTIAL_UPDATES_SUGGESTS_PARTIAL_IMAGES),
6448 msg, "PARTIAL_JSON");
6449 break;
6450 case ER_WARN_BINLOG_V1_ROW_EVENTS_DISABLED:
6451 push_warning_printf(
6452 thd, Sql_condition::SL_WARNING, code,
6453 ER_THD(thd, ER_WARN_BINLOG_V1_ROW_EVENTS_DISABLED), msg);
6454 break;
6455 default:
6456 DBUG_ASSERT(0); /* purecov: deadcode */
6457 }
6458 }
6459 }
6460
6461 return false;
6462 }
6463
6464 const char *binlog_row_value_options_names[] = {"PARTIAL_JSON", nullptr};
6465 static Sys_var_set Sys_binlog_row_value_options(
6466 "binlog_row_value_options",
6467 "When set to PARTIAL_JSON, this option enables a space-efficient "
6468 "row-based binary log format for UPDATE statements that modify a "
6469 "JSON value using only the functions JSON_SET, JSON_REPLACE, and "
6470 "JSON_REMOVE. For such updates, only the modified parts of the "
6471 "JSON document are included in the binary log, so small changes of "
6472 "big documents may need significantly less space.",
6473 SESSION_VAR(binlog_row_value_options), CMD_LINE(REQUIRED_ARG),
6474 binlog_row_value_options_names, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
6475 ON_CHECK(check_binlog_row_value_options));
6476
check_keyring_access(sys_var *,THD * thd,set_var *)6477 static bool check_keyring_access(sys_var *, THD *thd, set_var *) {
6478 if (!thd->security_context()->check_access(SUPER_ACL) &&
6479 !(thd->security_context()
6480 ->has_global_grant(STRING_WITH_LEN("ENCRYPTION_KEY_ADMIN"))
6481 .first)) {
6482 my_error(ER_KEYRING_ACCESS_DENIED_ERROR, MYF(0),
6483 "SUPER or ENCRYPTION_KEY_ADMIN");
6484 return true;
6485 }
6486 return false;
6487 }
6488
6489 /**
6490 This is a mutex used to protect global variable @@keyring_operations.
6491 */
6492 static PolyLock_mutex PLock_keyring_operations(&LOCK_keyring_operations);
6493 /**
6494 This variable provides access to keyring service APIs. When this variable
6495 is disabled calls to keyring_key_generate(), keyring_key_store() and
6496 keyring_key_remove() will report error until this variable is enabled.
6497 This variable is protected under a mutex named PLock_keyring_operations.
6498 To access this variable you must first set this mutex.
6499
6500 @sa PLock_keyring_operations
6501 */
6502 static Sys_var_bool Sys_keyring_operations(
6503 "keyring_operations",
6504 "This variable provides access to keyring service APIs. When this "
6505 "option is disabled calls to keyring_key_generate(), keyring_key_store() "
6506 "and keyring_key_remove() will report error until this variable is "
6507 "enabled.",
6508 NON_PERSIST GLOBAL_VAR(opt_keyring_operations), NO_CMD_LINE, DEFAULT(true),
6509 &PLock_keyring_operations, NOT_IN_BINLOG, ON_CHECK(check_keyring_access),
6510 ON_UPDATE(nullptr));
6511
check_default_collation_for_utf8mb4(sys_var * self,THD * thd,set_var * var)6512 static bool check_default_collation_for_utf8mb4(sys_var *self, THD *thd,
6513 set_var *var) {
6514 if (check_collation_not_null(self, thd, var)) {
6515 return true;
6516 }
6517
6518 if (!var->value)
6519 var->save_result.ptr = reinterpret_cast<void *>(self->get_default());
6520
6521 auto cs = static_cast<const CHARSET_INFO *>(var->save_result.ptr);
6522 if (cs == &my_charset_utf8mb4_0900_ai_ci ||
6523 cs == &my_charset_utf8mb4_general_ci)
6524 return false;
6525
6526 my_error(ER_INVALID_DEFAULT_UTF8MB4_COLLATION, MYF(0), cs->name);
6527 return true;
6528 }
6529
6530 static Sys_var_struct<CHARSET_INFO, Get_name> Sys_default_collation_for_utf8mb4(
6531 "default_collation_for_utf8mb4",
6532 "Controls default collation for utf8mb4 while replicating implicit "
6533 "utf8mb4 collations.",
6534 SESSION_VAR(default_collation_for_utf8mb4), NO_CMD_LINE,
6535 DEFAULT(&my_charset_utf8mb4_0900_ai_ci), NO_MUTEX_GUARD, IN_BINLOG,
6536 ON_CHECK(check_default_collation_for_utf8mb4),
6537 ON_UPDATE(update_deprecated));
6538
6539 static Sys_var_bool Sys_show_create_table_verbosity(
6540 "show_create_table_verbosity",
6541 "When this option is enabled, it increases the verbosity of "
6542 "'SHOW CREATE TABLE'.",
6543 SESSION_VAR(show_create_table_verbosity), CMD_LINE(OPT_ARG), DEFAULT(false),
6544 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr));
6545
6546 static const char *use_secondary_engine_values[] = {"OFF", "ON", "FORCED",
6547 nullptr};
6548 static Sys_var_enum Sys_use_secondary_engine(
6549 "use_secondary_engine",
6550 "Controls preparation of SELECT statements against secondary storage "
6551 "engine. Valid values: OFF/ON/FORCED. OFF = Prepare only against primary "
6552 "storage engine. ON = First prepare against secondary storage engine, "
6553 "reprepare against primary storage engine if error. FORCED = Prepare all "
6554 "SELECT statements referencing one or more base tables only against "
6555 "secondary storage engine.",
6556 HINT_UPDATEABLE SESSION_ONLY(use_secondary_engine), NO_CMD_LINE,
6557 use_secondary_engine_values, DEFAULT(SECONDARY_ENGINE_ON), NO_MUTEX_GUARD,
6558 NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr));
6559
6560 /**
6561 Cost threshold for executing queries in a secondary storage engine. Only
6562 queries that have an estimated cost above this value will be attempted
6563 executed in a secondary storage engine.
6564
6565 Secondary storage engines are meant to accelerate queries that would otherwise
6566 take a relatively long time to execute. If a secondary storage engine accepts
6567 a query, it is assumed that it will be able to accelerate it. However, if the
6568 estimated cost of the query is low, the query will execute fast in the primary
6569 engine too, so there is little to gain by offloading the query to the
6570 secondary engine.
6571
6572 The default value aims to avoid use of secondary storage engines for queries
6573 that could be executed by the primary engine in a few tenths of seconds or
6574 less, and attempt to use secondary storage engines for queries would take
6575 seconds or more.
6576 */
6577 static Sys_var_double Sys_secondary_engine_cost_threshold(
6578 "secondary_engine_cost_threshold",
6579 "Controls which statements to consider for execution in a secondary "
6580 "storage engine. Only statements that have a cost estimate higher than "
6581 "this value will be attempted executed in a secondary storage engine.",
6582 HINT_UPDATEABLE SESSION_VAR(secondary_engine_cost_threshold),
6583 CMD_LINE(OPT_ARG), VALID_RANGE(0, DBL_MAX), DEFAULT(100000), NO_MUTEX_GUARD,
6584 NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr));
6585
6586 static Sys_var_bool Sys_sql_require_primary_key{
6587 "sql_require_primary_key",
6588 "When set, tables must be created with a primary key, and an existing "
6589 "primary key cannot be removed with 'ALTER TABLE'. Attempts to do so "
6590 "will result in an error.",
6591 HINT_UPDATEABLE SESSION_VAR(sql_require_primary_key),
6592 CMD_LINE(OPT_ARG),
6593 DEFAULT(false),
6594 NO_MUTEX_GUARD,
6595 IN_BINLOG,
6596 ON_CHECK(check_session_admin)};
6597
6598 static Sys_var_charptr Sys_sys_variables_admin_subject(
6599 PERSIST_ONLY_ADMIN_X509_SUBJECT,
6600 "The client peer certificate name required to enable setting all "
6601 "system variables via SET PERSIST[_ONLY]",
6602 READ_ONLY NON_PERSIST GLOBAL_VAR(sys_var_persist_only_admin_x509_subject),
6603 CMD_LINE(OPT_ARG), IN_SYSTEM_CHARSET, DEFAULT(""));
6604
6605 static Sys_var_ulong Sys_binlog_row_event_max_size(
6606 "binlog_row_event_max_size",
6607 "The maximum size of a row-based binary log event in bytes. Rows will be "
6608 "grouped into events smaller than this size if possible. "
6609 "The value has to be a multiple of 256.",
6610 READ_ONLY GLOBAL_VAR(binlog_row_event_max_size), CMD_LINE(REQUIRED_ARG),
6611 VALID_RANGE(256, ULONG_MAX), DEFAULT(8192), BLOCK_SIZE(256));
6612
check_group_replication_consistency(sys_var * self,THD * thd,set_var * var)6613 static bool check_group_replication_consistency(sys_var *self, THD *thd,
6614 set_var *var) {
6615 if (var->type == OPT_GLOBAL || var->type == OPT_PERSIST) {
6616 Security_context *sctx = thd->security_context();
6617 if (!sctx->check_access(SUPER_ACL) &&
6618 !sctx->has_global_grant(STRING_WITH_LEN("GROUP_REPLICATION_ADMIN"))
6619 .first) {
6620 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0),
6621 "SUPER or GROUP_REPLICATION_ADMIN");
6622 return true;
6623 }
6624 }
6625
6626 return check_outside_trx(self, thd, var);
6627 }
6628
6629 static const char *group_replication_consistency_names[] = {
6630 "EVENTUAL", "BEFORE_ON_PRIMARY_FAILOVER", "BEFORE",
6631 "AFTER", "BEFORE_AND_AFTER", NullS};
6632
6633 static Sys_var_enum Sys_group_replication_consistency(
6634 "group_replication_consistency",
6635 "Transaction consistency guarantee, possible values: EVENTUAL, "
6636 "BEFORE_ON_PRIMARY_FAILOVER, BEFORE, AFTER, BEFORE_AND_AFTER",
6637 SESSION_VAR(group_replication_consistency), CMD_LINE(OPT_ARG),
6638 group_replication_consistency_names,
6639 DEFAULT(GROUP_REPLICATION_CONSISTENCY_EVENTUAL), NO_MUTEX_GUARD,
6640 NOT_IN_BINLOG, ON_CHECK(check_group_replication_consistency),
6641 ON_UPDATE(nullptr));
6642
check_binlog_encryption_admin(sys_var *,THD * thd,set_var *)6643 static bool check_binlog_encryption_admin(sys_var *, THD *thd, set_var *) {
6644 DBUG_TRACE;
6645 if (!thd->security_context()->check_access(SUPER_ACL) &&
6646 !(thd->security_context()
6647 ->has_global_grant(STRING_WITH_LEN("BINLOG_ENCRYPTION_ADMIN"))
6648 .first)) {
6649 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0),
6650 "SUPER or BINLOG_ENCRYPTION_ADMIN");
6651 return true;
6652 }
6653 return false;
6654 }
6655
global_update(THD * thd,set_var * var)6656 bool Sys_var_binlog_encryption::global_update(THD *thd, set_var *var) {
6657 DBUG_TRACE;
6658
6659 /* No-op if trying to set to current value */
6660 bool new_value = var->save_result.ulonglong_value;
6661 if (new_value == rpl_encryption.is_enabled()) return false;
6662
6663 DEBUG_SYNC(thd, "after_locking_global_sys_var_set_binlog_enc");
6664 /* We unlock in following statement to avoid deadlock involving following
6665 * conditions.
6666 * ------------------------------------------------------------------------
6667 * Thread 1 (START SLAVE) has locked channel_map and waiting for cond_wait
6668 * that is supposed to be done by Thread 2.
6669 *
6670 * Thread 2 (handle_slave_io) is supposed to signal Thread 1 but waiting to
6671 * lock LOCK_global_system_variables.
6672 *
6673 * Thread 3 (SET GLOBAL binlog_encryption=ON|OFF) has locked
6674 * LOCK_global_system_variables and waiting for channel_map.
6675 */
6676 mysql_mutex_unlock(&LOCK_global_system_variables);
6677 /* Set the option new value */
6678 bool res = false;
6679 if (new_value)
6680 res = rpl_encryption.enable(thd);
6681 else
6682 rpl_encryption.disable(thd);
6683 mysql_mutex_lock(&LOCK_global_system_variables);
6684 return res;
6685 }
6686
6687 static Sys_var_binlog_encryption Sys_binlog_encryption(
6688 "binlog_encryption", "Enable/disable binary and relay logs encryption.",
6689 GLOBAL_VAR(rpl_encryption.get_enabled_var()), CMD_LINE(OPT_ARG),
6690 DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG,
6691 ON_CHECK(check_binlog_encryption_admin));
6692
6693 static Sys_var_bool Sys_binlog_rotate_encryption_master_key_at_startup(
6694 "binlog_rotate_encryption_master_key_at_startup",
6695 "Force binlog encryption master key rotation at startup",
6696 READ_ONLY GLOBAL_VAR(
6697 rpl_encryption.get_master_key_rotation_at_startup_var()),
6698 CMD_LINE(OPT_ARG), DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG);
6699
6700 static Sys_var_uint Sys_original_server_version(
6701 "original_server_version",
6702 "The version of the server where the transaction was originally executed",
6703 SESSION_ONLY(original_server_version), NO_CMD_LINE,
6704 VALID_RANGE(0, UNDEFINED_SERVER_VERSION), DEFAULT(UNDEFINED_SERVER_VERSION),
6705 BLOCK_SIZE(1), NO_MUTEX_GUARD, IN_BINLOG,
6706 ON_CHECK(check_session_admin_or_replication_applier));
6707
6708 static Sys_var_uint Sys_immediate_server_version(
6709 "immediate_server_version",
6710 "The server version of the immediate server in the replication topology",
6711 SESSION_ONLY(immediate_server_version), NO_CMD_LINE,
6712 VALID_RANGE(0, UNDEFINED_SERVER_VERSION), DEFAULT(UNDEFINED_SERVER_VERSION),
6713 BLOCK_SIZE(1), NO_MUTEX_GUARD, IN_BINLOG,
6714 ON_CHECK(check_session_admin_or_replication_applier));
6715
check_set_default_table_encryption_access(sys_var * self MY_ATTRIBUTE ((unused)),THD * thd,set_var * var)6716 static bool check_set_default_table_encryption_access(
6717 sys_var *self MY_ATTRIBUTE((unused)), THD *thd, set_var *var) {
6718 DBUG_EXECUTE_IF("skip_table_encryption_admin_check_for_set",
6719 { return false; });
6720 if ((var->type == OPT_GLOBAL || var->type == OPT_PERSIST) &&
6721 is_group_replication_running()) {
6722 my_message(ER_GROUP_REPLICATION_RUNNING,
6723 "The default_table_encryption option cannot be changed when "
6724 "Group replication is running.",
6725 MYF(0));
6726 return true;
6727 }
6728
6729 // Should own one of SUPER or both (SYSTEM_VARIABLES_ADMIN and
6730 // TABLE_ENCRYPTION_ADMIN), unless this is the session option and
6731 // the value is unchanged.
6732 longlong previous_val = thd->variables.default_table_encryption;
6733 longlong val = (longlong)var->save_result.ulonglong_value;
6734 if ((!var->is_global_persist() && val == previous_val) ||
6735 thd->security_context()->check_access(SUPER_ACL) ||
6736 (thd->security_context()
6737 ->has_global_grant(STRING_WITH_LEN("SYSTEM_VARIABLES_ADMIN"))
6738 .first &&
6739 thd->security_context()
6740 ->has_global_grant(STRING_WITH_LEN("TABLE_ENCRYPTION_ADMIN"))
6741 .first)) {
6742 return false;
6743 }
6744
6745 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0),
6746 "SUPER or SYSTEM_VARIABLES_ADMIN and TABLE_ENCRYPTION_ADMIN");
6747 return true;
6748 }
6749
6750 static Sys_var_bool Sys_default_table_encryption(
6751 "default_table_encryption",
6752 "Database and tablespace are created with this default encryption property "
6753 "unless the user specifies an explicit encryption property.",
6754 HINT_UPDATEABLE SESSION_VAR(default_table_encryption), CMD_LINE(OPT_ARG),
6755 DEFAULT(false), NO_MUTEX_GUARD, IN_BINLOG,
6756 ON_CHECK(check_set_default_table_encryption_access), ON_UPDATE(nullptr));
6757
check_set_table_encryption_privilege_access(sys_var *,THD * thd,set_var *)6758 static bool check_set_table_encryption_privilege_access(sys_var *, THD *thd,
6759 set_var *) {
6760 DBUG_EXECUTE_IF("skip_table_encryption_admin_check_for_set",
6761 { return false; });
6762 if (!thd->security_context()->check_access(SUPER_ACL)) {
6763 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
6764 return true;
6765 }
6766 return false;
6767 }
6768
6769 static Sys_var_bool Sys_table_encryption_privilege_check(
6770 "table_encryption_privilege_check",
6771 "Indicates if server enables privilege check when user tries to use "
6772 "non-default value for CREATE DATABASE or CREATE TABLESPACE or when "
6773 "user tries to do CREATE TABLE with ENCRYPTION option which deviates "
6774 "from per-database default.",
6775 GLOBAL_VAR(opt_table_encryption_privilege_check), CMD_LINE(OPT_ARG),
6776 DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG,
6777 ON_CHECK(check_set_table_encryption_privilege_access), ON_UPDATE(nullptr));
6778
6779 static Sys_var_bool Sys_var_print_identified_with_as_hex(
6780 "print_identified_with_as_hex",
6781 "SHOW CREATE USER will print the AS clause as HEX if it contains "
6782 "non-prinable characters",
6783 SESSION_VAR(print_identified_with_as_hex), CMD_LINE(OPT_ARG),
6784 DEFAULT(false));
6785
6786 /**
6787 Session only flag to skip printing secondary engine in SHOW CREATE
6788 TABLE.
6789
6790 @sa store_create_info
6791 */
6792 static Sys_var_bool Sys_var_show_create_table_skip_secondary_engine(
6793 "show_create_table_skip_secondary_engine",
6794 "SHOW CREATE TABLE will skip SECONDARY_ENGINE when printing the table "
6795 "definition",
6796 SESSION_ONLY(show_create_table_skip_secondary_engine), NO_CMD_LINE,
6797 DEFAULT(false));
6798
6799 static Sys_var_uint Sys_generated_random_password_length(
6800 "generated_random_password_length",
6801 "Determines the length randomly generated passwords in CREATE USER-,"
6802 "SET PASSWORD- or ALTER USER statements",
6803 SESSION_VAR(generated_random_password_length), CMD_LINE(REQUIRED_ARG),
6804 VALID_RANGE(5, 255), DEFAULT(20), BLOCK_SIZE(1), NO_MUTEX_GUARD, IN_BINLOG,
6805 ON_CHECK(nullptr));
6806
check_set_protocol_compression_algorithms(sys_var *,THD *,set_var * var)6807 static bool check_set_protocol_compression_algorithms(sys_var *, THD *,
6808 set_var *var) {
6809 if (!(var->save_result.string_value.str)) return true;
6810 return validate_compression_attributes(var->save_result.string_value.str,
6811 std::string(), true);
6812 }
6813
6814 static Sys_var_charptr Sys_protocol_compression_algorithms(
6815 "protocol_compression_algorithms",
6816 "List of compression algorithms supported by server. Supported values "
6817 "are any combination of zlib, zstd, uncompressed. Command line clients "
6818 "may use the --compression-algorithms flag to specify a set of algorithms, "
6819 "and the connection will use an algorithm supported by both client and "
6820 "server. It picks zlib if both client and server support it; otherwise it "
6821 "picks zstd if both support it; otherwise it picks uncompressed if both "
6822 "support it; otherwise it fails.",
6823 GLOBAL_VAR(opt_protocol_compression_algorithms), CMD_LINE(REQUIRED_ARG),
6824 IN_FS_CHARSET,
6825 DEFAULT(const_cast<char *>(PROTOCOL_COMPRESSION_DEFAULT_VALUE)),
6826 NO_MUTEX_GUARD, NOT_IN_BINLOG,
6827 ON_CHECK(check_set_protocol_compression_algorithms), ON_UPDATE(nullptr));
6828
check_set_require_row_format(sys_var *,THD * thd,set_var * var)6829 static bool check_set_require_row_format(sys_var *, THD *thd, set_var *var) {
6830 /*
6831 Should own SUPER or SYSTEM_VARIABLES_ADMIN or SESSION_VARIABLES_ADMIN
6832 when the value is changing to NO, no privileges are needed to set to YES
6833 */
6834 longlong previous_val = thd->variables.require_row_format;
6835 longlong val = (longlong)var->save_result.ulonglong_value;
6836 DBUG_ASSERT(!var->is_global_persist());
6837
6838 // if it was true and we are changing it
6839 if (previous_val && val != previous_val) {
6840 if (thd->security_context()->check_access(SUPER_ACL) ||
6841 thd->security_context()
6842 ->has_global_grant(STRING_WITH_LEN("SYSTEM_VARIABLES_ADMIN"))
6843 .first ||
6844 thd->security_context()
6845 ->has_global_grant(STRING_WITH_LEN("SESSION_VARIABLES_ADMIN"))
6846 .first)
6847 return false;
6848
6849 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0),
6850 "SUPER or SYSTEM_VARIABLES_ADMIN or SESSION_VARIABLES_ADMIN");
6851 return true;
6852 }
6853 return false;
6854 }
6855
6856 /**
6857 Session only flag to limit the application of queries to row based events
6858 and DDLs with the exception of temporary table creation/deletion
6859 */
6860 static Sys_var_bool Sys_var_require_row_format(
6861 "require_row_format",
6862 "Limit the application of queries to row based events "
6863 "and DDLs with the exception of temporary table creation/deletion.",
6864 SESSION_ONLY(require_row_format), NO_CMD_LINE, DEFAULT(false),
6865 NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_set_require_row_format));
6866