1 /* Copyright (c) 2002, 2015, Oracle and/or its affiliates.
2    Copyright (c) 2012, 2020, MariaDB Corporation.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; version 2 of the License.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335  USA */
16 
17 /**
18   @file
19   Definitions of all server's session or global variables.
20 
21   How to add new variables:
22 
23   1. copy one of the existing variables, and edit the declaration.
24   2. if you need special behavior on assignment or additional checks
25      use ON_CHECK and ON_UPDATE callbacks.
26   3. *Don't* add new Sys_var classes or uncle Occam will come
27      with his razor to haunt you at nights
28 
29   Note - all storage engine variables (for example myisam_whatever)
30   should go into the corresponding storage engine sources
31   (for example in storage/myisam/ha_myisam.cc) !
32 */
33 
34 #include "sql_plugin.h"
35 #include "sql_priv.h"
36 #include "sql_class.h"                          // set_var.h: THD
37 #include "sys_vars.inl"
38 #include "my_sys.h"
39 
40 #include "events.h"
41 #include <thr_alarm.h>
42 #include "slave.h"
43 #include "rpl_mi.h"
44 #include "transaction.h"
45 #include "mysqld.h"
46 #include "lock.h"
47 #include "sql_time.h"                       // known_date_time_formats
48 #include "sql_acl.h" // SUPER_ACL,
49                      // mysql_user_table_is_in_short_password_format
50 #include "derror.h"  // read_texts
51 #include "sql_base.h"                           // close_cached_tables
52 #include "hostname.h"                           // host_cache_size
53 #include <myisam.h>
54 #include "debug_sync.h"                         // DEBUG_SYNC
55 #include "sql_show.h"
56 #include "opt_trace_context.h"
57 
58 #include "log_event.h"
59 #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
60 #include "../storage/perfschema/pfs_server.h"
61 #endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
62 #include "threadpool.h"
63 #include "sql_repl.h"
64 #include "opt_range.h"
65 #include "rpl_parallel.h"
66 #include "semisync_master.h"
67 #include "semisync_slave.h"
68 #include <ssl_compat.h>
69 
70 /*
71   The rule for this file: everything should be 'static'. When a sys_var
72   variable or a function from this file is - in very rare cases - needed
73   elsewhere it should be explicitly declared 'export' here to show that it's
74   not a mistakenly forgotten 'static' keyword.
75 */
76 #define export /* not static */
77 
78 #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
79 
80 static Sys_var_mybool Sys_pfs_enabled(
81        "performance_schema",
82        "Enable the performance schema.",
83        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_enabled),
84        CMD_LINE(OPT_ARG), DEFAULT(FALSE));
85 
86 static Sys_var_long Sys_pfs_events_waits_history_long_size(
87        "performance_schema_events_waits_history_long_size",
88        "Number of rows in EVENTS_WAITS_HISTORY_LONG."
89        " Use 0 to disable, -1 for automated sizing.",
90        PARSED_EARLY READ_ONLY
91        GLOBAL_VAR(pfs_param.m_events_waits_history_long_sizing),
92        CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024*1024),
93        DEFAULT(-1), BLOCK_SIZE(1));
94 
95 static Sys_var_long Sys_pfs_events_waits_history_size(
96        "performance_schema_events_waits_history_size",
97        "Number of rows per thread in EVENTS_WAITS_HISTORY."
98        " Use 0 to disable, -1 for automated sizing.",
99        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_events_waits_history_sizing),
100        CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024),
101        DEFAULT(-1), BLOCK_SIZE(1));
102 
103 static Sys_var_ulong Sys_pfs_max_cond_classes(
104        "performance_schema_max_cond_classes",
105        "Maximum number of condition instruments.",
106        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_cond_class_sizing),
107        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 256),
108        DEFAULT(PFS_MAX_COND_CLASS), BLOCK_SIZE(1));
109 
110 static Sys_var_long Sys_pfs_max_cond_instances(
111        "performance_schema_max_cond_instances",
112        "Maximum number of instrumented condition objects."
113        " Use 0 to disable, -1 for automated sizing.",
114        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_cond_sizing),
115        CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024*1024),
116        DEFAULT(-1), BLOCK_SIZE(1));
117 
118 static Sys_var_ulong Sys_pfs_max_file_classes(
119        "performance_schema_max_file_classes",
120        "Maximum number of file instruments.",
121        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_file_class_sizing),
122        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 256),
123        DEFAULT(PFS_MAX_FILE_CLASS), BLOCK_SIZE(1));
124 
125 static Sys_var_ulong Sys_pfs_max_file_handles(
126        "performance_schema_max_file_handles",
127        "Maximum number of opened instrumented files.",
128        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_file_handle_sizing),
129        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024*1024),
130        DEFAULT(PFS_MAX_FILE_HANDLE), BLOCK_SIZE(1));
131 
132 static Sys_var_long Sys_pfs_max_file_instances(
133        "performance_schema_max_file_instances",
134        "Maximum number of instrumented files."
135        " Use 0 to disable, -1 for automated sizing.",
136        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_file_sizing),
137        CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024*1024),
138        DEFAULT(-1), BLOCK_SIZE(1));
139 
140 static Sys_var_long Sys_pfs_max_sockets(
141        "performance_schema_max_socket_instances",
142        "Maximum number of opened instrumented sockets."
143        " Use 0 to disable, -1 for automated sizing.",
144        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_socket_sizing),
145        CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024*1024),
146        DEFAULT(-1),
147        BLOCK_SIZE(1));
148 
149 static Sys_var_ulong Sys_pfs_max_socket_classes(
150        "performance_schema_max_socket_classes",
151        "Maximum number of socket instruments.",
152        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_socket_class_sizing),
153        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 256),
154        DEFAULT(PFS_MAX_SOCKET_CLASS),
155        BLOCK_SIZE(1));
156 
157 static Sys_var_ulong Sys_pfs_max_mutex_classes(
158        "performance_schema_max_mutex_classes",
159        "Maximum number of mutex instruments.",
160        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_mutex_class_sizing),
161        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 256),
162        DEFAULT(PFS_MAX_MUTEX_CLASS), BLOCK_SIZE(1));
163 
164 static Sys_var_long Sys_pfs_max_mutex_instances(
165        "performance_schema_max_mutex_instances",
166        "Maximum number of instrumented MUTEX objects."
167        " Use 0 to disable, -1 for automated sizing.",
168        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_mutex_sizing),
169        CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 100*1024*1024),
170        DEFAULT(-1), BLOCK_SIZE(1));
171 
172 static Sys_var_ulong Sys_pfs_max_rwlock_classes(
173        "performance_schema_max_rwlock_classes",
174        "Maximum number of rwlock instruments.",
175        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_rwlock_class_sizing),
176        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 256),
177        DEFAULT(PFS_MAX_RWLOCK_CLASS), BLOCK_SIZE(1));
178 
179 static Sys_var_long Sys_pfs_max_rwlock_instances(
180        "performance_schema_max_rwlock_instances",
181        "Maximum number of instrumented RWLOCK objects."
182        " Use 0 to disable, -1 for automated sizing.",
183        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_rwlock_sizing),
184        CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 100*1024*1024),
185        DEFAULT(-1), BLOCK_SIZE(1));
186 
187 static Sys_var_long Sys_pfs_max_table_handles(
188        "performance_schema_max_table_handles",
189        "Maximum number of opened instrumented tables."
190        " Use 0 to disable, -1 for automated sizing.",
191        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_table_sizing),
192        CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024*1024),
193        DEFAULT(-1), BLOCK_SIZE(1));
194 
195 static Sys_var_long Sys_pfs_max_table_instances(
196        "performance_schema_max_table_instances",
197        "Maximum number of instrumented tables."
198        " Use 0 to disable, -1 for automated sizing.",
199        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_table_share_sizing),
200        CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024*1024),
201        DEFAULT(-1), BLOCK_SIZE(1));
202 
203 static Sys_var_ulong Sys_pfs_max_thread_classes(
204        "performance_schema_max_thread_classes",
205        "Maximum number of thread instruments.",
206        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_thread_class_sizing),
207        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 256),
208        DEFAULT(PFS_MAX_THREAD_CLASS), BLOCK_SIZE(1));
209 
210 static Sys_var_long Sys_pfs_max_thread_instances(
211        "performance_schema_max_thread_instances",
212        "Maximum number of instrumented threads."
213        " Use 0 to disable, -1 for automated sizing.",
214        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_thread_sizing),
215        CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024*1024),
216        DEFAULT(-1), BLOCK_SIZE(1));
217 
218 static Sys_var_ulong Sys_pfs_setup_actors_size(
219        "performance_schema_setup_actors_size",
220        "Maximum number of rows in SETUP_ACTORS.",
221        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_setup_actor_sizing),
222        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024),
223        DEFAULT(PFS_MAX_SETUP_ACTOR),
224        BLOCK_SIZE(1));
225 
226 static Sys_var_ulong Sys_pfs_setup_objects_size(
227        "performance_schema_setup_objects_size",
228        "Maximum number of rows in SETUP_OBJECTS.",
229        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_setup_object_sizing),
230        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024*1024),
231        DEFAULT(PFS_MAX_SETUP_OBJECT),
232        BLOCK_SIZE(1));
233 
234 static Sys_var_long Sys_pfs_accounts_size(
235        "performance_schema_accounts_size",
236        "Maximum number of instrumented user@host accounts."
237        " Use 0 to disable, -1 for automated sizing.",
238        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_account_sizing),
239        CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024*1024),
240        DEFAULT(-1),
241        BLOCK_SIZE(1));
242 
243 static Sys_var_long Sys_pfs_hosts_size(
244        "performance_schema_hosts_size",
245        "Maximum number of instrumented hosts."
246        " Use 0 to disable, -1 for automated sizing.",
247        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_host_sizing),
248        CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024*1024),
249        DEFAULT(-1),
250        BLOCK_SIZE(1));
251 
252 static Sys_var_long Sys_pfs_users_size(
253        "performance_schema_users_size",
254        "Maximum number of instrumented users."
255        " Use 0 to disable, -1 for automated sizing.",
256        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_user_sizing),
257        CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024*1024),
258        DEFAULT(-1),
259        BLOCK_SIZE(1));
260 
261 static Sys_var_ulong Sys_pfs_max_stage_classes(
262        "performance_schema_max_stage_classes",
263        "Maximum number of stage instruments.",
264        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_stage_class_sizing),
265        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 256),
266        DEFAULT(PFS_MAX_STAGE_CLASS),
267        BLOCK_SIZE(1));
268 
269 static Sys_var_long Sys_pfs_events_stages_history_long_size(
270        "performance_schema_events_stages_history_long_size",
271        "Number of rows in EVENTS_STAGES_HISTORY_LONG."
272        " Use 0 to disable, -1 for automated sizing.",
273        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_events_stages_history_long_sizing),
274        CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024*1024),
275        DEFAULT(-1),
276        BLOCK_SIZE(1));
277 
278 static Sys_var_long Sys_pfs_events_stages_history_size(
279        "performance_schema_events_stages_history_size",
280        "Number of rows per thread in EVENTS_STAGES_HISTORY."
281        " Use 0 to disable, -1 for automated sizing.",
282        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_events_stages_history_sizing),
283        CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024),
284        DEFAULT(-1),
285        BLOCK_SIZE(1));
286 
287 /**
288   Variable performance_schema_max_statement_classes.
289   The default number of statement classes is the sum of:
290   - (COM_END - mariadb gap) for all regular "statement/com/...",
291   - 1 for "statement/com/new_packet", for unknown enum_server_command
292   - 1 for "statement/com/Error", for invalid enum_server_command
293   - SQLCOM_END for all regular "statement/sql/...",
294   - 1 for "statement/sql/error", for invalid enum_sql_command
295   - 1 for "statement/rpl/relay_log", for replicated statements.
296 */
297 static Sys_var_ulong Sys_pfs_max_statement_classes(
298        "performance_schema_max_statement_classes",
299        "Maximum number of statement instruments.",
300        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_statement_class_sizing),
301        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 256),
302        DEFAULT((ulong) SQLCOM_END +
303                (ulong) (COM_END -(COM_MDB_GAP_END - COM_MDB_GAP_BEG + 1)) + 4),
304        BLOCK_SIZE(1));
305 
306 static Sys_var_long Sys_pfs_events_statements_history_long_size(
307        "performance_schema_events_statements_history_long_size",
308        "Number of rows in EVENTS_STATEMENTS_HISTORY_LONG."
309        " Use 0 to disable, -1 for automated sizing.",
310        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_events_statements_history_long_sizing),
311        CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024*1024),
312        DEFAULT(-1),
313        BLOCK_SIZE(1));
314 
315 static Sys_var_long Sys_pfs_events_statements_history_size(
316        "performance_schema_events_statements_history_size",
317        "Number of rows per thread in EVENTS_STATEMENTS_HISTORY."
318        " Use 0 to disable, -1 for automated sizing.",
319        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_events_statements_history_sizing),
320        CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024),
321        DEFAULT(-1),
322        BLOCK_SIZE(1));
323 
324 static Sys_var_long Sys_pfs_digest_size(
325        "performance_schema_digests_size",
326        "Size of the statement digest."
327        " Use 0 to disable, -1 for automated sizing.",
328        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_digest_sizing),
329        CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024 * 1024),
330        DEFAULT(-1),
331        BLOCK_SIZE(1));
332 
333 static Sys_var_long Sys_pfs_max_digest_length(
334        "performance_schema_max_digest_length",
335        "Maximum length considered for digest text, when stored in performance_schema tables.",
336        PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_max_digest_length),
337        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024 * 1024),
338        DEFAULT(1024),
339        BLOCK_SIZE(1));
340 
341 static Sys_var_long Sys_pfs_connect_attrs_size(
342        "performance_schema_session_connect_attrs_size",
343        "Size of session attribute string buffer per thread."
344          " Use 0 to disable, -1 for automated sizing.",
345        PARSED_EARLY READ_ONLY
346        GLOBAL_VAR(pfs_param.m_session_connect_attrs_sizing),
347        CMD_LINE(REQUIRED_ARG), VALID_RANGE(-1, 1024 * 1024),
348        DEFAULT(-1),
349        BLOCK_SIZE(1));
350 
351 #endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
352 
353 #ifdef WITH_WSREP
354 
355 /*
356   We need to keep the original values set by the user, as they will
357   be lost if wsrep_auto_increment_control set to 'ON':
358 */
359 static bool update_auto_increment_increment (sys_var *self, THD *thd, enum_var_type type)
360 {
361   if (type == OPT_GLOBAL)
362     global_system_variables.saved_auto_increment_increment=
363       global_system_variables.auto_increment_increment;
364   else
365     thd->variables.saved_auto_increment_increment=
366       thd->variables.auto_increment_increment;
367   return false;
368 }
369 
370 #endif /* WITH_WSREP */
371 
372 static Sys_var_double Sys_analyze_sample_percentage(
373        "analyze_sample_percentage",
374        "Percentage of rows from the table ANALYZE TABLE will sample "
375        "to collect table statistics. Set to 0 to let MariaDB decide "
376        "what percentage of rows to sample.",
377        SESSION_VAR(sample_percentage),
378        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 100),
379        DEFAULT(100));
380 
381 static Sys_var_ulong Sys_auto_increment_increment(
382        "auto_increment_increment",
383        "Auto-increment columns are incremented by this",
384        SESSION_VAR(auto_increment_increment),
385        CMD_LINE(OPT_ARG),
386        VALID_RANGE(1, 65535), DEFAULT(1), BLOCK_SIZE(1),
387 #ifdef WITH_WSREP
388        NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(0),
389        ON_UPDATE(update_auto_increment_increment));
390 #else
391        NO_MUTEX_GUARD, IN_BINLOG);
392 #endif /* WITH_WSREP */
393 
394 #ifdef WITH_WSREP
395 
396 /*
397   We need to keep the original values set by the user, as they will
398   be lost if wsrep_auto_increment_control set to 'ON':
399 */
400 static bool update_auto_increment_offset (sys_var *self, THD *thd, enum_var_type type)
401 {
402   if (type == OPT_GLOBAL)
403     global_system_variables.saved_auto_increment_offset=
404       global_system_variables.auto_increment_offset;
405   else
406     thd->variables.saved_auto_increment_offset=
407       thd->variables.auto_increment_offset;
408   return false;
409 }
410 
411 #endif /* WITH_WSREP */
412 
413 static Sys_var_ulong Sys_auto_increment_offset(
414        "auto_increment_offset",
415        "Offset added to Auto-increment columns. Used when "
416        "auto-increment-increment != 1",
417        SESSION_VAR(auto_increment_offset),
418        CMD_LINE(OPT_ARG),
419        VALID_RANGE(1, 65535), DEFAULT(1), BLOCK_SIZE(1),
420 #ifdef WITH_WSREP
421        NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(0),
422        ON_UPDATE(update_auto_increment_offset));
423 #else
424        NO_MUTEX_GUARD, IN_BINLOG);
425 #endif /* WITH_WSREP */
426 
427 static Sys_var_mybool Sys_automatic_sp_privileges(
428        "automatic_sp_privileges",
429        "Creating and dropping stored procedures alters ACLs",
430        GLOBAL_VAR(sp_automatic_privileges),
431        CMD_LINE(OPT_ARG), DEFAULT(TRUE));
432 
433 static Sys_var_ulong Sys_back_log(
434        "back_log", "The number of outstanding connection requests "
435        "MariaDB can have. This comes into play when the main MariaDB thread "
436        "gets very many connection requests in a very short time",
437        AUTO_SET READ_ONLY GLOBAL_VAR(back_log), CMD_LINE(REQUIRED_ARG),
438        VALID_RANGE(0, 65535), DEFAULT(150), BLOCK_SIZE(1));
439 
440 static Sys_var_charptr Sys_basedir(
441        "basedir", "Path to installation directory. All paths are "
442        "usually resolved relative to this",
443        READ_ONLY GLOBAL_VAR(mysql_home_ptr), CMD_LINE(REQUIRED_ARG, 'b'),
444        IN_FS_CHARSET, DEFAULT(0));
445 
446 static Sys_var_charptr Sys_my_bind_addr(
447        "bind_address", "IP address to bind to.",
448        READ_ONLY GLOBAL_VAR(my_bind_addr_str), CMD_LINE(REQUIRED_ARG),
449        IN_FS_CHARSET, DEFAULT(0));
450 
451 static Sys_var_vers_asof Sys_vers_asof_timestamp(
452        "system_versioning_asof", "Default value for the FOR SYSTEM_TIME AS OF clause",
453        SESSION_VAR(vers_asof_timestamp.type), NO_CMD_LINE,
454        DEFAULT(SYSTEM_TIME_UNSPECIFIED));
455 
456 static const char *vers_alter_history_keywords[]= {"ERROR", "KEEP", NullS};
457 static Sys_var_enum Sys_vers_alter_history(
458        "system_versioning_alter_history", "Versioning ALTER TABLE mode. "
459        "ERROR: Fail ALTER with error; " /* TODO: fail only when history non-empty */
460        "KEEP: Keep historical system rows and subject them to ALTER",
461        SESSION_VAR(vers_alter_history), CMD_LINE(REQUIRED_ARG),
462        vers_alter_history_keywords, DEFAULT(VERS_ALTER_HISTORY_ERROR));
463 
464 static Sys_var_ulonglong Sys_binlog_cache_size(
465        "binlog_cache_size", "The size of the transactional cache for "
466        "updates to transactional engines for the binary log. "
467        "If you often use transactions containing many statements, "
468        "you can increase this to get more performance",
469        GLOBAL_VAR(binlog_cache_size),
470        CMD_LINE(REQUIRED_ARG),
471        VALID_RANGE(IO_SIZE, SIZE_T_MAX), DEFAULT(32768), BLOCK_SIZE(IO_SIZE));
472 
473 static Sys_var_ulonglong  Sys_binlog_file_cache_size(
474        "binlog_file_cache_size",
475        "The size of file cache for the binary log",
476        GLOBAL_VAR(binlog_file_cache_size),
477        CMD_LINE(REQUIRED_ARG),
478        VALID_RANGE(IO_SIZE*2, SIZE_T_MAX), DEFAULT(IO_SIZE*4), BLOCK_SIZE(IO_SIZE));
479 
480 static Sys_var_ulonglong Sys_binlog_stmt_cache_size(
481        "binlog_stmt_cache_size", "The size of the statement cache for "
482        "updates to non-transactional engines for the binary log. "
483        "If you often use statements updating a great number of rows, "
484        "you can increase this to get more performance.",
485        GLOBAL_VAR(binlog_stmt_cache_size),
486        CMD_LINE(REQUIRED_ARG),
487        VALID_RANGE(IO_SIZE, SIZE_T_MAX), DEFAULT(32768), BLOCK_SIZE(IO_SIZE));
488 
489 /*
490   Some variables like @sql_log_bin and @binlog_format change how/if binlogging
491   is done. We must not change them inside a running transaction or statement,
492   otherwise the event group eventually written to the binlog may become
493   incomplete or otherwise garbled.
494 
495   This function does the appropriate check.
496 
497   It returns true if an error is caused by incorrect usage, false if ok.
498 */
499 static bool
500 error_if_in_trans_or_substatement(THD *thd, int in_substatement_error,
501                                   int in_transaction_error)
502 {
503   if (unlikely(thd->in_sub_stmt))
504   {
505     my_error(in_substatement_error, MYF(0));
506     return true;
507   }
508 
509   if (unlikely(thd->in_active_multi_stmt_transaction()))
510   {
511     my_error(in_transaction_error, MYF(0));
512     return true;
513   }
514 
515   return false;
516 }
517 
518 bool check_has_super(sys_var *self, THD *thd, set_var *var)
519 {
520   DBUG_ASSERT(self->scope() != sys_var::GLOBAL);// don't abuse check_has_super()
521 #ifndef NO_EMBEDDED_ACCESS_CHECKS
522   if (!(thd->security_ctx->master_access & SUPER_ACL))
523   {
524     my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
525     return true;
526   }
527 #endif
528   return false;
529 }
530 
531 static Sys_var_bit Sys_core_file("core_file", "write a core-file on crashes",
532           READ_ONLY GLOBAL_VAR(test_flags), NO_CMD_LINE,
533           TEST_CORE_ON_SIGNAL, DEFAULT(IF_WIN(TRUE,FALSE)), NO_MUTEX_GUARD, NOT_IN_BINLOG,
534           0,0,0);
535 
536 static bool binlog_format_check(sys_var *self, THD *thd, set_var *var)
537 {
538   if (check_has_super(self, thd, var))
539     return true;
540 
541   /*
542     MariaDB Galera does not support STATEMENT or MIXED binlog format currently.
543   */
544   if ((WSREP(thd) || opt_support_flashback) &&
545       var->save_result.ulonglong_value != BINLOG_FORMAT_ROW)
546   {
547     // Push a warning to the error log.
548     push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
549                         "MariaDB Galera and flashback do not support binlog format: %s",
550                         binlog_format_names[var->save_result.ulonglong_value]);
551     /*
552       We allow setting up binlog_format other then ROW for session scope when
553       wsrep/flasback is enabled.This is done because of 2 reasons
554       1. User might want to run pt-table-checksum.
555       2. SuperUser knows what is doing :-)
556 
557       For refrence:- MDEV-7322
558     */
559     if (var->type == OPT_GLOBAL)
560     {
561       if (WSREP(thd))
562         WSREP_ERROR("MariaDB Galera does not support binlog format: %s",
563                     binlog_format_names[var->save_result.ulonglong_value]);
564       else
565         my_error(ER_FLASHBACK_NOT_SUPPORTED,MYF(0),"binlog_format",
566                  binlog_format_names[var->save_result.ulonglong_value]);
567       return true;
568     }
569   }
570 
571   if (var->type == OPT_GLOBAL)
572     return false;
573 
574   /*
575      If RBR and open temporary tables, their CREATE TABLE may not be in the
576      binlog, so we can't toggle to SBR in this connection.
577 
578      If binlog_format=MIXED, there are open temporary tables, and an unsafe
579      statement is executed, then subsequent statements are logged in row
580      format and hence changes to temporary tables may be lost. So we forbid
581      switching @@SESSION.binlog_format from MIXED to STATEMENT when there are
582      open temp tables and we are logging in row format.
583   */
584   if (thd->has_thd_temporary_tables() &&
585       var->type == OPT_SESSION &&
586       var->save_result.ulonglong_value == BINLOG_FORMAT_STMT &&
587       ((thd->variables.binlog_format == BINLOG_FORMAT_MIXED &&
588         thd->is_current_stmt_binlog_format_row()) ||
589        thd->variables.binlog_format == BINLOG_FORMAT_ROW))
590   {
591     my_error(ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR, MYF(0));
592     return true;
593   }
594 
595   if (unlikely(error_if_in_trans_or_substatement(thd,
596                                                  ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT,
597                                                  ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT)))
598     return true;
599 
600   return false;
601 }
602 
603 static bool fix_binlog_format_after_update(sys_var *self, THD *thd,
604                                            enum_var_type type)
605 {
606   if (type == OPT_SESSION)
607     thd->reset_current_stmt_binlog_format_row();
608   return false;
609 }
610 
611 static Sys_var_enum Sys_binlog_format(
612        "binlog_format", "What form of binary logging the master will "
613        "use: either ROW for row-based binary logging, STATEMENT "
614        "for statement-based binary logging, or MIXED. MIXED is statement-"
615        "based binary logging except for those statements where only row-"
616        "based is correct: those which involve user-defined functions (i.e. "
617        "UDFs) or the UUID() function; for those, row-based binary logging is "
618        "automatically used.",
619        SESSION_VAR(binlog_format), CMD_LINE(REQUIRED_ARG, OPT_BINLOG_FORMAT),
620        binlog_format_names, DEFAULT(BINLOG_FORMAT_MIXED),
621        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(binlog_format_check),
622        ON_UPDATE(fix_binlog_format_after_update));
623 
624 static bool binlog_direct_check(sys_var *self, THD *thd, set_var *var)
625 {
626   if (check_has_super(self, thd, var))
627     return true;
628 
629   if (var->type == OPT_GLOBAL)
630     return false;
631 
632   if (unlikely(error_if_in_trans_or_substatement(thd,
633                                                  ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_DIRECT,
634                                                  ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT)))
635      return true;
636 
637   return false;
638 }
639 
640 static Sys_var_mybool Sys_binlog_direct(
641        "binlog_direct_non_transactional_updates",
642        "Causes updates to non-transactional engines using statement format to "
643        "be written directly to binary log. Before using this option make sure "
644        "that there are no dependencies between transactional and "
645        "non-transactional tables such as in the statement INSERT INTO t_myisam "
646        "SELECT * FROM t_innodb; otherwise, slaves may diverge from the master.",
647        SESSION_VAR(binlog_direct_non_trans_update),
648        CMD_LINE(OPT_ARG), DEFAULT(FALSE),
649        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(binlog_direct_check));
650 
651 
652 static Sys_var_mybool Sys_explicit_defaults_for_timestamp(
653        "explicit_defaults_for_timestamp",
654        "This option causes CREATE TABLE to create all TIMESTAMP columns "
655        "as NULL with DEFAULT NULL attribute, Without this option, "
656        "TIMESTAMP columns are NOT NULL and have implicit DEFAULT clauses.",
657        READ_ONLY GLOBAL_VAR(opt_explicit_defaults_for_timestamp),
658        CMD_LINE(OPT_ARG), DEFAULT(FALSE));
659 
660 
661 static Sys_var_ulonglong Sys_bulk_insert_buff_size(
662        "bulk_insert_buffer_size", "Size of tree cache used in bulk "
663        "insert optimisation. Note that this is a limit per thread!",
664        SESSION_VAR(bulk_insert_buff_size), CMD_LINE(REQUIRED_ARG),
665        VALID_RANGE(0, SIZE_T_MAX), DEFAULT(8192*1024), BLOCK_SIZE(1));
666 
667 static Sys_var_charptr Sys_character_sets_dir(
668        "character_sets_dir", "Directory where character sets are",
669        READ_ONLY GLOBAL_VAR(charsets_dir), CMD_LINE(REQUIRED_ARG),
670        IN_FS_CHARSET, DEFAULT(0));
671 
672 static bool check_not_null(sys_var *self, THD *thd, set_var *var)
673 {
674   return var->value && var->value->is_null();
675 }
676 static bool check_charset(sys_var *self, THD *thd, set_var *var)
677 {
678   if (!var->value)
679     return false;
680 
681   char buff[STRING_BUFFER_USUAL_SIZE];
682   if (var->value->result_type() == STRING_RESULT)
683   {
684     String str(buff, sizeof(buff), system_charset_info), *res;
685     if (!(res= var->value->val_str(&str)))
686       var->save_result.ptr= NULL;
687     else
688     {
689       ErrConvString err(res); /* Get utf8 '\0' terminated string */
690       if (!(var->save_result.ptr= get_charset_by_csname(err.ptr(),
691                                                          MY_CS_PRIMARY,
692                                                          MYF(0))) &&
693           !(var->save_result.ptr= get_old_charset_by_name(err.ptr())))
694       {
695         my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), err.ptr());
696         return true;
697       }
698     }
699   }
700   else // INT_RESULT
701   {
702     int csno= (int)var->value->val_int();
703     if (!(var->save_result.ptr= get_charset(csno, MYF(0))))
704     {
705       my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), llstr(csno, buff));
706       return true;
707     }
708   }
709   return false;
710 }
711 static bool check_charset_not_null(sys_var *self, THD *thd, set_var *var)
712 {
713   return check_charset(self, thd, var) || check_not_null(self, thd, var);
714 }
715 static Sys_var_struct Sys_character_set_system(
716        "character_set_system", "The character set used by the server "
717        "for storing identifiers",
718        READ_ONLY GLOBAL_VAR(system_charset_info), NO_CMD_LINE,
719        offsetof(CHARSET_INFO, csname), DEFAULT(0));
720 
721 static Sys_var_struct Sys_character_set_server(
722        "character_set_server", "The default character set",
723        SESSION_VAR(collation_server), NO_CMD_LINE,
724        offsetof(CHARSET_INFO, csname), DEFAULT(&default_charset_info),
725        NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_charset_not_null));
726 
727 static bool check_charset_db(sys_var *self, THD *thd, set_var *var)
728 {
729   if (check_charset_not_null(self, thd, var))
730     return true;
731   if (!var->value) // = DEFAULT
732     var->save_result.ptr= thd->db_charset;
733   return false;
734 }
735 static Sys_var_struct Sys_character_set_database(
736        "character_set_database",
737        "The character set used by the default database",
738        SESSION_VAR(collation_database), NO_CMD_LINE,
739        offsetof(CHARSET_INFO, csname), DEFAULT(&default_charset_info),
740        NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_charset_db));
741 
742 static bool check_cs_client(sys_var *self, THD *thd, set_var *var)
743 {
744   if (check_charset_not_null(self, thd, var))
745     return true;
746 
747   // Currently, UCS-2 cannot be used as a client character set
748   if (!is_supported_parser_charset((CHARSET_INFO *)(var->save_result.ptr)))
749     return true;
750 
751   return false;
752 }
753 static bool fix_thd_charset(sys_var *self, THD *thd, enum_var_type type)
754 {
755   if (type == OPT_SESSION)
756     thd->update_charset();
757   return false;
758 }
759 static Sys_var_struct Sys_character_set_client(
760        "character_set_client", "The character set for statements "
761        "that arrive from the client",
762        NO_SET_STMT SESSION_VAR(character_set_client), NO_CMD_LINE,
763        offsetof(CHARSET_INFO, csname), DEFAULT(&default_charset_info),
764        NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_cs_client),
765        ON_UPDATE(fix_thd_charset));
766 // for check changing
767 export sys_var *Sys_character_set_client_ptr= &Sys_character_set_client;
768 
769 static Sys_var_struct Sys_character_set_connection(
770        "character_set_connection", "The character set used for "
771        "literals that do not have a character set introducer and for "
772        "number-to-string conversion",
773        NO_SET_STMT SESSION_VAR(collation_connection), NO_CMD_LINE,
774        offsetof(CHARSET_INFO, csname), DEFAULT(&default_charset_info),
775        NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_charset_not_null),
776        ON_UPDATE(fix_thd_charset));
777 // for check changing
778 export sys_var *Sys_character_set_connection_ptr= &Sys_character_set_connection;
779 
780 static Sys_var_struct Sys_character_set_results(
781        "character_set_results", "The character set used for returning "
782        "query results to the client",
783        SESSION_VAR(character_set_results), NO_CMD_LINE,
784        offsetof(CHARSET_INFO, csname), DEFAULT(&default_charset_info),
785        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_charset));
786 // for check changing
787 export sys_var *Sys_character_set_results_ptr= &Sys_character_set_results;
788 
789 static Sys_var_struct Sys_character_set_filesystem(
790        "character_set_filesystem", "The filesystem character set",
791        NO_SET_STMT SESSION_VAR(character_set_filesystem), NO_CMD_LINE,
792        offsetof(CHARSET_INFO, csname), DEFAULT(&character_set_filesystem),
793        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_charset_not_null),
794        ON_UPDATE(fix_thd_charset));
795 
796 static const char *completion_type_names[]= {"NO_CHAIN", "CHAIN", "RELEASE", 0};
797 static Sys_var_enum Sys_completion_type(
798        "completion_type", "The transaction completion type",
799        SESSION_VAR(completion_type), CMD_LINE(REQUIRED_ARG),
800        completion_type_names, DEFAULT(0));
801 
802 static bool check_collation_not_null(sys_var *self, THD *thd, set_var *var)
803 {
804   if (!var->value)
805     return false;
806 
807   char buff[STRING_BUFFER_USUAL_SIZE];
808   if (var->value->result_type() == STRING_RESULT)
809   {
810     String str(buff, sizeof(buff), system_charset_info), *res;
811     if (!(res= var->value->val_str(&str)))
812       var->save_result.ptr= NULL;
813     else
814     {
815       ErrConvString err(res); /* Get utf8 '\0'-terminated string */
816       if (!(var->save_result.ptr= get_charset_by_name(err.ptr(), MYF(0))))
817       {
818         my_error(ER_UNKNOWN_COLLATION, MYF(0), err.ptr());
819         return true;
820       }
821     }
822   }
823   else // INT_RESULT
824   {
825     int csno= (int)var->value->val_int();
826     if (!(var->save_result.ptr= get_charset(csno, MYF(0))))
827     {
828       my_error(ER_UNKNOWN_COLLATION, MYF(0), llstr(csno, buff));
829       return true;
830     }
831   }
832   return check_not_null(self, thd, var);
833 }
834 static Sys_var_struct Sys_collation_connection(
835        "collation_connection", "The collation of the connection "
836        "character set",
837        NO_SET_STMT SESSION_VAR(collation_connection), NO_CMD_LINE,
838        offsetof(CHARSET_INFO, name), DEFAULT(&default_charset_info),
839        NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_collation_not_null),
840        ON_UPDATE(fix_thd_charset));
841 
842 static bool check_collation_db(sys_var *self, THD *thd, set_var *var)
843 {
844   if (check_collation_not_null(self, thd, var))
845     return true;
846   if (!var->value) // = DEFAULT
847     var->save_result.ptr= thd->db_charset;
848   return false;
849 }
850 static Sys_var_struct Sys_collation_database(
851        "collation_database", "The collation of the database "
852        "character set",
853        SESSION_VAR(collation_database), NO_CMD_LINE,
854        offsetof(CHARSET_INFO, name), DEFAULT(&default_charset_info),
855        NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_collation_db));
856 
857 static Sys_var_struct Sys_collation_server(
858        "collation_server", "The server default collation",
859        SESSION_VAR(collation_server), NO_CMD_LINE,
860        offsetof(CHARSET_INFO, name), DEFAULT(&default_charset_info),
861        NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_collation_not_null));
862 
863 static Sys_var_uint Sys_column_compression_threshold(
864        "column_compression_threshold",
865        "Minimum column data length eligible for compression",
866        SESSION_VAR(column_compression_threshold), CMD_LINE(REQUIRED_ARG),
867        VALID_RANGE(0, UINT_MAX), DEFAULT(100), BLOCK_SIZE(1));
868 
869 static Sys_var_uint Sys_column_compression_zlib_level(
870        "column_compression_zlib_level",
871        "zlib compression level (1 gives best speed, 9 gives best compression)",
872        SESSION_VAR(column_compression_zlib_level), CMD_LINE(REQUIRED_ARG),
873        VALID_RANGE(0, 9), DEFAULT(6), BLOCK_SIZE(1));
874 
875 /*
876   Note that names must correspond to zlib strategy definition. So that we can
877   pass column_compression_zlib_strategy directly to deflateInit2().
878 */
879 static const char *column_compression_zlib_strategy_names[]=
880 { "DEFAULT_STRATEGY", "FILTERED", "HUFFMAN_ONLY", "RLE", "FIXED", 0 };
881 
882 static Sys_var_enum Sys_column_compression_zlib_strategy(
883        "column_compression_zlib_strategy",
884        "The strategy parameter is used to tune the compression algorithm. Use "
885        "the value DEFAULT_STRATEGY for normal data, FILTERED for data produced "
886        "by a filter (or predictor), HUFFMAN_ONLY to force Huffman encoding "
887        "only (no string match), or RLE to limit match distances to one "
888        "(run-length encoding). Filtered data consists mostly of small values "
889        "with a somewhat random distribution. In this case, the compression "
890        "algorithm is tuned to compress them better. The effect of FILTERED is "
891        "to force more Huffman coding and less string matching; it is somewhat "
892        "intermediate between DEFAULT_STRATEGY and HUFFMAN_ONLY. RLE is "
893        "designed to be almost as fast as HUFFMAN_ONLY, but give better "
894        "compression for PNG image data. The strategy parameter only affects "
895        "the compression ratio but not the correctness of the compressed output "
896        "even if it is not set appropriately. FIXED prevents the use of dynamic "
897        "Huffman codes, allowing for a simpler decoder for special "
898        "applications.",
899        SESSION_VAR(column_compression_zlib_strategy), CMD_LINE(REQUIRED_ARG),
900        column_compression_zlib_strategy_names, DEFAULT(0));
901 
902 static Sys_var_mybool Sys_column_compression_zlib_wrap(
903        "column_compression_zlib_wrap",
904        "Generate zlib header and trailer and compute adler32 check value. "
905        "It can be used with storage engines that don't provide data integrity "
906        "verification to detect data corruption.",
907        SESSION_VAR(column_compression_zlib_wrap), CMD_LINE(OPT_ARG),
908        DEFAULT(FALSE));
909 
910 static const char *concurrent_insert_names[]= {"NEVER", "AUTO", "ALWAYS", 0};
911 static Sys_var_enum Sys_concurrent_insert(
912        "concurrent_insert", "Use concurrent insert with MyISAM",
913        GLOBAL_VAR(myisam_concurrent_insert), CMD_LINE(OPT_ARG),
914        concurrent_insert_names, DEFAULT(1));
915 
916 static Sys_var_ulong Sys_connect_timeout(
917        "connect_timeout",
918        "The number of seconds the mysqld server is waiting for a connect "
919        "packet before responding with 'Bad handshake'",
920        GLOBAL_VAR(connect_timeout), CMD_LINE(REQUIRED_ARG),
921        VALID_RANGE(2, LONG_TIMEOUT), DEFAULT(CONNECT_TIMEOUT), BLOCK_SIZE(1));
922 
923 static Sys_var_charptr Sys_datadir(
924        "datadir", "Path to the database root directory",
925        READ_ONLY GLOBAL_VAR(mysql_real_data_home_ptr),
926        CMD_LINE(REQUIRED_ARG, 'h'), IN_FS_CHARSET, DEFAULT(mysql_real_data_home));
927 
928 #ifndef DBUG_OFF
929 static Sys_var_dbug Sys_dbug(
930        "debug", "Built-in DBUG debugger", sys_var::SESSION,
931        CMD_LINE(OPT_ARG, '#'), DEFAULT(""), NO_MUTEX_GUARD, NOT_IN_BINLOG,
932        ON_CHECK(check_has_super), ON_UPDATE(0),
933        DEPRECATED("'@@debug_dbug'"));
934 
935 static Sys_var_dbug Sys_debug_dbug(
936        "debug_dbug", "Built-in DBUG debugger", sys_var::SESSION,
937        CMD_LINE(OPT_ARG, '#'), DEFAULT(""), NO_MUTEX_GUARD, NOT_IN_BINLOG,
938        ON_CHECK(check_has_super));
939 #endif
940 
941 /**
942   @todo
943     When updating myisam_delay_key_write, we should do a 'flush tables'
944     of all MyISAM tables to ensure that they are reopen with the
945     new attribute.
946 */
947 export bool fix_delay_key_write(sys_var *self, THD *thd, enum_var_type type)
948 {
949   switch (delay_key_write_options) {
950   case DELAY_KEY_WRITE_NONE:
951     myisam_delay_key_write=0;
952     ha_open_options&= ~HA_OPEN_DELAY_KEY_WRITE;
953     break;
954   case DELAY_KEY_WRITE_ON:
955     myisam_delay_key_write=1;
956     ha_open_options&= ~HA_OPEN_DELAY_KEY_WRITE;
957     break;
958   case DELAY_KEY_WRITE_ALL:
959     myisam_delay_key_write=1;
960     ha_open_options|= HA_OPEN_DELAY_KEY_WRITE;
961     break;
962   }
963 #ifdef WITH_ARIA_STORAGE_ENGINE
964   maria_delay_key_write= myisam_delay_key_write;
965 #endif
966   return false;
967 }
968 static const char *delay_key_write_names[]= { "OFF", "ON", "ALL", NullS };
969 static Sys_var_enum Sys_delay_key_write(
970        "delay_key_write", "Specifies how MyISAM tables handles CREATE "
971        "TABLE DELAY_KEY_WRITE. If set to ON, the default, any DELAY KEY "
972        "WRITEs are honored. The key buffer is then flushed only when the "
973        "table closes, speeding up writes. MyISAM tables should be "
974        "automatically checked upon startup in this case, and "
975        "--external locking should not be used, as it can lead to index "
976        "corruption. If set to OFF, DELAY KEY WRITEs are ignored, while if "
977        "set to ALL, all new opened tables are treated as if created with "
978        "DELAY KEY WRITEs enabled.",
979        GLOBAL_VAR(delay_key_write_options), CMD_LINE(OPT_ARG),
980        delay_key_write_names, DEFAULT(DELAY_KEY_WRITE_ON),
981        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
982        ON_UPDATE(fix_delay_key_write));
983 
984 static Sys_var_ulong Sys_delayed_insert_limit(
985        "delayed_insert_limit",
986        "After inserting delayed_insert_limit rows, the INSERT DELAYED "
987        "handler will check if there are any SELECT statements pending. "
988        "If so, it allows these to execute before continuing.",
989        GLOBAL_VAR(delayed_insert_limit), CMD_LINE(REQUIRED_ARG),
990        VALID_RANGE(1, UINT_MAX), DEFAULT(DELAYED_LIMIT), BLOCK_SIZE(1));
991 
992 static Sys_var_ulong Sys_delayed_insert_timeout(
993        "delayed_insert_timeout",
994        "How long a INSERT DELAYED thread should wait for INSERT statements "
995        "before terminating",
996        GLOBAL_VAR(delayed_insert_timeout), CMD_LINE(REQUIRED_ARG),
997        VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(DELAYED_WAIT_TIMEOUT),
998        BLOCK_SIZE(1));
999 
1000 static Sys_var_ulong Sys_delayed_queue_size(
1001        "delayed_queue_size",
1002        "What size queue (in rows) should be allocated for handling INSERT "
1003        "DELAYED. If the queue becomes full, any client that does INSERT "
1004        "DELAYED will wait until there is room in the queue again",
1005        GLOBAL_VAR(delayed_queue_size), CMD_LINE(REQUIRED_ARG),
1006        VALID_RANGE(1, UINT_MAX), DEFAULT(DELAYED_QUEUE_SIZE), BLOCK_SIZE(1));
1007 
1008 #ifdef HAVE_EVENT_SCHEDULER
1009 static const char *event_scheduler_names[]= { "OFF", "ON", "DISABLED",
1010                                               "ORIGINAL", NullS };
1011 static bool event_scheduler_check(sys_var *self, THD *thd, set_var *var)
1012 {
1013   if (Events::opt_event_scheduler == Events::EVENTS_DISABLED)
1014   {
1015     my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
1016              "--event-scheduler=DISABLED or --skip-grant-tables");
1017     return true;
1018   }
1019   /* DISABLED is only accepted on the command line */
1020   if (var->save_result.ulonglong_value == Events::EVENTS_DISABLED)
1021     return true;
1022   return false;
1023 }
1024 
1025 static bool event_scheduler_update(sys_var *self, THD *thd, enum_var_type type)
1026 {
1027   int err_no= 0;
1028   bool ret;
1029   uint opt_event_scheduler_value= Events::opt_event_scheduler;
1030   mysql_mutex_unlock(&LOCK_global_system_variables);
1031   /*
1032     Events::start() is heavyweight. In particular it creates a new THD,
1033     which takes LOCK_global_system_variables internally.
1034     Thus we have to release it here.
1035     We need to re-take it before returning, though.
1036 
1037     Note that since we release LOCK_global_system_variables before calling
1038     start/stop, there is a possibility that the server variable
1039     can become out of sync with the real event scheduler state.
1040 
1041     This can happen with two concurrent statments if the first gets
1042     interrupted after start/stop but before retaking
1043     LOCK_global_system_variables. However, this problem should be quite
1044     rare and it's difficult to avoid it without opening up possibilities
1045     for deadlocks. See bug#51160.
1046   */
1047 
1048   /* EVENTS_ORIGINAL means we should revert back to the startup state */
1049   if (opt_event_scheduler_value == Events::EVENTS_ORIGINAL)
1050   {
1051     opt_event_scheduler_value= Events::opt_event_scheduler=
1052       Events::startup_state;
1053   }
1054 
1055   /*
1056     If the scheduler was not properly inited (because of wrong system tables),
1057     try to init it again. This is needed for mysql_upgrade to work properly if
1058     the event tables where upgraded.
1059   */
1060   if (!Events::inited && (Events::init(thd, 0) || !Events::inited))
1061     ret= 1;
1062   else
1063     ret= opt_event_scheduler_value == Events::EVENTS_ON ?
1064       Events::start(&err_no) :
1065       Events::stop();
1066   mysql_mutex_lock(&LOCK_global_system_variables);
1067   if (ret)
1068   {
1069     Events::opt_event_scheduler= Events::EVENTS_OFF;
1070     my_error(ER_EVENT_SET_VAR_ERROR, MYF(0), err_no);
1071   }
1072   return ret;
1073 }
1074 
1075 static Sys_var_enum Sys_event_scheduler(
1076        "event_scheduler", "Enable the event scheduler. Possible values are "
1077        "ON, OFF, and DISABLED (keep the event scheduler completely "
1078        "deactivated, it cannot be activated run-time)",
1079        GLOBAL_VAR(Events::opt_event_scheduler), CMD_LINE(OPT_ARG),
1080        event_scheduler_names, DEFAULT(Events::EVENTS_OFF),
1081        NO_MUTEX_GUARD, NOT_IN_BINLOG,
1082        ON_CHECK(event_scheduler_check), ON_UPDATE(event_scheduler_update));
1083 #endif
1084 
1085 static Sys_var_ulong Sys_expire_logs_days(
1086        "expire_logs_days",
1087        "If non-zero, binary logs will be purged after expire_logs_days "
1088        "days; possible purges happen at startup and at binary log rotation",
1089        GLOBAL_VAR(expire_logs_days),
1090        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 99), DEFAULT(0), BLOCK_SIZE(1));
1091 
1092 static Sys_var_mybool Sys_flush(
1093        "flush", "Flush MyISAM tables to disk between SQL commands",
1094        GLOBAL_VAR(myisam_flush),
1095        CMD_LINE(OPT_ARG), DEFAULT(FALSE));
1096 
1097 static Sys_var_ulong Sys_flush_time(
1098        "flush_time",
1099        "A dedicated thread is created to flush all tables at the "
1100        "given interval",
1101        GLOBAL_VAR(flush_time),
1102        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, LONG_TIMEOUT),
1103        DEFAULT(0), BLOCK_SIZE(1));
1104 
1105 static bool check_ftb_syntax(sys_var *self, THD *thd, set_var *var)
1106 {
1107   return ft_boolean_check_syntax_string((uchar*)
1108                       (var->save_result.string_value.str),
1109                       var->save_result.string_value.length,
1110                       self->charset(thd));
1111 }
1112 static bool query_cache_flush(sys_var *self, THD *thd, enum_var_type type)
1113 {
1114 #ifdef HAVE_QUERY_CACHE
1115   query_cache.flush();
1116 #endif /* HAVE_QUERY_CACHE */
1117   return false;
1118 }
1119 /// @todo make SESSION_VAR (usability enhancement and a fix for a race condition)
1120 static Sys_var_charptr Sys_ft_boolean_syntax(
1121        "ft_boolean_syntax", "List of operators for "
1122        "MATCH ... AGAINST ( ... IN BOOLEAN MODE)",
1123        GLOBAL_VAR(ft_boolean_syntax),
1124        CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET,
1125        DEFAULT(DEFAULT_FTB_SYNTAX), NO_MUTEX_GUARD,
1126        NOT_IN_BINLOG, ON_CHECK(check_ftb_syntax), ON_UPDATE(query_cache_flush));
1127 
1128 static Sys_var_ulong Sys_ft_max_word_len(
1129        "ft_max_word_len",
1130        "The maximum length of the word to be included in a FULLTEXT index. "
1131        "Note: FULLTEXT indexes must be rebuilt after changing this variable",
1132        READ_ONLY GLOBAL_VAR(ft_max_word_len), CMD_LINE(REQUIRED_ARG),
1133        VALID_RANGE(10, HA_FT_MAXCHARLEN), DEFAULT(HA_FT_MAXCHARLEN),
1134        BLOCK_SIZE(1));
1135 
1136 static Sys_var_ulong Sys_ft_min_word_len(
1137        "ft_min_word_len",
1138        "The minimum length of the word to be included in a FULLTEXT index. "
1139        "Note: FULLTEXT indexes must be rebuilt after changing this variable",
1140        READ_ONLY GLOBAL_VAR(ft_min_word_len), CMD_LINE(REQUIRED_ARG),
1141        VALID_RANGE(1, HA_FT_MAXCHARLEN), DEFAULT(4), BLOCK_SIZE(1));
1142 
1143 /// @todo make it an updatable SESSION_VAR
1144 static Sys_var_ulong Sys_ft_query_expansion_limit(
1145        "ft_query_expansion_limit",
1146        "Number of best matches to use for query expansion",
1147        READ_ONLY GLOBAL_VAR(ft_query_expansion_limit),
1148        CMD_LINE(REQUIRED_ARG),
1149        VALID_RANGE(0, 1000), DEFAULT(20), BLOCK_SIZE(1));
1150 
1151 static Sys_var_charptr Sys_ft_stopword_file(
1152        "ft_stopword_file",
1153        "Use stopwords from this file instead of built-in list",
1154        READ_ONLY GLOBAL_VAR(ft_stopword_file), CMD_LINE(REQUIRED_ARG),
1155        IN_FS_CHARSET, DEFAULT(0));
1156 
1157 static Sys_var_mybool Sys_ignore_builtin_innodb(
1158        "ignore_builtin_innodb",
1159        "Disable initialization of builtin InnoDB plugin",
1160        READ_ONLY GLOBAL_VAR(opt_ignore_builtin_innodb),
1161        CMD_LINE(OPT_ARG), DEFAULT(FALSE));
1162 
1163 static bool check_init_string(sys_var *self, THD *thd, set_var *var)
1164 {
1165   if (var->save_result.string_value.str == 0)
1166   {
1167     var->save_result.string_value.str= const_cast<char*>("");
1168     var->save_result.string_value.length= 0;
1169   }
1170   return false;
1171 }
1172 static PolyLock_rwlock PLock_sys_init_connect(&LOCK_sys_init_connect);
1173 static Sys_var_lexstring Sys_init_connect(
1174        "init_connect", "Command(s) that are executed for each "
1175        "new connection (unless the user has SUPER privilege)",
1176        GLOBAL_VAR(opt_init_connect), CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET,
1177        DEFAULT(""), &PLock_sys_init_connect, NOT_IN_BINLOG,
1178        ON_CHECK(check_init_string));
1179 
1180 #ifdef HAVE_REPLICATION
1181 static bool check_master_connection(sys_var *self, THD *thd, set_var *var)
1182 {
1183   LEX_CSTRING tmp;
1184   tmp.str= var->save_result.string_value.str;
1185   tmp.length= var->save_result.string_value.length;
1186   if (!tmp.str || check_master_connection_name(&tmp))
1187     return true;
1188 
1189   return false;
1190 }
1191 
1192 static Sys_var_session_lexstring Sys_default_master_connection(
1193        "default_master_connection",
1194        "Master connection to use for all slave variables and slave commands",
1195        SESSION_ONLY(default_master_connection),
1196        NO_CMD_LINE, IN_SYSTEM_CHARSET,
1197        DEFAULT(""), MAX_CONNECTION_NAME, ON_CHECK(check_master_connection));
1198 #endif
1199 
1200 static Sys_var_charptr Sys_init_file(
1201        "init_file", "Read SQL commands from this file at startup",
1202        READ_ONLY GLOBAL_VAR(opt_init_file),
1203 #ifdef DISABLE_GRANT_OPTIONS
1204        NO_CMD_LINE,
1205 #else
1206        CMD_LINE(REQUIRED_ARG),
1207 #endif
1208        IN_FS_CHARSET, DEFAULT(0));
1209 
1210 static PolyLock_rwlock PLock_sys_init_slave(&LOCK_sys_init_slave);
1211 static Sys_var_lexstring Sys_init_slave(
1212        "init_slave", "Command(s) that are executed by a slave server "
1213        "each time the SQL thread starts", GLOBAL_VAR(opt_init_slave),
1214        CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET,
1215        DEFAULT(""), &PLock_sys_init_slave,
1216        NOT_IN_BINLOG, ON_CHECK(check_init_string));
1217 
1218 static Sys_var_ulong Sys_interactive_timeout(
1219        "interactive_timeout",
1220        "The number of seconds the server waits for activity on an interactive "
1221        "connection before closing it",
1222        NO_SET_STMT SESSION_VAR(net_interactive_timeout),
1223        CMD_LINE(REQUIRED_ARG),
1224        VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(NET_WAIT_TIMEOUT), BLOCK_SIZE(1));
1225 
1226 static Sys_var_ulonglong Sys_join_buffer_size(
1227        "join_buffer_size",
1228        "The size of the buffer that is used for joins",
1229        SESSION_VAR(join_buff_size), CMD_LINE(REQUIRED_ARG),
1230        VALID_RANGE(128, SIZE_T_MAX), DEFAULT(256*1024), BLOCK_SIZE(128));
1231 
1232 static Sys_var_keycache Sys_key_buffer_size(
1233        "key_buffer_size", "The size of the buffer used for "
1234        "index blocks for MyISAM tables. Increase this to get better index "
1235        "handling (for all reads and multiple writes) to as much as you can "
1236        "afford",
1237        KEYCACHE_VAR(param_buff_size),
1238        CMD_LINE(REQUIRED_ARG, OPT_KEY_BUFFER_SIZE),
1239        VALID_RANGE(0, SIZE_T_MAX), DEFAULT(KEY_CACHE_SIZE),
1240        BLOCK_SIZE(IO_SIZE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
1241        ON_UPDATE(update_buffer_size));
1242 
1243 static Sys_var_keycache Sys_key_cache_block_size(
1244        "key_cache_block_size", "The default size of key cache blocks",
1245        KEYCACHE_VAR(param_block_size),
1246        CMD_LINE(REQUIRED_ARG, OPT_KEY_CACHE_BLOCK_SIZE),
1247        VALID_RANGE(512, 1024*16), DEFAULT(KEY_CACHE_BLOCK_SIZE),
1248        BLOCK_SIZE(512), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
1249        ON_UPDATE(resize_keycache));
1250 
1251 static Sys_var_keycache Sys_key_cache_division_limit(
1252        "key_cache_division_limit",
1253        "The minimum percentage of warm blocks in key cache",
1254        KEYCACHE_VAR(param_division_limit),
1255        CMD_LINE(REQUIRED_ARG, OPT_KEY_CACHE_DIVISION_LIMIT),
1256        VALID_RANGE(1, 100), DEFAULT(100),
1257        BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
1258        ON_UPDATE(change_keycache_param));
1259 
1260 static Sys_var_keycache Sys_key_cache_age_threshold(
1261        "key_cache_age_threshold", "This characterizes the number of "
1262        "hits a hot block has to be untouched until it is considered aged "
1263        "enough to be downgraded to a warm block. This specifies the "
1264        "percentage ratio of that number of hits to the total number of "
1265        "blocks in key cache",
1266        KEYCACHE_VAR(param_age_threshold),
1267        CMD_LINE(REQUIRED_ARG, OPT_KEY_CACHE_AGE_THRESHOLD),
1268        VALID_RANGE(100, UINT_MAX), DEFAULT(300),
1269        BLOCK_SIZE(100), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
1270        ON_UPDATE(change_keycache_param));
1271 
1272 static Sys_var_keycache Sys_key_cache_file_hash_size(
1273        "key_cache_file_hash_size",
1274        "Number of hash buckets for open and changed files.  If you have a lot of MyISAM "
1275        "files open you should increase this for faster flush of changes. A good "
1276        "value is probably 1/10 of number of possible open MyISAM files.",
1277        KEYCACHE_VAR(changed_blocks_hash_size),
1278        CMD_LINE(REQUIRED_ARG, OPT_KEY_CACHE_CHANGED_BLOCKS_HASH_SIZE),
1279        VALID_RANGE(128, 16384), DEFAULT(512),
1280        BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
1281        ON_UPDATE(resize_keycache));
1282 
1283 static Sys_var_mybool Sys_large_files_support(
1284        "large_files_support",
1285        "Whether mysqld was compiled with options for large file support",
1286        READ_ONLY GLOBAL_VAR(opt_large_files),
1287        CMD_LINE_HELP_ONLY, DEFAULT(sizeof(my_off_t) > 4));
1288 
1289 static Sys_var_uint Sys_large_page_size(
1290        "large_page_size",
1291        "If large page support is enabled, this shows the size of memory pages",
1292        READ_ONLY GLOBAL_VAR(opt_large_page_size), NO_CMD_LINE,
1293        VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1));
1294 
1295 static Sys_var_mybool Sys_large_pages(
1296        "large_pages", "Enable support for large pages",
1297        READ_ONLY GLOBAL_VAR(opt_large_pages),
1298        IF_WIN(NO_CMD_LINE, CMD_LINE(OPT_ARG)), DEFAULT(FALSE));
1299 
1300 static Sys_var_charptr Sys_language(
1301        "lc_messages_dir", "Directory where error messages are",
1302        READ_ONLY GLOBAL_VAR(lc_messages_dir_ptr), CMD_LINE(REQUIRED_ARG, 'L'),
1303        IN_FS_CHARSET, DEFAULT(0));
1304 
1305 static Sys_var_mybool Sys_local_infile(
1306        "local_infile", "Enable LOAD DATA LOCAL INFILE",
1307        GLOBAL_VAR(opt_local_infile), CMD_LINE(OPT_ARG), DEFAULT(TRUE));
1308 
1309 static Sys_var_ulong Sys_lock_wait_timeout(
1310        "lock_wait_timeout",
1311        "Timeout in seconds to wait for a lock before returning an error.",
1312        SESSION_VAR(lock_wait_timeout), CMD_LINE(REQUIRED_ARG),
1313        VALID_RANGE(0, LONG_TIMEOUT), DEFAULT(24 * 60 * 60), BLOCK_SIZE(1));
1314 
1315 #ifdef HAVE_MLOCKALL
1316 static Sys_var_mybool Sys_locked_in_memory(
1317        "locked_in_memory",
1318        "Whether mysqld was locked in memory with --memlock",
1319        READ_ONLY GLOBAL_VAR(locked_in_memory), NO_CMD_LINE, DEFAULT(FALSE));
1320 #endif
1321 
1322 /* this says NO_CMD_LINE, as command-line option takes a string, not a bool */
1323 static Sys_var_mybool Sys_log_bin(
1324        "log_bin", "Whether the binary log is enabled",
1325        READ_ONLY GLOBAL_VAR(opt_bin_log), NO_CMD_LINE, DEFAULT(FALSE));
1326 
1327 static Sys_var_mybool Sys_log_bin_compress(
1328   "log_bin_compress", "Whether the binary log can be compressed",
1329   GLOBAL_VAR(opt_bin_log_compress), CMD_LINE(OPT_ARG), DEFAULT(FALSE));
1330 
1331 /* the min length is 10, means that Begin/Commit/Rollback would never be compressed!   */
1332 static Sys_var_uint Sys_log_bin_compress_min_len(
1333   "log_bin_compress_min_len",
1334   "Minimum length of sql statement(in statement mode) or record(in row mode)"
1335   "that can be compressed.",
1336   GLOBAL_VAR(opt_bin_log_compress_min_len),
1337   CMD_LINE(OPT_ARG), VALID_RANGE(10, 1024), DEFAULT(256), BLOCK_SIZE(1));
1338 
1339 static Sys_var_mybool Sys_trust_function_creators(
1340        "log_bin_trust_function_creators",
1341        "If set to FALSE (the default), then when --log-bin is used, creation "
1342        "of a stored function (or trigger) is allowed only to users having the "
1343        "SUPER privilege and only if this stored function (trigger) may not "
1344        "break binary logging. Note that if ALL connections to this server "
1345        "ALWAYS use row-based binary logging, the security issues do not "
1346        "exist and the binary logging cannot break, so you can safely set "
1347        "this to TRUE",
1348        GLOBAL_VAR(trust_function_creators),
1349        CMD_LINE(OPT_ARG), DEFAULT(FALSE));
1350 
1351 static Sys_var_charptr Sys_log_error(
1352        "log_error",
1353        "Log errors to file (instead of stdout).  If file name is not specified "
1354        "then 'datadir'/'log-basename'.err or the 'pid-file' path with extension "
1355        ".err is used",
1356        READ_ONLY GLOBAL_VAR(log_error_file_ptr),
1357        CMD_LINE(OPT_ARG, OPT_LOG_ERROR),
1358        IN_FS_CHARSET, DEFAULT(disabled_my_option));
1359 
1360 static Sys_var_bit Sys_log_queries_not_using_indexes(
1361        "log_queries_not_using_indexes",
1362        "Log queries that are executed without benefit of any index to the "
1363        "slow log if it is open. Same as log_slow_filter='not_using_index'",
1364        SESSION_VAR(log_slow_filter), CMD_LINE(OPT_ARG), QPLAN_NOT_USING_INDEX,
1365        DEFAULT(FALSE));
1366 
1367 static Sys_var_bit Sys_log_slow_admin_statements(
1368        "log_slow_admin_statements",
1369        "Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements "
1370        "to the slow log if it is open.  Resets or sets the option 'admin' in "
1371        "log_slow_disabled_statements",
1372        SESSION_VAR(log_slow_disabled_statements),
1373        CMD_LINE(OPT_ARG), REVERSE(LOG_SLOW_DISABLE_ADMIN), DEFAULT(TRUE));
1374 
1375 static Sys_var_bit Sys_log_slow_slave_statements(
1376        "log_slow_slave_statements",
1377        "Log slow statements executed by slave thread to the slow log if it is "
1378        "open. Resets or sets the option 'slave' in "
1379        "log_slow_disabled_statements",
1380        SESSION_VAR(log_slow_disabled_statements),
1381        CMD_LINE(OPT_ARG), REVERSE(LOG_SLOW_DISABLE_SLAVE), DEFAULT(TRUE));
1382 
1383 static Sys_var_ulong Sys_log_warnings(
1384        "log_warnings",
1385        "Log some not critical warnings to the general log file."
1386        "Value can be between 0 and 11. Higher values mean more verbosity",
1387        SESSION_VAR(log_warnings),
1388        CMD_LINE(OPT_ARG, 'W'),
1389        VALID_RANGE(0, UINT_MAX), DEFAULT(2), BLOCK_SIZE(1));
1390 
1391 static bool update_cached_long_query_time(sys_var *self, THD *thd,
1392                                           enum_var_type type)
1393 {
1394   if (type == OPT_SESSION)
1395     thd->variables.long_query_time=
1396       double2ulonglong(thd->variables.long_query_time_double * 1e6);
1397   else
1398     global_system_variables.long_query_time=
1399       double2ulonglong(global_system_variables.long_query_time_double * 1e6);
1400   return false;
1401 }
1402 
1403 static Sys_var_double Sys_long_query_time(
1404        "long_query_time",
1405        "Log all queries that have taken more than long_query_time seconds "
1406        "to execute to the slow query log file. The argument will be treated "
1407        "as a decimal value with microsecond precision",
1408        SESSION_VAR(long_query_time_double),
1409        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, LONG_TIMEOUT), DEFAULT(10),
1410        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
1411        ON_UPDATE(update_cached_long_query_time));
1412 
1413 
1414 static bool update_cached_max_statement_time(sys_var *self, THD *thd,
1415                                          enum_var_type type)
1416 {
1417   if (type == OPT_SESSION)
1418     thd->variables.max_statement_time=
1419       double2ulonglong(thd->variables.max_statement_time_double * 1e6);
1420   else
1421     global_system_variables.max_statement_time=
1422       double2ulonglong(global_system_variables.max_statement_time_double * 1e6);
1423   return false;
1424 }
1425 
1426 static Sys_var_double Sys_max_statement_time(
1427        "max_statement_time",
1428        "A query that has taken more than max_statement_time seconds "
1429        "will be aborted. The argument will be treated as a decimal value "
1430        "with microsecond precision. A value of 0 (default) means no timeout",
1431        SESSION_VAR(max_statement_time_double),
1432        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, LONG_TIMEOUT), DEFAULT(0),
1433        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
1434        ON_UPDATE(update_cached_max_statement_time));
1435 
1436 static bool fix_low_prio_updates(sys_var *self, THD *thd, enum_var_type type)
1437 {
1438   if (type == OPT_SESSION)
1439     thd->update_lock_default= (thd->variables.low_priority_updates ?
1440                                TL_WRITE_LOW_PRIORITY : TL_WRITE);
1441   else
1442     thr_upgraded_concurrent_insert_lock=
1443       (global_system_variables.low_priority_updates ?
1444        TL_WRITE_LOW_PRIORITY : TL_WRITE);
1445   return false;
1446 }
1447 static Sys_var_mybool Sys_low_priority_updates(
1448        "low_priority_updates",
1449        "INSERT/DELETE/UPDATE has lower priority than selects",
1450        SESSION_VAR(low_priority_updates),
1451        CMD_LINE(OPT_ARG),
1452        DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
1453        ON_UPDATE(fix_low_prio_updates));
1454 
1455 static Sys_var_mybool Sys_lower_case_file_system(
1456        "lower_case_file_system",
1457        "Case sensitivity of file names on the file system where the "
1458        "data directory is located",
1459        READ_ONLY GLOBAL_VAR(lower_case_file_system),
1460        CMD_LINE_HELP_ONLY,
1461        DEFAULT(FALSE));
1462 
1463 static Sys_var_uint Sys_lower_case_table_names(
1464        "lower_case_table_names",
1465        "If set to 1 table names are stored in lowercase on disk and table "
1466        "names will be case-insensitive.  Should be set to 2 if you are using "
1467        "a case insensitive file system",
1468        READ_ONLY GLOBAL_VAR(lower_case_table_names),
1469        CMD_LINE(OPT_ARG, OPT_LOWER_CASE_TABLE_NAMES),
1470        VALID_RANGE(0, 2),
1471 #ifdef FN_NO_CASE_SENSE
1472     DEFAULT(1),
1473 #else
1474     DEFAULT(0),
1475 #endif
1476        BLOCK_SIZE(1));
1477 
1478 static bool session_readonly(sys_var *self, THD *thd, set_var *var)
1479 {
1480   if (var->type == OPT_GLOBAL)
1481     return false;
1482   my_error(ER_VARIABLE_IS_READONLY, MYF(0), "SESSION",
1483            self->name.str, "GLOBAL");
1484   return true;
1485 }
1486 
1487 static bool check_max_allowed_packet(sys_var *self, THD *thd,  set_var *var)
1488 {
1489   longlong val;
1490   if (session_readonly(self, thd, var))
1491     return true;
1492 
1493   val= var->save_result.ulonglong_value;
1494   if (val < (longlong) global_system_variables.net_buffer_length)
1495   {
1496     push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
1497                         WARN_OPTION_BELOW_LIMIT,
1498                         ER_THD(thd, WARN_OPTION_BELOW_LIMIT),
1499                         "max_allowed_packet", "net_buffer_length");
1500   }
1501   return false;
1502 }
1503 
1504 
1505 static Sys_var_ulong Sys_max_allowed_packet(
1506        "max_allowed_packet",
1507        "Max packet length to send to or receive from the server",
1508        SESSION_VAR(max_allowed_packet), CMD_LINE(REQUIRED_ARG),
1509        VALID_RANGE(1024, 1024*1024*1024), DEFAULT(16*1024*1024),
1510        BLOCK_SIZE(1024), NO_MUTEX_GUARD, NOT_IN_BINLOG,
1511        ON_CHECK(check_max_allowed_packet));
1512 
1513 static Sys_var_ulong Sys_slave_max_allowed_packet(
1514        "slave_max_allowed_packet",
1515        "The maximum packet length to sent successfully from the master to slave.",
1516        GLOBAL_VAR(slave_max_allowed_packet), CMD_LINE(REQUIRED_ARG),
1517        VALID_RANGE(1024, MAX_MAX_ALLOWED_PACKET),
1518        DEFAULT(MAX_MAX_ALLOWED_PACKET),
1519        BLOCK_SIZE(1024));
1520 
1521 static Sys_var_ulonglong Sys_max_binlog_cache_size(
1522        "max_binlog_cache_size",
1523        "Sets the total size of the transactional cache",
1524        GLOBAL_VAR(max_binlog_cache_size), CMD_LINE(REQUIRED_ARG),
1525        VALID_RANGE(IO_SIZE, SIZE_T_MAX),
1526        DEFAULT((SIZE_T_MAX/IO_SIZE)*IO_SIZE),
1527        BLOCK_SIZE(IO_SIZE));
1528 
1529 static Sys_var_ulonglong Sys_max_binlog_stmt_cache_size(
1530        "max_binlog_stmt_cache_size",
1531        "Sets the total size of the statement cache",
1532        GLOBAL_VAR(max_binlog_stmt_cache_size), CMD_LINE(REQUIRED_ARG),
1533        VALID_RANGE(IO_SIZE, SIZE_T_MAX),
1534        DEFAULT((SIZE_T_MAX/IO_SIZE)*IO_SIZE),
1535        BLOCK_SIZE(IO_SIZE));
1536 
1537 static bool fix_max_binlog_size(sys_var *self, THD *thd, enum_var_type type)
1538 {
1539   mysql_bin_log.set_max_size(max_binlog_size);
1540   return false;
1541 }
1542 static Sys_var_ulong Sys_max_binlog_size(
1543        "max_binlog_size",
1544        "Binary log will be rotated automatically when the size exceeds this "
1545        "value.",
1546        GLOBAL_VAR(max_binlog_size), CMD_LINE(REQUIRED_ARG),
1547        VALID_RANGE(IO_SIZE, 1024*1024L*1024L), DEFAULT(1024*1024L*1024L),
1548        BLOCK_SIZE(IO_SIZE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
1549        ON_UPDATE(fix_max_binlog_size));
1550 
1551 static bool fix_max_connections(sys_var *self, THD *thd, enum_var_type type)
1552 {
1553 #ifndef EMBEDDED_LIBRARY
1554   resize_thr_alarm(max_connections + extra_max_connections +
1555                    global_system_variables.max_insert_delayed_threads + 10);
1556 #endif
1557   return false;
1558 }
1559 
1560 // Default max_connections of 151 is larger than Apache's default max
1561 // children, to avoid "too many connections" error in a common setup
1562 static Sys_var_ulong Sys_max_connections(
1563        "max_connections", "The number of simultaneous clients allowed",
1564        PARSED_EARLY GLOBAL_VAR(max_connections), CMD_LINE(REQUIRED_ARG),
1565        VALID_RANGE(10, 100000),
1566        DEFAULT(MAX_CONNECTIONS_DEFAULT), BLOCK_SIZE(1), NO_MUTEX_GUARD,
1567        NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(fix_max_connections));
1568 
1569 static Sys_var_uint Sys_default_password_lifetime(
1570        "default_password_lifetime",
1571        "This defines the global password expiration policy. 0 means "
1572        "automatic password expiration is disabled. If the value is a "
1573        "positive integer N, the passwords must be changed every N days. This "
1574        "behavior can be overridden using the password expiration options in "
1575        "ALTER USER.",
1576        GLOBAL_VAR(default_password_lifetime), CMD_LINE(REQUIRED_ARG),
1577        VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1));
1578 
1579 static Sys_var_mybool Sys_disconnect_on_expired_password(
1580        "disconnect_on_expired_password",
1581        "This variable controls how the server handles clients that are not "
1582        "aware of the sandbox mode. If enabled, the server disconnects the "
1583        "client, otherwise the server puts the client in a sandbox mode.",
1584        GLOBAL_VAR(disconnect_on_expired_password), CMD_LINE(OPT_ARG),
1585        DEFAULT(FALSE));
1586 
1587 static Sys_var_ulong Sys_max_connect_errors(
1588        "max_connect_errors",
1589        "If there is more than this number of interrupted connections from "
1590        "a host this host will be blocked from further connections",
1591        GLOBAL_VAR(max_connect_errors), CMD_LINE(REQUIRED_ARG),
1592        VALID_RANGE(1, UINT_MAX), DEFAULT(MAX_CONNECT_ERRORS),
1593        BLOCK_SIZE(1));
1594 
1595 static Sys_var_uint Sys_max_password_errors(
1596        "max_password_errors",
1597        "If there is more than this number of failed connect attempts "
1598        "due to invalid password, user will be blocked from further connections until FLUSH_PRIVILEGES.",
1599        GLOBAL_VAR(max_password_errors), CMD_LINE(REQUIRED_ARG),
1600        VALID_RANGE(1, UINT_MAX), DEFAULT(UINT_MAX),
1601        BLOCK_SIZE(1));
1602 
1603 static Sys_var_uint Sys_max_digest_length(
1604        "max_digest_length", "Maximum length considered for digest text.",
1605        READ_ONLY GLOBAL_VAR(max_digest_length),
1606        CMD_LINE(REQUIRED_ARG),
1607        VALID_RANGE(0, 1024 * 1024), DEFAULT(1024), BLOCK_SIZE(1));
1608 
1609 static bool check_max_delayed_threads(sys_var *self, THD *thd, set_var *var)
1610 {
1611   return var->type != OPT_GLOBAL &&
1612          var->save_result.ulonglong_value != 0 &&
1613          var->save_result.ulonglong_value !=
1614                            global_system_variables.max_insert_delayed_threads;
1615 }
1616 
1617 // Alias for max_delayed_threads
1618 static Sys_var_ulong Sys_max_insert_delayed_threads(
1619        "max_insert_delayed_threads",
1620        "Don't start more than this number of threads to handle INSERT "
1621        "DELAYED statements. If set to zero INSERT DELAYED will be not used",
1622        SESSION_VAR(max_insert_delayed_threads),
1623        NO_CMD_LINE, VALID_RANGE(0, 16384), DEFAULT(20),
1624        BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG,
1625        ON_CHECK(check_max_delayed_threads), ON_UPDATE(fix_max_connections));
1626 
1627 static Sys_var_ulong Sys_max_delayed_threads(
1628        "max_delayed_threads",
1629        "Don't start more than this number of threads to handle INSERT "
1630        "DELAYED statements. If set to zero INSERT DELAYED will be not used",
1631        SESSION_VAR(max_insert_delayed_threads),
1632        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 16384), DEFAULT(20),
1633        BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG,
1634        ON_CHECK(check_max_delayed_threads), ON_UPDATE(fix_max_connections));
1635 
1636 static Sys_var_ulong Sys_max_error_count(
1637        "max_error_count",
1638        "Max number of errors/warnings to store for a statement",
1639        SESSION_VAR(max_error_count), CMD_LINE(REQUIRED_ARG),
1640        VALID_RANGE(0, 65535), DEFAULT(DEFAULT_ERROR_COUNT), BLOCK_SIZE(1));
1641 
1642 static Sys_var_ulonglong Sys_max_heap_table_size(
1643        "max_heap_table_size",
1644        "Don't allow creation of heap tables bigger than this",
1645        SESSION_VAR(max_heap_table_size), CMD_LINE(REQUIRED_ARG),
1646        VALID_RANGE(16384, SIZE_T_MAX), DEFAULT(16*1024*1024),
1647        BLOCK_SIZE(1024));
1648 
1649 static ulong mdl_locks_cache_size;
1650 static Sys_var_ulong Sys_metadata_locks_cache_size(
1651        "metadata_locks_cache_size", "Unused",
1652        READ_ONLY GLOBAL_VAR(mdl_locks_cache_size), CMD_LINE(REQUIRED_ARG),
1653        VALID_RANGE(1, 1024*1024), DEFAULT(1024),
1654        BLOCK_SIZE(1));
1655 
1656 static ulong mdl_locks_hash_partitions;
1657 static Sys_var_ulong Sys_metadata_locks_hash_instances(
1658        "metadata_locks_hash_instances", "Unused",
1659        READ_ONLY GLOBAL_VAR(mdl_locks_hash_partitions), CMD_LINE(REQUIRED_ARG),
1660        VALID_RANGE(1, 1024), DEFAULT(8),
1661        BLOCK_SIZE(1));
1662 
1663 static Sys_var_ulonglong Sys_pseudo_thread_id(
1664        "pseudo_thread_id",
1665        "This variable is for internal server use",
1666        SESSION_ONLY(pseudo_thread_id),
1667        NO_CMD_LINE, VALID_RANGE(0, ULONGLONG_MAX), DEFAULT(0),
1668        BLOCK_SIZE(1), NO_MUTEX_GUARD, IN_BINLOG,
1669        ON_CHECK(check_has_super));
1670 
1671 static bool
1672 check_gtid_domain_id(sys_var *self, THD *thd, set_var *var)
1673 {
1674   if (check_has_super(self, thd, var))
1675     return true;
1676   if (var->type != OPT_GLOBAL &&
1677       error_if_in_trans_or_substatement(thd,
1678           ER_STORED_FUNCTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO,
1679           ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO))
1680     return true;
1681 
1682   return false;
1683 }
1684 
1685 
1686 static Sys_var_uint Sys_gtid_domain_id(
1687        "gtid_domain_id",
1688        "Used with global transaction ID to identify logically independent "
1689        "replication streams. When events can propagate through multiple "
1690        "parallel paths (for example multiple masters), each independent "
1691        "source server must use a distinct domain_id. For simple tree-shaped "
1692        "replication topologies, it can be left at its default, 0.",
1693        SESSION_VAR(gtid_domain_id),
1694        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, UINT_MAX32), DEFAULT(0),
1695        BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG,
1696        ON_CHECK(check_gtid_domain_id));
1697 
1698 
1699 static bool check_gtid_seq_no(sys_var *self, THD *thd, set_var *var)
1700 {
1701   uint32 domain_id, server_id;
1702   uint64 seq_no;
1703 
1704   if (check_has_super(self, thd, var))
1705     return true;
1706   if (unlikely(error_if_in_trans_or_substatement(thd,
1707                                                  ER_STORED_FUNCTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO,
1708                                                  ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO)))
1709     return true;
1710 
1711   domain_id= thd->variables.gtid_domain_id;
1712   server_id= thd->variables.server_id;
1713   seq_no= (uint64)var->value->val_uint();
1714   DBUG_EXECUTE_IF("ignore_set_gtid_seq_no_check", return 0;);
1715   if (opt_gtid_strict_mode && opt_bin_log &&
1716       mysql_bin_log.check_strict_gtid_sequence(domain_id, server_id, seq_no))
1717     return true;
1718 
1719   return false;
1720 }
1721 
1722 
1723 static Sys_var_ulonglong Sys_gtid_seq_no(
1724        "gtid_seq_no",
1725        "Internal server usage, for replication with global transaction id. "
1726        "When set, next event group logged to the binary log will use this "
1727        "sequence number, not generate a new one, thus allowing to preserve "
1728        "master's GTID in slave's binlog.",
1729        SESSION_ONLY(gtid_seq_no),
1730        NO_CMD_LINE, VALID_RANGE(0, ULONGLONG_MAX), DEFAULT(0),
1731        BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG,
1732        ON_CHECK(check_gtid_seq_no));
1733 
1734 
1735 #ifdef HAVE_REPLICATION
1736 static unsigned char opt_gtid_binlog_pos_dummy;
1737 static Sys_var_gtid_binlog_pos Sys_gtid_binlog_pos(
1738        "gtid_binlog_pos", "Last GTID logged to the binary log, per replication"
1739        "domain",
1740        READ_ONLY GLOBAL_VAR(opt_gtid_binlog_pos_dummy), NO_CMD_LINE);
1741 
1742 
1743 const uchar *
1744 Sys_var_gtid_binlog_pos::global_value_ptr(THD *thd,
1745                                           const LEX_CSTRING *base) const
1746 {
1747   char buf[128];
1748   String str(buf, sizeof(buf), system_charset_info);
1749   char *p;
1750 
1751   str.length(0);
1752   if ((opt_bin_log && mysql_bin_log.append_state_pos(&str)) ||
1753       !(p= thd->strmake(str.ptr(), str.length())))
1754   {
1755     my_error(ER_OUT_OF_RESOURCES, MYF(0));
1756     return NULL;
1757   }
1758 
1759   return (uchar *)p;
1760 }
1761 
1762 
1763 static unsigned char opt_gtid_current_pos_dummy;
1764 static Sys_var_gtid_current_pos Sys_gtid_current_pos(
1765        "gtid_current_pos", "Current GTID position of the server. Per "
1766        "replication domain, this is either the last GTID replicated by a "
1767        "slave thread, or the GTID logged to the binary log, whichever is "
1768        "most recent.",
1769        READ_ONLY GLOBAL_VAR(opt_gtid_current_pos_dummy), NO_CMD_LINE);
1770 
1771 
1772 const uchar *
1773 Sys_var_gtid_current_pos::global_value_ptr(THD *thd,
1774                                            const LEX_CSTRING *base) const
1775 {
1776   String str;
1777   char *p;
1778 
1779   str.length(0);
1780   if (rpl_append_gtid_state(&str, true) ||
1781       !(p= thd->strmake(str.ptr(), str.length())))
1782   {
1783     my_error(ER_OUT_OF_RESOURCES, MYF(0));
1784     return NULL;
1785   }
1786 
1787   return (uchar *)p;
1788 }
1789 
1790 
1791 bool
1792 Sys_var_gtid_slave_pos::do_check(THD *thd, set_var *var)
1793 {
1794   String str, *res;
1795 
1796   DBUG_ASSERT(var->type == OPT_GLOBAL);
1797 
1798   if (rpl_load_gtid_slave_state(thd))
1799   {
1800     my_error(ER_CANNOT_LOAD_SLAVE_GTID_STATE, MYF(0), "mysql",
1801              rpl_gtid_slave_state_table_name.str);
1802     return true;
1803   }
1804 
1805   if (give_error_if_slave_running(0))
1806     return true;
1807   if (!(res= var->value->val_str(&str)))
1808     return true;
1809   if (thd->in_active_multi_stmt_transaction())
1810   {
1811     my_error(ER_CANT_DO_THIS_DURING_AN_TRANSACTION, MYF(0));
1812     return true;
1813   }
1814   if (rpl_gtid_pos_check(thd, &((*res)[0]), res->length()))
1815     return true;
1816 
1817   if (!(var->save_result.string_value.str=
1818         thd->strmake(res->ptr(), res->length())))
1819   {
1820     my_error(ER_OUT_OF_RESOURCES, MYF(0));
1821     return true;
1822   }
1823   var->save_result.string_value.length= res->length();
1824   return false;
1825 }
1826 
1827 
1828 bool
1829 Sys_var_gtid_slave_pos::global_update(THD *thd, set_var *var)
1830 {
1831   bool err;
1832 
1833   DBUG_ASSERT(var->type == OPT_GLOBAL);
1834 
1835   if (!var->value)
1836   {
1837     my_error(ER_NO_DEFAULT, MYF(0), var->var->name.str);
1838     return true;
1839   }
1840 
1841   mysql_mutex_unlock(&LOCK_global_system_variables);
1842   mysql_mutex_lock(&LOCK_active_mi);
1843   if (give_error_if_slave_running(1))
1844     err= true;
1845   else
1846     err= rpl_gtid_pos_update(thd, var->save_result.string_value.str,
1847                              var->save_result.string_value.length);
1848   mysql_mutex_unlock(&LOCK_active_mi);
1849   mysql_mutex_lock(&LOCK_global_system_variables);
1850   return err;
1851 }
1852 
1853 
1854 const uchar *
1855 Sys_var_gtid_slave_pos::global_value_ptr(THD *thd,
1856                                          const LEX_CSTRING *base) const
1857 {
1858   String str;
1859   char *p;
1860 
1861   str.length(0);
1862   /*
1863     If the mysql.rpl_slave_pos table could not be loaded, then we cannot
1864     easily automatically try to reload it here - we may be inside a statement
1865     that already has tables locked and so opening more tables is problematic.
1866 
1867     But if the table is not loaded (eg. missing mysql_upgrade_db or some such),
1868     then the slave state must be empty anyway.
1869   */
1870   if ((rpl_global_gtid_slave_state->loaded &&
1871        rpl_append_gtid_state(&str, false)) ||
1872       !(p= thd->strmake(str.ptr(), str.length())))
1873   {
1874     my_error(ER_OUT_OF_RESOURCES, MYF(0));
1875     return NULL;
1876   }
1877 
1878   return (uchar *)p;
1879 }
1880 
1881 
1882 static unsigned char opt_gtid_slave_pos_dummy;
1883 static Sys_var_gtid_slave_pos Sys_gtid_slave_pos(
1884        "gtid_slave_pos",
1885        "The list of global transaction IDs that were last replicated on the "
1886        "server, one for each replication domain.",
1887        GLOBAL_VAR(opt_gtid_slave_pos_dummy), NO_CMD_LINE);
1888 
1889 
1890 static Sys_var_mybool Sys_gtid_strict_mode(
1891        "gtid_strict_mode",
1892        "Enforce strict seq_no ordering of events in the binary log. Slave "
1893        "stops with an error if it encounters an event that would cause it to "
1894        "generate an out-of-order binlog if executed.",
1895        GLOBAL_VAR(opt_gtid_strict_mode),
1896        CMD_LINE(OPT_ARG), DEFAULT(FALSE));
1897 
1898 
1899 struct gtid_binlog_state_data { rpl_gtid *list; uint32 list_len; };
1900 
1901 bool
1902 Sys_var_gtid_binlog_state::do_check(THD *thd, set_var *var)
1903 {
1904   String str, *res;
1905   struct gtid_binlog_state_data *data;
1906   rpl_gtid *list;
1907   uint32 list_len;
1908 
1909   DBUG_ASSERT(var->type == OPT_GLOBAL);
1910 
1911   if (!(res= var->value->val_str(&str)))
1912     return true;
1913   if (thd->in_active_multi_stmt_transaction())
1914   {
1915     my_error(ER_CANT_DO_THIS_DURING_AN_TRANSACTION, MYF(0));
1916     return true;
1917   }
1918   if (!mysql_bin_log.is_open())
1919   {
1920     my_error(ER_FLUSH_MASTER_BINLOG_CLOSED, MYF(0));
1921     return true;
1922   }
1923   if (!mysql_bin_log.is_empty_state())
1924   {
1925     my_error(ER_BINLOG_MUST_BE_EMPTY, MYF(0));
1926     return true;
1927   }
1928   if (res->length() == 0)
1929   {
1930     list= NULL;
1931     list_len= 0;
1932   }
1933   else if (!(list= gtid_parse_string_to_list(res->ptr(), res->length(),
1934                                              &list_len)))
1935   {
1936     my_error(ER_INCORRECT_GTID_STATE, MYF(0));
1937     return true;
1938   }
1939   if (!(data= (gtid_binlog_state_data *)my_malloc(sizeof(*data), MYF(0))))
1940   {
1941     my_free(list);
1942     my_error(ER_OUT_OF_RESOURCES, MYF(0));
1943     return true;
1944   }
1945   data->list= list;
1946   data->list_len= list_len;
1947   var->save_result.ptr= data;
1948   return false;
1949 }
1950 
1951 
1952 bool
1953 Sys_var_gtid_binlog_state::global_update(THD *thd, set_var *var)
1954 {
1955   bool res;
1956 
1957   DBUG_ASSERT(var->type == OPT_GLOBAL);
1958 
1959   if (!var->value)
1960   {
1961     my_error(ER_NO_DEFAULT, MYF(0), var->var->name.str);
1962     return true;
1963   }
1964 
1965   struct gtid_binlog_state_data *data=
1966     (struct gtid_binlog_state_data *)var->save_result.ptr;
1967   mysql_mutex_unlock(&LOCK_global_system_variables);
1968   res= (reset_master(thd, data->list, data->list_len, 0) != 0);
1969   mysql_mutex_lock(&LOCK_global_system_variables);
1970   my_free(data->list);
1971   my_free(data);
1972   return res;
1973 }
1974 
1975 
1976 const uchar *
1977 Sys_var_gtid_binlog_state::global_value_ptr(THD *thd,
1978                                             const LEX_CSTRING *base) const
1979 {
1980   char buf[512];
1981   String str(buf, sizeof(buf), system_charset_info);
1982   char *p;
1983 
1984   str.length(0);
1985   if ((opt_bin_log && mysql_bin_log.append_state(&str)) ||
1986       !(p= thd->strmake(str.ptr(), str.length())))
1987   {
1988     my_error(ER_OUT_OF_RESOURCES, MYF(0));
1989     return NULL;
1990   }
1991 
1992   return (uchar *)p;
1993 }
1994 
1995 
1996 static unsigned char opt_gtid_binlog_state_dummy;
1997 static Sys_var_gtid_binlog_state Sys_gtid_binlog_state(
1998        "gtid_binlog_state",
1999        "The internal GTID state of the binlog, used to keep track of all "
2000        "GTIDs ever logged to the binlog.",
2001        GLOBAL_VAR(opt_gtid_binlog_state_dummy), NO_CMD_LINE);
2002 
2003 
2004 static Sys_var_last_gtid Sys_last_gtid(
2005        "last_gtid", "The GTID of the last commit (if binlogging was enabled), "
2006        "or the empty string if none.",
2007        READ_ONLY sys_var::ONLY_SESSION, NO_CMD_LINE);
2008 
2009 export sys_var *Sys_last_gtid_ptr= &Sys_last_gtid; // for check changing
2010 
2011 
2012 const uchar *
2013 Sys_var_last_gtid::session_value_ptr(THD *thd, const LEX_CSTRING *base) const
2014 {
2015   char buf[10+1+10+1+20+1];
2016   String str(buf, sizeof(buf), system_charset_info);
2017   char *p;
2018   bool first= true;
2019 
2020   str.length(0);
2021   rpl_gtid gtid= thd->get_last_commit_gtid();
2022   if ((gtid.seq_no > 0 &&
2023        rpl_slave_state_tostring_helper(&str, &gtid, &first)) ||
2024       !(p= thd->strmake(str.ptr(), str.length())))
2025   {
2026     my_error(ER_OUT_OF_RESOURCES, MYF(0));
2027     return NULL;
2028   }
2029 
2030   return (uchar *)p;
2031 }
2032 
2033 
2034 static Sys_var_uint Sys_gtid_cleanup_batch_size(
2035        "gtid_cleanup_batch_size",
2036        "Normally does not need tuning. How many old rows must accumulate in "
2037        "the mysql.gtid_slave_pos table before a background job will be run to "
2038        "delete them. Can be increased to reduce number of commits if "
2039        "using many different engines with --gtid_pos_auto_engines, or to "
2040        "reduce CPU overhead if using a huge number of different "
2041        "gtid_domain_ids. Can be decreased to reduce number of old rows in the "
2042        "table.",
2043        GLOBAL_VAR(opt_gtid_cleanup_batch_size), CMD_LINE(REQUIRED_ARG),
2044        VALID_RANGE(0,2147483647), DEFAULT(64), BLOCK_SIZE(1));
2045 
2046 
2047 static bool
2048 check_slave_parallel_threads(sys_var *self, THD *thd, set_var *var)
2049 {
2050   return give_error_if_slave_running(0);
2051 }
2052 
2053 static bool
2054 fix_slave_parallel_threads(sys_var *self, THD *thd, enum_var_type type)
2055 {
2056   bool err;
2057 
2058   mysql_mutex_unlock(&LOCK_global_system_variables);
2059   err= give_error_if_slave_running(0);
2060   mysql_mutex_lock(&LOCK_global_system_variables);
2061 
2062   return err;
2063 }
2064 
2065 
2066 static Sys_var_ulong Sys_slave_parallel_threads(
2067        "slave_parallel_threads",
2068        "If non-zero, number of threads to spawn to apply in parallel events "
2069        "on the slave that were group-committed on the master or were logged "
2070        "with GTID in different replication domains. Note that these threads "
2071        "are in addition to the IO and SQL threads, which are always created "
2072        "by a replication slave",
2073        GLOBAL_VAR(opt_slave_parallel_threads), CMD_LINE(REQUIRED_ARG),
2074        VALID_RANGE(0,16383), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD,
2075        NOT_IN_BINLOG, ON_CHECK(check_slave_parallel_threads),
2076        ON_UPDATE(fix_slave_parallel_threads));
2077 
2078 /* Alias for @@slave_parallel_threads to match what MySQL 5.7 uses. */
2079 static Sys_var_ulong Sys_slave_parallel_workers(
2080        "slave_parallel_workers",
2081        "Alias for slave_parallel_threads",
2082        GLOBAL_VAR(opt_slave_parallel_threads), CMD_LINE(REQUIRED_ARG),
2083        VALID_RANGE(0,16383), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD,
2084        NOT_IN_BINLOG, ON_CHECK(check_slave_parallel_threads),
2085        ON_UPDATE(fix_slave_parallel_threads));
2086 
2087 
2088 static bool
2089 check_slave_domain_parallel_threads(sys_var *self, THD *thd, set_var *var)
2090 {
2091   return give_error_if_slave_running(0);
2092 }
2093 
2094 static bool
2095 fix_slave_domain_parallel_threads(sys_var *self, THD *thd, enum_var_type type)
2096 {
2097   bool running;
2098 
2099   mysql_mutex_unlock(&LOCK_global_system_variables);
2100   running= give_error_if_slave_running(0);
2101   mysql_mutex_lock(&LOCK_global_system_variables);
2102 
2103   return running;
2104 }
2105 
2106 
2107 static Sys_var_ulong Sys_slave_domain_parallel_threads(
2108        "slave_domain_parallel_threads",
2109        "Maximum number of parallel threads to use on slave for events in a "
2110        "single replication domain. When using multiple domains, this can be "
2111        "used to limit a single domain from grabbing all threads and thus "
2112        "stalling other domains. The default of 0 means to allow a domain to "
2113        "grab as many threads as it wants, up to the value of "
2114        "slave_parallel_threads.",
2115        GLOBAL_VAR(opt_slave_domain_parallel_threads), CMD_LINE(REQUIRED_ARG),
2116        VALID_RANGE(0,16383), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD,
2117        NOT_IN_BINLOG, ON_CHECK(check_slave_domain_parallel_threads),
2118        ON_UPDATE(fix_slave_domain_parallel_threads));
2119 
2120 
2121 static Sys_var_ulong Sys_slave_parallel_max_queued(
2122        "slave_parallel_max_queued",
2123        "Limit on how much memory SQL threads should use per parallel "
2124        "replication thread when reading ahead in the relay log looking for "
2125        "opportunities for parallel replication. Only used when "
2126        "--slave-parallel-threads > 0.",
2127        GLOBAL_VAR(opt_slave_parallel_max_queued), CMD_LINE(REQUIRED_ARG),
2128        VALID_RANGE(0,2147483647), DEFAULT(131072), BLOCK_SIZE(1));
2129 
2130 
2131 bool
2132 Sys_var_slave_parallel_mode::global_update(THD *thd, set_var *var)
2133 {
2134   enum_slave_parallel_mode new_value=
2135     (enum_slave_parallel_mode)var->save_result.ulonglong_value;
2136   LEX_CSTRING *base_name= &var->base;
2137   Master_info *mi;
2138   bool res= false;
2139 
2140   if (!base_name->length)
2141     base_name= &thd->variables.default_master_connection;
2142 
2143   mysql_mutex_unlock(&LOCK_global_system_variables);
2144   mysql_mutex_lock(&LOCK_active_mi);
2145 
2146   mi= master_info_index->
2147     get_master_info(base_name, !base_name->length ?
2148                     Sql_condition::WARN_LEVEL_ERROR :
2149                     Sql_condition::WARN_LEVEL_WARN);
2150 
2151   if (mi)
2152   {
2153     if (mi->rli.slave_running)
2154     {
2155       my_error(ER_SLAVE_MUST_STOP, MYF(0),
2156                (int) mi->connection_name.length, mi->connection_name.str);
2157       res= true;
2158     }
2159     else
2160     {
2161       mi->parallel_mode= new_value;
2162       if (!base_name->length)
2163       {
2164         /* Use as default value for new connections */
2165         opt_slave_parallel_mode= new_value;
2166       }
2167     }
2168   }
2169 
2170   mysql_mutex_unlock(&LOCK_active_mi);
2171   mysql_mutex_lock(&LOCK_global_system_variables);
2172 
2173   return res;
2174 }
2175 
2176 
2177 const uchar *
2178 Sys_var_slave_parallel_mode::global_value_ptr(THD *thd,
2179                                               const
2180                                               LEX_CSTRING *base_name) const
2181 {
2182   Master_info *mi;
2183   enum_slave_parallel_mode val=
2184     (enum_slave_parallel_mode)opt_slave_parallel_mode;
2185 
2186   if (!base_name->length)
2187     base_name= &thd->variables.default_master_connection;
2188 
2189   mysql_mutex_unlock(&LOCK_global_system_variables);
2190   mysql_mutex_lock(&LOCK_active_mi);
2191 
2192   mi= master_info_index->
2193     get_master_info(base_name, !base_name->length ?
2194                     Sql_condition::WARN_LEVEL_ERROR :
2195                     Sql_condition::WARN_LEVEL_WARN);
2196   if (mi)
2197     val= mi->parallel_mode;
2198 
2199   mysql_mutex_unlock(&LOCK_active_mi);
2200   mysql_mutex_lock(&LOCK_global_system_variables);
2201   if (!mi)
2202     return 0;
2203 
2204   return valptr(thd, val);
2205 }
2206 
2207 
2208 /* The order here must match enum_slave_parallel_mode in mysqld.h. */
2209 static const char *slave_parallel_mode_names[] = {
2210   "none", "minimal", "conservative", "optimistic", "aggressive", NULL
2211 };
2212 export TYPELIB slave_parallel_mode_typelib = {
2213   array_elements(slave_parallel_mode_names)-1,
2214   "",
2215   slave_parallel_mode_names,
2216   NULL
2217 };
2218 
2219 static Sys_var_slave_parallel_mode Sys_slave_parallel_mode(
2220        "slave_parallel_mode",
2221        "Controls what transactions are applied in parallel when using "
2222        "--slave-parallel-threads. Possible values: \"optimistic\" tries to "
2223        "apply most transactional DML in parallel, and handles any conflicts "
2224        "with rollback and retry. \"conservative\" limits parallelism in an "
2225        "effort to avoid any conflicts. \"aggressive\" tries to maximise the "
2226        "parallelism, possibly at the cost of increased conflict rate. "
2227        "\"minimal\" only parallelizes the commit steps of transactions. "
2228        "\"none\" disables parallel apply completely.",
2229        GLOBAL_VAR(opt_slave_parallel_mode), NO_CMD_LINE,
2230        slave_parallel_mode_names, DEFAULT(SLAVE_PARALLEL_CONSERVATIVE));
2231 
2232 
2233 static Sys_var_bit Sys_skip_parallel_replication(
2234        "skip_parallel_replication",
2235        "If set when a transaction is written to the binlog, parallel apply of "
2236        "that transaction will be avoided on a slave where slave_parallel_mode "
2237        "is not \"aggressive\". Can be used to avoid unnecessary rollback and "
2238        "retry for transactions that are likely to cause a conflict if "
2239        "replicated in parallel.",
2240        SESSION_ONLY(option_bits), NO_CMD_LINE, OPTION_RPL_SKIP_PARALLEL,
2241        DEFAULT(FALSE));
2242 
2243 
2244 static bool
2245 check_gtid_ignore_duplicates(sys_var *self, THD *thd, set_var *var)
2246 {
2247   return give_error_if_slave_running(0);
2248 }
2249 
2250 static bool
2251 fix_gtid_ignore_duplicates(sys_var *self, THD *thd, enum_var_type type)
2252 {
2253   bool running;
2254 
2255   mysql_mutex_unlock(&LOCK_global_system_variables);
2256   running= give_error_if_slave_running(0);
2257   mysql_mutex_lock(&LOCK_global_system_variables);
2258 
2259   return running;
2260 }
2261 
2262 
2263 static Sys_var_mybool Sys_gtid_ignore_duplicates(
2264        "gtid_ignore_duplicates",
2265        "When set, different master connections in multi-source replication are "
2266        "allowed to receive and process event groups with the same GTID (when "
2267        "using GTID mode). Only one will be applied, any others will be "
2268        "ignored. Within a given replication domain, just the sequence number "
2269        "will be used to decide whether a given GTID has been already applied; "
2270        "this means it is the responsibility of the user to ensure that GTID "
2271        "sequence numbers are strictly increasing.",
2272        GLOBAL_VAR(opt_gtid_ignore_duplicates), CMD_LINE(OPT_ARG),
2273        DEFAULT(FALSE), NO_MUTEX_GUARD,
2274        NOT_IN_BINLOG, ON_CHECK(check_gtid_ignore_duplicates),
2275        ON_UPDATE(fix_gtid_ignore_duplicates));
2276 #endif
2277 
2278 
2279 static Sys_var_ulong Sys_binlog_commit_wait_count(
2280        "binlog_commit_wait_count",
2281        "If non-zero, binlog write will wait at most binlog_commit_wait_usec "
2282        "microseconds for at least this many commits to queue up for group "
2283        "commit to the binlog. This can reduce I/O on the binlog and provide "
2284        "increased opportunity for parallel apply on the slave, but too high "
2285        "a value will decrease commit throughput.",
2286        GLOBAL_VAR(opt_binlog_commit_wait_count), CMD_LINE(REQUIRED_ARG),
2287        VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1));
2288 
2289 
2290 static Sys_var_ulong Sys_binlog_commit_wait_usec(
2291        "binlog_commit_wait_usec",
2292        "Maximum time, in microseconds, to wait for more commits to queue up "
2293        "for binlog group commit. Only takes effect if the value of "
2294        "binlog_commit_wait_count is non-zero.",
2295        GLOBAL_VAR(opt_binlog_commit_wait_usec), CMD_LINE(REQUIRED_ARG),
2296        VALID_RANGE(0, ULONG_MAX), DEFAULT(100000), BLOCK_SIZE(1));
2297 
2298 
2299 static bool fix_max_join_size(sys_var *self, THD *thd, enum_var_type type)
2300 {
2301   SV *sv= type == OPT_GLOBAL ? &global_system_variables : &thd->variables;
2302   if (sv->max_join_size == HA_POS_ERROR)
2303     sv->option_bits|= OPTION_BIG_SELECTS;
2304   else
2305     sv->option_bits&= ~OPTION_BIG_SELECTS;
2306   return false;
2307 }
2308 static Sys_var_harows Sys_max_join_size(
2309        "max_join_size",
2310        "Joins that are probably going to read more than max_join_size "
2311        "records return an error",
2312        SESSION_VAR(max_join_size), CMD_LINE(REQUIRED_ARG),
2313        VALID_RANGE(1, HA_POS_ERROR), DEFAULT(HA_POS_ERROR), BLOCK_SIZE(1),
2314        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
2315        ON_UPDATE(fix_max_join_size));
2316 
2317 static Sys_var_ulong Sys_max_seeks_for_key(
2318        "max_seeks_for_key",
2319        "Limit assumed max number of seeks when looking up rows based on a key",
2320        SESSION_VAR(max_seeks_for_key), CMD_LINE(REQUIRED_ARG),
2321        VALID_RANGE(1, UINT_MAX), DEFAULT(UINT_MAX), BLOCK_SIZE(1));
2322 
2323 static Sys_var_ulong Sys_max_length_for_sort_data(
2324        "max_length_for_sort_data",
2325        "Max number of bytes in sorted records",
2326        SESSION_VAR(max_length_for_sort_data), CMD_LINE(REQUIRED_ARG),
2327        VALID_RANGE(4, 8192*1024L), DEFAULT(1024), BLOCK_SIZE(1));
2328 
2329 static Sys_var_ulong Sys_max_long_data_size(
2330        "max_long_data_size",
2331        "The maximum BLOB length to send to server from "
2332        "mysql_send_long_data API. Deprecated option; "
2333        "use max_allowed_packet instead.",
2334        READ_ONLY GLOBAL_VAR(max_long_data_size),
2335        CMD_LINE(REQUIRED_ARG, OPT_MAX_LONG_DATA_SIZE),
2336        VALID_RANGE(1024, UINT_MAX32), DEFAULT(1024*1024),
2337        BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG,
2338        ON_CHECK(0), ON_UPDATE(0),
2339        DEPRECATED("'@@max_allowed_packet'"));
2340 
2341 static PolyLock_mutex PLock_prepared_stmt_count(&LOCK_prepared_stmt_count);
2342 static Sys_var_uint Sys_max_prepared_stmt_count(
2343        "max_prepared_stmt_count",
2344        "Maximum number of prepared statements in the server",
2345        GLOBAL_VAR(max_prepared_stmt_count), CMD_LINE(REQUIRED_ARG),
2346        VALID_RANGE(0, UINT_MAX32), DEFAULT(16382), BLOCK_SIZE(1),
2347        &PLock_prepared_stmt_count);
2348 
2349 static Sys_var_ulong Sys_max_recursive_iterations(
2350        "max_recursive_iterations",
2351        "Maximum number of iterations when executing recursive queries",
2352        SESSION_VAR(max_recursive_iterations), CMD_LINE(OPT_ARG),
2353        VALID_RANGE(0, UINT_MAX), DEFAULT(UINT_MAX), BLOCK_SIZE(1));
2354 
2355 static Sys_var_ulong Sys_max_sort_length(
2356        "max_sort_length",
2357        "The number of bytes to use when sorting BLOB or TEXT values (only "
2358        "the first max_sort_length bytes of each value are used; the rest "
2359        "are ignored)",
2360        SESSION_VAR(max_sort_length), CMD_LINE(REQUIRED_ARG),
2361        VALID_RANGE(64, 8192*1024L), DEFAULT(1024), BLOCK_SIZE(1));
2362 
2363 static Sys_var_ulong Sys_max_sp_recursion_depth(
2364        "max_sp_recursion_depth",
2365        "Maximum stored procedure recursion depth",
2366        SESSION_VAR(max_sp_recursion_depth), CMD_LINE(OPT_ARG),
2367        VALID_RANGE(0, 255), DEFAULT(0), BLOCK_SIZE(1));
2368 
2369 
2370 static bool if_checking_enabled(sys_var *self, THD *thd,  set_var *var)
2371 {
2372   if (session_readonly(self, thd, var))
2373     return true;
2374 
2375   if (!max_user_connections_checking)
2376   {
2377     my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--max-user-connections=0");
2378     return true;
2379   }
2380 
2381   return false;
2382 }
2383 // non-standard session_value_ptr() here
2384 static Sys_var_max_user_conn Sys_max_user_connections(
2385        "max_user_connections",
2386        "The maximum number of active connections for a single user "
2387        "(0 = no limit)",
2388        SESSION_VAR(max_user_connections), CMD_LINE(REQUIRED_ARG),
2389        VALID_RANGE(-1, INT_MAX), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD,
2390        NOT_IN_BINLOG, ON_CHECK(if_checking_enabled));
2391 
2392 static Sys_var_ulong Sys_max_tmp_tables(
2393        "max_tmp_tables", "Unused, will be removed.",
2394        SESSION_VAR(max_tmp_tables), CMD_LINE(REQUIRED_ARG),
2395        VALID_RANGE(1, UINT_MAX), DEFAULT(32), BLOCK_SIZE(1),
2396        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0),
2397        DEPRECATED(""));
2398 
2399 static Sys_var_ulong Sys_max_write_lock_count(
2400        "max_write_lock_count",
2401        "After this many write locks, allow some read locks to run in between",
2402        GLOBAL_VAR(max_write_lock_count), CMD_LINE(REQUIRED_ARG),
2403        VALID_RANGE(1, UINT_MAX), DEFAULT(UINT_MAX), BLOCK_SIZE(1));
2404 
2405 static Sys_var_ulong Sys_min_examined_row_limit(
2406        "min_examined_row_limit",
2407        "Don't write queries to slow log that examine fewer rows "
2408        "than that",
2409        SESSION_VAR(min_examined_row_limit), CMD_LINE(REQUIRED_ARG),
2410        VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1));
2411 
2412 #ifdef _WIN32
2413 static Sys_var_mybool Sys_named_pipe(
2414        "named_pipe", "Enable the named pipe (NT)",
2415        READ_ONLY GLOBAL_VAR(opt_enable_named_pipe), CMD_LINE(OPT_ARG),
2416        DEFAULT(FALSE));
2417 #endif
2418 
2419 
2420 static bool check_net_buffer_length(sys_var *self, THD *thd,  set_var *var)
2421 {
2422   longlong val;
2423   if (session_readonly(self, thd, var))
2424     return true;
2425 
2426   val= var->save_result.ulonglong_value;
2427   if (val > (longlong) global_system_variables.max_allowed_packet)
2428   {
2429     push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
2430                         WARN_OPTION_BELOW_LIMIT,
2431                         ER_THD(thd, WARN_OPTION_BELOW_LIMIT),
2432                         "max_allowed_packet", "net_buffer_length");
2433   }
2434   return false;
2435 }
2436 static Sys_var_ulong Sys_net_buffer_length(
2437        "net_buffer_length",
2438        "Buffer length for TCP/IP and socket communication",
2439        SESSION_VAR(net_buffer_length), CMD_LINE(REQUIRED_ARG),
2440        VALID_RANGE(1024, 1024*1024), DEFAULT(16384), BLOCK_SIZE(1024),
2441        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_net_buffer_length));
2442 
2443 static bool fix_net_read_timeout(sys_var *self, THD *thd, enum_var_type type)
2444 {
2445   if (type != OPT_GLOBAL)
2446     my_net_set_read_timeout(&thd->net, thd->variables.net_read_timeout);
2447   return false;
2448 }
2449 static Sys_var_ulong Sys_net_read_timeout(
2450        "net_read_timeout",
2451        "Number of seconds to wait for more data from a connection before "
2452        "aborting the read",
2453        SESSION_VAR(net_read_timeout), CMD_LINE(REQUIRED_ARG),
2454        VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(NET_READ_TIMEOUT), BLOCK_SIZE(1),
2455        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
2456        ON_UPDATE(fix_net_read_timeout));
2457 
2458 static bool fix_net_write_timeout(sys_var *self, THD *thd, enum_var_type type)
2459 {
2460   if (type != OPT_GLOBAL)
2461     my_net_set_write_timeout(&thd->net, thd->variables.net_write_timeout);
2462   return false;
2463 }
2464 static Sys_var_ulong Sys_net_write_timeout(
2465        "net_write_timeout",
2466        "Number of seconds to wait for a block to be written to a connection "
2467        "before aborting the write",
2468        SESSION_VAR(net_write_timeout), CMD_LINE(REQUIRED_ARG),
2469        VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(NET_WRITE_TIMEOUT), BLOCK_SIZE(1),
2470        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
2471        ON_UPDATE(fix_net_write_timeout));
2472 
2473 static bool fix_net_retry_count(sys_var *self, THD *thd, enum_var_type type)
2474 {
2475   if (type != OPT_GLOBAL)
2476     thd->net.retry_count=thd->variables.net_retry_count;
2477   return false;
2478 }
2479 static Sys_var_ulong Sys_net_retry_count(
2480        "net_retry_count",
2481        "If a read on a communication port is interrupted, retry this "
2482        "many times before giving up",
2483        SESSION_VAR(net_retry_count), CMD_LINE(REQUIRED_ARG),
2484        VALID_RANGE(1, UINT_MAX), DEFAULT(MYSQLD_NET_RETRY_COUNT),
2485        BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
2486        ON_UPDATE(fix_net_retry_count));
2487 
2488 static Sys_var_mybool Sys_old_mode(
2489        "old", "Use compatible behavior from previous MariaDB version. See also --old-mode",
2490        SESSION_VAR(old_mode), CMD_LINE(OPT_ARG), DEFAULT(FALSE));
2491 
2492 static const char *alter_algorithm_modes[]= {"DEFAULT", "COPY", "INPLACE",
2493 "NOCOPY", "INSTANT", NULL};
2494 
2495 static Sys_var_enum Sys_alter_algorithm(
2496 	"alter_algorithm", "Specify the alter table algorithm",
2497 	SESSION_VAR(alter_algorithm), CMD_LINE(OPT_ARG),
2498 	alter_algorithm_modes, DEFAULT(0));
2499 
2500 static Sys_var_enum Sys_old_alter_table(
2501        "old_alter_table", "Alias for alter_algorithm. "
2502        "Deprecated. Use --alter-algorithm instead.",
2503        SESSION_VAR(alter_algorithm), CMD_LINE(OPT_ARG),
2504        alter_algorithm_modes, DEFAULT(0));
2505 
2506 static bool check_old_passwords(sys_var *self, THD *thd, set_var *var)
2507 {
2508   return mysql_user_table_is_in_short_password_format;
2509 }
2510 static Sys_var_mybool Sys_old_passwords(
2511        "old_passwords",
2512        "Use old password encryption method (needed for 4.0 and older clients)",
2513        SESSION_VAR(old_passwords), CMD_LINE(OPT_ARG),
2514        DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG,
2515        ON_CHECK(check_old_passwords));
2516 export sys_var *Sys_old_passwords_ptr= &Sys_old_passwords; // for sql_acl.cc
2517 
2518 static Sys_var_ulong Sys_open_files_limit(
2519        "open_files_limit",
2520        "If this is not 0, then mysqld will use this value to reserve file "
2521        "descriptors to use with setrlimit(). If this value is 0 or autoset "
2522        "then mysqld will reserve max_connections*5 or max_connections + "
2523        "table_cache*2 (whichever is larger) number of file descriptors",
2524        AUTO_SET READ_ONLY GLOBAL_VAR(open_files_limit), CMD_LINE(REQUIRED_ARG),
2525        VALID_RANGE(0, OS_FILE_LIMIT), DEFAULT(0), BLOCK_SIZE(1));
2526 
2527 /// @todo change to enum
2528 static Sys_var_ulong Sys_optimizer_prune_level(
2529        "optimizer_prune_level",
2530        "Controls the heuristic(s) applied during query optimization to prune "
2531        "less-promising partial plans from the optimizer search space. "
2532        "Meaning: 0 - do not apply any heuristic, thus perform exhaustive "
2533        "search; 1 - prune plans based on number of retrieved rows",
2534        SESSION_VAR(optimizer_prune_level), CMD_LINE(REQUIRED_ARG),
2535        VALID_RANGE(0, 1), DEFAULT(1), BLOCK_SIZE(1));
2536 
2537 static Sys_var_ulong Sys_optimizer_selectivity_sampling_limit(
2538        "optimizer_selectivity_sampling_limit",
2539        "Controls number of record samples to check condition selectivity",
2540        SESSION_VAR(optimizer_selectivity_sampling_limit),
2541        CMD_LINE(REQUIRED_ARG),
2542        VALID_RANGE(SELECTIVITY_SAMPLING_THRESHOLD, UINT_MAX),
2543        DEFAULT(SELECTIVITY_SAMPLING_LIMIT), BLOCK_SIZE(1));
2544 
2545 static Sys_var_ulong Sys_optimizer_use_condition_selectivity(
2546        "optimizer_use_condition_selectivity",
2547        "Controls selectivity of which conditions the optimizer takes into "
2548        "account to calculate cardinality of a partial join when it searches "
2549        "for the best execution plan "
2550        "Meaning: "
2551        "1 - use selectivity of index backed range conditions to calculate "
2552        "the cardinality of a partial join if the last joined table is "
2553        "accessed by full table scan or an index scan, "
2554        "2 - use selectivity of index backed range conditions to calculate "
2555        "the cardinality of a partial join in any case, "
2556        "3 - additionally always use selectivity of range conditions that are "
2557        "not backed by any index to calculate the cardinality of a partial join, "
2558        "4 - use histograms to calculate selectivity of range conditions that "
2559        "are not backed by any index to calculate the cardinality of "
2560        "a partial join."
2561        "5 - additionally use selectivity of certain non-range predicates "
2562        "calculated on record samples",
2563        SESSION_VAR(optimizer_use_condition_selectivity), CMD_LINE(REQUIRED_ARG),
2564        VALID_RANGE(1, 5), DEFAULT(4), BLOCK_SIZE(1));
2565 
2566 static Sys_var_ulong Sys_optimizer_search_depth(
2567        "optimizer_search_depth",
2568        "Maximum depth of search performed by the query optimizer. Values "
2569        "larger than the number of relations in a query result in better "
2570        "query plans, but take longer to compile a query. Values smaller "
2571        "than the number of tables in a relation result in faster "
2572        "optimization, but may produce very bad query plans. If set to 0, "
2573        "the system will automatically pick a reasonable value.",
2574        SESSION_VAR(optimizer_search_depth), CMD_LINE(REQUIRED_ARG),
2575        VALID_RANGE(0, MAX_TABLES+1), DEFAULT(MAX_TABLES+1), BLOCK_SIZE(1));
2576 
2577 /* this is used in the sigsegv handler */
2578 export const char *optimizer_switch_names[]=
2579 {
2580   "index_merge","index_merge_union","index_merge_sort_union",
2581   "index_merge_intersection","index_merge_sort_intersection",
2582   "engine_condition_pushdown",
2583   "index_condition_pushdown",
2584   "derived_merge", "derived_with_keys",
2585   "firstmatch","loosescan","materialization","in_to_exists","semijoin",
2586   "partial_match_rowid_merge",
2587   "partial_match_table_scan",
2588   "subquery_cache",
2589   "mrr",
2590   "mrr_cost_based",
2591   "mrr_sort_keys",
2592   "outer_join_with_cache",
2593   "semijoin_with_cache",
2594   "join_cache_incremental",
2595   "join_cache_hashed",
2596   "join_cache_bka",
2597   "optimize_join_buffer_size",
2598   "table_elimination",
2599   "extended_keys",
2600   "exists_to_in",
2601   "orderby_uses_equalities",
2602   "condition_pushdown_for_derived",
2603   "split_materialized",
2604   "condition_pushdown_for_subquery",
2605   "rowid_filter",
2606   "condition_pushdown_from_having",
2607   "default",
2608   NullS
2609 };
2610 static bool fix_optimizer_switch(sys_var *self, THD *thd,
2611                                  enum_var_type type)
2612 {
2613   SV *sv= (type == OPT_GLOBAL) ? &global_system_variables : &thd->variables;
2614   if (sv->optimizer_switch & deprecated_ENGINE_CONDITION_PUSHDOWN)
2615     push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
2616                         ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT,
2617                         ER_THD(thd, ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT),
2618                         "engine_condition_pushdown=on");
2619   return false;
2620 }
2621 static bool check_legal_optimizer_switch(sys_var *self, THD *thd,
2622                                          set_var *var)
2623 {
2624   if (var->save_result.ulonglong_value & (OPTIMIZER_SWITCH_MATERIALIZATION |
2625                                           OPTIMIZER_SWITCH_IN_TO_EXISTS))
2626   {
2627     return false;
2628   }
2629   my_error(ER_ILLEGAL_SUBQUERY_OPTIMIZER_SWITCHES, MYF(0));
2630   return true;
2631 }
2632 static Sys_var_flagset Sys_optimizer_switch(
2633        "optimizer_switch",
2634        "Fine-tune the optimizer behavior",
2635        SESSION_VAR(optimizer_switch), CMD_LINE(REQUIRED_ARG),
2636        optimizer_switch_names, DEFAULT(OPTIMIZER_SWITCH_DEFAULT),
2637        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_legal_optimizer_switch),
2638        ON_UPDATE(fix_optimizer_switch));
2639 
2640 static Sys_var_flagset Sys_optimizer_trace(
2641     "optimizer_trace",
2642     "Controls tracing of the Optimizer:"
2643     " optimizer_trace=option=val[,option=val...], where option is one of"
2644     " {enabled}"
2645     " and val is one of {on, off, default}",
2646     SESSION_VAR(optimizer_trace), CMD_LINE(REQUIRED_ARG),
2647     Opt_trace_context::flag_names, DEFAULT(Opt_trace_context::FLAG_DEFAULT));
2648     // @see set_var::is_var_optimizer_trace()
2649 export sys_var *Sys_optimizer_trace_ptr = &Sys_optimizer_trace;
2650 
2651 static Sys_var_ulong Sys_optimizer_trace_max_mem_size(
2652     "optimizer_trace_max_mem_size",
2653     "Maximum allowed size of an optimizer trace",
2654     SESSION_VAR(optimizer_trace_max_mem_size), CMD_LINE(REQUIRED_ARG),
2655     VALID_RANGE(0, ULONG_MAX), DEFAULT(1024 * 1024), BLOCK_SIZE(1));
2656 
2657 static Sys_var_charptr Sys_pid_file(
2658        "pid_file", "Pid file used by safe_mysqld",
2659        READ_ONLY GLOBAL_VAR(pidfile_name_ptr), CMD_LINE(REQUIRED_ARG),
2660        IN_FS_CHARSET, DEFAULT(0));
2661 
2662 static Sys_var_charptr Sys_plugin_dir(
2663        "plugin_dir", "Directory for plugins",
2664        READ_ONLY GLOBAL_VAR(opt_plugin_dir_ptr), CMD_LINE(REQUIRED_ARG),
2665        IN_FS_CHARSET, DEFAULT(0));
2666 
2667 static Sys_var_uint Sys_port(
2668        "port",
2669        "Port number to use for connection or 0 to default to, "
2670        "my.cnf, $MYSQL_TCP_PORT, "
2671 #if MYSQL_PORT_DEFAULT == 0
2672        "/etc/services, "
2673 #endif
2674        "built-in default (" STRINGIFY_ARG(MYSQL_PORT) "), whatever comes first",
2675        READ_ONLY GLOBAL_VAR(mysqld_port), CMD_LINE(REQUIRED_ARG, 'P'),
2676        VALID_RANGE(0, UINT_MAX32), DEFAULT(0), BLOCK_SIZE(1));
2677 
2678 static Sys_var_ulong Sys_preload_buff_size(
2679        "preload_buffer_size",
2680        "The size of the buffer that is allocated when preloading indexes",
2681        SESSION_VAR(preload_buff_size), CMD_LINE(REQUIRED_ARG),
2682        VALID_RANGE(1024, 1024*1024*1024), DEFAULT(32768), BLOCK_SIZE(1));
2683 
2684 static Sys_var_uint Sys_protocol_version(
2685        "protocol_version",
2686        "The version of the client/server protocol used by the MariaDB server",
2687        READ_ONLY GLOBAL_VAR(protocol_version), CMD_LINE_HELP_ONLY,
2688        VALID_RANGE(0, ~0U), DEFAULT(PROTOCOL_VERSION), BLOCK_SIZE(1));
2689 
2690 static Sys_var_proxy_user Sys_proxy_user(
2691        "proxy_user", "The proxy user account name used when logging in",
2692        IN_SYSTEM_CHARSET);
2693 
2694 static Sys_var_external_user Sys_exterenal_user(
2695        "external_user", "The external user account used when logging in",
2696        IN_SYSTEM_CHARSET);
2697 
2698 static Sys_var_ulong Sys_read_buff_size(
2699        "read_buffer_size",
2700        "Each thread that does a sequential scan allocates a buffer of "
2701        "this size for each table it scans. If you do many sequential scans, "
2702        "you may want to increase this value",
2703        SESSION_VAR(read_buff_size), CMD_LINE(REQUIRED_ARG),
2704        VALID_RANGE(IO_SIZE*2, INT_MAX32), DEFAULT(128*1024),
2705        BLOCK_SIZE(IO_SIZE));
2706 
2707 static bool check_read_only(sys_var *self, THD *thd, set_var *var)
2708 {
2709   /* Prevent self dead-lock */
2710   if (thd->locked_tables_mode || thd->in_active_multi_stmt_transaction() ||
2711       thd->current_backup_stage != BACKUP_FINISHED)
2712   {
2713     my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
2714     return true;
2715   }
2716   return false;
2717 }
2718 
2719 static bool fix_read_only(sys_var *self, THD *thd, enum_var_type type)
2720 {
2721   bool result= true;
2722   my_bool new_read_only= read_only; // make a copy before releasing a mutex
2723   DBUG_ENTER("sys_var_opt_readonly::update");
2724 
2725   if (read_only == FALSE || read_only == opt_readonly)
2726   {
2727     opt_readonly= read_only;
2728     DBUG_RETURN(false);
2729   }
2730 
2731   if (check_read_only(self, thd, 0)) // just in case
2732     goto end;
2733 
2734   if (thd->global_read_lock.is_acquired())
2735   {
2736     /*
2737       This connection already holds the global read lock.
2738       This can be the case with:
2739       - FLUSH TABLES WITH READ LOCK
2740       - SET GLOBAL READ_ONLY = 1
2741     */
2742     opt_readonly= read_only;
2743     DBUG_RETURN(false);
2744   }
2745 
2746   /*
2747     READ_ONLY=1 prevents write locks from being taken on tables and
2748     blocks transactions from committing. We therefore should make sure
2749     that no such events occur while setting the read_only variable.
2750     This is a 2 step process:
2751     [1] lock_global_read_lock()
2752       Prevents connections from obtaining new write locks on
2753       tables. Note that we can still have active rw transactions.
2754     [2] make_global_read_lock_block_commit()
2755       Prevents transactions from committing.
2756   */
2757 
2758   read_only= opt_readonly;
2759   mysql_mutex_unlock(&LOCK_global_system_variables);
2760 
2761   if (thd->global_read_lock.lock_global_read_lock(thd))
2762     goto end_with_mutex_unlock;
2763 
2764   if ((result= thd->global_read_lock.make_global_read_lock_block_commit(thd)))
2765     goto end_with_read_lock;
2766 
2767   /* Change the opt_readonly system variable, safe because the lock is held */
2768   opt_readonly= new_read_only;
2769   result= false;
2770 
2771  end_with_read_lock:
2772   /* Release the lock */
2773   thd->global_read_lock.unlock_global_read_lock(thd);
2774  end_with_mutex_unlock:
2775   mysql_mutex_lock(&LOCK_global_system_variables);
2776  end:
2777   read_only= opt_readonly;
2778   DBUG_RETURN(result);
2779 }
2780 
2781 
2782 /**
2783   The read_only boolean is always equal to the opt_readonly boolean except
2784   during fix_read_only(); when that function is entered, opt_readonly is
2785   the pre-update value and read_only is the post-update value.
2786   fix_read_only() compares them and runs needed operations for the
2787   transition (especially when transitioning from false to true) and
2788   synchronizes both booleans in the end.
2789 */
2790 static Sys_var_mybool Sys_readonly(
2791        "read_only",
2792        "Make all non-temporary tables read-only, with the exception for "
2793        "replication (slave) threads and users with the SUPER privilege",
2794        GLOBAL_VAR(read_only), CMD_LINE(OPT_ARG), DEFAULT(FALSE),
2795        NO_MUTEX_GUARD, NOT_IN_BINLOG,
2796        ON_CHECK(check_read_only), ON_UPDATE(fix_read_only));
2797 
2798 // Small lower limit to be able to test MRR
2799 static Sys_var_ulong Sys_read_rnd_buff_size(
2800        "read_rnd_buffer_size",
2801        "When reading rows in sorted order after a sort, the rows are read "
2802        "through this buffer to avoid a disk seeks",
2803        SESSION_VAR(read_rnd_buff_size), CMD_LINE(REQUIRED_ARG),
2804        VALID_RANGE(1, INT_MAX32), DEFAULT(256*1024), BLOCK_SIZE(1));
2805 
2806 static Sys_var_ulong Sys_div_precincrement(
2807        "div_precision_increment", "Precision of the result of '/' "
2808        "operator will be increased on that value",
2809        SESSION_VAR(div_precincrement), CMD_LINE(REQUIRED_ARG),
2810        VALID_RANGE(0, DECIMAL_MAX_SCALE), DEFAULT(4), BLOCK_SIZE(1));
2811 
2812 static Sys_var_uint Sys_eq_range_index_dive_limit(
2813        "eq_range_index_dive_limit",
2814        "The optimizer will use existing index statistics instead of "
2815        "doing index dives for equality ranges if the number of equality "
2816        "ranges for the index is larger than or equal to this number. "
2817        "If set to 0, index dives are always used.",
2818        SESSION_VAR(eq_range_index_dive_limit), CMD_LINE(REQUIRED_ARG),
2819        VALID_RANGE(0, UINT_MAX32), DEFAULT(200),
2820        BLOCK_SIZE(1));
2821 
2822 static Sys_var_ulong Sys_range_alloc_block_size(
2823        "range_alloc_block_size",
2824        "Allocation block size for storing ranges during optimization",
2825        SESSION_VAR(range_alloc_block_size), CMD_LINE(REQUIRED_ARG),
2826        VALID_RANGE(RANGE_ALLOC_BLOCK_SIZE, UINT_MAX),
2827        DEFAULT(RANGE_ALLOC_BLOCK_SIZE), BLOCK_SIZE(1024));
2828 
2829 static Sys_var_ulong Sys_multi_range_count(
2830        "multi_range_count", "Ignored. Use mrr_buffer_size instead",
2831        SESSION_VAR(multi_range_count), CMD_LINE(REQUIRED_ARG),
2832        VALID_RANGE(1, ULONG_MAX), DEFAULT(256), BLOCK_SIZE(1),
2833        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0),
2834        DEPRECATED("'@@mrr_buffer_size'"));
2835 
2836 static bool fix_thd_mem_root(sys_var *self, THD *thd, enum_var_type type)
2837 {
2838   if (type != OPT_GLOBAL)
2839     reset_root_defaults(thd->mem_root,
2840                         thd->variables.query_alloc_block_size,
2841                         thd->variables.query_prealloc_size);
2842   return false;
2843 }
2844 static Sys_var_ulong Sys_query_alloc_block_size(
2845        "query_alloc_block_size",
2846        "Allocation block size for query parsing and execution",
2847        SESSION_VAR(query_alloc_block_size), CMD_LINE(REQUIRED_ARG),
2848        VALID_RANGE(1024, UINT_MAX), DEFAULT(QUERY_ALLOC_BLOCK_SIZE),
2849        BLOCK_SIZE(1024), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
2850        ON_UPDATE(fix_thd_mem_root));
2851 
2852 static Sys_var_ulong Sys_query_prealloc_size(
2853        "query_prealloc_size",
2854        "Persistent buffer for query parsing and execution",
2855        SESSION_VAR(query_prealloc_size), CMD_LINE(REQUIRED_ARG),
2856        VALID_RANGE(1024, UINT_MAX),
2857        DEFAULT(QUERY_ALLOC_PREALLOC_SIZE),
2858        BLOCK_SIZE(1024), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
2859        ON_UPDATE(fix_thd_mem_root));
2860 
2861 
2862 // this has to be NO_CMD_LINE as the command-line option has a different name
2863 static Sys_var_mybool Sys_skip_external_locking(
2864        "skip_external_locking", "Don't use system (external) locking",
2865        READ_ONLY GLOBAL_VAR(my_disable_locking), NO_CMD_LINE, DEFAULT(TRUE));
2866 
2867 static Sys_var_mybool Sys_skip_networking(
2868        "skip_networking", "Don't allow connection with TCP/IP",
2869        READ_ONLY GLOBAL_VAR(opt_disable_networking), CMD_LINE(OPT_ARG),
2870        DEFAULT(FALSE));
2871 
2872 static Sys_var_mybool Sys_skip_name_resolve(
2873        "skip_name_resolve",
2874        "Don't resolve hostnames. All hostnames are IP's or 'localhost'.",
2875        READ_ONLY GLOBAL_VAR(opt_skip_name_resolve),
2876        CMD_LINE(OPT_ARG, OPT_SKIP_RESOLVE),
2877        DEFAULT(FALSE));
2878 
2879 static Sys_var_mybool Sys_skip_show_database(
2880        "skip_show_database", "Don't allow 'SHOW DATABASE' commands",
2881        READ_ONLY GLOBAL_VAR(opt_skip_show_db), CMD_LINE(OPT_ARG),
2882        DEFAULT(FALSE));
2883 
2884 static Sys_var_charptr Sys_socket(
2885        "socket", "Socket file to use for connection",
2886        READ_ONLY GLOBAL_VAR(mysqld_unix_port), CMD_LINE(REQUIRED_ARG),
2887        IN_FS_CHARSET, DEFAULT(0));
2888 
2889 /*
2890   thread_concurrency is a no-op on all platforms since
2891   MySQL 5.1.  It will be removed in the context of
2892   WL#5265
2893 */
2894 static Sys_var_ulong Sys_thread_concurrency(
2895        "thread_concurrency",
2896        "Permits the application to give the threads system a hint for "
2897        "the desired number of threads that should be run at the same time."
2898        "This variable has no effect, and is deprecated. "
2899        "It will be removed in a future release.",
2900        READ_ONLY GLOBAL_VAR(concurrency),
2901        CMD_LINE(REQUIRED_ARG, OPT_THREAD_CONCURRENCY),
2902        VALID_RANGE(1, 512), DEFAULT(DEFAULT_CONCURRENCY), BLOCK_SIZE(1),
2903        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0),
2904        DEPRECATED(""));
2905 
2906 static Sys_var_ulonglong Sys_thread_stack(
2907        "thread_stack", "The stack size for each thread",
2908        READ_ONLY GLOBAL_VAR(my_thread_stack_size), CMD_LINE(REQUIRED_ARG),
2909        VALID_RANGE(128*1024, ULONGLONG_MAX), DEFAULT(DEFAULT_THREAD_STACK),
2910        BLOCK_SIZE(1024));
2911 
2912 static Sys_var_charptr Sys_tmpdir(
2913        "tmpdir", "Path for temporary files. Several paths may "
2914        "be specified, separated by a "
2915 #if defined(__WIN__)
2916        "semicolon (;)"
2917 #else
2918        "colon (:)"
2919 #endif
2920        ", in this case they are used in a round-robin fashion",
2921        READ_ONLY GLOBAL_VAR(opt_mysql_tmpdir), CMD_LINE(REQUIRED_ARG, 't'),
2922        IN_FS_CHARSET, DEFAULT(0));
2923 
2924 static bool fix_trans_mem_root(sys_var *self, THD *thd, enum_var_type type)
2925 {
2926   if (type != OPT_GLOBAL)
2927     reset_root_defaults(&thd->transaction.mem_root,
2928                         thd->variables.trans_alloc_block_size,
2929                         thd->variables.trans_prealloc_size);
2930   return false;
2931 }
2932 static Sys_var_ulong Sys_trans_alloc_block_size(
2933        "transaction_alloc_block_size",
2934        "Allocation block size for transactions to be stored in binary log",
2935        SESSION_VAR(trans_alloc_block_size), CMD_LINE(REQUIRED_ARG),
2936        VALID_RANGE(1024, 128 * 1024 * 1024), DEFAULT(TRANS_ALLOC_BLOCK_SIZE),
2937        BLOCK_SIZE(1024), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
2938        ON_UPDATE(fix_trans_mem_root));
2939 
2940 static Sys_var_ulong Sys_trans_prealloc_size(
2941        "transaction_prealloc_size",
2942        "Persistent buffer for transactions to be stored in binary log",
2943        SESSION_VAR(trans_prealloc_size), CMD_LINE(REQUIRED_ARG),
2944        VALID_RANGE(1024, 128 * 1024 * 1024), DEFAULT(TRANS_ALLOC_PREALLOC_SIZE),
2945        BLOCK_SIZE(1024), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
2946        ON_UPDATE(fix_trans_mem_root));
2947 
2948 static const char *thread_handling_names[]=
2949 {
2950   "one-thread-per-connection", "no-threads",
2951 #ifdef HAVE_POOL_OF_THREADS
2952   "pool-of-threads",
2953 #endif
2954   0
2955 };
2956 
2957 #if defined (_WIN32) && defined (HAVE_POOL_OF_THREADS)
2958 /* Windows is using OS threadpool, so we're pretty sure it works well */
2959 #define DEFAULT_THREAD_HANDLING 2
2960 #else
2961 #define DEFAULT_THREAD_HANDLING 0
2962 #endif
2963 
2964 static Sys_var_enum Sys_thread_handling(
2965        "thread_handling",
2966        "Define threads usage for handling queries",
2967        READ_ONLY GLOBAL_VAR(thread_handling), CMD_LINE(REQUIRED_ARG),
2968        thread_handling_names,
2969        DEFAULT(DEFAULT_THREAD_HANDLING)
2970  );
2971 
2972 #ifdef HAVE_QUERY_CACHE
2973 static bool fix_query_cache_size(sys_var *self, THD *thd, enum_var_type type)
2974 {
2975   size_t new_cache_size= query_cache.resize((size_t)query_cache_size);
2976   /*
2977      Note: query_cache_size is a global variable reflecting the
2978      requested cache size. See also query_cache_size_arg
2979   */
2980   if (query_cache_size != new_cache_size)
2981     push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
2982                         ER_WARN_QC_RESIZE, ER_THD(thd, ER_WARN_QC_RESIZE),
2983                         query_cache_size, (ulong)new_cache_size);
2984 
2985   query_cache_size= new_cache_size;
2986 
2987   return false;
2988 }
2989 
2990 static bool fix_query_cache_limit(sys_var *self, THD *thd, enum_var_type type)
2991 {
2992   query_cache.result_size_limit(query_cache_limit);
2993   return false;
2994 }
2995 static Sys_var_ulonglong Sys_query_cache_size(
2996        "query_cache_size",
2997        "The memory allocated to store results from old queries",
2998        GLOBAL_VAR(query_cache_size), CMD_LINE(REQUIRED_ARG),
2999        VALID_RANGE(0, ULONG_MAX), DEFAULT(1024*1024), BLOCK_SIZE(1024),
3000        NO_MUTEX_GUARD, NOT_IN_BINLOG, NULL,
3001        ON_UPDATE(fix_query_cache_size));
3002 
3003 static Sys_var_ulong Sys_query_cache_limit(
3004        "query_cache_limit",
3005        "Don't cache results that are bigger than this",
3006        GLOBAL_VAR(query_cache_limit), CMD_LINE(REQUIRED_ARG),
3007        VALID_RANGE(0, UINT_MAX), DEFAULT(1024*1024), BLOCK_SIZE(1),
3008        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
3009        ON_UPDATE(fix_query_cache_limit));
3010 
3011 static bool fix_qcache_min_res_unit(sys_var *self, THD *thd, enum_var_type type)
3012 {
3013   query_cache_min_res_unit=
3014     (ulong)query_cache.set_min_res_unit(query_cache_min_res_unit);
3015   return false;
3016 }
3017 static Sys_var_ulong Sys_query_cache_min_res_unit(
3018        "query_cache_min_res_unit",
3019        "The minimum size for blocks allocated by the query cache",
3020        GLOBAL_VAR(query_cache_min_res_unit), CMD_LINE(REQUIRED_ARG),
3021        VALID_RANGE(0, UINT_MAX), DEFAULT(QUERY_CACHE_MIN_RESULT_DATA_SIZE),
3022        BLOCK_SIZE(8), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
3023        ON_UPDATE(fix_qcache_min_res_unit));
3024 
3025 static const char *query_cache_type_names[]= { "OFF", "ON", "DEMAND", 0 };
3026 
3027 static bool check_query_cache_type(sys_var *self, THD *thd, set_var *var)
3028 {
3029   if (query_cache.is_disable_in_progress())
3030   {
3031     my_error(ER_QUERY_CACHE_IS_DISABLED, MYF(0));
3032     return true;
3033   }
3034 
3035   if (var->type != OPT_GLOBAL && global_system_variables.query_cache_type == 0)
3036   {
3037     if (var->value)
3038     {
3039       if (var->save_result.ulonglong_value != 0)
3040       {
3041         my_error(ER_QUERY_CACHE_IS_GLOBALY_DISABLED, MYF(0));
3042         return true;
3043       }
3044     }
3045   }
3046   return false;
3047 }
3048 
3049 
3050 static bool fix_query_cache_type(sys_var *self, THD *thd, enum_var_type type)
3051 {
3052   if (type != OPT_GLOBAL)
3053     return false;
3054 
3055   if (global_system_variables.query_cache_type != 0 &&
3056       query_cache.is_disabled())
3057   {
3058     /* if disabling in progress variable will not be set */
3059     DBUG_ASSERT(!query_cache.is_disable_in_progress());
3060     /* Enable query cache because it was disabled */
3061     fix_query_cache_size(0, thd, type);
3062   }
3063   else if (global_system_variables.query_cache_type == 0)
3064     query_cache.disable_query_cache(thd);
3065   return false;
3066 }
3067 static Sys_var_enum Sys_query_cache_type(
3068        "query_cache_type",
3069        "OFF = Don't cache or retrieve results. ON = Cache all results "
3070        "except SELECT SQL_NO_CACHE ... queries. DEMAND = Cache only "
3071        "SELECT SQL_CACHE ... queries",
3072        NO_SET_STMT SESSION_VAR(query_cache_type), CMD_LINE(REQUIRED_ARG),
3073        query_cache_type_names, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
3074        ON_CHECK(check_query_cache_type),
3075        ON_UPDATE(fix_query_cache_type));
3076 
3077 static Sys_var_mybool Sys_query_cache_wlock_invalidate(
3078        "query_cache_wlock_invalidate",
3079        "Invalidate queries in query cache on LOCK for write",
3080        SESSION_VAR(query_cache_wlock_invalidate), CMD_LINE(OPT_ARG),
3081        DEFAULT(FALSE));
3082 #endif /* HAVE_QUERY_CACHE */
3083 
3084 static Sys_var_mybool Sys_secure_auth(
3085        "secure_auth",
3086        "Disallow authentication for accounts that have old (pre-4.1) "
3087        "passwords",
3088        GLOBAL_VAR(opt_secure_auth), CMD_LINE(OPT_ARG),
3089        DEFAULT(TRUE));
3090 
3091 static Sys_var_charptr Sys_secure_file_priv(
3092        "secure_file_priv",
3093        "Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
3094        "within specified directory",
3095        PREALLOCATED READ_ONLY GLOBAL_VAR(opt_secure_file_priv),
3096        CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET, DEFAULT(0));
3097 
3098 static bool fix_server_id(sys_var *self, THD *thd, enum_var_type type)
3099 {
3100   if (type == OPT_GLOBAL)
3101   {
3102     thd->variables.server_id= global_system_variables.server_id;
3103     /*
3104       Historically, server_id was a global variable that is exported to
3105       plugins. Now it is a session variable, and lives in the
3106       global_system_variables struct, but we still need to export the
3107       value for reading to plugins for backwards compatibility reasons.
3108     */
3109     ::server_id= global_system_variables.server_id;
3110   }
3111   return false;
3112 }
3113 static Sys_var_ulong Sys_server_id(
3114        "server_id",
3115        "Uniquely identifies the server instance in the community of "
3116        "replication partners",
3117        SESSION_VAR(server_id), CMD_LINE(REQUIRED_ARG, OPT_SERVER_ID),
3118        VALID_RANGE(1, UINT_MAX32), DEFAULT(1), BLOCK_SIZE(1), NO_MUTEX_GUARD,
3119        NOT_IN_BINLOG, ON_CHECK(check_has_super), ON_UPDATE(fix_server_id));
3120 
3121 static Sys_var_mybool Sys_slave_compressed_protocol(
3122        "slave_compressed_protocol",
3123        "Use compression on master/slave protocol",
3124        GLOBAL_VAR(opt_slave_compressed_protocol), CMD_LINE(OPT_ARG),
3125        DEFAULT(FALSE));
3126 
3127 #ifdef HAVE_REPLICATION
3128 static const char *slave_exec_mode_names[]= {"STRICT", "IDEMPOTENT", 0};
3129 static Sys_var_enum Slave_exec_mode(
3130        "slave_exec_mode",
3131        "How replication events should be executed. Legal values "
3132        "are STRICT (default) and IDEMPOTENT. In IDEMPOTENT mode, "
3133        "replication will not stop for operations that are idempotent. "
3134        "For example, in row based replication attempts to delete rows that "
3135        "doesn't exist will be ignored. "
3136        "In STRICT mode, replication will stop on any unexpected difference "
3137        "between the master and the slave.",
3138        GLOBAL_VAR(slave_exec_mode_options), CMD_LINE(REQUIRED_ARG),
3139        slave_exec_mode_names, DEFAULT(SLAVE_EXEC_MODE_STRICT));
3140 
3141 static Sys_var_enum Slave_ddl_exec_mode(
3142        "slave_ddl_exec_mode",
3143        "How replication events should be executed. Legal values "
3144        "are STRICT and IDEMPOTENT (default). In IDEMPOTENT mode, "
3145        "replication will not stop for DDL operations that are idempotent. "
3146        "This means that CREATE TABLE is treated as CREATE TABLE OR REPLACE and "
3147        "DROP TABLE is treated as DROP TABLE IF EXISTS.",
3148        GLOBAL_VAR(slave_ddl_exec_mode_options), CMD_LINE(REQUIRED_ARG),
3149        slave_exec_mode_names, DEFAULT(SLAVE_EXEC_MODE_IDEMPOTENT));
3150 
3151 static const char *slave_run_triggers_for_rbr_names[]=
3152   {"NO", "YES", "LOGGING", 0};
3153 static Sys_var_enum Slave_run_triggers_for_rbr(
3154        "slave_run_triggers_for_rbr",
3155        "Modes for how triggers in row-base replication on slave side will be "
3156        "executed. Legal values are NO (default), YES and LOGGING. NO means "
3157        "that trigger for RBR will not be running on slave. YES and LOGGING "
3158        "means that triggers will be running on slave, if there was not "
3159        "triggers running on the master for the statement. LOGGING also means "
3160        "results of that the executed triggers work will be written to "
3161        "the binlog.",
3162        GLOBAL_VAR(slave_run_triggers_for_rbr), CMD_LINE(REQUIRED_ARG),
3163        slave_run_triggers_for_rbr_names,
3164        DEFAULT(SLAVE_RUN_TRIGGERS_FOR_RBR_NO));
3165 
3166 static const char *slave_type_conversions_name[]= {"ALL_LOSSY", "ALL_NON_LOSSY", 0};
3167 static Sys_var_set Slave_type_conversions(
3168        "slave_type_conversions",
3169        "Set of slave type conversions that are enabled."
3170        " If the variable is empty, no conversions are"
3171        " allowed and it is expected that the types match exactly",
3172        GLOBAL_VAR(slave_type_conversions_options), CMD_LINE(REQUIRED_ARG),
3173        slave_type_conversions_name,
3174        DEFAULT(0));
3175 
3176 static Sys_var_mybool Sys_slave_sql_verify_checksum(
3177        "slave_sql_verify_checksum",
3178        "Force checksum verification of replication events after reading them "
3179        "from relay log. Note: Events are always checksum-verified by slave on "
3180        "receiving them from the network before writing them to the relay log",
3181        GLOBAL_VAR(opt_slave_sql_verify_checksum), CMD_LINE(OPT_ARG),
3182        DEFAULT(TRUE));
3183 
3184 static Sys_var_mybool Sys_master_verify_checksum(
3185        "master_verify_checksum",
3186        "Force checksum verification of logged events in the binary log before "
3187        "sending them to slaves or printing them in the output of "
3188        "SHOW BINLOG EVENTS",
3189        GLOBAL_VAR(opt_master_verify_checksum), CMD_LINE(OPT_ARG),
3190        DEFAULT(FALSE));
3191 
3192 /* These names must match RPL_SKIP_XXX #defines in slave.h. */
3193 static const char *replicate_events_marked_for_skip_names[]= {
3194   "REPLICATE", "FILTER_ON_SLAVE", "FILTER_ON_MASTER", 0
3195 };
3196 
3197 bool
3198 Sys_var_replicate_events_marked_for_skip::global_update(THD *thd, set_var *var)
3199 {
3200   bool result= true;                            // Assume error
3201   DBUG_ENTER("Sys_var_replicate_events_marked_for_skip::global_update");
3202 
3203   mysql_mutex_unlock(&LOCK_global_system_variables);
3204   if (!give_error_if_slave_running(0))
3205     result= Sys_var_enum::global_update(thd, var);
3206   mysql_mutex_lock(&LOCK_global_system_variables);
3207   DBUG_RETURN(result);
3208 }
3209 
3210 static Sys_var_replicate_events_marked_for_skip Replicate_events_marked_for_skip
3211    ("replicate_events_marked_for_skip",
3212    "Whether the slave should replicate events that were created with "
3213    "@@skip_replication=1 on the master. Default REPLICATE (no events are "
3214    "skipped). Other values are FILTER_ON_SLAVE (events will be sent by the "
3215    "master but ignored by the slave) and FILTER_ON_MASTER (events marked with "
3216    "@@skip_replication=1 will be filtered on the master and never be sent to "
3217    "the slave).",
3218    GLOBAL_VAR(opt_replicate_events_marked_for_skip), CMD_LINE(REQUIRED_ARG),
3219    replicate_events_marked_for_skip_names, DEFAULT(RPL_SKIP_REPLICATE));
3220 
3221 /* new options for semisync */
3222 
3223 static bool fix_rpl_semi_sync_master_enabled(sys_var *self, THD *thd,
3224                                              enum_var_type type)
3225 {
3226   mysql_mutex_unlock(&LOCK_global_system_variables);
3227   mysql_mutex_lock(&repl_semisync_master.LOCK_rpl_semi_sync_master_enabled);
3228   if (rpl_semi_sync_master_enabled)
3229   {
3230     if (repl_semisync_master.enable_master() != 0)
3231       rpl_semi_sync_master_enabled= false;
3232     else if (ack_receiver.start())
3233     {
3234       repl_semisync_master.disable_master();
3235       rpl_semi_sync_master_enabled= false;
3236     }
3237   }
3238   else
3239   {
3240     repl_semisync_master.disable_master();
3241     ack_receiver.stop();
3242   }
3243   mysql_mutex_unlock(&repl_semisync_master.LOCK_rpl_semi_sync_master_enabled);
3244   mysql_mutex_lock(&LOCK_global_system_variables);
3245   return false;
3246 }
3247 
3248 static bool fix_rpl_semi_sync_master_timeout(sys_var *self, THD *thd,
3249                                              enum_var_type type)
3250 {
3251   repl_semisync_master.set_wait_timeout(rpl_semi_sync_master_timeout);
3252   return false;
3253 }
3254 
3255 static bool fix_rpl_semi_sync_master_trace_level(sys_var *self, THD *thd,
3256                                                  enum_var_type type)
3257 {
3258   repl_semisync_master.set_trace_level(rpl_semi_sync_master_trace_level);
3259   ack_receiver.set_trace_level(rpl_semi_sync_master_trace_level);
3260   return false;
3261 }
3262 
3263 static bool fix_rpl_semi_sync_master_wait_point(sys_var *self, THD *thd,
3264                                                 enum_var_type type)
3265 {
3266   repl_semisync_master.set_wait_point(rpl_semi_sync_master_wait_point);
3267   return false;
3268 }
3269 
3270 static bool fix_rpl_semi_sync_master_wait_no_slave(sys_var *self, THD *thd,
3271                                                    enum_var_type type)
3272 {
3273   repl_semisync_master.check_and_switch();
3274   return false;
3275 }
3276 
3277 static Sys_var_mybool Sys_semisync_master_enabled(
3278        "rpl_semi_sync_master_enabled",
3279        "Enable semi-synchronous replication master (disabled by default).",
3280        GLOBAL_VAR(rpl_semi_sync_master_enabled),
3281        CMD_LINE(OPT_ARG), DEFAULT(FALSE),
3282        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
3283        ON_UPDATE(fix_rpl_semi_sync_master_enabled));
3284 
3285 static Sys_var_ulong Sys_semisync_master_timeout(
3286        "rpl_semi_sync_master_timeout",
3287        "The timeout value (in ms) for semi-synchronous replication in the "
3288        "master",
3289        GLOBAL_VAR(rpl_semi_sync_master_timeout),
3290        CMD_LINE(REQUIRED_ARG),
3291        VALID_RANGE(0,~0L),DEFAULT(10000),BLOCK_SIZE(1),
3292        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
3293        ON_UPDATE(fix_rpl_semi_sync_master_timeout));
3294 
3295 static Sys_var_mybool Sys_semisync_master_wait_no_slave(
3296        "rpl_semi_sync_master_wait_no_slave",
3297        "Wait until timeout when no semi-synchronous replication slave "
3298        "available (enabled by default).",
3299        GLOBAL_VAR(rpl_semi_sync_master_wait_no_slave),
3300        CMD_LINE(OPT_ARG), DEFAULT(TRUE),
3301        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
3302        ON_UPDATE(fix_rpl_semi_sync_master_wait_no_slave));
3303 
3304 static Sys_var_ulong Sys_semisync_master_trace_level(
3305        "rpl_semi_sync_master_trace_level",
3306        "The tracing level for semi-sync replication.",
3307        GLOBAL_VAR(rpl_semi_sync_master_trace_level),
3308        CMD_LINE(REQUIRED_ARG),
3309        VALID_RANGE(0,~0L),DEFAULT(32),BLOCK_SIZE(1),
3310        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
3311        ON_UPDATE(fix_rpl_semi_sync_master_trace_level));
3312 
3313 static const char *repl_semisync_wait_point[]=
3314 {"AFTER_SYNC", "AFTER_COMMIT", NullS};
3315 
3316 static Sys_var_enum Sys_semisync_master_wait_point(
3317        "rpl_semi_sync_master_wait_point",
3318        "Should transaction wait for semi-sync ack after having synced binlog, "
3319        "or after having committed in storage engine.",
3320        GLOBAL_VAR(rpl_semi_sync_master_wait_point), CMD_LINE(REQUIRED_ARG),
3321        repl_semisync_wait_point, DEFAULT(1),
3322        NO_MUTEX_GUARD, NOT_IN_BINLOG,ON_CHECK(0),
3323        ON_UPDATE(fix_rpl_semi_sync_master_wait_point));
3324 
3325 static bool fix_rpl_semi_sync_slave_enabled(sys_var *self, THD *thd,
3326                                             enum_var_type type)
3327 {
3328   repl_semisync_slave.set_slave_enabled(rpl_semi_sync_slave_enabled != 0);
3329   return false;
3330 }
3331 
3332 static bool fix_rpl_semi_sync_slave_trace_level(sys_var *self, THD *thd,
3333                                                 enum_var_type type)
3334 {
3335   repl_semisync_slave.set_trace_level(rpl_semi_sync_slave_trace_level);
3336   return false;
3337 }
3338 
3339 static bool fix_rpl_semi_sync_slave_delay_master(sys_var *self, THD *thd,
3340                                                  enum_var_type type)
3341 {
3342   repl_semisync_slave.set_delay_master(rpl_semi_sync_slave_delay_master);
3343   return false;
3344 }
3345 
3346 static bool fix_rpl_semi_sync_slave_kill_conn_timeout(sys_var *self, THD *thd,
3347                                                       enum_var_type type)
3348 {
3349   repl_semisync_slave.
3350     set_kill_conn_timeout(rpl_semi_sync_slave_kill_conn_timeout);
3351   return false;
3352 }
3353 
3354 static Sys_var_mybool Sys_semisync_slave_enabled(
3355        "rpl_semi_sync_slave_enabled",
3356        "Enable semi-synchronous replication slave (disabled by default).",
3357        GLOBAL_VAR(rpl_semi_sync_slave_enabled),
3358        CMD_LINE(OPT_ARG), DEFAULT(FALSE),
3359        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
3360        ON_UPDATE(fix_rpl_semi_sync_slave_enabled));
3361 
3362 static Sys_var_ulong Sys_semisync_slave_trace_level(
3363        "rpl_semi_sync_slave_trace_level",
3364        "The tracing level for semi-sync replication.",
3365        GLOBAL_VAR(rpl_semi_sync_slave_trace_level),
3366        CMD_LINE(REQUIRED_ARG),
3367        VALID_RANGE(0,~0L),DEFAULT(32),BLOCK_SIZE(1),
3368        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
3369        ON_UPDATE(fix_rpl_semi_sync_slave_trace_level));
3370 
3371 static Sys_var_mybool Sys_semisync_slave_delay_master(
3372        "rpl_semi_sync_slave_delay_master",
3373        "Only write master info file when ack is needed.",
3374        GLOBAL_VAR(rpl_semi_sync_slave_delay_master),
3375        CMD_LINE(OPT_ARG), DEFAULT(FALSE),
3376        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
3377        ON_UPDATE(fix_rpl_semi_sync_slave_delay_master));
3378 
3379 static Sys_var_uint  Sys_semisync_slave_kill_conn_timeout(
3380        "rpl_semi_sync_slave_kill_conn_timeout",
3381        "Timeout for the mysql connection used to kill the slave io_thread's "
3382        "connection on master. This timeout comes into play when stop slave "
3383        "is executed.",
3384        GLOBAL_VAR(rpl_semi_sync_slave_kill_conn_timeout),
3385        CMD_LINE(OPT_ARG),
3386        VALID_RANGE(0, UINT_MAX), DEFAULT(5), BLOCK_SIZE(1),
3387        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
3388        ON_UPDATE(fix_rpl_semi_sync_slave_kill_conn_timeout));
3389 #endif /* HAVE_REPLICATION */
3390 
3391 static Sys_var_ulong Sys_slow_launch_time(
3392        "slow_launch_time",
3393        "If creating the thread takes longer than this value (in seconds), "
3394        "the Slow_launch_threads counter will be incremented",
3395        GLOBAL_VAR(slow_launch_time), CMD_LINE(REQUIRED_ARG),
3396        VALID_RANGE(0, LONG_TIMEOUT), DEFAULT(2), BLOCK_SIZE(1));
3397 
3398 static Sys_var_ulonglong Sys_sort_buffer(
3399        "sort_buffer_size",
3400        "Each thread that needs to do a sort allocates a buffer of this size",
3401        SESSION_VAR(sortbuff_size), CMD_LINE(REQUIRED_ARG),
3402        VALID_RANGE(MIN_SORT_MEMORY, SIZE_T_MAX), DEFAULT(MAX_SORT_MEMORY),
3403        BLOCK_SIZE(1));
3404 
3405 export sql_mode_t expand_sql_mode(sql_mode_t sql_mode)
3406 {
3407   if (sql_mode & MODE_ANSI)
3408   {
3409     /*
3410       Note that we dont set
3411       MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | MODE_NO_FIELD_OPTIONS
3412       to allow one to get full use of MySQL in this mode.
3413 
3414       MODE_ONLY_FULL_GROUP_BY was removed from ANSI mode because it is
3415       currently overly restrictive (see BUG#8510).
3416     */
3417     sql_mode|= (MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
3418                 MODE_IGNORE_SPACE);
3419   }
3420   if (sql_mode & MODE_ORACLE)
3421     sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
3422                 MODE_IGNORE_SPACE |
3423                 MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
3424                 MODE_NO_FIELD_OPTIONS | MODE_NO_AUTO_CREATE_USER |
3425                 MODE_SIMULTANEOUS_ASSIGNMENT);
3426   if (sql_mode & MODE_MSSQL)
3427     sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
3428                 MODE_IGNORE_SPACE |
3429                 MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
3430                 MODE_NO_FIELD_OPTIONS);
3431   if (sql_mode & MODE_POSTGRESQL)
3432     sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
3433                 MODE_IGNORE_SPACE |
3434                 MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
3435                 MODE_NO_FIELD_OPTIONS);
3436   if (sql_mode & MODE_DB2)
3437     sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
3438                 MODE_IGNORE_SPACE |
3439                 MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
3440                 MODE_NO_FIELD_OPTIONS);
3441   if (sql_mode & MODE_MAXDB)
3442     sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
3443                 MODE_IGNORE_SPACE |
3444                 MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
3445                 MODE_NO_FIELD_OPTIONS | MODE_NO_AUTO_CREATE_USER);
3446   if (sql_mode & MODE_MYSQL40)
3447     sql_mode|= MODE_HIGH_NOT_PRECEDENCE;
3448   if (sql_mode & MODE_MYSQL323)
3449     sql_mode|= MODE_HIGH_NOT_PRECEDENCE;
3450   if (sql_mode & MODE_TRADITIONAL)
3451     sql_mode|= (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES |
3452                 MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
3453                 MODE_ERROR_FOR_DIVISION_BY_ZERO | MODE_NO_AUTO_CREATE_USER |
3454                 MODE_NO_ENGINE_SUBSTITUTION);
3455   return sql_mode;
3456 }
3457 static bool check_sql_mode(sys_var *self, THD *thd, set_var *var)
3458 {
3459   var->save_result.ulonglong_value=
3460     (ulonglong) expand_sql_mode(var->save_result.ulonglong_value);
3461   return false;
3462 }
3463 static bool fix_sql_mode(sys_var *self, THD *thd, enum_var_type type)
3464 {
3465   if (type != OPT_GLOBAL)
3466   {
3467     /* Update thd->server_status */
3468     if (thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)
3469       thd->server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES;
3470     else
3471       thd->server_status&= ~SERVER_STATUS_NO_BACKSLASH_ESCAPES;
3472     if (thd->variables.sql_mode & MODE_ANSI_QUOTES)
3473       thd->server_status|= SERVER_STATUS_ANSI_QUOTES;
3474     else
3475       thd->server_status&= ~SERVER_STATUS_ANSI_QUOTES;
3476   }
3477   return false;
3478 }
3479 /*
3480   WARNING: When adding new SQL modes don't forget to update the
3481   tables definitions that stores it's value (ie: mysql.event, mysql.proc)
3482 */
3483 static const char *sql_mode_names[]=
3484 {
3485   "REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE",
3486   "IGNORE_BAD_TABLE_OPTIONS",
3487   "ONLY_FULL_GROUP_BY", "NO_UNSIGNED_SUBTRACTION", "NO_DIR_IN_CREATE",
3488   "POSTGRESQL", "ORACLE", "MSSQL", "DB2", "MAXDB", "NO_KEY_OPTIONS",
3489   "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", "MYSQL323", "MYSQL40", "ANSI",
3490   "NO_AUTO_VALUE_ON_ZERO", "NO_BACKSLASH_ESCAPES", "STRICT_TRANS_TABLES",
3491   "STRICT_ALL_TABLES", "NO_ZERO_IN_DATE", "NO_ZERO_DATE",
3492   "ALLOW_INVALID_DATES", "ERROR_FOR_DIVISION_BY_ZERO", "TRADITIONAL",
3493   "NO_AUTO_CREATE_USER", "HIGH_NOT_PRECEDENCE", "NO_ENGINE_SUBSTITUTION",
3494   "PAD_CHAR_TO_FULL_LENGTH", "EMPTY_STRING_IS_NULL", "SIMULTANEOUS_ASSIGNMENT",
3495   "TIME_ROUND_FRACTIONAL",
3496   0
3497 };
3498 
3499 
3500 const char *sql_mode_string_representation(uint bit_number)
3501 {
3502   DBUG_ASSERT(bit_number < array_elements(sql_mode_names));
3503   return sql_mode_names[bit_number];
3504 }
3505 
3506 
3507 export bool sql_mode_string_representation(THD *thd, sql_mode_t sql_mode,
3508                                            LEX_CSTRING *ls)
3509 {
3510   set_to_string(thd, ls, sql_mode, sql_mode_names);
3511   return ls->str == 0;
3512 }
3513 /*
3514   sql_mode should *not* be IN_BINLOG: even though it is written to the binlog,
3515   the slave ignores the MODE_NO_DIR_IN_CREATE variable, so slave's value
3516   differs from master's (see log_event.cc: Query_log_event::do_apply_event()).
3517 */
3518 static Sys_var_set Sys_sql_mode(
3519        "sql_mode",
3520        "Sets the sql mode",
3521        SESSION_VAR(sql_mode), CMD_LINE(REQUIRED_ARG),
3522        sql_mode_names,
3523        DEFAULT(MODE_STRICT_TRANS_TABLES |
3524                MODE_ERROR_FOR_DIVISION_BY_ZERO |
3525                MODE_NO_ENGINE_SUBSTITUTION |
3526                MODE_NO_AUTO_CREATE_USER),
3527        NO_MUTEX_GUARD, NOT_IN_BINLOG,
3528        ON_CHECK(check_sql_mode), ON_UPDATE(fix_sql_mode));
3529 
3530 static const char *old_mode_names[]=
3531 {
3532   "NO_DUP_KEY_WARNINGS_WITH_IGNORE",
3533   "NO_PROGRESS_INFO",
3534   "ZERO_DATE_TIME_CAST",
3535   0
3536 };
3537 
3538 /*
3539   sql_mode should *not* be IN_BINLOG as the slave can't remember this
3540   anyway on restart.
3541 */
3542 static Sys_var_set Sys_old_behavior(
3543        "old_mode",
3544        "Used to emulate old behavior from earlier MariaDB or MySQL versions",
3545        SESSION_VAR(old_behavior), CMD_LINE(REQUIRED_ARG),
3546        old_mode_names, DEFAULT(0));
3547 
3548 #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
3549 #define SSL_OPT(X) CMD_LINE(REQUIRED_ARG,X)
3550 #else
3551 #define SSL_OPT(X) NO_CMD_LINE
3552 #endif
3553 
3554 static Sys_var_charptr Sys_ssl_ca(
3555        "ssl_ca",
3556        "CA file in PEM format (check OpenSSL docs, implies --ssl)",
3557        READ_ONLY GLOBAL_VAR(opt_ssl_ca), SSL_OPT(OPT_SSL_CA),
3558        IN_FS_CHARSET, DEFAULT(0));
3559 
3560 static Sys_var_charptr Sys_ssl_capath(
3561        "ssl_capath",
3562        "CA directory (check OpenSSL docs, implies --ssl)",
3563        READ_ONLY GLOBAL_VAR(opt_ssl_capath), SSL_OPT(OPT_SSL_CAPATH),
3564        IN_FS_CHARSET, DEFAULT(0));
3565 
3566 static Sys_var_charptr Sys_ssl_cert(
3567        "ssl_cert", "X509 cert in PEM format (implies --ssl)",
3568        READ_ONLY GLOBAL_VAR(opt_ssl_cert), SSL_OPT(OPT_SSL_CERT),
3569        IN_FS_CHARSET, DEFAULT(0));
3570 
3571 static Sys_var_charptr Sys_ssl_cipher(
3572        "ssl_cipher", "SSL cipher to use (implies --ssl)",
3573        READ_ONLY GLOBAL_VAR(opt_ssl_cipher), SSL_OPT(OPT_SSL_CIPHER),
3574        IN_FS_CHARSET, DEFAULT(0));
3575 
3576 static Sys_var_charptr Sys_ssl_key(
3577        "ssl_key", "X509 key in PEM format (implies --ssl)",
3578        READ_ONLY GLOBAL_VAR(opt_ssl_key), SSL_OPT(OPT_SSL_KEY),
3579        IN_FS_CHARSET, DEFAULT(0));
3580 
3581 static Sys_var_charptr Sys_ssl_crl(
3582        "ssl_crl",
3583        "CRL file in PEM format (check OpenSSL docs, implies --ssl)",
3584        READ_ONLY GLOBAL_VAR(opt_ssl_crl), SSL_OPT(OPT_SSL_CRL),
3585        IN_FS_CHARSET, DEFAULT(0));
3586 
3587 static Sys_var_charptr Sys_ssl_crlpath(
3588        "ssl_crlpath",
3589        "CRL directory (check OpenSSL docs, implies --ssl)",
3590        READ_ONLY GLOBAL_VAR(opt_ssl_crlpath), SSL_OPT(OPT_SSL_CRLPATH),
3591        IN_FS_CHARSET, DEFAULT(0));
3592 
3593 static const char *tls_version_names[]=
3594 {
3595   "TLSv1.0",
3596   "TLSv1.1",
3597   "TLSv1.2",
3598   "TLSv1.3",
3599   0
3600 };
3601 
3602 export bool tls_version_string_representation(THD *thd, sql_mode_t sql_mode,
3603                                               LEX_CSTRING *ls)
3604 {
3605   set_to_string(thd, ls, tls_version, tls_version_names);
3606   return ls->str == 0;
3607 }
3608 
3609 static Sys_var_set Sys_tls_version(
3610        "tls_version",
3611        "TLS protocol version for secure connections.",
3612        READ_ONLY GLOBAL_VAR(tls_version), CMD_LINE(REQUIRED_ARG),
3613        tls_version_names,
3614        DEFAULT(VIO_TLSv1_1 | VIO_TLSv1_2 | VIO_TLSv1_3));
3615 
3616 static Sys_var_mybool Sys_standard_compliant_cte(
3617        "standard_compliant_cte",
3618        "Allow only CTEs compliant to SQL standard",
3619        SESSION_VAR(only_standard_compliant_cte), CMD_LINE(OPT_ARG),
3620        DEFAULT(TRUE));
3621 
3622 
3623 // why ENUM and not BOOL ?
3624 static const char *updatable_views_with_limit_names[]= {"NO", "YES", 0};
3625 static Sys_var_enum Sys_updatable_views_with_limit(
3626        "updatable_views_with_limit",
3627        "YES = Don't issue an error message (warning only) if a VIEW without "
3628        "presence of a key of the underlying table is used in queries with a "
3629        "LIMIT clause for updating. NO = Prohibit update of a VIEW, which "
3630        "does not contain a key of the underlying table and the query uses "
3631        "a LIMIT clause (usually get from GUI tools)",
3632        SESSION_VAR(updatable_views_with_limit), CMD_LINE(REQUIRED_ARG),
3633        updatable_views_with_limit_names, DEFAULT(TRUE));
3634 
3635 static Sys_var_mybool Sys_sync_frm(
3636        "sync_frm", "Sync .frm files to disk on creation",
3637        GLOBAL_VAR(opt_sync_frm), CMD_LINE(OPT_ARG),
3638        DEFAULT(TRUE));
3639 
3640 static char *system_time_zone_ptr;
3641 static Sys_var_charptr Sys_system_time_zone(
3642        "system_time_zone", "The server system time zone",
3643        READ_ONLY GLOBAL_VAR(system_time_zone_ptr),
3644        CMD_LINE_HELP_ONLY,
3645        IN_SYSTEM_CHARSET, DEFAULT(system_time_zone));
3646 
3647 /*
3648   If One use views with prepared statements this should be bigger than
3649   table_open_cache (now we allow 2 times bigger value)
3650 */
3651 static Sys_var_ulong Sys_table_def_size(
3652        "table_definition_cache",
3653        "The number of cached table definitions",
3654        GLOBAL_VAR(tdc_size), CMD_LINE(REQUIRED_ARG),
3655        VALID_RANGE(TABLE_DEF_CACHE_MIN, 2*1024*1024),
3656        DEFAULT(TABLE_DEF_CACHE_DEFAULT), BLOCK_SIZE(1));
3657 
3658 
3659 static bool fix_table_open_cache(sys_var *, THD *, enum_var_type)
3660 {
3661   mysql_mutex_unlock(&LOCK_global_system_variables);
3662   tc_purge();
3663   mysql_mutex_lock(&LOCK_global_system_variables);
3664   return false;
3665 }
3666 
3667 /* Check the table_definition_cache comment if makes changes */
3668 static Sys_var_ulong Sys_table_cache_size(
3669        "table_open_cache", "The number of cached open tables",
3670        GLOBAL_VAR(tc_size), CMD_LINE(REQUIRED_ARG),
3671        VALID_RANGE(10, 1024*1024), DEFAULT(TABLE_OPEN_CACHE_DEFAULT),
3672        BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
3673        ON_UPDATE(fix_table_open_cache));
3674 
3675 static Sys_var_uint Sys_table_cache_instances(
3676        "table_open_cache_instances", "Maximum number of table cache instances",
3677        READ_ONLY GLOBAL_VAR(tc_instances), CMD_LINE(REQUIRED_ARG),
3678        VALID_RANGE(1, 64), DEFAULT(8), BLOCK_SIZE(1));
3679 
3680 static Sys_var_ulong Sys_thread_cache_size(
3681        "thread_cache_size",
3682        "How many threads we should keep in a cache for reuse. These are freed after 5 minutes of idle time",
3683        GLOBAL_VAR(thread_cache_size), CMD_LINE(REQUIRED_ARG),
3684        VALID_RANGE(0, 16384), DEFAULT(256), BLOCK_SIZE(1));
3685 
3686 #ifdef HAVE_POOL_OF_THREADS
3687 static bool fix_tp_max_threads(sys_var *, THD *, enum_var_type)
3688 {
3689   tp_set_max_threads(threadpool_max_threads);
3690   return false;
3691 }
3692 
3693 
3694 #ifdef _WIN32
3695 static bool fix_tp_min_threads(sys_var *, THD *, enum_var_type)
3696 {
3697   tp_set_min_threads(threadpool_min_threads);
3698   return false;
3699 }
3700 #endif
3701 
3702 static bool check_threadpool_size(sys_var *self, THD *thd, set_var *var)
3703 {
3704 
3705 #ifdef _WIN32
3706   if (threadpool_mode != TP_MODE_GENERIC)
3707     return false;
3708 #endif
3709 
3710   ulonglong v= var->save_result.ulonglong_value;
3711   if (v > threadpool_max_size)
3712   {
3713     var->save_result.ulonglong_value= threadpool_max_size;
3714     return throw_bounds_warning(thd, self->name.str, true, true, v);
3715   }
3716   return false;
3717 }
3718 
3719 
3720 static bool fix_threadpool_size(sys_var*, THD*, enum_var_type)
3721 {
3722   tp_set_threadpool_size(threadpool_size);
3723   return false;
3724 }
3725 
3726 
3727 static bool fix_threadpool_stall_limit(sys_var*, THD*, enum_var_type)
3728 {
3729   tp_set_threadpool_stall_limit(threadpool_stall_limit);
3730   return false;
3731 }
3732 
3733 #ifdef _WIN32
3734 static Sys_var_uint Sys_threadpool_min_threads(
3735   "thread_pool_min_threads",
3736   "Minimum number of threads in the thread pool.",
3737   GLOBAL_VAR(threadpool_min_threads), CMD_LINE(REQUIRED_ARG),
3738   VALID_RANGE(1, 256), DEFAULT(1), BLOCK_SIZE(1),
3739   NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
3740   ON_UPDATE(fix_tp_min_threads)
3741   );
3742 
3743 static const char *threadpool_mode_names[]={ "windows", "generic", 0 };
3744 static Sys_var_enum Sys_threadpool_mode(
3745   "thread_pool_mode",
3746   "Chose implementation of the threadpool",
3747   READ_ONLY GLOBAL_VAR(threadpool_mode), CMD_LINE(REQUIRED_ARG),
3748   threadpool_mode_names, DEFAULT(TP_MODE_WINDOWS)
3749   );
3750 #endif
3751 
3752 static const char *threadpool_priority_names[]={ "high", "low", "auto", 0 };
3753 static Sys_var_enum Sys_thread_pool_priority(
3754   "thread_pool_priority",
3755   "Threadpool priority. High priority connections usually start executing earlier than low priority."
3756   "If priority set to 'auto', the the actual priority(low or high) is determined based on whether or not connection is inside transaction.",
3757   SESSION_VAR(threadpool_priority), CMD_LINE(REQUIRED_ARG),
3758   threadpool_priority_names, DEFAULT(TP_PRIORITY_AUTO));
3759 
3760 static Sys_var_uint Sys_threadpool_idle_thread_timeout(
3761   "thread_pool_idle_timeout",
3762   "Timeout in seconds for an idle thread in the thread pool."
3763   "Worker thread will be shut down after timeout",
3764   GLOBAL_VAR(threadpool_idle_timeout), CMD_LINE(REQUIRED_ARG),
3765   VALID_RANGE(1, UINT_MAX), DEFAULT(60), BLOCK_SIZE(1)
3766 );
3767 static Sys_var_uint Sys_threadpool_oversubscribe(
3768   "thread_pool_oversubscribe",
3769   "How many additional active worker threads in a group are allowed.",
3770   GLOBAL_VAR(threadpool_oversubscribe), CMD_LINE(REQUIRED_ARG),
3771   VALID_RANGE(1, 1000), DEFAULT(3), BLOCK_SIZE(1)
3772 );
3773 static Sys_var_uint Sys_threadpool_size(
3774  "thread_pool_size",
3775  "Number of thread groups in the pool. "
3776  "This parameter is roughly equivalent to maximum number of concurrently "
3777  "executing threads (threads in a waiting state do not count as executing).",
3778   GLOBAL_VAR(threadpool_size), CMD_LINE(REQUIRED_ARG),
3779   VALID_RANGE(1, MAX_THREAD_GROUPS), DEFAULT(8), BLOCK_SIZE(1),
3780   NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_threadpool_size),
3781   ON_UPDATE(fix_threadpool_size)
3782 );
3783 static Sys_var_uint Sys_threadpool_stall_limit(
3784  "thread_pool_stall_limit",
3785  "Maximum query execution time in milliseconds,"
3786  "before an executing non-yielding thread is considered stalled."
3787  "If a worker thread is stalled, additional worker thread "
3788  "may be created to handle remaining clients.",
3789   GLOBAL_VAR(threadpool_stall_limit), CMD_LINE(REQUIRED_ARG),
3790   VALID_RANGE(10, UINT_MAX), DEFAULT(500), BLOCK_SIZE(1),
3791   NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
3792   ON_UPDATE(fix_threadpool_stall_limit)
3793 );
3794 
3795 static Sys_var_uint Sys_threadpool_max_threads(
3796   "thread_pool_max_threads",
3797   "Maximum allowed number of worker threads in the thread pool",
3798    GLOBAL_VAR(threadpool_max_threads), CMD_LINE(REQUIRED_ARG),
3799    VALID_RANGE(1, 65536), DEFAULT(65536), BLOCK_SIZE(1),
3800    NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
3801    ON_UPDATE(fix_tp_max_threads)
3802 );
3803 
3804 static Sys_var_uint Sys_threadpool_threadpool_prio_kickup_timer(
3805  "thread_pool_prio_kickup_timer",
3806  "The number of milliseconds before a dequeued low-priority statement is moved to the high-priority queue",
3807   GLOBAL_VAR(threadpool_prio_kickup_timer), CMD_LINE(REQUIRED_ARG),
3808   VALID_RANGE(0, UINT_MAX), DEFAULT(1000), BLOCK_SIZE(1)
3809 );
3810 #endif /* HAVE_POOL_OF_THREADS */
3811 
3812 /**
3813   Can't change the 'next' tx_isolation if we are already in a
3814   transaction.
3815 */
3816 
3817 static bool check_tx_isolation(sys_var *self, THD *thd, set_var *var)
3818 {
3819   if (var->type == OPT_DEFAULT && thd->in_active_multi_stmt_transaction())
3820   {
3821     DBUG_ASSERT(thd->in_multi_stmt_transaction_mode());
3822     my_error(ER_CANT_CHANGE_TX_CHARACTERISTICS, MYF(0));
3823     return TRUE;
3824   }
3825   return FALSE;
3826 }
3827 
3828 // NO_CMD_LINE - different name of the option
3829 static Sys_var_tx_isolation Sys_tx_isolation(
3830        "tx_isolation", "Default transaction isolation level",
3831        NO_SET_STMT SESSION_VAR(tx_isolation), NO_CMD_LINE,
3832        tx_isolation_names, DEFAULT(ISO_REPEATABLE_READ),
3833        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_tx_isolation));
3834 
3835 
3836 /**
3837   Can't change the tx_read_only state if we are already in a
3838   transaction.
3839 */
3840 
3841 static bool check_tx_read_only(sys_var *self, THD *thd, set_var *var)
3842 {
3843   if (var->type == OPT_DEFAULT && thd->in_active_multi_stmt_transaction())
3844   {
3845     DBUG_ASSERT(thd->in_multi_stmt_transaction_mode());
3846     my_error(ER_CANT_CHANGE_TX_CHARACTERISTICS, MYF(0));
3847     return true;
3848   }
3849   return false;
3850 }
3851 
3852 
3853 bool Sys_var_tx_read_only::session_update(THD *thd, set_var *var)
3854 {
3855   if (var->type == OPT_SESSION && Sys_var_mybool::session_update(thd, var))
3856     return true;
3857   if (var->type == OPT_DEFAULT || !thd->in_active_multi_stmt_transaction())
3858   {
3859     // @see Sys_var_tx_isolation::session_update() above for the rules.
3860     thd->tx_read_only= var->save_result.ulonglong_value;
3861 
3862 #ifndef EMBEDDED_LIBRARY
3863     if (thd->variables.session_track_transaction_info > TX_TRACK_NONE)
3864     {
3865       if (var->type == OPT_DEFAULT)
3866         thd->session_tracker.transaction_info.set_read_flags(thd,
3867                             thd->tx_read_only ? TX_READ_ONLY : TX_READ_WRITE);
3868       else
3869         thd->session_tracker.transaction_info.set_read_flags(thd,
3870                             TX_READ_INHERIT);
3871     }
3872 #endif //EMBEDDED_LIBRARY
3873   }
3874   return false;
3875 }
3876 
3877 
3878 static Sys_var_tx_read_only Sys_tx_read_only(
3879        "tx_read_only", "Default transaction access mode. If set to OFF, "
3880        "the default, access is read/write. If set to ON, access is read-only. "
3881        "The SET TRANSACTION statement can also change the value of this variable. "
3882        "See SET TRANSACTION and START TRANSACTION.",
3883        SESSION_VAR(tx_read_only), NO_CMD_LINE, DEFAULT(0),
3884        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_tx_read_only));
3885 
3886 static Sys_var_ulonglong Sys_tmp_table_size(
3887        "tmp_table_size",
3888        "Alias for tmp_memory_table_size. "
3889        "If an internal in-memory temporary table exceeds this size, MariaDB "
3890        "will automatically convert it to an on-disk MyISAM or Aria table.",
3891        SESSION_VAR(tmp_memory_table_size), CMD_LINE(REQUIRED_ARG),
3892        VALID_RANGE(1024, (ulonglong)~(intptr)0), DEFAULT(16*1024*1024),
3893        BLOCK_SIZE(1));
3894 
3895 static Sys_var_ulonglong Sys_tmp_memory_table_size(
3896        "tmp_memory_table_size",
3897        "If an internal in-memory temporary table exceeds this size, MariaDB "
3898        "will automatically convert it to an on-disk MyISAM or Aria table. "
3899        "Same as tmp_table_size.",
3900        SESSION_VAR(tmp_memory_table_size), CMD_LINE(REQUIRED_ARG),
3901        VALID_RANGE(1024, (ulonglong)~(intptr)0), DEFAULT(16*1024*1024),
3902        BLOCK_SIZE(1));
3903 
3904 static Sys_var_ulonglong Sys_tmp_disk_table_size(
3905        "tmp_disk_table_size",
3906        "Max size for data for an internal temporary on-disk MyISAM or Aria table.",
3907        SESSION_VAR(tmp_disk_table_size), CMD_LINE(REQUIRED_ARG),
3908        VALID_RANGE(1024, (ulonglong)~(intptr)0),
3909        DEFAULT((ulonglong)~(intptr)0),
3910        BLOCK_SIZE(1));
3911 
3912 static Sys_var_mybool Sys_timed_mutexes(
3913        "timed_mutexes",
3914        "Specify whether to time mutexes. Deprecated, has no effect.",
3915        GLOBAL_VAR(timed_mutexes), CMD_LINE(OPT_ARG), DEFAULT(0),
3916        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0),
3917        DEPRECATED(""));
3918 
3919 static Sys_var_charptr Sys_version(
3920        "version", "Server version number. It may also include a suffix "
3921        "with configuration or build information. -debug indicates "
3922        "debugging support was enabled on the server, and -log indicates "
3923        "at least one of the binary log, general log or slow query log are "
3924        "enabled, for example 10.1.1-MariaDB-mariadb1precise-log.",
3925        READ_ONLY GLOBAL_VAR(server_version_ptr),
3926        CMD_LINE_HELP_ONLY,
3927        IN_SYSTEM_CHARSET, DEFAULT(server_version));
3928 
3929 static char *server_version_comment_ptr;
3930 static Sys_var_charptr Sys_version_comment(
3931        "version_comment", "Value of the COMPILATION_COMMENT option "
3932        "specified by CMake when building MariaDB, for example "
3933        "mariadb.org binary distribution.",
3934        READ_ONLY GLOBAL_VAR(server_version_comment_ptr),
3935        CMD_LINE_HELP_ONLY,
3936        IN_SYSTEM_CHARSET, DEFAULT(MYSQL_COMPILATION_COMMENT));
3937 
3938 static char *server_version_compile_machine_ptr;
3939 static Sys_var_charptr Sys_version_compile_machine(
3940        "version_compile_machine", "The machine type or architecture "
3941        "MariaDB was built on, for example i686.",
3942        READ_ONLY GLOBAL_VAR(server_version_compile_machine_ptr),
3943        CMD_LINE_HELP_ONLY, IN_SYSTEM_CHARSET, DEFAULT(DEFAULT_MACHINE));
3944 
3945 static char *server_version_compile_os_ptr;
3946 static Sys_var_charptr Sys_version_compile_os(
3947        "version_compile_os", "Operating system that MariaDB was built "
3948        "on, for example debian-linux-gnu.",
3949        READ_ONLY GLOBAL_VAR(server_version_compile_os_ptr),
3950        CMD_LINE_HELP_ONLY,
3951        IN_SYSTEM_CHARSET, DEFAULT(SYSTEM_TYPE));
3952 
3953 #include <source_revision.h>
3954 static char *server_version_source_revision;
3955 static Sys_var_charptr Sys_version_source_revision(
3956        "version_source_revision", "Source control revision id for MariaDB source code",
3957        READ_ONLY GLOBAL_VAR(server_version_source_revision),
3958        CMD_LINE_HELP_ONLY,
3959        IN_SYSTEM_CHARSET, DEFAULT(SOURCE_REVISION));
3960 
3961 static char *malloc_library;
3962 static Sys_var_charptr Sys_malloc_library(
3963        "version_malloc_library", "Version of the used malloc library",
3964        READ_ONLY GLOBAL_VAR(malloc_library), CMD_LINE_HELP_ONLY,
3965        IN_SYSTEM_CHARSET, DEFAULT(guess_malloc_library()));
3966 
3967 static char *ssl_library;
3968 static Sys_var_charptr Sys_ssl_library(
3969        "version_ssl_library", "Version of the used SSL library",
3970        READ_ONLY GLOBAL_VAR(ssl_library), CMD_LINE_HELP_ONLY,
3971        IN_SYSTEM_CHARSET, DEFAULT(SSL_LIBRARY));
3972 
3973 static Sys_var_ulong Sys_net_wait_timeout(
3974        "wait_timeout",
3975        "The number of seconds the server waits for activity on a "
3976        "connection before closing it",
3977        NO_SET_STMT SESSION_VAR(net_wait_timeout), CMD_LINE(REQUIRED_ARG),
3978        VALID_RANGE(1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT)),
3979        DEFAULT(NET_WAIT_TIMEOUT), BLOCK_SIZE(1));
3980 
3981 static Sys_var_uint Sys_idle_transaction_timeout(
3982        "idle_transaction_timeout",
3983        "The number of seconds the server waits for idle transaction",
3984        SESSION_VAR(idle_transaction_timeout), CMD_LINE(REQUIRED_ARG),
3985        VALID_RANGE(0, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT)),
3986        DEFAULT(0), BLOCK_SIZE(1));
3987 
3988 static Sys_var_uint Sys_idle_readonly_transaction_timeout(
3989        "idle_readonly_transaction_timeout",
3990        "The number of seconds the server waits for read-only idle transaction",
3991        SESSION_VAR(idle_readonly_transaction_timeout), CMD_LINE(REQUIRED_ARG),
3992        VALID_RANGE(0, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT)),
3993        DEFAULT(0), BLOCK_SIZE(1));
3994 
3995 static Sys_var_uint Sys_idle_write_transaction_timeout(
3996        "idle_write_transaction_timeout",
3997        "The number of seconds the server waits for write idle transaction",
3998        SESSION_VAR(idle_write_transaction_timeout), CMD_LINE(REQUIRED_ARG),
3999        VALID_RANGE(0, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT)),
4000        DEFAULT(0), BLOCK_SIZE(1));
4001 
4002 static Sys_var_plugin Sys_default_storage_engine(
4003        "default_storage_engine", "The default storage engine for new tables",
4004        SESSION_VAR(table_plugin), NO_CMD_LINE,
4005        MYSQL_STORAGE_ENGINE_PLUGIN, DEFAULT(&default_storage_engine),
4006        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_not_null));
4007 
4008 //  Alias for @@default_storage_engine
4009 static Sys_var_plugin Sys_storage_engine(
4010        "storage_engine", "Alias for @@default_storage_engine. Deprecated",
4011        SESSION_VAR(table_plugin), NO_CMD_LINE,
4012        MYSQL_STORAGE_ENGINE_PLUGIN, DEFAULT(&default_storage_engine),
4013        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_not_null));
4014 
4015 static Sys_var_plugin Sys_default_tmp_storage_engine(
4016        "default_tmp_storage_engine", "The default storage engine for user-created temporary tables",
4017        SESSION_VAR(tmp_table_plugin), NO_CMD_LINE,
4018        MYSQL_STORAGE_ENGINE_PLUGIN, DEFAULT(&default_tmp_storage_engine));
4019 
4020 static Sys_var_plugin Sys_enforce_storage_engine(
4021        "enforce_storage_engine", "Force the use of a storage engine for new tables",
4022        SESSION_VAR(enforced_table_plugin),
4023        NO_CMD_LINE, MYSQL_STORAGE_ENGINE_PLUGIN,
4024        DEFAULT(&enforced_storage_engine), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_has_super));
4025 
4026 
4027 #ifdef HAVE_REPLICATION
4028 /*
4029   Check
4030    1. Value for gtid_pos_auto_engines is not NULL.
4031    2. No slave SQL thread is running.
4032 */
4033 static bool
4034 check_gtid_pos_auto_engines(sys_var *self, THD *thd, set_var *var)
4035 {
4036   bool running;
4037   bool err= false;
4038 
4039   DBUG_ASSERT(var->type == OPT_GLOBAL);
4040   if (var->value && var->value->is_null())
4041     err= true;
4042   else
4043   {
4044     running= give_error_if_slave_running(false);
4045     if (running)
4046       err= true;
4047   }
4048   return err;
4049 }
4050 
4051 
4052 static Sys_var_pluginlist Sys_gtid_pos_auto_engines(
4053        "gtid_pos_auto_engines",
4054        "List of engines for which to automatically create a "
4055        "mysql.gtid_slave_pos_ENGINE table, if a transaction using that engine "
4056        "is replicated. This can be used to avoid introducing cross-engine "
4057        "transactions, if engines are used different from that used by table "
4058        "mysql.gtid_slave_pos",
4059        GLOBAL_VAR(opt_gtid_pos_auto_plugins), NO_CMD_LINE,
4060        DEFAULT(&gtid_pos_auto_engines),
4061        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_gtid_pos_auto_engines));
4062 #endif
4063 
4064 
4065 #if defined(ENABLED_DEBUG_SYNC)
4066 /*
4067   Variable can be set for the session only.
4068 
4069   This could be changed later. Then we need to have a global array of
4070   actions in addition to the thread local ones. SET GLOBAL would
4071   manage the global array, SET [SESSION] the local array. A sync point
4072   would need to look for a local and a global action. Setting and
4073   executing of global actions need to be protected by a mutex.
4074 
4075   The purpose of global actions could be to allow synchronizing with
4076   connectionless threads that cannot execute SET statements.
4077 */
4078 static Sys_var_debug_sync Sys_debug_sync(
4079        "debug_sync", "Debug Sync Facility",
4080        NO_SET_STMT sys_var::ONLY_SESSION, NO_CMD_LINE,
4081        DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_has_super));
4082 #endif /* defined(ENABLED_DEBUG_SYNC) */
4083 
4084 /**
4085  "time_format" "date_format" "datetime_format"
4086 
4087   the following three variables are unused, and the source of confusion
4088   (bug reports like "I've changed date_format, but date format hasn't changed.
4089   I've made them read-only, to alleviate the situation somewhat.
4090 
4091   @todo make them NO_CMD_LINE ?
4092 */
4093 static Sys_var_charptr Sys_date_format(
4094        "date_format", "The DATE format (ignored)",
4095        READ_ONLY GLOBAL_VAR(global_date_format.format.str),
4096        CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET,
4097        DEFAULT(known_date_time_formats[ISO_FORMAT].date_format),
4098        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0), DEPRECATED(""));
4099 
4100 static Sys_var_charptr Sys_datetime_format(
4101        "datetime_format", "The DATETIME format (ignored)",
4102        READ_ONLY GLOBAL_VAR(global_datetime_format.format.str),
4103        CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET,
4104        DEFAULT(known_date_time_formats[ISO_FORMAT].datetime_format),
4105        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0), DEPRECATED(""));
4106 
4107 static Sys_var_charptr Sys_time_format(
4108        "time_format", "The TIME format (ignored)",
4109        READ_ONLY GLOBAL_VAR(global_time_format.format.str),
4110        CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET,
4111        DEFAULT(known_date_time_formats[ISO_FORMAT].time_format),
4112        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0), DEPRECATED(""));
4113 
4114 static bool fix_autocommit(sys_var *self, THD *thd, enum_var_type type)
4115 {
4116   if (type == OPT_GLOBAL)
4117   {
4118     if (global_system_variables.option_bits & OPTION_AUTOCOMMIT)
4119       global_system_variables.option_bits&= ~OPTION_NOT_AUTOCOMMIT;
4120     else
4121       global_system_variables.option_bits|= OPTION_NOT_AUTOCOMMIT;
4122     return false;
4123   }
4124 
4125   if (test_all_bits(thd->variables.option_bits,
4126                     (OPTION_AUTOCOMMIT | OPTION_NOT_AUTOCOMMIT)))
4127   {
4128     // activating autocommit
4129     if (trans_commit_stmt(thd) || trans_commit(thd))
4130     {
4131       thd->variables.option_bits&= ~OPTION_AUTOCOMMIT;
4132       thd->release_transactional_locks();
4133       WSREP_DEBUG("autocommit, MDL TRX lock released: %lld",
4134                   (longlong) thd->thread_id);
4135       return true;
4136     }
4137     /*
4138       Don't close thread tables or release metadata locks: if we do so, we
4139       risk releasing locks/closing tables of expressions used to assign
4140       other variables, as in:
4141       set @var=my_stored_function1(), @@autocommit=1, @var2=(select MY_MAX(a)
4142       from my_table), ...
4143       The locks will be released at statement end anyway, as SET
4144       statement that assigns autocommit is marked to commit
4145       transaction implicitly at the end (@sa stmt_causes_implicitcommit()).
4146     */
4147     thd->variables.option_bits&=
4148                  ~(OPTION_BEGIN | OPTION_KEEP_LOG | OPTION_NOT_AUTOCOMMIT |
4149                    OPTION_GTID_BEGIN);
4150     thd->transaction.all.modified_non_trans_table= false;
4151     thd->transaction.all.m_unsafe_rollback_flags&= ~THD_TRANS::DID_WAIT;
4152     thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
4153     return false;
4154   }
4155 
4156   if ((thd->variables.option_bits &
4157        (OPTION_AUTOCOMMIT |OPTION_NOT_AUTOCOMMIT)) == 0)
4158   {
4159     // disabling autocommit
4160     thd->transaction.all.modified_non_trans_table= false;
4161     thd->transaction.all.m_unsafe_rollback_flags&= ~THD_TRANS::DID_WAIT;
4162     thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
4163     thd->variables.option_bits|= OPTION_NOT_AUTOCOMMIT;
4164     return false;
4165   }
4166 
4167   return false; // autocommit value wasn't changed
4168 }
4169 
4170 static Sys_var_bit Sys_autocommit(
4171        "autocommit", "If set to 1, the default, all queries are committed "
4172        "immediately. If set to 0, they are only committed upon a COMMIT statement"
4173        ", or rolled back with a ROLLBACK statement. If autocommit is set to 0, "
4174        "and then changed to 1, all open transactions are immediately committed.",
4175        NO_SET_STMT SESSION_VAR(option_bits), NO_CMD_LINE,
4176        OPTION_AUTOCOMMIT, DEFAULT(TRUE),
4177        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(fix_autocommit));
4178 export sys_var *Sys_autocommit_ptr= &Sys_autocommit; // for sql_yacc.yy
4179 
4180 static Sys_var_mybool Sys_big_tables(
4181        "big_tables", "Old variable, which if set to 1, allows large result sets "
4182        "by saving all temporary sets to disk, avoiding 'table full' errors. No "
4183        "longer needed, as the server now handles this automatically. "
4184        "sql_big_tables is a synonym.",
4185        SESSION_VAR(big_tables), CMD_LINE(OPT_ARG), DEFAULT(FALSE));
4186 
4187 static Sys_var_bit Sys_big_selects(
4188        "sql_big_selects", "If set to 0, MariaDB will not perform large SELECTs."
4189        " See max_join_size for details. If max_join_size is set to anything but "
4190        "DEFAULT, sql_big_selects is automatically set to 0. If sql_big_selects "
4191        "is again set, max_join_size will be ignored.",
4192        SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_BIG_SELECTS,
4193        DEFAULT(FALSE));
4194 
4195 static Sys_var_bit Sys_log_off(
4196        "sql_log_off", "If set to 1 (0 is the default), no logging to the general "
4197        "query log is done for the client. Only clients with the SUPER privilege "
4198        "can update this variable.",
4199        NO_SET_STMT SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_LOG_OFF,
4200        DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_has_super));
4201 
4202 /**
4203   This function sets the session variable thd->variables.sql_log_bin
4204   to reflect changes to @@session.sql_log_bin.
4205 
4206   @param[IN] self   A pointer to the sys_var, i.e. Sys_log_binlog.
4207   @param[IN] type   The type either session or global.
4208 
4209   @return @c FALSE.
4210 */
4211 static bool fix_sql_log_bin_after_update(sys_var *self, THD *thd,
4212                                          enum_var_type type)
4213 {
4214   DBUG_ASSERT(type == OPT_SESSION);
4215 
4216   if (thd->variables.sql_log_bin)
4217     thd->variables.option_bits |= OPTION_BIN_LOG;
4218   else
4219     thd->variables.option_bits &= ~OPTION_BIN_LOG;
4220 
4221   return FALSE;
4222 }
4223 
4224 static bool check_session_only_variable(sys_var *self, THD *,set_var *var)
4225 {
4226   if (unlikely(var->type == OPT_GLOBAL))
4227   {
4228     my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), self->name.str, "SESSION");
4229     return true;
4230   }
4231   return false;
4232 }
4233 
4234 /**
4235   This function checks if the sql_log_bin can be changed,
4236   what is possible if:
4237     - the user is a super user;
4238     - the set is not called from within a function/trigger;
4239     - there is no on-going transaction.
4240 
4241   @param[IN] self   A pointer to the sys_var, i.e. Sys_log_binlog.
4242   @param[IN] var    A pointer to the set_var created by the parser.
4243 
4244   @return @c FALSE if the change is allowed, otherwise @c TRUE.
4245 */
4246 static bool check_sql_log_bin(sys_var *self, THD *thd, set_var *var)
4247 {
4248   if (check_has_super(self, thd, var))
4249     return true;
4250 
4251   if (check_session_only_variable(self, thd, var))
4252     return true;
4253 
4254   if (unlikely(error_if_in_trans_or_substatement(thd,
4255                                                  ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN,
4256                                                  ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SQL_LOG_BIN)))
4257     return true;
4258 
4259   return false;
4260 }
4261 
4262 static Sys_var_mybool Sys_log_binlog(
4263        "sql_log_bin", "If set to 0 (1 is the default), no logging to the binary "
4264        "log is done for the client. Only clients with the SUPER privilege can "
4265        "update this variable. Can have unintended consequences if set globally, "
4266        "see SET SQL_LOG_BIN. Starting MariaDB 10.1.7, this variable does not "
4267        "affect the replication of events in a Galera cluster.",
4268        SESSION_VAR(sql_log_bin), NO_CMD_LINE, DEFAULT(TRUE),
4269        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_sql_log_bin),
4270        ON_UPDATE(fix_sql_log_bin_after_update));
4271 
4272 static Sys_var_bit Sys_sql_warnings(
4273        "sql_warnings", "If set to 1, single-row INSERTs will produce a string "
4274        "containing warning information if a warning occurs.",
4275        SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_WARNINGS,
4276        DEFAULT(FALSE));
4277 
4278 static Sys_var_bit Sys_sql_notes(
4279        "sql_notes", "If set to 1, the default, warning_count is incremented each "
4280        "time a Note warning is encountered. If set to 0, Note warnings are not "
4281        "recorded. mysqldump has outputs to set this variable to 0 so that no "
4282        "unnecessary increments occur when data is reloaded.",
4283        SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_SQL_NOTES,
4284        DEFAULT(TRUE));
4285 
4286 static Sys_var_bit Sys_auto_is_null(
4287        "sql_auto_is_null", "If set to 1, the query SELECT * FROM table_name WHERE "
4288        "auto_increment_column IS NULL will return an auto-increment that has just "
4289        "been successfully inserted, the same as the LAST_INSERT_ID() function. Some"
4290        " ODBC programs make use of this IS NULL comparison.",
4291        SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_AUTO_IS_NULL,
4292        DEFAULT(FALSE), NO_MUTEX_GUARD, IN_BINLOG);
4293 
4294 static Sys_var_bit Sys_safe_updates(
4295        "sql_safe_updates", "If set to 1, UPDATEs and DELETEs need either a key in "
4296        "the WHERE clause, or a LIMIT clause, or else they will aborted. Prevents "
4297        "the common mistake of accidentally deleting or updating every row in a table.",
4298        SESSION_VAR(option_bits), CMD_LINE(OPT_ARG), OPTION_SAFE_UPDATES,
4299        DEFAULT(FALSE));
4300 
4301 static Sys_var_bit Sys_buffer_results(
4302        "sql_buffer_result", "If set to 1 (0 is default), results from SELECT "
4303        "statements are always placed into temporary tables. This can help the "
4304        "server when it takes a long time to send the results to the client by "
4305        "allowing the table locks to be freed early.",
4306        SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_BUFFER_RESULT,
4307        DEFAULT(FALSE));
4308 
4309 static Sys_var_bit Sys_quote_show_create(
4310        "sql_quote_show_create", "If set to 1, the default, the server will "
4311        "quote identifiers for SHOW CREATE DATABASE, SHOW CREATE TABLE and "
4312        "SHOW CREATE VIEW statements. Quoting is disabled if set to 0. Enable "
4313        "to ensure replications works when identifiers require quoting.",
4314        SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_QUOTE_SHOW_CREATE,
4315        DEFAULT(TRUE));
4316 
4317 static Sys_var_bit Sys_foreign_key_checks(
4318        "foreign_key_checks", "If set to 1 (the default) foreign key constraints"
4319        " (including ON UPDATE and ON DELETE behavior) InnoDB tables are checked,"
4320        " while if set to 0, they are not checked. 0 is not recommended for normal "
4321        "use, though it can be useful in situations where you know the data is "
4322        "consistent, but want to reload data in a different order from that that "
4323        "specified by parent/child relationships. Setting this variable to 1 does "
4324        "not retrospectively check for inconsistencies introduced while set to 0.",
4325        SESSION_VAR(option_bits), NO_CMD_LINE,
4326        REVERSE(OPTION_NO_FOREIGN_KEY_CHECKS),
4327        DEFAULT(TRUE), NO_MUTEX_GUARD, IN_BINLOG);
4328 
4329 static Sys_var_bit Sys_unique_checks(
4330        "unique_checks", "If set to 1, the default, secondary indexes in InnoDB "
4331        "tables are performed. If set to 0, storage engines can (but are not "
4332        "required to) assume that duplicate keys are not present in input data. "
4333        "Set to 0 to speed up imports of large tables to InnoDB. The storage "
4334        "engine will still issue a duplicate key error if it detects one, even "
4335        "if set to 0.",
4336        SESSION_VAR(option_bits), NO_CMD_LINE,
4337        REVERSE(OPTION_RELAXED_UNIQUE_CHECKS),
4338        DEFAULT(TRUE), NO_MUTEX_GUARD, IN_BINLOG);
4339 
4340 static Sys_var_bit Sys_no_check_constraint(
4341        "check_constraint_checks", "check_constraint_checks",
4342        SESSION_VAR(option_bits), NO_CMD_LINE,
4343        REVERSE(OPTION_NO_CHECK_CONSTRAINT_CHECKS),
4344        DEFAULT(TRUE), NO_MUTEX_GUARD, IN_BINLOG);
4345 
4346 #ifdef ENABLED_PROFILING
4347 static bool update_profiling(sys_var *self, THD *thd, enum_var_type type)
4348 {
4349   if (type == OPT_SESSION)
4350     thd->profiling.reset();
4351   return false;
4352 }
4353 
4354 static Sys_var_bit Sys_profiling(
4355        "profiling", "If set to 1 (0 is default), statement profiling will be "
4356        "enabled. See SHOW PROFILES and SHOW PROFILE.",
4357        NO_SET_STMT SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_PROFILING,
4358        DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
4359        ON_UPDATE(update_profiling));
4360 
4361 static Sys_var_ulong Sys_profiling_history_size(
4362        "profiling_history_size", "Number of statements about which profiling "
4363        "information is maintained. If set to 0, no profiles are stored. "
4364        "See SHOW PROFILES.",
4365        NO_SET_STMT SESSION_VAR(profiling_history_size), CMD_LINE(REQUIRED_ARG),
4366        VALID_RANGE(0, 100), DEFAULT(15), BLOCK_SIZE(1));
4367 #endif
4368 
4369 /*
4370   When this is set by a connection, binlogged events will be marked with a
4371   corresponding flag. The slave can be configured to not replicate events
4372   so marked.
4373   In the binlog dump thread on the master, this variable is re-used for a
4374   related purpose: The slave sets this flag when connecting to the master to
4375   request that the master filter out (ie. not send) any events with the flag
4376   set, thus saving network traffic on events that would be ignored by the
4377   slave anyway.
4378 */
4379 static bool check_skip_replication(sys_var *self, THD *thd, set_var *var)
4380 {
4381   /*
4382     We must not change @@skip_replication in the middle of a transaction or
4383     statement, as that could result in only part of the transaction / statement
4384     being replicated.
4385     (This would be particularly serious if we were to replicate eg.
4386     Rows_log_event without Table_map_log_event or transactional updates without
4387     the COMMIT).
4388   */
4389   if (unlikely(error_if_in_trans_or_substatement(thd,
4390                                                  ER_STORED_FUNCTION_PREVENTS_SWITCH_SKIP_REPLICATION,
4391                                                  ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SKIP_REPLICATION)))
4392     return 1;
4393 
4394   return 0;
4395 }
4396 
4397 static Sys_var_bit Sys_skip_replication(
4398        "skip_replication", "Changes are logged into the binary log with the "
4399        "@@skip_replication flag set. Such events will not be replicated by "
4400        "slaves that run with --replicate-events-marked-for-skip set different "
4401        "from its default of REPLICATE. See Selectively skipping replication "
4402        "of binlog events for more information.",
4403        NO_SET_STMT SESSION_ONLY(option_bits),
4404        NO_CMD_LINE, OPTION_SKIP_REPLICATION,
4405        DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG,
4406        ON_CHECK(check_skip_replication));
4407 
4408 static Sys_var_harows Sys_select_limit(
4409        "sql_select_limit",
4410        "The maximum number of rows to return from SELECT statements",
4411        SESSION_VAR(select_limit), NO_CMD_LINE,
4412        VALID_RANGE(0, HA_POS_ERROR), DEFAULT(HA_POS_ERROR), BLOCK_SIZE(1));
4413 
4414 static const char *secure_timestamp_levels[]= {"NO", "SUPER", "REPLICATION", "YES", 0};
4415 static bool check_timestamp(sys_var *self, THD *thd, set_var *var)
4416 {
4417   if (opt_secure_timestamp == SECTIME_NO)
4418     return false;
4419   if (opt_secure_timestamp == SECTIME_SUPER)
4420     return check_has_super(self, thd, var);
4421   char buf[1024];
4422   strxnmov(buf, sizeof(buf), "--secure-timestamp=",
4423            secure_timestamp_levels[opt_secure_timestamp], NULL);
4424   my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), buf);
4425   return true;
4426 }
4427 static Sys_var_timestamp Sys_timestamp(
4428        "timestamp", "Set the time for this client",
4429        sys_var::ONLY_SESSION, NO_CMD_LINE,
4430        VALID_RANGE(0, TIMESTAMP_MAX_VALUE),
4431        NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_timestamp));
4432 
4433 static bool update_last_insert_id(THD *thd, set_var *var)
4434 {
4435   if (!var->value)
4436   {
4437     my_error(ER_NO_DEFAULT, MYF(0), var->var->name.str);
4438     return true;
4439   }
4440   thd->first_successful_insert_id_in_prev_stmt=
4441     var->save_result.ulonglong_value;
4442   return false;
4443 }
4444 static ulonglong read_last_insert_id(THD *thd)
4445 {
4446   return (ulonglong) thd->read_first_successful_insert_id_in_prev_stmt();
4447 }
4448 static Sys_var_session_special Sys_last_insert_id(
4449        "last_insert_id", "The value to be returned from LAST_INSERT_ID()",
4450        sys_var::ONLY_SESSION, NO_CMD_LINE,
4451        VALID_RANGE(0, ULONGLONG_MAX), BLOCK_SIZE(1),
4452        NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(0),
4453        ON_UPDATE(update_last_insert_id), ON_READ(read_last_insert_id));
4454 
4455 // alias for last_insert_id(), Sybase-style
4456 static Sys_var_session_special Sys_identity(
4457        "identity", "Synonym for the last_insert_id variable",
4458        sys_var::ONLY_SESSION, NO_CMD_LINE,
4459        VALID_RANGE(0, ULONGLONG_MAX), BLOCK_SIZE(1),
4460        NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(0),
4461        ON_UPDATE(update_last_insert_id), ON_READ(read_last_insert_id));
4462 
4463 /*
4464   insert_id should *not* be marked as written to the binlog (i.e., it
4465   should *not* be IN_BINLOG), because we want any statement that
4466   refers to insert_id explicitly to be unsafe.  (By "explicitly", we
4467   mean using @@session.insert_id, whereas insert_id is used
4468   "implicitly" when NULL value is inserted into an auto_increment
4469   column).
4470 
4471   We want statements referring explicitly to @@session.insert_id to be
4472   unsafe, because insert_id is modified internally by the slave sql
4473   thread when NULL values are inserted in an AUTO_INCREMENT column.
4474   This modification interfers with the value of the
4475   @@session.insert_id variable if @@session.insert_id is referred
4476   explicitly by an insert statement (as is seen by executing "SET
4477   @@session.insert_id=0; CREATE TABLE t (a INT, b INT KEY
4478   AUTO_INCREMENT); INSERT INTO t(a) VALUES (@@session.insert_id);" in
4479   statement-based logging mode: t will be different on master and
4480   slave).
4481 */
4482 static bool update_insert_id(THD *thd, set_var *var)
4483 {
4484   /*
4485     If we set the insert_id to the DEFAULT or 0
4486     it means we 'reset' it so it's value doesn't
4487     affect the INSERT.
4488   */
4489   if (!var->value ||
4490       var->save_result.ulonglong_value == 0)
4491     thd->auto_inc_intervals_forced.empty();
4492   else
4493     thd->force_one_auto_inc_interval(var->save_result.ulonglong_value);
4494   return false;
4495 }
4496 
4497 static ulonglong read_insert_id(THD *thd)
4498 {
4499   return thd->auto_inc_intervals_forced.minimum();
4500 }
4501 
4502 
4503 static Sys_var_session_special Sys_insert_id(
4504        "insert_id", "The value to be used by the following INSERT "
4505        "or ALTER TABLE statement when inserting an AUTO_INCREMENT value",
4506        sys_var::ONLY_SESSION, NO_CMD_LINE,
4507        VALID_RANGE(0, ULONGLONG_MAX), BLOCK_SIZE(1),
4508        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
4509        ON_UPDATE(update_insert_id), ON_READ(read_insert_id));
4510 
4511 static bool update_rand_seed1(THD *thd, set_var *var)
4512 {
4513   if (!var->value)
4514   {
4515     my_error(ER_NO_DEFAULT, MYF(0), var->var->name.str);
4516     return true;
4517   }
4518   thd->rand.seed1= (ulong) var->save_result.ulonglong_value;
4519   return false;
4520 }
4521 static ulonglong read_rand_seed1(THD *thd)
4522 {
4523   return thd->rand.seed1;
4524 }
4525 static Sys_var_session_special Sys_rand_seed1(
4526        "rand_seed1", "Sets the internal state of the RAND() "
4527        "generator for replication purposes",
4528        sys_var::ONLY_SESSION, NO_CMD_LINE,
4529        VALID_RANGE(0, ULONG_MAX), BLOCK_SIZE(1),
4530        NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(0),
4531        ON_UPDATE(update_rand_seed1), ON_READ(read_rand_seed1));
4532 
4533 static bool update_rand_seed2(THD *thd, set_var *var)
4534 {
4535   if (!var->value)
4536   {
4537     my_error(ER_NO_DEFAULT, MYF(0), var->var->name.str);
4538     return true;
4539   }
4540   thd->rand.seed2= (ulong) var->save_result.ulonglong_value;
4541   return false;
4542 }
4543 static ulonglong read_rand_seed2(THD *thd)
4544 {
4545   return thd->rand.seed2;
4546 }
4547 static Sys_var_session_special Sys_rand_seed2(
4548        "rand_seed2", "Sets the internal state of the RAND() "
4549        "generator for replication purposes",
4550        sys_var::ONLY_SESSION, NO_CMD_LINE,
4551        VALID_RANGE(0, ULONG_MAX), BLOCK_SIZE(1),
4552        NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(0),
4553        ON_UPDATE(update_rand_seed2), ON_READ(read_rand_seed2));
4554 
4555 static ulonglong read_error_count(THD *thd)
4556 {
4557   return thd->get_stmt_da()->error_count();
4558 }
4559 // this really belongs to the SHOW STATUS
4560 static Sys_var_session_special Sys_error_count(
4561        "error_count", "The number of errors that resulted from the "
4562        "last statement that generated messages",
4563        READ_ONLY sys_var::ONLY_SESSION, NO_CMD_LINE,
4564        VALID_RANGE(0, ULONGLONG_MAX), BLOCK_SIZE(1), NO_MUTEX_GUARD,
4565        NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0), ON_READ(read_error_count));
4566 
4567 static ulonglong read_warning_count(THD *thd)
4568 {
4569   return thd->get_stmt_da()->warn_count();
4570 }
4571 // this really belongs to the SHOW STATUS
4572 static Sys_var_session_special Sys_warning_count(
4573        "warning_count", "The number of errors, warnings, and notes "
4574        "that resulted from the last statement that generated messages",
4575        READ_ONLY sys_var::ONLY_SESSION, NO_CMD_LINE,
4576        VALID_RANGE(0, ULONGLONG_MAX), BLOCK_SIZE(1), NO_MUTEX_GUARD,
4577        NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0), ON_READ(read_warning_count));
4578 
4579 static Sys_var_ulong Sys_default_week_format(
4580        "default_week_format",
4581        "The default week format used by WEEK() functions",
4582        SESSION_VAR(default_week_format), CMD_LINE(REQUIRED_ARG),
4583        VALID_RANGE(0, 7), DEFAULT(0), BLOCK_SIZE(1));
4584 
4585 static Sys_var_uint Sys_group_concat_max_len(
4586        "group_concat_max_len",
4587        "The maximum length of the result of function GROUP_CONCAT()",
4588        SESSION_VAR(group_concat_max_len), CMD_LINE(REQUIRED_ARG),
4589        VALID_RANGE(4, UINT_MAX32), DEFAULT(1024*1024), BLOCK_SIZE(1));
4590 
4591 static char *glob_hostname_ptr;
4592 static Sys_var_charptr Sys_hostname(
4593        "hostname", "Server host name",
4594        READ_ONLY GLOBAL_VAR(glob_hostname_ptr), NO_CMD_LINE,
4595        IN_SYSTEM_CHARSET, DEFAULT(glob_hostname));
4596 
4597 #ifndef EMBEDDED_LIBRARY
4598 static Sys_var_charptr Sys_repl_report_host(
4599        "report_host",
4600        "Hostname or IP of the slave to be reported to the master during "
4601        "slave registration. Will appear in the output of SHOW SLAVE HOSTS. "
4602        "Leave unset if you do not want the slave to register itself with the "
4603        "master. Note that it is not sufficient for the master to simply read "
4604        "the IP of the slave off the socket once the slave connects. Due to "
4605        "NAT and other routing issues, that IP may not be valid for connecting "
4606        "to the slave from the master or other hosts",
4607        READ_ONLY GLOBAL_VAR(report_host), CMD_LINE(REQUIRED_ARG),
4608        IN_SYSTEM_CHARSET, DEFAULT(0));
4609 
4610 static Sys_var_charptr Sys_repl_report_user(
4611        "report_user",
4612        "The account user name of the slave to be reported to the master "
4613        "during slave registration",
4614        READ_ONLY GLOBAL_VAR(report_user), CMD_LINE(REQUIRED_ARG),
4615        IN_SYSTEM_CHARSET, DEFAULT(0));
4616 
4617 static Sys_var_charptr Sys_repl_report_password(
4618        "report_password",
4619        "The account password of the slave to be reported to the master "
4620        "during slave registration",
4621        READ_ONLY GLOBAL_VAR(report_password), CMD_LINE(REQUIRED_ARG),
4622        IN_SYSTEM_CHARSET, DEFAULT(0));
4623 
4624 static Sys_var_uint Sys_repl_report_port(
4625        "report_port",
4626        "Port for connecting to slave reported to the master during slave "
4627        "registration. Set it only if the slave is listening on a non-default "
4628        "port or if you have a special tunnel from the master or other clients "
4629        "to the slave. If not sure, leave this option unset",
4630        READ_ONLY GLOBAL_VAR(report_port), CMD_LINE(REQUIRED_ARG),
4631        VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1));
4632 #endif
4633 
4634 static Sys_var_mybool Sys_keep_files_on_create(
4635        "keep_files_on_create",
4636        "Don't overwrite stale .MYD and .MYI even if no directory is specified",
4637        SESSION_VAR(keep_files_on_create), CMD_LINE(OPT_ARG),
4638        DEFAULT(FALSE));
4639 
4640 static char *license;
4641 static Sys_var_charptr Sys_license(
4642        "license", "The type of license the server has",
4643        READ_ONLY GLOBAL_VAR(license), NO_CMD_LINE, IN_SYSTEM_CHARSET,
4644        DEFAULT(STRINGIFY_ARG(LICENSE)));
4645 
4646 #include <proxy_protocol.h>
4647 char *my_proxy_protocol_networks;
4648 static bool check_proxy_protocol_networks(sys_var *, THD *, set_var *var)
4649 {
4650   if (!var->value)
4651     return false;
4652   return !proxy_protocol_networks_valid(var->save_result.string_value.str);
4653 }
4654 
4655 
4656 static bool fix_proxy_protocol_networks(sys_var *, THD *, enum_var_type)
4657 {
4658   return (bool)set_proxy_protocol_networks(my_proxy_protocol_networks);
4659 }
4660 
4661 
4662 static Sys_var_charptr Sys_proxy_protocol_networks(
4663     "proxy_protocol_networks", "Enable proxy protocol for these source "
4664     "networks. The syntax is a comma separated list of IPv4 and IPv6 "
4665     "networks. If the network doesn't contain mask, it is considered to be "
4666     "a single host. \"*\" represents all networks and must the only "
4667     "directive on the line. String \"localhost\" represents non-TCP "
4668     "local connections (Unix domain socket, Windows named pipe or shared memory).",
4669     GLOBAL_VAR(my_proxy_protocol_networks), CMD_LINE(REQUIRED_ARG),
4670     IN_FS_CHARSET, DEFAULT(""), NO_MUTEX_GUARD, NOT_IN_BINLOG,
4671     ON_CHECK(check_proxy_protocol_networks), ON_UPDATE(fix_proxy_protocol_networks));
4672 
4673 
4674 static bool check_log_path(sys_var *self, THD *thd, set_var *var)
4675 {
4676   if (!var->value)
4677     return false; // DEFAULT is ok
4678 
4679   if (!var->save_result.string_value.str)
4680     return true;
4681 
4682   LEX_STRING *val= &var->save_result.string_value;
4683 
4684   if (val->length > FN_REFLEN)
4685   { // path is too long
4686     my_error(ER_PATH_LENGTH, MYF(0), self->name.str);
4687     return true;
4688   }
4689 
4690   char path[FN_REFLEN];
4691   size_t path_length= unpack_filename(path, val->str);
4692 
4693   if (!path_length)
4694     return true;
4695 
4696   if (!is_filename_allowed(var->save_result.string_value.str,
4697                            var->save_result.string_value.length, TRUE))
4698   {
4699      my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0),
4700               self->name.str, var->save_result.string_value.str);
4701      return true;
4702   }
4703 
4704   static const LEX_CSTRING my_cnf= { STRING_WITH_LEN("my.cnf") };
4705   static const LEX_CSTRING my_ini= { STRING_WITH_LEN("my.ini") };
4706   if (path_length >= my_cnf.length)
4707   {
4708     if (strcasecmp(path + path_length - my_cnf.length, my_cnf.str) == 0)
4709       return true; // log file name ends with "my.cnf"
4710     DBUG_ASSERT(my_cnf.length == my_ini.length);
4711     if (strcasecmp(path + path_length - my_ini.length, my_ini.str) == 0)
4712       return true; // log file name ends with "my.ini"
4713   }
4714 
4715   MY_STAT f_stat;
4716 
4717   if (my_stat(path, &f_stat, MYF(0)))
4718   {
4719     if (!MY_S_ISREG(f_stat.st_mode) || !(f_stat.st_mode & MY_S_IWRITE))
4720       return true; // not a regular writable file
4721     return false;
4722   }
4723 
4724   (void) dirname_part(path, val->str, &path_length);
4725 
4726   if (val->length - path_length >= FN_LEN)
4727   { // filename is too long
4728       my_error(ER_PATH_LENGTH, MYF(0), self->name.str);
4729       return true;
4730   }
4731 
4732   if (!path_length) // no path is good path (remember, relative to datadir)
4733     return false;
4734 
4735   if (my_access(path, (F_OK|W_OK)))
4736     return true; // directory is not writable
4737 
4738   return false;
4739 }
4740 static bool fix_log(char** logname, const char* default_logname,
4741                     const char*ext, bool enabled, void (*reopen)(char*))
4742 {
4743   if (!*logname) // SET ... = DEFAULT
4744   {
4745     make_default_log_name(logname, ext, false);
4746     if (!*logname)
4747       return true;
4748   }
4749   logger.lock_exclusive();
4750   mysql_mutex_unlock(&LOCK_global_system_variables);
4751   if (enabled)
4752     reopen(*logname);
4753   logger.unlock();
4754   mysql_mutex_lock(&LOCK_global_system_variables);
4755   return false;
4756 }
4757 static void reopen_general_log(char* name)
4758 {
4759   logger.get_log_file_handler()->close(0);
4760   logger.get_log_file_handler()->open_query_log(name);
4761 }
4762 static bool fix_general_log_file(sys_var *self, THD *thd, enum_var_type type)
4763 {
4764   return fix_log(&opt_logname,  opt_log_basename, ".log", opt_log,
4765                  reopen_general_log);
4766 }
4767 static Sys_var_charptr Sys_general_log_path(
4768        "general_log_file", "Log connections and queries to given file",
4769        PREALLOCATED GLOBAL_VAR(opt_logname), CMD_LINE(REQUIRED_ARG),
4770        IN_FS_CHARSET, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
4771        ON_CHECK(check_log_path), ON_UPDATE(fix_general_log_file));
4772 
4773 static void reopen_slow_log(char* name)
4774 {
4775   logger.get_slow_log_file_handler()->close(0);
4776   logger.get_slow_log_file_handler()->open_slow_log(name);
4777 }
4778 static bool fix_slow_log_file(sys_var *self, THD *thd, enum_var_type type)
4779 {
4780   return fix_log(&opt_slow_logname, opt_log_basename, "-slow.log",
4781                  global_system_variables.sql_log_slow, reopen_slow_log);
4782 }
4783 static Sys_var_charptr Sys_slow_log_path(
4784        "slow_query_log_file", "Log slow queries to given log file. "
4785        "Defaults logging to 'hostname'-slow.log. Must be enabled to activate "
4786        "other slow log options",
4787        PREALLOCATED GLOBAL_VAR(opt_slow_logname), CMD_LINE(REQUIRED_ARG),
4788        IN_FS_CHARSET, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
4789        ON_CHECK(check_log_path), ON_UPDATE(fix_slow_log_file));
4790 
4791 static Sys_var_have Sys_have_compress(
4792        "have_compress", "If the zlib compression library is accessible to the "
4793        "server, this will be set to YES, otherwise it will be NO. The COMPRESS() "
4794        "and UNCOMPRESS() functions will only be available if set to YES.",
4795        READ_ONLY GLOBAL_VAR(have_compress), NO_CMD_LINE);
4796 
4797 static Sys_var_have Sys_have_crypt(
4798        "have_crypt", "If the crypt() system call is available this variable will "
4799        "be set to YES, otherwise it will be set to NO. If set to NO, the "
4800        "ENCRYPT() function cannot be used.",
4801        READ_ONLY GLOBAL_VAR(have_crypt), NO_CMD_LINE);
4802 
4803 static Sys_var_have Sys_have_dlopen(
4804        "have_dynamic_loading", "If the server supports dynamic loading of plugins, "
4805        "will be set to YES, otherwise will be set to NO.",
4806        READ_ONLY GLOBAL_VAR(have_dlopen), NO_CMD_LINE);
4807 
4808 static Sys_var_have Sys_have_geometry(
4809        "have_geometry", "If the server supports spatial data types, will be set to "
4810        "YES, otherwise will be set to NO.",
4811        READ_ONLY GLOBAL_VAR(have_geometry), NO_CMD_LINE);
4812 
4813 static Sys_var_have Sys_have_openssl(
4814        "have_openssl", "Comparing have_openssl with have_ssl will indicate whether "
4815        "YaSSL or openssl was used. If YaSSL, have_ssl will be YES, but have_openssl "
4816        "will be NO.",
4817        READ_ONLY GLOBAL_VAR(have_openssl), NO_CMD_LINE);
4818 
4819 static Sys_var_have Sys_have_profiling(
4820        "have_profiling", "If statement profiling is available, will be set to YES, "
4821        "otherwise will be set to NO. See SHOW PROFILES and SHOW PROFILE.",
4822        READ_ONLY GLOBAL_VAR(have_profiling), NO_CMD_LINE);
4823 
4824 static Sys_var_have Sys_have_query_cache(
4825        "have_query_cache", "If the server supports the query cache, will be set to "
4826        "YES, otherwise will be set to NO.",
4827        READ_ONLY GLOBAL_VAR(have_query_cache), NO_CMD_LINE);
4828 
4829 static Sys_var_have Sys_have_rtree_keys(
4830        "have_rtree_keys", "If RTREE indexes (used for spatial indexes) "
4831        "are available, will be set to YES, otherwise will be set to NO.",
4832        READ_ONLY GLOBAL_VAR(have_rtree_keys), NO_CMD_LINE);
4833 
4834 static Sys_var_have Sys_have_ssl(
4835        "have_ssl", "If the server supports secure connections, will be set to YES, "
4836        "otherwise will be set to NO. If set to DISABLED, the server was compiled with "
4837        "TLS support, but was not started with TLS support (see the mysqld options). "
4838        "See also have_openssl.",
4839        READ_ONLY GLOBAL_VAR(have_ssl), NO_CMD_LINE);
4840 
4841 static Sys_var_have Sys_have_symlink(
4842        "have_symlink", "If symbolic link support is enabled, will be set to YES, "
4843        "otherwise will be set to NO. Required for the INDEX DIRECTORY and DATA "
4844        "DIRECTORY table options (see CREATE TABLE) and Windows symlink support. "
4845        "Will be set to DISABLED if the server is started with the "
4846        "--skip-symbolic-links option.",
4847        READ_ONLY GLOBAL_VAR(have_symlink), NO_CMD_LINE);
4848 
4849 #if defined(__SANITIZE_ADDRESS__) || defined(WITH_UBSAN)
4850 
4851 #ifdef __SANITIZE_ADDRESS__
4852 #define SANITIZER_MODE "ASAN"
4853 #else
4854 #define SANITIZER_MODE "UBSAN"
4855 #endif /* __SANITIZE_ADDRESS__ */
4856 
4857 static char *have_sanitizer;
4858 static Sys_var_charptr Sys_have_santitizer(
4859        "have_sanitizer",
4860        "If the server is compiled with sanitize (compiler option), this "
4861        "variable is set to the sanitizer mode used. Possible values are "
4862        "ASAN (Address sanitizer) or UBSAN (The Undefined Behavior Sanitizer).",
4863         READ_ONLY GLOBAL_VAR(have_sanitizer), NO_CMD_LINE,
4864        IN_FS_CHARSET, DEFAULT(SANITIZER_MODE));
4865 #endif /* defined(__SANITIZE_ADDRESS__) || defined(WITH_UBSAN) */
4866 
4867 static bool fix_log_state(sys_var *self, THD *thd, enum_var_type type);
4868 
4869 static Sys_var_mybool Sys_general_log(
4870        "general_log", "Log connections and queries to a table or log file. "
4871        "Defaults logging to a file 'hostname'.log or a table mysql.general_log"
4872        "if --log-output=TABLE is used.",
4873        GLOBAL_VAR(opt_log), CMD_LINE(OPT_ARG),
4874        DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
4875        ON_UPDATE(fix_log_state));
4876 
4877 static Sys_var_mybool Sys_slow_query_log(
4878        "slow_query_log",
4879        "Log slow queries to a table or log file. Defaults logging to a file "
4880        "'hostname'-slow.log or a table mysql.slow_log if --log-output=TABLE is "
4881        "used. Must be enabled to activate other slow log options.",
4882        SESSION_VAR(sql_log_slow), CMD_LINE(OPT_ARG),
4883        DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG,
4884        ON_CHECK(0), ON_UPDATE(fix_log_state));
4885 
4886 static bool fix_log_state(sys_var *self, THD *thd, enum_var_type type)
4887 {
4888   bool res;
4889   my_bool *UNINIT_VAR(newvalptr), newval, UNINIT_VAR(oldval);
4890   uint UNINIT_VAR(log_type);
4891 
4892   if (type != OPT_GLOBAL)
4893     return 0;
4894 
4895   if (self == &Sys_general_log)
4896   {
4897     newvalptr= &opt_log;
4898     oldval=    logger.get_log_file_handler()->is_open();
4899     log_type=  QUERY_LOG_GENERAL;
4900   }
4901   else
4902   {
4903     DBUG_ASSERT(self == &Sys_slow_query_log);
4904     newvalptr= &global_system_variables.sql_log_slow;
4905     oldval=    logger.get_slow_log_file_handler()->is_open();
4906     log_type=  QUERY_LOG_SLOW;
4907   }
4908 
4909   newval= *newvalptr;
4910   if (oldval == newval)
4911     return false;
4912 
4913   *newvalptr= oldval; // [de]activate_log_handler works that way (sigh)
4914 
4915   mysql_mutex_unlock(&LOCK_global_system_variables);
4916   if (!newval)
4917   {
4918     logger.deactivate_log_handler(thd, log_type);
4919     res= false;
4920   }
4921   else
4922     res= logger.activate_log_handler(thd, log_type);
4923   mysql_mutex_lock(&LOCK_global_system_variables);
4924   return res;
4925 }
4926 
4927 
4928 static bool check_not_empty_set(sys_var *self, THD *thd, set_var *var)
4929 {
4930   return var->save_result.ulonglong_value == 0;
4931 }
4932 static bool fix_log_output(sys_var *self, THD *thd, enum_var_type type)
4933 {
4934   logger.lock_exclusive();
4935   logger.init_slow_log(log_output_options);
4936   logger.init_general_log(log_output_options);
4937   logger.unlock();
4938   return false;
4939 }
4940 
4941 static const char *log_output_names[] = { "NONE", "FILE", "TABLE", NULL};
4942 
4943 static Sys_var_set Sys_log_output(
4944        "log_output", "How logs should be written",
4945        GLOBAL_VAR(log_output_options), CMD_LINE(REQUIRED_ARG),
4946        log_output_names, DEFAULT(LOG_FILE), NO_MUTEX_GUARD, NOT_IN_BINLOG,
4947        ON_CHECK(check_not_empty_set), ON_UPDATE(fix_log_output));
4948 
4949 #ifdef HAVE_REPLICATION
4950 static Sys_var_mybool Sys_log_slave_updates(
4951        "log_slave_updates", "Tells the slave to log the updates from "
4952        "the slave thread to the binary log. You will need to turn it on if "
4953        "you plan to daisy-chain the slaves.",
4954        READ_ONLY GLOBAL_VAR(opt_log_slave_updates), CMD_LINE(OPT_ARG),
4955        DEFAULT(0));
4956 
4957 static Sys_var_charptr Sys_relay_log(
4958        "relay_log", "The location and name to use for relay logs.",
4959        READ_ONLY GLOBAL_VAR(opt_relay_logname), CMD_LINE(REQUIRED_ARG),
4960        IN_FS_CHARSET, DEFAULT(0));
4961 
4962 /*
4963   Uses NO_CMD_LINE since the --relay-log-index option set
4964   opt_relaylog_index_name variable and computes a value for the
4965   relay_log_index variable.
4966 */
4967 static Sys_var_charptr Sys_relay_log_index(
4968        "relay_log_index", "The location and name to use for the file "
4969        "that keeps a list of the last relay logs.",
4970        READ_ONLY GLOBAL_VAR(relay_log_index), NO_CMD_LINE,
4971        IN_FS_CHARSET, DEFAULT(0));
4972 
4973 /*
4974   Uses NO_CMD_LINE since the --log-bin-index option set
4975   opt_binlog_index_name variable and computes a value for the
4976   log_bin_index variable.
4977 */
4978 static Sys_var_charptr Sys_binlog_index(
4979        "log_bin_index", "File that holds the names for last binary log files.",
4980        READ_ONLY GLOBAL_VAR(log_bin_index), NO_CMD_LINE,
4981        IN_FS_CHARSET, DEFAULT(0));
4982 
4983 static Sys_var_charptr Sys_relay_log_basename(
4984        "relay_log_basename",
4985        "The full path of the relay log file names, excluding the extension.",
4986        READ_ONLY GLOBAL_VAR(relay_log_basename), NO_CMD_LINE,
4987        IN_FS_CHARSET, DEFAULT(0));
4988 
4989 static Sys_var_charptr Sys_log_bin_basename(
4990        "log_bin_basename",
4991        "The full path of the binary log file names, excluding the extension.",
4992        READ_ONLY GLOBAL_VAR(log_bin_basename), NO_CMD_LINE,
4993        IN_FS_CHARSET, DEFAULT(0));
4994 
4995 static Sys_var_charptr Sys_relay_log_info_file(
4996        "relay_log_info_file", "The location and name of the file that "
4997        "remembers where the SQL replication thread is in the relay logs.",
4998        READ_ONLY GLOBAL_VAR(relay_log_info_file), CMD_LINE(REQUIRED_ARG),
4999        IN_FS_CHARSET, DEFAULT(0));
5000 
5001 static Sys_var_mybool Sys_relay_log_purge(
5002        "relay_log_purge", "if disabled - do not purge relay logs. "
5003        "if enabled - purge them as soon as they are no more needed.",
5004        GLOBAL_VAR(relay_log_purge), CMD_LINE(OPT_ARG), DEFAULT(TRUE));
5005 
5006 static Sys_var_mybool Sys_relay_log_recovery(
5007        "relay_log_recovery", "Enables automatic relay log recovery "
5008        "right after the database startup, which means that the IO Thread "
5009        "starts re-fetching from the master right after the last transaction "
5010        "processed.",
5011        GLOBAL_VAR(relay_log_recovery), CMD_LINE(OPT_ARG), DEFAULT(FALSE));
5012 
5013 
5014 bool Sys_var_rpl_filter::global_update(THD *thd, set_var *var)
5015 {
5016   bool result= true;                            // Assume error
5017   LEX_CSTRING *base_name= &var->base;
5018 
5019   if (!base_name->length)
5020     base_name= &thd->variables.default_master_connection;
5021 
5022   mysql_mutex_unlock(&LOCK_global_system_variables);
5023 
5024   if (Master_info *mi= get_master_info(base_name, !var->base.length ?
5025                                        Sql_condition::WARN_LEVEL_ERROR :
5026                                        Sql_condition::WARN_LEVEL_WARN))
5027   {
5028     if (mi->rli.slave_running)
5029     {
5030       my_error(ER_SLAVE_MUST_STOP, MYF(0),
5031                (int) mi->connection_name.length,
5032                mi->connection_name.str);
5033       result= true;
5034     }
5035     else
5036     {
5037       result= set_filter_value(var->save_result.string_value.str, mi);
5038     }
5039     mi->release();
5040   }
5041 
5042   mysql_mutex_lock(&LOCK_global_system_variables);
5043   return result;
5044 }
5045 
5046 bool Sys_var_rpl_filter::set_filter_value(const char *value, Master_info *mi)
5047 {
5048   bool status= true;
5049   Rpl_filter* rpl_filter= mi->rpl_filter;
5050 
5051   /* Proctect against other threads */
5052   mysql_mutex_lock(&LOCK_active_mi);
5053   switch (opt_id) {
5054   case OPT_REPLICATE_DO_DB:
5055     status= rpl_filter->set_do_db(value);
5056     break;
5057   case OPT_REPLICATE_DO_TABLE:
5058     status= rpl_filter->set_do_table(value);
5059     break;
5060   case OPT_REPLICATE_IGNORE_DB:
5061     status= rpl_filter->set_ignore_db(value);
5062     break;
5063   case OPT_REPLICATE_IGNORE_TABLE:
5064     status= rpl_filter->set_ignore_table(value);
5065     break;
5066   case OPT_REPLICATE_WILD_DO_TABLE:
5067     status= rpl_filter->set_wild_do_table(value);
5068     break;
5069   case OPT_REPLICATE_WILD_IGNORE_TABLE:
5070     status= rpl_filter->set_wild_ignore_table(value);
5071     break;
5072   }
5073   mysql_mutex_unlock(&LOCK_active_mi);
5074   return status;
5075 }
5076 
5077 const uchar *
5078 Sys_var_rpl_filter::global_value_ptr(THD *thd,
5079                                      const LEX_CSTRING *base_name) const
5080 {
5081   char buf[256];
5082   String tmp(buf, sizeof(buf), &my_charset_bin);
5083   uchar *ret;
5084   Master_info *mi;
5085   Rpl_filter *rpl_filter;
5086 
5087   mysql_mutex_unlock(&LOCK_global_system_variables);
5088   mi= get_master_info(base_name, !base_name->length ?
5089                       Sql_condition::WARN_LEVEL_ERROR :
5090                       Sql_condition::WARN_LEVEL_WARN);
5091 
5092   if (!mi)
5093   {
5094     mysql_mutex_lock(&LOCK_global_system_variables);
5095     return 0;
5096   }
5097 
5098   rpl_filter= mi->rpl_filter;
5099   tmp.length(0);
5100 
5101   mysql_mutex_lock(&LOCK_active_mi);
5102   switch (opt_id) {
5103   case OPT_REPLICATE_DO_DB:
5104     rpl_filter->get_do_db(&tmp);
5105     break;
5106   case OPT_REPLICATE_DO_TABLE:
5107     rpl_filter->get_do_table(&tmp);
5108     break;
5109   case OPT_REPLICATE_IGNORE_DB:
5110     rpl_filter->get_ignore_db(&tmp);
5111     break;
5112   case OPT_REPLICATE_IGNORE_TABLE:
5113     rpl_filter->get_ignore_table(&tmp);
5114     break;
5115   case OPT_REPLICATE_WILD_DO_TABLE:
5116     rpl_filter->get_wild_do_table(&tmp);
5117     break;
5118   case OPT_REPLICATE_WILD_IGNORE_TABLE:
5119     rpl_filter->get_wild_ignore_table(&tmp);
5120     break;
5121   }
5122   mysql_mutex_unlock(&LOCK_active_mi);
5123   mysql_mutex_lock(&LOCK_global_system_variables);
5124 
5125   mi->release();
5126 
5127   ret= (uchar *) thd->strmake(tmp.ptr(), tmp.length());
5128 
5129   return ret;
5130 }
5131 
5132 static Sys_var_rpl_filter Sys_replicate_do_db(
5133        "replicate_do_db", OPT_REPLICATE_DO_DB,
5134        "Tell the slave to restrict replication to updates of tables "
5135        "whose names appear in the comma-separated list. For "
5136        "statement-based replication, only the default database (that "
5137        "is, the one selected by USE) is considered, not any explicitly "
5138        "mentioned tables in the query. For row-based replication, the "
5139        "actual names of table(s) being updated are checked.");
5140 
5141 static Sys_var_rpl_filter Sys_replicate_do_table(
5142        "replicate_do_table", OPT_REPLICATE_DO_TABLE,
5143        "Tells the slave to restrict replication to tables in the "
5144        "comma-separated list.");
5145 
5146 static Sys_var_rpl_filter Sys_replicate_ignore_db(
5147        "replicate_ignore_db", OPT_REPLICATE_IGNORE_DB,
5148        "Tell the slave to restrict replication to updates of tables "
5149        "whose names do not appear in the comma-separated list. For "
5150        "statement-based replication, only the default database (that "
5151        "is, the one selected by USE) is considered, not any explicitly "
5152        "mentioned tables in the query. For row-based replication, the "
5153        "actual names of table(s) being updated are checked.");
5154 
5155 static Sys_var_rpl_filter Sys_replicate_ignore_table(
5156        "replicate_ignore_table", OPT_REPLICATE_IGNORE_TABLE,
5157        "Tells the slave thread not to replicate any statement that "
5158        "updates the specified table, even if any other tables might be "
5159        "updated by the same statement.");
5160 
5161 static Sys_var_rpl_filter Sys_replicate_wild_do_table(
5162        "replicate_wild_do_table", OPT_REPLICATE_WILD_DO_TABLE,
5163        "Tells the slave thread to restrict replication to statements "
5164        "where any of the updated tables match the specified database "
5165        "and table name patterns.");
5166 
5167 static Sys_var_rpl_filter Sys_replicate_wild_ignore_table(
5168        "replicate_wild_ignore_table", OPT_REPLICATE_WILD_IGNORE_TABLE,
5169        "Tells the slave thread to not replicate to the tables that "
5170        "match the given wildcard pattern.");
5171 
5172 static Sys_var_charptr Sys_slave_load_tmpdir(
5173        "slave_load_tmpdir", "The location where the slave should put "
5174        "its temporary files when replicating a LOAD DATA INFILE command",
5175        READ_ONLY GLOBAL_VAR(slave_load_tmpdir), CMD_LINE(REQUIRED_ARG),
5176        IN_FS_CHARSET, DEFAULT(0));
5177 
5178 static Sys_var_uint Sys_slave_net_timeout(
5179        "slave_net_timeout", "Number of seconds to wait for more data "
5180        "from any master/slave connection before aborting the read",
5181        GLOBAL_VAR(slave_net_timeout), CMD_LINE(REQUIRED_ARG),
5182        VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(SLAVE_NET_TIMEOUT), BLOCK_SIZE(1));
5183 
5184 
5185 /*
5186   Access a multi_source variable
5187   Return 0 + warning if it doesn't exist
5188 */
5189 
5190 ulonglong Sys_var_multi_source_ulonglong::
5191 get_master_info_ulonglong_value(THD *thd, ptrdiff_t offset) const
5192 {
5193   Master_info *mi;
5194   ulonglong res= 0;                                  // Default value
5195   mysql_mutex_unlock(&LOCK_global_system_variables);
5196   if ((mi= get_master_info(&thd->variables.default_master_connection,
5197                            Sql_condition::WARN_LEVEL_WARN)))
5198   {
5199     res= *((ulonglong*) (((uchar*) mi) + master_info_offset));
5200     mi->release();
5201   }
5202   mysql_mutex_lock(&LOCK_global_system_variables);
5203   return res;
5204 }
5205 
5206 
5207 bool update_multi_source_variable(sys_var *self_var, THD *thd,
5208                                   enum_var_type type)
5209 {
5210   Sys_var_multi_source_ulonglong *self= (Sys_var_multi_source_ulonglong*) self_var;
5211   bool result= true;
5212   Master_info *mi;
5213 
5214   if (type == OPT_GLOBAL)
5215     mysql_mutex_unlock(&LOCK_global_system_variables);
5216   if ((mi= (get_master_info(&thd->variables.default_master_connection,
5217                             Sql_condition::WARN_LEVEL_ERROR))))
5218   {
5219     mysql_mutex_lock(&mi->rli.run_lock);
5220     mysql_mutex_lock(&mi->rli.data_lock);
5221     result= self->update_variable(thd, mi);
5222     mysql_mutex_unlock(&mi->rli.data_lock);
5223     mysql_mutex_unlock(&mi->rli.run_lock);
5224     mi->release();
5225   }
5226   if (type == OPT_GLOBAL)
5227     mysql_mutex_lock(&LOCK_global_system_variables);
5228   return result;
5229 }
5230 
5231 static bool update_slave_skip_counter(sys_var *self, THD *thd, Master_info *mi)
5232 {
5233   if (mi->rli.slave_running)
5234   {
5235     my_error(ER_SLAVE_MUST_STOP, MYF(0), (int) mi->connection_name.length,
5236              mi->connection_name.str);
5237     return true;
5238   }
5239   if (mi->using_gtid != Master_info::USE_GTID_NO && mi->using_parallel())
5240   {
5241     ulong domain_count;
5242     mysql_mutex_lock(&rpl_global_gtid_slave_state->LOCK_slave_state);
5243     domain_count= rpl_global_gtid_slave_state->count();
5244     mysql_mutex_unlock(&rpl_global_gtid_slave_state->LOCK_slave_state);
5245     if (domain_count > 1)
5246     {
5247       /*
5248         With domain-based parallel replication, the slave position is
5249         multi-dimensional, so the relay log position is not very meaningful.
5250         It might not even correspond to the next GTID to execute in _any_
5251         domain (the case after error stop). So slave_skip_counter will most
5252         likely not do what the user intends. Instead give an error, with a
5253         suggestion to instead set @@gtid_slave_pos past the point of error;
5254         this works reliably also in the case of multiple domains.
5255       */
5256       my_error(ER_SLAVE_SKIP_NOT_IN_GTID, MYF(0));
5257       return true;
5258     }
5259   }
5260 
5261   /* The value was stored temporarily in thd */
5262   mi->rli.slave_skip_counter= thd->variables.slave_skip_counter;
5263   return false;
5264 }
5265 
5266 static Sys_var_multi_source_ulonglong Sys_slave_skip_counter(
5267        "sql_slave_skip_counter", "Skip the next N events from the master log",
5268        SESSION_VAR(slave_skip_counter), NO_CMD_LINE,
5269        MASTER_INFO_VAR(rli.slave_skip_counter),
5270        VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1),
5271        ON_UPDATE(update_slave_skip_counter));
5272 
5273 static bool update_max_relay_log_size(sys_var *self, THD *thd, Master_info *mi)
5274 {
5275   mi->rli.max_relay_log_size= thd->variables.max_relay_log_size;
5276   mi->rli.relay_log.set_max_size((ulong)mi->rli.max_relay_log_size);
5277   return false;
5278 }
5279 
5280 static Sys_var_multi_source_ulonglong Sys_max_relay_log_size(
5281        "max_relay_log_size",
5282        "relay log will be rotated automatically when the size exceeds this "
5283        "value.  If 0 at startup, it's set to max_binlog_size",
5284        SESSION_VAR(max_relay_log_size), CMD_LINE(REQUIRED_ARG),
5285        MASTER_INFO_VAR(rli.max_relay_log_size),
5286        VALID_RANGE(0, 1024L*1024*1024), DEFAULT(0), BLOCK_SIZE(IO_SIZE),
5287        ON_UPDATE(update_max_relay_log_size));
5288 
5289 static Sys_var_charptr Sys_slave_skip_errors(
5290        "slave_skip_errors", "Tells the slave thread to continue "
5291        "replication when a query event returns an error from the "
5292        "provided list",
5293        READ_ONLY GLOBAL_VAR(opt_slave_skip_errors), CMD_LINE(REQUIRED_ARG),
5294        IN_SYSTEM_CHARSET, DEFAULT(0));
5295 
5296 static Sys_var_ulonglong Sys_read_binlog_speed_limit(
5297        "read_binlog_speed_limit", "Maximum speed(KB/s) to read binlog from"
5298        " master (0 = no limit)",
5299        GLOBAL_VAR(opt_read_binlog_speed_limit), CMD_LINE(REQUIRED_ARG),
5300        VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1));
5301 
5302 static Sys_var_charptr Sys_slave_transaction_retry_errors(
5303        "slave_transaction_retry_errors", "Tells the slave thread to retry "
5304        "transaction for replication when a query event returns an error from "
5305        "the provided list. Deadlock error, elapsed lock wait timeout, "
5306        "net read error, net read timeout, net write error, net write timeout, "
5307        "connect error and 2 types of lost connection error are automatically "
5308        "added to this list",
5309        READ_ONLY GLOBAL_VAR(opt_slave_transaction_retry_errors), CMD_LINE(REQUIRED_ARG),
5310        IN_SYSTEM_CHARSET, DEFAULT(0));
5311 
5312 static Sys_var_ulonglong Sys_relay_log_space_limit(
5313        "relay_log_space_limit", "Maximum space to use for all relay logs",
5314        READ_ONLY GLOBAL_VAR(relay_log_space_limit), CMD_LINE(REQUIRED_ARG),
5315        VALID_RANGE(0, ULONGLONG_MAX), DEFAULT(0), BLOCK_SIZE(1));
5316 
5317 static Sys_var_uint Sys_sync_relaylog_period(
5318        "sync_relay_log", "Synchronously flush relay log to disk after "
5319        "every #th event. Use 0 to disable synchronous flushing",
5320        GLOBAL_VAR(sync_relaylog_period), CMD_LINE(REQUIRED_ARG),
5321        VALID_RANGE(0, UINT_MAX), DEFAULT(10000), BLOCK_SIZE(1));
5322 
5323 static Sys_var_uint Sys_sync_relayloginfo_period(
5324        "sync_relay_log_info", "Synchronously flush relay log info "
5325        "to disk after every #th transaction. Use 0 to disable "
5326        "synchronous flushing",
5327        GLOBAL_VAR(sync_relayloginfo_period), CMD_LINE(REQUIRED_ARG),
5328        VALID_RANGE(0, UINT_MAX), DEFAULT(10000), BLOCK_SIZE(1));
5329 #endif
5330 
5331 static Sys_var_uint Sys_sync_binlog_period(
5332        "sync_binlog", "Synchronously flush binary log to disk after "
5333        "every #th event. Use 0 (default) to disable synchronous flushing",
5334        GLOBAL_VAR(sync_binlog_period), CMD_LINE(REQUIRED_ARG),
5335        VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1));
5336 
5337 static Sys_var_uint Sys_sync_masterinfo_period(
5338        "sync_master_info", "Synchronously flush master info to disk "
5339        "after every #th event. Use 0 to disable synchronous flushing",
5340        GLOBAL_VAR(sync_masterinfo_period), CMD_LINE(REQUIRED_ARG),
5341        VALID_RANGE(0, UINT_MAX), DEFAULT(10000), BLOCK_SIZE(1));
5342 
5343 #ifdef HAVE_REPLICATION
5344 static Sys_var_ulong Sys_slave_trans_retries(
5345        "slave_transaction_retries", "Number of times the slave SQL "
5346        "thread will retry a transaction in case it failed with a deadlock, "
5347        "elapsed lock wait timeout or listed in "
5348        "slave_transaction_retry_errors, before giving up and stopping",
5349        GLOBAL_VAR(slave_trans_retries), CMD_LINE(REQUIRED_ARG),
5350        VALID_RANGE(0, UINT_MAX), DEFAULT(10), BLOCK_SIZE(1));
5351 
5352 static Sys_var_ulong Sys_slave_trans_retry_interval(
5353        "slave_transaction_retry_interval", "Interval of the slave SQL "
5354        "thread will retry a transaction in case it failed with a deadlock "
5355        "or elapsed lock wait timeout or listed in "
5356        "slave_transaction_retry_errors",
5357        GLOBAL_VAR(slave_trans_retry_interval), CMD_LINE(REQUIRED_ARG),
5358        VALID_RANGE(0, 3600), DEFAULT(0), BLOCK_SIZE(1));
5359 #endif
5360 
5361 static bool check_locale(sys_var *self, THD *thd, set_var *var)
5362 {
5363   if (!var->value)
5364     return false;
5365 
5366   MY_LOCALE *locale;
5367   char buff[STRING_BUFFER_USUAL_SIZE];
5368   if (var->value->result_type() == INT_RESULT)
5369   {
5370     int lcno= (int)var->value->val_int();
5371     if (!(locale= my_locale_by_number(lcno)))
5372     {
5373       my_error(ER_UNKNOWN_LOCALE, MYF(0), llstr(lcno, buff));
5374       return true;
5375     }
5376     if (check_not_null(self, thd, var))
5377       return true;
5378   }
5379   else // STRING_RESULT
5380   {
5381     String str(buff, sizeof(buff), system_charset_info), *res;
5382     if (!(res=var->value->val_str(&str)))
5383       return true;
5384     else if (!(locale= my_locale_by_name(res->c_ptr_safe())))
5385     {
5386       ErrConvString err(res);
5387       my_error(ER_UNKNOWN_LOCALE, MYF(0), err.ptr());
5388       return true;
5389     }
5390   }
5391 
5392   var->save_result.ptr= locale;
5393 
5394   if (!locale->errmsgs->errmsgs)
5395   {
5396     bool res;
5397     mysql_mutex_lock(&LOCK_error_messages);
5398     res= (!locale->errmsgs->errmsgs &&
5399           read_texts(ERRMSG_FILE, locale->errmsgs->language,
5400                      &locale->errmsgs->errmsgs));
5401     mysql_mutex_unlock(&LOCK_error_messages);
5402     if (res)
5403     {
5404       push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
5405                           "Can't process error message file for locale '%s'",
5406                           locale->name);
5407       return true;
5408     }
5409   }
5410   status_var_increment(thd->status_var.feature_locale);
5411   return false;
5412 }
5413 
5414 static bool update_locale(sys_var *self, THD* thd, enum_var_type type)
5415 {
5416   /* Cache pointer to error messages */
5417   if (type == OPT_SESSION)
5418     thd->variables.errmsgs= thd->variables.lc_messages->errmsgs->errmsgs;
5419   else
5420     global_system_variables.errmsgs=
5421       global_system_variables.lc_messages->errmsgs->errmsgs;
5422   return false;
5423 }
5424 
5425 static Sys_var_struct Sys_lc_messages(
5426        "lc_messages", "Set the language used for the error messages",
5427        SESSION_VAR(lc_messages), NO_CMD_LINE,
5428        offsetof(MY_LOCALE, name), DEFAULT(&my_default_lc_messages),
5429        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_locale), ON_UPDATE(update_locale));
5430 
5431 static Sys_var_struct Sys_lc_time_names(
5432        "lc_time_names", "Set the language used for the month "
5433        "names and the days of the week",
5434        SESSION_VAR(lc_time_names), NO_CMD_LINE,
5435        offsetof(MY_LOCALE, name), DEFAULT(&my_default_lc_time_names),
5436        NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_locale));
5437 
5438 static Sys_var_tz Sys_time_zone(
5439        "time_zone", "The current time zone, used to initialize the time "
5440        "zone for a client when it connects. Set to SYSTEM by default, in "
5441        "which the client uses the system time zone value.",
5442        SESSION_VAR(time_zone), NO_CMD_LINE,
5443        DEFAULT(&default_tz), NO_MUTEX_GUARD, IN_BINLOG);
5444 
5445 #ifdef WITH_WSREP
5446 #include "wsrep_var.h"
5447 #include "wsrep_sst.h"
5448 #include "wsrep_binlog.h"
5449 
5450 static Sys_var_charptr Sys_wsrep_provider(
5451        "wsrep_provider", "Path to replication provider library",
5452        PREALLOCATED READ_ONLY GLOBAL_VAR(wsrep_provider), CMD_LINE(REQUIRED_ARG),
5453        IN_FS_CHARSET, DEFAULT(WSREP_NONE),
5454        NO_MUTEX_GUARD, NOT_IN_BINLOG,
5455        ON_CHECK(wsrep_provider_check), ON_UPDATE(wsrep_provider_update));
5456 
5457 static Sys_var_charptr Sys_wsrep_provider_options(
5458        "wsrep_provider_options", "Semicolon (;) separated list of wsrep "
5459        "options (see wsrep_provider_options documentation).",
5460        PREALLOCATED GLOBAL_VAR(wsrep_provider_options),
5461        CMD_LINE(REQUIRED_ARG),
5462        IN_SYSTEM_CHARSET, DEFAULT(""), NO_MUTEX_GUARD, NOT_IN_BINLOG,
5463        ON_CHECK(wsrep_provider_options_check),
5464        ON_UPDATE(wsrep_provider_options_update));
5465 
5466 static Sys_var_charptr Sys_wsrep_data_home_dir(
5467        "wsrep_data_home_dir", "home directory for wsrep provider",
5468        READ_ONLY GLOBAL_VAR(wsrep_data_home_dir), CMD_LINE(REQUIRED_ARG),
5469        IN_FS_CHARSET, DEFAULT(mysql_real_data_home));
5470 
5471 static Sys_var_charptr Sys_wsrep_cluster_name(
5472        "wsrep_cluster_name", "Name for the cluster",
5473        PREALLOCATED GLOBAL_VAR(wsrep_cluster_name), CMD_LINE(REQUIRED_ARG),
5474        IN_SYSTEM_CHARSET, DEFAULT(WSREP_CLUSTER_NAME),
5475        NO_MUTEX_GUARD, NOT_IN_BINLOG,
5476        ON_CHECK(wsrep_cluster_name_check),
5477        ON_UPDATE(wsrep_cluster_name_update));
5478 
5479 static Sys_var_charptr Sys_wsrep_cluster_address (
5480        "wsrep_cluster_address", "Address to initially connect to cluster",
5481        PREALLOCATED GLOBAL_VAR(wsrep_cluster_address),
5482        CMD_LINE(REQUIRED_ARG),
5483        IN_SYSTEM_CHARSET, DEFAULT(""),
5484        NO_MUTEX_GUARD, NOT_IN_BINLOG,
5485        ON_CHECK(wsrep_cluster_address_check),
5486        ON_UPDATE(wsrep_cluster_address_update));
5487 
5488 static Sys_var_charptr Sys_wsrep_node_name (
5489        "wsrep_node_name", "Name of this node. This name can be used in "
5490        "wsrep_sst_donor as a preferred donor. Note that multiple nodes "
5491        "in a cluster can have the same name.",
5492        PREALLOCATED GLOBAL_VAR(wsrep_node_name), CMD_LINE(REQUIRED_ARG),
5493        IN_SYSTEM_CHARSET, DEFAULT(glob_hostname), NO_MUTEX_GUARD, NOT_IN_BINLOG,
5494        wsrep_node_name_check, wsrep_node_name_update);
5495 
5496 static Sys_var_charptr Sys_wsrep_node_address (
5497        "wsrep_node_address", "Specifies the node's network address, in "
5498        "the format ip address[:port]. Used in situations where autoguessing "
5499        "is not reliable. As of MariaDB 10.1.8, supports IPv6.",
5500        PREALLOCATED GLOBAL_VAR(wsrep_node_address), CMD_LINE(REQUIRED_ARG),
5501        IN_SYSTEM_CHARSET, DEFAULT(""),
5502        NO_MUTEX_GUARD, NOT_IN_BINLOG,
5503        ON_CHECK(wsrep_node_address_check),
5504        ON_UPDATE(wsrep_node_address_update));
5505 
5506 static Sys_var_charptr Sys_wsrep_node_incoming_address(
5507        "wsrep_node_incoming_address", "Client connection address",
5508        PREALLOCATED GLOBAL_VAR(wsrep_node_incoming_address),CMD_LINE(REQUIRED_ARG),
5509        IN_SYSTEM_CHARSET, DEFAULT(WSREP_NODE_INCOMING_AUTO));
5510 
5511 static Sys_var_ulong Sys_wsrep_slave_threads(
5512        "wsrep_slave_threads", "Number of slave appliers to launch",
5513        GLOBAL_VAR(wsrep_slave_threads), CMD_LINE(REQUIRED_ARG),
5514        VALID_RANGE(1, 512), DEFAULT(1), BLOCK_SIZE(1),
5515        NO_MUTEX_GUARD, NOT_IN_BINLOG,
5516        ON_CHECK(0),
5517        ON_UPDATE(wsrep_slave_threads_update));
5518 
5519 static Sys_var_charptr Sys_wsrep_dbug_option(
5520        "wsrep_dbug_option", "DBUG options to provider library",
5521        GLOBAL_VAR(wsrep_dbug_option),CMD_LINE(REQUIRED_ARG),
5522        IN_SYSTEM_CHARSET, DEFAULT(""));
5523 
5524 static const char *wsrep_debug_names[]=
5525 { "NONE", "SERVER", "TRANSACTION", "STREAMING", "CLIENT", NullS };
5526 static Sys_var_enum Sys_wsrep_debug(
5527        "wsrep_debug", "WSREP debug level logging",
5528        GLOBAL_VAR(wsrep_debug), CMD_LINE(REQUIRED_ARG),
5529        wsrep_debug_names, DEFAULT(0),
5530        NO_MUTEX_GUARD, NOT_IN_BINLOG,
5531        ON_CHECK(0), ON_UPDATE(wsrep_debug_update));
5532 
5533 static Sys_var_mybool Sys_wsrep_convert_LOCK_to_trx(
5534        "wsrep_convert_LOCK_to_trx", "To convert locking sessions "
5535        "into transactions",
5536        GLOBAL_VAR(wsrep_convert_LOCK_to_trx),
5537        CMD_LINE(OPT_ARG), DEFAULT(FALSE));
5538 
5539 static Sys_var_ulong Sys_wsrep_retry_autocommit(
5540       "wsrep_retry_autocommit", "Max number of times to retry "
5541       "a failed autocommit statement",
5542        SESSION_VAR(wsrep_retry_autocommit), CMD_LINE(REQUIRED_ARG),
5543        VALID_RANGE(0, 10000), DEFAULT(1), BLOCK_SIZE(1));
5544 
5545 static bool update_wsrep_auto_increment_control (sys_var *self, THD *thd, enum_var_type type)
5546 {
5547   if (wsrep_auto_increment_control)
5548   {
5549     /*
5550       The variables that control auto increment shall be calculated
5551       automaticaly based on the size of the cluster. This usually done
5552       within the wsrep_view_handler_cb callback. However, if the user
5553       manually sets the value of wsrep_auto_increment_control to 'ON',
5554       then we should to re-calculate these variables again (because
5555       these values may be required before wsrep_view_handler_cb will
5556       be re-invoked, which is rarely invoked if the cluster stays in
5557       the stable state):
5558     */
5559     global_system_variables.auto_increment_increment=
5560        wsrep_cluster_size ? wsrep_cluster_size : 1;
5561     global_system_variables.auto_increment_offset=
5562        wsrep_local_index >= 0 ? wsrep_local_index + 1 : 1;
5563     thd->variables.auto_increment_increment=
5564       global_system_variables.auto_increment_increment;
5565     thd->variables.auto_increment_offset=
5566       global_system_variables.auto_increment_offset;
5567   }
5568   else
5569   {
5570     /*
5571       We must restore the last values of the variables that
5572       are explicitly specified by the user:
5573     */
5574     global_system_variables.auto_increment_increment=
5575       global_system_variables.saved_auto_increment_increment;
5576     global_system_variables.auto_increment_offset=
5577       global_system_variables.saved_auto_increment_offset;
5578     thd->variables.auto_increment_increment=
5579       thd->variables.saved_auto_increment_increment;
5580     thd->variables.auto_increment_offset=
5581       thd->variables.saved_auto_increment_offset;
5582   }
5583   return false;
5584 }
5585 
5586 static Sys_var_mybool Sys_wsrep_auto_increment_control(
5587        "wsrep_auto_increment_control", "To automatically control the "
5588        "assignment of autoincrement variables",
5589        GLOBAL_VAR(wsrep_auto_increment_control),
5590        CMD_LINE(OPT_ARG), DEFAULT(TRUE),
5591        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
5592        ON_UPDATE(update_wsrep_auto_increment_control));
5593 
5594 static Sys_var_mybool Sys_wsrep_drupal_282555_workaround(
5595        "wsrep_drupal_282555_workaround", "Enable a workaround to handle the "
5596        "cases where inserting a DEFAULT value into an auto-increment column "
5597        "could fail with duplicate key error",
5598        GLOBAL_VAR(wsrep_drupal_282555_workaround),
5599        CMD_LINE(OPT_ARG), DEFAULT(FALSE));
5600 
5601 static Sys_var_charptr sys_wsrep_sst_method(
5602        "wsrep_sst_method", "State snapshot transfer method",
5603        GLOBAL_VAR(wsrep_sst_method),CMD_LINE(REQUIRED_ARG),
5604        IN_SYSTEM_CHARSET, DEFAULT(WSREP_SST_DEFAULT), NO_MUTEX_GUARD, NOT_IN_BINLOG,
5605        ON_CHECK(wsrep_sst_method_check));
5606 
5607 static Sys_var_charptr Sys_wsrep_sst_receive_address(
5608        "wsrep_sst_receive_address", "Address where node is waiting for "
5609        "SST contact",
5610        GLOBAL_VAR(wsrep_sst_receive_address),CMD_LINE(REQUIRED_ARG),
5611        IN_SYSTEM_CHARSET, DEFAULT(WSREP_SST_ADDRESS_AUTO), NO_MUTEX_GUARD,
5612        NOT_IN_BINLOG,
5613        ON_CHECK(wsrep_sst_receive_address_check),
5614        ON_UPDATE(wsrep_sst_receive_address_update));
5615 
5616 static Sys_var_charptr Sys_wsrep_sst_auth(
5617        "wsrep_sst_auth", "Authentication for SST connection",
5618        PREALLOCATED GLOBAL_VAR(wsrep_sst_auth), CMD_LINE(REQUIRED_ARG),
5619        IN_SYSTEM_CHARSET, DEFAULT(NULL), NO_MUTEX_GUARD,
5620        NOT_IN_BINLOG,
5621        ON_CHECK(wsrep_sst_auth_check),
5622        ON_UPDATE(wsrep_sst_auth_update));
5623 
5624 static Sys_var_charptr Sys_wsrep_sst_donor(
5625        "wsrep_sst_donor", "preferred donor node for the SST",
5626        GLOBAL_VAR(wsrep_sst_donor),CMD_LINE(REQUIRED_ARG),
5627        IN_SYSTEM_CHARSET, DEFAULT(""), NO_MUTEX_GUARD, NOT_IN_BINLOG,
5628        ON_CHECK(wsrep_sst_donor_check),
5629        ON_UPDATE(wsrep_sst_donor_update));
5630 
5631 static Sys_var_mybool Sys_wsrep_sst_donor_rejects_queries(
5632        "wsrep_sst_donor_rejects_queries", "Reject client queries "
5633        "when donating state snapshot transfer",
5634        GLOBAL_VAR(wsrep_sst_donor_rejects_queries),
5635        CMD_LINE(OPT_ARG), DEFAULT(FALSE));
5636 
5637 static Sys_var_mybool Sys_wsrep_on (
5638        "wsrep_on", "To enable wsrep replication ",
5639        SESSION_VAR(wsrep_on),
5640        CMD_LINE(OPT_ARG), DEFAULT(FALSE),
5641        NO_MUTEX_GUARD, NOT_IN_BINLOG,
5642        ON_CHECK(wsrep_on_check),
5643        ON_UPDATE(wsrep_on_update));
5644 
5645 static Sys_var_charptr Sys_wsrep_start_position (
5646        "wsrep_start_position", "global transaction position to start from ",
5647        PREALLOCATED GLOBAL_VAR(wsrep_start_position),
5648        CMD_LINE(REQUIRED_ARG),
5649        IN_SYSTEM_CHARSET, DEFAULT(WSREP_START_POSITION_ZERO),
5650        NO_MUTEX_GUARD, NOT_IN_BINLOG,
5651        ON_CHECK(wsrep_start_position_check),
5652        ON_UPDATE(wsrep_start_position_update));
5653 
5654 static Sys_var_ulong Sys_wsrep_max_ws_size (
5655        "wsrep_max_ws_size", "Max write set size (bytes)",
5656        GLOBAL_VAR(wsrep_max_ws_size), CMD_LINE(REQUIRED_ARG),
5657        VALID_RANGE(1024, WSREP_MAX_WS_SIZE), DEFAULT(WSREP_MAX_WS_SIZE),
5658        BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG,
5659        ON_CHECK(wsrep_max_ws_size_check), ON_UPDATE(wsrep_max_ws_size_update));
5660 
5661 static Sys_var_ulong Sys_wsrep_max_ws_rows (
5662        "wsrep_max_ws_rows", "Max number of rows in write set",
5663        GLOBAL_VAR(wsrep_max_ws_rows), CMD_LINE(REQUIRED_ARG),
5664        VALID_RANGE(0, 1048576), DEFAULT(0), BLOCK_SIZE(1));
5665 
5666 static Sys_var_charptr Sys_wsrep_notify_cmd(
5667        "wsrep_notify_cmd", "",
5668        READ_ONLY GLOBAL_VAR(wsrep_notify_cmd), CMD_LINE(REQUIRED_ARG),
5669        IN_SYSTEM_CHARSET, DEFAULT(""));
5670 
5671 static Sys_var_mybool Sys_wsrep_certify_nonPK(
5672        "wsrep_certify_nonPK", "Certify tables with no primary key",
5673        GLOBAL_VAR(wsrep_certify_nonPK),
5674        CMD_LINE(OPT_ARG), DEFAULT(TRUE));
5675 
5676 static const char *wsrep_certification_rules_names[]= { "strict", "optimized", NullS };
5677 static Sys_var_enum Sys_wsrep_certification_rules(
5678        "wsrep_certification_rules",
5679        "Certification rules to use in the cluster. Possible values are: "
5680        "\"strict\": stricter rules that could result in more certification "
5681        "failures. "
5682        "\"optimized\": relaxed rules that allow more concurrency and "
5683        "cause less certification failures.",
5684        GLOBAL_VAR(wsrep_certification_rules), CMD_LINE(REQUIRED_ARG),
5685        wsrep_certification_rules_names, DEFAULT(WSREP_CERTIFICATION_RULES_STRICT),
5686        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
5687        ON_UPDATE(0));
5688 
5689 static Sys_var_mybool Sys_wsrep_causal_reads(
5690        "wsrep_causal_reads", "Setting this variable is equivalent "
5691        "to setting wsrep_sync_wait READ flag",
5692        SESSION_VAR(wsrep_causal_reads),
5693        CMD_LINE(OPT_ARG, OPT_WSREP_CAUSAL_READS), DEFAULT(FALSE),
5694        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
5695        ON_UPDATE(wsrep_causal_reads_update),
5696        DEPRECATED("'@@wsrep_sync_wait=1'"));
5697 
5698 static Sys_var_uint Sys_wsrep_sync_wait(
5699        "wsrep_sync_wait", "Ensure \"synchronous\" read view before executing "
5700        "an operation of the type specified by bitmask: 1 - READ(includes "
5701        "SELECT, SHOW and BEGIN/START TRANSACTION); 2 - UPDATE and DELETE; 4 - "
5702        "INSERT and REPLACE",
5703        SESSION_VAR(wsrep_sync_wait), CMD_LINE(OPT_ARG, OPT_WSREP_SYNC_WAIT),
5704        VALID_RANGE(WSREP_SYNC_WAIT_NONE, WSREP_SYNC_WAIT_MAX),
5705        DEFAULT(WSREP_SYNC_WAIT_NONE), BLOCK_SIZE(1),
5706        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
5707        ON_UPDATE(wsrep_sync_wait_update));
5708 
5709 static const char *wsrep_OSU_method_names[]= { "TOI", "RSU", NullS };
5710 static Sys_var_enum Sys_wsrep_OSU_method(
5711        "wsrep_OSU_method", "Method for Online Schema Upgrade",
5712        SESSION_VAR(wsrep_OSU_method), CMD_LINE(OPT_ARG),
5713        wsrep_OSU_method_names, DEFAULT(WSREP_OSU_TOI));
5714 
5715 static PolyLock_mutex PLock_wsrep_desync(&LOCK_wsrep_desync);
5716 static Sys_var_mybool Sys_wsrep_desync (
5717        "wsrep_desync", "To desynchronize the node from the cluster",
5718        GLOBAL_VAR(wsrep_desync),
5719        CMD_LINE(OPT_ARG), DEFAULT(FALSE),
5720        &PLock_wsrep_desync, NOT_IN_BINLOG,
5721        ON_CHECK(wsrep_desync_check),
5722        ON_UPDATE(wsrep_desync_update));
5723 
5724 static const char *wsrep_reject_queries_names[]= { "NONE", "ALL", "ALL_KILL", NullS };
5725 static Sys_var_enum Sys_wsrep_reject_queries(
5726        "wsrep_reject_queries", "Variable to set to reject queries",
5727        GLOBAL_VAR(wsrep_reject_queries), CMD_LINE(OPT_ARG),
5728        wsrep_reject_queries_names, DEFAULT(WSREP_REJECT_NONE),
5729        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
5730        ON_UPDATE(wsrep_reject_queries_update));
5731 
5732 static const char *wsrep_binlog_format_names[]=
5733        {"MIXED", "STATEMENT", "ROW", "NONE", NullS};
5734 static Sys_var_enum Sys_wsrep_forced_binlog_format(
5735        "wsrep_forced_binlog_format", "binlog format to take effect over user's choice",
5736        GLOBAL_VAR(wsrep_forced_binlog_format), CMD_LINE(REQUIRED_ARG),
5737        wsrep_binlog_format_names, DEFAULT(BINLOG_FORMAT_UNSPEC));
5738 
5739 static Sys_var_mybool Sys_wsrep_recover_datadir(
5740        "wsrep_recover", "Recover database state after crash and exit",
5741        READ_ONLY GLOBAL_VAR(wsrep_recovery),
5742        CMD_LINE(OPT_ARG), DEFAULT(FALSE));
5743 
5744 static Sys_var_mybool Sys_wsrep_replicate_myisam(
5745        "wsrep_replicate_myisam", "To enable myisam replication",
5746        GLOBAL_VAR(wsrep_replicate_myisam), CMD_LINE(OPT_ARG), DEFAULT(FALSE));
5747 
5748 static Sys_var_mybool Sys_wsrep_log_conflicts(
5749        "wsrep_log_conflicts", "To log multi-master conflicts",
5750        GLOBAL_VAR(wsrep_log_conflicts), CMD_LINE(OPT_ARG), DEFAULT(FALSE));
5751 
5752 static Sys_var_ulong Sys_wsrep_mysql_replication_bundle(
5753       "wsrep_mysql_replication_bundle", "mysql replication group commit ",
5754        GLOBAL_VAR(wsrep_mysql_replication_bundle), CMD_LINE(REQUIRED_ARG),
5755        VALID_RANGE(0, 1000), DEFAULT(0), BLOCK_SIZE(1));
5756 
5757 static Sys_var_mybool Sys_wsrep_load_data_splitting(
5758        "wsrep_load_data_splitting", "To commit LOAD DATA "
5759        "transaction after every 10K rows inserted (deprecated)",
5760        GLOBAL_VAR(wsrep_load_data_splitting),
5761        CMD_LINE(OPT_ARG), DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
5762        ON_CHECK(0), ON_UPDATE(0), DEPRECATED(""));
5763 
5764 static Sys_var_mybool Sys_wsrep_slave_FK_checks(
5765        "wsrep_slave_FK_checks", "Should slave thread do "
5766        "foreign key constraint checks",
5767        GLOBAL_VAR(wsrep_slave_FK_checks),
5768        CMD_LINE(OPT_ARG), DEFAULT(TRUE));
5769 
5770 static Sys_var_mybool Sys_wsrep_slave_UK_checks(
5771        "wsrep_slave_UK_checks", "Should slave thread do "
5772        "secondary index uniqueness checks",
5773        GLOBAL_VAR(wsrep_slave_UK_checks),
5774        CMD_LINE(OPT_ARG), DEFAULT(FALSE));
5775 
5776 static Sys_var_mybool Sys_wsrep_restart_slave(
5777        "wsrep_restart_slave", "Should MariaDB slave be restarted automatically, when node joins back to cluster",
5778        GLOBAL_VAR(wsrep_restart_slave), CMD_LINE(OPT_ARG), DEFAULT(FALSE));
5779 
5780 static Sys_var_ulonglong Sys_wsrep_trx_fragment_size(
5781       "wsrep_trx_fragment_size",
5782       "Size of transaction fragments for streaming replication (measured in "
5783       "units of 'wsrep_trx_fragment_unit')",
5784       SESSION_VAR(wsrep_trx_fragment_size), CMD_LINE(REQUIRED_ARG),
5785       VALID_RANGE(0, WSREP_MAX_WS_SIZE), DEFAULT(0), BLOCK_SIZE(1),
5786       NO_MUTEX_GUARD, NOT_IN_BINLOG,
5787       ON_CHECK(wsrep_trx_fragment_size_check),
5788       ON_UPDATE(wsrep_trx_fragment_size_update));
5789 
5790 extern const char *wsrep_fragment_units[];
5791 
5792 static Sys_var_enum Sys_wsrep_trx_fragment_unit(
5793       "wsrep_trx_fragment_unit",
5794       "Unit for streaming replication transaction fragments' size: bytes, "
5795       "rows, statements",
5796       SESSION_VAR(wsrep_trx_fragment_unit), CMD_LINE(REQUIRED_ARG),
5797       wsrep_fragment_units,
5798       DEFAULT(WSREP_FRAG_BYTES),
5799       NO_MUTEX_GUARD, NOT_IN_BINLOG,
5800       ON_CHECK(0),
5801       ON_UPDATE(wsrep_trx_fragment_unit_update));
5802 
5803 extern const char *wsrep_SR_store_types[];
5804 static Sys_var_enum Sys_wsrep_SR_store(
5805        "wsrep_SR_store", "Storage for streaming replication fragments",
5806        READ_ONLY GLOBAL_VAR(wsrep_SR_store_type), CMD_LINE(REQUIRED_ARG),
5807        wsrep_SR_store_types, DEFAULT(WSREP_SR_STORE_TABLE));
5808 
5809 static Sys_var_mybool Sys_wsrep_dirty_reads(
5810        "wsrep_dirty_reads",
5811        "Allow reads even when the node is not in the primary component.",
5812        SESSION_VAR(wsrep_dirty_reads), CMD_LINE(OPT_ARG),
5813        DEFAULT(FALSE));
5814 
5815 static Sys_var_uint Sys_wsrep_ignore_apply_errors (
5816        "wsrep_ignore_apply_errors", "Ignore replication errors",
5817        GLOBAL_VAR(wsrep_ignore_apply_errors), CMD_LINE(REQUIRED_ARG),
5818        VALID_RANGE(WSREP_IGNORE_ERRORS_NONE, WSREP_IGNORE_ERRORS_MAX),
5819        DEFAULT(7), BLOCK_SIZE(1));
5820 
5821 static Sys_var_uint Sys_wsrep_gtid_domain_id(
5822        "wsrep_gtid_domain_id", "When wsrep_gtid_mode is set, this value is "
5823        "used as gtid_domain_id for galera transactions and also copied to the "
5824        "joiner nodes during state transfer. It is ignored, otherwise.",
5825        GLOBAL_VAR(wsrep_gtid_domain_id), CMD_LINE(REQUIRED_ARG),
5826        VALID_RANGE(0, UINT_MAX32), DEFAULT(0), BLOCK_SIZE(1));
5827 
5828 static Sys_var_mybool Sys_wsrep_gtid_mode(
5829        "wsrep_gtid_mode", "Automatically update the (joiner) node's "
5830        "wsrep_gtid_domain_id value with that of donor's (received during "
5831        "state transfer) and use it in place of gtid_domain_id for all galera "
5832        "transactions. When OFF (default), wsrep_gtid_domain_id is simply "
5833        "ignored (backward compatibility).",
5834        GLOBAL_VAR(wsrep_gtid_mode), CMD_LINE(OPT_ARG), DEFAULT(FALSE));
5835 
5836 static char *wsrep_patch_version_ptr;
5837 static Sys_var_charptr Sys_wsrep_patch_version(
5838        "wsrep_patch_version", "Wsrep patch version, for example wsrep_25.10.",
5839        READ_ONLY GLOBAL_VAR(wsrep_patch_version_ptr), CMD_LINE_HELP_ONLY,
5840        IN_SYSTEM_CHARSET, DEFAULT(WSREP_PATCH_VERSION));
5841 
5842 #endif /* WITH_WSREP */
5843 
5844 static bool fix_host_cache_size(sys_var *, THD *, enum_var_type)
5845 {
5846   hostname_cache_resize((uint) host_cache_size);
5847   return false;
5848 }
5849 
5850 static Sys_var_ulong Sys_host_cache_size(
5851        "host_cache_size",
5852        "How many host names should be cached to avoid resolving.",
5853        AUTO_SET GLOBAL_VAR(host_cache_size),
5854        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 65536),
5855        DEFAULT(HOST_CACHE_SIZE),
5856        BLOCK_SIZE(1),
5857        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
5858        ON_UPDATE(fix_host_cache_size));
5859 
5860 vio_keepalive_opts opt_vio_keepalive;
5861 
5862 static Sys_var_int Sys_keepalive_time(
5863        "tcp_keepalive_time",
5864        "Timeout, in seconds, with no activity until the first TCP keep-alive packet is sent."
5865        "If set to 0, system dependent default is used.",
5866        AUTO_SET GLOBAL_VAR(opt_vio_keepalive.idle),
5867        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, INT_MAX32/1000), DEFAULT(0),
5868        BLOCK_SIZE(1));
5869 
5870 static Sys_var_int Sys_keepalive_interval(
5871        "tcp_keepalive_interval",
5872        "The interval, in seconds, between when successive keep-alive packets are sent if no acknowledgement is received."
5873        "If set to 0, system dependent default is used.",
5874        AUTO_SET GLOBAL_VAR(opt_vio_keepalive.interval),
5875        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, INT_MAX32/1000), DEFAULT(0),
5876        BLOCK_SIZE(1));
5877 
5878 static Sys_var_int Sys_keepalive_probes(
5879        "tcp_keepalive_probes",
5880        "The number of unacknowledged probes to send before considering the connection dead and notifying the application layer."
5881        "If set to 0, system dependent default is used.",
5882        AUTO_SET GLOBAL_VAR(opt_vio_keepalive.probes),
5883        CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, INT_MAX32/1000), DEFAULT(0),
5884        BLOCK_SIZE(1));
5885 
5886 
5887 static bool update_tcp_nodelay(sys_var *self, THD *thd,
5888   enum_var_type type)
5889 {
5890   DBUG_ASSERT(thd);
5891 
5892   Vio *vio = thd->net.vio;
5893   if (vio)
5894     return (MY_TEST(vio_nodelay(vio, thd->variables.tcp_nodelay)));
5895 
5896   return false;
5897 }
5898 
5899 static Sys_var_mybool Sys_tcp_nodelay(
5900        "tcp_nodelay",
5901        "Set option TCP_NODELAY (disable Nagle's algorithm) on socket",
5902        SESSION_VAR(tcp_nodelay), CMD_LINE(OPT_ARG),
5903        DEFAULT(TRUE),NO_MUTEX_GUARD, NOT_IN_BINLOG,
5904        ON_CHECK(check_session_only_variable),
5905        ON_UPDATE(update_tcp_nodelay));
5906 
5907 static Sys_var_charptr Sys_ignore_db_dirs(
5908        "ignore_db_dirs",
5909        "Specifies a directory to add to the ignore list when collecting "
5910        "database names from the datadir. Put a blank argument to reset "
5911        "the list accumulated so far.",
5912        READ_ONLY GLOBAL_VAR(opt_ignore_db_dirs),
5913        CMD_LINE(REQUIRED_ARG, OPT_IGNORE_DB_DIRECTORY),
5914        IN_FS_CHARSET, DEFAULT(0));
5915 
5916 static Sys_var_ulong Sys_sp_cache_size(
5917        "stored_program_cache",
5918        "The soft upper limit for number of cached stored routines for "
5919        "one connection.",
5920        GLOBAL_VAR(stored_program_cache_size), CMD_LINE(REQUIRED_ARG),
5921        VALID_RANGE(0, 512 * 1024), DEFAULT(256), BLOCK_SIZE(1));
5922 
5923 export const char *plugin_maturity_names[]=
5924 { "unknown", "experimental", "alpha", "beta", "gamma", "stable", 0 };
5925 static Sys_var_enum Sys_plugin_maturity(
5926        "plugin_maturity",
5927        "The lowest desirable plugin maturity. "
5928        "Plugins less mature than that will not be installed or loaded",
5929        READ_ONLY GLOBAL_VAR(plugin_maturity), CMD_LINE(REQUIRED_ARG),
5930        plugin_maturity_names,
5931        DEFAULT(SERVER_MATURITY_LEVEL > 0 ?
5932                SERVER_MATURITY_LEVEL - 1 : SERVER_MATURITY_LEVEL));
5933 
5934 static Sys_var_ulong Sys_deadlock_search_depth_short(
5935        "deadlock_search_depth_short",
5936        "Short search depth for the two-step deadlock detection",
5937        SESSION_VAR(wt_deadlock_search_depth_short), CMD_LINE(REQUIRED_ARG),
5938        VALID_RANGE(0, 32), DEFAULT(4), BLOCK_SIZE(1));
5939 
5940 static Sys_var_ulong Sys_deadlock_search_depth_long(
5941        "deadlock_search_depth_long",
5942        "Long search depth for the two-step deadlock detection",
5943        SESSION_VAR(wt_deadlock_search_depth_long), CMD_LINE(REQUIRED_ARG),
5944        VALID_RANGE(0, 33), DEFAULT(15), BLOCK_SIZE(1));
5945 
5946 static Sys_var_ulong Sys_deadlock_timeout_depth_short(
5947        "deadlock_timeout_short",
5948        "Short timeout for the two-step deadlock detection (in microseconds)",
5949        SESSION_VAR(wt_timeout_short), CMD_LINE(REQUIRED_ARG),
5950        VALID_RANGE(0, UINT_MAX), DEFAULT(10000), BLOCK_SIZE(1));
5951 
5952 static Sys_var_ulong Sys_deadlock_timeout_depth_long(
5953        "deadlock_timeout_long",
5954        "Long timeout for the two-step deadlock detection (in microseconds)",
5955        SESSION_VAR(wt_timeout_long), CMD_LINE(REQUIRED_ARG),
5956        VALID_RANGE(0, UINT_MAX), DEFAULT(50000000), BLOCK_SIZE(1));
5957 
5958 static Sys_var_uint Sys_extra_port(
5959        "extra_port",
5960        "Extra port number to use for tcp connections in a "
5961        "one-thread-per-connection manner. 0 means don't use another port",
5962        READ_ONLY GLOBAL_VAR(mysqld_extra_port), CMD_LINE(REQUIRED_ARG),
5963        VALID_RANGE(0, UINT_MAX32), DEFAULT(0), BLOCK_SIZE(1));
5964 
5965 static Sys_var_ulong Sys_extra_max_connections(
5966        "extra_max_connections", "The number of connections on extra-port",
5967        GLOBAL_VAR(extra_max_connections), CMD_LINE(REQUIRED_ARG),
5968        VALID_RANGE(1, 100000), DEFAULT(1), BLOCK_SIZE(1), NO_MUTEX_GUARD,
5969        NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(fix_max_connections));
5970 
5971 #ifdef SAFE_MUTEX
5972 static Sys_var_mybool Sys_mutex_deadlock_detector(
5973        "debug_mutex_deadlock_detector", "Enable checking of wrong mutex usage",
5974        READ_ONLY GLOBAL_VAR(safe_mutex_deadlock_detector),
5975        CMD_LINE(OPT_ARG), DEFAULT(TRUE));
5976 #endif
5977 
5978 static Sys_var_keycache Sys_key_cache_segments(
5979        "key_cache_segments", "The number of segments in a key cache",
5980        KEYCACHE_VAR(param_partitions),
5981        CMD_LINE(REQUIRED_ARG, OPT_KEY_CACHE_PARTITIONS),
5982        VALID_RANGE(0, MAX_KEY_CACHE_PARTITIONS),
5983        DEFAULT(DEFAULT_KEY_CACHE_PARTITIONS),
5984        BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
5985        ON_UPDATE(repartition_keycache));
5986 
5987 static const char *log_slow_filter_names[]=
5988 {
5989   "admin", "filesort", "filesort_on_disk", "filesort_priority_queue",
5990   "full_join", "full_scan", "not_using_index", "query_cache",
5991   "query_cache_miss", "tmp_table", "tmp_table_on_disk", 0
5992 };
5993 
5994 
5995 static Sys_var_set Sys_log_slow_filter(
5996        "log_slow_filter",
5997        "Log only certain types of queries to the slow log. If variable empty alll kind of queries are logged.  All types are bound by slow_query_time, except 'not_using_index' which is always logged if enabled",
5998        SESSION_VAR(log_slow_filter), CMD_LINE(REQUIRED_ARG),
5999        log_slow_filter_names,
6000        /* by default we log all queries except 'not_using_index' */
6001        DEFAULT(my_set_bits(array_elements(log_slow_filter_names)-1) &
6002                ~QPLAN_NOT_USING_INDEX));
6003 
6004 static const char *log_slow_disabled_statements_names[]=
6005 { "admin", "call", "slave", "sp", 0 };
6006 
6007 static const char *log_disabled_statements_names[]=
6008 { "slave", "sp", 0 };
6009 
6010 static Sys_var_set Sys_log_slow_disabled_statements(
6011        "log_slow_disabled_statements",
6012        "Don't log certain types of statements to slow log",
6013        SESSION_VAR(log_slow_disabled_statements), CMD_LINE(REQUIRED_ARG),
6014        log_slow_disabled_statements_names,
6015        DEFAULT(LOG_SLOW_DISABLE_SP));
6016 
6017 static Sys_var_set Sys_log_disabled_statements(
6018        "log_disabled_statements",
6019        "Don't log certain types of statements to general log",
6020        SESSION_VAR(log_disabled_statements), CMD_LINE(REQUIRED_ARG),
6021        log_disabled_statements_names,
6022        DEFAULT(LOG_DISABLE_SP),
6023        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_has_super));
6024 
6025 static const char *default_regex_flags_names[]=
6026 {
6027   "DOTALL",    // (?s)  . matches anything including NL
6028   "DUPNAMES",  // (?J)  Allow duplicate names for subpatterns
6029   "EXTENDED",  // (?x)  Ignore white space and # comments
6030   "EXTRA",     // (?X)  extra features (e.g. error on unknown escape character)
6031   "MULTILINE", // (?m)  ^ and $ match newlines within data
6032   "UNGREEDY",  // (?U)  Invert greediness of quantifiers
6033   0
6034 };
6035 static const int default_regex_flags_to_pcre[]=
6036 {
6037   PCRE_DOTALL,
6038   PCRE_DUPNAMES,
6039   PCRE_EXTENDED,
6040   PCRE_EXTRA,
6041   PCRE_MULTILINE,
6042   PCRE_UNGREEDY,
6043   0
6044 };
6045 int default_regex_flags_pcre(const THD *thd)
6046 {
6047   ulonglong src= thd->variables.default_regex_flags;
6048   int i, res;
6049   for (i= res= 0; default_regex_flags_to_pcre[i]; i++)
6050   {
6051     if (src & (1ULL << i))
6052       res|= default_regex_flags_to_pcre[i];
6053   }
6054   return res;
6055 }
6056 static Sys_var_set Sys_default_regex_flags(
6057        "default_regex_flags",
6058        "Default flags for the regex library",
6059        SESSION_VAR(default_regex_flags), CMD_LINE(REQUIRED_ARG),
6060        default_regex_flags_names,
6061        DEFAULT(0));
6062 
6063 static Sys_var_ulong Sys_log_slow_rate_limit(
6064        "log_slow_rate_limit",
6065        "Write to slow log every #th slow query. Set to 1 to log everything. "
6066        "Increase it to reduce the size of the slow or the performance impact "
6067        "of slow logging",
6068        SESSION_VAR(log_slow_rate_limit), CMD_LINE(REQUIRED_ARG),
6069        VALID_RANGE(1, UINT_MAX), DEFAULT(1), BLOCK_SIZE(1));
6070 
6071 static const char *log_slow_verbosity_names[]= { "innodb", "query_plan",
6072                                                  "explain", 0 };
6073 static Sys_var_set Sys_log_slow_verbosity(
6074        "log_slow_verbosity",
6075        "Verbosity level for the slow log",
6076        SESSION_VAR(log_slow_verbosity), CMD_LINE(REQUIRED_ARG),
6077        log_slow_verbosity_names, DEFAULT(LOG_SLOW_VERBOSITY_INIT));
6078 
6079 static Sys_var_ulong Sys_join_cache_level(
6080        "join_cache_level",
6081        "Controls what join operations can be executed with join buffers. Odd "
6082        "numbers are used for plain join buffers while even numbers are used "
6083        "for linked buffers",
6084        SESSION_VAR(join_cache_level), CMD_LINE(REQUIRED_ARG),
6085        VALID_RANGE(0, 8), DEFAULT(2), BLOCK_SIZE(1));
6086 
6087 static Sys_var_ulong Sys_mrr_buffer_size(
6088        "mrr_buffer_size",
6089        "Size of buffer to use when using MRR with range access",
6090        SESSION_VAR(mrr_buff_size), CMD_LINE(REQUIRED_ARG),
6091        VALID_RANGE(IO_SIZE*2, INT_MAX32), DEFAULT(256*1024), BLOCK_SIZE(1));
6092 
6093 static Sys_var_ulong Sys_rowid_merge_buff_size(
6094        "rowid_merge_buff_size",
6095        "The size of the buffers used [NOT] IN evaluation via partial matching",
6096        SESSION_VAR(rowid_merge_buff_size), CMD_LINE(REQUIRED_ARG),
6097        VALID_RANGE(0, LONG_MAX), DEFAULT(8*1024*1024),
6098        BLOCK_SIZE(1));
6099 
6100 static Sys_var_mybool Sys_userstat(
6101        "userstat",
6102        "Enables statistics gathering for USER_STATISTICS, CLIENT_STATISTICS, "
6103        "INDEX_STATISTICS and TABLE_STATISTICS tables in the INFORMATION_SCHEMA",
6104        GLOBAL_VAR(opt_userstat_running),
6105        CMD_LINE(OPT_ARG), DEFAULT(FALSE));
6106 
6107 static Sys_var_mybool Sys_binlog_annotate_row_events(
6108        "binlog_annotate_row_events",
6109        "Tells the master to annotate RBR events with the statement that "
6110        "caused these events",
6111        SESSION_VAR(binlog_annotate_row_events), CMD_LINE(OPT_ARG),
6112        DEFAULT(TRUE));
6113 
6114 #ifdef HAVE_REPLICATION
6115 static Sys_var_mybool Sys_replicate_annotate_row_events(
6116        "replicate_annotate_row_events",
6117        "Tells the slave to write annotate rows events received from the master "
6118        "to its own binary log. Ignored if log_slave_updates is not set",
6119        READ_ONLY GLOBAL_VAR(opt_replicate_annotate_row_events),
6120        CMD_LINE(OPT_ARG), DEFAULT(TRUE));
6121 #endif
6122 
6123 static Sys_var_ulonglong Sys_join_buffer_space_limit(
6124        "join_buffer_space_limit",
6125        "The limit of the space for all join buffers used by a query",
6126        SESSION_VAR(join_buff_space_limit), CMD_LINE(REQUIRED_ARG),
6127        VALID_RANGE(2048, ULONGLONG_MAX), DEFAULT(16*128*1024),
6128        BLOCK_SIZE(2048));
6129 
6130 static Sys_var_ulong Sys_progress_report_time(
6131        "progress_report_time",
6132        "Seconds between sending progress reports to the client for "
6133        "time-consuming statements. Set to 0 to disable progress reporting.",
6134        SESSION_VAR(progress_report_time), CMD_LINE(REQUIRED_ARG),
6135        VALID_RANGE(0, UINT_MAX), DEFAULT(5), BLOCK_SIZE(1));
6136 
6137 const char *use_stat_tables_modes[] =
6138            {"NEVER", "COMPLEMENTARY", "PREFERABLY",
6139            "COMPLEMENTARY_FOR_QUERIES", "PREFERABLY_FOR_QUERIES", 0};
6140 static Sys_var_enum Sys_optimizer_use_stat_tables(
6141        "use_stat_tables",
6142        "Specifies how to use system statistics tables",
6143        SESSION_VAR(use_stat_tables), CMD_LINE(REQUIRED_ARG),
6144        use_stat_tables_modes, DEFAULT(4));
6145 
6146 static Sys_var_ulong Sys_histogram_size(
6147        "histogram_size",
6148        "Number of bytes used for a histogram. "
6149        "If set to 0, no histograms are created by ANALYZE.",
6150        SESSION_VAR(histogram_size), CMD_LINE(REQUIRED_ARG),
6151        VALID_RANGE(0, 255), DEFAULT(254), BLOCK_SIZE(1));
6152 
6153 extern const char *histogram_types[];
6154 static Sys_var_enum Sys_histogram_type(
6155        "histogram_type",
6156        "Specifies type of the histograms created by ANALYZE. "
6157        "Possible values are: "
6158        "SINGLE_PREC_HB - single precision height-balanced, "
6159        "DOUBLE_PREC_HB - double precision height-balanced.",
6160        SESSION_VAR(histogram_type), CMD_LINE(REQUIRED_ARG),
6161        histogram_types, DEFAULT(1));
6162 
6163 static Sys_var_mybool Sys_no_thread_alarm(
6164        "debug_no_thread_alarm",
6165        "Disable system thread alarm calls. Disabling it may be useful "
6166        "in debugging or testing, never do it in production",
6167        READ_ONLY GLOBAL_VAR(my_disable_thr_alarm), CMD_LINE(OPT_ARG),
6168        DEFAULT(FALSE));
6169 
6170 static Sys_var_mybool Sys_query_cache_strip_comments(
6171        "query_cache_strip_comments",
6172        "Strip all comments from a query before storing it "
6173        "in the query cache",
6174        SESSION_VAR(query_cache_strip_comments), CMD_LINE(OPT_ARG),
6175        DEFAULT(FALSE));
6176 
6177 static ulonglong in_transaction(THD *thd)
6178 {
6179   return MY_TEST(thd->in_active_multi_stmt_transaction());
6180 }
6181 static Sys_var_session_special Sys_in_transaction(
6182        "in_transaction", "Whether there is an active transaction",
6183        READ_ONLY sys_var::ONLY_SESSION, NO_CMD_LINE,
6184        VALID_RANGE(0, 1), BLOCK_SIZE(1), NO_MUTEX_GUARD,
6185        NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0), ON_READ(in_transaction));
6186 
6187 #ifndef DBUG_OFF
6188 static Sys_var_ulong Sys_debug_binlog_fsync_sleep(
6189        "debug_binlog_fsync_sleep",
6190        "Extra sleep (in microseconds) to add to binlog fsync(), for debugging",
6191        GLOBAL_VAR(opt_binlog_dbug_fsync_sleep),
6192        CMD_LINE(REQUIRED_ARG),
6193        VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1));
6194 #endif
6195 
6196 static Sys_var_harows Sys_expensive_subquery_limit(
6197        "expensive_subquery_limit",
6198        "The maximum number of rows a subquery may examine in order to be "
6199        "executed during optimization and used for constant optimization",
6200        SESSION_VAR(expensive_subquery_limit), CMD_LINE(REQUIRED_ARG),
6201        VALID_RANGE(0, HA_POS_ERROR), DEFAULT(100), BLOCK_SIZE(1));
6202 
6203 static Sys_var_mybool Sys_encrypt_tmp_disk_tables(
6204        "encrypt_tmp_disk_tables",
6205        "Encrypt temporary on-disk tables (created as part of query execution)",
6206        GLOBAL_VAR(encrypt_tmp_disk_tables),
6207        CMD_LINE(OPT_ARG), DEFAULT(FALSE));
6208 
6209 static Sys_var_mybool Sys_encrypt_tmp_files(
6210        "encrypt_tmp_files",
6211        "Encrypt temporary files (created for filesort, binary log cache, etc)",
6212        READ_ONLY GLOBAL_VAR(encrypt_tmp_files),
6213        CMD_LINE(OPT_ARG), DEFAULT(FALSE));
6214 
6215 static Sys_var_mybool Sys_binlog_encryption(
6216        "encrypt_binlog", "Encrypt binary logs (including relay logs)",
6217        READ_ONLY GLOBAL_VAR(encrypt_binlog), CMD_LINE(OPT_ARG),
6218        DEFAULT(FALSE));
6219 
6220 static const char *binlog_row_image_names[]= {"MINIMAL", "NOBLOB", "FULL", NullS};
6221 static Sys_var_enum Sys_binlog_row_image(
6222        "binlog_row_image",
6223        "Controls whether rows should be logged in 'FULL', 'NOBLOB' or "
6224        "'MINIMAL' formats. 'FULL', means that all columns in the before "
6225        "and after image are logged. 'NOBLOB', means that mysqld avoids logging "
6226        "blob columns whenever possible (eg, blob column was not changed or "
6227        "is not part of primary key). 'MINIMAL', means that a PK equivalent (PK "
6228        "columns or full row if there is no PK in the table) is logged in the "
6229        "before image, and only changed columns are logged in the after image. "
6230        "(Default: FULL).",
6231        SESSION_VAR(binlog_row_image), CMD_LINE(REQUIRED_ARG),
6232        binlog_row_image_names, DEFAULT(BINLOG_ROW_IMAGE_FULL));
6233 
6234 static bool check_pseudo_slave_mode(sys_var *self, THD *thd, set_var *var)
6235 {
6236   longlong previous_val= thd->variables.pseudo_slave_mode;
6237   longlong val= (longlong) var->save_result.ulonglong_value;
6238   bool rli_fake= false;
6239 
6240 #ifndef EMBEDDED_LIBRARY
6241   rli_fake= thd->rli_fake ? true : false;
6242 #endif
6243 
6244   if (rli_fake)
6245   {
6246     if (!val)
6247     {
6248 #ifndef EMBEDDED_LIBRARY
6249       delete thd->rli_fake;
6250       thd->rli_fake= NULL;
6251       delete thd->rgi_fake;
6252       thd->rgi_fake= NULL;
6253 #endif
6254     }
6255     else if (previous_val && val)
6256       goto ineffective;
6257     else if (!previous_val && val)
6258       push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
6259                    ER_WRONG_VALUE_FOR_VAR,
6260                    "'pseudo_slave_mode' is already ON.");
6261   }
6262   else
6263   {
6264     if (!previous_val && !val)
6265       goto ineffective;
6266     else if (previous_val && !val)
6267       push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
6268                    ER_WRONG_VALUE_FOR_VAR,
6269                    "Slave applier execution mode not active, "
6270                    "statement ineffective.");
6271   }
6272   goto end;
6273 
6274 ineffective:
6275   push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
6276                ER_WRONG_VALUE_FOR_VAR,
6277                "'pseudo_slave_mode' change was ineffective.");
6278 
6279 end:
6280   return FALSE;
6281 }
6282 static Sys_var_mybool Sys_pseudo_slave_mode(
6283        "pseudo_slave_mode",
6284        "SET pseudo_slave_mode= 0,1 are commands that mysqlbinlog "
6285        "adds to beginning and end of binary log dumps. While zero "
6286        "value indeed disables, the actual enabling of the slave "
6287        "applier execution mode is done implicitly when a "
6288        "Format_description_event is sent through the session.",
6289        SESSION_ONLY(pseudo_slave_mode), NO_CMD_LINE, DEFAULT(FALSE),
6290        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_pseudo_slave_mode));
6291 
6292 static Sys_var_mybool Sys_mysql56_temporal_format(
6293        "mysql56_temporal_format",
6294        "Use MySQL-5.6 (instead of MariaDB-5.3) format for TIME, DATETIME, TIMESTAMP columns.",
6295        GLOBAL_VAR(opt_mysql56_temporal_format),
6296        CMD_LINE(OPT_ARG), DEFAULT(TRUE));
6297 
6298 static Sys_var_mybool Sys_strict_password_validation(
6299        "strict_password_validation",
6300        "When password validation plugins are enabled, reject passwords "
6301        "that cannot be validated (passwords specified as a hash)",
6302        GLOBAL_VAR(strict_password_validation),
6303        CMD_LINE(OPT_ARG), DEFAULT(TRUE));
6304 
6305 #ifdef HAVE_MMAP
6306 static Sys_var_ulong Sys_log_tc_size(
6307        "log_tc_size",
6308        "Size of transaction coordinator log.",
6309        READ_ONLY GLOBAL_VAR(opt_tc_log_size),
6310        CMD_LINE(REQUIRED_ARG),
6311        VALID_RANGE(my_getpagesize() * 3, ULONG_MAX),
6312        DEFAULT(my_getpagesize() * 6),
6313        BLOCK_SIZE(my_getpagesize()));
6314 #endif
6315 
6316 static Sys_var_ulonglong Sys_max_thread_mem(
6317        "max_session_mem_used", "Amount of memory a single user session "
6318        "is allowed to allocate. This limits the value of the "
6319        "session variable MEM_USED", SESSION_VAR(max_mem_used),
6320        CMD_LINE(REQUIRED_ARG), VALID_RANGE(8192,  ULONGLONG_MAX),
6321        DEFAULT(LONGLONG_MAX), BLOCK_SIZE(1));
6322 
6323 #ifndef EMBEDDED_LIBRARY
6324 
6325 static Sys_var_sesvartrack Sys_track_session_sys_vars(
6326        "session_track_system_variables",
6327        "Track changes in registered system variables. ",
6328        CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET,
6329        DEFAULT("autocommit,character_set_client,character_set_connection,"
6330        "character_set_results,time_zone"));
6331 
6332 static bool update_session_track_schema(sys_var *self, THD *thd,
6333                                         enum_var_type type)
6334 {
6335   DBUG_ENTER("update_session_track_schema");
6336   DBUG_RETURN(thd->session_tracker.current_schema.update(thd, NULL));
6337 }
6338 
6339 static Sys_var_mybool Sys_session_track_schema(
6340        "session_track_schema",
6341        "Track changes to the default schema.",
6342        SESSION_VAR(session_track_schema),
6343        CMD_LINE(OPT_ARG), DEFAULT(TRUE),
6344        NO_MUTEX_GUARD, NOT_IN_BINLOG,
6345        ON_CHECK(0),
6346        ON_UPDATE(update_session_track_schema));
6347 
6348 
6349 static bool update_session_track_tx_info(sys_var *self, THD *thd,
6350                                          enum_var_type type)
6351 {
6352   DBUG_ENTER("update_session_track_tx_info");
6353   DBUG_RETURN(thd->session_tracker.transaction_info.update(thd, NULL));
6354 }
6355 
6356 static const char *session_track_transaction_info_names[]=
6357   { "OFF", "STATE", "CHARACTERISTICS", NullS };
6358 
6359 static Sys_var_enum Sys_session_track_transaction_info(
6360        "session_track_transaction_info",
6361        "Track changes to the transaction attributes. OFF to disable; "
6362        "STATE to track just transaction state (Is there an active transaction? "
6363        "Does it have any data? etc.); CHARACTERISTICS to track transaction "
6364        "state and report all statements needed to start a transaction with "
6365        "the same characteristics (isolation level, read only/read write,"
6366        "snapshot - but not any work done / data modified within the "
6367        "transaction).",
6368        SESSION_VAR(session_track_transaction_info),
6369        CMD_LINE(REQUIRED_ARG), session_track_transaction_info_names,
6370        DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
6371        ON_UPDATE(update_session_track_tx_info));
6372 
6373 
6374 static bool update_session_track_state_change(sys_var *self, THD *thd,
6375                                               enum_var_type type)
6376 {
6377   DBUG_ENTER("update_session_track_state_change");
6378   DBUG_RETURN(thd->session_tracker.state_change.update(thd, NULL));
6379 }
6380 
6381 static Sys_var_mybool Sys_session_track_state_change(
6382        "session_track_state_change",
6383        "Track changes to the session state.",
6384        SESSION_VAR(session_track_state_change),
6385        CMD_LINE(OPT_ARG), DEFAULT(FALSE),
6386        NO_MUTEX_GUARD, NOT_IN_BINLOG,
6387        ON_CHECK(0),
6388        ON_UPDATE(update_session_track_state_change));
6389 
6390 #endif //EMBEDDED_LIBRARY
6391 
6392 static Sys_var_uint Sys_in_subquery_conversion_threshold(
6393        "in_predicate_conversion_threshold",
6394        "The minimum number of scalar elements in the value list of "
6395        "IN predicate that triggers its conversion to IN subquery. Set to "
6396        "0 to disable the conversion.",
6397        SESSION_VAR(in_subquery_conversion_threshold), CMD_LINE(REQUIRED_ARG),
6398        VALID_RANGE(0, UINT_MAX), DEFAULT(IN_SUBQUERY_CONVERSION_THRESHOLD), BLOCK_SIZE(1));
6399 
6400 static Sys_var_enum Sys_secure_timestamp(
6401        "secure_timestamp", "Restricts direct setting of a session "
6402        "timestamp. Possible levels are: YES - timestamp cannot deviate from "
6403        "the system clock, REPLICATION - replication thread can adjust "
6404        "timestamp to match the master's, SUPER - a user with this "
6405        "privilege and a replication thread can adjust timestamp, NO - "
6406        "historical behavior, anyone can modify session timestamp",
6407        READ_ONLY GLOBAL_VAR(opt_secure_timestamp), CMD_LINE(REQUIRED_ARG),
6408        secure_timestamp_levels, DEFAULT(SECTIME_NO));
6409 
6410 static Sys_var_ulonglong Sys_max_rowid_filter_size(
6411        "max_rowid_filter_size",
6412        "The maximum size of the container of a rowid filter",
6413        SESSION_VAR(max_rowid_filter_size), CMD_LINE(REQUIRED_ARG),
6414        VALID_RANGE(1024, (ulonglong)~(intptr)0), DEFAULT(128*1024),
6415        BLOCK_SIZE(1));
6416