1 /* Copyright (c) 2000, 2021, Oracle and/or its affiliates.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 #include "mysqld.h"
24 #include "mysqld_daemon.h"
25 
26 #include <vector>
27 #include <algorithm>
28 #include <functional>
29 #include <list>
30 #include <set>
31 #include <string>
32 
33 #include <fenv.h>
34 #include <signal.h>
35 #ifdef HAVE_SYS_WAIT_H
36 #include <sys/wait.h>
37 #endif
38 #ifdef HAVE_PWD_H
39 #include <pwd.h>
40 #endif
41 #ifdef HAVE_GRP_H
42 #include <grp.h>
43 #endif
44 #ifdef HAVE_SYS_RESOURCE_H
45 #include <sys/resource.h>
46 #endif
47 #ifdef _WIN32
48 #include <crtdbg.h>
49 #endif
50 
51 #include <sys/types.h>
52 #ifdef HAVE_SYS_MMAN_H
53 #include <sys/mman.h>
54 #endif
55 
56 #include "sql_parse.h"    // test_if_data_home_dir
57 #include "sql_cache.h"    // query_cache, query_cache_*
58 #include "sql_locale.h"   // MY_LOCALES, my_locales, my_locale_by_name
59 #include "sql_show.h"     // free_status_vars, add_status_vars,
60                           // reset_status_vars
61 #include "strfunc.h"      // find_set_from_flags
62 #include "parse_file.h"   // File_parser_dummy_hook
63 #include "sql_db.h"       // my_dboptions_cache_free
64                           // my_dboptions_cache_init
65 #include "sql_table.h"    // release_ddl_log, execute_ddl_log_recovery
66 #include "sql_connect.h"  // free_max_user_conn, init_max_user_conn,
67                           // handle_one_connection
68 #include "sql_time.h"     // known_date_time_formats,
69                           // get_date_time_format_str
70 #include "tztime.h"       // my_tz_free, my_tz_init, my_tz_SYSTEM
71 #include "hostname.h"     // hostname_cache_free, hostname_cache_init
72 #include "auth_common.h"  // set_default_auth_plugin
73                           // acl_free, acl_init
74                           // grant_free, grant_init
75 #include "sql_base.h"     // table_def_free, table_def_init,
76                           // Table_cache,
77                           // cached_table_definitions
78 #include "sql_test.h"     // mysql_print_status
79 #include "item_create.h"  // item_create_cleanup, item_create_init
80 #include "sql_servers.h"  // servers_free, servers_init
81 #include "init.h"         // unireg_init
82 #include "derror.h"       // init_errmessage
83 #include "des_key_file.h" // load_des_key_file
84 #include "sql_manager.h"  // stop_handle_manager, start_handle_manager
85 #include "bootstrap.h"    // bootstrap
86 #include <m_ctype.h>
87 #include <my_dir.h>
88 #include <my_bit.h>
89 #include "rpl_gtid.h"
90 #include "rpl_gtid_persist.h"
91 #include "rpl_slave.h"
92 #include "rpl_msr.h"
93 #include "rpl_master.h"
94 #include "rpl_mi.h"
95 #include "rpl_filter.h"
96 #include <sql_common.h>
97 #include <my_stacktrace.h>
98 #include "mysqld_suffix.h"
99 #include "mysys_err.h"
100 #include "events.h"
101 #include "sql_audit.h"
102 #include "probes_mysql.h"
103 #include "debug_sync.h"
104 #include "sql_callback.h"
105 #include "opt_trace_context.h"
106 #include "opt_costconstantcache.h"
107 #include "sql_plugin.h"                         // plugin_shutdown
108 #include "sql_initialize.h"
109 #include "log_event.h"
110 #include "log.h"
111 #include "binlog.h"
112 #include "rpl_rli.h"     // Relay_log_info
113 #include "replication.h" // thd_enter_cond
114 
115 #include "my_default.h"
116 #include "mysql_version.h"
117 
118 #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
119 #include "../storage/perfschema/pfs_server.h"
120 #include <pfs_idle_provider.h>
121 #endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
122 
123 #include "pfs_file_provider.h"
124 #include "mysql/psi/mysql_file.h"
125 
126 #include <mysql/psi/mysql_idle.h>
127 #include <mysql/psi/mysql_socket.h>
128 #include <mysql/psi/mysql_memory.h>
129 #include <mysql/psi/mysql_statement.h>
130 
131 #include "migrate_keyring.h"            // Migrate_keyring
132 #include "mysql_com_server.h"
133 #include "keycaches.h"
134 #include "../storage/myisam/ha_myisam.h"
135 #include "set_var.h"
136 #include "sys_vars_shared.h"
137 #include "rpl_injector.h"
138 #include "rpl_handler.h"
139 #include <ft_global.h>
140 #include <errmsg.h>
141 #include "sp_rcontext.h"
142 #include "sql_reload.h"  // reload_acl_and_cache
143 #include "sp_head.h"  // init_sp_psi_keys
144 #include "event_data_objects.h" //init_scheduler_psi_keys
145 #include "my_timer.h"    // my_timer_init, my_timer_deinit
146 #include "table_cache.h"                // table_cache_manager
147 #include "connection_acceptor.h"        // Connection_acceptor
148 #include "connection_handler_impl.h"    // *_connection_handler
149 #include "connection_handler_manager.h" // Connection_handler_manager
150 #include "socket_connection.h"          // Mysqld_socket_listener
151 #include "mysqld_thd_manager.h"         // Global_THD_manager
152 #include "my_getopt.h"
153 #include "partitioning/partition_handler.h" // partitioning_init
154 #include "item_cmpfunc.h"               // arg_cmp_func
155 #include "item_strfunc.h"               // Item_func_uuid
156 #include "handler.h"
157 
158 #ifndef EMBEDDED_LIBRARY
159 #include "srv_session.h"
160 #endif
161 
162 #ifdef _WIN32
163 #include "named_pipe.h"
164 #include "named_pipe_connection.h"
165 #include "shared_memory_connection.h"
166 #endif
167 
168 using std::min;
169 using std::max;
170 using std::vector;
171 
172 #define mysqld_charset &my_charset_latin1
173 
174 #ifdef HAVE_FPU_CONTROL_H
175 # include <fpu_control.h>
176 #elif defined(__i386__)
177 # define fpu_control_t unsigned int
178 # define _FPU_EXTENDED 0x300
179 # define _FPU_DOUBLE 0x200
180 # if defined(__GNUC__) || defined(__SUNPRO_CC)
181 #  define _FPU_GETCW(cw) asm volatile ("fnstcw %0" : "=m" (*&cw))
182 #  define _FPU_SETCW(cw) asm volatile ("fldcw %0" : : "m" (*&cw))
183 # else
184 #  define _FPU_GETCW(cw) (cw= 0)
185 #  define _FPU_SETCW(cw)
186 # endif
187 #endif
188 
setup_fpu()189 inline void setup_fpu()
190 {
191 #ifdef HAVE_FEDISABLEEXCEPT
192   fedisableexcept(FE_ALL_EXCEPT);
193 #endif
194 
195   /* Set FPU rounding mode to "round-to-nearest" */
196   fesetround(FE_TONEAREST);
197 
198   /*
199     x86 (32-bit) requires FPU precision to be explicitly set to 64 bit
200     (double precision) for portable results of floating point operations.
201     However, there is no need to do so if compiler is using SSE2 for floating
202     point, double values will be stored and processed in 64 bits anyway.
203   */
204 #if defined(__i386__) && !defined(__SSE2_MATH__)
205 #if defined(_WIN32)
206 #if !defined(_WIN64)
207   _control87(_PC_53, MCW_PC);
208 #endif /* !_WIN64 */
209 #else /* !_WIN32 */
210   fpu_control_t cw;
211   _FPU_GETCW(cw);
212   cw= (cw & ~_FPU_EXTENDED) | _FPU_DOUBLE;
213   _FPU_SETCW(cw);
214 #endif /* _WIN32 && */
215 #endif /* __i386__ */
216 
217 }
218 
219 #ifndef EMBEDDED_LIBRARY
220 extern "C" void handle_fatal_signal(int sig);
221 #endif
222 
223 /* Constants */
224 
225 #include <welcome_copyright_notice.h> // ORACLE_WELCOME_COPYRIGHT_NOTICE
226 
227 const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"};
228 
229 static const char *tc_heuristic_recover_names[]=
230 {
231   "OFF", "COMMIT", "ROLLBACK", NullS
232 };
233 static TYPELIB tc_heuristic_recover_typelib=
234 {
235   array_elements(tc_heuristic_recover_names)-1,"",
236   tc_heuristic_recover_names, NULL
237 };
238 
239 const char *first_keyword= "first", *binary_keyword= "BINARY";
240 const char *my_localhost= "localhost";
241 
242 bool opt_large_files= sizeof(my_off_t) > 4;
243 static my_bool opt_autocommit; ///< for --autocommit command-line option
244 
245 /*
246   Used with --help for detailed option
247 */
248 my_bool opt_help= 0, opt_verbose= 0;
249 
250 arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
251 {{&Arg_comparator::compare_string,     &Arg_comparator::compare_e_string},
252  {&Arg_comparator::compare_real,       &Arg_comparator::compare_e_real},
253  {&Arg_comparator::compare_int_signed, &Arg_comparator::compare_e_int},
254  {&Arg_comparator::compare_row,        &Arg_comparator::compare_e_row},
255  {&Arg_comparator::compare_decimal,    &Arg_comparator::compare_e_decimal}};
256 
257 #ifdef HAVE_PSI_INTERFACE
258 #ifndef EMBEDDED_LIBRARY
259 #if defined(_WIN32)
260 static PSI_thread_key key_thread_handle_con_namedpipes;
261 static PSI_thread_key key_thread_handle_con_sharedmem;
262 static PSI_thread_key key_thread_handle_con_sockets;
263 static PSI_mutex_key key_LOCK_handler_count;
264 static PSI_cond_key key_COND_handler_count;
265 static PSI_thread_key key_thread_handle_shutdown;
266 static PSI_rwlock_key key_rwlock_LOCK_named_pipe_full_access_group;
267 #else
268 static PSI_mutex_key key_LOCK_socket_listener_active;
269 static PSI_cond_key key_COND_socket_listener_active;
270 static PSI_mutex_key key_LOCK_start_signal_handler;
271 static PSI_cond_key key_COND_start_signal_handler;
272 #endif // _WIN32
273 #endif // !EMBEDDED_LIBRARY
274 #endif /* HAVE_PSI_INTERFACE */
275 
276 /**
277   Statement instrumentation key for replication.
278 */
279 #ifdef HAVE_PSI_STATEMENT_INTERFACE
280 PSI_statement_info stmt_info_rpl;
281 #endif
282 
283 /* the default log output is log tables */
284 static bool lower_case_table_names_used= 0;
285 #if !defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
286 static bool socket_listener_active= false;
287 static int pipe_write_fd= -1;
288 static my_bool opt_daemonize= 0;
289 #endif
290 static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0;
291 static my_bool opt_short_log_format= 0;
292 static char *mysqld_user, *mysqld_chroot;
293 static char *default_character_set_name;
294 static char *character_set_filesystem_name;
295 static char *lc_messages;
296 static char *lc_time_names_name;
297 char *my_bind_addr_str;
298 static char *default_collation_name;
299 char *default_storage_engine;
300 char *default_tmp_storage_engine;
301 /**
302    Use to mark which engine should be choosen to create internal
303    temp table
304  */
305 ulong internal_tmp_disk_storage_engine;
306 static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME;
307 static bool binlog_format_used= false;
308 
309 LEX_STRING opt_init_connect, opt_init_slave;
310 
311 /* Global variables */
312 
313 bool opt_bin_log, opt_ignore_builtin_innodb= 0;
314 bool opt_general_log, opt_slow_log, opt_general_log_raw;
315 ulonglong log_output_options;
316 my_bool opt_log_queries_not_using_indexes= 0;
317 ulong opt_log_throttle_queries_not_using_indexes= 0;
318 bool opt_disable_networking=0, opt_skip_show_db=0;
319 bool opt_skip_name_resolve=0;
320 my_bool opt_character_set_client_handshake= 1;
321 bool server_id_supplied = false;
322 bool opt_endinfo, using_udf_functions;
323 my_bool locked_in_memory;
324 bool opt_using_transactions;
325 bool volatile abort_loop;
326 ulong opt_tc_log_size;
327 
328 static enum_server_operational_state server_operational_state= SERVER_BOOTING;
329 ulong log_warnings;
330 bool  opt_log_syslog_enable;
331 char *opt_log_syslog_tag= NULL;
332 char *opt_keyring_migration_user= NULL;
333 char *opt_keyring_migration_host= NULL;
334 char *opt_keyring_migration_password= NULL;
335 char *opt_keyring_migration_socket= NULL;
336 char *opt_keyring_migration_source= NULL;
337 char *opt_keyring_migration_destination= NULL;
338 ulong opt_keyring_migration_port= 0;
339 bool migrate_connect_options= 0;
340 #ifndef _WIN32
341 bool  opt_log_syslog_include_pid;
342 char *opt_log_syslog_facility;
343 
344 #else
345 /*
346   Thread handle of shutdown event handler thread.
347   It is used as argument during thread join.
348 */
349 my_thread_handle shutdown_thr_handle;
350 #endif
351 uint host_cache_size;
352 ulong log_error_verbosity= 3; // have a non-zero value during early start-up
353 
354 #if MYSQL_VERSION_ID >= 50800
355 #error "show_compatibility_56 is to be removed in MySQL 5.8"
356 #else
357 /*
358   Default value TRUE for the EMBEDDED_LIBRARY,
359   default value from Sys_show_compatibility_56 otherwise.
360 */
361 my_bool show_compatibility_56= TRUE;
362 #endif /* MYSQL_VERSION_ID >= 50800 */
363 
364 #if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
365 ulong slow_start_timeout;
366 #endif
367 
368 my_bool opt_bootstrap= 0;
369 my_bool opt_initialize= 0;
370 my_bool opt_disable_partition_check= TRUE;
371 my_bool opt_skip_slave_start = 0; ///< If set, slave is not autostarted
372 my_bool opt_reckless_slave = 0;
373 my_bool opt_enable_named_pipe= 0;
374 my_bool opt_local_infile, opt_slave_compressed_protocol;
375 my_bool opt_safe_user_create = 0;
376 my_bool opt_show_slave_auth_info;
377 my_bool opt_log_slave_updates= 0;
378 char *opt_slave_skip_errors;
379 my_bool opt_slave_allow_batching= 0;
380 
381 /**
382   compatibility option:
383     - index usage hints (USE INDEX without a FOR clause) behave as in 5.0
384 */
385 my_bool old_mode;
386 
387 /*
388   Legacy global handlerton. These will be removed (please do not add more).
389 */
390 handlerton *heap_hton;
391 handlerton *myisam_hton;
392 handlerton *innodb_hton;
393 
394 char *opt_disabled_storage_engines;
395 uint opt_server_id_bits= 0;
396 ulong opt_server_id_mask= 0;
397 my_bool read_only= 0, opt_readonly= 0;
398 my_bool super_read_only= 0, opt_super_readonly= 0;
399 my_bool opt_require_secure_transport= 0;
400 my_bool use_temp_pool, relay_log_purge;
401 my_bool relay_log_recovery;
402 my_bool opt_sync_frm, opt_allow_suspicious_udfs;
403 my_bool opt_secure_auth= 0;
404 char* opt_secure_file_priv;
405 my_bool opt_log_slow_admin_statements= 0;
406 my_bool opt_log_slow_slave_statements= 0;
407 my_bool lower_case_file_system= 0;
408 my_bool opt_large_pages= 0;
409 my_bool opt_super_large_pages= 0;
410 my_bool opt_myisam_use_mmap= 0;
411 my_bool offline_mode= 0;
412 my_bool opt_log_builtin_as_identified_by_password= 0;
413 uint   opt_large_page_size= 0;
414 uint default_password_lifetime= 0;
415 
416 mysql_mutex_t LOCK_default_password_lifetime;
417 
418 #if defined(ENABLED_DEBUG_SYNC)
419 MYSQL_PLUGIN_IMPORT uint    opt_debug_sync_timeout= 0;
420 #endif /* defined(ENABLED_DEBUG_SYNC) */
421 my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
422 my_bool check_proxy_users= 0, mysql_native_password_proxy_users= 0, sha256_password_proxy_users= 0;
423 /*
424   True if there is at least one per-hour limit for some user, so we should
425   check them before each query (and possibly reset counters when hour is
426   changed). False otherwise.
427 */
428 volatile bool mqh_used = 0;
429 my_bool opt_noacl= 0;
430 my_bool sp_automatic_privileges= 1;
431 
432 ulong opt_binlog_rows_event_max_size;
433 const char *binlog_checksum_default= "NONE";
434 ulong binlog_checksum_options;
435 my_bool opt_master_verify_checksum= 0;
436 my_bool opt_slave_sql_verify_checksum= 1;
437 const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS};
438 my_bool binlog_gtid_simple_recovery;
439 ulong binlog_error_action;
440 const char *binlog_error_action_list[]= {"IGNORE_ERROR", "ABORT_SERVER", NullS};
441 uint32 gtid_executed_compression_period= 0;
442 my_bool opt_log_unsafe_statements;
443 
444 #ifdef HAVE_INITGROUPS
445 volatile sig_atomic_t calling_initgroups= 0; /**< Used in SIGSEGV handler. */
446 #endif
447 const char *timestamp_type_names[]= {"UTC", "SYSTEM", NullS};
448 ulong opt_log_timestamps;
449 uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
450 uint mysqld_port_timeout;
451 ulong delay_key_write_options;
452 uint protocol_version;
453 uint lower_case_table_names;
454 long tc_heuristic_recover;
455 ulong back_log, connect_timeout, server_id;
456 ulong table_cache_size, table_def_size;
457 ulong table_cache_instances;
458 ulong table_cache_size_per_instance;
459 ulong what_to_log;
460 ulong slow_launch_time;
461 Atomic_int32 slave_open_temp_tables;
462 ulong open_files_limit, max_binlog_size, max_relay_log_size;
463 ulong slave_trans_retries;
464 uint  slave_net_timeout;
465 ulong slave_exec_mode_options;
466 ulonglong slave_type_conversions_options;
467 ulong opt_mts_slave_parallel_workers;
468 ulonglong opt_mts_pending_jobs_size_max;
469 ulonglong slave_rows_search_algorithms_options;
470 
471 #ifdef HAVE_REPLICATION
472 my_bool opt_slave_preserve_commit_order;
473 #endif
474 
475 #ifndef NDEBUG
476 uint slave_rows_last_search_algorithm_used;
477 #endif
478 ulong mts_parallel_option;
479 ulong binlog_cache_size=0;
480 ulonglong  max_binlog_cache_size=0;
481 ulong slave_max_allowed_packet= 0;
482 ulong binlog_stmt_cache_size=0;
483 int32 opt_binlog_max_flush_queue_time= 0;
484 long opt_binlog_group_commit_sync_delay= 0;
485 ulong opt_binlog_group_commit_sync_no_delay_count= 0;
486 ulonglong  max_binlog_stmt_cache_size=0;
487 ulong query_cache_size=0;
488 ulong refresh_version;  /* Increments on each reload */
489 query_id_t global_query_id;
490 ulong aborted_threads;
491 ulong delayed_insert_timeout, delayed_insert_limit, delayed_queue_size;
492 ulong delayed_insert_threads, delayed_insert_writes, delayed_rows_in_use;
493 ulong delayed_insert_errors,flush_time;
494 ulong specialflag=0;
495 ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
496 ulong binlog_stmt_cache_use= 0, binlog_stmt_cache_disk_use= 0;
497 ulong max_connections, max_connect_errors;
498 ulong rpl_stop_slave_timeout= LONG_TIMEOUT;
499 my_bool log_bin_use_v1_row_events= 0;
500 bool thread_cache_size_specified= false;
501 bool host_cache_size_specified= false;
502 bool table_definition_cache_specified= false;
503 ulong locked_account_connection_count= 0;
504 bool opt_keyring_operations= TRUE;
505 
506 /**
507   Limit of the total number of prepared statements in the server.
508   Is necessary to protect the server against out-of-memory attacks.
509 */
510 ulong max_prepared_stmt_count;
511 /**
512   Current total number of prepared statements in the server. This number
513   is exact, and therefore may not be equal to the difference between
514   `com_stmt_prepare' and `com_stmt_close' (global status variables), as
515   the latter ones account for all registered attempts to prepare
516   a statement (including unsuccessful ones).  Prepared statements are
517   currently connection-local: if the same SQL query text is prepared in
518   two different connections, this counts as two distinct prepared
519   statements.
520 */
521 ulong prepared_stmt_count=0;
522 ulong current_pid;
523 uint sync_binlog_period= 0, sync_relaylog_period= 0,
524      sync_relayloginfo_period= 0, sync_masterinfo_period= 0,
525      opt_mts_checkpoint_period, opt_mts_checkpoint_group;
526 ulong expire_logs_days = 0;
527 /**
528   Soft upper limit for number of sp_head objects that can be stored
529   in the sp_cache for one connection.
530 */
531 ulong stored_program_cache_size= 0;
532 /**
533   Compatibility option to prevent auto upgrade of old temporals
534   during certain ALTER TABLE operations.
535 */
536 my_bool avoid_temporal_upgrade;
537 
538 const double log_10[] = {
539   1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007, 1e008, 1e009,
540   1e010, 1e011, 1e012, 1e013, 1e014, 1e015, 1e016, 1e017, 1e018, 1e019,
541   1e020, 1e021, 1e022, 1e023, 1e024, 1e025, 1e026, 1e027, 1e028, 1e029,
542   1e030, 1e031, 1e032, 1e033, 1e034, 1e035, 1e036, 1e037, 1e038, 1e039,
543   1e040, 1e041, 1e042, 1e043, 1e044, 1e045, 1e046, 1e047, 1e048, 1e049,
544   1e050, 1e051, 1e052, 1e053, 1e054, 1e055, 1e056, 1e057, 1e058, 1e059,
545   1e060, 1e061, 1e062, 1e063, 1e064, 1e065, 1e066, 1e067, 1e068, 1e069,
546   1e070, 1e071, 1e072, 1e073, 1e074, 1e075, 1e076, 1e077, 1e078, 1e079,
547   1e080, 1e081, 1e082, 1e083, 1e084, 1e085, 1e086, 1e087, 1e088, 1e089,
548   1e090, 1e091, 1e092, 1e093, 1e094, 1e095, 1e096, 1e097, 1e098, 1e099,
549   1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109,
550   1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119,
551   1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129,
552   1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139,
553   1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149,
554   1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159,
555   1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169,
556   1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179,
557   1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189,
558   1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199,
559   1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209,
560   1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219,
561   1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229,
562   1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239,
563   1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249,
564   1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259,
565   1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269,
566   1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279,
567   1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289,
568   1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299,
569   1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308
570 };
571 
572 time_t server_start_time, flush_status_time;
573 
574 char server_uuid[UUID_LENGTH+1];
575 const char *server_uuid_ptr;
576 char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
577 char default_logfile_name[FN_REFLEN];
578 char *default_tz_name;
579 static char errorlog_filename_buff[FN_REFLEN];
580 const char *log_error_dest;
581 char glob_hostname[FN_REFLEN];
582 char mysql_real_data_home[FN_REFLEN],
583      lc_messages_dir[FN_REFLEN], reg_ext[FN_EXTLEN],
584      mysql_charsets_dir[FN_REFLEN],
585      *opt_init_file, *opt_tc_log_file;
586 char *lc_messages_dir_ptr;
587 char mysql_unpacked_real_data_home[FN_REFLEN];
588 size_t mysql_unpacked_real_data_home_len;
589 size_t mysql_real_data_home_len, mysql_data_home_len= 1;
590 uint reg_ext_length;
591 const key_map key_map_empty(0);
592 key_map key_map_full(0);                        // Will be initialized later
593 char logname_path[FN_REFLEN];
594 char slow_logname_path[FN_REFLEN];
595 char secure_file_real_path[FN_REFLEN];
596 
597 Date_time_format global_date_format, global_datetime_format, global_time_format;
598 Time_zone *default_tz;
599 
600 char *mysql_data_home= const_cast<char*>(".");
601 const char *mysql_real_data_home_ptr= mysql_real_data_home;
602 char server_version[SERVER_VERSION_LENGTH];
603 char *mysqld_unix_port, *opt_mysql_tmpdir;
604 
605 /** name of reference on left expression in rewritten IN subquery */
606 const char *in_left_expr_name= "<left expr>";
607 /** name of additional condition */
608 const char *in_additional_cond= "<IN COND>";
609 const char *in_having_cond= "<IN HAVING>";
610 
611 my_decimal decimal_zero;
612 #ifndef EMBEDDED_LIBRARY
613 /** Number of connection errors from internal server errors. */
614 ulong connection_errors_internal= 0;
615 /** Number of errors when reading the peer address. */
616 ulong connection_errors_peer_addr= 0;
617 #endif
618 
619 /* classes for comparation parsing/processing */
620 Eq_creator eq_creator;
621 Ne_creator ne_creator;
622 Equal_creator equal_creator;
623 Gt_creator gt_creator;
624 Lt_creator lt_creator;
625 Ge_creator ge_creator;
626 Le_creator le_creator;
627 
628 Rpl_filter* rpl_filter;
629 Rpl_filter* binlog_filter;
630 
631 struct system_variables global_system_variables;
632 struct system_variables max_system_variables;
633 struct system_status_var global_status_var;
634 
635 MY_TMPDIR mysql_tmpdir_list;
636 MY_BITMAP temp_pool;
637 
638 CHARSET_INFO *system_charset_info, *files_charset_info ;
639 CHARSET_INFO *national_charset_info, *table_alias_charset;
640 CHARSET_INFO *character_set_filesystem;
641 CHARSET_INFO *error_message_charset_info;
642 
643 MY_LOCALE *my_default_lc_messages;
644 MY_LOCALE *my_default_lc_time_names;
645 
646 SHOW_COMP_OPTION have_ssl, have_symlink, have_dlopen, have_query_cache;
647 SHOW_COMP_OPTION have_geometry, have_rtree_keys;
648 SHOW_COMP_OPTION have_crypt, have_compress;
649 SHOW_COMP_OPTION have_profiling;
650 SHOW_COMP_OPTION have_statement_timeout= SHOW_OPTION_DISABLED;
651 
652 /* Thread specific variables */
653 
654 thread_local_key_t THR_MALLOC;
655 bool THR_MALLOC_initialized= false;
656 thread_local_key_t THR_THD;
657 bool THR_THD_initialized= false;
658 mysql_mutex_t
659   LOCK_status, LOCK_uuid_generator,
660   LOCK_crypt,
661   LOCK_global_system_variables,
662   LOCK_user_conn, LOCK_slave_list,
663   LOCK_error_messages;
664 mysql_mutex_t LOCK_sql_rand;
665 
666 /**
667   The below lock protects access to two global server variables:
668   max_prepared_stmt_count and prepared_stmt_count. These variables
669   set the limit and hold the current total number of prepared statements
670   in the server, respectively. As PREPARE/DEALLOCATE rate in a loaded
671   server may be fairly high, we need a dedicated lock.
672 */
673 mysql_mutex_t LOCK_prepared_stmt_count;
674 
675 /*
676  The below two locks are introudced as guards (second mutex) for
677   the global variables sql_slave_skip_counter and slave_net_timeout
678   respectively. See fix_slave_skip_counter/fix_slave_net_timeout
679   for more details
680 */
681 mysql_mutex_t LOCK_sql_slave_skip_counter;
682 mysql_mutex_t LOCK_slave_net_timeout;
683 mysql_mutex_t LOCK_slave_trans_dep_tracker;
684 mysql_mutex_t LOCK_log_throttle_qni;
685 mysql_mutex_t LOCK_offline_mode;
686 #ifdef HAVE_OPENSSL
687 mysql_mutex_t LOCK_des_key_file;
688 #endif
689 mysql_rwlock_t LOCK_sys_init_connect, LOCK_sys_init_slave;
690 mysql_rwlock_t LOCK_system_variables_hash;
691 my_thread_handle signal_thread_id;
692 my_thread_attr_t connection_attrib;
693 mysql_mutex_t LOCK_server_started;
694 mysql_cond_t COND_server_started;
695 mysql_mutex_t LOCK_reset_gtid_table;
696 mysql_mutex_t LOCK_compress_gtid_table;
697 mysql_cond_t COND_compress_gtid_table;
698 #if !defined (EMBEDDED_LIBRARY) && !defined(_WIN32)
699 mysql_mutex_t LOCK_socket_listener_active;
700 mysql_cond_t COND_socket_listener_active;
701 mysql_mutex_t LOCK_start_signal_handler;
702 mysql_cond_t COND_start_signal_handler;
703 #endif
704 
705 bool mysqld_server_started= false;
706 
707 /*
708   The below lock protects access to global server variable
709   keyring_operations.
710 */
711 mysql_mutex_t LOCK_keyring_operations;
712 
713 File_parser_dummy_hook file_parser_dummy_hook;
714 
715 /* replication parameters, if master_host is not NULL, we are a slave */
716 uint report_port= 0;
717 ulong master_retry_count=0;
718 char *master_info_file;
719 char *relay_log_info_file, *report_user, *report_password, *report_host;
720 char *opt_relay_logname = 0, *opt_relaylog_index_name=0;
721 char *opt_general_logname, *opt_slow_logname, *opt_bin_logname;
722 
723 /* Static variables */
724 
725 static volatile sig_atomic_t kill_in_progress;
726 
727 static my_bool opt_myisam_log;
728 static int cleanup_done;
729 static ulong opt_specialflag;
730 static char *opt_update_logname;
731 char *opt_binlog_index_name;
732 char *mysql_home_ptr, *pidfile_name_ptr;
733 char *default_auth_plugin;
734 /** Initial command line arguments (count), after load_defaults().*/
735 static int defaults_argc;
736 /**
737   Initial command line arguments (arguments), after load_defaults().
738   This memory is allocated by @c load_defaults() and should be freed
739   using @c free_defaults().
740   Do not modify defaults_argc / defaults_argv,
741   use remaining_argc / remaining_argv instead to parse the command
742   line arguments in multiple steps.
743 */
744 static char **defaults_argv;
745 /** Remaining command line arguments (count), filtered by handle_options().*/
746 static int remaining_argc;
747 /** Remaining command line arguments (arguments), filtered by handle_options().*/
748 static char **remaining_argv;
749 
750 int orig_argc;
751 char **orig_argv;
752 
753 #if defined(HAVE_OPENSSL)
754 bool init_rsa_keys(void);
755 void deinit_rsa_keys(void);
756 int show_rsa_public_key(THD *thd, SHOW_VAR *var, char *buff);
757 #endif
758 
759 Connection_acceptor<Mysqld_socket_listener> *mysqld_socket_acceptor= NULL;
760 #ifdef _WIN32
761 static Named_pipe_listener *named_pipe_listener= NULL;
762 Connection_acceptor<Named_pipe_listener> *named_pipe_acceptor= NULL;
763 Connection_acceptor<Shared_mem_listener> *shared_mem_acceptor= NULL;
764 mysql_rwlock_t LOCK_named_pipe_full_access_group;
765 char *named_pipe_full_access_group;
766 #endif
767 
768 Checkable_rwlock *global_sid_lock= NULL;
769 Sid_map *global_sid_map= NULL;
770 Gtid_state *gtid_state= NULL;
771 Gtid_table_persistor *gtid_table_persistor= NULL;
772 
773 
set_remaining_args(int argc,char ** argv)774 void set_remaining_args(int argc, char **argv)
775 {
776   remaining_argc= argc;
777   remaining_argv= argv;
778 }
779 /*
780   Multiple threads of execution use the random state maintained in global
781   sql_rand to generate random numbers. sql_rnd_with_mutex use mutex
782   LOCK_sql_rand to protect sql_rand across multiple instantiations that use
783   sql_rand to generate random numbers.
784  */
sql_rnd_with_mutex()785 ulong sql_rnd_with_mutex()
786 {
787   mysql_mutex_lock(&LOCK_sql_rand);
788   ulong tmp=(ulong) (my_rnd(&sql_rand) * 0xffffffff); /* make all bits random */
789   mysql_mutex_unlock(&LOCK_sql_rand);
790   return tmp;
791 }
792 
793 
794 C_MODE_START
795 
option_error_reporter(enum loglevel level,const char * format,...)796 static void option_error_reporter(enum loglevel level, const char *format, ...)
797 {
798   va_list args;
799   va_start(args, format);
800 
801   /* Don't print warnings for --loose options during bootstrap */
802   if (level == ERROR_LEVEL || !opt_bootstrap ||
803       (log_error_verbosity > 1))
804   {
805     error_log_print(level, format, args);
806   }
807   va_end(args);
808 }
809 
810 /**
811   Character set and collation error reporter that prints to sql error log.
812   @param level          log message level
813   @param format         log message format string
814 
815   This routine is used to print character set and collation
816   warnings and errors inside an already running mysqld server,
817   e.g. when a character set or collation is requested for the very first time
818   and its initialization does not go well for some reasons.
819 */
charset_error_reporter(enum loglevel level,const char * format,...)820 static void charset_error_reporter(enum loglevel level,
821                                    const char *format, ...)
822 {
823   va_list args;
824   va_start(args, format);
825   error_log_print(level, format, args);
826   va_end(args);
827 }
828 C_MODE_END
829 
830 struct rand_struct sql_rand; ///< used by sql_class.cc:THD::THD()
831 
832 #ifndef EMBEDDED_LIBRARY
833 struct passwd *user_info= NULL;
834 #ifndef _WIN32
835 static my_thread_t main_thread_id;
836 #endif // !_WIN32
837 #endif // !EMBEDDED_LIBRARY
838 
839 /* OS specific variables */
840 
841 #ifdef _WIN32
842 #include <process.h>
843 
844 static bool windows_service= false;
845 static bool use_opt_args;
846 static int opt_argc;
847 static char **opt_argv;
848 
849 #if !defined(EMBEDDED_LIBRARY)
850 static mysql_mutex_t LOCK_handler_count;
851 static mysql_cond_t COND_handler_count;
852 static HANDLE hEventShutdown;
853 char *shared_memory_base_name= default_shared_memory_base_name;
854 my_bool opt_enable_shared_memory;
855 static char shutdown_event_name[40];
856 #include "nt_servc.h"
857 static   NTService  Service;        ///< Service object for WinNT
858 #endif /* EMBEDDED_LIBRARY */
859 #endif /* _WIN32 */
860 
861 #ifndef EMBEDDED_LIBRARY
862 bool mysqld_embedded=0;
863 #else
864 bool mysqld_embedded=1;
865 #endif
866 
867 static my_bool plugins_are_initialized= FALSE;
868 
869 #ifndef NDEBUG
870 static const char* default_dbug_option;
871 #endif
872 ulong query_cache_min_res_unit= QUERY_CACHE_MIN_RESULT_DATA_SIZE;
873 Query_cache query_cache;
874 
875 my_bool opt_use_ssl= 1;
876 char *opt_ssl_ca= NULL, *opt_ssl_capath= NULL, *opt_ssl_cert= NULL,
877      *opt_ssl_cipher= NULL, *opt_ssl_key= NULL, *opt_ssl_crl= NULL,
878      *opt_ssl_crlpath= NULL, *opt_tls_version= NULL;
879 
880 #ifdef HAVE_OPENSSL
881 char *des_key_file;
882 #ifndef EMBEDDED_LIBRARY
883 struct st_VioSSLFd *ssl_acceptor_fd;
884 SSL *ssl_acceptor;
885 #endif
886 #endif /* HAVE_OPENSSL */
887 
888 /* Function declarations */
889 
890 extern "C" void *signal_hand(void *arg);
891 static int mysql_init_variables(void);
892 static int get_options(int *argc_ptr, char ***argv_ptr);
893 static void add_terminator(vector<my_option> *options);
894 extern "C" my_bool mysqld_get_one_option(int, const struct my_option *, char *);
895 static void set_server_version(void);
896 static int init_thread_environment();
897 static char *get_relative_path(const char *path);
898 static int fix_paths(void);
899 static bool read_init_file(char *file_name);
900 static void clean_up(bool print_message);
901 static int test_if_case_insensitive(const char *dir_name);
902 static void end_ssl();
903 static void start_processing_signals();
904 
905 #ifndef EMBEDDED_LIBRARY
906 static bool pid_file_created= false;
907 static void usage(void);
908 static void clean_up_mutexes(void);
909 static void create_pid_file();
910 static void mysqld_exit(int exit_code) MY_ATTRIBUTE((noreturn));
911 static void delete_pid_file(myf flags);
912 #endif
913 
914 
915 #ifndef EMBEDDED_LIBRARY
916 /****************************************************************************
917 ** Code to end mysqld
918 ****************************************************************************/
919 
920 /**
921   This class implements callback function used by close_connections()
922   to set KILL_CONNECTION flag on all thds in thd list.
923   If m_kill_dump_thread_flag is not set it kills all other threads
924   except dump threads. If this flag is set, it kills dump threads.
925 */
926 class Set_kill_conn : public Do_THD_Impl
927 {
928 private:
929   int m_dump_thread_count;
930   bool m_kill_dump_threads_flag;
931 public:
Set_kill_conn()932   Set_kill_conn()
933     : m_dump_thread_count(0),
934       m_kill_dump_threads_flag(false)
935   {}
936 
set_dump_thread_flag()937   void set_dump_thread_flag()
938   {
939     m_kill_dump_threads_flag= true;
940   }
941 
get_dump_thread_count() const942   int get_dump_thread_count() const
943   {
944     return m_dump_thread_count;
945   }
946 
operator ()(THD * killing_thd)947   virtual void operator()(THD *killing_thd)
948   {
949     DBUG_PRINT("quit",("Informing thread %u that it's time to die",
950                        killing_thd->thread_id()));
951     if (!m_kill_dump_threads_flag)
952     {
953       // We skip slave threads & scheduler on this first loop through.
954       if (killing_thd->slave_thread)
955         return;
956 
957       if (killing_thd->get_command() == COM_BINLOG_DUMP ||
958           killing_thd->get_command() == COM_BINLOG_DUMP_GTID)
959       {
960         ++m_dump_thread_count;
961         return;
962       }
963       DBUG_EXECUTE_IF("Check_dump_thread_is_alive",
964                       {
965                         assert(killing_thd->get_command() != COM_BINLOG_DUMP &&
966                                killing_thd->get_command() != COM_BINLOG_DUMP_GTID);
967                       };);
968     }
969     mysql_mutex_lock(&killing_thd->LOCK_thd_data);
970     killing_thd->killed= THD::KILL_CONNECTION;
971     MYSQL_CALLBACK(Connection_handler_manager::event_functions,
972                    post_kill_notification, (killing_thd));
973     if (killing_thd->is_killable)
974     {
975       mysql_mutex_lock(&killing_thd->LOCK_current_cond);
976       if (killing_thd->current_cond)
977       {
978         mysql_mutex_lock(killing_thd->current_mutex);
979         mysql_cond_broadcast(killing_thd->current_cond);
980         mysql_mutex_unlock(killing_thd->current_mutex);
981       }
982       mysql_mutex_unlock(&killing_thd->LOCK_current_cond);
983     }
984     mysql_mutex_unlock(&killing_thd->LOCK_thd_data);
985   }
986 };
987 
988 /**
989   This class implements callback function used by close_connections()
990   to close vio connection for all thds in thd list
991 */
992 class Call_close_conn : public Do_THD_Impl
993 {
994 public:
Call_close_conn(bool server_shutdown)995   Call_close_conn(bool server_shutdown) : is_server_shutdown(server_shutdown)
996   {}
997 
operator ()(THD * closing_thd)998   virtual void operator()(THD *closing_thd)
999   {
1000     if (closing_thd->get_protocol()->connection_alive())
1001     {
1002       LEX_CSTRING main_sctx_user= closing_thd->m_main_security_ctx.user();
1003       sql_print_warning(ER_DEFAULT(ER_FORCING_CLOSE),my_progname,
1004                         closing_thd->thread_id(),
1005                         (main_sctx_user.length ? main_sctx_user.str : ""));
1006       /*
1007         Do not generate MYSQL_AUDIT_CONNECTION_DISCONNECT event, when closing
1008         thread close sessions. Each session will generate DISCONNECT event by
1009         itself.
1010       */
1011       close_connection(closing_thd, 0, is_server_shutdown, false);
1012     }
1013   }
1014 private:
1015   bool is_server_shutdown;
1016 };
1017 
close_connections(void)1018 static void close_connections(void)
1019 {
1020   DBUG_ENTER("close_connections");
1021   (void) RUN_HOOK(server_state, before_server_shutdown, (NULL));
1022 
1023   Per_thread_connection_handler::kill_blocked_pthreads();
1024 
1025   uint dump_thread_count= 0;
1026   uint dump_thread_kill_retries= 8;
1027 
1028   // Close listeners.
1029   if (mysqld_socket_acceptor != NULL)
1030     mysqld_socket_acceptor->close_listener();
1031 #ifdef _WIN32
1032   if (named_pipe_acceptor != NULL)
1033     named_pipe_acceptor->close_listener();
1034 
1035   if (shared_mem_acceptor != NULL)
1036     shared_mem_acceptor->close_listener();
1037 #endif
1038 
1039   /*
1040     First signal all threads that it's time to die
1041     This will give the threads some time to gracefully abort their
1042     statements and inform their clients that the server is about to die.
1043   */
1044 
1045   Global_THD_manager *thd_manager= Global_THD_manager::get_instance();
1046   sql_print_information("Giving %d client threads a chance to die gracefully",
1047                         static_cast<int>(thd_manager->get_thd_count()));
1048 
1049   Set_kill_conn set_kill_conn;
1050   thd_manager->do_for_all_thd(&set_kill_conn);
1051   sql_print_information("Shutting down slave threads");
1052   end_slave();
1053 
1054   if (set_kill_conn.get_dump_thread_count())
1055   {
1056     /*
1057       Replication dump thread should be terminated after the clients are
1058       terminated. Wait for few more seconds for other sessions to end.
1059      */
1060     while (thd_manager->get_thd_count() > dump_thread_count &&
1061            dump_thread_kill_retries)
1062     {
1063       sleep(1);
1064       dump_thread_kill_retries--;
1065     }
1066     set_kill_conn.set_dump_thread_flag();
1067     thd_manager->do_for_all_thd(&set_kill_conn);
1068   }
1069   if (thd_manager->get_thd_count() > 0)
1070     sleep(2);         // Give threads time to die
1071 
1072   /*
1073     Force remaining threads to die by closing the connection to the client
1074     This will ensure that threads that are waiting for a command from the
1075     client on a blocking read call are aborted.
1076   */
1077 
1078   sql_print_information("Forcefully disconnecting %d remaining clients",
1079                         static_cast<int>(thd_manager->get_thd_count()));
1080 
1081   Call_close_conn call_close_conn(true);
1082   thd_manager->do_for_all_thd(&call_close_conn);
1083 
1084   (void) RUN_HOOK(server_state, after_server_shutdown, (NULL));
1085 
1086   /*
1087     All threads have now been aborted. Stop event scheduler thread
1088     after aborting all client connections, otherwise user may
1089     start/stop event scheduler after Events::deinit() deallocates
1090     scheduler object(static member in Events class)
1091   */
1092   Events::deinit();
1093   DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",
1094                      thd_manager->get_thd_count()));
1095   thd_manager->wait_till_no_thd();
1096 
1097   /*
1098     Connection threads might take a little while to go down after removing from
1099     global thread list. Give it some time.
1100   */
1101   Connection_handler_manager::wait_till_no_connection();
1102 
1103   delete_slave_info_objects();
1104   DBUG_PRINT("quit",("close_connections thread"));
1105 
1106   DBUG_VOID_RETURN;
1107 }
1108 
1109 
kill_mysql(void)1110 void kill_mysql(void)
1111 {
1112   DBUG_ENTER("kill_mysql");
1113 
1114 #if defined(_WIN32)
1115   {
1116     if (!SetEvent(hEventShutdown))
1117     {
1118       DBUG_PRINT("error",("Got error: %ld from SetEvent",GetLastError()));
1119     }
1120     /*
1121       or:
1122       HANDLE hEvent=OpenEvent(0, FALSE, "MySqlShutdown");
1123       SetEvent(hEventShutdown);
1124       CloseHandle(hEvent);
1125     */
1126   }
1127 #else
1128   if (pthread_kill(signal_thread_id.thread, SIGTERM))
1129   {
1130     DBUG_PRINT("error",("Got error %d from pthread_kill",errno)); /* purecov: inspected */
1131   }
1132 #endif
1133   DBUG_PRINT("quit",("After pthread_kill"));
1134   DBUG_VOID_RETURN;
1135 }
1136 
1137 
unireg_abort(int exit_code)1138 extern "C" void unireg_abort(int exit_code)
1139 {
1140   DBUG_ENTER("unireg_abort");
1141 
1142   // At this point it does not make sense to buffer more messages.
1143   // Just flush what we have and write directly to stderr.
1144   flush_error_log_messages();
1145 
1146   if (opt_help)
1147     usage();
1148   if (exit_code)
1149     sql_print_error("Aborting\n");
1150 
1151   mysql_audit_notify(MYSQL_AUDIT_SERVER_SHUTDOWN_SHUTDOWN,
1152                      MYSQL_AUDIT_SERVER_SHUTDOWN_REASON_ABORT, exit_code);
1153 #ifndef _WIN32
1154   if (signal_thread_id.thread != 0)
1155   {
1156     start_processing_signals();
1157 
1158     pthread_kill(signal_thread_id.thread, SIGTERM);
1159     my_thread_join(&signal_thread_id, NULL);
1160   }
1161   signal_thread_id.thread= 0;
1162 
1163   if (opt_daemonize)
1164   {
1165     mysqld::runtime::signal_parent(pipe_write_fd,0);
1166   }
1167 #endif
1168 
1169   clean_up(!opt_help && (exit_code || !opt_bootstrap)); /* purecov: inspected */
1170   DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
1171   mysqld_exit(exit_code);
1172 }
1173 
mysqld_exit(int exit_code)1174 static void mysqld_exit(int exit_code)
1175 {
1176   assert(exit_code >= MYSQLD_SUCCESS_EXIT
1177          && exit_code <= MYSQLD_FAILURE_EXIT);
1178   mysql_audit_finalize();
1179 #ifndef EMBEDDED_LIBRARY
1180   Srv_session::module_deinit();
1181 #endif
1182   delete_optimizer_cost_module();
1183   clean_up_mutexes();
1184   my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
1185   destroy_error_log();
1186 #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
1187   shutdown_performance_schema();
1188 #endif
1189 #if defined(_WIN32)
1190   if (Service.IsNT() && windows_service)
1191   {
1192     Service.Stop();
1193   }
1194   else
1195   {
1196     Service.SetShutdownEvent(0);
1197     if (hEventShutdown)
1198       CloseHandle(hEventShutdown);
1199   }
1200 #endif
1201   exit(exit_code); /* purecov: inspected */
1202 }
1203 
1204 #endif /* !EMBEDDED_LIBRARY */
1205 
1206 /**
1207    GTID cleanup destroys objects and reset their pointer.
1208    Function is reentrant.
1209 */
gtid_server_cleanup()1210 void gtid_server_cleanup()
1211 {
1212   if (gtid_state != NULL)
1213   {
1214     delete gtid_state;
1215     gtid_state= NULL;
1216   }
1217   if (global_sid_map != NULL)
1218   {
1219     delete global_sid_map;
1220     global_sid_map= NULL;
1221   }
1222   if (global_sid_lock != NULL)
1223   {
1224     delete global_sid_lock;
1225     global_sid_lock= NULL;
1226   }
1227   if (gtid_table_persistor != NULL)
1228   {
1229     delete gtid_table_persistor;
1230     gtid_table_persistor= NULL;
1231   }
1232   if (gtid_mode_lock)
1233   {
1234     delete gtid_mode_lock;
1235     gtid_mode_lock= NULL;
1236   }
1237 }
1238 
1239 /**
1240    GTID initialization.
1241 
1242    @return true if allocation does not succeed
1243            false if OK
1244 */
gtid_server_init()1245 bool gtid_server_init()
1246 {
1247   bool res=
1248     (!(global_sid_lock= new Checkable_rwlock(
1249 #ifdef HAVE_PSI_INTERFACE
1250                                              key_rwlock_global_sid_lock
1251 #endif
1252                                             )) ||
1253      !(gtid_mode_lock= new Checkable_rwlock(
1254 #ifdef HAVE_PSI_INTERFACE
1255                                             key_rwlock_gtid_mode_lock
1256 #endif
1257                                            )) ||
1258      !(global_sid_map= new Sid_map(global_sid_lock)) ||
1259      !(gtid_state= new Gtid_state(global_sid_lock, global_sid_map))||
1260      !(gtid_table_persistor= new Gtid_table_persistor()));
1261   if (res)
1262   {
1263     gtid_server_cleanup();
1264   }
1265   return res;
1266 }
1267 
1268 #ifndef EMBEDDED_LIBRARY
1269 // Free connection acceptors
free_connection_acceptors()1270 static void free_connection_acceptors()
1271 {
1272   delete mysqld_socket_acceptor;
1273   mysqld_socket_acceptor= NULL;
1274 
1275 #ifdef _WIN32
1276   delete named_pipe_acceptor;
1277   named_pipe_acceptor= NULL;
1278   delete shared_mem_acceptor;
1279   shared_mem_acceptor= NULL;
1280 #endif
1281 }
1282 #endif
1283 
1284 
clean_up(bool print_message)1285 void clean_up(bool print_message)
1286 {
1287   DBUG_PRINT("exit",("clean_up"));
1288   if (cleanup_done++)
1289     return; /* purecov: inspected */
1290 
1291   stop_handle_manager();
1292   release_ddl_log();
1293 
1294   memcached_shutdown();
1295 
1296   /*
1297     make sure that handlers finish up
1298     what they have that is dependent on the binlog
1299   */
1300   if ((opt_help == 0) || (opt_verbose > 0))
1301     sql_print_information("Binlog end");
1302   ha_binlog_end(current_thd);
1303 
1304   injector::free_instance();
1305   mysql_bin_log.cleanup();
1306   gtid_server_cleanup();
1307 
1308 #ifdef HAVE_REPLICATION
1309   if (use_slave_mask)
1310     bitmap_free(&slave_error_mask);
1311 #endif
1312   my_tz_free();
1313   my_dboptions_cache_free();
1314   ignore_db_dirs_free();
1315   servers_free(1);
1316 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1317   acl_free(1);
1318   grant_free();
1319 #endif
1320   query_cache.destroy();
1321   hostname_cache_free();
1322   item_func_sleep_free();
1323   lex_free();       /* Free some memory */
1324   item_create_cleanup();
1325   if (!opt_noacl)
1326   {
1327 #ifdef HAVE_DLOPEN
1328     udf_free();
1329 #endif
1330   }
1331   table_def_start_shutdown();
1332   delegates_shutdown();
1333   plugin_shutdown();
1334   delete_optimizer_cost_module();
1335   ha_end();
1336   if (tc_log)
1337   {
1338     tc_log->close();
1339     tc_log= NULL;
1340   }
1341   delegates_destroy();
1342   transaction_cache_free();
1343   table_def_free();
1344   mdl_destroy();
1345   key_caches.delete_elements((void (*)(const char*, uchar*)) free_key_cache);
1346   multi_keycache_free();
1347   free_status_vars();
1348   query_logger.cleanup();
1349   my_free_open_file_info();
1350   if (defaults_argv)
1351     free_defaults(defaults_argv);
1352   free_tmpdir(&mysql_tmpdir_list);
1353   my_free(opt_bin_logname);
1354   bitmap_free(&temp_pool);
1355   free_max_user_conn();
1356 #ifdef HAVE_REPLICATION
1357   end_slave_list();
1358 #endif
1359   delete binlog_filter;
1360   delete rpl_filter;
1361   end_ssl();
1362   vio_end();
1363   my_regex_end();
1364 #if defined(ENABLED_DEBUG_SYNC)
1365   /* End the debug sync facility. See debug_sync.cc. */
1366   debug_sync_end();
1367 #endif /* defined(ENABLED_DEBUG_SYNC) */
1368 
1369 #ifndef EMBEDDED_LIBRARY
1370   delete_pid_file(MYF(0));
1371 #endif
1372 
1373   if (print_message && my_default_lc_messages && server_start_time)
1374     sql_print_information(ER_DEFAULT(ER_SHUTDOWN_COMPLETE),my_progname);
1375   cleanup_errmsgs();
1376 
1377 #ifndef EMBEDDED_LIBRARY
1378   free_connection_acceptors();
1379   Connection_handler_manager::destroy_instance();
1380 #endif
1381 
1382   mysql_client_plugin_deinit();
1383   finish_client_errs();
1384   deinit_errmessage(); // finish server errs
1385   DBUG_PRINT("quit", ("Error messages freed"));
1386 
1387   free_charsets();
1388   sys_var_end();
1389   Global_THD_manager::destroy_instance();
1390 
1391   my_free(const_cast<char*>(log_bin_basename));
1392   my_free(const_cast<char*>(log_bin_index));
1393 #ifndef EMBEDDED_LIBRARY
1394   my_free(const_cast<char*>(relay_log_basename));
1395   my_free(const_cast<char*>(relay_log_index));
1396 #endif
1397   free_list(opt_early_plugin_load_list_ptr);
1398   free_list(opt_plugin_load_list_ptr);
1399 
1400   if (THR_THD_initialized)
1401   {
1402     THR_THD_initialized= false;
1403     (void) my_delete_thread_local_key(THR_THD);
1404   }
1405 
1406   if (THR_MALLOC_initialized)
1407   {
1408     THR_MALLOC_initialized= false;
1409     (void) my_delete_thread_local_key(THR_MALLOC);
1410   }
1411 
1412   if (have_statement_timeout == SHOW_OPTION_YES)
1413     my_timer_deinitialize();
1414 
1415   have_statement_timeout= SHOW_OPTION_DISABLED;
1416 
1417   log_syslog_exit();
1418 
1419   /*
1420     The following lines may never be executed as the main thread may have
1421     killed us
1422   */
1423   DBUG_PRINT("quit", ("done with cleanup"));
1424 } /* clean_up */
1425 
1426 
1427 #ifndef EMBEDDED_LIBRARY
1428 
clean_up_mutexes()1429 static void clean_up_mutexes()
1430 {
1431   mysql_mutex_destroy(&LOCK_log_throttle_qni);
1432   mysql_mutex_destroy(&LOCK_status);
1433   mysql_mutex_destroy(&LOCK_manager);
1434   mysql_mutex_destroy(&LOCK_crypt);
1435   mysql_mutex_destroy(&LOCK_user_conn);
1436 #ifdef HAVE_OPENSSL
1437   mysql_mutex_destroy(&LOCK_des_key_file);
1438 #endif
1439   mysql_rwlock_destroy(&LOCK_sys_init_connect);
1440   mysql_rwlock_destroy(&LOCK_sys_init_slave);
1441   mysql_mutex_destroy(&LOCK_global_system_variables);
1442   mysql_rwlock_destroy(&LOCK_system_variables_hash);
1443   mysql_mutex_destroy(&LOCK_uuid_generator);
1444   mysql_mutex_destroy(&LOCK_sql_rand);
1445   mysql_mutex_destroy(&LOCK_prepared_stmt_count);
1446   mysql_mutex_destroy(&LOCK_sql_slave_skip_counter);
1447   mysql_mutex_destroy(&LOCK_slave_net_timeout);
1448   mysql_mutex_destroy(&LOCK_slave_trans_dep_tracker);
1449   mysql_mutex_destroy(&LOCK_error_messages);
1450   mysql_mutex_destroy(&LOCK_offline_mode);
1451   mysql_mutex_destroy(&LOCK_default_password_lifetime);
1452   mysql_cond_destroy(&COND_manager);
1453 #ifdef _WIN32
1454   mysql_cond_destroy(&COND_handler_count);
1455   mysql_mutex_destroy(&LOCK_handler_count);
1456   mysql_rwlock_destroy(&LOCK_named_pipe_full_access_group);
1457 #endif
1458 #ifndef _WIN32
1459   mysql_cond_destroy(&COND_socket_listener_active);
1460   mysql_mutex_destroy(&LOCK_socket_listener_active);
1461   mysql_cond_destroy(&COND_start_signal_handler);
1462   mysql_mutex_destroy(&LOCK_start_signal_handler);
1463 #endif
1464   mysql_mutex_destroy(&LOCK_keyring_operations);
1465 }
1466 
1467 
1468 /****************************************************************************
1469 ** Init IP and UNIX socket
1470 ****************************************************************************/
1471 
set_ports()1472 static void set_ports()
1473 {
1474   char  *env;
1475   if (!mysqld_port && !opt_disable_networking)
1476   {         // Get port if not from commandline
1477     mysqld_port= MYSQL_PORT;
1478 
1479     /*
1480       if builder specifically requested a default port, use that
1481       (even if it coincides with our factory default).
1482       only if they didn't do we check /etc/services (and, failing
1483       on that, fall back to the factory default of 3306).
1484       either default can be overridden by the environment variable
1485       MYSQL_TCP_PORT, which in turn can be overridden with command
1486       line options.
1487     */
1488 
1489 #if MYSQL_PORT_DEFAULT == 0
1490     struct  servent *serv_ptr;
1491     if ((serv_ptr= getservbyname("mysql", "tcp")))
1492       mysqld_port= ntohs((u_short) serv_ptr->s_port); /* purecov: inspected */
1493 #endif
1494     if ((env = getenv("MYSQL_TCP_PORT")))
1495       mysqld_port= (uint) atoi(env);    /* purecov: inspected */
1496   }
1497   if (!mysqld_unix_port)
1498   {
1499 #ifdef _WIN32
1500     mysqld_unix_port= (char*) MYSQL_NAMEDPIPE;
1501 #else
1502     mysqld_unix_port= (char*) MYSQL_UNIX_ADDR;
1503 #endif
1504     if ((env = getenv("MYSQL_UNIX_PORT")))
1505       mysqld_unix_port= env;      /* purecov: inspected */
1506   }
1507 }
1508 
1509 
1510 #if !defined(_WIN32)
1511 /* Change to run as another user if started with --user */
1512 
check_user(const char * user)1513 static struct passwd *check_user(const char *user)
1514 {
1515   struct passwd *tmp_user_info;
1516   uid_t user_id= geteuid();
1517 
1518   // Don't bother if we aren't superuser
1519   if (user_id)
1520   {
1521     if (user)
1522     {
1523       /* Don't give a warning, if real user is same as given with --user */
1524       tmp_user_info= getpwnam(user);
1525       if ((!tmp_user_info || user_id != tmp_user_info->pw_uid))
1526         sql_print_warning(
1527                     "One can only use the --user switch if running as root\n");
1528     }
1529     return NULL;
1530   }
1531   if (!user)
1532   {
1533     if (!opt_bootstrap && !opt_help)
1534     {
1535       sql_print_error("Fatal error: Please read \"Security\" section of the manual to find out how to run mysqld as root!\n");
1536       unireg_abort(MYSQLD_ABORT_EXIT);
1537     }
1538     return NULL;
1539   }
1540   /* purecov: begin tested */
1541   if (!strcmp(user,"root"))
1542     return NULL;                        // Avoid problem with dynamic libraries
1543 
1544   if (!(tmp_user_info= getpwnam(user)))
1545   {
1546     // Allow a numeric uid to be used
1547     const char *pos;
1548     for (pos= user; my_isdigit(mysqld_charset,*pos); pos++) ;
1549     if (*pos)                                   // Not numeric id
1550       goto err;
1551     if (!(tmp_user_info= getpwuid(atoi(user))))
1552       goto err;
1553   }
1554   return tmp_user_info;
1555   /* purecov: end */
1556 
1557 err:
1558   sql_print_error("Fatal error: Can't change to run as user '%s' ;  Please check that the user exists!\n",user);
1559   unireg_abort(MYSQLD_ABORT_EXIT);
1560 
1561 #ifdef PR_SET_DUMPABLE
1562   if (test_flags & TEST_CORE_ON_SIGNAL)
1563   {
1564     /* inform kernel that process is dumpable */
1565     (void) prctl(PR_SET_DUMPABLE, 1);
1566   }
1567 #endif
1568 
1569   return NULL;
1570 }
1571 
set_user(const char * user,struct passwd * user_info_arg)1572 static void set_user(const char *user, struct passwd *user_info_arg)
1573 {
1574   /* purecov: begin tested */
1575   assert(user_info_arg != 0);
1576 #ifdef HAVE_INITGROUPS
1577   /*
1578     We can get a SIGSEGV when calling initgroups() on some systems when NSS
1579     is configured to use LDAP and the server is statically linked.  We set
1580     calling_initgroups as a flag to the SIGSEGV handler that is then used to
1581     output a specific message to help the user resolve this problem.
1582   */
1583   calling_initgroups= 1;
1584   initgroups((char*) user, user_info_arg->pw_gid);
1585   calling_initgroups= 0;
1586 #endif
1587   if (setgid(user_info_arg->pw_gid) == -1)
1588   {
1589     sql_print_error("setgid: %s", strerror(errno));
1590     unireg_abort(MYSQLD_ABORT_EXIT);
1591   }
1592   if (setuid(user_info_arg->pw_uid) == -1)
1593   {
1594     sql_print_error("setuid: %s", strerror(errno));
1595     unireg_abort(MYSQLD_ABORT_EXIT);
1596   }
1597   /* purecov: end */
1598 }
1599 
1600 
set_effective_user(struct passwd * user_info_arg)1601 static void set_effective_user(struct passwd *user_info_arg)
1602 {
1603   assert(user_info_arg != 0);
1604   if (setregid((gid_t)-1, user_info_arg->pw_gid) == -1)
1605   {
1606     sql_print_error("setregid: %s", strerror(errno));
1607     unireg_abort(MYSQLD_ABORT_EXIT);
1608   }
1609   if (setreuid((uid_t)-1, user_info_arg->pw_uid) == -1)
1610   {
1611     sql_print_error("setreuid: %s", strerror(errno));
1612     unireg_abort(MYSQLD_ABORT_EXIT);
1613   }
1614 }
1615 
1616 
1617 /** Change root user if started with @c --chroot . */
set_root(const char * path)1618 static void set_root(const char *path)
1619 {
1620   if (chroot(path) == -1)
1621   {
1622     sql_print_error("chroot: %s", strerror(errno));
1623     unireg_abort(MYSQLD_ABORT_EXIT);
1624   }
1625   my_setwd("/", MYF(0));
1626 }
1627 #endif // !_WIN32
1628 
1629 
network_init(void)1630 static bool network_init(void)
1631 {
1632   if (opt_bootstrap)
1633     return false;
1634 
1635   set_ports();
1636 
1637 #ifdef HAVE_SYS_UN_H
1638   std::string const unix_sock_name(mysqld_unix_port ? mysqld_unix_port : "");
1639 #else
1640   std::string const unix_sock_name("");
1641 #endif
1642 
1643   if (!opt_disable_networking || unix_sock_name != "")
1644   {
1645     std::string const bind_addr_str(my_bind_addr_str ? my_bind_addr_str : "");
1646 
1647     Mysqld_socket_listener *mysqld_socket_listener=
1648       new (std::nothrow) Mysqld_socket_listener(bind_addr_str,
1649                                                 mysqld_port, back_log,
1650                                                 mysqld_port_timeout,
1651                                                 unix_sock_name);
1652     if (mysqld_socket_listener == NULL)
1653       return true;
1654 
1655     mysqld_socket_acceptor=
1656       new (std::nothrow) Connection_acceptor<Mysqld_socket_listener>(mysqld_socket_listener);
1657     if (mysqld_socket_acceptor == NULL)
1658     {
1659       delete mysqld_socket_listener;
1660       mysqld_socket_listener= NULL;
1661       return true;
1662     }
1663 
1664     if (mysqld_socket_acceptor->init_connection_acceptor())
1665       return true; // mysqld_socket_acceptor would be freed in unireg_abort.
1666 
1667     if (report_port == 0)
1668       report_port= mysqld_port;
1669 
1670     if (!opt_disable_networking)
1671       assert(report_port != 0);
1672   }
1673 #ifdef _WIN32
1674   // Create named pipe
1675   if (opt_enable_named_pipe)
1676   {
1677     std::string pipe_name= mysqld_unix_port ? mysqld_unix_port : "";
1678 
1679     named_pipe_listener= new (std::nothrow) Named_pipe_listener(&pipe_name);
1680     if (named_pipe_listener == NULL)
1681       return true;
1682 
1683     named_pipe_acceptor=
1684       new (std::nothrow) Connection_acceptor<Named_pipe_listener>(named_pipe_listener);
1685     if (named_pipe_acceptor == NULL)
1686     {
1687       delete named_pipe_listener;
1688       named_pipe_listener= NULL;
1689       return true;
1690     }
1691 
1692     if (named_pipe_acceptor->init_connection_acceptor())
1693       return true; // named_pipe_acceptor would be freed in unireg_abort.
1694   }
1695 
1696   // Setup shared_memory acceptor
1697   if (opt_enable_shared_memory)
1698   {
1699     std::string shared_mem_base_name= shared_memory_base_name ? shared_memory_base_name : "";
1700 
1701     Shared_mem_listener *shared_mem_listener=
1702       new (std::nothrow) Shared_mem_listener(&shared_mem_base_name);
1703     if (shared_mem_listener == NULL)
1704       return true;
1705 
1706     shared_mem_acceptor=
1707       new (std::nothrow) Connection_acceptor<Shared_mem_listener>(shared_mem_listener);
1708     if (shared_mem_acceptor == NULL)
1709     {
1710       delete shared_mem_listener;
1711       shared_mem_listener= NULL;
1712       return true;
1713     }
1714 
1715     if (shared_mem_acceptor->init_connection_acceptor())
1716       return true; // shared_mem_acceptor would be freed in unireg_abort.
1717   }
1718 #endif // _WIN32
1719   return false;
1720 }
1721 
1722 #ifdef _WIN32
1723 static uint handler_count= 0;
1724 
1725 
decrement_handler_count()1726 static inline void decrement_handler_count()
1727 {
1728   mysql_mutex_lock(&LOCK_handler_count);
1729   handler_count--;
1730   mysql_cond_signal(&COND_handler_count);
1731   mysql_mutex_unlock(&LOCK_handler_count);
1732 }
1733 
1734 
socket_conn_event_handler(void * arg)1735 extern "C" void *socket_conn_event_handler(void *arg)
1736 {
1737   my_thread_init();
1738 
1739   Connection_acceptor<Mysqld_socket_listener> *conn_acceptor=
1740     static_cast<Connection_acceptor<Mysqld_socket_listener>*>(arg);
1741   conn_acceptor->connection_event_loop();
1742 
1743   decrement_handler_count();
1744   my_thread_end();
1745   return 0;
1746 }
1747 
1748 
named_pipe_conn_event_handler(void * arg)1749 extern "C" void *named_pipe_conn_event_handler(void *arg)
1750 {
1751   my_thread_init();
1752 
1753   Connection_acceptor<Named_pipe_listener> *conn_acceptor=
1754     static_cast<Connection_acceptor<Named_pipe_listener>*>(arg);
1755   conn_acceptor->connection_event_loop();
1756 
1757   decrement_handler_count();
1758   my_thread_end();
1759   return 0;
1760 }
1761 
1762 
shared_mem_conn_event_handler(void * arg)1763 extern "C" void *shared_mem_conn_event_handler(void *arg)
1764 {
1765   my_thread_init();
1766 
1767   Connection_acceptor<Shared_mem_listener> *conn_acceptor=
1768     static_cast<Connection_acceptor<Shared_mem_listener>*>(arg);
1769   conn_acceptor->connection_event_loop();
1770 
1771   decrement_handler_count();
1772   my_thread_end();
1773   return 0;
1774 }
1775 
1776 
setup_conn_event_handler_threads()1777 void setup_conn_event_handler_threads()
1778 {
1779   my_thread_handle hThread;
1780 
1781   DBUG_ENTER("handle_connections_methods");
1782 
1783   if ((!have_tcpip || opt_disable_networking) &&
1784       !opt_enable_shared_memory && !opt_enable_named_pipe)
1785   {
1786     sql_print_error("TCP/IP, --shared-memory, or --named-pipe should be configured on NT OS");
1787     unireg_abort(MYSQLD_ABORT_EXIT);        // Will not return
1788   }
1789 
1790   mysql_mutex_lock(&LOCK_handler_count);
1791   handler_count=0;
1792 
1793   if (opt_enable_named_pipe)
1794   {
1795     int error= mysql_thread_create(key_thread_handle_con_namedpipes,
1796                                    &hThread, &connection_attrib,
1797                                    named_pipe_conn_event_handler,
1798                                    named_pipe_acceptor);
1799     if (!error)
1800       handler_count++;
1801     else
1802       sql_print_warning("Can't create thread to handle named pipes"
1803                         " (errno= %d)", error);
1804   }
1805 
1806   if (have_tcpip && !opt_disable_networking)
1807   {
1808     int error= mysql_thread_create(key_thread_handle_con_sockets,
1809                                    &hThread, &connection_attrib,
1810                                    socket_conn_event_handler,
1811                                    mysqld_socket_acceptor);
1812     if (!error)
1813       handler_count++;
1814     else
1815       sql_print_warning("Can't create thread to handle TCP/IP (errno= %d)",
1816                         error);
1817   }
1818 
1819   if (opt_enable_shared_memory)
1820   {
1821     int error= mysql_thread_create(key_thread_handle_con_sharedmem,
1822                                    &hThread, &connection_attrib,
1823                                    shared_mem_conn_event_handler,
1824                                    shared_mem_acceptor);
1825     if (!error)
1826       handler_count++;
1827     else
1828       sql_print_warning("Can't create thread to handle shared memory"
1829                         " (errno= %d)", error);
1830   }
1831 
1832   // Block until all connection listener threads have exited.
1833   while (handler_count > 0)
1834     mysql_cond_wait(&COND_handler_count, &LOCK_handler_count);
1835   mysql_mutex_unlock(&LOCK_handler_count);
1836   DBUG_VOID_RETURN;
1837 }
1838 
1839 
1840 /*
1841   On Windows, we use native SetConsoleCtrlHandler for handle events like Ctrl-C
1842   with graceful shutdown.
1843   Also, we do not use signal(), but SetUnhandledExceptionFilter instead - as it
1844   provides possibility to pass the exception to just-in-time debugger, collect
1845   dumps and potentially also the exception and thread context used to output
1846   callstack.
1847 */
1848 
console_event_handler(DWORD type)1849 static BOOL WINAPI console_event_handler( DWORD type )
1850 {
1851   DBUG_ENTER("console_event_handler");
1852   if(type == CTRL_C_EVENT)
1853   {
1854      /*
1855        Do not shutdown before startup is finished and shutdown
1856        thread is initialized. Otherwise there is a race condition
1857        between main thread doing initialization and CTRL-C thread doing
1858        cleanup, which can result into crash.
1859      */
1860      if(hEventShutdown)
1861        kill_mysql();
1862      else
1863        sql_print_warning("CTRL-C ignored during startup");
1864      DBUG_RETURN(TRUE);
1865   }
1866   DBUG_RETURN(FALSE);
1867 }
1868 
1869 
1870 #ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER
1871 #define DEBUGGER_ATTACH_TIMEOUT 120
1872 /*
1873   Wait for debugger to attach and break into debugger. If debugger is not attached,
1874   resume after timeout.
1875 */
wait_for_debugger(int timeout_sec)1876 static void wait_for_debugger(int timeout_sec)
1877 {
1878    if(!IsDebuggerPresent())
1879    {
1880      int i;
1881      printf("Waiting for debugger to attach, pid=%u\n",GetCurrentProcessId());
1882      fflush(stdout);
1883      for(i= 0; i < timeout_sec; i++)
1884      {
1885        Sleep(1000);
1886        if(IsDebuggerPresent())
1887        {
1888          /* Break into debugger */
1889          __debugbreak();
1890          return;
1891        }
1892      }
1893      printf("pid=%u, debugger not attached after %d seconds, resuming\n",GetCurrentProcessId(),
1894        timeout_sec);
1895      fflush(stdout);
1896    }
1897 }
1898 #endif /* DEBUG_UNHANDLED_EXCEPTION_FILTER */
1899 
my_unhandler_exception_filter(EXCEPTION_POINTERS * ex_pointers)1900 LONG WINAPI my_unhandler_exception_filter(EXCEPTION_POINTERS *ex_pointers)
1901 {
1902    static BOOL first_time= TRUE;
1903    if(!first_time)
1904    {
1905      /*
1906        This routine can be called twice, typically
1907        when detaching in JIT debugger.
1908        Return EXCEPTION_EXECUTE_HANDLER to terminate process.
1909      */
1910      return EXCEPTION_EXECUTE_HANDLER;
1911    }
1912    first_time= FALSE;
1913 #ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER
1914    /*
1915     Unfortunately there is no clean way to debug unhandled exception filters,
1916     as debugger does not stop there(also documented in MSDN)
1917     To overcome, one could put a MessageBox, but this will not work in service.
1918     Better solution is to print error message and sleep some minutes
1919     until debugger is attached
1920   */
1921   wait_for_debugger(DEBUGGER_ATTACH_TIMEOUT);
1922 #endif /* DEBUG_UNHANDLED_EXCEPTION_FILTER */
1923   __try
1924   {
1925     my_set_exception_pointers(ex_pointers);
1926     handle_fatal_signal(ex_pointers->ExceptionRecord->ExceptionCode);
1927   }
1928   __except(EXCEPTION_EXECUTE_HANDLER)
1929   {
1930     DWORD written;
1931     const char msg[] = "Got exception in exception handler!\n";
1932     WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),msg, sizeof(msg)-1,
1933       &written,NULL);
1934   }
1935   /*
1936     Return EXCEPTION_CONTINUE_SEARCH to give JIT debugger
1937     (drwtsn32 or vsjitdebugger) possibility to attach,
1938     if JIT debugger is configured.
1939     Windows Error reporting might generate a dump here.
1940   */
1941   return EXCEPTION_CONTINUE_SEARCH;
1942 }
1943 
1944 
my_init_signals()1945 void my_init_signals()
1946 {
1947   if(opt_console)
1948     SetConsoleCtrlHandler(console_event_handler,TRUE);
1949 
1950     /* Avoid MessageBox()es*/
1951   _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
1952   _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
1953   _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
1954   _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
1955   _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
1956   _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
1957 
1958    /*
1959      Do not use SEM_NOGPFAULTERRORBOX in the following SetErrorMode (),
1960      because it would prevent JIT debugger and Windows error reporting
1961      from working. We need WER or JIT-debugging, since our own unhandled
1962      exception filter is not guaranteed to work in all situation
1963      (like heap corruption or stack overflow)
1964    */
1965   SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS
1966                                | SEM_NOOPENFILEERRORBOX);
1967   SetUnhandledExceptionFilter(my_unhandler_exception_filter);
1968 }
1969 
1970 #else // !_WIN32
1971 
1972 extern "C" {
empty_signal_handler(int sig MY_ATTRIBUTE ((unused)))1973 static void empty_signal_handler(int sig MY_ATTRIBUTE((unused)))
1974 { }
1975 }
1976 
1977 
my_init_signals()1978 void my_init_signals()
1979 {
1980   DBUG_ENTER("my_init_signals");
1981   struct sigaction sa;
1982   (void) sigemptyset(&sa.sa_mask);
1983 
1984   if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL))
1985   {
1986 #ifdef HAVE_STACKTRACE
1987     my_init_stacktrace();
1988 #endif
1989 
1990     if (test_flags & TEST_CORE_ON_SIGNAL)
1991     {
1992       // Change limits so that we will get a core file.
1993       struct rlimit rl;
1994       rl.rlim_cur= rl.rlim_max= RLIM_INFINITY;
1995       if (setrlimit(RLIMIT_CORE, &rl))
1996         sql_print_warning("setrlimit could not change the size of core files to"
1997                           " 'infinity';  We may not be able to generate a"
1998                           " core file on signals");
1999     }
2000 
2001     /*
2002       SA_RESETHAND resets handler action to default when entering handler.
2003       SA_NODEFER allows receiving the same signal during handler.
2004       E.g. SIGABRT during our signal handler will dump core (default action).
2005     */
2006     sa.sa_flags= SA_RESETHAND | SA_NODEFER;
2007     sa.sa_handler= handle_fatal_signal;
2008     // Treat all these as fatal and handle them.
2009     (void) sigaction(SIGSEGV, &sa, NULL);
2010     (void) sigaction(SIGABRT, &sa, NULL);
2011     (void) sigaction(SIGBUS, &sa, NULL);
2012     (void) sigaction(SIGILL, &sa, NULL);
2013     (void) sigaction(SIGFPE, &sa, NULL);
2014   }
2015 
2016   // Ignore SIGPIPE and SIGALRM
2017   sa.sa_flags= 0;
2018   sa.sa_handler= SIG_IGN;
2019   (void) sigaction(SIGPIPE, &sa, NULL);
2020   (void) sigaction(SIGALRM, &sa, NULL);
2021 
2022   // SIGUSR1 is used to interrupt the socket listener.
2023   sa.sa_handler= empty_signal_handler;
2024   (void) sigaction(SIGUSR1, &sa, NULL);
2025 
2026   // Fix signals if ignored by parents (can happen on Mac OS X).
2027   sa.sa_handler= SIG_DFL;
2028   (void) sigaction(SIGTERM, &sa, NULL);
2029   (void) sigaction(SIGHUP, &sa, NULL);
2030 
2031   sigset_t set;
2032   (void) sigemptyset(&set);
2033   /*
2034     Block SIGQUIT, SIGHUP and SIGTERM.
2035     The signal handler thread does sigwait() on these.
2036   */
2037   (void) sigaddset(&set, SIGQUIT);
2038   (void) sigaddset(&set, SIGHUP);
2039   (void) sigaddset(&set, SIGTERM);
2040   (void) sigaddset(&set, SIGTSTP);
2041   /*
2042     Block SIGINT unless debugging to prevent Ctrl+C from causing
2043     unclean shutdown of the server.
2044   */
2045   if (!(test_flags & TEST_SIGINT))
2046     (void) sigaddset(&set, SIGINT);
2047   pthread_sigmask(SIG_SETMASK, &set, NULL);
2048   DBUG_VOID_RETURN;
2049 }
2050 
2051 
start_signal_handler()2052 static void start_signal_handler()
2053 {
2054   int error;
2055   my_thread_attr_t thr_attr;
2056   DBUG_ENTER("start_signal_handler");
2057 
2058   (void) my_thread_attr_init(&thr_attr);
2059   (void) pthread_attr_setscope(&thr_attr, PTHREAD_SCOPE_SYSTEM);
2060   (void) my_thread_attr_setdetachstate(&thr_attr, MY_THREAD_CREATE_JOINABLE);
2061 
2062   size_t guardize= 0;
2063   (void) pthread_attr_getguardsize(&thr_attr, &guardize);
2064 #if defined(__ia64__) || defined(__ia64)
2065   /*
2066     Peculiar things with ia64 platforms - it seems we only have half the
2067     stack size in reality, so we have to double it here
2068   */
2069   guardize= my_thread_stack_size;
2070 #endif
2071   (void) my_thread_attr_setstacksize(&thr_attr, my_thread_stack_size + guardize);
2072 
2073   /*
2074     Set main_thread_id so that SIGTERM/SIGQUIT/SIGKILL can interrupt
2075     the socket listener successfully.
2076   */
2077   main_thread_id= my_thread_self();
2078 
2079   mysql_mutex_lock(&LOCK_start_signal_handler);
2080   if ((error=
2081        mysql_thread_create(key_thread_signal_hand,
2082                            &signal_thread_id, &thr_attr, signal_hand, 0)))
2083   {
2084     sql_print_error("Can't create interrupt-thread (error %d, errno: %d)",
2085                     error, errno);
2086     flush_error_log_messages();
2087     exit(MYSQLD_ABORT_EXIT);
2088   }
2089   mysql_cond_wait(&COND_start_signal_handler, &LOCK_start_signal_handler);
2090   mysql_mutex_unlock(&LOCK_start_signal_handler);
2091 
2092   (void) my_thread_attr_destroy(&thr_attr);
2093   DBUG_VOID_RETURN;
2094 }
2095 
2096 
2097 /** This thread handles SIGTERM, SIGQUIT and SIGHUP signals. */
2098 /* ARGSUSED */
signal_hand(void * arg MY_ATTRIBUTE ((unused)))2099 extern "C" void *signal_hand(void *arg MY_ATTRIBUTE((unused)))
2100 {
2101   my_thread_init();
2102 
2103   sigset_t set;
2104   (void) sigemptyset(&set);
2105   (void) sigaddset(&set, SIGTERM);
2106   (void) sigaddset(&set, SIGQUIT);
2107   (void) sigaddset(&set, SIGHUP);
2108 
2109   /*
2110     Signal to start_signal_handler that we are ready.
2111     This works by waiting for start_signal_handler to free mutex,
2112     after which we signal it that we are ready.
2113   */
2114   mysql_mutex_lock(&LOCK_start_signal_handler);
2115   mysql_cond_broadcast(&COND_start_signal_handler);
2116   mysql_mutex_unlock(&LOCK_start_signal_handler);
2117 
2118   /*
2119     Waiting until mysqld_server_started == true to ensure that all server
2120     components have been successfully initialized. This step is mandatory
2121     since signal processing can be done safely only when all server components
2122     have been initialized.
2123   */
2124   mysql_mutex_lock(&LOCK_server_started);
2125   while (!mysqld_server_started)
2126     mysql_cond_wait(&COND_server_started, &LOCK_server_started);
2127   mysql_mutex_unlock(&LOCK_server_started);
2128 
2129   for (;;)
2130   {
2131     int sig;
2132     while (sigwait(&set, &sig) == EINTR)
2133     {}
2134     if (cleanup_done)
2135     {
2136       my_thread_end();
2137       my_thread_exit(0);      // Safety
2138       return NULL;            // Avoid compiler warnings
2139     }
2140     switch (sig) {
2141     case SIGTERM:
2142     case SIGQUIT:
2143       // Switch to the file log message processing.
2144       query_logger.set_handlers((log_output_options != LOG_NONE) ?
2145                                 LOG_FILE : LOG_NONE);
2146       DBUG_PRINT("info", ("Got signal: %d  abort_loop: %d", sig, abort_loop));
2147       if (!abort_loop)
2148       {
2149         abort_loop= true;       // Mark abort for threads.
2150 #ifdef HAVE_PSI_THREAD_INTERFACE
2151         // Delete the instrumentation for the signal thread.
2152         PSI_THREAD_CALL(delete_current_thread)();
2153 #endif
2154         /*
2155           Kill the socket listener.
2156           The main thread will then set socket_listener_active= false,
2157           and wait for us to finish all the cleanup below.
2158         */
2159         mysql_mutex_lock(&LOCK_socket_listener_active);
2160         while (socket_listener_active)
2161         {
2162           DBUG_PRINT("info",("Killing socket listener"));
2163           if (pthread_kill(main_thread_id, SIGUSR1))
2164           {
2165             assert(false);
2166             break;
2167           }
2168           mysql_cond_wait(&COND_socket_listener_active,
2169                           &LOCK_socket_listener_active);
2170         }
2171         mysql_mutex_unlock(&LOCK_socket_listener_active);
2172 
2173         close_connections();
2174       }
2175       my_thread_end();
2176       my_thread_exit(0);
2177       return NULL;  // Avoid compiler warnings
2178       break;
2179     case SIGHUP:
2180       if (!abort_loop)
2181       {
2182         int not_used;
2183         mysql_print_status();   // Print some debug info
2184         reload_acl_and_cache(NULL,
2185                              (REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |
2186                               REFRESH_GRANT | REFRESH_THREADS | REFRESH_HOSTS),
2187                              NULL, &not_used); // Flush logs
2188         // Reenable query logs after the options were reloaded.
2189         query_logger.set_handlers(log_output_options);
2190       }
2191       break;
2192     default:
2193       break;          /* purecov: tested */
2194     }
2195   }
2196   return NULL;        /* purecov: deadcode */
2197 }
2198 
2199 #endif // !_WIN32
2200 #endif // !EMBEDDED_LIBRARY
2201 
2202 /**
2203   Starts processing signals initialized in the signal_hand function.
2204 
2205   @see signal_hand
2206 */
start_processing_signals()2207 static void start_processing_signals()
2208 {
2209   mysql_mutex_lock(&LOCK_server_started);
2210   mysqld_server_started= true;
2211   mysql_cond_broadcast(&COND_server_started);
2212   mysql_mutex_unlock(&LOCK_server_started);
2213 }
2214 
2215 #if HAVE_BACKTRACE && HAVE_ABI_CXA_DEMANGLE
2216 #include <cxxabi.h>
my_demangle(const char * mangled_name,int * status)2217 extern "C" char *my_demangle(const char *mangled_name, int *status)
2218 {
2219   return abi::__cxa_demangle(mangled_name, NULL, NULL, status);
2220 }
2221 #endif
2222 
2223 
2224 /**
2225   All global error messages are sent here where the first one is stored
2226   for the client.
2227 */
2228 /* ARGSUSED */
2229 extern "C" void my_message_sql(uint error, const char *str, myf MyFlags);
2230 
my_message_sql(uint error,const char * str,myf MyFlags)2231 void my_message_sql(uint error, const char *str, myf MyFlags)
2232 {
2233   THD *thd= current_thd;
2234   DBUG_ENTER("my_message_sql");
2235   DBUG_PRINT("error", ("error: %u  message: '%s'", error, str));
2236 
2237   assert(str != NULL);
2238   /*
2239     An error should have a valid error number (!= 0), so it can be caught
2240     in stored procedures by SQL exception handlers.
2241     Calling my_error() with error == 0 is a bug.
2242     Remaining known places to fix:
2243     - storage/myisam/mi_create.c, my_printf_error()
2244     TODO:
2245     assert(error != 0);
2246   */
2247 
2248   if (error == 0)
2249   {
2250     /* At least, prevent new abuse ... */
2251     assert(strncmp(str, "MyISAM table", 12) == 0);
2252     error= ER_UNKNOWN_ERROR;
2253   }
2254 
2255   if (thd)
2256   {
2257     Sql_condition::enum_severity_level level= Sql_condition::SL_ERROR;
2258 
2259     /**
2260       Reporting an error invokes audit API call that notifies the error
2261       to the plugin. Audit API that generate the error adds a protection
2262       (condition handler) that prevents entering infinite recursion, when
2263       a plugin signals error, when already handling the error.
2264 
2265       handle_condition is normally invoked from within raise_condition,
2266       but we need to prevent recursion befere notifying error to the plugin.
2267 
2268       Additionaly, handle_condition must be called once during reporting
2269       an error, so the raise_condition is called depending on the result of
2270       the handle_condition call.
2271     */
2272     bool handle= thd->handle_condition(error,
2273                                        mysql_errno_to_sqlstate(error),
2274                                        &level,
2275                                        str ? str : ER(error));
2276 #ifndef EMBEDDED_LIBRARY
2277     if (!handle)
2278       mysql_audit_notify(thd, AUDIT_EVENT(MYSQL_AUDIT_GENERAL_ERROR),
2279                          error, str, strlen(str));
2280 #endif
2281 
2282     if (MyFlags & ME_FATALERROR)
2283       thd->is_fatal_error= 1;
2284 
2285     if (!handle)
2286       (void) thd->raise_condition(error, NULL, level, str, false);
2287   }
2288 
2289   /* When simulating OOM, skip writing to error log to avoid mtr errors */
2290   DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_VOID_RETURN;);
2291 
2292   if (!thd || MyFlags & ME_ERRORLOG)
2293     sql_print_error("%s: %s",my_progname,str); /* purecov: inspected */
2294   DBUG_VOID_RETURN;
2295 }
2296 
2297 
2298 #ifndef EMBEDDED_LIBRARY
2299 extern "C" void *my_str_malloc_mysqld(size_t size);
2300 extern "C" void my_str_free_mysqld(void *ptr);
2301 extern "C" void *my_str_realloc_mysqld(void *ptr, size_t size);
2302 
my_str_malloc_mysqld(size_t size)2303 void *my_str_malloc_mysqld(size_t size)
2304 {
2305   return my_malloc(key_memory_my_str_malloc,
2306                    size, MYF(MY_FAE));
2307 }
2308 
2309 
my_str_free_mysqld(void * ptr)2310 void my_str_free_mysqld(void *ptr)
2311 {
2312   my_free(ptr);
2313 }
2314 
my_str_realloc_mysqld(void * ptr,size_t size)2315 void *my_str_realloc_mysqld(void *ptr, size_t size)
2316 {
2317   return my_realloc(key_memory_my_str_malloc,
2318                     ptr, size, MYF(MY_FAE));
2319 }
2320 #endif // !EMBEDDED_LIBRARY
2321 
2322 const char *load_default_groups[]= {
2323 #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
2324 "mysql_cluster",
2325 #endif
2326 "mysqld","server", MYSQL_BASE_VERSION, 0, 0};
2327 
2328 #if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
2329 static const int load_default_groups_sz=
2330 sizeof(load_default_groups)/sizeof(load_default_groups[0]);
2331 #endif
2332 
2333 #ifndef EMBEDDED_LIBRARY
2334 /**
2335   This function is used to check for stack overrun for pathological
2336   cases of regular expressions and 'like' expressions.
2337   The call to current_thd is quite expensive, so we try to avoid it
2338   for the normal cases.
2339   The size of each stack frame for the wildcmp() routines is ~128 bytes,
2340   so checking *every* recursive call is not necessary.
2341  */
2342 extern "C" int
check_enough_stack_size(int recurse_level)2343 check_enough_stack_size(int recurse_level)
2344 {
2345   uchar stack_top;
2346   if (recurse_level % 16 != 0)
2347     return 0;
2348 
2349   THD *my_thd= current_thd;
2350   if (my_thd != NULL)
2351     return check_stack_overrun(my_thd, STACK_MIN_SIZE * 2, &stack_top);
2352   return 0;
2353 }
2354 #endif
2355 
2356 
2357 /**
2358   Initialize one of the global date/time format variables.
2359 
2360   @param format_type    What kind of format should be supported
2361   @param var_ptr    Pointer to variable that should be updated
2362 
2363   @retval
2364     0 ok
2365   @retval
2366     1 error
2367 */
2368 
init_global_datetime_format(timestamp_type format_type,Date_time_format * format)2369 static bool init_global_datetime_format(timestamp_type format_type,
2370                                         Date_time_format *format)
2371 {
2372   /*
2373     Get command line option
2374     format->format.str is already set by my_getopt
2375   */
2376   format->format.length= strlen(format->format.str);
2377 
2378   if (parse_date_time_format(format_type, format))
2379   {
2380     sql_print_error("Wrong date/time format specifier: %s",
2381                     format->format.str);
2382     return true;
2383   }
2384   return false;
2385 }
2386 
2387 SHOW_VAR com_status_vars[]= {
2388   {"admin_commands",       (char*) offsetof(STATUS_VAR, com_other),                                          SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2389   {"assign_to_keycache",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ASSIGN_TO_KEYCACHE]),         SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2390   {"alter_db",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_DB]),                   SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2391   {"alter_db_upgrade",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_DB_UPGRADE]),           SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2392   {"alter_event",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_EVENT]),                SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2393   {"alter_function",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_FUNCTION]),             SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2394   {"alter_instance",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_INSTANCE]),             SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2395   {"alter_procedure",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_PROCEDURE]),            SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2396   {"alter_server",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_SERVER]),               SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2397   {"alter_table",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_TABLE]),                SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2398   {"alter_tablespace",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_TABLESPACE]),           SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2399   {"alter_user",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_USER]),                 SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2400   {"analyze",              (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ANALYZE]),                    SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2401   {"begin",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BEGIN]),                      SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2402   {"binlog",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BINLOG_BASE64_EVENT]),        SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2403   {"call_procedure",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CALL]),                       SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2404   {"change_db",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHANGE_DB]),                  SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2405   {"change_master",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHANGE_MASTER]),              SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2406   {"change_repl_filter",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHANGE_REPLICATION_FILTER]),  SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2407   {"check",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHECK]),                      SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2408   {"checksum",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHECKSUM]),                   SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2409   {"commit",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_COMMIT]),                     SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2410   {"create_db",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_DB]),                  SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2411   {"create_event",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_EVENT]),               SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2412   {"create_function",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_SPFUNCTION]),          SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2413   {"create_index",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_INDEX]),               SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2414   {"create_procedure",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_PROCEDURE]),           SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2415   {"create_server",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_SERVER]),              SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2416   {"create_table",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_TABLE]),               SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2417   {"create_trigger",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_TRIGGER]),             SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2418   {"create_udf",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_FUNCTION]),            SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2419   {"create_user",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_USER]),                SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2420   {"create_view",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_VIEW]),                SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2421   {"dealloc_sql",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DEALLOCATE_PREPARE]),         SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2422   {"delete",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DELETE]),                     SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2423   {"delete_multi",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DELETE_MULTI]),               SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2424   {"do",                   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DO]),                         SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2425   {"drop_db",              (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_DB]),                    SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2426   {"drop_event",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_EVENT]),                 SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2427   {"drop_function",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_FUNCTION]),              SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2428   {"drop_index",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_INDEX]),                 SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2429   {"drop_procedure",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_PROCEDURE]),             SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2430   {"drop_server",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_SERVER]),                SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2431   {"drop_table",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_TABLE]),                 SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2432   {"drop_trigger",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_TRIGGER]),               SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2433   {"drop_user",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_USER]),                  SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2434   {"drop_view",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_VIEW]),                  SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2435   {"empty_query",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EMPTY_QUERY]),                SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2436   {"execute_sql",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EXECUTE]),                    SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2437   {"explain_other",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EXPLAIN_OTHER]),              SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2438   {"flush",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_FLUSH]),                      SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2439   {"get_diagnostics",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_GET_DIAGNOSTICS]),            SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2440   {"grant",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_GRANT]),                      SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2441   {"ha_close",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_CLOSE]),                   SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2442   {"ha_open",              (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_OPEN]),                    SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2443   {"ha_read",              (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_READ]),                    SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2444   {"help",                 (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HELP]),                       SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2445   {"insert",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_INSERT]),                     SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2446   {"insert_select",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_INSERT_SELECT]),              SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2447   {"install_plugin",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_INSTALL_PLUGIN]),             SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2448   {"kill",                 (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_KILL]),                       SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2449   {"load",                 (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOAD]),                       SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2450   {"lock_tables",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOCK_TABLES]),                SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2451   {"optimize",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_OPTIMIZE]),                   SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2452   {"preload_keys",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PRELOAD_KEYS]),               SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2453   {"prepare_sql",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PREPARE]),                    SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2454   {"purge",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PURGE]),                      SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2455   {"purge_before_date",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PURGE_BEFORE]),               SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2456   {"release_savepoint",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RELEASE_SAVEPOINT]),          SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2457   {"rename_table",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RENAME_TABLE]),               SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2458   {"rename_user",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RENAME_USER]),                SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2459   {"repair",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPAIR]),                     SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2460   {"replace",              (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPLACE]),                    SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2461   {"replace_select",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPLACE_SELECT]),             SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2462   {"reset",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RESET]),                      SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2463   {"resignal",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RESIGNAL]),                   SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2464   {"revoke",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REVOKE]),                     SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2465   {"revoke_all",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REVOKE_ALL]),                 SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2466   {"rollback",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ROLLBACK]),                   SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2467   {"rollback_to_savepoint",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ROLLBACK_TO_SAVEPOINT]),      SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2468   {"savepoint",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SAVEPOINT]),                  SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2469   {"select",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SELECT]),                     SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2470   {"set_option",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SET_OPTION]),                 SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2471   {"signal",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SIGNAL]),                     SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2472   {"show_binlog_events",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOG_EVENTS]),         SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2473   {"show_binlogs",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOGS]),               SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2474   {"show_charsets",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CHARSETS]),              SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2475   {"show_collations",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLLATIONS]),            SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2476   {"show_create_db",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_DB]),             SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2477   {"show_create_event",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_EVENT]),          SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2478   {"show_create_func",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_FUNC]),           SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2479   {"show_create_proc",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_PROC]),           SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2480   {"show_create_table",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE]),                SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2481   {"show_create_trigger",  (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_TRIGGER]),        SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2482   {"show_databases",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_DATABASES]),             SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2483   {"show_engine_logs",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_LOGS]),           SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2484   {"show_engine_mutex",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_MUTEX]),          SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2485   {"show_engine_status",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_STATUS]),         SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2486   {"show_events",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_EVENTS]),                SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2487   {"show_errors",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ERRORS]),                SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2488   {"show_fields",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_FIELDS]),                SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2489   {"show_function_code",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_FUNC_CODE]),             SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2490   {"show_function_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS_FUNC]),           SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2491   {"show_grants",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_GRANTS]),                SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2492   {"show_keys",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_KEYS]),                  SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2493   {"show_master_status",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_MASTER_STAT]),           SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2494   {"show_open_tables",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_OPEN_TABLES]),           SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2495   {"show_plugins",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PLUGINS]),               SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2496   {"show_privileges",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PRIVILEGES]),            SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2497   {"show_procedure_code",  (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROC_CODE]),             SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2498   {"show_procedure_status",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS_PROC]),           SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2499   {"show_processlist",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROCESSLIST]),           SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2500   {"show_profile",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROFILE]),               SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2501   {"show_profiles",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROFILES]),              SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2502   {"show_relaylog_events", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_RELAYLOG_EVENTS]),       SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2503   {"show_slave_hosts",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_HOSTS]),           SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2504   {"show_slave_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_STAT]),            SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2505   {"show_status",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS]),                SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2506   {"show_storage_engines", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STORAGE_ENGINES]),       SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2507   {"show_table_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATUS]),          SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2508   {"show_tables",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLES]),                SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2509   {"show_triggers",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TRIGGERS]),              SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2510   {"show_variables",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_VARIABLES]),             SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2511   {"show_warnings",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_WARNS]),                 SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2512   {"show_create_user",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_USER]),           SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2513   {"shutdown",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHUTDOWN]),                   SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2514   {"slave_start",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_START]),                SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2515   {"slave_stop",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_STOP]),                 SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2516   {"group_replication_start", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_START_GROUP_REPLICATION]), SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2517   {"group_replication_stop",  (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_STOP_GROUP_REPLICATION]),  SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2518   {"stmt_execute",         (char*) offsetof(STATUS_VAR, com_stmt_execute),                                   SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2519   {"stmt_close",           (char*) offsetof(STATUS_VAR, com_stmt_close),                                     SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2520   {"stmt_fetch",           (char*) offsetof(STATUS_VAR, com_stmt_fetch),                                     SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2521   {"stmt_prepare",         (char*) offsetof(STATUS_VAR, com_stmt_prepare),                                   SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2522   {"stmt_reset",           (char*) offsetof(STATUS_VAR, com_stmt_reset),                                     SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2523   {"stmt_send_long_data",  (char*) offsetof(STATUS_VAR, com_stmt_send_long_data),                            SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2524   {"truncate",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_TRUNCATE]),                   SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2525   {"uninstall_plugin",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNINSTALL_PLUGIN]),           SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2526   {"unlock_tables",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNLOCK_TABLES]),              SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2527   {"update",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UPDATE]),                     SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2528   {"update_multi",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UPDATE_MULTI]),               SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2529   {"xa_commit",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_COMMIT]),                  SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2530   {"xa_end",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_END]),                     SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2531   {"xa_prepare",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_PREPARE]),                 SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2532   {"xa_recover",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_RECOVER]),                 SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2533   {"xa_rollback",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_ROLLBACK]),                SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2534   {"xa_start",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_START]),                   SHOW_LONG_STATUS, SHOW_SCOPE_ALL},
2535   {NullS, NullS, SHOW_LONG, SHOW_SCOPE_ALL}
2536 };
2537 
2538 
2539 #ifndef EMBEDDED_LIBRARY
2540 LEX_CSTRING sql_statement_names[(uint) SQLCOM_END + 1];
2541 
init_sql_statement_names()2542 static void init_sql_statement_names()
2543 {
2544   static LEX_CSTRING empty= { C_STRING_WITH_LEN("") };
2545 
2546   char *first_com= (char*) offsetof(STATUS_VAR, com_stat[0]);
2547   char *last_com= (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_END]);
2548   int record_size= (char*) offsetof(STATUS_VAR, com_stat[1])
2549                    - (char*) offsetof(STATUS_VAR, com_stat[0]);
2550   char *ptr;
2551   uint i;
2552   uint com_index;
2553 
2554   for (i= 0; i < ((uint) SQLCOM_END + 1); i++)
2555     sql_statement_names[i]= empty;
2556 
2557   SHOW_VAR *var= &com_status_vars[0];
2558   while (var->name != NULL)
2559   {
2560     ptr= var->value;
2561     if ((first_com <= ptr) && (ptr <= last_com))
2562     {
2563       com_index= ((int)(ptr - first_com))/record_size;
2564       assert(com_index < (uint) SQLCOM_END);
2565       sql_statement_names[com_index].str= var->name;
2566       /* TODO: Change SHOW_VAR::name to a LEX_STRING, to avoid strlen() */
2567       sql_statement_names[com_index].length= strlen(var->name);
2568     }
2569     var++;
2570   }
2571 
2572   assert(strcmp(sql_statement_names[(uint) SQLCOM_SELECT].str, "select") == 0);
2573   assert(strcmp(sql_statement_names[(uint) SQLCOM_SIGNAL].str, "signal") == 0);
2574 
2575   sql_statement_names[(uint) SQLCOM_END].str= "error";
2576 }
2577 #endif // !EMBEDDED_LIBRARY
2578 
2579 #ifdef HAVE_PSI_STATEMENT_INTERFACE
2580 PSI_statement_info sql_statement_info[(uint) SQLCOM_END + 1];
2581 PSI_statement_info com_statement_info[(uint) COM_END + 1];
2582 PSI_statement_info stmt_info_new_packet;
2583 
2584 /**
2585   Initialize the command names array.
2586   Since we do not want to maintain a separate array,
2587   this is populated from data mined in com_status_vars,
2588   which already has one name for each command.
2589 */
init_sql_statement_info()2590 void init_sql_statement_info()
2591 {
2592   uint i;
2593 
2594   for (i= 0; i < ((uint) SQLCOM_END + 1); i++)
2595   {
2596     sql_statement_info[i].m_name= sql_statement_names[i].str;
2597     sql_statement_info[i].m_flags= 0;
2598   }
2599 
2600   /* "statement/sql/error" represents broken queries (syntax error). */
2601   sql_statement_info[(uint) SQLCOM_END].m_name= "error";
2602   sql_statement_info[(uint) SQLCOM_END].m_flags= 0;
2603 }
2604 
init_com_statement_info()2605 void init_com_statement_info()
2606 {
2607   uint index;
2608 
2609   for (index= 0; index < (uint) COM_END + 1; index++)
2610   {
2611     com_statement_info[index].m_name= command_name[index].str;
2612     com_statement_info[index].m_flags= 0;
2613   }
2614 
2615   /* "statement/abstract/query" can mutate into "statement/sql/..." */
2616   com_statement_info[(uint) COM_QUERY].m_flags= PSI_FLAG_MUTABLE;
2617 }
2618 #endif
2619 
2620 /**
2621   Create a replication file name or base for file names.
2622 
2623   @param[in] opt Value of option, or NULL
2624   @param[in] def Default value if option value is not set.
2625   @param[in] ext Extension to use for the path
2626 
2627   @returns Pointer to string containing the full file path, or NULL if
2628   it was not possible to create the path.
2629  */
2630 static inline const char *
rpl_make_log_name(PSI_memory_key key,const char * opt,const char * def,const char * ext)2631 rpl_make_log_name(PSI_memory_key key,
2632                   const char *opt,
2633                   const char *def,
2634                   const char *ext)
2635 {
2636   DBUG_ENTER("rpl_make_log_name");
2637   DBUG_PRINT("enter", ("opt: %s, def: %s, ext: %s", (opt && opt[0])? opt : "", def, ext));
2638   char buff[FN_REFLEN];
2639   /*
2640     opt[0] needs to be checked to make sure opt name is not an empty
2641     string, incase it is an empty string default name will be considered
2642   */
2643   const char *base= (opt && opt[0]) ? opt : def;
2644   unsigned int options=
2645     MY_REPLACE_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH;
2646 
2647   /* mysql_real_data_home_ptr may be null if no value of datadir has been
2648      specified through command-line or througha cnf file. If that is the
2649      case we make mysql_real_data_home_ptr point to mysql_real_data_home
2650      which, in that case holds the default path for data-dir.
2651   */
2652 
2653   DBUG_EXECUTE_IF("emulate_empty_datadir_param",
2654                   {
2655                     mysql_real_data_home_ptr= NULL;
2656                   };
2657                  );
2658 
2659   if(mysql_real_data_home_ptr == NULL)
2660     mysql_real_data_home_ptr= mysql_real_data_home;
2661 
2662   if (fn_format(buff, base, mysql_real_data_home_ptr, ext, options))
2663     DBUG_RETURN(my_strdup(key, buff, MYF(0)));
2664   else
2665     DBUG_RETURN(NULL);
2666 }
2667 
2668 
init_common_variables()2669 int init_common_variables()
2670 {
2671   umask(((~my_umask) & 0666));
2672   my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
2673   tzset();      // Set tzname
2674 
2675   max_system_variables.pseudo_thread_id= (my_thread_id) ~0;
2676   server_start_time= flush_status_time= my_time(0);
2677 
2678   rpl_filter= new Rpl_filter;
2679   binlog_filter= new Rpl_filter;
2680   if (!rpl_filter || !binlog_filter)
2681   {
2682     sql_print_error("Could not allocate replication and binlog filters: %s",
2683                     strerror(errno));
2684     return 1;
2685   }
2686 
2687   if (init_thread_environment() ||
2688       mysql_init_variables())
2689     return 1;
2690 
2691   ignore_db_dirs_init();
2692 
2693   {
2694     struct tm tm_tmp;
2695     localtime_r(&server_start_time,&tm_tmp);
2696 #ifdef _WIN32
2697     strmake(system_time_zone, _tzname[tm_tmp.tm_isdst != 0 ? 1 : 0],
2698             sizeof(system_time_zone) - 1);
2699 #else
2700     strmake(system_time_zone, tzname[tm_tmp.tm_isdst != 0 ? 1 : 0],
2701             sizeof(system_time_zone)-1);
2702 #endif
2703 
2704  }
2705 
2706   /*
2707     We set SYSTEM time zone as reasonable default and
2708     also for failure of my_tz_init() and bootstrap mode.
2709     If user explicitly set time zone with --default-time-zone
2710     option we will change this value in my_tz_init().
2711   */
2712   global_system_variables.time_zone= my_tz_SYSTEM;
2713 
2714 #ifdef HAVE_PSI_INTERFACE
2715   /*
2716     Complete the mysql_bin_log initialization.
2717     Instrumentation keys are known only after the performance schema initialization,
2718     and can not be set in the MYSQL_BIN_LOG constructor (called before main()).
2719   */
2720   mysql_bin_log.set_psi_keys(key_BINLOG_LOCK_index,
2721                              key_BINLOG_LOCK_commit,
2722                              key_BINLOG_LOCK_commit_queue,
2723                              key_BINLOG_LOCK_done,
2724                              key_BINLOG_LOCK_flush_queue,
2725                              key_BINLOG_LOCK_log,
2726                              key_BINLOG_LOCK_binlog_end_pos,
2727                              key_BINLOG_LOCK_sync,
2728                              key_BINLOG_LOCK_sync_queue,
2729                              key_BINLOG_LOCK_xids,
2730                              key_BINLOG_COND_done,
2731                              key_BINLOG_update_cond,
2732                              key_BINLOG_prep_xids_cond,
2733                              key_file_binlog,
2734                              key_file_binlog_index,
2735                              key_file_binlog_cache,
2736                              key_file_binlog_index_cache);
2737 #endif
2738 
2739   /*
2740     Init mutexes for the global MYSQL_BIN_LOG objects.
2741     As safe_mutex depends on what MY_INIT() does, we can't init the mutexes of
2742     global MYSQL_BIN_LOGs in their constructors, because then they would be
2743     inited before MY_INIT(). So we do it here.
2744   */
2745   mysql_bin_log.init_pthread_objects();
2746 
2747   /* TODO: remove this when my_time_t is 64 bit compatible */
2748   if (!IS_TIME_T_VALID_FOR_TIMESTAMP(server_start_time))
2749   {
2750     sql_print_error("This MySQL server doesn't support dates later than 2038");
2751     return 1;
2752   }
2753 
2754   if (gethostname(glob_hostname,sizeof(glob_hostname)) < 0)
2755   {
2756     strmake(glob_hostname, STRING_WITH_LEN("localhost"));
2757     sql_print_warning("gethostname failed, using '%s' as hostname",
2758                       glob_hostname);
2759     strmake(default_logfile_name, STRING_WITH_LEN("mysql"));
2760   }
2761   else
2762     strmake(default_logfile_name, glob_hostname,
2763       sizeof(default_logfile_name)-5);
2764 
2765   strmake(pidfile_name, default_logfile_name, sizeof(pidfile_name)-5);
2766   my_stpcpy(fn_ext(pidfile_name),".pid");    // Add proper extension
2767 
2768 
2769   /*
2770     The default-storage-engine entry in my_long_options should have a
2771     non-null default value. It was earlier intialized as
2772     (longlong)"MyISAM" in my_long_options but this triggered a
2773     compiler error in the Sun Studio 12 compiler. As a work-around we
2774     set the def_value member to 0 in my_long_options and initialize it
2775     to the correct value here.
2776 
2777     From MySQL 5.5 onwards, the default storage engine is InnoDB
2778     (except in the embedded server, where the default continues to
2779     be MyISAM)
2780   */
2781 #ifdef EMBEDDED_LIBRARY
2782   default_storage_engine= const_cast<char *>("MyISAM");
2783 #else
2784   default_storage_engine= const_cast<char *>("InnoDB");
2785 #endif
2786   default_tmp_storage_engine= default_storage_engine;
2787 
2788 
2789   /*
2790     Add server status variables to the dynamic list of
2791     status variables that is shown by SHOW STATUS.
2792     Later, in plugin_init, and mysql_install_plugin
2793     new entries could be added to that list.
2794   */
2795   if (add_status_vars(status_vars))
2796     return 1; // an error was already reported
2797 
2798 #ifndef NDEBUG
2799   /*
2800     We have few debug-only commands in com_status_vars, only visible in debug
2801     builds. for simplicity we enable the assert only in debug builds
2802 
2803     There are 8 Com_ variables which don't have corresponding SQLCOM_ values:
2804     (TODO strictly speaking they shouldn't be here, should not have Com_ prefix
2805     that is. Perhaps Stmt_ ? Comstmt_ ? Prepstmt_ ?)
2806 
2807       Com_admin_commands       => com_other
2808       Com_stmt_close           => com_stmt_close
2809       Com_stmt_execute         => com_stmt_execute
2810       Com_stmt_fetch           => com_stmt_fetch
2811       Com_stmt_prepare         => com_stmt_prepare
2812       Com_stmt_reprepare       => com_stmt_reprepare
2813       Com_stmt_reset           => com_stmt_reset
2814       Com_stmt_send_long_data  => com_stmt_send_long_data
2815 
2816     With this correction the number of Com_ variables (number of elements in
2817     the array, excluding the last element - terminator) must match the number
2818     of SQLCOM_ constants.
2819   */
2820   compile_time_assert(sizeof(com_status_vars)/sizeof(com_status_vars[0]) - 1 ==
2821                      SQLCOM_END + 7);
2822 #endif
2823 
2824   if (get_options(&remaining_argc, &remaining_argv))
2825     return 1;
2826 
2827   update_parser_max_mem_size();
2828 
2829   if (log_syslog_init())
2830     opt_log_syslog_enable= 0;
2831 
2832   if (set_default_auth_plugin(default_auth_plugin, strlen(default_auth_plugin)))
2833   {
2834     sql_print_error("Can't start server: "
2835 		    "Invalid value for --default-authentication-plugin");
2836     return 1;
2837   }
2838   set_server_version();
2839 
2840   log_warnings= log_error_verbosity - 1; // backward compatibility
2841 
2842   sql_print_information("%s (mysqld %s) starting as process %lu ...",
2843                         my_progname, server_version, (ulong) getpid());
2844 
2845 
2846 #ifndef EMBEDDED_LIBRARY
2847   if (opt_help && !opt_verbose)
2848     unireg_abort(MYSQLD_SUCCESS_EXIT);
2849 #endif /*!EMBEDDED_LIBRARY*/
2850 
2851   DBUG_PRINT("info",("%s  Ver %s for %s on %s\n",my_progname,
2852          server_version, SYSTEM_TYPE,MACHINE_TYPE));
2853 
2854 #ifdef HAVE_LINUX_LARGE_PAGES
2855   /* Initialize large page size */
2856   if (opt_large_pages && (opt_large_page_size= my_get_large_page_size()))
2857   {
2858       DBUG_PRINT("info", ("Large page set, large_page_size = %d",
2859                  opt_large_page_size));
2860       my_use_large_pages= 1;
2861       my_large_page_size= opt_large_page_size;
2862   }
2863   else
2864   {
2865     opt_large_pages= 0;
2866     /*
2867        Either not configured to use large pages or Linux haven't
2868        been compiled with large page support
2869     */
2870   }
2871 #endif /* HAVE_LINUX_LARGE_PAGES */
2872 #ifdef HAVE_SOLARIS_LARGE_PAGES
2873 #define LARGE_PAGESIZE (4*1024*1024)  /* 4MB */
2874 #define SUPER_LARGE_PAGESIZE (256*1024*1024)  /* 256MB */
2875   if (opt_large_pages)
2876   {
2877   /*
2878     tell the kernel that we want to use 4/256MB page for heap storage
2879     and also for the stack. We use 4 MByte as default and if the
2880     super-large-page is set we increase it to 256 MByte. 256 MByte
2881     is for server installations with GBytes of RAM memory where
2882     the MySQL Server will have page caches and other memory regions
2883     measured in a number of GBytes.
2884     We use as big pages as possible which isn't bigger than the above
2885     desired page sizes.
2886   */
2887    int nelem;
2888    size_t max_desired_page_size;
2889    if (opt_super_large_pages)
2890      max_desired_page_size= SUPER_LARGE_PAGESIZE;
2891    else
2892      max_desired_page_size= LARGE_PAGESIZE;
2893    nelem = getpagesizes(NULL, 0);
2894    if (nelem > 0)
2895    {
2896      size_t *pagesize = (size_t *) malloc(sizeof(size_t) * nelem);
2897      if (pagesize != NULL && getpagesizes(pagesize, nelem) > 0)
2898      {
2899        size_t max_page_size= 0;
2900        for (int i= 0; i < nelem; i++)
2901        {
2902          if (pagesize[i] > max_page_size &&
2903              pagesize[i] <= max_desired_page_size)
2904             max_page_size= pagesize[i];
2905        }
2906        free(pagesize);
2907        if (max_page_size > 0)
2908        {
2909          struct memcntl_mha mpss;
2910 
2911          mpss.mha_cmd= MHA_MAPSIZE_BSSBRK;
2912          mpss.mha_pagesize= max_page_size;
2913          mpss.mha_flags= 0;
2914          memcntl(NULL, 0, MC_HAT_ADVISE, (caddr_t)&mpss, 0, 0);
2915          mpss.mha_cmd= MHA_MAPSIZE_STACK;
2916          memcntl(NULL, 0, MC_HAT_ADVISE, (caddr_t)&mpss, 0, 0);
2917        }
2918      }
2919    }
2920   }
2921 #endif /* HAVE_SOLARIS_LARGE_PAGES */
2922 
2923   longlong default_value;
2924   sys_var *var;
2925 #ifndef EMBEDDED_LIBRARY
2926   /* Calculate and update default value for thread_cache_size. */
2927   if ((default_value= 8 + max_connections / 100) > 100)
2928     default_value= 100;
2929   var= intern_find_sys_var(STRING_WITH_LEN("thread_cache_size"));
2930   var->update_default(default_value);
2931 #endif
2932 
2933   /* Calculate and update default value for host_cache_size. */
2934   if ((default_value= 128 + max_connections) > 628 &&
2935       (default_value= 628 + ((max_connections - 500) / 20)) > 2000)
2936     default_value= 2000;
2937   var= intern_find_sys_var(STRING_WITH_LEN("host_cache_size"));
2938   var->update_default(default_value);
2939 
2940 #ifndef EMBEDDED_LIBRARY
2941   /* Fix thread_cache_size. */
2942   if (!thread_cache_size_specified &&
2943       (Per_thread_connection_handler::max_blocked_pthreads=
2944        8 + max_connections / 100) > 100)
2945     Per_thread_connection_handler::max_blocked_pthreads= 100;
2946 #endif // !EMBEDDED_LIBRARY
2947 
2948   /* Fix host_cache_size. */
2949   if (!host_cache_size_specified &&
2950       (host_cache_size= 128 + max_connections) > 628 &&
2951       (host_cache_size= 628 + ((max_connections - 500) / 20)) > 2000)
2952     host_cache_size= 2000;
2953 
2954   /* Fix back_log */
2955   if (back_log == 0 && (back_log= 50 + max_connections / 5) > 900)
2956     back_log= 900;
2957 
2958   unireg_init(opt_specialflag); /* Set up extern variabels */
2959   if (!(my_default_lc_messages=
2960         my_locale_by_name(lc_messages)))
2961   {
2962     sql_print_error("Unknown locale: '%s'", lc_messages);
2963     return 1;
2964   }
2965   global_system_variables.lc_messages= my_default_lc_messages;
2966   if (init_errmessage())  /* Read error messages from file */
2967     return 1;
2968   init_client_errs();
2969 
2970   mysql_client_plugin_init();
2971   if (item_create_init())
2972     return 1;
2973   item_init();
2974 #ifndef EMBEDDED_LIBRARY
2975   my_regex_init(&my_charset_latin1, check_enough_stack_size);
2976   my_string_stack_guard= check_enough_stack_size;
2977 #else
2978   my_regex_init(&my_charset_latin1, NULL);
2979 #endif
2980   /*
2981     Process a comma-separated character set list and choose
2982     the first available character set. This is mostly for
2983     test purposes, to be able to start "mysqld" even if
2984     the requested character set is not available (see bug#18743).
2985   */
2986   for (;;)
2987   {
2988     char *next_character_set_name= strchr(default_character_set_name, ',');
2989     if (next_character_set_name)
2990       *next_character_set_name++= '\0';
2991     if (!(default_charset_info=
2992           get_charset_by_csname(default_character_set_name,
2993                                 MY_CS_PRIMARY, MYF(MY_WME))))
2994     {
2995       if (next_character_set_name)
2996       {
2997         default_character_set_name= next_character_set_name;
2998         default_collation_name= 0;          // Ignore collation
2999       }
3000       else
3001         return 1;                           // Eof of the list
3002     }
3003     else
3004       break;
3005   }
3006 
3007   if (default_collation_name)
3008   {
3009     CHARSET_INFO *default_collation;
3010     default_collation= get_charset_by_name(default_collation_name, MYF(0));
3011     if (!default_collation)
3012     {
3013       sql_print_error(ER_DEFAULT(ER_UNKNOWN_COLLATION), default_collation_name);
3014       return 1;
3015     }
3016     if (!my_charset_same(default_charset_info, default_collation))
3017     {
3018       sql_print_error(ER_DEFAULT(ER_COLLATION_CHARSET_MISMATCH),
3019           default_collation_name,
3020           default_charset_info->csname);
3021       return 1;
3022     }
3023     default_charset_info= default_collation;
3024   }
3025   /* Set collactions that depends on the default collation */
3026   global_system_variables.collation_server=  default_charset_info;
3027   global_system_variables.collation_database=  default_charset_info;
3028 
3029   if (is_supported_parser_charset(default_charset_info))
3030   {
3031     global_system_variables.collation_connection= default_charset_info;
3032     global_system_variables.character_set_results= default_charset_info;
3033     global_system_variables.character_set_client= default_charset_info;
3034   }
3035   else
3036   {
3037     sql_print_information("'%s' can not be used as client character set. "
3038                           "'%s' will be used as default client character set.",
3039                           default_charset_info->csname,
3040                           my_charset_latin1.csname);
3041     global_system_variables.collation_connection= &my_charset_latin1;
3042     global_system_variables.character_set_results= &my_charset_latin1;
3043     global_system_variables.character_set_client= &my_charset_latin1;
3044   }
3045 
3046   if (!(character_set_filesystem=
3047         get_charset_by_csname(character_set_filesystem_name,
3048                               MY_CS_PRIMARY, MYF(MY_WME))))
3049     return 1;
3050   global_system_variables.character_set_filesystem= character_set_filesystem;
3051 
3052   if (lex_init())
3053   {
3054     sql_print_error("Out of memory");
3055     return 1;
3056   }
3057 
3058   if (!(my_default_lc_time_names=
3059         my_locale_by_name(lc_time_names_name)))
3060   {
3061     sql_print_error("Unknown locale: '%s'", lc_time_names_name);
3062     return 1;
3063   }
3064   global_system_variables.lc_time_names= my_default_lc_time_names;
3065 
3066   /* check log options and issue warnings if needed */
3067   if (opt_general_log && opt_general_logname && !(log_output_options & LOG_FILE) &&
3068       !(log_output_options & LOG_NONE))
3069     sql_print_warning("Although a path was specified for the "
3070                       "--general-log-file option, log tables are used. "
3071                       "To enable logging to files use the --log-output=file option.");
3072 
3073   if (opt_slow_log && opt_slow_logname && !(log_output_options & LOG_FILE)
3074       && !(log_output_options & LOG_NONE))
3075     sql_print_warning("Although a path was specified for the "
3076                       "--slow-query-log-file option, log tables are used. "
3077                       "To enable logging to files use the --log-output=file option.");
3078 
3079   if (opt_general_logname &&
3080       !is_valid_log_name(opt_general_logname, strlen(opt_general_logname)))
3081   {
3082     sql_print_error("Invalid value for --general_log_file: %s",
3083                     opt_general_logname);
3084     return 1;
3085   }
3086 
3087   if (opt_slow_logname &&
3088       !is_valid_log_name(opt_slow_logname, strlen(opt_slow_logname)))
3089   {
3090     sql_print_error("Invalid value for --slow_query_log_file: %s",
3091                     opt_slow_logname);
3092     return 1;
3093   }
3094 
3095   /* We set the atomic field m_opt_tracking_mode to the value of the sysvar
3096      variable m_opt_tracking_mode_value here, as it now has the user given
3097      value
3098   */
3099   set_mysqld_opt_tracking_mode();
3100   if (global_system_variables.transaction_write_set_extraction == HASH_ALGORITHM_OFF
3101       && mysql_bin_log.m_dependency_tracker.m_opt_tracking_mode != DEPENDENCY_TRACKING_COMMIT_ORDER)
3102   {
3103     sql_print_error("The transaction_write_set_extraction must be set to XXHASH64 or MURMUR32"
3104                     " when binlog_transaction_dependency_tracking is WRITESET or WRITESET_SESSION.");
3105     return 1;
3106   }
3107   else
3108     mysql_bin_log.m_dependency_tracker.tracking_mode_changed();
3109 
3110   my_atomic_store64(&mysql_bin_log.m_dependency_tracker.get_writeset()->m_opt_max_history_size,
3111                     static_cast<int64>(mysql_bin_log.m_dependency_tracker.
3112                         get_writeset()->m_opt_max_history_size_base_var));
3113 
3114 
3115 #define FIX_LOG_VAR(VAR, ALT)                                   \
3116   if (!VAR || !*VAR)                                            \
3117     VAR= ALT;
3118 
3119   FIX_LOG_VAR(opt_general_logname,
3120               make_query_log_name(logname_path, QUERY_LOG_GENERAL));
3121   FIX_LOG_VAR(opt_slow_logname,
3122               make_query_log_name(slow_logname_path, QUERY_LOG_SLOW));
3123 
3124 #if defined(ENABLED_DEBUG_SYNC)
3125   /* Initialize the debug sync facility. See debug_sync.cc. */
3126   if (debug_sync_init())
3127     return 1; /* purecov: tested */
3128 #endif /* defined(ENABLED_DEBUG_SYNC) */
3129 
3130 #if defined(__linux__)
3131   if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
3132     return 1;
3133 #else
3134   use_temp_pool= 0;
3135 #endif
3136 
3137   if (my_dboptions_cache_init())
3138     return 1;
3139 
3140   if (ignore_db_dirs_process_additions())
3141   {
3142     sql_print_error("An error occurred while storing ignore_db_dirs to a hash.");
3143     return 1;
3144   }
3145 
3146   /* create the data directory if requested */
3147   if (unlikely(opt_initialize) &&
3148       initialize_create_data_directory(mysql_real_data_home))
3149       return 1;
3150 
3151 
3152   /*
3153     Ensure that lower_case_table_names is set on system where we have case
3154     insensitive names.  If this is not done the users MyISAM tables will
3155     get corrupted if accesses with names of different case.
3156   */
3157   DBUG_PRINT("info", ("lower_case_table_names: %d", lower_case_table_names));
3158   lower_case_file_system= test_if_case_insensitive(mysql_real_data_home);
3159   if (!lower_case_table_names && lower_case_file_system == 1)
3160   {
3161     if (lower_case_table_names_used)
3162     {
3163       sql_print_error("The server option 'lower_case_table_names' is "
3164                       "configured to use case sensitive table names but the "
3165                       "data directory is on a case-insensitive file system "
3166                       "which is an unsupported combination. Please consider "
3167                       "either using a case sensitive file system for your data "
3168                       "directory or switching to a case-insensitive table name "
3169                       "mode.");
3170       return 1;
3171     }
3172     else
3173     {
3174       sql_print_warning("Setting lower_case_table_names=2 because file system for %s is case insensitive", mysql_real_data_home);
3175       lower_case_table_names= 2;
3176     }
3177   }
3178   else if (lower_case_table_names == 2 &&
3179            !(lower_case_file_system=
3180              (test_if_case_insensitive(mysql_real_data_home) == 1)))
3181   {
3182     sql_print_warning("lower_case_table_names was set to 2, even though your "
3183                         "the file system '%s' is case sensitive.  Now setting "
3184                         "lower_case_table_names to 0 to avoid future problems.",
3185       mysql_real_data_home);
3186     lower_case_table_names= 0;
3187   }
3188   else
3189   {
3190     lower_case_file_system=
3191       (test_if_case_insensitive(mysql_real_data_home) == 1);
3192   }
3193 
3194   /* Reset table_alias_charset, now that lower_case_table_names is set. */
3195   table_alias_charset= (lower_case_table_names ?
3196       &my_charset_utf8_tolower_ci :
3197       &my_charset_bin);
3198 
3199   /*
3200     Build do_table and ignore_table rules to hush
3201     after the resetting of table_alias_charset
3202   */
3203   if (rpl_filter->build_do_table_hash() ||
3204       rpl_filter->build_ignore_table_hash())
3205   {
3206     sql_print_error("An error occurred while building do_table"
3207                     "and ignore_table rules to hush.");
3208     return 1;
3209   }
3210 
3211   return 0;
3212 }
3213 
3214 
init_thread_environment()3215 static int init_thread_environment()
3216 {
3217   mysql_mutex_init(key_LOCK_status, &LOCK_status, MY_MUTEX_INIT_FAST);
3218   mysql_mutex_init(key_LOCK_manager,
3219                    &LOCK_manager, MY_MUTEX_INIT_FAST);
3220   mysql_mutex_init(key_LOCK_crypt, &LOCK_crypt, MY_MUTEX_INIT_FAST);
3221   mysql_mutex_init(key_LOCK_user_conn, &LOCK_user_conn, MY_MUTEX_INIT_FAST);
3222   mysql_mutex_init(key_LOCK_global_system_variables,
3223                    &LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
3224   mysql_rwlock_init(key_rwlock_LOCK_system_variables_hash,
3225                     &LOCK_system_variables_hash);
3226   mysql_mutex_init(key_LOCK_prepared_stmt_count,
3227                    &LOCK_prepared_stmt_count, MY_MUTEX_INIT_FAST);
3228   mysql_mutex_init(key_LOCK_sql_slave_skip_counter,
3229                    &LOCK_sql_slave_skip_counter, MY_MUTEX_INIT_FAST);
3230   mysql_mutex_init(key_LOCK_slave_net_timeout,
3231                    &LOCK_slave_net_timeout, MY_MUTEX_INIT_FAST);
3232   mysql_mutex_init(key_LOCK_slave_trans_dep_tracker,
3233                    &LOCK_slave_trans_dep_tracker, MY_MUTEX_INIT_FAST);
3234   mysql_mutex_init(key_LOCK_error_messages,
3235                    &LOCK_error_messages, MY_MUTEX_INIT_FAST);
3236   mysql_mutex_init(key_LOCK_uuid_generator,
3237                    &LOCK_uuid_generator, MY_MUTEX_INIT_FAST);
3238   mysql_mutex_init(key_LOCK_sql_rand,
3239                    &LOCK_sql_rand, MY_MUTEX_INIT_FAST);
3240   mysql_mutex_init(key_LOCK_log_throttle_qni,
3241                    &LOCK_log_throttle_qni, MY_MUTEX_INIT_FAST);
3242   mysql_mutex_init(key_LOCK_offline_mode,
3243                    &LOCK_offline_mode, MY_MUTEX_INIT_FAST);
3244   mysql_mutex_init(key_LOCK_default_password_lifetime,
3245                    &LOCK_default_password_lifetime, MY_MUTEX_INIT_FAST);
3246 #ifdef HAVE_OPENSSL
3247   mysql_mutex_init(key_LOCK_des_key_file,
3248                    &LOCK_des_key_file, MY_MUTEX_INIT_FAST);
3249 #endif
3250   mysql_rwlock_init(key_rwlock_LOCK_sys_init_connect, &LOCK_sys_init_connect);
3251   mysql_rwlock_init(key_rwlock_LOCK_sys_init_slave, &LOCK_sys_init_slave);
3252   mysql_cond_init(key_COND_manager, &COND_manager);
3253   mysql_mutex_init(key_LOCK_server_started,
3254                    &LOCK_server_started, MY_MUTEX_INIT_FAST);
3255   mysql_mutex_init(key_LOCK_keyring_operations,
3256                    &LOCK_keyring_operations, MY_MUTEX_INIT_FAST);
3257   mysql_cond_init(key_COND_server_started, &COND_server_started);
3258   mysql_mutex_init(key_LOCK_reset_gtid_table,
3259                    &LOCK_reset_gtid_table, MY_MUTEX_INIT_FAST);
3260   mysql_mutex_init(key_LOCK_compress_gtid_table,
3261                    &LOCK_compress_gtid_table, MY_MUTEX_INIT_FAST);
3262   mysql_cond_init(key_COND_compress_gtid_table,
3263                   &COND_compress_gtid_table);
3264 #ifndef EMBEDDED_LIBRARY
3265   Events::init_mutexes();
3266 #if defined(_WIN32)
3267   mysql_mutex_init(key_LOCK_handler_count,
3268                    &LOCK_handler_count, MY_MUTEX_INIT_FAST);
3269   mysql_cond_init(key_COND_handler_count, &COND_handler_count);
3270   mysql_rwlock_init(key_rwlock_LOCK_named_pipe_full_access_group,
3271                     &LOCK_named_pipe_full_access_group);
3272 #else
3273   mysql_mutex_init(key_LOCK_socket_listener_active,
3274                    &LOCK_socket_listener_active, MY_MUTEX_INIT_FAST);
3275   mysql_cond_init(key_COND_socket_listener_active,
3276                   &COND_socket_listener_active);
3277   mysql_mutex_init(key_LOCK_start_signal_handler,
3278                    &LOCK_start_signal_handler, MY_MUTEX_INIT_FAST);
3279   mysql_cond_init(key_COND_start_signal_handler,
3280                   &COND_start_signal_handler);
3281 #endif // _WIN32
3282 #endif // !EMBEDDED_LIBRARY
3283   /* Parameter for threads created for connections */
3284   (void) my_thread_attr_init(&connection_attrib);
3285   my_thread_attr_setdetachstate(&connection_attrib, MY_THREAD_CREATE_DETACHED);
3286 #ifndef _WIN32
3287   pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM);
3288 #endif
3289 
3290   assert(! THR_THD_initialized);
3291   assert(! THR_MALLOC_initialized);
3292   if (my_create_thread_local_key(&THR_THD,NULL) ||
3293       my_create_thread_local_key(&THR_MALLOC,NULL))
3294   {
3295     sql_print_error("Can't create thread-keys");
3296     return 1;
3297   }
3298   THR_THD_initialized= true;
3299   THR_MALLOC_initialized= true;
3300   return 0;
3301 }
3302 
3303 #ifndef EMBEDDED_LIBRARY
auto_detect_ssl()3304 ssl_artifacts_status auto_detect_ssl()
3305 {
3306   MY_STAT cert_stat, cert_key, ca_stat;
3307   uint result= 1;
3308   ssl_artifacts_status ret_status= SSL_ARTIFACTS_VIA_OPTIONS;
3309 
3310   if ((!opt_ssl_cert || !opt_ssl_cert[0]) &&
3311       (!opt_ssl_key || !opt_ssl_key[0]) &&
3312       (!opt_ssl_ca || !opt_ssl_ca[0]) &&
3313       (!opt_ssl_capath || !opt_ssl_capath[0]) &&
3314       (!opt_ssl_crl || !opt_ssl_crl[0]) &&
3315       (!opt_ssl_crlpath || !opt_ssl_crlpath[0]))
3316   {
3317     result= result << (my_stat(DEFAULT_SSL_SERVER_CERT, &cert_stat, MYF(0)) ? 1 : 0)
3318                    << (my_stat(DEFAULT_SSL_SERVER_KEY, &cert_key, MYF(0)) ? 1 : 0)
3319                    << (my_stat(DEFAULT_SSL_CA_CERT, &ca_stat, MYF(0)) ? 1 : 0);
3320 
3321     switch(result)
3322     {
3323       case 8:
3324         opt_ssl_ca= (char *)DEFAULT_SSL_CA_CERT;
3325         opt_ssl_cert= (char *)DEFAULT_SSL_SERVER_CERT;
3326         opt_ssl_key= (char *)DEFAULT_SSL_SERVER_KEY;
3327         ret_status= SSL_ARTIFACTS_AUTO_DETECTED;
3328         break;
3329       case 4:
3330       case 2:
3331         ret_status= SSL_ARTIFACT_TRACES_FOUND;
3332         break;
3333       default:
3334         ret_status= SSL_ARTIFACTS_NOT_FOUND;
3335         break;
3336     };
3337   }
3338 
3339   return ret_status;
3340 }
3341 
warn_one(const char * file_name)3342 int warn_one(const char *file_name)
3343 {
3344   FILE *fp;
3345   char *issuer= NULL;
3346   char *subject= NULL;
3347 
3348   if (!(fp= my_fopen(file_name, O_RDONLY | O_BINARY, MYF(MY_WME))))
3349   {
3350     sql_print_error("Error opening CA certificate file");
3351     return 1;
3352   }
3353 
3354   X509 *ca_cert= PEM_read_X509(fp, 0, 0, 0);
3355 
3356   if (!ca_cert)
3357   {
3358     /* We are not interested in anything other than X509 certificates */
3359     my_fclose(fp, MYF(MY_WME));
3360     return 0;
3361   }
3362 
3363   issuer= X509_NAME_oneline(X509_get_issuer_name(ca_cert), 0, 0);
3364   subject= X509_NAME_oneline(X509_get_subject_name(ca_cert), 0, 0);
3365 
3366   if (!strcmp(issuer, subject))
3367   {
3368     sql_print_warning("CA certificate %s is self signed.", file_name);
3369   }
3370 
3371   OPENSSL_free(issuer);
3372   OPENSSL_free(subject);
3373   X509_free(ca_cert);
3374   my_fclose(fp, MYF(MY_WME));
3375   return 0;
3376 
3377 }
3378 
warn_self_signed_ca()3379 int warn_self_signed_ca()
3380 {
3381   int ret_val= 0;
3382   if (opt_ssl_ca && opt_ssl_ca[0])
3383   {
3384     if (warn_one(opt_ssl_ca))
3385       return 1;
3386   }
3387   if (opt_ssl_capath && opt_ssl_capath[0])
3388   {
3389     /* We have ssl-capath. So search all files in the dir */
3390     MY_DIR *ca_dir;
3391     uint file_count;
3392     DYNAMIC_STRING file_path;
3393     char dir_separator[FN_REFLEN];
3394     size_t dir_path_length;
3395 
3396     init_dynamic_string(&file_path, opt_ssl_capath, FN_REFLEN, FN_REFLEN);
3397     dir_separator[0]= FN_LIBCHAR;
3398     dir_separator[1]= 0;
3399     dynstr_append(&file_path, dir_separator);
3400     dir_path_length= file_path.length;
3401 
3402     if (!(ca_dir= my_dir(opt_ssl_capath,MY_WANT_STAT|MY_DONT_SORT|MY_WME)))
3403     {
3404       sql_print_error("Error accessing directory pointed by --ssl-capath");
3405       return 1;
3406     }
3407 
3408     for (file_count = 0; file_count < ca_dir->number_off_files; file_count++)
3409     {
3410       if (!MY_S_ISDIR(ca_dir->dir_entry[file_count].mystat->st_mode))
3411       {
3412         file_path.length= dir_path_length;
3413         dynstr_append(&file_path, ca_dir->dir_entry[file_count].name);
3414         if ((ret_val= warn_one(file_path.str)))
3415           break;
3416       }
3417     }
3418     my_dirend(ca_dir);
3419     dynstr_free(&file_path);
3420 
3421     ca_dir= 0;
3422     memset(&file_path, 0, sizeof(file_path));
3423   }
3424   return ret_val;
3425 }
3426 
push_deprecated_tls_option_no_replacement(const char * tls_version)3427 static void push_deprecated_tls_option_no_replacement(const char *tls_version) {
3428   sql_print_warning(ER_DEFAULT(ER_WARN_DEPRECATED_TLS_VERSION), tls_version);
3429 }
3430 
3431 #endif /* EMBEDDED_LIBRARY */
3432 
init_ssl()3433 static int init_ssl()
3434 {
3435 #ifdef HAVE_OPENSSL
3436 #if OPENSSL_VERSION_NUMBER < 0x10100000L
3437   CRYPTO_malloc_init();
3438 #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
3439   OPENSSL_malloc_init();
3440 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
3441   ssl_start();
3442 #ifndef EMBEDDED_LIBRARY
3443 
3444   if (opt_use_ssl)
3445   {
3446     ssl_artifacts_status auto_detection_status= auto_detect_ssl();
3447     if (auto_detection_status == SSL_ARTIFACTS_AUTO_DETECTED)
3448       sql_print_information("Found %s, %s and %s in data directory. "
3449                             "Trying to enable SSL support using them.",
3450                             DEFAULT_SSL_CA_CERT, DEFAULT_SSL_SERVER_CERT,
3451                             DEFAULT_SSL_SERVER_KEY);
3452     if (do_auto_cert_generation(auto_detection_status) == false)
3453       return 1;
3454 
3455     enum enum_ssl_init_error error= SSL_INITERR_NOERROR;
3456     long ssl_ctx_flags= process_tls_version(opt_tls_version);
3457 
3458     if (!(ssl_ctx_flags & SSL_OP_NO_TLSv1))
3459       push_deprecated_tls_option_no_replacement("TLSv1");
3460     if (!(ssl_ctx_flags & SSL_OP_NO_TLSv1_1))
3461       push_deprecated_tls_option_no_replacement("TLSv1.1");
3462 
3463     /* having ssl_acceptor_fd != 0 signals the use of SSL */
3464     ssl_acceptor_fd= new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert,
3465 					  opt_ssl_ca, opt_ssl_capath,
3466 					  opt_ssl_cipher, &error,
3467                                           opt_ssl_crl, opt_ssl_crlpath, ssl_ctx_flags);
3468     DBUG_PRINT("info",("ssl_acceptor_fd: 0x%lx", (long) ssl_acceptor_fd));
3469 #if OPENSSL_VERSION_NUMBER < 0x10100000L
3470     ERR_remove_thread_state(0);
3471 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
3472     if (!ssl_acceptor_fd)
3473     {
3474       /*
3475         No real need for opt_use_ssl to be enabled in bootstrap mode,
3476         but we want the SSL materal generation and/or validation (if supplied).
3477         So we keep it on.
3478       */
3479       sql_print_warning("Failed to set up SSL because of the"
3480                         " following SSL library error: %s",
3481                         sslGetErrString(error));
3482       opt_use_ssl = 0;
3483       have_ssl= SHOW_OPTION_DISABLED;
3484     }
3485     else
3486     {
3487       /* Check if CA certificate is self signed */
3488       if (warn_self_signed_ca())
3489         return 1;
3490       /* create one SSL that we can use to read information from */
3491       if (!(ssl_acceptor= SSL_new(ssl_acceptor_fd->ssl_context)))
3492         return 1;
3493     }
3494   }
3495   else
3496   {
3497     have_ssl= SHOW_OPTION_DISABLED;
3498   }
3499 #else
3500   have_ssl= SHOW_OPTION_DISABLED;
3501 #endif /* ! EMBEDDED_LIBRARY */
3502   if (des_key_file)
3503     load_des_key_file(des_key_file);
3504   if (init_rsa_keys())
3505     return 1;
3506 #endif /* HAVE_OPENSSL */
3507   return 0;
3508 }
3509 
3510 
end_ssl()3511 static void end_ssl()
3512 {
3513 #ifdef HAVE_OPENSSL
3514 #ifndef EMBEDDED_LIBRARY
3515   if (ssl_acceptor_fd)
3516   {
3517     if (ssl_acceptor)
3518       SSL_free(ssl_acceptor);
3519     free_vio_ssl_acceptor_fd(ssl_acceptor_fd);
3520     ssl_acceptor_fd= 0;
3521   }
3522 #endif /* ! EMBEDDED_LIBRARY */
3523   deinit_rsa_keys();
3524 #endif /* HAVE_OPENSSL */
3525 }
3526 
3527 /**
3528   Generate a UUID and save it into server_uuid variable.
3529 
3530   @return Retur 0 or 1 if an error occurred.
3531  */
generate_server_uuid()3532 static int generate_server_uuid()
3533 {
3534   THD *thd;
3535   Item_func_uuid *func_uuid;
3536   String uuid;
3537 
3538   /*
3539     To be able to run this from boot, we allocate a temporary THD
3540    */
3541   if (!(thd=new THD))
3542   {
3543     sql_print_error("Failed to generate a server UUID because it is failed"
3544                     " to allocate the THD.");
3545     return 1;
3546   }
3547 
3548   thd->thread_stack= (char*) &thd;
3549   thd->store_globals();
3550 
3551   /*
3552     Initialize the variables which are used during "uuid generator
3553     initialization" with values that should normally differ between
3554     mysqlds on the same host. This avoids that another mysqld started
3555     at the same time on the same host get the same "server_uuid".
3556   */
3557   sql_print_information("Salting uuid generator variables, current_pid: %lu, "
3558                         "server_start_time: %lu, bytes_sent: %llu, ",
3559                         current_pid,
3560                         (ulong)server_start_time, thd->status_var.bytes_sent);
3561 
3562   const time_t save_server_start_time= server_start_time;
3563   server_start_time+= ((ulonglong)current_pid << 48) + current_pid;
3564   thd->status_var.bytes_sent= (ulonglong)thd;
3565 
3566   lex_start(thd);
3567   func_uuid= new (thd->mem_root) Item_func_uuid();
3568   func_uuid->fixed= 1;
3569   func_uuid->val_str(&uuid);
3570 
3571   sql_print_information("Generated uuid: '%s', "
3572                         "server_start_time: %lu, bytes_sent: %llu",
3573                         uuid.c_ptr(),
3574                         (ulong)server_start_time, thd->status_var.bytes_sent);
3575   // Restore global variables used for salting
3576   server_start_time = save_server_start_time;
3577 
3578   delete thd;
3579 
3580   strncpy(server_uuid, uuid.c_ptr(), UUID_LENGTH);
3581   DBUG_EXECUTE_IF("server_uuid_deterministic",
3582                   memcpy(server_uuid, "00000000-1111-0000-1111-000000000000",
3583                          UUID_LENGTH););
3584   server_uuid[UUID_LENGTH]= '\0';
3585   return 0;
3586 }
3587 
3588 /**
3589   Save all options which was auto-generated by server-self into the given file.
3590 
3591   @param fname The name of the file in which the auto-generated options will b
3592   e saved.
3593 
3594   @return Return 0 or 1 if an error occurred.
3595  */
flush_auto_options(const char * fname)3596 int flush_auto_options(const char* fname)
3597 {
3598   File fd;
3599   IO_CACHE io_cache;
3600   int result= 0;
3601 
3602   if ((fd= my_open(fname, O_CREAT|O_RDWR, MYF(MY_WME))) < 0)
3603   {
3604     sql_print_error("Failed to create file(file: '%s', errno %d)", fname, my_errno());
3605     return 1;
3606   }
3607 
3608   if (init_io_cache(&io_cache, fd, IO_SIZE*2, WRITE_CACHE, 0L, 0, MYF(MY_WME)))
3609   {
3610     sql_print_error("Failed to create a cache on (file: %s', errno %d)", fname, my_errno());
3611     my_close(fd, MYF(MY_WME));
3612     return 1;
3613   }
3614 
3615   my_b_seek(&io_cache, 0L);
3616   my_b_printf(&io_cache, "%s\n", "[auto]");
3617   my_b_printf(&io_cache, "server-uuid=%s\n", server_uuid);
3618 
3619   if (flush_io_cache(&io_cache) || my_sync(fd, MYF(MY_WME)))
3620     result= 1;
3621 
3622   my_close(fd, MYF(MY_WME));
3623   end_io_cache(&io_cache);
3624   return result;
3625 }
3626 
3627 /**
3628   File 'auto.cnf' resides in the data directory to hold values of options that
3629   server evaluates itself and that needs to be durable to sustain the server
3630   restart. There is only a section ['auto'] in the file. All these options are
3631   in the section. Only one option exists now, it is server_uuid.
3632   Note, the user may not supply any literal value to these auto-options, and
3633   only allowed to trigger (re)evaluation.
3634   For instance, 'server_uuid' value will be evaluated and stored if there is
3635   no corresponding line in the file.
3636   Because of the specifics of the auto-options, they need a seperate storage.
3637   Meanwhile, it is the 'auto.cnf' that has the same structure as 'my.cnf'.
3638 
3639   @todo consider to implement sql-query-able persistent storage by WL#5279.
3640   @return Return 0 or 1 if an error occurred.
3641  */
init_server_auto_options()3642 static int init_server_auto_options()
3643 {
3644   bool flush= false;
3645   char fname[FN_REFLEN];
3646   char *name= (char *)"auto";
3647   const char *groups[]= {"auto", NULL};
3648   char *uuid= 0;
3649   my_option auto_options[]= {
3650     {"server-uuid", 0, "", &uuid, &uuid,
3651       0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3652     {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
3653   };
3654 
3655   DBUG_ENTER("init_server_auto_options");
3656 
3657   if (NULL == fn_format(fname, "auto.cnf", mysql_data_home, "",
3658                         MY_UNPACK_FILENAME | MY_SAFE_PATH))
3659     DBUG_RETURN(1);
3660 
3661   /* load_defaults require argv[0] is not null */
3662   char **argv= &name;
3663   int argc= 1;
3664   if (!check_file_permissions(fname, false))
3665   {
3666     /*
3667       Found a world writable file hence removing it as it is dangerous to write
3668       a new UUID into the same file.
3669      */
3670     my_delete(fname,MYF(MY_WME));
3671     sql_print_warning("World-writable config file '%s' has been removed.\n",
3672                       fname);
3673   }
3674 
3675   /* load all options in 'auto.cnf'. */
3676   if (my_load_defaults(fname, groups, &argc, &argv, NULL))
3677     DBUG_RETURN(1);
3678 
3679   /*
3680     Record the origial pointer allocated by my_load_defaults for free,
3681     because argv will be changed by handle_options
3682    */
3683   char **old_argv= argv;
3684   if (handle_options(&argc, &argv, auto_options, mysqld_get_one_option))
3685     DBUG_RETURN(1);
3686 
3687   DBUG_PRINT("info", ("uuid=%p=%s server_uuid=%s", uuid, uuid, server_uuid));
3688   if (uuid)
3689   {
3690     if (!Uuid::is_valid(uuid))
3691     {
3692       sql_print_error("The server_uuid stored in auto.cnf file is not a valid UUID.");
3693       goto err;
3694     }
3695     /*
3696       Uuid::is_valid() cannot do strict check on the length as it will be
3697       called by GTID::is_valid() as well (GTID = UUID:seq_no). We should
3698       explicitly add the *length check* here in this function.
3699 
3700       If UUID length is less than '36' (UUID_LENGTH), that error case would have
3701       got caught in above is_valid check. The below check is to make sure that
3702       length is not greater than UUID_LENGTH i.e., there are no extra characters
3703       (Garbage) at the end of the valid UUID.
3704     */
3705     if (strlen(uuid) > UUID_LENGTH)
3706     {
3707       sql_print_error("Garbage characters found at the end of the server_uuid "
3708                       "value in auto.cnf file. It should be of length '%d' "
3709                       "(UUID_LENGTH). Clear it and restart the server. ",
3710                       UUID_LENGTH);
3711       goto err;
3712     }
3713     strcpy(server_uuid, uuid);
3714   }
3715   else
3716   {
3717     DBUG_PRINT("info", ("generating server_uuid"));
3718     flush= TRUE;
3719     /* server_uuid will be set in the function */
3720     if (generate_server_uuid())
3721       goto err;
3722     DBUG_PRINT("info", ("generated server_uuid=%s", server_uuid));
3723     sql_print_warning("No existing UUID has been found, so we assume that this"
3724                       " is the first time that this server has been started."
3725                       " Generating a new UUID: %s.",
3726                       server_uuid);
3727   }
3728   /*
3729     The uuid has been copied to server_uuid, so the memory allocated by
3730     my_load_defaults can be freed now.
3731    */
3732   free_defaults(old_argv);
3733 
3734   if (flush)
3735     DBUG_RETURN(flush_auto_options(fname));
3736   DBUG_RETURN(0);
3737 err:
3738   free_defaults(argv);
3739   DBUG_RETURN(1);
3740 }
3741 
3742 
3743 static bool
initialize_storage_engine(char * se_name,const char * se_kind,plugin_ref * dest_plugin)3744 initialize_storage_engine(char *se_name, const char *se_kind,
3745                           plugin_ref *dest_plugin)
3746 {
3747   LEX_STRING name= { se_name, strlen(se_name) };
3748   plugin_ref plugin;
3749   handlerton *hton;
3750   if ((plugin= ha_resolve_by_name(0, &name, FALSE)))
3751     hton= plugin_data<handlerton*>(plugin);
3752   else
3753   {
3754     sql_print_error("Unknown/unsupported storage engine: %s", se_name);
3755     return true;
3756   }
3757   if (!ha_storage_engine_is_enabled(hton))
3758   {
3759     if (!opt_bootstrap)
3760     {
3761       sql_print_error("Default%s storage engine (%s) is not available",
3762                       se_kind, se_name);
3763       return true;
3764     }
3765     assert(*dest_plugin);
3766   }
3767   else
3768   {
3769     /*
3770       Need to unlock as global_system_variables.table_plugin
3771       was acquired during plugin_init()
3772     */
3773     plugin_ref old_dest_plugin = *dest_plugin;
3774     *dest_plugin = plugin;
3775     plugin_unlock(0, old_dest_plugin);
3776   }
3777   return false;
3778 }
3779 
3780 
init_server_query_cache()3781 static void init_server_query_cache()
3782 {
3783   ulong set_cache_size;
3784 
3785   query_cache.set_min_res_unit(query_cache_min_res_unit);
3786   query_cache.init();
3787 
3788   set_cache_size= query_cache.resize(query_cache_size);
3789   if (set_cache_size != query_cache_size)
3790   {
3791     sql_print_warning(ER_DEFAULT(ER_WARN_QC_RESIZE), query_cache_size,
3792                       set_cache_size);
3793     query_cache_size= set_cache_size;
3794   }
3795 }
3796 
3797 
init_server_components()3798 static int init_server_components()
3799 {
3800   DBUG_ENTER("init_server_components");
3801   /*
3802     We need to call each of these following functions to ensure that
3803     all things are initialized so that unireg_abort() doesn't fail
3804   */
3805   mdl_init();
3806   partitioning_init();
3807   if (table_def_init() | hostname_cache_init(host_cache_size))
3808     unireg_abort(MYSQLD_ABORT_EXIT);
3809 
3810   if (my_timer_initialize())
3811     sql_print_error("Failed to initialize timer component (errno %d).", errno);
3812   else
3813     have_statement_timeout= SHOW_OPTION_YES;
3814 
3815   init_server_query_cache();
3816 
3817   randominit(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2);
3818   setup_fpu();
3819 #ifdef HAVE_REPLICATION
3820   init_slave_list();
3821 #endif
3822 
3823   /* Setup logs */
3824 
3825   /*
3826     Enable old-fashioned error log, except when the user has requested
3827     help information. Since the implementation of plugin server
3828     variables the help output is now written much later.
3829 
3830     log_error_dest can be:
3831     disabled_my_option     --log-error was not used or --log-error=
3832     ""                     --log-error without arguments (no '=')
3833     filename               --log-error=filename
3834   */
3835 #ifdef _WIN32
3836   /*
3837     Enable the error log file only if console option is not specified
3838     and --help is not used.
3839   */
3840   bool log_errors_to_file= !opt_help && !opt_console;
3841 #else
3842   /*
3843     Enable the error log file only if --log-error=filename or --log-error
3844     was used. Logging to file is disabled by default unlike on Windows.
3845   */
3846   bool log_errors_to_file= !opt_help && (log_error_dest != disabled_my_option);
3847 #endif
3848 
3849   if (log_errors_to_file)
3850   {
3851     // Construct filename if no filename was given by the user.
3852     if (!log_error_dest[0] || log_error_dest == disabled_my_option)
3853       fn_format(errorlog_filename_buff, pidfile_name, mysql_data_home, ".err",
3854                 MY_REPLACE_EXT); /* replace '.<domain>' by '.err', bug#4997 */
3855     else
3856       fn_format(errorlog_filename_buff, log_error_dest, mysql_data_home, ".err",
3857                 MY_UNPACK_FILENAME);
3858     /*
3859       log_error_dest may have been set to disabled_my_option or "" if no
3860       argument was passed, but we need to show the real name in SHOW VARIABLES.
3861     */
3862     log_error_dest= errorlog_filename_buff;
3863 
3864     if (open_error_log(errorlog_filename_buff, false))
3865       unireg_abort(MYSQLD_ABORT_EXIT);
3866 
3867   }
3868   else
3869   {
3870     // We are logging to stderr and SHOW VARIABLES should reflect that.
3871     log_error_dest= "stderr";
3872     // Flush messages buffered so far.
3873     flush_error_log_messages();
3874   }
3875 
3876   enter_cond_hook= thd_enter_cond;
3877   exit_cond_hook= thd_exit_cond;
3878   is_killed_hook= (int(*)(const void*))thd_killed;
3879 
3880   if (transaction_cache_init())
3881   {
3882     sql_print_error("Out of memory");
3883     unireg_abort(MYSQLD_ABORT_EXIT);
3884   }
3885 
3886   /*
3887     initialize delegates for extension observers, errors have already
3888     been reported in the function
3889   */
3890   if (delegates_init())
3891     unireg_abort(MYSQLD_ABORT_EXIT);
3892 
3893   /* need to configure logging before initializing storage engines */
3894   if (opt_log_slave_updates && !opt_bin_log)
3895   {
3896     sql_print_warning("You need to use --log-bin to make "
3897                     "--log-slave-updates work.");
3898   }
3899   if (binlog_format_used && !opt_bin_log)
3900     sql_print_warning("You need to use --log-bin to make "
3901                       "--binlog-format work.");
3902 
3903   /* Check that we have not let the format to unspecified at this point */
3904   assert((uint)global_system_variables.binlog_format <=
3905          array_elements(binlog_format_names)-1);
3906 
3907 #ifdef HAVE_REPLICATION
3908   if (opt_log_slave_updates && replicate_same_server_id)
3909   {
3910     if (opt_bin_log)
3911     {
3912       sql_print_error("using --replicate-same-server-id in conjunction with \
3913 --log-slave-updates is impossible, it would lead to infinite loops in this \
3914 server.");
3915       unireg_abort(MYSQLD_ABORT_EXIT);
3916     }
3917     else
3918       sql_print_warning("using --replicate-same-server-id in conjunction with \
3919 --log-slave-updates would lead to infinite loops in this server. However this \
3920 will be ignored as the --log-bin option is not defined.");
3921   }
3922 #endif
3923 
3924   opt_server_id_mask = ~ulong(0);
3925 #ifdef HAVE_REPLICATION
3926   opt_server_id_mask = (opt_server_id_bits == 32)?
3927     ~ ulong(0) : (1 << opt_server_id_bits) -1;
3928   if (server_id != (server_id & opt_server_id_mask))
3929   {
3930     sql_print_error("server-id configured is too large to represent with"
3931                     "server-id-bits configured.");
3932     unireg_abort(MYSQLD_ABORT_EXIT);
3933   }
3934 #endif
3935 
3936   if (opt_bin_log)
3937   {
3938     /* Reports an error and aborts, if the --log-bin's path
3939        is a directory.*/
3940     if (opt_bin_logname &&
3941         opt_bin_logname[strlen(opt_bin_logname) - 1] == FN_LIBCHAR)
3942     {
3943       sql_print_error("Path '%s' is a directory name, please specify \
3944 a file name for --log-bin option", opt_bin_logname);
3945       unireg_abort(MYSQLD_ABORT_EXIT);
3946     }
3947 
3948     /* Reports an error and aborts, if the --log-bin-index's path
3949        is a directory.*/
3950     if (opt_binlog_index_name &&
3951         opt_binlog_index_name[strlen(opt_binlog_index_name) - 1]
3952         == FN_LIBCHAR)
3953     {
3954       sql_print_error("Path '%s' is a directory name, please specify \
3955 a file name for --log-bin-index option", opt_binlog_index_name);
3956       unireg_abort(MYSQLD_ABORT_EXIT);
3957     }
3958 
3959     char buf[FN_REFLEN];
3960     const char *ln;
3961     ln= mysql_bin_log.generate_name(opt_bin_logname, "-bin", buf);
3962     if (!opt_bin_logname && !opt_binlog_index_name)
3963     {
3964       /*
3965         User didn't give us info to name the binlog index file.
3966         Picking `hostname`-bin.index like did in 4.x, causes replication to
3967         fail if the hostname is changed later. So, we would like to instead
3968         require a name. But as we don't want to break many existing setups, we
3969         only give warning, not error.
3970       */
3971       sql_print_warning("No argument was provided to --log-bin, and "
3972                         "--log-bin-index was not used; so replication "
3973                         "may break when this MySQL server acts as a "
3974                         "master and has his hostname changed!! Please "
3975                         "use '--log-bin=%s' to avoid this problem.", ln);
3976     }
3977     if (ln == buf)
3978     {
3979       my_free(opt_bin_logname);
3980       opt_bin_logname=my_strdup(key_memory_opt_bin_logname,
3981                                 buf, MYF(0));
3982     }
3983 
3984     /*
3985       Skip opening the index file if we start with --help. This is necessary
3986       to avoid creating the file in an otherwise empty datadir, which will
3987       cause a succeeding 'mysqld --initialize' to fail.
3988     */
3989     if (!opt_help && mysql_bin_log.open_index_file(opt_binlog_index_name, ln, TRUE))
3990     {
3991       unireg_abort(MYSQLD_ABORT_EXIT);
3992     }
3993   }
3994 
3995   if (opt_bin_log)
3996   {
3997     /*
3998       opt_bin_logname[0] needs to be checked to make sure opt binlog name is
3999       not an empty string, incase it is an empty string default file
4000       extension will be passed
4001      */
4002     log_bin_basename=
4003       rpl_make_log_name(key_memory_MYSQL_BIN_LOG_basename,
4004                         opt_bin_logname, default_logfile_name,
4005                         (opt_bin_logname && opt_bin_logname[0]) ? "" : "-bin");
4006     log_bin_index=
4007       rpl_make_log_name(key_memory_MYSQL_BIN_LOG_index,
4008                         opt_binlog_index_name, log_bin_basename, ".index");
4009     if (log_bin_basename == NULL || log_bin_index == NULL)
4010     {
4011       sql_print_error("Unable to create replication path names:"
4012                       " out of memory or path names too long"
4013                       " (path name exceeds " STRINGIFY_ARG(FN_REFLEN)
4014                       " or file name exceeds " STRINGIFY_ARG(FN_LEN) ").");
4015       unireg_abort(MYSQLD_ABORT_EXIT);
4016     }
4017   }
4018 
4019 #ifndef EMBEDDED_LIBRARY
4020   DBUG_PRINT("debug",
4021              ("opt_bin_logname: %s, opt_relay_logname: %s, pidfile_name: %s",
4022               opt_bin_logname, opt_relay_logname, pidfile_name));
4023   /*
4024     opt_relay_logname[0] needs to be checked to make sure opt relaylog name is
4025     not an empty string, incase it is an empty string default file
4026     extension will be passed
4027    */
4028   relay_log_basename=
4029     rpl_make_log_name(key_memory_MYSQL_RELAY_LOG_basename,
4030                       opt_relay_logname, default_logfile_name,
4031                       (opt_relay_logname && opt_relay_logname[0]) ? "" : "-relay-bin");
4032 
4033   if (relay_log_basename != NULL)
4034     relay_log_index=
4035       rpl_make_log_name(key_memory_MYSQL_RELAY_LOG_index,
4036                         opt_relaylog_index_name, relay_log_basename, ".index");
4037 
4038   if (relay_log_basename == NULL || relay_log_index == NULL)
4039   {
4040     sql_print_error("Unable to create replication path names:"
4041                     " out of memory or path names too long"
4042                     " (path name exceeds " STRINGIFY_ARG(FN_REFLEN)
4043                     " or file name exceeds " STRINGIFY_ARG(FN_LEN) ").");
4044     unireg_abort(MYSQLD_ABORT_EXIT);
4045   }
4046 #endif /* !EMBEDDED_LIBRARY */
4047 
4048   /* call ha_init_key_cache() on all key caches to init them */
4049   process_key_caches(&ha_init_key_cache);
4050 
4051   /* Allow storage engine to give real error messages */
4052   if (ha_init_errors())
4053     DBUG_RETURN(1);
4054 
4055   if (opt_ignore_builtin_innodb)
4056     sql_print_warning("ignore-builtin-innodb is ignored "
4057                       "and will be removed in future releases.");
4058   if (gtid_server_init())
4059   {
4060     sql_print_error("Failed to initialize GTID structures.");
4061     unireg_abort(MYSQLD_ABORT_EXIT);
4062   }
4063 
4064   /*
4065     Set tc_log to point to TC_LOG_DUMMY early in order to allow plugin_init()
4066     to commit attachable transaction after reading from mysql.plugin table.
4067     If necessary tc_log will be adjusted to point to correct TC_LOG instance
4068     later.
4069   */
4070   tc_log= &tc_log_dummy;
4071 
4072   /*Load early plugins */
4073   if (plugin_register_early_plugins(&remaining_argc, remaining_argv,
4074                                     opt_help ?
4075                                       PLUGIN_INIT_SKIP_INITIALIZATION : 0))
4076   {
4077     sql_print_error("Failed to initialize early plugins.");
4078     unireg_abort(MYSQLD_ABORT_EXIT);
4079   }
4080   /* Load builtin plugins, initialize MyISAM, CSV and InnoDB */
4081   if (plugin_register_builtin_and_init_core_se(&remaining_argc,
4082                                                remaining_argv))
4083   {
4084     sql_print_error("Failed to initialize builtin plugins.");
4085     unireg_abort(MYSQLD_ABORT_EXIT);
4086   }
4087   /*
4088     Skip reading the plugin table when starting with --help in order
4089     to also skip initializing InnoDB. This provides a simpler and more
4090     uniform handling of various startup use cases, e.g. when the data
4091     directory does not exist, exists but is empty, exists with InnoDB
4092     system tablespaces present etc.
4093   */
4094   if (plugin_register_dynamic_and_init_all(&remaining_argc, remaining_argv,
4095                   (opt_noacl ? PLUGIN_INIT_SKIP_PLUGIN_TABLE : 0) |
4096                   (opt_help ? (PLUGIN_INIT_SKIP_INITIALIZATION |
4097                                PLUGIN_INIT_SKIP_PLUGIN_TABLE) : 0)))
4098   {
4099     sql_print_error("Failed to initialize dynamic plugins.");
4100     unireg_abort(MYSQLD_ABORT_EXIT);
4101   }
4102   plugins_are_initialized= TRUE;  /* Don't separate from init function */
4103 
4104   Session_tracker session_track_system_variables_check;
4105   LEX_STRING var_list;
4106   char *tmp_str;
4107   size_t len= strlen(global_system_variables.track_sysvars_ptr);
4108   tmp_str= (char *)my_malloc(PSI_NOT_INSTRUMENTED, len*sizeof(char)+2,
4109                              MYF(MY_WME));
4110   strcpy(tmp_str,global_system_variables.track_sysvars_ptr);
4111   var_list.length= len;
4112   var_list.str= tmp_str;
4113   if (session_track_system_variables_check.server_boot_verify(system_charset_info,
4114 	                                                      var_list))
4115   {
4116     sql_print_error("The variable session_track_system_variables either has "
4117 	            "duplicate values or invalid values.");
4118     if (tmp_str)
4119       my_free(tmp_str);
4120     unireg_abort(MYSQLD_ABORT_EXIT);
4121   }
4122   if (tmp_str)
4123     my_free(tmp_str);
4124   /* we do want to exit if there are any other unknown options */
4125   if (remaining_argc > 1)
4126   {
4127     int ho_error;
4128     struct my_option no_opts[]=
4129     {
4130       {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
4131     };
4132     /*
4133       We need to eat any 'loose' arguments first before we conclude
4134       that there are unprocessed options.
4135     */
4136     my_getopt_skip_unknown= 0;
4137 
4138     if ((ho_error= handle_options(&remaining_argc, &remaining_argv, no_opts,
4139                                   mysqld_get_one_option)))
4140       unireg_abort(MYSQLD_ABORT_EXIT);
4141     /* Add back the program name handle_options removes */
4142     remaining_argc++;
4143     remaining_argv--;
4144     my_getopt_skip_unknown= TRUE;
4145 
4146     if (remaining_argc > 1)
4147     {
4148       sql_print_error("Too many arguments (first extra is '%s').",
4149                       remaining_argv[1]);
4150       sql_print_information("Use --verbose --help to get a list "
4151                             "of available options!");
4152       unireg_abort(MYSQLD_ABORT_EXIT);
4153 
4154     }
4155   }
4156 
4157   if (opt_help)
4158     unireg_abort(MYSQLD_SUCCESS_EXIT);
4159 
4160   /* if the errmsg.sys is not loaded, terminate to maintain behaviour */
4161   if (!my_default_lc_messages->errmsgs->is_loaded())
4162   {
4163     sql_print_error("Unable to read errmsg.sys file");
4164     unireg_abort(MYSQLD_ABORT_EXIT);
4165   }
4166 
4167   /* We have to initialize the storage engines before CSV logging */
4168   if (ha_init())
4169   {
4170     sql_print_error("Can't init databases");
4171     unireg_abort(MYSQLD_ABORT_EXIT);
4172   }
4173 
4174   if (opt_bootstrap)
4175     log_output_options= LOG_FILE;
4176 
4177   /*
4178     Issue a warning if there were specified additional options to the
4179     log-output along with NONE. Probably this wasn't what user wanted.
4180   */
4181   if ((log_output_options & LOG_NONE) && (log_output_options & ~LOG_NONE))
4182     sql_print_warning("There were other values specified to "
4183                       "log-output besides NONE. Disabling slow "
4184                       "and general logs anyway.");
4185 
4186   if (log_output_options & LOG_TABLE)
4187   {
4188     /* Fall back to log files if the csv engine is not loaded. */
4189     LEX_CSTRING csv_name={C_STRING_WITH_LEN("csv")};
4190     if (!plugin_is_ready(csv_name, MYSQL_STORAGE_ENGINE_PLUGIN))
4191     {
4192       sql_print_error("CSV engine is not present, falling back to the "
4193                       "log files");
4194       log_output_options= (log_output_options & ~LOG_TABLE) | LOG_FILE;
4195     }
4196   }
4197 
4198   query_logger.set_handlers(log_output_options);
4199 
4200   // Open slow log file if enabled.
4201   if (opt_slow_log && query_logger.reopen_log_file(QUERY_LOG_SLOW))
4202     opt_slow_log= false;
4203 
4204   // Open general log file if enabled.
4205   if (opt_general_log && query_logger.reopen_log_file(QUERY_LOG_GENERAL))
4206     opt_general_log= false;
4207 
4208   /*
4209     Set the default storage engines
4210   */
4211   if (initialize_storage_engine(default_storage_engine, "",
4212                                 &global_system_variables.table_plugin))
4213     unireg_abort(MYSQLD_ABORT_EXIT);
4214   if (initialize_storage_engine(default_tmp_storage_engine, " temp",
4215                                 &global_system_variables.temp_table_plugin))
4216     unireg_abort(MYSQLD_ABORT_EXIT);
4217 
4218   if (!opt_bootstrap && !opt_noacl)
4219   {
4220     std::string disabled_se_str(opt_disabled_storage_engines);
4221     ha_set_normalized_disabled_se_str(disabled_se_str);
4222 
4223     // Log warning if default_storage_engine is a disabled storage engine.
4224     handlerton *default_se_handle=
4225       plugin_data<handlerton*>(global_system_variables.table_plugin);
4226     if (ha_is_storage_engine_disabled(default_se_handle))
4227       sql_print_warning("default_storage_engine is set to a "
4228                         "disabled storage engine %s.", default_storage_engine);
4229 
4230     // Log warning if default_tmp_storage_engine is a disabled storage engine.
4231     handlerton *default_tmp_se_handle=
4232       plugin_data<handlerton*>(global_system_variables.temp_table_plugin);
4233     if (ha_is_storage_engine_disabled(default_tmp_se_handle))
4234       sql_print_warning("default_tmp_storage_engine is set to a "
4235                         "disabled storage engine %s.",
4236                         default_tmp_storage_engine);
4237 
4238   }
4239 
4240   if (total_ha_2pc > 1 || (1 == total_ha_2pc && opt_bin_log))
4241   {
4242     if (opt_bin_log)
4243       tc_log= &mysql_bin_log;
4244     else
4245       tc_log= &tc_log_mmap;
4246   }
4247 
4248   if (tc_log->open(opt_bin_log ? opt_bin_logname : opt_tc_log_file))
4249   {
4250     sql_print_error("Can't init tc log");
4251     unireg_abort(MYSQLD_ABORT_EXIT);
4252   }
4253   (void)RUN_HOOK(server_state, before_recovery, (NULL));
4254 
4255   if (ha_recover(0))
4256   {
4257     unireg_abort(MYSQLD_ABORT_EXIT);
4258   }
4259 
4260   /// @todo: this looks suspicious, revisit this /sven
4261   enum_gtid_mode gtid_mode= get_gtid_mode(GTID_MODE_LOCK_NONE);
4262 
4263   if (gtid_mode == GTID_MODE_ON &&
4264       _gtid_consistency_mode != GTID_CONSISTENCY_MODE_ON)
4265   {
4266     sql_print_error("GTID_MODE = ON requires ENFORCE_GTID_CONSISTENCY = ON.");
4267     unireg_abort(MYSQLD_ABORT_EXIT);
4268   }
4269 
4270   if (opt_bin_log)
4271   {
4272     /*
4273       Configures what object is used by the current log to store processed
4274       gtid(s). This is necessary in the MYSQL_BIN_LOG::MYSQL_BIN_LOG to
4275       corretly compute the set of previous gtids.
4276     */
4277     assert(!mysql_bin_log.is_relay_log);
4278     mysql_mutex_t *log_lock= mysql_bin_log.get_log_lock();
4279     mysql_mutex_lock(log_lock);
4280 
4281     if (mysql_bin_log.open_binlog(opt_bin_logname, 0,
4282                                   max_binlog_size, false,
4283                                   true/*need_lock_index=true*/,
4284                                   true/*need_sid_lock=true*/,
4285                                   NULL))
4286     {
4287       mysql_mutex_unlock(log_lock);
4288       unireg_abort(MYSQLD_ABORT_EXIT);
4289     }
4290     mysql_mutex_unlock(log_lock);
4291   }
4292 
4293   if (opt_myisam_log)
4294     (void) mi_log(1);
4295 
4296 #if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && !defined(EMBEDDED_LIBRARY)
4297   if (locked_in_memory && !getuid())
4298   {
4299     if (setreuid((uid_t)-1, 0) == -1)
4300     {                        // this should never happen
4301       sql_print_error("setreuid: %s", strerror(errno));
4302       unireg_abort(MYSQLD_ABORT_EXIT);
4303     }
4304     if (mlockall(MCL_CURRENT))
4305     {
4306       sql_print_warning("Failed to lock memory. Errno: %d\n",errno); /* purecov: inspected */
4307       locked_in_memory= 0;
4308     }
4309 #ifndef _WIN32
4310     if (user_info)
4311       set_user(mysqld_user, user_info);
4312 #endif
4313   }
4314   else
4315 #endif
4316     locked_in_memory=0;
4317 
4318   /* Initialize the optimizer cost module */
4319   init_optimizer_cost_module(true);
4320   ft_init_stopwords();
4321 
4322   init_max_user_conn();
4323   init_update_queries();
4324   DBUG_RETURN(0);
4325 }
4326 
4327 
4328 #ifndef EMBEDDED_LIBRARY
4329 #ifdef _WIN32
4330 
handle_shutdown(void * arg)4331 extern "C" void *handle_shutdown(void *arg)
4332 {
4333   MSG msg;
4334   my_thread_init();
4335   /* This call should create the message queue for this thread. */
4336   PeekMessage(&msg, NULL, 1, 65534,PM_NOREMOVE);
4337   if (WaitForSingleObject(hEventShutdown,INFINITE)==WAIT_OBJECT_0)
4338   {
4339     sql_print_information(ER_DEFAULT(ER_NORMAL_SHUTDOWN), my_progname);
4340     abort_loop= true;
4341     close_connections();
4342     my_thread_end();
4343     my_thread_exit(0);
4344   }
4345   return 0;
4346 }
4347 
4348 
create_shutdown_thread()4349 static void create_shutdown_thread()
4350 {
4351   hEventShutdown=CreateEvent(0, FALSE, FALSE, shutdown_event_name);
4352   my_thread_attr_t thr_attr;
4353   DBUG_ENTER("create_shutdown_thread");
4354 
4355   my_thread_attr_init(&thr_attr);
4356 
4357   if (my_thread_create(&shutdown_thr_handle, &thr_attr, handle_shutdown, 0))
4358     sql_print_warning("Can't create thread to handle shutdown requests"
4359                       " (errno= %d)", errno);
4360   my_thread_attr_destroy(&thr_attr);
4361   // On "Stop Service" we have to do regular shutdown
4362   Service.SetShutdownEvent(hEventShutdown);
4363 }
4364 #endif /* _WIN32 */
4365 
4366 #ifndef NDEBUG
4367 /*
4368   Debugging helper function to keep the locale database
4369   (see sql_locale.cc) and max_month_name_length and
4370   max_day_name_length variable values in consistent state.
4371 */
test_lc_time_sz()4372 static void test_lc_time_sz()
4373 {
4374   DBUG_ENTER("test_lc_time_sz");
4375   for (MY_LOCALE **loc= my_locales; *loc; loc++)
4376   {
4377     size_t max_month_len= 0;
4378     size_t max_day_len = 0;
4379     for (const char **month= (*loc)->month_names->type_names; *month; month++)
4380     {
4381       set_if_bigger(max_month_len,
4382                     my_numchars_mb(&my_charset_utf8_general_ci,
4383                                    *month, *month + strlen(*month)));
4384     }
4385     for (const char **day= (*loc)->day_names->type_names; *day; day++)
4386     {
4387       set_if_bigger(max_day_len,
4388                     my_numchars_mb(&my_charset_utf8_general_ci,
4389                                    *day, *day + strlen(*day)));
4390     }
4391     if ((*loc)->max_month_name_length != max_month_len ||
4392         (*loc)->max_day_name_length != max_day_len)
4393     {
4394       DBUG_PRINT("Wrong max day name(or month name) length for locale:",
4395                  ("%s", (*loc)->name));
4396       assert(0);
4397     }
4398   }
4399   DBUG_VOID_RETURN;
4400 }
4401 #endif//NDEBUG
4402 
4403 /*
4404   @brief : Set opt_super_readonly to user supplied value before
4405            enabling communication channels to accept user connections
4406 */
4407 
set_super_read_only_post_init()4408 static void set_super_read_only_post_init()
4409 {
4410   opt_super_readonly= super_read_only;
4411 }
4412 
4413 #ifdef _WIN32
win_main(int argc,char ** argv)4414 int win_main(int argc, char **argv)
4415 #else
4416 int mysqld_main(int argc, char **argv)
4417 #endif
4418 {
4419   /*
4420     Perform basic thread library and malloc initialization,
4421     to be able to read defaults files and parse options.
4422   */
4423   my_progname= argv[0];
4424 
4425 #ifndef _WIN32
4426 #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
4427   pre_initialize_performance_schema();
4428 #endif /*WITH_PERFSCHEMA_STORAGE_ENGINE */
4429   // For windows, my_init() is called from the win specific mysqld_main
4430   if (my_init())                 // init my_sys library & pthreads
4431   {
4432     sql_print_error("my_init() failed.");
4433     flush_error_log_messages();
4434     return 1;
4435   }
4436 #endif /* _WIN32 */
4437 
4438   orig_argc= argc;
4439   orig_argv= argv;
4440   my_getopt_use_args_separator= TRUE;
4441   my_defaults_read_login_file= FALSE;
4442   if (load_defaults(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv))
4443   {
4444     flush_error_log_messages();
4445     return 1;
4446   }
4447   my_getopt_use_args_separator= FALSE;
4448   defaults_argc= argc;
4449   defaults_argv= argv;
4450   remaining_argc= argc;
4451   remaining_argv= argv;
4452 
4453   /* Must be initialized early for comparison of options name */
4454   system_charset_info= &my_charset_utf8_general_ci;
4455 
4456   /* Write mysys error messages to the error log. */
4457   local_message_hook= error_log_print;
4458 
4459   int ho_error;
4460 
4461 #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
4462   /*
4463     Initialize the array of performance schema instrument configurations.
4464   */
4465   init_pfs_instrument_array();
4466 #endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
4467 
4468   ho_error= handle_early_options();
4469 
4470 #if !defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
4471 
4472   if (opt_bootstrap && opt_daemonize)
4473   {
4474     fprintf(stderr, "Bootstrap and daemon options are incompatible.\n");
4475     exit(MYSQLD_ABORT_EXIT);
4476   }
4477 
4478   if (opt_daemonize && log_error_dest == disabled_my_option &&
4479       (isatty(STDOUT_FILENO) || isatty(STDERR_FILENO)))
4480   {
4481     fprintf(stderr, "Please enable --log-error option or set appropriate "
4482                     "redirections for standard output and/or standard error "
4483                     "in daemon mode.\n");
4484     exit(MYSQLD_ABORT_EXIT);
4485   }
4486 
4487   if (opt_daemonize)
4488   {
4489     if (chdir("/") < 0)
4490     {
4491       fprintf(stderr, "Cannot change to root director: %s\n",
4492                       strerror(errno));
4493       exit(MYSQLD_ABORT_EXIT);
4494     }
4495 
4496     if ((pipe_write_fd= mysqld::runtime::mysqld_daemonize()) < 0)
4497     {
4498       fprintf(stderr, "mysqld_daemonize failed \n");
4499       exit(MYSQLD_ABORT_EXIT);
4500     }
4501   }
4502 #endif
4503 
4504   init_sql_statement_names();
4505   sys_var_init();
4506   ulong requested_open_files;
4507   adjust_related_options(&requested_open_files);
4508 
4509 #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
4510   if (ho_error == 0)
4511   {
4512     if (!opt_help && !opt_bootstrap)
4513     {
4514       /* Add sizing hints from the server sizing parameters. */
4515       pfs_param.m_hints.m_table_definition_cache= table_def_size;
4516       pfs_param.m_hints.m_table_open_cache= table_cache_size;
4517       pfs_param.m_hints.m_max_connections= max_connections;
4518       pfs_param.m_hints.m_open_files_limit= requested_open_files;
4519       pfs_param.m_hints.m_max_prepared_stmt_count= max_prepared_stmt_count;
4520 
4521       PSI_hook= initialize_performance_schema(&pfs_param);
4522       if (PSI_hook == NULL && pfs_param.m_enabled)
4523       {
4524         pfs_param.m_enabled= false;
4525         sql_print_warning("Performance schema disabled (reason: init failed).");
4526       }
4527     }
4528   }
4529 #else
4530   /*
4531     Other provider of the instrumentation interface should
4532     initialize PSI_hook here:
4533     - HAVE_PSI_INTERFACE is for the instrumentation interface
4534     - WITH_PERFSCHEMA_STORAGE_ENGINE is for one implementation
4535       of the interface,
4536     but there could be alternate implementations, which is why
4537     these two defines are kept separate.
4538   */
4539 #endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
4540 
4541 #ifdef HAVE_PSI_INTERFACE
4542   /*
4543     Obtain the current performance schema instrumentation interface,
4544     if available.
4545   */
4546   if (PSI_hook)
4547   {
4548     PSI *psi_server= (PSI*) PSI_hook->get_interface(PSI_CURRENT_VERSION);
4549     if (likely(psi_server != NULL))
4550     {
4551       set_psi_server(psi_server);
4552 
4553       /*
4554         Now that we have parsed the command line arguments, and have initialized
4555         the performance schema itself, the next step is to register all the
4556         server instruments.
4557       */
4558       init_server_psi_keys();
4559       /* Instrument the main thread */
4560       PSI_thread *psi= PSI_THREAD_CALL(new_thread)(key_thread_main, NULL, 0);
4561       PSI_THREAD_CALL(set_thread_os_id)(psi);
4562       PSI_THREAD_CALL(set_thread)(psi);
4563 
4564       /*
4565         Now that some instrumentation is in place,
4566         recreate objects which were initialised early,
4567         so that they are instrumented as well.
4568       */
4569       my_thread_global_reinit();
4570     }
4571   }
4572 #endif /* HAVE_PSI_INTERFACE */
4573 
4574   init_error_log();
4575 
4576   /* Initialize audit interface globals. Audit plugins are inited later. */
4577   mysql_audit_initialize();
4578 
4579 #ifndef EMBEDDED_LIBRARY
4580   Srv_session::module_init();
4581 #endif
4582 
4583   /*
4584     Perform basic query log initialization. Should be called after
4585     MY_INIT, as it initializes mutexes.
4586   */
4587   query_logger.init();
4588 
4589   if (ho_error)
4590   {
4591     /*
4592       Parsing command line option failed,
4593       Since we don't have a workable remaining_argc/remaining_argv
4594       to continue the server initialization, this is as far as this
4595       code can go.
4596       This is the best effort to log meaningful messages:
4597       - messages will be printed to stderr, which is not redirected yet,
4598       - messages will be printed in the NT event log, for windows.
4599     */
4600     flush_error_log_messages();
4601     /*
4602       Not enough initializations for unireg_abort()
4603       Using exit() for windows.
4604     */
4605     exit (MYSQLD_ABORT_EXIT);
4606   }
4607 
4608   if (init_common_variables())
4609     unireg_abort(MYSQLD_ABORT_EXIT);        // Will do exit
4610 
4611   my_init_signals();
4612 
4613   size_t guardize= 0;
4614 #ifndef _WIN32
4615   int retval= pthread_attr_getguardsize(&connection_attrib, &guardize);
4616   assert(retval == 0);
4617   if (retval != 0)
4618     guardize= my_thread_stack_size;
4619 #endif
4620 
4621 #if defined(__ia64__) || defined(__ia64)
4622   /*
4623     Peculiar things with ia64 platforms - it seems we only have half the
4624     stack size in reality, so we have to double it here
4625   */
4626   guardize= my_thread_stack_size;
4627 #endif
4628 
4629   my_thread_attr_setstacksize(&connection_attrib,
4630                             my_thread_stack_size + guardize);
4631 
4632   {
4633     /* Retrieve used stack size;  Needed for checking stack overflows */
4634     size_t stack_size= 0;
4635     my_thread_attr_getstacksize(&connection_attrib, &stack_size);
4636 
4637     /* We must check if stack_size = 0 as Solaris 2.9 can return 0 here */
4638     if (stack_size && stack_size < (my_thread_stack_size + guardize))
4639     {
4640       sql_print_warning("Asked for %lu thread stack, but got %ld",
4641                         my_thread_stack_size + guardize, (long) stack_size);
4642 #if defined(__ia64__) || defined(__ia64)
4643       my_thread_stack_size= stack_size / 2;
4644 #else
4645       my_thread_stack_size= static_cast<ulong>(stack_size - guardize);
4646 #endif
4647     }
4648   }
4649 
4650 #ifndef NDEBUG
4651   test_lc_time_sz();
4652   srand(static_cast<uint>(time(NULL)));
4653 #endif
4654 
4655 #ifndef _WIN32
4656   if ((user_info= check_user(mysqld_user)))
4657   {
4658 #if HAVE_CHOWN
4659     if (unlikely(opt_initialize))
4660     {
4661       /* need to change the owner of the freshly created data directory */
4662       MY_STAT stat;
4663       char errbuf[MYSYS_STRERROR_SIZE];
4664       bool must_chown= true;
4665 
4666       /* fetch the directory's owner */
4667       if (!my_stat(mysql_real_data_home, &stat, MYF(0)))
4668       {
4669         sql_print_information("Can't read data directory's stats (%d): %s."
4670                               "Assuming that it's not owned by the same user/group",
4671                               my_errno(),
4672                               my_strerror(errbuf, sizeof(errbuf), my_errno()));
4673       }
4674       /* Don't change it if it's already the same as SElinux stops this */
4675       else if(stat.st_uid == user_info->pw_uid &&
4676               stat.st_gid == user_info->pw_gid)
4677         must_chown= false;
4678 
4679       if (must_chown &&
4680           chown(mysql_real_data_home, user_info->pw_uid, user_info->pw_gid)
4681          )
4682       {
4683         sql_print_error("Can't change data directory owner to %s", mysqld_user);
4684         unireg_abort(1);
4685       }
4686     }
4687 #endif
4688 
4689 
4690 #if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
4691     if (locked_in_memory) // getuid() == 0 here
4692       set_effective_user(user_info);
4693     else
4694 #endif
4695       set_user(mysqld_user, user_info);
4696   }
4697 #endif // !_WIN32
4698 
4699   /*
4700    initiate key migration if any one of the migration specific
4701    options are provided.
4702   */
4703   if (opt_keyring_migration_source ||
4704       opt_keyring_migration_destination ||
4705       migrate_connect_options)
4706   {
4707     Migrate_keyring mk;
4708     if (mk.init(remaining_argc, remaining_argv,
4709                 opt_keyring_migration_source,
4710                 opt_keyring_migration_destination,
4711                 opt_keyring_migration_user,
4712                 opt_keyring_migration_host,
4713                 opt_keyring_migration_password,
4714                 opt_keyring_migration_socket,
4715                 opt_keyring_migration_port))
4716     {
4717       sql_print_error(ER_DEFAULT(ER_KEYRING_MIGRATION_STATUS),
4718                       "failed");
4719       log_error_dest= "stderr";
4720       flush_error_log_messages();
4721       unireg_abort(MYSQLD_ABORT_EXIT);
4722     }
4723 
4724     if (mk.execute())
4725     {
4726       sql_print_error(ER_DEFAULT(ER_KEYRING_MIGRATION_STATUS),
4727                       "failed");
4728       log_error_dest= "stderr";
4729       flush_error_log_messages();
4730       unireg_abort(MYSQLD_ABORT_EXIT);
4731     }
4732 
4733     sql_print_information(ER_DEFAULT(ER_KEYRING_MIGRATION_STATUS),
4734                           "successful");
4735     log_error_dest= "stderr";
4736     flush_error_log_messages();
4737     unireg_abort(MYSQLD_SUCCESS_EXIT);
4738   }
4739 
4740   /*
4741    We have enough space for fiddling with the argv, continue
4742   */
4743   if (my_setwd(mysql_real_data_home,MYF(MY_WME)) && !opt_help)
4744   {
4745     sql_print_error("failed to set datadir to %s", mysql_real_data_home);
4746     unireg_abort(MYSQLD_ABORT_EXIT);        /* purecov: inspected */
4747   }
4748 
4749   //If the binlog is enabled, one needs to provide a server-id
4750   if (opt_bin_log && !(server_id_supplied) )
4751   {
4752     sql_print_error("You have enabled the binary log, but you haven't provided "
4753                     "the mandatory server-id. Please refer to the proper "
4754                     "server start-up parameters documentation");
4755     unireg_abort(MYSQLD_ABORT_EXIT);
4756   }
4757 
4758   /*
4759    The subsequent calls may take a long time : e.g. innodb log read.
4760    Thus set the long running service control manager timeout
4761   */
4762 #if defined(_WIN32)
4763   Service.SetSlowStarting(slow_start_timeout);
4764 #endif
4765 
4766   if (init_server_components())
4767     unireg_abort(MYSQLD_ABORT_EXIT);
4768 
4769   /*
4770     Each server should have one UUID. We will create it automatically, if it
4771     does not exist.
4772    */
4773   if (init_server_auto_options())
4774   {
4775     sql_print_error("Initialization of the server's UUID failed because it could"
4776                     " not be read from the auto.cnf file. If this is a new"
4777                     " server, the initialization failed because it was not"
4778                     " possible to generate a new UUID.");
4779     unireg_abort(MYSQLD_ABORT_EXIT);
4780   }
4781 
4782   /*
4783     Add server_uuid to the sid_map.  This must be done after
4784     server_uuid has been initialized in init_server_auto_options and
4785     after the binary log (and sid_map file) has been initialized in
4786     init_server_components().
4787 
4788     No error message is needed: init_sid_map() prints a message.
4789 
4790     Strictly speaking, this is not currently needed when
4791     opt_bin_log==0, since the variables that gtid_state->init
4792     initializes are not currently used in that case.  But we call it
4793     regardless to avoid possible future bugs if gtid_state ever
4794     needs to do anything else.
4795   */
4796   global_sid_lock->wrlock();
4797   int gtid_ret= gtid_state->init();
4798   global_sid_lock->unlock();
4799 
4800   if (gtid_ret)
4801     unireg_abort(MYSQLD_ABORT_EXIT);
4802 
4803   // Initialize executed_gtids from mysql.gtid_executed table.
4804   if (gtid_state->read_gtid_executed_from_table() == -1)
4805     unireg_abort(1);
4806 
4807   if (opt_bin_log)
4808   {
4809     /*
4810       Initialize GLOBAL.GTID_EXECUTED and GLOBAL.GTID_PURGED from
4811       gtid_executed table and binlog files during server startup.
4812     */
4813     Gtid_set *executed_gtids=
4814       const_cast<Gtid_set *>(gtid_state->get_executed_gtids());
4815     Gtid_set *lost_gtids=
4816       const_cast<Gtid_set *>(gtid_state->get_lost_gtids());
4817     Gtid_set *gtids_only_in_table=
4818       const_cast<Gtid_set *>(gtid_state->get_gtids_only_in_table());
4819     Gtid_set *previous_gtids_logged=
4820       const_cast<Gtid_set *>(gtid_state->get_previous_gtids_logged());
4821 
4822     Gtid_set purged_gtids_from_binlog(global_sid_map, global_sid_lock);
4823     Gtid_set gtids_in_binlog(global_sid_map, global_sid_lock);
4824     Gtid_set gtids_in_binlog_not_in_table(global_sid_map, global_sid_lock);
4825 
4826     if (mysql_bin_log.init_gtid_sets(&gtids_in_binlog,
4827                                      &purged_gtids_from_binlog,
4828                                      opt_master_verify_checksum,
4829                                      true/*true=need lock*/,
4830                                      NULL/*trx_parser*/,
4831                                      NULL/*gtid_partial_trx*/,
4832                                      true/*is_server_starting*/))
4833       unireg_abort(MYSQLD_ABORT_EXIT);
4834 
4835     global_sid_lock->wrlock();
4836 
4837     purged_gtids_from_binlog.dbug_print("purged_gtids_from_binlog");
4838     gtids_in_binlog.dbug_print("gtids_in_binlog");
4839 
4840     if (!gtids_in_binlog.is_empty() &&
4841         !gtids_in_binlog.is_subset(executed_gtids))
4842     {
4843       gtids_in_binlog_not_in_table.add_gtid_set(&gtids_in_binlog);
4844       if (!executed_gtids->is_empty())
4845         gtids_in_binlog_not_in_table.remove_gtid_set(executed_gtids);
4846       /*
4847         Save unsaved GTIDs into gtid_executed table, in the following
4848         four cases:
4849           1. the upgrade case.
4850           2. the case that a slave is provisioned from a backup of
4851              the master and the slave is cleaned by RESET MASTER
4852              and RESET SLAVE before this.
4853           3. the case that no binlog rotation happened from the
4854              last RESET MASTER on the server before it crashes.
4855           4. The set of GTIDs of the last binlog is not saved into the
4856              gtid_executed table if server crashes, so we save it into
4857              gtid_executed table and executed_gtids during recovery
4858              from the crash.
4859       */
4860       if (gtid_state->save(&gtids_in_binlog_not_in_table) == -1)
4861       {
4862         global_sid_lock->unlock();
4863         unireg_abort(MYSQLD_ABORT_EXIT);
4864       }
4865       executed_gtids->add_gtid_set(&gtids_in_binlog_not_in_table);
4866     }
4867 
4868     /* gtids_only_in_table= executed_gtids - gtids_in_binlog */
4869     if (gtids_only_in_table->add_gtid_set(executed_gtids) !=
4870         RETURN_STATUS_OK)
4871     {
4872       global_sid_lock->unlock();
4873       unireg_abort(MYSQLD_ABORT_EXIT);
4874     }
4875     gtids_only_in_table->remove_gtid_set(&gtids_in_binlog);
4876     /*
4877       lost_gtids = executed_gtids -
4878                    (gtids_in_binlog - purged_gtids_from_binlog)
4879                  = gtids_only_in_table + purged_gtids_from_binlog;
4880     */
4881     assert(lost_gtids->is_empty());
4882     if (lost_gtids->add_gtid_set(gtids_only_in_table) != RETURN_STATUS_OK ||
4883         lost_gtids->add_gtid_set(&purged_gtids_from_binlog) !=
4884         RETURN_STATUS_OK)
4885     {
4886       global_sid_lock->unlock();
4887       unireg_abort(MYSQLD_ABORT_EXIT);
4888     }
4889 
4890     /* Prepare previous_gtids_logged for next binlog */
4891     if (previous_gtids_logged->add_gtid_set(&gtids_in_binlog) !=
4892         RETURN_STATUS_OK)
4893     {
4894       global_sid_lock->unlock();
4895       unireg_abort(MYSQLD_ABORT_EXIT);
4896     }
4897 
4898     /*
4899       Write the previous set of gtids at this point because during
4900       the creation of the binary log this is not done as we cannot
4901       move the init_gtid_sets() to a place before openning the binary
4902       log. This requires some investigation.
4903 
4904       /Alfranio
4905     */
4906     Previous_gtids_log_event prev_gtids_ev(&gtids_in_binlog);
4907 
4908     global_sid_lock->unlock();
4909 
4910     (prev_gtids_ev.common_footer)->checksum_alg=
4911       static_cast<enum_binlog_checksum_alg>(binlog_checksum_options);
4912 
4913     if (prev_gtids_ev.write(mysql_bin_log.get_log_file()))
4914       unireg_abort(MYSQLD_ABORT_EXIT);
4915     mysql_bin_log.add_bytes_written(
4916       prev_gtids_ev.common_header->data_written);
4917 
4918     if (flush_io_cache(mysql_bin_log.get_log_file()) ||
4919         mysql_file_sync(mysql_bin_log.get_log_file()->file, MYF(MY_WME)))
4920       unireg_abort(MYSQLD_ABORT_EXIT);
4921     mysql_bin_log.update_binlog_end_pos();
4922 
4923 #ifdef HAVE_REPLICATION
4924     if (opt_bin_log && expire_logs_days)
4925     {
4926       time_t purge_time= server_start_time - expire_logs_days * 24 * 60 * 60;
4927       DBUG_EXECUTE_IF("expire_logs_always_at_start",
4928                       { purge_time= my_time(0); });
4929       if (purge_time >= 0)
4930         mysql_bin_log.purge_logs_before_date(purge_time, true);
4931     }
4932 #endif
4933 
4934     (void) RUN_HOOK(server_state, after_engine_recovery, (NULL));
4935   }
4936 
4937 
4938   if (init_ssl())
4939     unireg_abort(MYSQLD_ABORT_EXIT);
4940   if (network_init())
4941     unireg_abort(MYSQLD_ABORT_EXIT);
4942 
4943 #ifdef _WIN32
4944 #ifndef EMBEDDED_LIBRARY
4945   if (opt_require_secure_transport &&
4946       !opt_enable_shared_memory && !opt_use_ssl &&
4947       !opt_initialize && !opt_bootstrap)
4948   {
4949     sql_print_error("Server is started with --require-secure-transport=ON "
4950                     "but no secure transports (SSL or Shared Memory) are "
4951                     "configured.");
4952     unireg_abort(MYSQLD_ABORT_EXIT);
4953   }
4954 #endif
4955 
4956 #endif
4957 
4958   /*
4959    Initialize my_str_malloc(), my_str_realloc() and my_str_free()
4960   */
4961   my_str_malloc= &my_str_malloc_mysqld;
4962   my_str_free= &my_str_free_mysqld;
4963   my_str_realloc= &my_str_realloc_mysqld;
4964 
4965   error_handler_hook= my_message_sql;
4966 
4967   /* Save pid of this process in a file */
4968   if (!opt_bootstrap)
4969     create_pid_file();
4970 
4971 
4972   /* Read the optimizer cost model configuration tables */
4973   if (!opt_bootstrap)
4974     reload_optimizer_cost_constants();
4975 
4976   if (mysql_rm_tmp_tables() || acl_init(opt_noacl) ||
4977       my_tz_init((THD *)0, default_tz_name, opt_bootstrap) ||
4978       grant_init(opt_noacl))
4979   {
4980     abort_loop= true;
4981     sql_print_error("Fatal error: Failed to initialize ACL/grant/time zones "
4982                     "structures or failed to remove temporary table files.");
4983 
4984     delete_pid_file(MYF(MY_WME));
4985 
4986     unireg_abort(MYSQLD_ABORT_EXIT);
4987   }
4988 
4989   if (!opt_bootstrap)
4990     servers_init(0);
4991 
4992   if (!opt_noacl)
4993   {
4994 #ifdef HAVE_DLOPEN
4995     udf_init();
4996 #endif
4997   }
4998 
4999   init_status_vars();
5000   /* If running with bootstrap, do not start replication. */
5001   if (opt_bootstrap)
5002     opt_skip_slave_start= 1;
5003 
5004   check_binlog_cache_size(NULL);
5005   check_binlog_stmt_cache_size(NULL);
5006 
5007   binlog_unsafe_map_init();
5008 
5009   /* If running with bootstrap, do not start replication. */
5010   if (!opt_bootstrap)
5011   {
5012     // Make @@slave_skip_errors show the nice human-readable value.
5013     set_slave_skip_errors(&opt_slave_skip_errors);
5014 
5015     /*
5016       init_slave() must be called after the thread keys are created.
5017     */
5018     if (server_id != 0)
5019       init_slave(); /* Ignoring errors while configuring replication. */
5020   }
5021 
5022 #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
5023   initialize_performance_schema_acl(opt_bootstrap);
5024   /*
5025     Do not check the structure of the performance schema tables
5026     during bootstrap:
5027     - the tables are not supposed to exist yet, bootstrap will create them
5028     - a check would print spurious error messages
5029   */
5030   if (! opt_bootstrap)
5031     check_performance_schema();
5032 #endif
5033 
5034   initialize_information_schema_acl();
5035 
5036   execute_ddl_log_recovery();
5037   (void) RUN_HOOK(server_state, after_recovery, (NULL));
5038 
5039   if (Events::init(opt_noacl || opt_bootstrap))
5040     unireg_abort(MYSQLD_ABORT_EXIT);
5041 
5042 #ifndef _WIN32
5043   //  Start signal handler thread.
5044   start_signal_handler();
5045 #endif
5046 
5047   if (opt_bootstrap)
5048   {
5049     start_processing_signals();
5050 
5051     int error= bootstrap(mysql_stdin);
5052     unireg_abort(error ? MYSQLD_ABORT_EXIT : MYSQLD_SUCCESS_EXIT);
5053   }
5054 
5055   if (opt_init_file && *opt_init_file)
5056   {
5057     if (read_init_file(opt_init_file))
5058       unireg_abort(MYSQLD_ABORT_EXIT);
5059   }
5060 
5061   /*
5062     Event must be invoked after error_handler_hook is assigned to
5063     my_message_sql, otherwise my_message will not cause the event to abort.
5064   */
5065   if (mysql_audit_notify(AUDIT_EVENT(MYSQL_AUDIT_SERVER_STARTUP_STARTUP),
5066                          (const char **) argv, argc))
5067     unireg_abort(MYSQLD_ABORT_EXIT);
5068 
5069 #ifdef _WIN32
5070   create_shutdown_thread();
5071 #endif
5072   start_handle_manager();
5073 
5074   create_compress_gtid_table_thread();
5075 
5076   sql_print_information(ER_DEFAULT(ER_STARTUP),
5077                         my_progname,
5078                         server_version,
5079 #ifdef HAVE_SYS_UN_H
5080                         (opt_bootstrap ? (char*) "" : mysqld_unix_port),
5081 #else
5082                         (char*) "",
5083 #endif
5084                          mysqld_port,
5085                          MYSQL_COMPILATION_COMMENT);
5086 #if defined(_WIN32)
5087   Service.SetRunning();
5088 #endif
5089 
5090   start_processing_signals();
5091 
5092 #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
5093   /* engine specific hook, to be made generic */
5094   if (ndb_wait_setup_func && ndb_wait_setup_func(opt_ndb_wait_setup))
5095   {
5096     sql_print_warning("NDB : Tables not available after %lu seconds."
5097                       "  Consider increasing --ndb-wait-setup value",
5098                       opt_ndb_wait_setup);
5099   }
5100 #endif
5101 
5102   if (!opt_bootstrap)
5103   {
5104     /*
5105       Execute an I_S query to implicitly check for tables using the deprecated
5106       partition engine. No need to do this during bootstrap. We ignore the
5107       return value from the query execution. Note that this must be done after
5108       NDB is initialized to avoid polluting the server with invalid table shares.
5109     */
5110     if (!opt_disable_partition_check)
5111     {
5112       sql_print_information(
5113               "Executing 'SELECT * FROM INFORMATION_SCHEMA.TABLES;' "
5114               "to get a list of tables using the deprecated partition "
5115               "engine.");
5116 
5117       sql_print_information("Beginning of list of non-natively partitioned tables");
5118       (void) bootstrap_single_query(
5119               "SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES "
5120               "WHERE CREATE_OPTIONS LIKE '%partitioned%';");
5121       sql_print_information("End of list of non-natively partitioned tables");
5122     }
5123   }
5124 
5125   /*
5126     Set opt_super_readonly here because if opt_super_readonly is set
5127     in get_option, it will create problem while setting up event scheduler.
5128   */
5129   set_super_read_only_post_init();
5130 
5131   DBUG_PRINT("info", ("Block, listening for incoming connections"));
5132 
5133   (void)MYSQL_SET_STAGE(0 ,__FILE__, __LINE__);
5134 
5135   server_operational_state= SERVER_OPERATING;
5136 
5137   (void) RUN_HOOK(server_state, before_handle_connection, (NULL));
5138 
5139 #if defined(_WIN32)
5140   setup_conn_event_handler_threads();
5141 #else
5142   mysql_mutex_lock(&LOCK_socket_listener_active);
5143   // Make it possible for the signal handler to kill the listener.
5144   socket_listener_active= true;
5145   mysql_mutex_unlock(&LOCK_socket_listener_active);
5146 
5147   if (opt_daemonize)
5148     mysqld::runtime::signal_parent(pipe_write_fd,1);
5149 
5150   mysqld_socket_acceptor->connection_event_loop();
5151 #endif /* _WIN32 */
5152   server_operational_state= SERVER_SHUTTING_DOWN;
5153 
5154   DBUG_PRINT("info", ("No longer listening for incoming connections"));
5155 
5156   mysql_audit_notify(MYSQL_AUDIT_SERVER_SHUTDOWN_SHUTDOWN,
5157                      MYSQL_AUDIT_SERVER_SHUTDOWN_REASON_SHUTDOWN,
5158                      MYSQLD_SUCCESS_EXIT);
5159 
5160   terminate_compress_gtid_table_thread();
5161   /*
5162     Save set of GTIDs of the last binlog into gtid_executed table
5163     on server shutdown.
5164   */
5165   if (opt_bin_log)
5166     if (gtid_state->save_gtids_of_last_binlog_into_table(false))
5167       sql_print_warning("Failed to save the set of Global Transaction "
5168                         "Identifiers of the last binary log into the "
5169                         "mysql.gtid_executed table while the server was "
5170                         "shutting down. The next server restart will make "
5171                         "another attempt to save Global Transaction "
5172                         "Identifiers into the table.");
5173 
5174 #ifndef _WIN32
5175   mysql_mutex_lock(&LOCK_socket_listener_active);
5176   // Notify the signal handler that we have stopped listening for connections.
5177   socket_listener_active= false;
5178   mysql_cond_broadcast(&COND_socket_listener_active);
5179   mysql_mutex_unlock(&LOCK_socket_listener_active);
5180 #endif // !_WIN32
5181 
5182 #ifdef HAVE_PSI_THREAD_INTERFACE
5183   /*
5184     Disable the main thread instrumentation,
5185     to avoid recording events during the shutdown.
5186   */
5187   PSI_THREAD_CALL(delete_current_thread)();
5188 #endif
5189 
5190   DBUG_PRINT("info", ("Waiting for shutdown proceed"));
5191   int ret= 0;
5192 #ifdef _WIN32
5193   if (shutdown_thr_handle.handle)
5194     ret= my_thread_join(&shutdown_thr_handle, NULL);
5195   shutdown_thr_handle.handle= NULL;
5196   if (0 != ret)
5197     sql_print_warning("Could not join shutdown thread. error:%d", ret);
5198 #else
5199   if (signal_thread_id.thread != 0)
5200     ret= my_thread_join(&signal_thread_id, NULL);
5201   signal_thread_id.thread= 0;
5202   if (0 != ret)
5203     sql_print_warning("Could not join signal_thread. error:%d", ret);
5204 #endif
5205 
5206   clean_up(1);
5207   mysqld_exit(MYSQLD_SUCCESS_EXIT);
5208 }
5209 
5210 
5211 /****************************************************************************
5212   Main and thread entry function for Win32
5213   (all this is needed only to run mysqld as a service on WinNT)
5214 ****************************************************************************/
5215 
5216 #if defined(_WIN32)
mysql_service(void * p)5217 int mysql_service(void *p)
5218 {
5219   if (my_thread_init())
5220   {
5221     flush_error_log_messages();
5222     return 1;
5223   }
5224 
5225   if (use_opt_args)
5226     win_main(opt_argc, opt_argv);
5227   else
5228     win_main(Service.my_argc, Service.my_argv);
5229 
5230   my_thread_end();
5231   return 0;
5232 }
5233 
5234 
5235 /* Quote string if it contains space, else copy */
5236 
add_quoted_string(char * to,const char * from,char * to_end)5237 static char *add_quoted_string(char *to, const char *from, char *to_end)
5238 {
5239   uint length= (uint) (to_end-to);
5240 
5241   if (!strchr(from, ' '))
5242     return strmake(to, from, length-1);
5243   return strxnmov(to, length-1, "\"", from, "\"", NullS);
5244 }
5245 
5246 
5247 /**
5248   Handle basic handling of services, like installation and removal.
5249 
5250   @param argv             Pointer to argument list
5251   @param servicename    Internal name of service
5252   @param displayname    Display name of service (in taskbar ?)
5253   @param file_path    Path to this program
5254   @param startup_option Startup option to mysqld
5255 
5256   @retval
5257     0   option handled
5258   @retval
5259     1   Could not handle option
5260 */
5261 
5262 static bool
default_service_handling(char ** argv,const char * servicename,const char * displayname,const char * file_path,const char * extra_opt,const char * account_name)5263 default_service_handling(char **argv,
5264        const char *servicename,
5265        const char *displayname,
5266        const char *file_path,
5267        const char *extra_opt,
5268        const char *account_name)
5269 {
5270   char path_and_service[FN_REFLEN+FN_REFLEN+32], *pos, *end;
5271   const char *opt_delim;
5272   end= path_and_service + sizeof(path_and_service)-3;
5273 
5274   /* We have to quote filename if it contains spaces */
5275   pos= add_quoted_string(path_and_service, file_path, end);
5276   if (extra_opt && *extra_opt)
5277   {
5278     /*
5279      Add option after file_path. There will be zero or one extra option.  It's
5280      assumed to be --defaults-file=file but isn't checked.  The variable (not
5281      the option name) should be quoted if it contains a string.
5282     */
5283     *pos++= ' ';
5284     if (opt_delim= strchr(extra_opt, '='))
5285     {
5286       size_t length= ++opt_delim - extra_opt;
5287       pos= my_stpnmov(pos, extra_opt, length);
5288     }
5289     else
5290       opt_delim= extra_opt;
5291 
5292     pos= add_quoted_string(pos, opt_delim, end);
5293   }
5294   /* We must have servicename last */
5295   *pos++= ' ';
5296   (void) add_quoted_string(pos, servicename, end);
5297 
5298   if (Service.got_service_option(argv, "install"))
5299   {
5300     Service.Install(1, servicename, displayname, path_and_service,
5301                     account_name);
5302     return 0;
5303   }
5304   if (Service.got_service_option(argv, "install-manual"))
5305   {
5306     Service.Install(0, servicename, displayname, path_and_service,
5307                     account_name);
5308     return 0;
5309   }
5310   if (Service.got_service_option(argv, "remove"))
5311   {
5312     Service.Remove(servicename);
5313     return 0;
5314   }
5315   return 1;
5316 }
5317 
5318 
mysqld_main(int argc,char ** argv)5319 int mysqld_main(int argc, char **argv)
5320 {
5321   /*
5322     When several instances are running on the same machine, we
5323     need to have an  unique  named  hEventShudown  through the
5324     application PID e.g.: MySQLShutdown1890; MySQLShutdown2342
5325   */
5326   int10_to_str((int) GetCurrentProcessId(),my_stpcpy(shutdown_event_name,
5327                                                   "MySQLShutdown"), 10);
5328 
5329   /* Must be initialized early for comparison of service name */
5330   system_charset_info= &my_charset_utf8_general_ci;
5331 
5332 #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
5333   pre_initialize_performance_schema();
5334 #endif /*WITH_PERFSCHEMA_STORAGE_ENGINE */
5335 
5336   if (my_init())
5337   {
5338     sql_print_error("my_init() failed.");
5339     flush_error_log_messages();
5340     return 1;
5341   }
5342 
5343   if (Service.GetOS())  /* true NT family */
5344   {
5345     char file_path[FN_REFLEN];
5346     my_path(file_path, argv[0], "");          /* Find name in path */
5347     fn_format(file_path,argv[0],file_path,"",
5348               MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_RESOLVE_SYMLINKS);
5349 
5350     if (argc == 2)
5351     {
5352       if (!default_service_handling(argv, MYSQL_SERVICENAME, MYSQL_SERVICENAME,
5353                                     file_path, "", NULL))
5354         return 0;
5355       if (Service.IsService(argv[1]))        /* Start an optional service */
5356       {
5357         /*
5358           Only add the service name to the groups read from the config file
5359           if it's not "MySQL". (The default service name should be 'mysqld'
5360           but we started a bad tradition by calling it MySQL from the start
5361           and we are now stuck with it.
5362         */
5363         if (my_strcasecmp(system_charset_info, argv[1],"mysql"))
5364           load_default_groups[load_default_groups_sz-2]= argv[1];
5365         windows_service= true;
5366         Service.Init(argv[1], mysql_service);
5367         return 0;
5368       }
5369     }
5370     else if (argc == 3) /* install or remove any optional service */
5371     {
5372       if (!default_service_handling(argv, argv[2], argv[2], file_path, "",
5373                                     NULL))
5374         return 0;
5375       if (Service.IsService(argv[2]))
5376       {
5377         /*
5378           mysqld was started as
5379           mysqld --defaults-file=my_path\my.ini service-name
5380         */
5381         use_opt_args=1;
5382         opt_argc= 2;        // Skip service-name
5383         opt_argv=argv;
5384         windows_service= true;
5385         if (my_strcasecmp(system_charset_info, argv[2],"mysql"))
5386           load_default_groups[load_default_groups_sz-2]= argv[2];
5387         Service.Init(argv[2], mysql_service);
5388         return 0;
5389       }
5390     }
5391     else if (argc == 4 || argc == 5)
5392     {
5393       /*
5394         This may seem strange, because we handle --local-service while
5395         preserving 4.1's behavior of allowing any one other argument that is
5396         passed to the service on startup. (The assumption is that this is
5397         --defaults-file=file, but that was not enforced in 4.1, so we don't
5398         enforce it here.)
5399       */
5400       const char *extra_opt= NullS;
5401       const char *account_name = NullS;
5402       int index;
5403       for (index = 3; index < argc; index++)
5404       {
5405         if (!strcmp(argv[index], "--local-service"))
5406           account_name= "NT AUTHORITY\\LocalService";
5407         else
5408           extra_opt= argv[index];
5409       }
5410 
5411       if (argc == 4 || account_name)
5412         if (!default_service_handling(argv, argv[2], argv[2], file_path,
5413                                       extra_opt, account_name))
5414           return 0;
5415     }
5416     else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME))
5417     {
5418       /* start the default service */
5419       windows_service= true;
5420       Service.Init(MYSQL_SERVICENAME, mysql_service);
5421       return 0;
5422     }
5423   }
5424   /* Start as standalone server */
5425   Service.my_argc=argc;
5426   Service.my_argv=argv;
5427   mysql_service(NULL);
5428   return 0;
5429 }
5430 #endif // _WIN32
5431 #endif // !EMBEDDED_LIBRARY
5432 
5433 
read_init_file(char * file_name)5434 static bool read_init_file(char *file_name)
5435 {
5436   MYSQL_FILE *file;
5437   DBUG_ENTER("read_init_file");
5438   DBUG_PRINT("enter",("name: %s",file_name));
5439 
5440   sql_print_information("Execution of init_file \'%s\' started.", file_name);
5441 
5442   if (!(file= mysql_file_fopen(key_file_init, file_name,
5443                                O_RDONLY, MYF(MY_WME))))
5444     DBUG_RETURN(TRUE);
5445   (void) bootstrap(file);
5446   mysql_file_fclose(file, MYF(MY_WME));
5447 
5448   sql_print_information("Execution of init_file \'%s\' ended.", file_name);
5449 
5450   DBUG_RETURN(FALSE);
5451 }
5452 
5453 
5454 /****************************************************************************
5455   Handle start options
5456 ******************************************************************************/
5457 
5458 /**
5459   Process command line options flagged as 'early'.
5460   Some components needs to be initialized as early as possible,
5461   because the rest of the server initialization depends on them.
5462   Options that needs to be parsed early includes:
5463   - the performance schema, when compiled in,
5464   - options related to the help,
5465   - options related to the bootstrap
5466   The performance schema needs to be initialized as early as possible,
5467   before to-be-instrumented objects of the server are initialized.
5468 */
handle_early_options()5469 int handle_early_options()
5470 {
5471   int ho_error;
5472   vector<my_option> all_early_options;
5473   all_early_options.reserve(100);
5474 
5475   my_getopt_register_get_addr(NULL);
5476   /* Skip unknown options so that they may be processed later */
5477   my_getopt_skip_unknown= TRUE;
5478 
5479   /* Add the system variables parsed early */
5480   sys_var_add_options(&all_early_options, sys_var::PARSE_EARLY);
5481 
5482   /* Add the command line options parsed early */
5483   for (my_option *opt= my_long_early_options;
5484        opt->name != NULL;
5485        opt++)
5486     all_early_options.push_back(*opt);
5487 
5488   add_terminator(&all_early_options);
5489 
5490   my_getopt_error_reporter= option_error_reporter;
5491   my_charset_error_reporter= charset_error_reporter;
5492 
5493   ho_error= handle_options(&remaining_argc, &remaining_argv,
5494                            &all_early_options[0], mysqld_get_one_option);
5495   if (ho_error == 0)
5496   {
5497     /* Add back the program name handle_options removes */
5498     remaining_argc++;
5499     remaining_argv--;
5500 
5501     /* adjust the bootstrap options */
5502     if (opt_bootstrap)
5503     {
5504       sql_print_warning("--bootstrap is deprecated. "
5505                         "Please consider using --initialize instead");
5506     }
5507     if (opt_initialize_insecure)
5508       opt_initialize= TRUE;
5509     if (opt_initialize)
5510     {
5511       if (opt_bootstrap)
5512       {
5513         sql_print_error("Both --bootstrap and --initialize specified."
5514                         " Please pick one. Exiting.");
5515         ho_error= EXIT_AMBIGUOUS_OPTION;
5516       }
5517       opt_bootstrap= TRUE;
5518     }
5519   }
5520 
5521   // Swap with an empty vector, i.e. delete elements and free allocated space.
5522   vector<my_option>().swap(all_early_options);
5523 
5524   return ho_error;
5525 }
5526 
5527 /**
5528   Adjust @c open_files_limit.
5529   Computation is  based on:
5530   - @c max_connections,
5531   - @c table_cache_size,
5532   - the platform max open file limit.
5533 */
adjust_open_files_limit(ulong * requested_open_files)5534 void adjust_open_files_limit(ulong *requested_open_files)
5535 {
5536   ulong limit_1;
5537   ulong limit_2;
5538   ulong limit_3;
5539   ulong request_open_files;
5540   ulong effective_open_files;
5541 
5542   /* MyISAM requires two file handles per table. */
5543   limit_1= 10 + max_connections + table_cache_size * 2;
5544 
5545   /*
5546     We are trying to allocate no less than max_connections*5 file
5547     handles (i.e. we are trying to set the limit so that they will
5548     be available).
5549   */
5550   limit_2= max_connections * 5;
5551 
5552   /* Try to allocate no less than 5000 by default. */
5553   limit_3= open_files_limit ? open_files_limit : 5000;
5554 
5555   request_open_files= max<ulong>(max<ulong>(limit_1, limit_2), limit_3);
5556 
5557   /* Notice: my_set_max_open_files() may return more than requested. */
5558   effective_open_files= my_set_max_open_files(request_open_files);
5559 
5560   if (effective_open_files < request_open_files)
5561   {
5562     if (open_files_limit == 0)
5563     {
5564       sql_print_warning("Changed limits: max_open_files: %lu (requested %lu)",
5565                         effective_open_files, request_open_files);
5566     }
5567     else
5568     {
5569       sql_print_warning("Could not increase number of max_open_files to "
5570                         "more than %lu (request: %lu)",
5571                         effective_open_files, request_open_files);
5572     }
5573   }
5574 
5575   open_files_limit= effective_open_files;
5576   if (requested_open_files)
5577     *requested_open_files= min<ulong>(effective_open_files, request_open_files);
5578 }
5579 
adjust_max_connections(ulong requested_open_files)5580 void adjust_max_connections(ulong requested_open_files)
5581 {
5582   ulong limit;
5583 
5584   limit= requested_open_files - 10 - TABLE_OPEN_CACHE_MIN * 2;
5585 
5586   if (limit < max_connections)
5587   {
5588     sql_print_warning("Changed limits: max_connections: %lu (requested %lu)",
5589                       limit, max_connections);
5590 
5591     // This can be done unprotected since it is only called on startup.
5592     max_connections= limit;
5593   }
5594 }
5595 
adjust_table_cache_size(ulong requested_open_files)5596 void adjust_table_cache_size(ulong requested_open_files)
5597 {
5598   ulong limit;
5599 
5600   limit= max<ulong>((requested_open_files - 10 - max_connections) / 2,
5601                     TABLE_OPEN_CACHE_MIN);
5602 
5603   if (limit < table_cache_size)
5604   {
5605     sql_print_warning("Changed limits: table_open_cache: %lu (requested %lu)",
5606                       limit, table_cache_size);
5607 
5608     table_cache_size= limit;
5609   }
5610 
5611   table_cache_size_per_instance= table_cache_size / table_cache_instances;
5612 }
5613 
adjust_table_def_size()5614 void adjust_table_def_size()
5615 {
5616   ulong default_value;
5617   sys_var *var;
5618 
5619   default_value= min<ulong> (400 + table_cache_size / 2, 2000);
5620   var= intern_find_sys_var(STRING_WITH_LEN("table_definition_cache"));
5621   assert(var != NULL);
5622   var->update_default(default_value);
5623 
5624   if (! table_definition_cache_specified)
5625     table_def_size= default_value;
5626 }
5627 
adjust_related_options(ulong * requested_open_files)5628 void adjust_related_options(ulong *requested_open_files)
5629 {
5630   /* In bootstrap, disable grant tables (we are about to create them) */
5631   if (opt_bootstrap)
5632     opt_noacl= 1;
5633 
5634   /* The order is critical here, because of dependencies. */
5635   adjust_open_files_limit(requested_open_files);
5636   adjust_max_connections(*requested_open_files);
5637   adjust_table_cache_size(*requested_open_files);
5638   adjust_table_def_size();
5639 }
5640 
5641 vector<my_option> all_options;
5642 
5643 struct my_option my_long_early_options[]=
5644 {
5645   {"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts.", 0, 0, 0,
5646    GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
5647 #if !defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
5648   {"daemonize", 0, "Run mysqld as sysv daemon", &opt_daemonize,
5649     &opt_daemonize, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,0},
5650 #endif
5651   {"skip-grant-tables", 0,
5652    "Start without grant tables. This gives all users FULL ACCESS to all tables.",
5653    &opt_noacl, &opt_noacl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
5654    0},
5655   {"help", '?', "Display this help and exit.",
5656    &opt_help, &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
5657    0, 0},
5658   {"verbose", 'v', "Used with --help option for detailed help.",
5659    &opt_verbose, &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
5660   {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
5661    NO_ARG, 0, 0, 0, 0, 0, 0},
5662   {"initialize", 0, "Create the default database and exit."
5663    " Create a super user with a random expired password and store it into the log.",
5664    &opt_initialize, &opt_initialize, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
5665   {"initialize-insecure", 0, "Create the default database and exit."
5666    " Create a super user with empty password.",
5667    &opt_initialize_insecure, &opt_initialize_insecure, 0, GET_BOOL, NO_ARG,
5668    0, 0, 0, 0, 0, 0},
5669   {"disable-partition-engine-check", 0,
5670    "Skip the check for non-natively partitioned tables during bootstrap. "
5671    "This option is deprecated along with the partition engine.",
5672    &opt_disable_partition_check, &opt_disable_partition_check, 0, GET_BOOL,
5673    NO_ARG, TRUE, 0, 0, 0, 0, 0},
5674   {"keyring-migration-source", OPT_KEYRING_MIGRATION_SOURCE,
5675    "Keyring plugin from where the keys needs to "
5676    "be migrated to. This option must be specified along with "
5677    "--keyring-migration-destination.",
5678    &opt_keyring_migration_source, &opt_keyring_migration_source,
5679    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5680   {"keyring-migration-destination", OPT_KEYRING_MIGRATION_DESTINATION,
5681    "Keyring plugin to which the keys are "
5682    "migrated to. This option must be specified along with "
5683    "--keyring-migration-source.",
5684    &opt_keyring_migration_destination, &opt_keyring_migration_destination,
5685    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5686   {"keyring-migration-user", OPT_KEYRING_MIGRATION_USER,
5687    "User to login to server.",
5688    &opt_keyring_migration_user, &opt_keyring_migration_user,
5689    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5690   {"keyring-migration-host", OPT_KEYRING_MIGRATION_HOST, "Connect to host.",
5691    &opt_keyring_migration_host, &opt_keyring_migration_host,
5692    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5693   {"keyring-migration-password", OPT_KEYRING_MIGRATION_PASSWORD,
5694    "Password to use when connecting to server during keyring migration. "
5695    "If password value is not specified then it will be asked from the tty.",
5696    0, 0, 0, GET_PASSWORD, OPT_ARG, 0, 0, 0, 0, 0, 0},
5697   {"keyring-migration-socket", OPT_KEYRING_MIGRATION_SOCKET,
5698    "The socket file to use for connection.",
5699    &opt_keyring_migration_socket, &opt_keyring_migration_socket,
5700    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5701   {"keyring-migration-port", OPT_KEYRING_MIGRATION_PORT,
5702    "Port number to use for connection.",
5703    &opt_keyring_migration_port, &opt_keyring_migration_port,
5704    0, GET_ULONG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5705   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }
5706 };
5707 
5708 /**
5709   System variables are automatically command-line options (few
5710   exceptions are documented in sys_var.h), so don't need
5711   to be listed here.
5712 */
5713 
5714 struct my_option my_long_options[]=
5715 {
5716 #ifdef HAVE_REPLICATION
5717   {"abort-slave-event-count", 0,
5718    "Option used by mysql-test for debugging and testing of replication.",
5719    &abort_slave_event_count,  &abort_slave_event_count,
5720    0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5721 #endif /* HAVE_REPLICATION */
5722   {"allow-suspicious-udfs", 0,
5723    "Allows use of UDFs consisting of only one symbol xxx() "
5724    "without corresponding xxx_init() or xxx_deinit(). That also means "
5725    "that one can load any function from any library, for example exit() "
5726    "from libc.so",
5727    &opt_allow_suspicious_udfs, &opt_allow_suspicious_udfs,
5728    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
5729   {"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax. This mode "
5730    "will also set transaction isolation level 'serializable'.", 0, 0, 0,
5731    GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
5732   /*
5733     Because Sys_var_bit does not support command-line options, we need to
5734     explicitely add one for --autocommit
5735   */
5736   {"autocommit", 0, "Set default value for autocommit (0 or 1)",
5737    &opt_autocommit, &opt_autocommit, 0,
5738    GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, NULL},
5739   {"binlog-do-db", OPT_BINLOG_DO_DB,
5740    "Tells the master it should log updates for the specified database, "
5741    "and exclude all others not explicitly mentioned.",
5742    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5743   {"binlog-ignore-db", OPT_BINLOG_IGNORE_DB,
5744    "Tells the master that updates to the given database should not be logged to the binary log.",
5745    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5746   {"binlog-row-event-max-size", 0,
5747    "The maximum size of a row-based binary log event in bytes. Rows will be "
5748    "grouped into events smaller than this size if possible. "
5749    "The value has to be a multiple of 256.",
5750    &opt_binlog_rows_event_max_size, &opt_binlog_rows_event_max_size,
5751    0, GET_ULONG, REQUIRED_ARG,
5752    /* def_value */ 8192, /* min_value */  256, /* max_value */ ULONG_MAX,
5753    /* sub_size */     0, /* block_size */ 256,
5754    /* app_type */ 0
5755   },
5756   {"character-set-client-handshake", 0,
5757    "Don't ignore client side character set value sent during handshake.",
5758    &opt_character_set_client_handshake,
5759    &opt_character_set_client_handshake,
5760     0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
5761   {"character-set-filesystem", 0,
5762    "Set the filesystem character set.",
5763    &character_set_filesystem_name,
5764    &character_set_filesystem_name,
5765    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
5766   {"character-set-server", 'C', "Set the default character set.",
5767    &default_character_set_name, &default_character_set_name,
5768    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
5769   {"chroot", 'r', "Chroot mysqld daemon during startup.",
5770    &mysqld_chroot, &mysqld_chroot, 0, GET_STR, REQUIRED_ARG,
5771    0, 0, 0, 0, 0, 0},
5772   {"collation-server", 0, "Set the default collation.",
5773    &default_collation_name, &default_collation_name,
5774    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
5775   {"console", OPT_CONSOLE, "Write error output on screen; don't remove the console window on windows.",
5776    &opt_console, &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0,
5777    0, 0, 0},
5778   {"core-file", OPT_WANT_CORE, "Write core on errors.", 0, 0, 0, GET_NO_ARG,
5779    NO_ARG, 0, 0, 0, 0, 0, 0},
5780   /* default-storage-engine should have "MyISAM" as def_value. Instead
5781      of initializing it here it is done in init_common_variables() due
5782      to a compiler bug in Sun Studio compiler. */
5783   {"default-storage-engine", 0, "The default storage engine for new tables",
5784    &default_storage_engine, 0, 0, GET_STR, REQUIRED_ARG,
5785    0, 0, 0, 0, 0, 0 },
5786   {"default-tmp-storage-engine", 0,
5787     "The default storage engine for new explict temporary tables",
5788    &default_tmp_storage_engine, 0, 0, GET_STR, REQUIRED_ARG,
5789    0, 0, 0, 0, 0, 0 },
5790   {"default-time-zone", 0, "Set the default time zone.",
5791    &default_tz_name, &default_tz_name,
5792    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
5793 #ifdef HAVE_OPENSSL
5794   {"des-key-file", 0,
5795    "Load keys for des_encrypt() and des_encrypt from given file.",
5796    &des_key_file, &des_key_file, 0, GET_STR, REQUIRED_ARG,
5797    0, 0, 0, 0, 0, 0},
5798 #endif /* HAVE_OPENSSL */
5799 #ifdef HAVE_REPLICATION
5800   {"disconnect-slave-event-count", 0,
5801    "Option used by mysql-test for debugging and testing of replication.",
5802    &disconnect_slave_event_count, &disconnect_slave_event_count,
5803    0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5804 #endif /* HAVE_REPLICATION */
5805   {"exit-info", 'T', "Used for debugging. Use at your own risk.", 0, 0, 0,
5806    GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
5807 
5808   {"external-locking", 0, "Use system (external) locking (disabled by "
5809    "default).  With this option enabled you can run myisamchk to test "
5810    "(not repair) tables while the MySQL server is running. Disable with "
5811    "--skip-external-locking.", &opt_external_locking, &opt_external_locking,
5812    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
5813   /* We must always support the next option to make scripts like mysqltest
5814      easier to do */
5815   {"gdb", 0,
5816    "Set up signals usable for debugging.",
5817    &opt_debugging, &opt_debugging,
5818    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
5819 #if defined(HAVE_LINUX_LARGE_PAGES) || defined (HAVE_SOLARIS_LARGE_PAGES)
5820   {"super-large-pages", 0, "Enable support for super large pages.",
5821    &opt_super_large_pages, &opt_super_large_pages, 0,
5822    GET_BOOL, OPT_ARG, 0, 0, 1, 0, 1, 0},
5823 #endif
5824   {"ignore-db-dir", OPT_IGNORE_DB_DIRECTORY,
5825    "Specifies a directory to add to the ignore list when collecting "
5826    "database names from the datadir. Put a blank argument to reset "
5827    "the list accumulated so far.", 0, 0, 0, GET_STR, REQUIRED_ARG,
5828    0, 0, 0, 0, 0, 0},
5829   {"language", 'L',
5830    "Client error messages in given language. May be given as a full path. "
5831    "Deprecated. Use --lc-messages-dir instead.",
5832    &lc_messages_dir_ptr, &lc_messages_dir_ptr, 0,
5833    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5834   {"lc-messages", 0,
5835    "Set the language used for the error messages.",
5836    &lc_messages, &lc_messages, 0, GET_STR, REQUIRED_ARG,
5837    0, 0, 0, 0, 0, 0 },
5838   {"lc-time-names", 0,
5839    "Set the language used for the month names and the days of the week.",
5840    &lc_time_names_name, &lc_time_names_name,
5841    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
5842   {"log-bin", OPT_BIN_LOG,
5843    "Log update queries in binary format. Optional (but strongly recommended "
5844    "to avoid replication problems if server's hostname changes) argument "
5845    "should be the chosen location for the binary log files.",
5846    &opt_bin_logname, &opt_bin_logname, 0, GET_STR_ALLOC,
5847    OPT_ARG, 0, 0, 0, 0, 0, 0},
5848   {"log-bin-index", 0,
5849    "File that holds the names for binary log files.",
5850    &opt_binlog_index_name, &opt_binlog_index_name, 0, GET_STR,
5851    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5852   {"relay-log-index", 0,
5853    "File that holds the names for relay log files.",
5854    &opt_relaylog_index_name, &opt_relaylog_index_name, 0, GET_STR,
5855    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5856   {"log-isam", OPT_ISAM_LOG, "Log all MyISAM changes to file.",
5857    &myisam_log_filename, &myisam_log_filename, 0, GET_STR,
5858    OPT_ARG, 0, 0, 0, 0, 0, 0},
5859   {"log-raw", 0,
5860    "Log to general log before any rewriting of the query. For use in debugging, not production as "
5861    "sensitive information may be logged.",
5862    &opt_general_log_raw, &opt_general_log_raw,
5863    0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0 },
5864   {"log-short-format", 0,
5865    "Don't log extra information to update and slow-query logs.",
5866    &opt_short_log_format, &opt_short_log_format,
5867    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
5868   {"log-tc", 0,
5869    "Path to transaction coordinator log (used for transactions that affect "
5870    "more than one storage engine, when binary log is disabled).",
5871    &opt_tc_log_file, &opt_tc_log_file, 0, GET_STR,
5872    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5873   {"log-tc-size", 0, "Size of transaction coordinator log.",
5874    &opt_tc_log_size, &opt_tc_log_size, 0, GET_ULONG,
5875    REQUIRED_ARG, TC_LOG_MIN_PAGES * my_getpagesize(),
5876    TC_LOG_MIN_PAGES * my_getpagesize(), ULONG_MAX, 0,
5877    my_getpagesize(), 0},
5878   {"master-info-file", 0,
5879    "The location and name of the file that remembers the master and where "
5880    "the I/O replication thread is in the master's binlogs.",
5881    &master_info_file, &master_info_file, 0, GET_STR,
5882    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5883   {"master-retry-count", OPT_MASTER_RETRY_COUNT,
5884    "The number of tries the slave will make to connect to the master before giving up. "
5885    "Deprecated option, use 'CHANGE MASTER TO master_retry_count = <num>' instead.",
5886    &master_retry_count, &master_retry_count, 0, GET_ULONG,
5887    REQUIRED_ARG, 3600*24, 0, 0, 0, 0, 0},
5888 #ifdef HAVE_REPLICATION
5889   {"max-binlog-dump-events", 0,
5890    "Option used by mysql-test for debugging and testing of replication.",
5891    &max_binlog_dump_events, &max_binlog_dump_events, 0,
5892    GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5893 #endif /* HAVE_REPLICATION */
5894   {"memlock", 0, "Lock mysqld in memory.", &locked_in_memory,
5895    &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
5896   {"old-style-user-limits", 0,
5897    "Enable old-style user limits (before 5.0.3, user resources were counted "
5898    "per each user+host vs. per account).",
5899    &opt_old_style_user_limits, &opt_old_style_user_limits,
5900    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
5901   {"port-open-timeout", 0,
5902    "Maximum time in seconds to wait for the port to become free. "
5903    "(Default: No wait).", &mysqld_port_timeout, &mysqld_port_timeout, 0,
5904    GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5905   {"replicate-do-db", OPT_REPLICATE_DO_DB,
5906    "Tells the slave thread to restrict replication to the specified database. "
5907    "To specify more than one database, use the directive multiple times, "
5908    "once for each database. Note that this will only work if you do not use "
5909    "cross-database queries such as UPDATE some_db.some_table SET foo='bar' "
5910    "while having selected a different or no database. If you need cross "
5911    "database updates to work, make sure you have 3.23.28 or later, and use "
5912    "replicate-wild-do-table=db_name.%.",
5913    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5914   {"replicate-do-table", OPT_REPLICATE_DO_TABLE,
5915    "Tells the slave thread to restrict replication to the specified table. "
5916    "To specify more than one table, use the directive multiple times, once "
5917    "for each table. This will work for cross-database updates, in contrast "
5918    "to replicate-do-db.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5919   {"replicate-ignore-db", OPT_REPLICATE_IGNORE_DB,
5920    "Tells the slave thread to not replicate to the specified database. To "
5921    "specify more than one database to ignore, use the directive multiple "
5922    "times, once for each database. This option will not work if you use "
5923    "cross database updates. If you need cross database updates to work, "
5924    "make sure you have 3.23.28 or later, and use replicate-wild-ignore-"
5925    "table=db_name.%. ", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5926   {"replicate-ignore-table", OPT_REPLICATE_IGNORE_TABLE,
5927    "Tells the slave thread to not replicate to the specified table. To specify "
5928    "more than one table to ignore, use the directive multiple times, once for "
5929    "each table. This will work for cross-database updates, in contrast to "
5930    "replicate-ignore-db.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5931   {"replicate-rewrite-db", OPT_REPLICATE_REWRITE_DB,
5932    "Updates to a database with a different name than the original. Example: "
5933    "replicate-rewrite-db=master_db_name->slave_db_name.",
5934    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5935 #ifdef HAVE_REPLICATION
5936   {"replicate-same-server-id", 0,
5937    "In replication, if set to 1, do not skip events having our server id. "
5938    "Default value is 0 (to break infinite loops in circular replication). "
5939    "Can't be set to 1 if --log-slave-updates is used.",
5940    &replicate_same_server_id, &replicate_same_server_id,
5941    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
5942 #endif
5943   {"replicate-wild-do-table", OPT_REPLICATE_WILD_DO_TABLE,
5944    "Tells the slave thread to restrict replication to the tables that match "
5945    "the specified wildcard pattern. To specify more than one table, use the "
5946    "directive multiple times, once for each table. This will work for cross-"
5947    "database updates. Example: replicate-wild-do-table=foo%.bar% will "
5948    "replicate only updates to tables in all databases that start with foo "
5949    "and whose table names start with bar.",
5950    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5951   {"replicate-wild-ignore-table", OPT_REPLICATE_WILD_IGNORE_TABLE,
5952    "Tells the slave thread to not replicate to the tables that match the "
5953    "given wildcard pattern. To specify more than one table to ignore, use "
5954    "the directive multiple times, once for each table. This will work for "
5955    "cross-database updates. Example: replicate-wild-ignore-table=foo%.bar% "
5956    "will not do updates to tables in databases that start with foo and whose "
5957    "table names start with bar.",
5958    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5959   {"safe-user-create", 0,
5960    "Don't allow new user creation by the user who has no write privileges to the mysql.user table.",
5961    &opt_safe_user_create, &opt_safe_user_create, 0, GET_BOOL,
5962    NO_ARG, 0, 0, 0, 0, 0, 0},
5963   {"show-slave-auth-info", 0,
5964    "Show user and password in SHOW SLAVE HOSTS on this master.",
5965    &opt_show_slave_auth_info, &opt_show_slave_auth_info, 0,
5966    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
5967   {"skip-host-cache", OPT_SKIP_HOST_CACHE, "Don't cache host names.", 0, 0, 0,
5968    GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
5969   {"skip-new", OPT_SKIP_NEW, "Don't use new, possibly wrong routines.",
5970    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
5971   {"skip-slave-start", 0,
5972    "If set, slave is not autostarted.", &opt_skip_slave_start,
5973    &opt_skip_slave_start, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
5974   {"skip-stack-trace", OPT_SKIP_STACK_TRACE,
5975    "Don't print a stack trace on failure.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
5976    0, 0, 0, 0},
5977 #if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
5978   {"slow-start-timeout", 0,
5979    "Maximum number of milliseconds that the service control manager should wait "
5980    "before trying to kill the windows service during startup"
5981    "(Default: 15000).", &slow_start_timeout, &slow_start_timeout, 0,
5982    GET_ULONG, REQUIRED_ARG, 15000, 0, 0, 0, 0, 0},
5983 #endif
5984 #ifdef HAVE_REPLICATION
5985   {"sporadic-binlog-dump-fail", 0,
5986    "Option used by mysql-test for debugging and testing of replication.",
5987    &opt_sporadic_binlog_dump_fail,
5988    &opt_sporadic_binlog_dump_fail, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
5989    0},
5990 #endif /* HAVE_REPLICATION */
5991 #ifdef HAVE_OPENSSL
5992   {"ssl", 0,
5993    "Enable SSL for connection (automatically enabled with other flags).",
5994    &opt_use_ssl, &opt_use_ssl, 0, GET_BOOL, OPT_ARG, 1, 0, 0,
5995    0, 0, 0},
5996 #endif
5997 #ifdef _WIN32
5998   {"standalone", 0,
5999   "Dummy option to start as a standalone program (NT).", 0, 0, 0, GET_NO_ARG,
6000    NO_ARG, 0, 0, 0, 0, 0, 0},
6001 #endif
6002   {"symbolic-links", 's', "Enable symbolic link support.",
6003    &my_enable_symlinks, &my_enable_symlinks, 0, GET_BOOL, NO_ARG,
6004    1, 0, 0, 0, 0, 0},
6005   {"sysdate-is-now", 0,
6006    "Non-default option to alias SYSDATE() to NOW() to make it safe-replicable. "
6007    "Since 5.0, SYSDATE() returns a `dynamic' value different for different "
6008    "invocations, even within the same statement.",
6009    &global_system_variables.sysdate_is_now,
6010    0, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
6011   {"tc-heuristic-recover", 0,
6012    "Decision to use in heuristic recover process. Possible values are OFF, "
6013    "COMMIT or ROLLBACK.", &tc_heuristic_recover, &tc_heuristic_recover,
6014    &tc_heuristic_recover_typelib, GET_ENUM, REQUIRED_ARG,
6015    TC_HEURISTIC_NOT_USED, 0, 0, 0, 0, 0},
6016 #if defined(ENABLED_DEBUG_SYNC)
6017   {"debug-sync-timeout", OPT_DEBUG_SYNC_TIMEOUT,
6018    "Enable the debug sync facility "
6019    "and optionally specify a default wait timeout in seconds. "
6020    "A zero value keeps the facility disabled.",
6021    &opt_debug_sync_timeout, 0,
6022    0, GET_UINT, OPT_ARG, 0, 0, UINT_MAX, 0, 0, 0},
6023 #endif /* defined(ENABLED_DEBUG_SYNC) */
6024   {"temp-pool", 0,
6025    "This option is deprecated and will be removed in a future version. "
6026 #if defined(__linux__)
6027    "Using this option will cause most temporary files created to use a small "
6028    "set of names, rather than a unique name for each new file.",
6029 #else
6030    "This option is ignored on this OS.",
6031 #endif
6032    &use_temp_pool, &use_temp_pool, 0, GET_BOOL, NO_ARG, 1,
6033    0, 0, 0, 0, 0},
6034   {"transaction-isolation", OPT_TRANSACTION_ISOLATION,
6035    "Default transaction isolation level.",
6036    &global_system_variables.tx_isolation,
6037    &global_system_variables.tx_isolation, &tx_isolation_typelib,
6038    GET_ENUM, REQUIRED_ARG, ISO_REPEATABLE_READ, 0, 0, 0, 0, 0},
6039   {"transaction-read-only", OPT_TRANSACTION_READ_ONLY,
6040    "Default transaction access mode. "
6041    "True if transactions are read-only.",
6042    &global_system_variables.tx_read_only,
6043    &global_system_variables.tx_read_only, 0,
6044    GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
6045   {"user", 'u', "Run mysqld daemon as user.", 0, 0, 0, GET_STR, REQUIRED_ARG,
6046    0, 0, 0, 0, 0, 0},
6047   {"early-plugin-load", OPT_EARLY_PLUGIN_LOAD,
6048    "Optional semicolon-separated list of plugins to load before storage engine "
6049    "initialization, where each plugin is identified as name=library, where "
6050    "name is the plugin name and library is the plugin library in plugin_dir.",
6051    0, 0, 0,
6052    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6053   {"plugin-load", OPT_PLUGIN_LOAD,
6054    "Optional semicolon-separated list of plugins to load, where each plugin is "
6055    "identified as name=library, where name is the plugin name and library "
6056    "is the plugin library in plugin_dir.",
6057    0, 0, 0,
6058    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6059   {"plugin-load-add", OPT_PLUGIN_LOAD_ADD,
6060    "Optional semicolon-separated list of plugins to load, where each plugin is "
6061    "identified as name=library, where name is the plugin name and library "
6062    "is the plugin library in plugin_dir. This option adds to the list "
6063    "specified by --plugin-load in an incremental way. "
6064    "Multiple --plugin-load-add are supported.",
6065    0, 0, 0,
6066    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6067 
6068   {"innodb", OPT_SKIP_INNODB,
6069    "Deprecated option. Provided for backward compatibility only. "
6070    "The option has no effect on the server behaviour. InnoDB is always enabled. "
6071    "The option will be removed in a future release.",
6072    0, 0, 0, GET_BOOL, OPT_ARG,
6073    0, 0, 0, 0, 0, 0},
6074 
6075   {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
6076 };
6077 
6078 
show_queries(THD * thd,SHOW_VAR * var,char * buff)6079 static int show_queries(THD *thd, SHOW_VAR *var, char *buff)
6080 {
6081   var->type= SHOW_LONGLONG;
6082   var->value= (char *)&thd->query_id;
6083   return 0;
6084 }
6085 
6086 
show_net_compression(THD * thd,SHOW_VAR * var,char * buff)6087 static int show_net_compression(THD *thd, SHOW_VAR *var, char *buff)
6088 {
6089   var->type= SHOW_MY_BOOL;
6090   var->value= buff;
6091   *((bool *)buff)= thd->get_protocol()->get_compression();
6092   return 0;
6093 }
6094 
show_starttime(THD * thd,SHOW_VAR * var,char * buff)6095 static int show_starttime(THD *thd, SHOW_VAR *var, char *buff)
6096 {
6097   var->type= SHOW_LONGLONG;
6098   var->value= buff;
6099   *((longlong *)buff)= (longlong) (thd->query_start() - server_start_time);
6100   return 0;
6101 }
6102 
show_max_used_connections_time(THD * thd,SHOW_VAR * var,char * buff)6103 static int show_max_used_connections_time(THD *thd, SHOW_VAR *var, char *buff)
6104 {
6105   MYSQL_TIME max_used_connections_time;
6106   var->type= SHOW_CHAR;
6107   var->value= buff;
6108   thd->variables.time_zone->gmt_sec_to_TIME(&max_used_connections_time,
6109     Connection_handler_manager::max_used_connections_time);
6110   my_datetime_to_str(&max_used_connections_time, buff, 0);
6111   return 0;
6112 }
6113 
show_num_thread_running(THD * thd,SHOW_VAR * var,char * buff)6114 static int show_num_thread_running(THD *thd, SHOW_VAR *var, char *buff)
6115 {
6116   var->type= SHOW_LONGLONG;
6117   var->value= buff;
6118   long long *value= reinterpret_cast<long long*>(buff);
6119   *value= static_cast<long long>(Global_THD_manager::get_instance()->
6120                                  get_num_thread_running());
6121   return 0;
6122 }
6123 
6124 
show_num_thread_created(THD * thd,SHOW_VAR * var,char * buff)6125 static int show_num_thread_created(THD *thd, SHOW_VAR *var, char *buff)
6126 {
6127   var->type= SHOW_LONG;
6128   var->value= buff;
6129   long *value= reinterpret_cast<long*>(buff);
6130   *value= static_cast<long>(Global_THD_manager::get_instance()->
6131                             get_num_thread_created());
6132   return 0;
6133 }
6134 
show_thread_id_count(THD * thd,SHOW_VAR * var,char * buff)6135 static int show_thread_id_count(THD *thd, SHOW_VAR *var, char *buff)
6136 {
6137   var->type= SHOW_LONG;
6138   var->value= buff;
6139   long *value= reinterpret_cast<long*>(buff);
6140   *value= static_cast<long>(Global_THD_manager::get_instance()->
6141                             get_thread_id());
6142   return 0;
6143 }
6144 
6145 
6146 #ifndef EMBEDDED_LIBRARY
show_aborted_connects(THD * thd,SHOW_VAR * var,char * buff)6147 static int show_aborted_connects(THD *thd, SHOW_VAR *var, char *buff)
6148 {
6149   var->type= SHOW_LONG;
6150   var->value= buff;
6151   long *value= reinterpret_cast<long*>(buff);
6152   *value= static_cast<long>(Connection_handler_manager::get_instance()->
6153                             aborted_connects());
6154   return 0;
6155 }
6156 
6157 
show_connection_errors_max_connection(THD * thd,SHOW_VAR * var,char * buff)6158 static int show_connection_errors_max_connection(THD *thd, SHOW_VAR *var,
6159                                                  char *buff)
6160 {
6161   var->type= SHOW_LONG;
6162   var->value= buff;
6163   long *value= reinterpret_cast<long*>(buff);
6164   *value= static_cast<long>(Connection_handler_manager::get_instance()->
6165                             connection_errors_max_connection());
6166   return 0;
6167 }
6168 
show_connection_errors_select(THD * thd,SHOW_VAR * var,char * buff)6169 static int show_connection_errors_select(THD *thd, SHOW_VAR *var, char *buff)
6170 {
6171   var->type= SHOW_LONG;
6172   var->value= buff;
6173   long *value= reinterpret_cast<long*>(buff);
6174   *value=
6175     static_cast<long>(Mysqld_socket_listener::get_connection_errors_select());
6176   return 0;
6177 }
6178 
show_connection_errors_accept(THD * thd,SHOW_VAR * var,char * buff)6179 static int show_connection_errors_accept(THD *thd, SHOW_VAR *var, char *buff)
6180 {
6181   var->type= SHOW_LONG;
6182   var->value= buff;
6183   long *value= reinterpret_cast<long*>(buff);
6184   *value=
6185     static_cast<long>(Mysqld_socket_listener::get_connection_errors_accept());
6186   return 0;
6187 }
6188 
show_connection_errors_tcpwrap(THD * thd,SHOW_VAR * var,char * buff)6189 static int show_connection_errors_tcpwrap(THD *thd, SHOW_VAR *var, char *buff)
6190 {
6191   var->type= SHOW_LONG;
6192   var->value= buff;
6193   long *value= reinterpret_cast<long*>(buff);
6194   *value=
6195     static_cast<long>(Mysqld_socket_listener::get_connection_errors_tcpwrap());
6196   return 0;
6197 }
6198 #endif
6199 
6200 
6201 #ifdef ENABLED_PROFILING
show_flushstatustime(THD * thd,SHOW_VAR * var,char * buff)6202 static int show_flushstatustime(THD *thd, SHOW_VAR *var, char *buff)
6203 {
6204   var->type= SHOW_LONGLONG;
6205   var->value= buff;
6206   *((longlong *)buff)= (longlong) (thd->query_start() - flush_status_time);
6207   return 0;
6208 }
6209 #endif
6210 
6211 #ifdef HAVE_REPLICATION
6212 /**
6213   After Multisource replication, this function only shows the value
6214   of default channel.
6215 
6216   To know the status of other channels, performance schema replication
6217   tables comes to the rescue.
6218 
6219   @TODO: any warning needed if multiple channels exist to request
6220          the users to start using replication performance schema
6221          tables.
6222 */
show_slave_running(THD * thd,SHOW_VAR * var,char * buff)6223 static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff)
6224 {
6225   channel_map.rdlock();
6226   Master_info *mi= channel_map.get_default_channel_mi();
6227 
6228   if (mi)
6229   {
6230     var->type= SHOW_MY_BOOL;
6231     var->value= buff;
6232     *((my_bool *)buff)= (my_bool) (mi &&
6233                                    mi->slave_running == MYSQL_SLAVE_RUN_CONNECT &&
6234                                    mi->rli->slave_running);
6235   }
6236   else
6237     var->type= SHOW_UNDEF;
6238 
6239   channel_map.unlock();
6240   return 0;
6241 }
6242 
6243 
6244 /**
6245   This status variable is also exclusively (look comments on
6246   show_slave_running()) for default channel.
6247 */
show_slave_retried_trans(THD * thd,SHOW_VAR * var,char * buff)6248 static int show_slave_retried_trans(THD *thd, SHOW_VAR *var, char *buff)
6249 {
6250   channel_map.rdlock();
6251   Master_info *mi= channel_map.get_default_channel_mi();
6252 
6253   if (mi)
6254   {
6255     var->type= SHOW_LONG;
6256     var->value= buff;
6257     *((long *)buff)= (long)mi->rli->retried_trans;
6258   }
6259   else
6260     var->type= SHOW_UNDEF;
6261 
6262   channel_map.unlock();
6263   return 0;
6264 }
6265 
6266 /**
6267   Only for default channel. Refer to comments on show_slave_running()
6268 */
show_slave_received_heartbeats(THD * thd,SHOW_VAR * var,char * buff)6269 static int show_slave_received_heartbeats(THD *thd, SHOW_VAR *var, char *buff)
6270 {
6271   channel_map.rdlock();
6272   Master_info *mi= channel_map.get_default_channel_mi();
6273 
6274   if (mi)
6275   {
6276     var->type= SHOW_LONGLONG;
6277     var->value= buff;
6278     *((longlong *)buff)= mi->received_heartbeats;
6279   }
6280   else
6281     var->type= SHOW_UNDEF;
6282 
6283   channel_map.unlock();
6284   return 0;
6285 }
6286 
6287 /**
6288   Only for default channel. Refer to comments on show_slave_running()
6289 */
show_slave_last_heartbeat(THD * thd,SHOW_VAR * var,char * buff)6290 static int show_slave_last_heartbeat(THD *thd, SHOW_VAR *var, char *buff)
6291 {
6292   MYSQL_TIME received_heartbeat_time;
6293 
6294   channel_map.rdlock();
6295   Master_info *mi= channel_map.get_default_channel_mi();
6296 
6297   if (mi)
6298   {
6299     var->type= SHOW_CHAR;
6300     var->value= buff;
6301     if (mi->last_heartbeat == 0)
6302       buff[0]='\0';
6303     else
6304     {
6305       thd->variables.time_zone->gmt_sec_to_TIME(&received_heartbeat_time,
6306         static_cast<my_time_t>(mi->last_heartbeat));
6307       my_datetime_to_str(&received_heartbeat_time, buff, 0);
6308     }
6309   }
6310   else
6311     var->type= SHOW_UNDEF;
6312 
6313   channel_map.unlock();
6314   return 0;
6315 }
6316 
6317 /**
6318   Only for default channel. For details, refer to show_slave_running()
6319 */
show_heartbeat_period(THD * thd,SHOW_VAR * var,char * buff)6320 static int show_heartbeat_period(THD *thd, SHOW_VAR *var, char *buff)
6321 {
6322   DEBUG_SYNC(thd, "dsync_show_heartbeat_period");
6323 
6324   channel_map.rdlock();
6325   Master_info *mi= channel_map.get_default_channel_mi();
6326 
6327   if (mi)
6328   {
6329     var->type= SHOW_CHAR;
6330     var->value= buff;
6331     sprintf(buff, "%.3f", mi->heartbeat_period);
6332   }
6333   else
6334     var->type= SHOW_UNDEF;
6335 
6336   channel_map.unlock();
6337   return 0;
6338 }
6339 
6340 #ifndef NDEBUG
show_slave_rows_last_search_algorithm_used(THD * thd,SHOW_VAR * var,char * buff)6341 static int show_slave_rows_last_search_algorithm_used(THD *thd, SHOW_VAR *var, char *buff)
6342 {
6343   uint res= slave_rows_last_search_algorithm_used;
6344   const char* s= ((res == Rows_log_event::ROW_LOOKUP_TABLE_SCAN) ? "TABLE_SCAN" :
6345                   ((res == Rows_log_event::ROW_LOOKUP_HASH_SCAN) ? "HASH_SCAN" :
6346                    "INDEX_SCAN"));
6347 
6348   var->type= SHOW_CHAR;
6349   var->value= buff;
6350   sprintf(buff, "%s", s);
6351 
6352   return 0;
6353 }
6354 
show_ongoing_automatic_gtid_violating_transaction_count(THD * thd,SHOW_VAR * var,char * buf)6355 static int show_ongoing_automatic_gtid_violating_transaction_count(
6356   THD *thd, SHOW_VAR *var, char *buf)
6357 {
6358   var->type= SHOW_CHAR;
6359   var->value= buf;
6360   sprintf(buf, "%d",
6361           gtid_state->get_automatic_gtid_violating_transaction_count());
6362   return 0;
6363 }
6364 
show_ongoing_anonymous_gtid_violating_transaction_count(THD * thd,SHOW_VAR * var,char * buf)6365 static int show_ongoing_anonymous_gtid_violating_transaction_count(
6366   THD *thd, SHOW_VAR *var, char *buf)
6367 {
6368   var->type= SHOW_CHAR;
6369   var->value= buf;
6370   sprintf(buf, "%d",
6371           gtid_state->get_anonymous_gtid_violating_transaction_count());
6372   return 0;
6373 }
6374 
6375 #endif
6376 
show_ongoing_anonymous_transaction_count(THD * thd,SHOW_VAR * var,char * buf)6377 static int show_ongoing_anonymous_transaction_count(
6378   THD *thd, SHOW_VAR *var, char *buf)
6379 {
6380   var->type= SHOW_CHAR;
6381   var->value= buf;
6382   sprintf(buf, "%d", gtid_state->get_anonymous_ownership_count());
6383   return 0;
6384 }
6385 
6386 #endif /* HAVE_REPLICATION */
6387 
show_open_tables(THD * thd,SHOW_VAR * var,char * buff)6388 static int show_open_tables(THD *thd, SHOW_VAR *var, char *buff)
6389 {
6390   var->type= SHOW_LONG;
6391   var->value= buff;
6392   *((long *)buff)= (long)table_cache_manager.cached_tables();
6393   return 0;
6394 }
6395 
show_prepared_stmt_count(THD * thd,SHOW_VAR * var,char * buff)6396 static int show_prepared_stmt_count(THD *thd, SHOW_VAR *var, char *buff)
6397 {
6398   var->type= SHOW_LONG;
6399   var->value= buff;
6400   mysql_mutex_lock(&LOCK_prepared_stmt_count);
6401   *((long *)buff)= (long)prepared_stmt_count;
6402   mysql_mutex_unlock(&LOCK_prepared_stmt_count);
6403   return 0;
6404 }
6405 
show_table_definitions(THD * thd,SHOW_VAR * var,char * buff)6406 static int show_table_definitions(THD *thd, SHOW_VAR *var, char *buff)
6407 {
6408   var->type= SHOW_LONG;
6409   var->value= buff;
6410   *((long *)buff)= (long)cached_table_definitions();
6411   return 0;
6412 }
6413 
6414 #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
6415 /* Functions relying on CTX */
show_ssl_ctx_sess_accept(THD * thd,SHOW_VAR * var,char * buff)6416 static int show_ssl_ctx_sess_accept(THD *thd, SHOW_VAR *var, char *buff)
6417 {
6418   var->type= SHOW_LONG;
6419   var->value= buff;
6420   *((long *)buff)= (!ssl_acceptor_fd ? 0 :
6421                      SSL_CTX_sess_accept(ssl_acceptor_fd->ssl_context));
6422   return 0;
6423 }
6424 
show_ssl_ctx_sess_accept_good(THD * thd,SHOW_VAR * var,char * buff)6425 static int show_ssl_ctx_sess_accept_good(THD *thd, SHOW_VAR *var, char *buff)
6426 {
6427   var->type= SHOW_LONG;
6428   var->value= buff;
6429   *((long *)buff)= (!ssl_acceptor_fd ? 0 :
6430                      SSL_CTX_sess_accept_good(ssl_acceptor_fd->ssl_context));
6431   return 0;
6432 }
6433 
show_ssl_ctx_sess_connect_good(THD * thd,SHOW_VAR * var,char * buff)6434 static int show_ssl_ctx_sess_connect_good(THD *thd, SHOW_VAR *var, char *buff)
6435 {
6436   var->type= SHOW_LONG;
6437   var->value= buff;
6438   *((long *)buff)= (!ssl_acceptor_fd ? 0 :
6439                      SSL_CTX_sess_connect_good(ssl_acceptor_fd->ssl_context));
6440   return 0;
6441 }
6442 
show_ssl_ctx_sess_accept_renegotiate(THD * thd,SHOW_VAR * var,char * buff)6443 static int show_ssl_ctx_sess_accept_renegotiate(THD *thd, SHOW_VAR *var, char *buff)
6444 {
6445   var->type= SHOW_LONG;
6446   var->value= buff;
6447   *((long *)buff)= (!ssl_acceptor_fd ? 0 :
6448                      SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context));
6449   return 0;
6450 }
6451 
show_ssl_ctx_sess_connect_renegotiate(THD * thd,SHOW_VAR * var,char * buff)6452 static int show_ssl_ctx_sess_connect_renegotiate(THD *thd, SHOW_VAR *var, char *buff)
6453 {
6454   var->type= SHOW_LONG;
6455   var->value= buff;
6456   *((long *)buff)= (!ssl_acceptor_fd ? 0 :
6457                      SSL_CTX_sess_connect_renegotiate(ssl_acceptor_fd->ssl_context));
6458   return 0;
6459 }
6460 
show_ssl_ctx_sess_cb_hits(THD * thd,SHOW_VAR * var,char * buff)6461 static int show_ssl_ctx_sess_cb_hits(THD *thd, SHOW_VAR *var, char *buff)
6462 {
6463   var->type= SHOW_LONG;
6464   var->value= buff;
6465   *((long *)buff)= (!ssl_acceptor_fd ? 0 :
6466                      SSL_CTX_sess_cb_hits(ssl_acceptor_fd->ssl_context));
6467   return 0;
6468 }
6469 
show_ssl_ctx_sess_hits(THD * thd,SHOW_VAR * var,char * buff)6470 static int show_ssl_ctx_sess_hits(THD *thd, SHOW_VAR *var, char *buff)
6471 {
6472   var->type= SHOW_LONG;
6473   var->value= buff;
6474   *((long *)buff)= (!ssl_acceptor_fd ? 0 :
6475                      SSL_CTX_sess_hits(ssl_acceptor_fd->ssl_context));
6476   return 0;
6477 }
6478 
show_ssl_ctx_sess_cache_full(THD * thd,SHOW_VAR * var,char * buff)6479 static int show_ssl_ctx_sess_cache_full(THD *thd, SHOW_VAR *var, char *buff)
6480 {
6481   var->type= SHOW_LONG;
6482   var->value= buff;
6483   *((long *)buff)= (!ssl_acceptor_fd ? 0 :
6484                      SSL_CTX_sess_cache_full(ssl_acceptor_fd->ssl_context));
6485   return 0;
6486 }
6487 
show_ssl_ctx_sess_misses(THD * thd,SHOW_VAR * var,char * buff)6488 static int show_ssl_ctx_sess_misses(THD *thd, SHOW_VAR *var, char *buff)
6489 {
6490   var->type= SHOW_LONG;
6491   var->value= buff;
6492   *((long *)buff)= (!ssl_acceptor_fd ? 0 :
6493                      SSL_CTX_sess_misses(ssl_acceptor_fd->ssl_context));
6494   return 0;
6495 }
6496 
show_ssl_ctx_sess_timeouts(THD * thd,SHOW_VAR * var,char * buff)6497 static int show_ssl_ctx_sess_timeouts(THD *thd, SHOW_VAR *var, char *buff)
6498 {
6499   var->type= SHOW_LONG;
6500   var->value= buff;
6501   *((long *)buff)= (!ssl_acceptor_fd ? 0 :
6502                      SSL_CTX_sess_timeouts(ssl_acceptor_fd->ssl_context));
6503   return 0;
6504 }
6505 
show_ssl_ctx_sess_number(THD * thd,SHOW_VAR * var,char * buff)6506 static int show_ssl_ctx_sess_number(THD *thd, SHOW_VAR *var, char *buff)
6507 {
6508   var->type= SHOW_LONG;
6509   var->value= buff;
6510   *((long *)buff)= (!ssl_acceptor_fd ? 0 :
6511                      SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context));
6512   return 0;
6513 }
6514 
show_ssl_ctx_sess_connect(THD * thd,SHOW_VAR * var,char * buff)6515 static int show_ssl_ctx_sess_connect(THD *thd, SHOW_VAR *var, char *buff)
6516 {
6517   var->type= SHOW_LONG;
6518   var->value= buff;
6519   *((long *)buff)= (!ssl_acceptor_fd ? 0 :
6520                      SSL_CTX_sess_connect(ssl_acceptor_fd->ssl_context));
6521   return 0;
6522 }
6523 
show_ssl_ctx_sess_get_cache_size(THD * thd,SHOW_VAR * var,char * buff)6524 static int show_ssl_ctx_sess_get_cache_size(THD *thd, SHOW_VAR *var, char *buff)
6525 {
6526   var->type= SHOW_LONG;
6527   var->value= buff;
6528   *((long *)buff)= (!ssl_acceptor_fd ? 0 :
6529                      SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context));
6530   return 0;
6531 }
6532 
show_ssl_ctx_get_verify_mode(THD * thd,SHOW_VAR * var,char * buff)6533 static int show_ssl_ctx_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff)
6534 {
6535   var->type= SHOW_LONG;
6536   var->value= buff;
6537   *((long *)buff)= (!ssl_acceptor_fd ? 0 :
6538                      SSL_CTX_get_verify_mode(ssl_acceptor_fd->ssl_context));
6539   return 0;
6540 }
6541 
show_ssl_ctx_get_verify_depth(THD * thd,SHOW_VAR * var,char * buff)6542 static int show_ssl_ctx_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff)
6543 {
6544   var->type= SHOW_LONG;
6545   var->value= buff;
6546   *((long *)buff)= (!ssl_acceptor_fd ? 0 :
6547                      SSL_CTX_get_verify_depth(ssl_acceptor_fd->ssl_context));
6548   return 0;
6549 }
6550 
show_ssl_ctx_get_session_cache_mode(THD * thd,SHOW_VAR * var,char * buff)6551 static int show_ssl_ctx_get_session_cache_mode(THD *thd, SHOW_VAR *var, char *buff)
6552 {
6553   var->type= SHOW_CHAR;
6554   if (!ssl_acceptor_fd)
6555     var->value= const_cast<char*>("NONE");
6556   else
6557     switch (SSL_CTX_get_session_cache_mode(ssl_acceptor_fd->ssl_context))
6558     {
6559     case SSL_SESS_CACHE_OFF:
6560       var->value= const_cast<char*>("OFF"); break;
6561     case SSL_SESS_CACHE_CLIENT:
6562       var->value= const_cast<char*>("CLIENT"); break;
6563     case SSL_SESS_CACHE_SERVER:
6564       var->value= const_cast<char*>("SERVER"); break;
6565     case SSL_SESS_CACHE_BOTH:
6566       var->value= const_cast<char*>("BOTH"); break;
6567     case SSL_SESS_CACHE_NO_AUTO_CLEAR:
6568       var->value= const_cast<char*>("NO_AUTO_CLEAR"); break;
6569     case SSL_SESS_CACHE_NO_INTERNAL_LOOKUP:
6570       var->value= const_cast<char*>("NO_INTERNAL_LOOKUP"); break;
6571     default:
6572       var->value= const_cast<char*>("Unknown"); break;
6573     }
6574   return 0;
6575 }
6576 
6577 /*
6578    Functions relying on SSL
6579    Note: In the show_ssl_* functions, we need to check if we have a
6580          valid vio-object since this isn't always true, specifically
6581          when session_status or global_status is requested from
6582          inside an Event.
6583  */
show_ssl_get_version(THD * thd,SHOW_VAR * var,char * buff)6584 static int show_ssl_get_version(THD *thd, SHOW_VAR *var, char *buff)
6585 {
6586   SSL_handle ssl = thd->get_ssl();
6587   var->type= SHOW_CHAR;
6588   if (ssl)
6589     var->value=
6590       const_cast<char*>(SSL_get_version(ssl));
6591   else
6592     var->value= (char *)"";
6593   return 0;
6594 }
6595 
show_ssl_session_reused(THD * thd,SHOW_VAR * var,char * buff)6596 static int show_ssl_session_reused(THD *thd, SHOW_VAR *var, char *buff)
6597 {
6598   SSL_handle ssl = thd->get_ssl();
6599   var->type= SHOW_LONG;
6600   var->value= buff;
6601   if (ssl)
6602     *((long *)buff)=
6603         (long)SSL_session_reused(ssl);
6604   else
6605     *((long *)buff)= 0;
6606   return 0;
6607 }
6608 
show_ssl_get_default_timeout(THD * thd,SHOW_VAR * var,char * buff)6609 static int show_ssl_get_default_timeout(THD *thd, SHOW_VAR *var, char *buff)
6610 {
6611   SSL_handle ssl = thd->get_ssl();
6612   var->type= SHOW_LONG;
6613   var->value= buff;
6614   if (ssl)
6615     *((long *)buff)=
6616       (long)SSL_get_default_timeout(ssl);
6617   else
6618     *((long *)buff)= 0;
6619   return 0;
6620 }
6621 
show_ssl_get_verify_mode(THD * thd,SHOW_VAR * var,char * buff)6622 static int show_ssl_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff)
6623 {
6624   SSL_handle ssl = thd->get_ssl();
6625   var->type= SHOW_LONG;
6626   var->value= buff;
6627   if (ssl)
6628     *((long *)buff)=
6629       (long)SSL_get_verify_mode(ssl);
6630   else
6631     *((long *)buff)= 0;
6632   return 0;
6633 }
6634 
show_ssl_get_verify_depth(THD * thd,SHOW_VAR * var,char * buff)6635 static int show_ssl_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff)
6636 {
6637   SSL_handle ssl = thd->get_ssl();
6638   var->type= SHOW_LONG;
6639   var->value= buff;
6640   if (ssl)
6641     *((long *)buff)=
6642         (long)SSL_get_verify_depth(ssl);
6643   else
6644     *((long *)buff)= 0;
6645   return 0;
6646 }
6647 
show_ssl_get_cipher(THD * thd,SHOW_VAR * var,char * buff)6648 static int show_ssl_get_cipher(THD *thd, SHOW_VAR *var, char *buff)
6649 {
6650   SSL_handle ssl = thd->get_ssl();
6651   var->type= SHOW_CHAR;
6652   if (ssl)
6653     var->value=
6654       const_cast<char*>(SSL_get_cipher(ssl));
6655   else
6656     var->value= (char *)"";
6657   return 0;
6658 }
6659 
show_ssl_get_cipher_list(THD * thd,SHOW_VAR * var,char * buff)6660 static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff)
6661 {
6662   SSL_handle ssl = thd->get_ssl();
6663   var->type= SHOW_CHAR;
6664   var->value= buff;
6665   if (ssl)
6666   {
6667     int i;
6668     const char *p;
6669     char *end= buff + SHOW_VAR_FUNC_BUFF_SIZE;
6670     for (i=0; (p= SSL_get_cipher_list(ssl,i)) &&
6671                buff < end; i++)
6672     {
6673       buff= my_stpnmov(buff, p, end-buff-1);
6674       *buff++= ':';
6675     }
6676     if (i)
6677       buff--;
6678   }
6679   *buff=0;
6680   return 0;
6681 }
6682 
6683 
6684 static char *
my_asn1_time_to_string(ASN1_TIME * time,char * buf,size_t len)6685 my_asn1_time_to_string(ASN1_TIME *time, char *buf, size_t len)
6686 {
6687   int n_read;
6688   char *res= NULL;
6689   BIO *bio= BIO_new(BIO_s_mem());
6690 
6691   if (bio == NULL)
6692     return NULL;
6693 
6694   if (!ASN1_TIME_print(bio, time))
6695     goto end;
6696 
6697   n_read= BIO_read(bio, buf, (int) (len - 1));
6698 
6699   if (n_read > 0)
6700   {
6701     buf[n_read]= 0;
6702     res= buf;
6703   }
6704 
6705 end:
6706   BIO_free(bio);
6707   return res;
6708 }
6709 
6710 
6711 /**
6712   Handler function for the 'ssl_get_server_not_before' variable
6713 
6714   @param      thd  the mysql thread structure
6715   @param      var  the data for the variable
6716   @param[out] buf  the string to put the value of the variable into
6717 
6718   @return          status
6719   @retval     0    success
6720 */
6721 
6722 static int
show_ssl_get_server_not_before(THD * thd,SHOW_VAR * var,char * buff)6723 show_ssl_get_server_not_before(THD *thd, SHOW_VAR *var, char *buff)
6724 {
6725   var->type= SHOW_CHAR;
6726   if (ssl_acceptor_fd)
6727   {
6728     X509 *cert= SSL_get_certificate(ssl_acceptor);
6729     ASN1_TIME *not_before= X509_get_notBefore(cert);
6730 
6731     if (not_before == NULL)
6732     {
6733       var->value= empty_c_string;
6734       return 0;
6735     }
6736 
6737     var->value= my_asn1_time_to_string(not_before, buff,
6738                                        SHOW_VAR_FUNC_BUFF_SIZE);
6739     if (var->value == NULL)
6740     {
6741       var->value= empty_c_string;
6742       return 1;
6743     }
6744   }
6745   else
6746     var->value= empty_c_string;
6747   return 0;
6748 }
6749 
6750 
6751 /**
6752   Handler function for the 'ssl_get_server_not_after' variable
6753 
6754   @param      thd  the mysql thread structure
6755   @param      var  the data for the variable
6756   @param[out] buf  the string to put the value of the variable into
6757 
6758   @return          status
6759   @retval     0    success
6760 */
6761 
6762 static int
show_ssl_get_server_not_after(THD * thd,SHOW_VAR * var,char * buff)6763 show_ssl_get_server_not_after(THD *thd, SHOW_VAR *var, char *buff)
6764 {
6765   var->type= SHOW_CHAR;
6766   if (ssl_acceptor_fd)
6767   {
6768     X509 *cert= SSL_get_certificate(ssl_acceptor);
6769     ASN1_TIME *not_after= X509_get_notAfter(cert);
6770 
6771     if (not_after == NULL)
6772     {
6773       var->value= empty_c_string;
6774       return 0;
6775     }
6776 
6777     var->value= my_asn1_time_to_string(not_after, buff,
6778                                        SHOW_VAR_FUNC_BUFF_SIZE);
6779     if (var->value == NULL)
6780     {
6781       var->value= empty_c_string;
6782       return 1;
6783     }
6784   }
6785   else
6786     var->value= empty_c_string;
6787   return 0;
6788 }
6789 
6790 #endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
6791 
show_slave_open_temp_tables(THD * thd,SHOW_VAR * var,char * buf)6792 static int show_slave_open_temp_tables(THD *thd, SHOW_VAR *var, char *buf)
6793 {
6794   var->type= SHOW_INT;
6795   var->value= buf;
6796   *((int *) buf)= slave_open_temp_tables.atomic_get();
6797   return 0;
6798 }
6799 
6800 /*
6801   Variables shown by SHOW STATUS in alphabetical order
6802 */
6803 
6804 SHOW_VAR status_vars[]= {
6805   {"Aborted_clients",          (char*) &aborted_threads,                              SHOW_LONG,               SHOW_SCOPE_GLOBAL},
6806 #ifndef EMBEDDED_LIBRARY
6807   {"Aborted_connects",         (char*) &show_aborted_connects,                        SHOW_FUNC,               SHOW_SCOPE_GLOBAL},
6808 #endif
6809 #ifdef HAVE_REPLICATION
6810 #ifndef NDEBUG
6811   {"Ongoing_anonymous_gtid_violating_transaction_count",(char*) &show_ongoing_anonymous_gtid_violating_transaction_count, SHOW_FUNC, SHOW_SCOPE_GLOBAL},
6812 #endif//!NDEBUG
6813   {"Ongoing_anonymous_transaction_count",(char*) &show_ongoing_anonymous_transaction_count, SHOW_FUNC, SHOW_SCOPE_GLOBAL},
6814 #ifndef NDEBUG
6815   {"Ongoing_automatic_gtid_violating_transaction_count",(char*) &show_ongoing_automatic_gtid_violating_transaction_count, SHOW_FUNC, SHOW_SCOPE_GLOBAL},
6816 #endif//!NDEBUG
6817 #endif//HAVE_REPLICATION
6818   {"Binlog_cache_disk_use",    (char*) &binlog_cache_disk_use,                        SHOW_LONG,               SHOW_SCOPE_GLOBAL},
6819   {"Binlog_cache_use",         (char*) &binlog_cache_use,                             SHOW_LONG,               SHOW_SCOPE_GLOBAL},
6820   {"Binlog_stmt_cache_disk_use",(char*) &binlog_stmt_cache_disk_use,                  SHOW_LONG,               SHOW_SCOPE_GLOBAL},
6821   {"Binlog_stmt_cache_use",    (char*) &binlog_stmt_cache_use,                        SHOW_LONG,               SHOW_SCOPE_GLOBAL},
6822   {"Bytes_received",           (char*) offsetof(STATUS_VAR, bytes_received),          SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6823   {"Bytes_sent",               (char*) offsetof(STATUS_VAR, bytes_sent),              SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6824   {"Com",                      (char*) com_status_vars,                               SHOW_ARRAY,              SHOW_SCOPE_ALL},
6825   {"Com_stmt_reprepare",       (char*) offsetof(STATUS_VAR, com_stmt_reprepare),      SHOW_LONG_STATUS,        SHOW_SCOPE_ALL},
6826   {"Compression",              (char*) &show_net_compression,                         SHOW_FUNC,               SHOW_SCOPE_SESSION},
6827   {"Connections",              (char*) &show_thread_id_count,                         SHOW_FUNC,               SHOW_SCOPE_GLOBAL},
6828 #ifndef EMBEDDED_LIBRARY
6829   {"Connection_errors_accept",   (char*) &show_connection_errors_accept,              SHOW_FUNC,               SHOW_SCOPE_GLOBAL},
6830   {"Connection_errors_internal", (char*) &connection_errors_internal,                 SHOW_LONG,               SHOW_SCOPE_GLOBAL},
6831   {"Connection_errors_max_connections",   (char*) &show_connection_errors_max_connection, SHOW_FUNC,           SHOW_SCOPE_GLOBAL},
6832   {"Connection_errors_peer_address", (char*) &connection_errors_peer_addr,            SHOW_LONG,               SHOW_SCOPE_GLOBAL},
6833   {"Connection_errors_select",   (char*) &show_connection_errors_select,              SHOW_FUNC,               SHOW_SCOPE_GLOBAL},
6834   {"Connection_errors_tcpwrap",  (char*) &show_connection_errors_tcpwrap,             SHOW_FUNC,               SHOW_SCOPE_GLOBAL},
6835 #endif
6836   {"Created_tmp_disk_tables",  (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6837   {"Created_tmp_files",        (char*) &my_tmp_file_created,                          SHOW_LONG,               SHOW_SCOPE_GLOBAL},
6838   {"Created_tmp_tables",       (char*) offsetof(STATUS_VAR, created_tmp_tables),      SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6839   {"Delayed_errors",           (char*) &delayed_insert_errors,                        SHOW_LONG,               SHOW_SCOPE_GLOBAL},
6840   {"Delayed_insert_threads",   (char*) &delayed_insert_threads,                       SHOW_LONG_NOFLUSH,       SHOW_SCOPE_GLOBAL},
6841   {"Delayed_writes",           (char*) &delayed_insert_writes,                        SHOW_LONG,               SHOW_SCOPE_GLOBAL},
6842   {"Flush_commands",           (char*) &refresh_version,                              SHOW_LONG_NOFLUSH,       SHOW_SCOPE_GLOBAL},
6843   {"Handler_commit",           (char*) offsetof(STATUS_VAR, ha_commit_count),         SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6844   {"Handler_delete",           (char*) offsetof(STATUS_VAR, ha_delete_count),         SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6845   {"Handler_discover",         (char*) offsetof(STATUS_VAR, ha_discover_count),       SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6846   {"Handler_external_lock",    (char*) offsetof(STATUS_VAR, ha_external_lock_count),  SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6847   {"Handler_mrr_init",         (char*) offsetof(STATUS_VAR, ha_multi_range_read_init_count), SHOW_LONGLONG_STATUS, SHOW_SCOPE_ALL},
6848   {"Handler_prepare",          (char*) offsetof(STATUS_VAR, ha_prepare_count),        SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6849   {"Handler_read_first",       (char*) offsetof(STATUS_VAR, ha_read_first_count),     SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6850   {"Handler_read_key",         (char*) offsetof(STATUS_VAR, ha_read_key_count),       SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6851   {"Handler_read_last",        (char*) offsetof(STATUS_VAR, ha_read_last_count),      SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6852   {"Handler_read_next",        (char*) offsetof(STATUS_VAR, ha_read_next_count),      SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6853   {"Handler_read_prev",        (char*) offsetof(STATUS_VAR, ha_read_prev_count),      SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6854   {"Handler_read_rnd",         (char*) offsetof(STATUS_VAR, ha_read_rnd_count),       SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6855   {"Handler_read_rnd_next",    (char*) offsetof(STATUS_VAR, ha_read_rnd_next_count),  SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6856   {"Handler_rollback",         (char*) offsetof(STATUS_VAR, ha_rollback_count),       SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6857   {"Handler_savepoint",        (char*) offsetof(STATUS_VAR, ha_savepoint_count),      SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6858   {"Handler_savepoint_rollback",(char*) offsetof(STATUS_VAR, ha_savepoint_rollback_count), SHOW_LONGLONG_STATUS, SHOW_SCOPE_ALL},
6859   {"Handler_update",           (char*) offsetof(STATUS_VAR, ha_update_count),         SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6860   {"Handler_write",            (char*) offsetof(STATUS_VAR, ha_write_count),          SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6861   {"Key_blocks_not_flushed",   (char*) offsetof(KEY_CACHE, global_blocks_changed),    SHOW_KEY_CACHE_LONG,     SHOW_SCOPE_GLOBAL},
6862   {"Key_blocks_unused",        (char*) offsetof(KEY_CACHE, blocks_unused),            SHOW_KEY_CACHE_LONG,     SHOW_SCOPE_GLOBAL},
6863   {"Key_blocks_used",          (char*) offsetof(KEY_CACHE, blocks_used),              SHOW_KEY_CACHE_LONG,     SHOW_SCOPE_GLOBAL},
6864   {"Key_read_requests",        (char*) offsetof(KEY_CACHE, global_cache_r_requests),  SHOW_KEY_CACHE_LONGLONG, SHOW_SCOPE_GLOBAL},
6865   {"Key_reads",                (char*) offsetof(KEY_CACHE, global_cache_read),        SHOW_KEY_CACHE_LONGLONG, SHOW_SCOPE_GLOBAL},
6866   {"Key_write_requests",       (char*) offsetof(KEY_CACHE, global_cache_w_requests),  SHOW_KEY_CACHE_LONGLONG, SHOW_SCOPE_GLOBAL},
6867   {"Key_writes",               (char*) offsetof(KEY_CACHE, global_cache_write),       SHOW_KEY_CACHE_LONGLONG, SHOW_SCOPE_GLOBAL},
6868   {"Last_query_cost",          (char*) offsetof(STATUS_VAR, last_query_cost),         SHOW_DOUBLE_STATUS,      SHOW_SCOPE_SESSION},
6869   {"Last_query_partial_plans", (char*) offsetof(STATUS_VAR, last_query_partial_plans),SHOW_LONGLONG_STATUS,    SHOW_SCOPE_SESSION},
6870 #ifndef EMBEDDED_LIBRARY
6871   {"Locked_connects",          (char*) &locked_account_connection_count,              SHOW_LONG,               SHOW_SCOPE_GLOBAL},
6872 #endif
6873   {"Max_execution_time_exceeded",   (char*) offsetof(STATUS_VAR, max_execution_time_exceeded),   SHOW_LONGLONG_STATUS, SHOW_SCOPE_ALL},
6874   {"Max_execution_time_set",        (char*) offsetof(STATUS_VAR, max_execution_time_set),        SHOW_LONGLONG_STATUS, SHOW_SCOPE_ALL},
6875   {"Max_execution_time_set_failed", (char*) offsetof(STATUS_VAR, max_execution_time_set_failed), SHOW_LONGLONG_STATUS, SHOW_SCOPE_ALL},
6876   {"Max_used_connections",     (char*) &Connection_handler_manager::max_used_connections,        SHOW_LONG,        SHOW_SCOPE_GLOBAL},
6877   {"Max_used_connections_time",(char*) &show_max_used_connections_time,               SHOW_FUNC,               SHOW_SCOPE_GLOBAL},
6878   {"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use,                          SHOW_LONG_NOFLUSH,       SHOW_SCOPE_GLOBAL},
6879   {"Open_files",               (char*) &my_file_opened,                               SHOW_LONG_NOFLUSH,       SHOW_SCOPE_GLOBAL},
6880   {"Open_streams",             (char*) &my_stream_opened,                             SHOW_LONG_NOFLUSH,       SHOW_SCOPE_GLOBAL},
6881   {"Open_table_definitions",   (char*) &show_table_definitions,                       SHOW_FUNC,               SHOW_SCOPE_GLOBAL},
6882   {"Open_tables",              (char*) &show_open_tables,                             SHOW_FUNC,               SHOW_SCOPE_ALL},
6883   {"Opened_files",             (char*) &my_file_total_opened,                         SHOW_LONG_NOFLUSH,       SHOW_SCOPE_GLOBAL},
6884   {"Opened_tables",            (char*) offsetof(STATUS_VAR, opened_tables),           SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6885   {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares),           SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6886   {"Prepared_stmt_count",      (char*) &show_prepared_stmt_count,                     SHOW_FUNC,               SHOW_SCOPE_GLOBAL},
6887   {"Qcache_free_blocks",       (char*) &query_cache.free_memory_blocks,               SHOW_LONG_NOFLUSH,       SHOW_SCOPE_GLOBAL},
6888   {"Qcache_free_memory",       (char*) &query_cache.free_memory,                      SHOW_LONG_NOFLUSH,       SHOW_SCOPE_GLOBAL},
6889   {"Qcache_hits",              (char*) &query_cache.hits,                             SHOW_LONG,               SHOW_SCOPE_GLOBAL},
6890   {"Qcache_inserts",           (char*) &query_cache.inserts,                          SHOW_LONG,               SHOW_SCOPE_GLOBAL},
6891   {"Qcache_lowmem_prunes",     (char*) &query_cache.lowmem_prunes,                    SHOW_LONG,               SHOW_SCOPE_GLOBAL},
6892   {"Qcache_not_cached",        (char*) &query_cache.refused,                          SHOW_LONG,               SHOW_SCOPE_GLOBAL},
6893   {"Qcache_queries_in_cache",  (char*) &query_cache.queries_in_cache,                 SHOW_LONG_NOFLUSH,       SHOW_SCOPE_GLOBAL},
6894   {"Qcache_total_blocks",      (char*) &query_cache.total_blocks,                     SHOW_LONG_NOFLUSH,       SHOW_SCOPE_GLOBAL},
6895   {"Queries",                  (char*) &show_queries,                                 SHOW_FUNC,               SHOW_SCOPE_ALL},
6896   {"Questions",                (char*) offsetof(STATUS_VAR, questions),               SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6897   {"Select_full_join",         (char*) offsetof(STATUS_VAR, select_full_join_count),  SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
6898   {"Select_full_range_join",   (char*) offsetof(STATUS_VAR, select_full_range_join_count), SHOW_LONGLONG_STATUS, SHOW_SCOPE_ALL},
6899   {"Select_range",             (char*) offsetof(STATUS_VAR, select_range_count),       SHOW_LONGLONG_STATUS,   SHOW_SCOPE_ALL},
6900   {"Select_range_check",       (char*) offsetof(STATUS_VAR, select_range_check_count), SHOW_LONGLONG_STATUS,   SHOW_SCOPE_ALL},
6901   {"Select_scan",	       (char*) offsetof(STATUS_VAR, select_scan_count),              SHOW_LONGLONG_STATUS,   SHOW_SCOPE_ALL},
6902   {"Slave_open_temp_tables",   (char*) &show_slave_open_temp_tables,                   SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6903 #ifdef HAVE_REPLICATION
6904   {"Slave_retried_transactions",(char*) &show_slave_retried_trans,                     SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6905   {"Slave_heartbeat_period",   (char*) &show_heartbeat_period,                         SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6906   {"Slave_received_heartbeats",(char*) &show_slave_received_heartbeats,                SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6907   {"Slave_last_heartbeat",     (char*) &show_slave_last_heartbeat,                     SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6908 #ifndef NDEBUG
6909   {"Slave_rows_last_search_algorithm_used",(char*) &show_slave_rows_last_search_algorithm_used, SHOW_FUNC,     SHOW_SCOPE_GLOBAL},
6910 #endif
6911   {"Slave_running",            (char*) &show_slave_running,                            SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6912 #endif
6913 #ifndef EMBEDDED_LIBRARY
6914   {"Slow_launch_threads",      (char*) &Per_thread_connection_handler::slow_launch_threads, SHOW_LONG,         SHOW_SCOPE_ALL},
6915 #endif
6916   {"Slow_queries",             (char*) offsetof(STATUS_VAR, long_query_count),         SHOW_LONGLONG_STATUS,   SHOW_SCOPE_ALL},
6917   {"Sort_merge_passes",        (char*) offsetof(STATUS_VAR, filesort_merge_passes),    SHOW_LONGLONG_STATUS,   SHOW_SCOPE_ALL},
6918   {"Sort_range",               (char*) offsetof(STATUS_VAR, filesort_range_count),     SHOW_LONGLONG_STATUS,   SHOW_SCOPE_ALL},
6919   {"Sort_rows",                (char*) offsetof(STATUS_VAR, filesort_rows),            SHOW_LONGLONG_STATUS,   SHOW_SCOPE_ALL},
6920   {"Sort_scan",                (char*) offsetof(STATUS_VAR, filesort_scan_count),      SHOW_LONGLONG_STATUS,   SHOW_SCOPE_ALL},
6921 #ifdef HAVE_OPENSSL
6922 #ifndef EMBEDDED_LIBRARY
6923   {"Ssl_accept_renegotiates",  (char*) &show_ssl_ctx_sess_accept_renegotiate,          SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6924   {"Ssl_accepts",              (char*) &show_ssl_ctx_sess_accept,                      SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6925   {"Ssl_callback_cache_hits",  (char*) &show_ssl_ctx_sess_cb_hits,                     SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6926   {"Ssl_cipher",               (char*) &show_ssl_get_cipher,                           SHOW_FUNC,              SHOW_SCOPE_ALL},
6927   {"Ssl_cipher_list",          (char*) &show_ssl_get_cipher_list,                      SHOW_FUNC,              SHOW_SCOPE_ALL},
6928   {"Ssl_client_connects",      (char*) &show_ssl_ctx_sess_connect,                     SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6929   {"Ssl_connect_renegotiates", (char*) &show_ssl_ctx_sess_connect_renegotiate,         SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6930   {"Ssl_ctx_verify_depth",     (char*) &show_ssl_ctx_get_verify_depth,                 SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6931   {"Ssl_ctx_verify_mode",      (char*) &show_ssl_ctx_get_verify_mode,                  SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6932   {"Ssl_default_timeout",      (char*) &show_ssl_get_default_timeout,                  SHOW_FUNC,              SHOW_SCOPE_ALL},
6933   {"Ssl_finished_accepts",     (char*) &show_ssl_ctx_sess_accept_good,                 SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6934   {"Ssl_finished_connects",    (char*) &show_ssl_ctx_sess_connect_good,                SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6935   {"Ssl_session_cache_hits",   (char*) &show_ssl_ctx_sess_hits,                        SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6936   {"Ssl_session_cache_misses", (char*) &show_ssl_ctx_sess_misses,                      SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6937   {"Ssl_session_cache_mode",   (char*) &show_ssl_ctx_get_session_cache_mode,           SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6938   {"Ssl_session_cache_overflows", (char*) &show_ssl_ctx_sess_cache_full,               SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6939   {"Ssl_session_cache_size",   (char*) &show_ssl_ctx_sess_get_cache_size,              SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6940   {"Ssl_session_cache_timeouts", (char*) &show_ssl_ctx_sess_timeouts,                  SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6941   {"Ssl_sessions_reused",      (char*) &show_ssl_session_reused,                       SHOW_FUNC,              SHOW_SCOPE_ALL},
6942   {"Ssl_used_session_cache_entries",(char*) &show_ssl_ctx_sess_number,                 SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6943   {"Ssl_verify_depth",         (char*) &show_ssl_get_verify_depth,                     SHOW_FUNC,              SHOW_SCOPE_ALL},
6944   {"Ssl_verify_mode",          (char*) &show_ssl_get_verify_mode,                      SHOW_FUNC,              SHOW_SCOPE_ALL},
6945   {"Ssl_version",              (char*) &show_ssl_get_version,                          SHOW_FUNC,              SHOW_SCOPE_ALL},
6946   {"Ssl_server_not_before",    (char*) &show_ssl_get_server_not_before,                SHOW_FUNC,              SHOW_SCOPE_ALL},
6947   {"Ssl_server_not_after",     (char*) &show_ssl_get_server_not_after,                 SHOW_FUNC,              SHOW_SCOPE_ALL},
6948   {"Rsa_public_key",           (char*) &show_rsa_public_key,                           SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6949 #endif
6950 #endif /* HAVE_OPENSSL */
6951   {"Table_locks_immediate",    (char*) &locks_immediate,                               SHOW_LONG,              SHOW_SCOPE_GLOBAL},
6952   {"Table_locks_waited",       (char*) &locks_waited,                                  SHOW_LONG,              SHOW_SCOPE_GLOBAL},
6953   {"Table_open_cache_hits",    (char*) offsetof(STATUS_VAR, table_open_cache_hits),    SHOW_LONGLONG_STATUS,   SHOW_SCOPE_ALL},
6954   {"Table_open_cache_misses",  (char*) offsetof(STATUS_VAR, table_open_cache_misses),  SHOW_LONGLONG_STATUS,   SHOW_SCOPE_ALL},
6955   {"Table_open_cache_overflows",(char*) offsetof(STATUS_VAR, table_open_cache_overflows), SHOW_LONGLONG_STATUS,SHOW_SCOPE_ALL},
6956   {"Tc_log_max_pages_used",    (char*) &tc_log_max_pages_used,                         SHOW_LONG,              SHOW_SCOPE_GLOBAL},
6957   {"Tc_log_page_size",         (char*) &tc_log_page_size,                              SHOW_LONG_NOFLUSH,      SHOW_SCOPE_GLOBAL},
6958   {"Tc_log_page_waits",        (char*) &tc_log_page_waits,                             SHOW_LONG,              SHOW_SCOPE_GLOBAL},
6959 #ifndef EMBEDDED_LIBRARY
6960   {"Threads_cached",           (char*) &Per_thread_connection_handler::blocked_pthread_count, SHOW_LONG_NOFLUSH, SHOW_SCOPE_GLOBAL},
6961 #endif
6962   {"Threads_connected",        (char*) &Connection_handler_manager::connection_count,  SHOW_INT,               SHOW_SCOPE_GLOBAL},
6963   {"Threads_created",          (char*) &show_num_thread_created,                       SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6964   {"Threads_running",          (char*) &show_num_thread_running,                       SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6965   {"Uptime",                   (char*) &show_starttime,                                SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6966 #ifdef ENABLED_PROFILING
6967   {"Uptime_since_flush_status",(char*) &show_flushstatustime,                          SHOW_FUNC,              SHOW_SCOPE_GLOBAL},
6968 #endif
6969   {NullS, NullS, SHOW_LONG, SHOW_SCOPE_ALL}
6970 };
6971 
add_terminator(vector<my_option> * options)6972 void add_terminator(vector<my_option> *options)
6973 {
6974   my_option empty_element=
6975     {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0};
6976   options->push_back(empty_element);
6977 }
6978 
6979 #ifndef EMBEDDED_LIBRARY
print_version(void)6980 static void print_version(void)
6981 {
6982   set_server_version();
6983 
6984   printf("%s  Ver %s for %s on %s (%s)\n",my_progname,
6985    server_version,SYSTEM_TYPE,MACHINE_TYPE, MYSQL_COMPILATION_COMMENT);
6986 }
6987 
6988 /** Compares two options' names, treats - and _ the same */
operator <(const my_option & a,const my_option & b)6989 static bool operator<(const my_option &a, const my_option &b)
6990 {
6991   const char *sa= a.name;
6992   const char *sb= b.name;
6993   for (; *sa || *sb; sa++, sb++)
6994   {
6995     if (*sa < *sb)
6996     {
6997       if (*sa == '-' && *sb == '_')
6998         continue;
6999       else
7000         return true;
7001     }
7002     if (*sa > *sb)
7003     {
7004       if (*sa == '_' && *sb == '-')
7005         continue;
7006       else
7007         return false;
7008     }
7009   }
7010   assert(a.name == b.name);
7011   return false;
7012 }
7013 
print_help()7014 static void print_help()
7015 {
7016   MEM_ROOT mem_root;
7017   init_alloc_root(key_memory_help, &mem_root, 4096, 4096);
7018 
7019   all_options.pop_back();
7020   sys_var_add_options(&all_options, sys_var::PARSE_EARLY);
7021   for (my_option *opt= my_long_early_options;
7022        opt->name != NULL;
7023        opt++)
7024   {
7025     all_options.push_back(*opt);
7026   }
7027   add_plugin_options(&all_options, &mem_root);
7028   std::sort(all_options.begin(), all_options.end(), std::less<my_option>());
7029   add_terminator(&all_options);
7030 
7031   my_print_help(&all_options[0]);
7032   my_print_variables(&all_options[0]);
7033 
7034   free_root(&mem_root, MYF(0));
7035   vector<my_option>().swap(all_options);  // Deletes the vector contents.
7036 }
7037 
usage(void)7038 static void usage(void)
7039 {
7040   DBUG_ENTER("usage");
7041   if (!(default_charset_info= get_charset_by_csname(default_character_set_name,
7042                      MY_CS_PRIMARY,
7043                MYF(MY_WME))))
7044     exit(MYSQLD_ABORT_EXIT);
7045   if (!default_collation_name)
7046     default_collation_name= (char*) default_charset_info->name;
7047   print_version();
7048   puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000"));
7049   puts("Starts the MySQL database server.\n");
7050   printf("Usage: %s [OPTIONS]\n", my_progname);
7051   if (!opt_verbose)
7052     puts("\nFor more help options (several pages), use mysqld --verbose --help.");
7053   else
7054   {
7055 #ifdef _WIN32
7056   puts("NT and Win32 specific options:\n\
7057   --install                     Install the default service (NT).\n\
7058   --install-manual              Install the default service started manually (NT).\n\
7059   --install service_name        Install an optional service (NT).\n\
7060   --install-manual service_name Install an optional service started manually (NT).\n\
7061   --remove                      Remove the default service from the service list (NT).\n\
7062   --remove service_name         Remove the service_name from the service list (NT).\n\
7063   --enable-named-pipe           Only to be used for the default server (NT).\n\
7064   --standalone                  Dummy option to start as a standalone server (NT).\
7065 ");
7066   puts("");
7067 #endif
7068   print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
7069   puts("");
7070   set_ports();
7071 
7072   /* Print out all the options including plugin supplied options */
7073   print_help();
7074 
7075   if (! plugins_are_initialized)
7076   {
7077     puts("\n\
7078 Plugins have parameters that are not reflected in this list\n\
7079 because execution stopped before plugins were initialized.");
7080   }
7081 
7082   puts("\n\
7083 To see what values a running MySQL server is using, type\n\
7084 'mysqladmin variables' instead of 'mysqld --verbose --help'.");
7085   }
7086   DBUG_VOID_RETURN;
7087 }
7088 #endif /*!EMBEDDED_LIBRARY*/
7089 
7090 /**
7091   Initialize MySQL global variables to default values.
7092 
7093   @note
7094     The reason to set a lot of global variables to zero is to allow one to
7095     restart the embedded server with a clean environment
7096     It's also needed on some exotic platforms where global variables are
7097     not set to 0 when a program starts.
7098 
7099     We don't need to set variables refered to in my_long_options
7100     as these are initialized by my_getopt.
7101 */
7102 
mysql_init_variables(void)7103 static int mysql_init_variables(void)
7104 {
7105   /* Things reset to zero */
7106   opt_skip_slave_start= opt_reckless_slave = 0;
7107   mysql_home[0]= pidfile_name[0]= 0;
7108   myisam_test_invalid_symlink= test_if_data_home_dir;
7109   opt_general_log= opt_slow_log= false;
7110   opt_bin_log= 0;
7111   opt_disable_networking= opt_skip_show_db=0;
7112   opt_skip_name_resolve= 0;
7113   opt_ignore_builtin_innodb= 0;
7114   opt_general_logname= opt_update_logname= opt_binlog_index_name= opt_slow_logname= NULL;
7115   opt_tc_log_file= (char *)"tc.log";      // no hostname in tc_log file name !
7116   opt_secure_auth= 0;
7117   opt_myisam_log= 0;
7118   mqh_used= 0;
7119   kill_in_progress= 0;
7120   cleanup_done= 0;
7121   server_id_supplied= false;
7122   test_flags= select_errors= dropping_tables= ha_open_options=0;
7123   slave_open_temp_tables.atomic_set(0);
7124   opt_endinfo= using_udf_functions= 0;
7125   opt_using_transactions= 0;
7126   abort_loop= false;
7127   server_operational_state= SERVER_BOOTING;
7128   aborted_threads= 0;
7129   delayed_insert_threads= delayed_insert_writes= delayed_rows_in_use= 0;
7130   delayed_insert_errors= 0;
7131   specialflag= 0;
7132   binlog_cache_use=  binlog_cache_disk_use= 0;
7133   mysqld_user= mysqld_chroot= opt_init_file= opt_bin_logname = 0;
7134   prepared_stmt_count= 0;
7135   mysqld_unix_port= opt_mysql_tmpdir= my_bind_addr_str= NullS;
7136   memset(&mysql_tmpdir_list, 0, sizeof(mysql_tmpdir_list));
7137   memset(&global_status_var, 0, sizeof(global_status_var));
7138   opt_large_pages= 0;
7139   opt_super_large_pages= 0;
7140 #if defined(ENABLED_DEBUG_SYNC)
7141   opt_debug_sync_timeout= 0;
7142 #endif /* defined(ENABLED_DEBUG_SYNC) */
7143   key_map_full.set_all();
7144   server_uuid[0]= 0;
7145 
7146   /* Character sets */
7147   system_charset_info= &my_charset_utf8_general_ci;
7148   files_charset_info= &my_charset_utf8_general_ci;
7149   national_charset_info= &my_charset_utf8_general_ci;
7150   table_alias_charset= &my_charset_bin;
7151   character_set_filesystem= &my_charset_bin;
7152 
7153   opt_specialflag= 0;
7154   mysql_home_ptr= mysql_home;
7155   pidfile_name_ptr= pidfile_name;
7156   lc_messages_dir_ptr= lc_messages_dir;
7157   protocol_version= PROTOCOL_VERSION;
7158   what_to_log= ~ (1L << (uint) COM_TIME);
7159   refresh_version= 1L;  /* Increments on each reload */
7160   global_query_id= 1L;
7161   my_stpcpy(server_version, MYSQL_SERVER_VERSION);
7162   key_caches.empty();
7163   if (!(dflt_key_cache= get_or_create_key_cache(default_key_cache_base.str,
7164                                                 default_key_cache_base.length)))
7165   {
7166     sql_print_error("Cannot allocate the keycache");
7167     return 1;
7168   }
7169   /* set key_cache_hash.default_value = dflt_key_cache */
7170   multi_keycache_init();
7171 
7172   /* Set directory paths */
7173   mysql_real_data_home_len=
7174     strmake(mysql_real_data_home, get_relative_path(MYSQL_DATADIR),
7175             sizeof(mysql_real_data_home)-1) - mysql_real_data_home;
7176   /* Replication parameters */
7177   master_info_file= (char*) "master.info",
7178     relay_log_info_file= (char*) "relay-log.info";
7179   report_user= report_password = report_host= 0;  /* TO BE DELETED */
7180   opt_relay_logname= opt_relaylog_index_name= 0;
7181   log_bin_basename= NULL;
7182   log_bin_index= NULL;
7183 
7184   /* Handler variables */
7185   total_ha= 0;
7186   total_ha_2pc= 0;
7187   /* Variables in libraries */
7188   charsets_dir= 0;
7189   default_character_set_name= (char*) MYSQL_DEFAULT_CHARSET_NAME;
7190   default_collation_name= compiled_default_collation_name;
7191   character_set_filesystem_name= (char*) "binary";
7192   lc_messages= (char*) "en_US";
7193   lc_time_names_name= (char*) "en_US";
7194   opt_replication_optimize_for_static_plugin_config= 0;
7195   opt_replication_sender_observe_commit_only= 0;
7196 
7197   /* Variables that depends on compile options */
7198 #ifndef NDEBUG
7199   default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace",
7200            "d:t:i:o,/tmp/mysqld.trace");
7201 #endif
7202 #ifdef ENABLED_PROFILING
7203     have_profiling = SHOW_OPTION_YES;
7204 #else
7205     have_profiling = SHOW_OPTION_NO;
7206 #endif
7207 
7208 #ifdef HAVE_OPENSSL
7209   have_ssl=SHOW_OPTION_YES;
7210 #else
7211   have_ssl=SHOW_OPTION_NO;
7212 #endif
7213 
7214   have_symlink= SHOW_OPTION_YES;
7215 
7216 #ifdef HAVE_DLOPEN
7217   have_dlopen=SHOW_OPTION_YES;
7218 #else
7219   have_dlopen=SHOW_OPTION_NO;
7220 #endif
7221 
7222   have_query_cache=SHOW_OPTION_YES;
7223 
7224   have_geometry=SHOW_OPTION_YES;
7225 
7226   have_rtree_keys=SHOW_OPTION_YES;
7227 
7228 #ifdef HAVE_CRYPT
7229   have_crypt=SHOW_OPTION_YES;
7230 #else
7231   have_crypt=SHOW_OPTION_NO;
7232 #endif
7233 #ifdef HAVE_COMPRESS
7234   have_compress= SHOW_OPTION_YES;
7235 #else
7236   have_compress= SHOW_OPTION_NO;
7237 #endif
7238 #ifdef HAVE_OPENSSL
7239   des_key_file = 0;
7240 #ifndef EMBEDDED_LIBRARY
7241   ssl_acceptor_fd= 0;
7242 #endif /* ! EMBEDDED_LIBRARY */
7243 #endif /* HAVE_OPENSSL */
7244 #if defined (_WIN32) && !defined (EMBEDDED_LIBRARY)
7245   shared_memory_base_name= default_shared_memory_base_name;
7246 #endif
7247 
7248 #if defined(_WIN32)
7249   /* Allow Win32 users to move MySQL anywhere */
7250   {
7251     char prg_dev[LIBLEN];
7252     char executing_path_name[LIBLEN];
7253     if (!test_if_hard_path(my_progname))
7254     {
7255       // we don't want to use GetModuleFileName inside of my_path since
7256       // my_path is a generic path dereferencing function and here we care
7257       // only about the executing binary.
7258       GetModuleFileName(NULL, executing_path_name, sizeof(executing_path_name));
7259       my_path(prg_dev, executing_path_name, NULL);
7260     }
7261     else
7262       my_path(prg_dev, my_progname, "mysql/bin");
7263     strcat(prg_dev,"/../");     // Remove 'bin' to get base dir
7264     cleanup_dirname(mysql_home,prg_dev);
7265   }
7266 #else
7267   const char *tmpenv;
7268   if (!(tmpenv = getenv("MY_BASEDIR_VERSION")))
7269     tmpenv = DEFAULT_MYSQL_HOME;
7270   (void) strmake(mysql_home, tmpenv, sizeof(mysql_home)-1);
7271 #endif
7272   return 0;
7273 }
7274 
7275 my_bool
mysqld_get_one_option(int optid,const struct my_option * opt MY_ATTRIBUTE ((unused)),char * argument)7276 mysqld_get_one_option(int optid,
7277                       const struct my_option *opt MY_ATTRIBUTE((unused)),
7278                       char *argument)
7279 {
7280   switch(optid) {
7281   case '#':
7282 #ifndef NDEBUG
7283     DBUG_SET_INITIAL(argument ? argument : default_dbug_option);
7284 #endif
7285     opt_endinfo=1;        /* unireg: memory allocation */
7286     break;
7287   case 'a':
7288     global_system_variables.sql_mode= MODE_ANSI;
7289     global_system_variables.tx_isolation=
7290            global_system_variables.transaction_isolation= ISO_SERIALIZABLE;
7291     break;
7292   case 'b':
7293     strmake(mysql_home,argument,sizeof(mysql_home)-1);
7294     mysql_home_ptr= mysql_home;
7295     break;
7296   case 'C':
7297     if (default_collation_name == compiled_default_collation_name)
7298       default_collation_name= 0;
7299     break;
7300   case 'h':
7301     strmake(mysql_real_data_home,argument, sizeof(mysql_real_data_home)-1);
7302     /* Correct pointer set by my_getopt (for embedded library) */
7303     mysql_real_data_home_ptr= mysql_real_data_home;
7304     break;
7305   case 'u':
7306     if (!mysqld_user || !strcmp(mysqld_user, argument))
7307       mysqld_user= argument;
7308     else
7309       sql_print_warning("Ignoring user change to '%s' because the user was set to '%s' earlier on the command line\n", argument, mysqld_user);
7310     break;
7311   case 'L':
7312     push_deprecated_warn(NULL, "--language/-l", "'--lc-messages-dir'");
7313     /* Note:  fall-through */
7314   case OPT_LC_MESSAGES_DIRECTORY:
7315     strmake(lc_messages_dir, argument, sizeof(lc_messages_dir)-1);
7316     lc_messages_dir_ptr= lc_messages_dir;
7317     break;
7318   case OPT_BINLOG_FORMAT:
7319     binlog_format_used= true;
7320     break;
7321   case OPT_BINLOG_MAX_FLUSH_QUEUE_TIME:
7322     push_deprecated_warn_no_replacement(NULL, "--binlog_max_flush_queue_time");
7323     break;
7324 #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
7325   case OPT_SSL_KEY:
7326   case OPT_SSL_CERT:
7327   case OPT_SSL_CA:
7328   case OPT_SSL_CAPATH:
7329   case OPT_SSL_CIPHER:
7330   case OPT_SSL_CRL:
7331   case OPT_SSL_CRLPATH:
7332   case OPT_TLS_VERSION:
7333     /*
7334       Enable use of SSL if we are using any ssl option.
7335       One can disable SSL later by using --skip-ssl or --ssl=0.
7336     */
7337     opt_use_ssl= true;
7338     break;
7339 #endif /* HAVE_OPENSSL */
7340 #ifndef EMBEDDED_LIBRARY
7341   case 'V':
7342     print_version();
7343     exit(MYSQLD_SUCCESS_EXIT);
7344 #endif /*EMBEDDED_LIBRARY*/
7345   case 'W':
7346     push_deprecated_warn(NULL, "--log_warnings/-W", "'--log_error_verbosity'");
7347     if (!argument)
7348       log_error_verbosity++;
7349     else if (argument == disabled_my_option)
7350      log_error_verbosity= 1L;
7351     else
7352       log_error_verbosity= 1 + atoi(argument);
7353     log_error_verbosity= min(3UL, log_error_verbosity);
7354     break;
7355   case 'T':
7356     test_flags= argument ? (uint) atoi(argument) : 0;
7357     opt_endinfo=1;
7358     break;
7359   case (int) OPT_ISAM_LOG:
7360     opt_myisam_log=1;
7361     break;
7362   case (int) OPT_BIN_LOG:
7363     opt_bin_log= MY_TEST(argument != disabled_my_option);
7364     break;
7365 #ifdef HAVE_REPLICATION
7366   case (int)OPT_REPLICATE_IGNORE_DB:
7367   {
7368     rpl_filter->add_ignore_db(argument);
7369     break;
7370   }
7371   case (int)OPT_REPLICATE_DO_DB:
7372   {
7373     rpl_filter->add_do_db(argument);
7374     break;
7375   }
7376   case (int)OPT_REPLICATE_REWRITE_DB:
7377   {
7378     char* key = argument,*p, *val;
7379 
7380     if (!(p= strstr(argument, "->")))
7381     {
7382       sql_print_error("Bad syntax in replicate-rewrite-db - missing '->'!\n");
7383       return 1;
7384     }
7385     val= p + 2;
7386     while(p > argument && my_isspace(mysqld_charset, p[-1]))
7387       p--;
7388     *p= 0;
7389     if (!*key)
7390     {
7391       sql_print_error("Bad syntax in replicate-rewrite-db - empty FROM db!\n");
7392       return 1;
7393     }
7394     while (*val && my_isspace(mysqld_charset, *val))
7395       val++;
7396     if (!*val)
7397     {
7398       sql_print_error("Bad syntax in replicate-rewrite-db - empty TO db!\n");
7399       return 1;
7400     }
7401 
7402     rpl_filter->add_db_rewrite(key, val);
7403     break;
7404   }
7405 
7406   case (int)OPT_BINLOG_IGNORE_DB:
7407   {
7408     binlog_filter->add_ignore_db(argument);
7409     break;
7410   }
7411   case (int)OPT_BINLOG_DO_DB:
7412   {
7413     binlog_filter->add_do_db(argument);
7414     break;
7415   }
7416   case (int)OPT_REPLICATE_DO_TABLE:
7417   {
7418     if (rpl_filter->add_do_table_array(argument))
7419     {
7420       sql_print_error("Could not add do table rule '%s'!\n", argument);
7421       return 1;
7422     }
7423     break;
7424   }
7425   case (int)OPT_REPLICATE_WILD_DO_TABLE:
7426   {
7427     if (rpl_filter->add_wild_do_table(argument))
7428     {
7429       sql_print_error("Could not add do table rule '%s'!\n", argument);
7430       return 1;
7431     }
7432     break;
7433   }
7434   case (int)OPT_REPLICATE_WILD_IGNORE_TABLE:
7435   {
7436     if (rpl_filter->add_wild_ignore_table(argument))
7437     {
7438       sql_print_error("Could not add ignore table rule '%s'!\n", argument);
7439       return 1;
7440     }
7441     break;
7442   }
7443   case (int)OPT_REPLICATE_IGNORE_TABLE:
7444   {
7445     if (rpl_filter->add_ignore_table_array(argument))
7446     {
7447       sql_print_error("Could not add ignore table rule '%s'!\n", argument);
7448       return 1;
7449     }
7450     break;
7451   }
7452 #endif /* HAVE_REPLICATION */
7453   case (int) OPT_MASTER_RETRY_COUNT:
7454     push_deprecated_warn(NULL, "--master-retry-count", "'CHANGE MASTER TO master_retry_count = <num>'");
7455     break;
7456   case (int) OPT_SKIP_NEW:
7457     opt_specialflag|= SPECIAL_NO_NEW_FUNC;
7458     delay_key_write_options= DELAY_KEY_WRITE_NONE;
7459     myisam_concurrent_insert=0;
7460     myisam_recover_options= HA_RECOVER_OFF;
7461     sp_automatic_privileges=0;
7462     my_enable_symlinks= 0;
7463     ha_open_options&= ~(HA_OPEN_ABORT_IF_CRASHED | HA_OPEN_DELAY_KEY_WRITE);
7464     query_cache_size=0;
7465     break;
7466   case (int) OPT_SKIP_HOST_CACHE:
7467     opt_specialflag|= SPECIAL_NO_HOST_CACHE;
7468     break;
7469   case (int) OPT_SKIP_RESOLVE:
7470     opt_skip_name_resolve= 1;
7471     opt_specialflag|=SPECIAL_NO_RESOLVE;
7472     break;
7473   case (int) OPT_WANT_CORE:
7474     test_flags |= TEST_CORE_ON_SIGNAL;
7475     break;
7476   case (int) OPT_SKIP_STACK_TRACE:
7477     test_flags|=TEST_NO_STACKTRACE;
7478     break;
7479   case OPT_BOOTSTRAP:
7480     opt_bootstrap= 1;
7481     break;
7482   case OPT_SERVER_ID:
7483     /*
7484      Consider that one received a Server Id when 2 conditions are present:
7485      1) The argument is on the list
7486      2) There is a value present
7487     */
7488     server_id_supplied= (*argument != 0);
7489 
7490     break;
7491   case OPT_LOWER_CASE_TABLE_NAMES:
7492     lower_case_table_names_used= 1;
7493     break;
7494 #if defined(ENABLED_DEBUG_SYNC)
7495   case OPT_DEBUG_SYNC_TIMEOUT:
7496     /*
7497       Debug Sync Facility. See debug_sync.cc.
7498       Default timeout for WAIT_FOR action.
7499       Default value is zero (facility disabled).
7500       If option is given without an argument, supply a non-zero value.
7501     */
7502     if (!argument)
7503     {
7504       /* purecov: begin tested */
7505       opt_debug_sync_timeout= DEBUG_SYNC_DEFAULT_WAIT_TIMEOUT;
7506       /* purecov: end */
7507     }
7508     break;
7509 #endif /* defined(ENABLED_DEBUG_SYNC) */
7510   case OPT_LOG_ERROR:
7511     /*
7512       "No --log-error" == "write errors to stderr",
7513       "--log-error without argument" == "write errors to a file".
7514     */
7515     if (argument == NULL) /* no argument */
7516       log_error_dest= "";
7517     break;
7518 
7519   case OPT_IGNORE_DB_DIRECTORY:
7520     if (*argument == 0)
7521       ignore_db_dirs_reset();
7522     else
7523     {
7524       if (push_ignored_db_dir(argument))
7525       {
7526         sql_print_error("Can't start server: "
7527                         "cannot process --ignore-db-dir=%.*s",
7528                         FN_REFLEN, argument);
7529         return 1;
7530       }
7531     }
7532     break;
7533 
7534   case OPT_EARLY_PLUGIN_LOAD:
7535     free_list(opt_early_plugin_load_list_ptr);
7536     opt_early_plugin_load_list_ptr->push_back(new i_string(argument));
7537     break;
7538   case OPT_PLUGIN_LOAD:
7539     free_list(opt_plugin_load_list_ptr);
7540     /* fall through */
7541   case OPT_PLUGIN_LOAD_ADD:
7542     opt_plugin_load_list_ptr->push_back(new i_string(argument));
7543     break;
7544   case OPT_SECURE_AUTH:
7545     push_deprecated_warn_no_replacement(NULL, "--secure-auth");
7546     if (!opt_secure_auth)
7547     {
7548       sql_print_error("Unsupported value 0 for secure-auth");
7549       return 1;
7550     }
7551     break;
7552   case OPT_PFS_INSTRUMENT:
7553     {
7554 #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
7555 #ifndef EMBEDDED_LIBRARY
7556 
7557       /*
7558         Parse instrument name and value from argument string. Handle leading
7559         and trailing spaces. Also handle single quotes.
7560 
7561         Acceptable:
7562           performance_schema_instrument = ' foo/%/bar/  =  ON  '
7563           performance_schema_instrument = '%=OFF'
7564         Not acceptable:
7565           performance_schema_instrument = '' foo/%/bar = ON ''
7566           performance_schema_instrument = '%='OFF''
7567       */
7568       char *name= argument,*p= NULL, *val= NULL;
7569       my_bool quote= false; /* true if quote detected */
7570       my_bool error= true;  /* false if no errors detected */
7571       const int PFS_BUFFER_SIZE= 128;
7572       char orig_argument[PFS_BUFFER_SIZE+1];
7573       orig_argument[0]= 0;
7574 
7575       if (!argument)
7576         goto pfs_error;
7577 
7578       /* Save original argument string for error reporting */
7579       strncpy(orig_argument, argument, PFS_BUFFER_SIZE);
7580 
7581       /* Split instrument name and value at the equal sign */
7582       if (!(p= strchr(argument, '=')))
7583         goto pfs_error;
7584 
7585       /* Get option value */
7586       val= p + 1;
7587       if (!*val)
7588         goto pfs_error;
7589 
7590       /* Trim leading spaces and quote from the instrument name */
7591       while (*name && (my_isspace(mysqld_charset, *name) || (*name == '\'')))
7592       {
7593         /* One quote allowed */
7594         if (*name == '\'')
7595         {
7596           if (!quote)
7597             quote= true;
7598           else
7599             goto pfs_error;
7600         }
7601         name++;
7602       }
7603 
7604       /* Trim trailing spaces from instrument name */
7605       while ((p > name) && my_isspace(mysqld_charset, p[-1]))
7606         p--;
7607       *p= 0;
7608 
7609       /* Remove trailing slash from instrument name */
7610       if (p > name && (p[-1] == '/'))
7611         p[-1]= 0;
7612 
7613       if (!*name)
7614         goto pfs_error;
7615 
7616       /* Trim leading spaces from option value */
7617       while (*val && my_isspace(mysqld_charset, *val))
7618         val++;
7619 
7620       /* Trim trailing spaces and matching quote from value */
7621       p= val + strlen(val);
7622       while (p > val && (my_isspace(mysqld_charset, p[-1]) || p[-1] == '\''))
7623       {
7624         /* One matching quote allowed */
7625         if (p[-1] == '\'')
7626         {
7627           if (quote)
7628             quote= false;
7629           else
7630             goto pfs_error;
7631         }
7632         p--;
7633       }
7634 
7635       *p= 0;
7636 
7637       if (!*val)
7638         goto pfs_error;
7639 
7640       /* Add instrument name and value to array of configuration options */
7641       if (add_pfs_instr_to_array(name, val))
7642         goto pfs_error;
7643 
7644       error= false;
7645 
7646 pfs_error:
7647       if (error)
7648       {
7649         sql_print_warning("Invalid instrument name or value for "
7650                           "performance_schema_instrument '%s'",
7651                           orig_argument);
7652         return 0;
7653       }
7654 #endif /* EMBEDDED_LIBRARY */
7655 #endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
7656       break;
7657     }
7658   case OPT_THREAD_CACHE_SIZE:
7659     thread_cache_size_specified= true;
7660     break;
7661   case OPT_HOST_CACHE_SIZE:
7662     host_cache_size_specified= true;
7663     break;
7664   case OPT_TABLE_DEFINITION_CACHE:
7665     table_definition_cache_specified= true;
7666     break;
7667   case OPT_MDL_CACHE_SIZE:
7668     push_deprecated_warn_no_replacement(NULL, "--metadata_locks_cache_size");
7669     break;
7670   case OPT_MDL_HASH_INSTANCES:
7671     push_deprecated_warn_no_replacement(NULL,
7672                                         "--metadata_locks_hash_instances");
7673     break;
7674   case OPT_SKIP_INNODB:
7675     sql_print_warning("The use of InnoDB is mandatory since MySQL 5.7. "
7676                       "The former options like '--innodb=0/1/OFF/ON' or "
7677                       "'--skip-innodb' are ignored.");
7678     break;
7679   case OPT_AVOID_TEMPORAL_UPGRADE:
7680     push_deprecated_warn_no_replacement(NULL, "avoid_temporal_upgrade");
7681     break;
7682   case OPT_SHOW_OLD_TEMPORALS:
7683     push_deprecated_warn_no_replacement(NULL, "show_old_temporals");
7684     break;
7685   case OPT_KEYRING_MIGRATION_PASSWORD:
7686     if (argument)
7687     {
7688       char *start= argument;
7689       opt_keyring_migration_password= my_strdup(PSI_NOT_INSTRUMENTED,
7690         argument, MYF(MY_FAE));
7691       while (*argument) *argument++= 'x';
7692       if (*start)
7693        start[1]= 0;
7694     }
7695     else
7696       opt_keyring_migration_password= get_tty_password(NullS);
7697     migrate_connect_options= 1;
7698     break;
7699   case OPT_KEYRING_MIGRATION_USER:
7700   case OPT_KEYRING_MIGRATION_HOST:
7701   case OPT_KEYRING_MIGRATION_SOCKET:
7702   case OPT_KEYRING_MIGRATION_PORT:
7703     migrate_connect_options= 1;
7704     break;
7705   case OPT_ENFORCE_GTID_CONSISTENCY:
7706   {
7707     const char *wrong_value=
7708       fixup_enforce_gtid_consistency_command_line(argument);
7709     if (wrong_value != NULL)
7710       sql_print_warning("option 'enforce-gtid-consistency': value '%s' "
7711                         "was not recognized. Setting enforce-gtid-consistency "
7712                         "to OFF.", wrong_value);
7713     break;
7714   }
7715   case OPT_TRANSACTION_READ_ONLY:
7716     global_system_variables.transaction_read_only=
7717                             global_system_variables.tx_read_only;
7718     break;
7719   case OPT_TRANSACTION_ISOLATION:
7720     global_system_variables.transaction_isolation=
7721                             global_system_variables.tx_isolation;
7722     break;
7723   case OPT_NAMED_PIPE_FULL_ACCESS_GROUP:
7724 #if defined(_WIN32)  && !defined(EMBEDDED_LIBRARY)
7725     if (!is_valid_named_pipe_full_access_group(argument))
7726     {
7727       sql_print_error("Invalid value for named_pipe_full_access_group.");
7728       return 1;
7729     }
7730 #endif /* _WIN32 && !EMBEDDED_LIBRARY */
7731     break;
7732   }
7733   return 0;
7734 }
7735 
7736 
7737 /** Handle arguments for multiple key caches. */
7738 
7739 C_MODE_START
7740 
7741 static void*
mysql_getopt_value(const char * keyname,size_t key_length,const struct my_option * option,int * error)7742 mysql_getopt_value(const char *keyname, size_t key_length,
7743        const struct my_option *option, int *error)
7744 {
7745   if (error)
7746     *error= 0;
7747   switch (option->id) {
7748   case OPT_KEY_BUFFER_SIZE:
7749   case OPT_KEY_CACHE_BLOCK_SIZE:
7750   case OPT_KEY_CACHE_DIVISION_LIMIT:
7751   case OPT_KEY_CACHE_AGE_THRESHOLD:
7752   {
7753     KEY_CACHE *key_cache;
7754     if (!(key_cache= get_or_create_key_cache(keyname, key_length)))
7755     {
7756       if (error)
7757         *error= EXIT_OUT_OF_MEMORY;
7758       return 0;
7759     }
7760     switch (option->id) {
7761     case OPT_KEY_BUFFER_SIZE:
7762       return &key_cache->param_buff_size;
7763     case OPT_KEY_CACHE_BLOCK_SIZE:
7764       return &key_cache->param_block_size;
7765     case OPT_KEY_CACHE_DIVISION_LIMIT:
7766       return &key_cache->param_division_limit;
7767     case OPT_KEY_CACHE_AGE_THRESHOLD:
7768       return &key_cache->param_age_threshold;
7769     }
7770   }
7771   }
7772   return option->value;
7773 }
7774 
7775 C_MODE_END
7776 
7777 /**
7778   Ensure all the deprecared options with 1 possible value are
7779   within acceptable range.
7780 
7781   @retval true error in the values set
7782   @retval false all checked
7783 */
check_ghost_options()7784 bool check_ghost_options()
7785 {
7786   if (global_system_variables.old_passwords == 1)
7787   {
7788     sql_print_error("Invalid old_passwords mode: 1. Valid values are 2 and 0\n");
7789     return true;
7790   }
7791   if (!opt_secure_auth)
7792   {
7793     sql_print_error("Invalid secure_auth mode: 0. Valid value is 1\n");
7794     return true;
7795   }
7796 
7797   return false;
7798 }
7799 
7800 
7801 /**
7802   Get server options from the command line,
7803   and perform related server initializations.
7804   @param [in, out] argc_ptr       command line options (count)
7805   @param [in, out] argv_ptr       command line options (values)
7806   @return 0 on success
7807 
7808   @todo
7809   - FIXME add EXIT_TOO_MANY_ARGUMENTS to "mysys_err.h" and return that code?
7810 */
get_options(int * argc_ptr,char *** argv_ptr)7811 static int get_options(int *argc_ptr, char ***argv_ptr)
7812 {
7813   int ho_error;
7814 
7815   my_getopt_register_get_addr(mysql_getopt_value);
7816 
7817   /* prepare all_options array */
7818   all_options.reserve(array_elements(my_long_options));
7819   for (my_option *opt= my_long_options;
7820        opt < my_long_options + array_elements(my_long_options) - 1;
7821        opt++)
7822   {
7823     all_options.push_back(*opt);
7824   }
7825   sys_var_add_options(&all_options, sys_var::PARSE_NORMAL);
7826   add_terminator(&all_options);
7827 
7828   if (opt_help || opt_bootstrap)
7829   {
7830     /*
7831       Show errors during --help, but gag everything else so the info the
7832       user actually wants isn't lost in the spam.  (For --help --verbose,
7833       we need to set up far enough to be able to print variables provided
7834       by plugins, so a good number of warnings/notes might get printed.)
7835       Likewise for --bootstrap.
7836     */
7837     struct my_option *opt= &all_options[0];
7838     for (; opt->name; opt++)
7839       if (!strcmp("log_error_verbosity", opt->name))
7840         opt->def_value= opt_initialize ? 2 : 1;
7841   }
7842 
7843   /* Skip unknown options so that they may be processed later by plugins */
7844   my_getopt_skip_unknown= TRUE;
7845 
7846   if ((ho_error= handle_options(argc_ptr, argv_ptr, &all_options[0],
7847                                 mysqld_get_one_option)))
7848     return ho_error;
7849 
7850   if (!opt_help)
7851     vector<my_option>().swap(all_options);  // Deletes the vector contents.
7852 
7853   /* Add back the program name handle_options removes */
7854   (*argc_ptr)++;
7855   (*argv_ptr)--;
7856 
7857   /*
7858     Options have been parsed. Now some of them need additional special
7859     handling, like custom value checking, checking of incompatibilites
7860     between options, setting of multiple variables, etc.
7861     Do them here.
7862   */
7863 
7864   if (!opt_help && opt_verbose)
7865     sql_print_error("--verbose is for use with --help; "
7866                     "did you mean --log-error-verbosity?");
7867 
7868   if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes ||
7869        opt_log_slow_slave_statements) &&
7870       !opt_slow_log)
7871     sql_print_warning("options --log-slow-admin-statements, "
7872                       "--log-queries-not-using-indexes and "
7873                       "--log-slow-slave-statements have no effect if "
7874                       "--slow-query-log is not set");
7875   if (global_system_variables.net_buffer_length >
7876       global_system_variables.max_allowed_packet)
7877   {
7878     sql_print_warning("net_buffer_length (%lu) is set to be larger "
7879                       "than max_allowed_packet (%lu). Please rectify.",
7880                       global_system_variables.net_buffer_length,
7881                       global_system_variables.max_allowed_packet);
7882   }
7883 
7884   /*
7885     TIMESTAMP columns get implicit DEFAULT values when
7886     --explicit_defaults_for_timestamp is not set.
7887     This behavior is deprecated now.
7888   */
7889   if (!opt_help && !global_system_variables.explicit_defaults_for_timestamp)
7890     sql_print_warning("TIMESTAMP with implicit DEFAULT value is deprecated. "
7891                       "Please use --explicit_defaults_for_timestamp server "
7892                       "option (see documentation for more details).");
7893 
7894   opt_init_connect.length=strlen(opt_init_connect.str);
7895   opt_init_slave.length=strlen(opt_init_slave.str);
7896 
7897   if (global_system_variables.low_priority_updates)
7898     thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY;
7899 
7900   if (ft_boolean_check_syntax_string((uchar*) ft_boolean_syntax))
7901   {
7902     sql_print_error("Invalid ft-boolean-syntax string: %s\n",
7903                     ft_boolean_syntax);
7904     return 1;
7905   }
7906 
7907   if (opt_disable_networking)
7908     mysqld_port= 0;
7909 
7910   if (opt_skip_show_db)
7911     opt_specialflag|= SPECIAL_SKIP_SHOW_DB;
7912 
7913   if (check_ghost_options())
7914     return 1;
7915 
7916   if (myisam_flush)
7917     flush_time= 0;
7918 
7919 #ifdef HAVE_REPLICATION
7920   if (opt_slave_skip_errors)
7921     add_slave_skip_errors(opt_slave_skip_errors);
7922 #endif
7923 
7924   if (global_system_variables.max_join_size == HA_POS_ERROR)
7925     global_system_variables.option_bits|= OPTION_BIG_SELECTS;
7926   else
7927     global_system_variables.option_bits&= ~OPTION_BIG_SELECTS;
7928 
7929   // Synchronize @@global.autocommit on --autocommit
7930   const ulonglong turn_bit_on= opt_autocommit ?
7931     OPTION_AUTOCOMMIT : OPTION_NOT_AUTOCOMMIT;
7932   global_system_variables.option_bits=
7933     (global_system_variables.option_bits &
7934      ~(OPTION_NOT_AUTOCOMMIT | OPTION_AUTOCOMMIT)) | turn_bit_on;
7935 
7936   global_system_variables.sql_mode=
7937     expand_sql_mode(global_system_variables.sql_mode, NULL);
7938 
7939   if (!(global_system_variables.sql_mode & MODE_NO_AUTO_CREATE_USER))
7940   {
7941     sql_print_warning("'NO_AUTO_CREATE_USER' sql mode was not set.");
7942   }
7943 
7944   if (!my_enable_symlinks)
7945     have_symlink= SHOW_OPTION_DISABLED;
7946 
7947   if (opt_debugging)
7948   {
7949     /* Allow break with SIGINT, no core or stack trace */
7950     test_flags|= TEST_SIGINT | TEST_NO_STACKTRACE;
7951     test_flags&= ~TEST_CORE_ON_SIGNAL;
7952   }
7953   /* Set global MyISAM variables from delay_key_write_options */
7954   fix_delay_key_write(0, 0, OPT_GLOBAL);
7955 
7956 #ifndef EMBEDDED_LIBRARY
7957 #ifndef _WIN32
7958   if (mysqld_chroot)
7959     set_root(mysqld_chroot);
7960 #endif
7961 #else
7962   max_allowed_packet= global_system_variables.max_allowed_packet;
7963   net_buffer_length= global_system_variables.net_buffer_length;
7964 #endif
7965   if (fix_paths())
7966     return 1;
7967 
7968   /*
7969     Set some global variables from the global_system_variables
7970     In most cases the global variables will not be used
7971   */
7972   my_disable_locking= myisam_single_user= MY_TEST(opt_external_locking == 0);
7973   my_default_record_cache_size=global_system_variables.read_buff_size;
7974 
7975   global_system_variables.long_query_time= (ulonglong)
7976     (global_system_variables.long_query_time_double * 1e6);
7977 
7978   if (opt_short_log_format)
7979     opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT;
7980 
7981   if (init_global_datetime_format(MYSQL_TIMESTAMP_DATE,
7982                                   &global_date_format) ||
7983       init_global_datetime_format(MYSQL_TIMESTAMP_TIME,
7984                                   &global_time_format) ||
7985       init_global_datetime_format(MYSQL_TIMESTAMP_DATETIME,
7986                                   &global_datetime_format))
7987     return 1;
7988 
7989 #ifndef EMBEDDED_LIBRARY
7990   if (Connection_handler_manager::init())
7991   {
7992     sql_print_error("Could not allocate memory for connection handling");
7993     return 1;
7994   }
7995 #endif
7996   if (Global_THD_manager::create_instance())
7997   {
7998     sql_print_error("Could not allocate memory for thread handling");
7999     return 1;
8000   }
8001 
8002   /* If --super-read-only was specified, set read_only to 1 */
8003   read_only= super_read_only ? super_read_only : read_only;
8004   opt_readonly= read_only;
8005 
8006   return 0;
8007 }
8008 
8009 
8010 /*
8011   Create version name for running mysqld version
8012   We automaticly add suffixes -debug, -embedded, -log, -valgrind and -asan
8013   to the version name to make the version more descriptive.
8014   (MYSQL_SERVER_SUFFIX is set by the compilation environment)
8015 */
8016 
set_server_version(void)8017 static void set_server_version(void)
8018 {
8019   char *end= strxmov(server_version, MYSQL_SERVER_VERSION,
8020                      MYSQL_SERVER_SUFFIX_STR, NullS);
8021 #ifdef EMBEDDED_LIBRARY
8022   end= my_stpcpy(end, "-embedded");
8023 #endif
8024 #ifndef NDEBUG
8025   if (!strstr(MYSQL_SERVER_SUFFIX_STR, "-debug"))
8026     end= my_stpcpy(end, "-debug");
8027 #endif
8028   if (opt_general_log || opt_slow_log || opt_bin_log)
8029     end= my_stpcpy(end, "-log");          // This may slow down system
8030 #ifdef HAVE_VALGRIND
8031   if (SERVER_VERSION_LENGTH - (end - server_version) >
8032       static_cast<int>(sizeof("-valgrind")))
8033     end= my_stpcpy(end, "-valgrind");
8034 #endif
8035 #ifdef HAVE_ASAN
8036   if (SERVER_VERSION_LENGTH - (end - server_version) >
8037       static_cast<int>(sizeof("-asan")))
8038     end= my_stpcpy(end, "-asan");
8039 #endif
8040 }
8041 
8042 
get_relative_path(const char * path)8043 static char *get_relative_path(const char *path)
8044 {
8045   if (test_if_hard_path(path) &&
8046       is_prefix(path,DEFAULT_MYSQL_HOME) &&
8047       strcmp(DEFAULT_MYSQL_HOME,FN_ROOTDIR))
8048   {
8049     path+= strlen(DEFAULT_MYSQL_HOME);
8050     while (is_directory_separator(*path))
8051       path++;
8052   }
8053   return (char*) path;
8054 }
8055 
8056 
8057 /**
8058   Fix filename and replace extension where 'dir' is relative to
8059   mysql_real_data_home.
8060   @return
8061     1 if len(path) > FN_REFLEN
8062 */
8063 
8064 bool
fn_format_relative_to_data_home(char * to,const char * name,const char * dir,const char * extension)8065 fn_format_relative_to_data_home(char * to, const char *name,
8066         const char *dir, const char *extension)
8067 {
8068   char tmp_path[FN_REFLEN];
8069   if (!test_if_hard_path(dir))
8070   {
8071     strxnmov(tmp_path,sizeof(tmp_path)-1, mysql_real_data_home,
8072        dir, NullS);
8073     dir=tmp_path;
8074   }
8075   return !fn_format(to, name, dir, extension,
8076         MY_APPEND_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH);
8077 }
8078 
8079 
8080 /**
8081   Test a file path to determine if the path is compatible with the secure file
8082   path restriction.
8083 
8084   @param path null terminated character string
8085 
8086   @return
8087     @retval TRUE The path is secure
8088     @retval FALSE The path isn't secure
8089 */
8090 
is_secure_file_path(char * path)8091 bool is_secure_file_path(char *path)
8092 {
8093   char buff1[FN_REFLEN], buff2[FN_REFLEN];
8094   size_t opt_secure_file_priv_len;
8095   /*
8096     All paths are secure if opt_secure_file_priv is 0
8097   */
8098   if (!opt_secure_file_priv[0])
8099     return TRUE;
8100 
8101   opt_secure_file_priv_len= strlen(opt_secure_file_priv);
8102 
8103   if (strlen(path) >= FN_REFLEN)
8104     return FALSE;
8105 
8106   if (!my_strcasecmp(system_charset_info, opt_secure_file_priv, "NULL"))
8107     return FALSE;
8108 
8109   if (my_realpath(buff1, path, 0))
8110   {
8111     /*
8112       The supplied file path might have been a file and not a directory.
8113     */
8114     int length= (int)dirname_length(path);
8115     if (length >= FN_REFLEN)
8116       return FALSE;
8117     memcpy(buff2, path, length);
8118     buff2[length]= '\0';
8119     if (length == 0 || my_realpath(buff1, buff2, 0))
8120       return FALSE;
8121   }
8122   convert_dirname(buff2, buff1, NullS);
8123   if (!lower_case_file_system)
8124   {
8125     if (strncmp(opt_secure_file_priv, buff2, opt_secure_file_priv_len))
8126       return FALSE;
8127   }
8128   else
8129   {
8130     if (files_charset_info->coll->strnncoll(files_charset_info,
8131                                             (uchar *) buff2, strlen(buff2),
8132                                             (uchar *) opt_secure_file_priv,
8133                                             opt_secure_file_priv_len,
8134                                             TRUE))
8135       return FALSE;
8136   }
8137   return TRUE;
8138 }
8139 
8140 
8141 /**
8142   check_secure_file_priv_path : Checks path specified through
8143   --secure-file-priv and raises warning in following cases:
8144   1. If path is empty string or NULL and mysqld is not running
8145      with --bootstrap mode.
8146   2. If path can access data directory
8147   3. If path points to a directory which is accessible by
8148      all OS users (non-Windows build only)
8149 
8150   It throws error in following cases:
8151 
8152   1. If path normalization fails
8153   2. If it can not get stats of the directory
8154 
8155   @params NONE
8156 
8157   Assumptions :
8158   1. Data directory path has been normalized
8159   2. opt_secure_file_priv has been normalized unless it is set
8160      to "NULL".
8161 
8162   @returns Status of validation
8163     @retval true : Validation is successful with/without warnings
8164     @retval false : Validation failed. Error is raised.
8165 */
8166 
check_secure_file_priv_path()8167 bool check_secure_file_priv_path()
8168 {
8169   char datadir_buffer[FN_REFLEN+1]={0};
8170   char plugindir_buffer[FN_REFLEN+1]={0};
8171   char whichdir[20]= {0};
8172   size_t opt_plugindir_len= 0;
8173   size_t opt_datadir_len= 0;
8174   size_t opt_secure_file_priv_len= 0;
8175   bool warn= false;
8176   bool case_insensitive_fs;
8177 #ifndef _WIN32
8178   MY_STAT dir_stat;
8179 #endif
8180 
8181   if (!opt_secure_file_priv[0])
8182   {
8183     if (opt_bootstrap)
8184     {
8185       /*
8186         Do not impose --secure-file-priv restriction
8187         in --bootstrap mode
8188       */
8189       sql_print_information("Ignoring --secure-file-priv value as server is "
8190                             "running with --initialize(-insecure) or "
8191                             "--bootstrap.");
8192     }
8193     else
8194     {
8195       sql_print_warning("Insecure configuration for --secure-file-priv: "
8196                         "Current value does not restrict location of generated "
8197                         "files. Consider setting it to a valid, "
8198                         "non-empty path.");
8199     }
8200     return true;
8201   }
8202 
8203   /*
8204     Setting --secure-file-priv to NULL would disable
8205     reading/writing from/to file
8206   */
8207   if(!my_strcasecmp(system_charset_info, opt_secure_file_priv, "NULL"))
8208   {
8209     sql_print_information("--secure-file-priv is set to NULL. "
8210                           "Operations related to importing and exporting "
8211                           "data are disabled");
8212     return true;
8213   }
8214 
8215   /*
8216     Check if --secure-file-priv can access data directory
8217   */
8218   opt_secure_file_priv_len= strlen(opt_secure_file_priv);
8219 
8220   /*
8221     Adds dir seperator at the end.
8222     This is required in subsequent comparison
8223   */
8224   convert_dirname(datadir_buffer, mysql_unpacked_real_data_home, NullS);
8225   opt_datadir_len= strlen(datadir_buffer);
8226 
8227   case_insensitive_fs=
8228     (test_if_case_insensitive(datadir_buffer) == 1);
8229 
8230   if (!case_insensitive_fs)
8231   {
8232     if (!strncmp(datadir_buffer, opt_secure_file_priv,
8233           opt_datadir_len < opt_secure_file_priv_len ?
8234           opt_datadir_len : opt_secure_file_priv_len))
8235     {
8236       warn= true;
8237       strcpy(whichdir, "Data directory");
8238     }
8239   }
8240   else
8241   {
8242     if (!files_charset_info->coll->strnncoll(files_charset_info,
8243           (uchar *) datadir_buffer,
8244           opt_datadir_len,
8245           (uchar *) opt_secure_file_priv,
8246           opt_secure_file_priv_len,
8247           TRUE))
8248     {
8249       warn= true;
8250       strcpy(whichdir, "Data directory");
8251     }
8252   }
8253 
8254   /*
8255     Don't bother comparing --secure-file-priv with --plugin-dir
8256     if we already have a match against --datdir or
8257     --plugin-dir is not pointing to a valid directory.
8258   */
8259   if (!warn && !my_realpath(plugindir_buffer, opt_plugin_dir, 0))
8260   {
8261     convert_dirname(plugindir_buffer, plugindir_buffer, NullS);
8262     opt_plugindir_len= strlen(plugindir_buffer);
8263 
8264     if (!case_insensitive_fs)
8265     {
8266       if (!strncmp(plugindir_buffer, opt_secure_file_priv,
8267           opt_plugindir_len < opt_secure_file_priv_len ?
8268           opt_plugindir_len : opt_secure_file_priv_len))
8269       {
8270         warn= true;
8271         strcpy(whichdir, "Plugin directory");
8272       }
8273     }
8274     else
8275     {
8276       if (!files_charset_info->coll->strnncoll(files_charset_info,
8277           (uchar *) plugindir_buffer,
8278           opt_plugindir_len,
8279           (uchar *) opt_secure_file_priv,
8280           opt_secure_file_priv_len,
8281           TRUE))
8282       {
8283         warn= true;
8284         strcpy(whichdir, "Plugin directory");
8285       }
8286     }
8287   }
8288 
8289 
8290   if (warn)
8291     sql_print_warning("Insecure configuration for --secure-file-priv: "
8292                       "%s is accessible through "
8293                       "--secure-file-priv. Consider choosing a different "
8294                       "directory.", whichdir);
8295 
8296 #ifndef _WIN32
8297   /*
8298      Check for --secure-file-priv directory's permission
8299   */
8300   if (!(my_stat(opt_secure_file_priv, &dir_stat, MYF(0))))
8301   {
8302     sql_print_error("Failed to get stat for directory pointed out "
8303                     "by --secure-file-priv");
8304     return false;
8305   }
8306 
8307   if (dir_stat.st_mode & S_IRWXO)
8308     sql_print_warning("Insecure configuration for --secure-file-priv: "
8309                       "Location is accessible to all OS users. "
8310                       "Consider choosing a different directory.");
8311 #endif
8312   return true;
8313 }
8314 
fix_paths(void)8315 static int fix_paths(void)
8316 {
8317   char buff[FN_REFLEN],*pos;
8318   bool secure_file_priv_nonempty= false;
8319   convert_dirname(mysql_home,mysql_home,NullS);
8320   /* Resolve symlinks to allow 'mysql_home' to be a relative symlink */
8321   my_realpath(mysql_home,mysql_home,MYF(0));
8322   /* Ensure that mysql_home ends in FN_LIBCHAR */
8323   pos=strend(mysql_home);
8324   if (pos[-1] != FN_LIBCHAR)
8325   {
8326     pos[0]= FN_LIBCHAR;
8327     pos[1]= 0;
8328   }
8329   convert_dirname(lc_messages_dir, lc_messages_dir, NullS);
8330   convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
8331   (void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir
8332   (void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home);
8333   (void) my_load_path(pidfile_name, pidfile_name_ptr, mysql_real_data_home);
8334 
8335   convert_dirname(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr :
8336                                   get_relative_path(PLUGINDIR), NullS);
8337   (void) my_load_path(opt_plugin_dir, opt_plugin_dir, mysql_home);
8338   opt_plugin_dir_ptr= opt_plugin_dir;
8339 
8340   my_realpath(mysql_unpacked_real_data_home, mysql_real_data_home, MYF(0));
8341   mysql_unpacked_real_data_home_len=
8342     strlen(mysql_unpacked_real_data_home);
8343   if (mysql_unpacked_real_data_home[mysql_unpacked_real_data_home_len-1] == FN_LIBCHAR)
8344     --mysql_unpacked_real_data_home_len;
8345 
8346   char *sharedir=get_relative_path(SHAREDIR);
8347   if (test_if_hard_path(sharedir))
8348     strmake(buff,sharedir,sizeof(buff)-1);    /* purecov: tested */
8349   else
8350     strxnmov(buff,sizeof(buff)-1,mysql_home,sharedir,NullS);
8351   convert_dirname(buff,buff,NullS);
8352   (void) my_load_path(lc_messages_dir, lc_messages_dir, buff);
8353 
8354   /* If --character-sets-dir isn't given, use shared library dir */
8355   if (charsets_dir)
8356     strmake(mysql_charsets_dir, charsets_dir, sizeof(mysql_charsets_dir)-1);
8357   else
8358     strxnmov(mysql_charsets_dir, sizeof(mysql_charsets_dir)-1, buff,
8359        CHARSET_DIR, NullS);
8360   (void) my_load_path(mysql_charsets_dir, mysql_charsets_dir, buff);
8361   convert_dirname(mysql_charsets_dir, mysql_charsets_dir, NullS);
8362   charsets_dir=mysql_charsets_dir;
8363 
8364   if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir))
8365     return 1;
8366   if (!opt_mysql_tmpdir)
8367     opt_mysql_tmpdir= mysql_tmpdir;
8368 #ifdef HAVE_REPLICATION
8369   if (!slave_load_tmpdir)
8370     slave_load_tmpdir= mysql_tmpdir;
8371 #endif /* HAVE_REPLICATION */
8372   /*
8373     Convert the secure-file-priv option to system format, allowing
8374     a quick strcmp to check if read or write is in an allowed dir
8375   */
8376   if (opt_bootstrap)
8377     opt_secure_file_priv= EMPTY_STR.str;
8378   secure_file_priv_nonempty= opt_secure_file_priv[0] ? true : false;
8379 
8380   if (secure_file_priv_nonempty && strlen(opt_secure_file_priv) > FN_REFLEN)
8381   {
8382     sql_print_warning("Value for --secure-file-priv is longer than maximum "
8383                       "limit of %d", FN_REFLEN-1);
8384     return 1;
8385   }
8386 
8387   memset(buff, 0, sizeof(buff));
8388   if (secure_file_priv_nonempty &&
8389       my_strcasecmp(system_charset_info, opt_secure_file_priv, "NULL"))
8390   {
8391     int retval= my_realpath(buff, opt_secure_file_priv, MYF(MY_WME));
8392     if (!retval)
8393     {
8394       convert_dirname(secure_file_real_path, buff, NullS);
8395 #ifdef WIN32
8396       MY_DIR *dir= my_dir(secure_file_real_path, MYF(MY_DONT_SORT+MY_WME));
8397       if (!dir)
8398       {
8399         retval= 1;
8400       }
8401       else
8402       {
8403         my_dirend(dir);
8404       }
8405 #endif
8406     }
8407 
8408     if (retval)
8409     {
8410       char err_buffer[FN_REFLEN];
8411       my_snprintf(err_buffer, FN_REFLEN-1,
8412                   "Failed to access directory for --secure-file-priv."
8413                   " Please make sure that directory exists and is "
8414                   "accessible by MySQL Server. Supplied value : %s",
8415                   opt_secure_file_priv);
8416       err_buffer[FN_REFLEN-1]='\0';
8417       sql_print_error("%s", err_buffer);
8418       return 1;
8419     }
8420     opt_secure_file_priv= secure_file_real_path;
8421   }
8422 
8423   if (!check_secure_file_priv_path())
8424     return 1;
8425 
8426   return 0;
8427 }
8428 
8429 /**
8430   Check if file system used for databases is case insensitive.
8431 
8432   @param dir_name     Directory to test
8433 
8434   @retval
8435     -1  Don't know (Test failed)
8436   @retval
8437     0   File system is case sensitive
8438   @retval
8439     1   File system is case insensitive
8440 */
8441 
test_if_case_insensitive(const char * dir_name)8442 static int test_if_case_insensitive(const char *dir_name)
8443 {
8444   int result= 0;
8445   File file;
8446   char buff[FN_REFLEN], buff2[FN_REFLEN];
8447   MY_STAT stat_info;
8448   DBUG_ENTER("test_if_case_insensitive");
8449 
8450   fn_format(buff, glob_hostname, dir_name, ".lower-test",
8451       MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_REPLACE_DIR);
8452   fn_format(buff2, glob_hostname, dir_name, ".LOWER-TEST",
8453       MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_REPLACE_DIR);
8454   mysql_file_delete(key_file_casetest, buff2, MYF(0));
8455   if ((file= mysql_file_create(key_file_casetest,
8456                                buff, 0666, O_RDWR, MYF(0))) < 0)
8457   {
8458     sql_print_warning("Can't create test file %s", buff);
8459     DBUG_RETURN(-1);
8460   }
8461   mysql_file_close(file, MYF(0));
8462   if (mysql_file_stat(key_file_casetest, buff2, &stat_info, MYF(0)))
8463     result= 1;          // Can access file
8464   mysql_file_delete(key_file_casetest, buff, MYF(MY_WME));
8465   DBUG_PRINT("exit", ("result: %d", result));
8466   DBUG_RETURN(result);
8467 }
8468 
8469 
8470 #ifndef EMBEDDED_LIBRARY
8471 
8472 /**
8473   Create file to store pid number.
8474 */
create_pid_file()8475 static void create_pid_file()
8476 {
8477   File file;
8478   bool check_parent_path= 1, is_path_accessible= 1;
8479   char pid_filepath[FN_REFLEN], *pos= NULL;
8480   /* Copy pid file name to get pid file path */
8481   strcpy(pid_filepath, pidfile_name);
8482 
8483   /* Iterate through the entire path to check if even one of the sub-dirs
8484      is world-writable */
8485   while (check_parent_path && (pos= strrchr(pid_filepath, FN_LIBCHAR))
8486          && (pos != pid_filepath)) /* shouldn't check root */
8487   {
8488     *pos= '\0';  /* Trim the inner-most dir */
8489     switch (is_file_or_dir_world_writable(pid_filepath))
8490     {
8491       case -2:
8492         is_path_accessible= 0;
8493         break;
8494       case -1:
8495         sql_print_error("Can't start server: can't check PID filepath: %s",
8496                         strerror(errno));
8497         exit(MYSQLD_ABORT_EXIT);
8498       case 1:
8499         sql_print_warning("Insecure configuration for --pid-file: Location "
8500                           "'%s' in the path is accessible to all OS users. "
8501                           "Consider choosing a different directory.",
8502                           pid_filepath);
8503         check_parent_path= 0;
8504         break;
8505       case 0:
8506         continue; /* Keep checking the parent dir */
8507     }
8508   }
8509   if (!is_path_accessible)
8510   {
8511     sql_print_warning("Few location(s) are inaccessible while checking PID filepath.");
8512   }
8513   if ((file= mysql_file_create(key_file_pid, pidfile_name, 0664,
8514                                O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0)
8515   {
8516     char buff[MAX_BIGINT_WIDTH + 1], *end;
8517     end= int10_to_str((long) getpid(), buff, 10);
8518     *end++= '\n';
8519     if (!mysql_file_write(file, (uchar*) buff, (uint) (end-buff),
8520                           MYF(MY_WME | MY_NABP)))
8521     {
8522       mysql_file_close(file, MYF(0));
8523       pid_file_created= true;
8524       return;
8525     }
8526     mysql_file_close(file, MYF(0));
8527   }
8528   sql_print_error("Can't start server: can't create PID file: %s",
8529                   strerror(errno));
8530   exit(MYSQLD_ABORT_EXIT);
8531 }
8532 
8533 
8534 /**
8535   Remove the process' pid file.
8536 
8537   @param  flags  file operation flags
8538 */
8539 
delete_pid_file(myf flags)8540 static void delete_pid_file(myf flags)
8541 {
8542   File file;
8543   if (opt_bootstrap ||
8544       !pid_file_created ||
8545       !(file= mysql_file_open(key_file_pid, pidfile_name,
8546                               O_RDONLY, flags)))
8547     return;
8548 
8549   if (file == -1)
8550   {
8551     sql_print_information("Unable to delete pid file: %s", strerror(errno));
8552     return;
8553   }
8554 
8555   uchar buff[MAX_BIGINT_WIDTH + 1];
8556   /* Make sure that the pid file was created by the same process. */
8557   size_t error= mysql_file_read(file, buff, sizeof(buff), flags);
8558   mysql_file_close(file, flags);
8559   buff[sizeof(buff) - 1]= '\0';
8560   if (error != MY_FILE_ERROR &&
8561       atol((char *) buff) == (long) getpid())
8562   {
8563     mysql_file_delete(key_file_pid, pidfile_name, flags);
8564     pid_file_created= false;
8565   }
8566   return;
8567 }
8568 #endif /* EMBEDDED_LIBRARY */
8569 
8570 
8571 /**
8572   Returns the current state of the server : booting, operational or shutting
8573   down.
8574 
8575   @return
8576     SERVER_BOOTING        Server is not operational. It is starting.
8577     SERVER_OPERATING      Server is fully initialized and operating.
8578     SERVER_SHUTTING_DOWN  Server is shutting down.
8579 */
get_server_state()8580 enum_server_operational_state get_server_state()
8581 {
8582   return server_operational_state;
8583 }
8584 
8585 /**
8586   Reset status for all threads.
8587 */
8588 class Reset_thd_status : public Do_THD_Impl
8589 {
8590 public:
Reset_thd_status()8591   Reset_thd_status() { }
operator ()(THD * thd)8592   virtual void operator()(THD *thd)
8593   {
8594     /*
8595       Add thread's status variabes to global status
8596       and reset thread's status variables.
8597     */
8598     add_to_status(&global_status_var, &thd->status_var, true);
8599   }
8600 };
8601 
8602 /**
8603   Reset global and session status variables.
8604 */
refresh_status(THD * thd)8605 void refresh_status(THD *thd)
8606 {
8607   mysql_mutex_lock(&LOCK_status);
8608 
8609   if (show_compatibility_56)
8610   {
8611     /*
8612       Add thread's status variabes to global status
8613       and reset current thread's status variables.
8614     */
8615     add_to_status(&global_status_var, &thd->status_var, true);
8616   }
8617   else
8618   {
8619     /* For all threads, add status to global status and then reset. */
8620     Reset_thd_status reset_thd_status;
8621     Global_THD_manager::get_instance()->do_for_all_thd_copy(&reset_thd_status);
8622 #ifndef EMBEDDED_LIBRARY
8623 #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
8624     /* Reset aggregated status counters. */
8625     reset_pfs_status_stats();
8626 #endif
8627 #endif
8628   }
8629 
8630   /* Reset some global variables. */
8631   reset_status_vars();
8632 
8633   /* Reset the counters of all key caches (default and named). */
8634   process_key_caches(reset_key_cache_counters);
8635   flush_status_time= time((time_t*) 0);
8636   mysql_mutex_unlock(&LOCK_status);
8637 
8638 #ifndef EMBEDDED_LIBRARY
8639   /*
8640     Set max_used_connections to the number of currently open
8641     connections.  Do this out of LOCK_status to avoid deadlocks.
8642     Status reset becomes not atomic, but status data is not exact anyway.
8643   */
8644   Connection_handler_manager::reset_max_used_connections();
8645 #endif
8646 }
8647 
8648 
8649 /*****************************************************************************
8650   Instantiate variables for missing storage engines
8651   This section should go away soon
8652 *****************************************************************************/
8653 
8654 #ifdef HAVE_PSI_INTERFACE
8655 PSI_mutex_key key_LOCK_tc;
8656 
8657 #ifdef HAVE_OPENSSL
8658 PSI_mutex_key key_LOCK_des_key_file;
8659 #endif /* HAVE_OPENSSL */
8660 
8661 PSI_mutex_key key_BINLOG_LOCK_commit;
8662 PSI_mutex_key key_BINLOG_LOCK_commit_queue;
8663 PSI_mutex_key key_BINLOG_LOCK_done;
8664 PSI_mutex_key key_BINLOG_LOCK_flush_queue;
8665 PSI_mutex_key key_BINLOG_LOCK_index;
8666 PSI_mutex_key key_BINLOG_LOCK_log;
8667 PSI_mutex_key key_BINLOG_LOCK_binlog_end_pos;
8668 PSI_mutex_key key_BINLOG_LOCK_sync;
8669 PSI_mutex_key key_BINLOG_LOCK_sync_queue;
8670 PSI_mutex_key key_BINLOG_LOCK_xids;
8671 PSI_mutex_key
8672   key_hash_filo_lock,
8673   Gtid_set::key_gtid_executed_free_intervals_mutex,
8674   key_LOCK_crypt, key_LOCK_error_log,
8675   key_LOCK_gdl, key_LOCK_global_system_variables,
8676   key_LOCK_manager,
8677   key_LOCK_prepared_stmt_count,
8678   key_LOCK_server_started, key_LOCK_status,
8679   key_LOCK_sql_slave_skip_counter,
8680   key_LOCK_slave_net_timeout,
8681   key_LOCK_slave_trans_dep_tracker,
8682   key_LOCK_system_variables_hash, key_LOCK_table_share, key_LOCK_thd_data,
8683   key_LOCK_thd_sysvar,
8684   key_LOCK_user_conn, key_LOCK_uuid_generator, key_LOG_LOCK_log,
8685   key_master_info_data_lock, key_master_info_run_lock,
8686   key_master_info_sleep_lock, key_master_info_thd_lock,
8687   key_mutex_slave_reporting_capability_err_lock, key_relay_log_info_data_lock,
8688   key_relay_log_info_sleep_lock, key_relay_log_info_thd_lock,
8689   key_relay_log_info_log_space_lock, key_relay_log_info_run_lock,
8690   key_mutex_slave_parallel_pend_jobs, key_mutex_mts_temp_tables_lock,
8691   key_mutex_slave_parallel_worker_count,
8692   key_mutex_slave_parallel_worker,
8693   key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data,
8694   key_LOCK_error_messages,
8695   key_LOCK_log_throttle_qni, key_LOCK_query_plan, key_LOCK_thd_query,
8696   key_LOCK_cost_const, key_LOCK_current_cond,
8697   key_LOCK_keyring_operations;
8698 PSI_mutex_key key_RELAYLOG_LOCK_commit;
8699 PSI_mutex_key key_RELAYLOG_LOCK_commit_queue;
8700 PSI_mutex_key key_RELAYLOG_LOCK_done;
8701 PSI_mutex_key key_RELAYLOG_LOCK_flush_queue;
8702 PSI_mutex_key key_RELAYLOG_LOCK_index;
8703 PSI_mutex_key key_RELAYLOG_LOCK_log;
8704 PSI_mutex_key key_RELAYLOG_LOCK_sync;
8705 PSI_mutex_key key_RELAYLOG_LOCK_sync_queue;
8706 PSI_mutex_key key_RELAYLOG_LOCK_xids;
8707 PSI_mutex_key key_LOCK_sql_rand;
8708 PSI_mutex_key key_gtid_ensure_index_mutex;
8709 PSI_mutex_key key_mts_temp_table_LOCK;
8710 PSI_mutex_key key_LOCK_reset_gtid_table;
8711 PSI_mutex_key key_LOCK_compress_gtid_table;
8712 PSI_mutex_key key_mts_gaq_LOCK;
8713 PSI_mutex_key key_thd_timer_mutex;
8714 PSI_mutex_key key_LOCK_offline_mode;
8715 PSI_mutex_key key_LOCK_default_password_lifetime;
8716 
8717 #ifdef HAVE_REPLICATION
8718 PSI_mutex_key key_commit_order_manager_mutex;
8719 PSI_mutex_key key_mutex_slave_worker_hash;
8720 #endif
8721 
8722 static PSI_mutex_info all_server_mutexes[]=
8723 {
8724   { &key_LOCK_tc, "TC_LOG_MMAP::LOCK_tc", 0},
8725 
8726 #ifdef HAVE_OPENSSL
8727   { &key_LOCK_des_key_file, "LOCK_des_key_file", PSI_FLAG_GLOBAL},
8728 #endif /* HAVE_OPENSSL */
8729 
8730   { &key_BINLOG_LOCK_commit, "MYSQL_BIN_LOG::LOCK_commit", 0 },
8731   { &key_BINLOG_LOCK_commit_queue, "MYSQL_BIN_LOG::LOCK_commit_queue", 0 },
8732   { &key_BINLOG_LOCK_done, "MYSQL_BIN_LOG::LOCK_done", 0 },
8733   { &key_BINLOG_LOCK_flush_queue, "MYSQL_BIN_LOG::LOCK_flush_queue", 0 },
8734   { &key_BINLOG_LOCK_index, "MYSQL_BIN_LOG::LOCK_index", 0},
8735   { &key_BINLOG_LOCK_log, "MYSQL_BIN_LOG::LOCK_log", 0},
8736   { &key_BINLOG_LOCK_binlog_end_pos, "MYSQL_BIN_LOG::LOCK_binlog_end_pos", 0},
8737   { &key_BINLOG_LOCK_sync, "MYSQL_BIN_LOG::LOCK_sync", 0},
8738   { &key_BINLOG_LOCK_sync_queue, "MYSQL_BIN_LOG::LOCK_sync_queue", 0 },
8739   { &key_BINLOG_LOCK_xids, "MYSQL_BIN_LOG::LOCK_xids", 0 },
8740   { &key_RELAYLOG_LOCK_commit, "MYSQL_RELAY_LOG::LOCK_commit", 0},
8741   { &key_RELAYLOG_LOCK_commit_queue, "MYSQL_RELAY_LOG::LOCK_commit_queue", 0 },
8742   { &key_RELAYLOG_LOCK_done, "MYSQL_RELAY_LOG::LOCK_done", 0 },
8743   { &key_RELAYLOG_LOCK_flush_queue, "MYSQL_RELAY_LOG::LOCK_flush_queue", 0 },
8744   { &key_RELAYLOG_LOCK_index, "MYSQL_RELAY_LOG::LOCK_index", 0},
8745   { &key_RELAYLOG_LOCK_log, "MYSQL_RELAY_LOG::LOCK_log", 0},
8746   { &key_RELAYLOG_LOCK_sync, "MYSQL_RELAY_LOG::LOCK_sync", 0},
8747   { &key_RELAYLOG_LOCK_sync_queue, "MYSQL_RELAY_LOG::LOCK_sync_queue", 0 },
8748   { &key_RELAYLOG_LOCK_xids, "MYSQL_RELAY_LOG::LOCK_xids", 0},
8749   { &key_hash_filo_lock, "hash_filo::lock", 0},
8750   { &Gtid_set::key_gtid_executed_free_intervals_mutex, "Gtid_set::gtid_executed::free_intervals_mutex", 0 },
8751   { &key_LOCK_crypt, "LOCK_crypt", PSI_FLAG_GLOBAL},
8752   { &key_LOCK_error_log, "LOCK_error_log", PSI_FLAG_GLOBAL},
8753   { &key_LOCK_gdl, "LOCK_gdl", PSI_FLAG_GLOBAL},
8754   { &key_LOCK_global_system_variables, "LOCK_global_system_variables", PSI_FLAG_GLOBAL},
8755 #if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
8756   { &key_LOCK_handler_count, "LOCK_handler_count", PSI_FLAG_GLOBAL},
8757 #endif
8758   { &key_LOCK_manager, "LOCK_manager", PSI_FLAG_GLOBAL},
8759   { &key_LOCK_prepared_stmt_count, "LOCK_prepared_stmt_count", PSI_FLAG_GLOBAL},
8760   { &key_LOCK_sql_slave_skip_counter, "LOCK_sql_slave_skip_counter", PSI_FLAG_GLOBAL},
8761   { &key_LOCK_slave_net_timeout, "LOCK_slave_net_timeout", PSI_FLAG_GLOBAL},
8762   { &key_LOCK_slave_trans_dep_tracker, "LOCK_slave_trans_dep_tracker", PSI_FLAG_GLOBAL},
8763   { &key_LOCK_server_started, "LOCK_server_started", PSI_FLAG_GLOBAL},
8764   { &key_LOCK_keyring_operations, "LOCK_keyring_operations", PSI_FLAG_GLOBAL},
8765 #if !defined(EMBEDDED_LIBRARY) && !defined(_WIN32)
8766   { &key_LOCK_socket_listener_active, "LOCK_socket_listener_active", PSI_FLAG_GLOBAL},
8767   { &key_LOCK_start_signal_handler, "LOCK_start_signal_handler", PSI_FLAG_GLOBAL},
8768 #endif
8769   { &key_LOCK_status, "LOCK_status", PSI_FLAG_GLOBAL},
8770   { &key_LOCK_system_variables_hash, "LOCK_system_variables_hash", PSI_FLAG_GLOBAL},
8771   { &key_LOCK_table_share, "LOCK_table_share", PSI_FLAG_GLOBAL},
8772   { &key_LOCK_thd_data, "THD::LOCK_thd_data", PSI_FLAG_VOLATILITY_SESSION},
8773   { &key_LOCK_thd_query, "THD::LOCK_thd_query", PSI_FLAG_VOLATILITY_SESSION},
8774   { &key_LOCK_thd_sysvar, "THD::LOCK_thd_sysvar", PSI_FLAG_VOLATILITY_SESSION},
8775   { &key_LOCK_user_conn, "LOCK_user_conn", PSI_FLAG_GLOBAL},
8776   { &key_LOCK_uuid_generator, "LOCK_uuid_generator", PSI_FLAG_GLOBAL},
8777   { &key_LOCK_sql_rand, "LOCK_sql_rand", PSI_FLAG_GLOBAL},
8778   { &key_LOG_LOCK_log, "LOG::LOCK_log", 0},
8779   { &key_master_info_data_lock, "Master_info::data_lock", 0},
8780   { &key_master_info_run_lock, "Master_info::run_lock", 0},
8781   { &key_master_info_sleep_lock, "Master_info::sleep_lock", 0},
8782   { &key_master_info_thd_lock, "Master_info::info_thd_lock", 0},
8783   { &key_mutex_slave_reporting_capability_err_lock, "Slave_reporting_capability::err_lock", 0},
8784   { &key_relay_log_info_data_lock, "Relay_log_info::data_lock", 0},
8785   { &key_relay_log_info_sleep_lock, "Relay_log_info::sleep_lock", 0},
8786   { &key_relay_log_info_thd_lock, "Relay_log_info::info_thd_lock", 0},
8787   { &key_relay_log_info_log_space_lock, "Relay_log_info::log_space_lock", 0},
8788   { &key_relay_log_info_run_lock, "Relay_log_info::run_lock", 0},
8789   { &key_mutex_slave_parallel_pend_jobs, "Relay_log_info::pending_jobs_lock", 0},
8790   { &key_mutex_slave_parallel_worker_count, "Relay_log_info::exit_count_lock", 0},
8791   { &key_mutex_mts_temp_tables_lock, "Relay_log_info::temp_tables_lock", 0},
8792   { &key_mutex_slave_parallel_worker, "Worker_info::jobs_lock", 0},
8793   { &key_structure_guard_mutex, "Query_cache::structure_guard_mutex", 0},
8794   { &key_TABLE_SHARE_LOCK_ha_data, "TABLE_SHARE::LOCK_ha_data", 0},
8795   { &key_LOCK_error_messages, "LOCK_error_messages", PSI_FLAG_GLOBAL},
8796   { &key_LOCK_log_throttle_qni, "LOCK_log_throttle_qni", PSI_FLAG_GLOBAL},
8797   { &key_gtid_ensure_index_mutex, "Gtid_state", PSI_FLAG_GLOBAL},
8798   { &key_LOCK_query_plan, "THD::LOCK_query_plan", PSI_FLAG_VOLATILITY_SESSION},
8799   { &key_LOCK_cost_const, "Cost_constant_cache::LOCK_cost_const",
8800     PSI_FLAG_GLOBAL},
8801   { &key_LOCK_current_cond, "THD::LOCK_current_cond", PSI_FLAG_VOLATILITY_SESSION},
8802   { &key_mts_temp_table_LOCK, "key_mts_temp_table_LOCK", 0},
8803   { &key_LOCK_reset_gtid_table, "LOCK_reset_gtid_table", PSI_FLAG_GLOBAL},
8804   { &key_LOCK_compress_gtid_table, "LOCK_compress_gtid_table", PSI_FLAG_GLOBAL},
8805   { &key_mts_gaq_LOCK, "key_mts_gaq_LOCK", 0},
8806   { &key_thd_timer_mutex, "thd_timer_mutex", 0},
8807 #ifdef HAVE_REPLICATION
8808   { &key_commit_order_manager_mutex, "Commit_order_manager::m_mutex", 0},
8809   { &key_mutex_slave_worker_hash, "Relay_log_info::slave_worker_hash_lock", 0},
8810 #endif
8811   { &key_LOCK_offline_mode, "LOCK_offline_mode", PSI_FLAG_GLOBAL},
8812   { &key_LOCK_default_password_lifetime, "LOCK_default_password_lifetime", PSI_FLAG_GLOBAL}
8813 };
8814 
8815 PSI_rwlock_key key_rwlock_LOCK_grant, key_rwlock_LOCK_logger,
8816   key_rwlock_LOCK_sys_init_connect, key_rwlock_LOCK_sys_init_slave,
8817   key_rwlock_LOCK_system_variables_hash, key_rwlock_query_cache_query_lock,
8818   key_rwlock_global_sid_lock, key_rwlock_gtid_mode_lock,
8819   key_rwlock_channel_map_lock, key_rwlock_channel_lock;
8820 
8821 PSI_rwlock_key key_rwlock_Trans_delegate_lock;
8822 PSI_rwlock_key key_rwlock_Server_state_delegate_lock;
8823 PSI_rwlock_key key_rwlock_Binlog_storage_delegate_lock;
8824 #ifdef HAVE_REPLICATION
8825 PSI_rwlock_key key_rwlock_Binlog_transmit_delegate_lock;
8826 PSI_rwlock_key key_rwlock_Binlog_relay_IO_delegate_lock;
8827 #endif
8828 
8829 static PSI_rwlock_info all_server_rwlocks[]=
8830 {
8831 #ifdef HAVE_REPLICATION
8832   { &key_rwlock_Binlog_transmit_delegate_lock, "Binlog_transmit_delegate::lock", PSI_FLAG_GLOBAL},
8833   { &key_rwlock_Binlog_relay_IO_delegate_lock, "Binlog_relay_IO_delegate::lock", PSI_FLAG_GLOBAL},
8834 #endif
8835   { &key_rwlock_LOCK_grant, "LOCK_grant", 0},
8836   { &key_rwlock_LOCK_logger, "LOGGER::LOCK_logger", 0},
8837   { &key_rwlock_LOCK_sys_init_connect, "LOCK_sys_init_connect", PSI_FLAG_GLOBAL},
8838   { &key_rwlock_LOCK_sys_init_slave, "LOCK_sys_init_slave", PSI_FLAG_GLOBAL},
8839   { &key_rwlock_LOCK_system_variables_hash, "LOCK_system_variables_hash", PSI_FLAG_GLOBAL},
8840   { &key_rwlock_query_cache_query_lock, "Query_cache_query::lock", 0},
8841   { &key_rwlock_global_sid_lock, "gtid_commit_rollback", PSI_FLAG_GLOBAL},
8842   { &key_rwlock_gtid_mode_lock, "gtid_mode_lock", PSI_FLAG_GLOBAL},
8843   { &key_rwlock_channel_map_lock, "channel_map_lock", 0},
8844   { &key_rwlock_channel_lock, "channel_lock", 0},
8845   { &key_rwlock_Trans_delegate_lock, "Trans_delegate::lock", PSI_FLAG_GLOBAL},
8846   { &key_rwlock_Server_state_delegate_lock, "Server_state_delegate::lock", PSI_FLAG_GLOBAL},
8847   { &key_rwlock_Binlog_storage_delegate_lock, "Binlog_storage_delegate::lock", PSI_FLAG_GLOBAL},
8848 #if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
8849   { &key_rwlock_LOCK_named_pipe_full_access_group, "LOCK_named_pipe_full_access_group", PSI_FLAG_GLOBAL},
8850 #endif /* _WIN32 && !EMBEDDED_LIBRARY */
8851 };
8852 
8853 PSI_cond_key key_PAGE_cond, key_COND_active, key_COND_pool;
8854 PSI_cond_key key_BINLOG_update_cond,
8855   key_COND_cache_status_changed, key_COND_manager,
8856   key_COND_server_started,
8857   key_item_func_sleep_cond, key_master_info_data_cond,
8858   key_master_info_start_cond, key_master_info_stop_cond,
8859   key_master_info_sleep_cond,
8860   key_relay_log_info_data_cond, key_relay_log_info_log_space_cond,
8861   key_relay_log_info_start_cond, key_relay_log_info_stop_cond,
8862   key_relay_log_info_sleep_cond, key_cond_slave_parallel_pend_jobs,
8863   key_cond_slave_parallel_worker, key_cond_mts_gaq,
8864   key_cond_mts_submode_logical_clock,
8865   key_TABLE_SHARE_cond, key_user_level_lock_cond;
8866 PSI_cond_key key_RELAYLOG_update_cond;
8867 PSI_cond_key key_BINLOG_COND_done;
8868 PSI_cond_key key_RELAYLOG_COND_done;
8869 PSI_cond_key key_BINLOG_prep_xids_cond;
8870 PSI_cond_key key_RELAYLOG_prep_xids_cond;
8871 PSI_cond_key key_gtid_ensure_index_cond;
8872 PSI_cond_key key_COND_compress_gtid_table;
8873 PSI_cond_key key_COND_thr_lock;
8874 #ifdef HAVE_REPLICATION
8875 PSI_cond_key key_commit_order_manager_cond;
8876 PSI_cond_key key_cond_slave_worker_hash;
8877 #endif
8878 
8879 static PSI_cond_info all_server_conds[]=
8880 {
8881   { &key_PAGE_cond, "PAGE::cond", 0},
8882   { &key_COND_active, "TC_LOG_MMAP::COND_active", 0},
8883   { &key_COND_pool, "TC_LOG_MMAP::COND_pool", 0},
8884   { &key_BINLOG_COND_done, "MYSQL_BIN_LOG::COND_done", 0},
8885   { &key_BINLOG_update_cond, "MYSQL_BIN_LOG::update_cond", 0},
8886   { &key_BINLOG_prep_xids_cond, "MYSQL_BIN_LOG::prep_xids_cond", 0},
8887   { &key_RELAYLOG_COND_done, "MYSQL_RELAY_LOG::COND_done", 0},
8888   { &key_RELAYLOG_update_cond, "MYSQL_RELAY_LOG::update_cond", 0},
8889   { &key_RELAYLOG_prep_xids_cond, "MYSQL_RELAY_LOG::prep_xids_cond", 0},
8890   { &key_COND_cache_status_changed, "Query_cache::COND_cache_status_changed", 0},
8891 #if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
8892   { &key_COND_handler_count, "COND_handler_count", PSI_FLAG_GLOBAL},
8893 #endif
8894   { &key_COND_manager, "COND_manager", PSI_FLAG_GLOBAL},
8895   { &key_COND_server_started, "COND_server_started", PSI_FLAG_GLOBAL},
8896 #if !defined(EMBEDDED_LIBRARY) && !defined(_WIN32)
8897   { &key_COND_socket_listener_active, "COND_socket_listener_active", PSI_FLAG_GLOBAL},
8898   { &key_COND_start_signal_handler, "COND_start_signal_handler", PSI_FLAG_GLOBAL},
8899 #endif
8900   { &key_COND_thr_lock, "COND_thr_lock", 0 },
8901   { &key_item_func_sleep_cond, "Item_func_sleep::cond", 0},
8902   { &key_master_info_data_cond, "Master_info::data_cond", 0},
8903   { &key_master_info_start_cond, "Master_info::start_cond", 0},
8904   { &key_master_info_stop_cond, "Master_info::stop_cond", 0},
8905   { &key_master_info_sleep_cond, "Master_info::sleep_cond", 0},
8906   { &key_relay_log_info_data_cond, "Relay_log_info::data_cond", 0},
8907   { &key_relay_log_info_log_space_cond, "Relay_log_info::log_space_cond", 0},
8908   { &key_relay_log_info_start_cond, "Relay_log_info::start_cond", 0},
8909   { &key_relay_log_info_stop_cond, "Relay_log_info::stop_cond", 0},
8910   { &key_relay_log_info_sleep_cond, "Relay_log_info::sleep_cond", 0},
8911   { &key_cond_slave_parallel_pend_jobs, "Relay_log_info::pending_jobs_cond", 0},
8912   { &key_cond_slave_parallel_worker, "Worker_info::jobs_cond", 0},
8913   { &key_cond_mts_gaq, "Relay_log_info::mts_gaq_cond", 0},
8914   { &key_TABLE_SHARE_cond, "TABLE_SHARE::cond", 0},
8915   { &key_user_level_lock_cond, "User_level_lock::cond", 0},
8916   { &key_gtid_ensure_index_cond, "Gtid_state", PSI_FLAG_GLOBAL},
8917   { &key_COND_compress_gtid_table, "COND_compress_gtid_table", PSI_FLAG_GLOBAL}
8918 #ifdef HAVE_REPLICATION
8919   ,
8920   { &key_commit_order_manager_cond, "Commit_order_manager::m_workers.cond", 0},
8921   { &key_cond_slave_worker_hash, "Relay_log_info::slave_worker_hash_lock", 0}
8922 #endif
8923 };
8924 
8925 PSI_thread_key key_thread_bootstrap, key_thread_handle_manager, key_thread_main,
8926   key_thread_one_connection, key_thread_signal_hand,
8927   key_thread_compress_gtid_table, key_thread_parser_service;
8928 PSI_thread_key key_thread_timer_notifier;
8929 
8930 static PSI_thread_info all_server_threads[]=
8931 {
8932 #if defined (_WIN32) && !defined (EMBEDDED_LIBRARY)
8933   { &key_thread_handle_con_namedpipes, "con_named_pipes", PSI_FLAG_GLOBAL},
8934   { &key_thread_handle_con_sharedmem, "con_shared_mem", PSI_FLAG_GLOBAL},
8935   { &key_thread_handle_con_sockets, "con_sockets", PSI_FLAG_GLOBAL},
8936   { &key_thread_handle_shutdown, "shutdown", PSI_FLAG_GLOBAL},
8937 #endif /* _WIN32 && !EMBEDDED_LIBRARY */
8938   { &key_thread_timer_notifier, "thread_timer_notifier", PSI_FLAG_GLOBAL},
8939   { &key_thread_bootstrap, "bootstrap", PSI_FLAG_GLOBAL},
8940   { &key_thread_handle_manager, "manager", PSI_FLAG_GLOBAL},
8941   { &key_thread_main, "main", PSI_FLAG_GLOBAL},
8942   { &key_thread_one_connection, "one_connection", 0},
8943   { &key_thread_signal_hand, "signal_handler", PSI_FLAG_GLOBAL},
8944   { &key_thread_compress_gtid_table, "compress_gtid_table", PSI_FLAG_GLOBAL},
8945   { &key_thread_parser_service, "parser_service", PSI_FLAG_GLOBAL},
8946 };
8947 
8948 PSI_file_key key_file_map;
8949 PSI_file_key key_file_binlog, key_file_binlog_cache,
8950   key_file_binlog_index, key_file_binlog_index_cache, key_file_casetest,
8951   key_file_dbopt, key_file_des_key_file, key_file_ERRMSG, key_select_to_file,
8952   key_file_fileparser, key_file_frm, key_file_global_ddl_log, key_file_load,
8953   key_file_loadfile, key_file_log_event_data, key_file_log_event_info,
8954   key_file_master_info, key_file_misc, key_file_partition_ddl_log,
8955   key_file_pid, key_file_relay_log_info, key_file_send_file, key_file_tclog,
8956   key_file_trg, key_file_trn, key_file_init;
8957 PSI_file_key key_file_general_log, key_file_slow_log;
8958 PSI_file_key key_file_relaylog, key_file_relaylog_cache, key_file_relaylog_index, key_file_relaylog_index_cache;
8959 
8960 static PSI_file_info all_server_files[]=
8961 {
8962   { &key_file_map, "map", 0},
8963   { &key_file_binlog, "binlog", 0},
8964   { &key_file_binlog_cache, "binlog_cache", 0},
8965   { &key_file_binlog_index, "binlog_index", 0},
8966   { &key_file_binlog_index_cache, "binlog_index_cache", 0},
8967   { &key_file_relaylog, "relaylog", 0},
8968   { &key_file_relaylog_cache, "relaylog_cache", 0},
8969   { &key_file_relaylog_index, "relaylog_index", 0},
8970   { &key_file_relaylog_index_cache, "relaylog_index_cache", 0},
8971   { &key_file_io_cache, "io_cache", 0},
8972   { &key_file_casetest, "casetest", 0},
8973   { &key_file_dbopt, "dbopt", 0},
8974   { &key_file_des_key_file, "des_key_file", 0},
8975   { &key_file_ERRMSG, "ERRMSG", 0},
8976   { &key_select_to_file, "select_to_file", 0},
8977   { &key_file_fileparser, "file_parser", 0},
8978   { &key_file_frm, "FRM", 0},
8979   { &key_file_global_ddl_log, "global_ddl_log", 0},
8980   { &key_file_load, "load", 0},
8981   { &key_file_loadfile, "LOAD_FILE", 0},
8982   { &key_file_log_event_data, "log_event_data", 0},
8983   { &key_file_log_event_info, "log_event_info", 0},
8984   { &key_file_master_info, "master_info", 0},
8985   { &key_file_misc, "misc", 0},
8986   { &key_file_partition_ddl_log, "partition_ddl_log", 0},
8987   { &key_file_pid, "pid", 0},
8988   { &key_file_general_log, "query_log", 0},
8989   { &key_file_relay_log_info, "relay_log_info", 0},
8990   { &key_file_send_file, "send_file", 0},
8991   { &key_file_slow_log, "slow_log", 0},
8992   { &key_file_tclog, "tclog", 0},
8993   { &key_file_trg, "trigger_name", 0},
8994   { &key_file_trn, "trigger", 0},
8995   { &key_file_init, "init", 0}
8996 };
8997 #endif /* HAVE_PSI_INTERFACE */
8998 
8999 PSI_stage_info stage_after_create= { 0, "After create", 0};
9000 PSI_stage_info stage_allocating_local_table= { 0, "allocating local table", 0};
9001 PSI_stage_info stage_alter_inplace_prepare= { 0, "preparing for alter table", 0};
9002 PSI_stage_info stage_alter_inplace= { 0, "altering table", 0};
9003 PSI_stage_info stage_alter_inplace_commit= { 0, "committing alter table to storage engine", 0};
9004 PSI_stage_info stage_changing_master= { 0, "Changing master", 0};
9005 PSI_stage_info stage_checking_master_version= { 0, "Checking master version", 0};
9006 PSI_stage_info stage_checking_permissions= { 0, "checking permissions", 0};
9007 PSI_stage_info stage_checking_privileges_on_cached_query= { 0, "checking privileges on cached query", 0};
9008 PSI_stage_info stage_checking_query_cache_for_query= { 0, "checking query cache for query", 0};
9009 PSI_stage_info stage_cleaning_up= { 0, "cleaning up", 0};
9010 PSI_stage_info stage_closing_tables= { 0, "closing tables", 0};
9011 PSI_stage_info stage_compressing_gtid_table= { 0, "Compressing gtid_executed table", 0};
9012 PSI_stage_info stage_connecting_to_master= { 0, "Connecting to master", 0};
9013 PSI_stage_info stage_converting_heap_to_ondisk= { 0, "converting HEAP to ondisk", 0};
9014 PSI_stage_info stage_copying_to_group_table= { 0, "Copying to group table", 0};
9015 PSI_stage_info stage_copying_to_tmp_table= { 0, "Copying to tmp table", 0};
9016 PSI_stage_info stage_copy_to_tmp_table= { 0, "copy to tmp table", PSI_FLAG_STAGE_PROGRESS};
9017 PSI_stage_info stage_creating_sort_index= { 0, "Creating sort index", 0};
9018 PSI_stage_info stage_creating_table= { 0, "creating table", 0};
9019 PSI_stage_info stage_creating_tmp_table= { 0, "Creating tmp table", 0};
9020 PSI_stage_info stage_deleting_from_main_table= { 0, "deleting from main table", 0};
9021 PSI_stage_info stage_deleting_from_reference_tables= { 0, "deleting from reference tables", 0};
9022 PSI_stage_info stage_discard_or_import_tablespace= { 0, "discard_or_import_tablespace", 0};
9023 PSI_stage_info stage_end= { 0, "end", 0};
9024 PSI_stage_info stage_executing= { 0, "executing", 0};
9025 PSI_stage_info stage_execution_of_init_command= { 0, "Execution of init_command", 0};
9026 PSI_stage_info stage_explaining= { 0, "explaining", 0};
9027 PSI_stage_info stage_finished_reading_one_binlog_switching_to_next_binlog= { 0, "Finished reading one binlog; switching to next binlog", 0};
9028 PSI_stage_info stage_flushing_relay_log_and_master_info_repository= { 0, "Flushing relay log and master info repository.", 0};
9029 PSI_stage_info stage_flushing_relay_log_info_file= { 0, "Flushing relay-log info file.", 0};
9030 PSI_stage_info stage_freeing_items= { 0, "freeing items", 0};
9031 PSI_stage_info stage_fulltext_initialization= { 0, "FULLTEXT initialization", 0};
9032 PSI_stage_info stage_got_handler_lock= { 0, "got handler lock", 0};
9033 PSI_stage_info stage_got_old_table= { 0, "got old table", 0};
9034 PSI_stage_info stage_init= { 0, "init", 0};
9035 PSI_stage_info stage_insert= { 0, "insert", 0};
9036 PSI_stage_info stage_invalidating_query_cache_entries_table= { 0, "invalidating query cache entries (table)", 0};
9037 PSI_stage_info stage_invalidating_query_cache_entries_table_list= { 0, "invalidating query cache entries (table list)", 0};
9038 PSI_stage_info stage_killing_slave= { 0, "Killing slave", 0};
9039 PSI_stage_info stage_logging_slow_query= { 0, "logging slow query", 0};
9040 PSI_stage_info stage_making_temp_file_append_before_load_data= { 0, "Making temporary file (append) before replaying LOAD DATA INFILE", 0};
9041 PSI_stage_info stage_making_temp_file_create_before_load_data= { 0, "Making temporary file (create) before replaying LOAD DATA INFILE", 0};
9042 PSI_stage_info stage_manage_keys= { 0, "manage keys", 0};
9043 PSI_stage_info stage_master_has_sent_all_binlog_to_slave= { 0, "Master has sent all binlog to slave; waiting for more updates", 0};
9044 PSI_stage_info stage_opening_tables= { 0, "Opening tables", 0};
9045 PSI_stage_info stage_optimizing= { 0, "optimizing", 0};
9046 PSI_stage_info stage_preparing= { 0, "preparing", 0};
9047 PSI_stage_info stage_purging_old_relay_logs= { 0, "Purging old relay logs", 0};
9048 PSI_stage_info stage_query_end= { 0, "query end", 0};
9049 PSI_stage_info stage_queueing_master_event_to_the_relay_log= { 0, "Queueing master event to the relay log", 0};
9050 PSI_stage_info stage_reading_event_from_the_relay_log= { 0, "Reading event from the relay log", 0};
9051 PSI_stage_info stage_registering_slave_on_master= { 0, "Registering slave on master", 0};
9052 PSI_stage_info stage_removing_duplicates= { 0, "Removing duplicates", 0};
9053 PSI_stage_info stage_removing_tmp_table= { 0, "removing tmp table", 0};
9054 PSI_stage_info stage_rename= { 0, "rename", 0};
9055 PSI_stage_info stage_rename_result_table= { 0, "rename result table", 0};
9056 PSI_stage_info stage_requesting_binlog_dump= { 0, "Requesting binlog dump", 0};
9057 PSI_stage_info stage_reschedule= { 0, "reschedule", 0};
9058 PSI_stage_info stage_searching_rows_for_update= { 0, "Searching rows for update", 0};
9059 PSI_stage_info stage_sending_binlog_event_to_slave= { 0, "Sending binlog event to slave", 0};
9060 PSI_stage_info stage_sending_cached_result_to_client= { 0, "sending cached result to client", 0};
9061 PSI_stage_info stage_sending_data= { 0, "Sending data", 0};
9062 PSI_stage_info stage_setup= { 0, "setup", 0};
9063 PSI_stage_info stage_slave_has_read_all_relay_log= { 0, "Slave has read all relay log; waiting for more updates", 0};
9064 PSI_stage_info stage_slave_waiting_event_from_coordinator= { 0, "Waiting for an event from Coordinator", 0};
9065 PSI_stage_info stage_slave_waiting_for_workers_to_process_queue= { 0, "Waiting for slave workers to process their queues", 0};
9066 PSI_stage_info stage_slave_waiting_worker_queue= { 0, "Waiting for Slave Worker queue", 0};
9067 PSI_stage_info stage_slave_waiting_worker_to_free_events= { 0, "Waiting for Slave Workers to free pending events", 0};
9068 PSI_stage_info stage_slave_waiting_worker_to_release_partition= { 0, "Waiting for Slave Worker to release partition", 0};
9069 PSI_stage_info stage_slave_waiting_workers_to_exit= { 0, "Waiting for workers to exit", 0};
9070 PSI_stage_info stage_sorting_for_group= { 0, "Sorting for group", 0};
9071 PSI_stage_info stage_sorting_for_order= { 0, "Sorting for order", 0};
9072 PSI_stage_info stage_sorting_result= { 0, "Sorting result", 0};
9073 PSI_stage_info stage_statistics= { 0, "statistics", 0};
9074 PSI_stage_info stage_sql_thd_waiting_until_delay= { 0, "Waiting until MASTER_DELAY seconds after master executed event", 0 };
9075 PSI_stage_info stage_storing_result_in_query_cache= { 0, "storing result in query cache", 0};
9076 PSI_stage_info stage_storing_row_into_queue= { 0, "storing row into queue", 0};
9077 PSI_stage_info stage_system_lock= { 0, "System lock", 0};
9078 PSI_stage_info stage_update= { 0, "update", 0};
9079 PSI_stage_info stage_updating= { 0, "updating", 0};
9080 PSI_stage_info stage_updating_main_table= { 0, "updating main table", 0};
9081 PSI_stage_info stage_updating_reference_tables= { 0, "updating reference tables", 0};
9082 PSI_stage_info stage_upgrading_lock= { 0, "upgrading lock", 0};
9083 PSI_stage_info stage_user_sleep= { 0, "User sleep", 0};
9084 PSI_stage_info stage_verifying_table= { 0, "verifying table", 0};
9085 PSI_stage_info stage_waiting_for_gtid_to_be_committed= { 0, "Waiting for GTID to be committed", 0};
9086 PSI_stage_info stage_waiting_for_handler_insert= { 0, "waiting for handler insert", 0};
9087 PSI_stage_info stage_waiting_for_handler_lock= { 0, "waiting for handler lock", 0};
9088 PSI_stage_info stage_waiting_for_handler_open= { 0, "waiting for handler open", 0};
9089 PSI_stage_info stage_waiting_for_insert= { 0, "Waiting for INSERT", 0};
9090 PSI_stage_info stage_waiting_for_master_to_send_event= { 0, "Waiting for master to send event", 0};
9091 PSI_stage_info stage_waiting_for_master_update= { 0, "Waiting for master update", 0};
9092 PSI_stage_info stage_waiting_for_relay_log_space= { 0, "Waiting for the slave SQL thread to free enough relay log space", 0};
9093 PSI_stage_info stage_waiting_for_slave_mutex_on_exit= { 0, "Waiting for slave mutex on exit", 0};
9094 PSI_stage_info stage_waiting_for_slave_thread_to_start= { 0, "Waiting for slave thread to start", 0};
9095 PSI_stage_info stage_waiting_for_table_flush= { 0, "Waiting for table flush", 0};
9096 PSI_stage_info stage_waiting_for_query_cache_lock= { 0, "Waiting for query cache lock", 0};
9097 PSI_stage_info stage_waiting_for_the_next_event_in_relay_log= { 0, "Waiting for the next event in relay log", 0};
9098 PSI_stage_info stage_waiting_for_the_slave_thread_to_advance_position= { 0, "Waiting for the slave SQL thread to advance position", 0};
9099 PSI_stage_info stage_waiting_to_finalize_termination= { 0, "Waiting to finalize termination", 0};
9100 PSI_stage_info stage_worker_waiting_for_its_turn_to_commit= { 0, "Waiting for preceding transaction to commit", 0};
9101 PSI_stage_info stage_worker_waiting_for_commit_parent= { 0, "Waiting for dependent transaction to commit", 0};
9102 PSI_stage_info stage_suspending= { 0, "Suspending", 0};
9103 PSI_stage_info stage_starting= { 0, "starting", 0};
9104 PSI_stage_info stage_waiting_for_no_channel_reference= { 0, "Waiting for no channel reference.", 0};
9105 
9106 #ifdef HAVE_PSI_INTERFACE
9107 
9108 PSI_stage_info *all_server_stages[]=
9109 {
9110   & stage_after_create,
9111   & stage_allocating_local_table,
9112   & stage_alter_inplace_prepare,
9113   & stage_alter_inplace,
9114   & stage_alter_inplace_commit,
9115   & stage_changing_master,
9116   & stage_checking_master_version,
9117   & stage_checking_permissions,
9118   & stage_checking_privileges_on_cached_query,
9119   & stage_checking_query_cache_for_query,
9120   & stage_cleaning_up,
9121   & stage_closing_tables,
9122   & stage_compressing_gtid_table,
9123   & stage_connecting_to_master,
9124   & stage_converting_heap_to_ondisk,
9125   & stage_copying_to_group_table,
9126   & stage_copying_to_tmp_table,
9127   & stage_copy_to_tmp_table,
9128   & stage_creating_sort_index,
9129   & stage_creating_table,
9130   & stage_creating_tmp_table,
9131   & stage_deleting_from_main_table,
9132   & stage_deleting_from_reference_tables,
9133   & stage_discard_or_import_tablespace,
9134   & stage_end,
9135   & stage_executing,
9136   & stage_execution_of_init_command,
9137   & stage_explaining,
9138   & stage_finished_reading_one_binlog_switching_to_next_binlog,
9139   & stage_flushing_relay_log_and_master_info_repository,
9140   & stage_flushing_relay_log_info_file,
9141   & stage_freeing_items,
9142   & stage_fulltext_initialization,
9143   & stage_got_handler_lock,
9144   & stage_got_old_table,
9145   & stage_init,
9146   & stage_insert,
9147   & stage_invalidating_query_cache_entries_table,
9148   & stage_invalidating_query_cache_entries_table_list,
9149   & stage_killing_slave,
9150   & stage_logging_slow_query,
9151   & stage_making_temp_file_append_before_load_data,
9152   & stage_making_temp_file_create_before_load_data,
9153   & stage_manage_keys,
9154   & stage_master_has_sent_all_binlog_to_slave,
9155   & stage_opening_tables,
9156   & stage_optimizing,
9157   & stage_preparing,
9158   & stage_purging_old_relay_logs,
9159   & stage_query_end,
9160   & stage_queueing_master_event_to_the_relay_log,
9161   & stage_reading_event_from_the_relay_log,
9162   & stage_registering_slave_on_master,
9163   & stage_removing_duplicates,
9164   & stage_removing_tmp_table,
9165   & stage_rename,
9166   & stage_rename_result_table,
9167   & stage_requesting_binlog_dump,
9168   & stage_reschedule,
9169   & stage_searching_rows_for_update,
9170   & stage_sending_binlog_event_to_slave,
9171   & stage_sending_cached_result_to_client,
9172   & stage_sending_data,
9173   & stage_setup,
9174   & stage_slave_has_read_all_relay_log,
9175   & stage_slave_waiting_event_from_coordinator,
9176   & stage_slave_waiting_for_workers_to_process_queue,
9177   & stage_slave_waiting_worker_queue,
9178   & stage_slave_waiting_worker_to_free_events,
9179   & stage_slave_waiting_worker_to_release_partition,
9180   & stage_slave_waiting_workers_to_exit,
9181   & stage_sorting_for_group,
9182   & stage_sorting_for_order,
9183   & stage_sorting_result,
9184   & stage_sql_thd_waiting_until_delay,
9185   & stage_statistics,
9186   & stage_storing_result_in_query_cache,
9187   & stage_storing_row_into_queue,
9188   & stage_system_lock,
9189   & stage_update,
9190   & stage_updating,
9191   & stage_updating_main_table,
9192   & stage_updating_reference_tables,
9193   & stage_upgrading_lock,
9194   & stage_user_sleep,
9195   & stage_verifying_table,
9196   & stage_waiting_for_gtid_to_be_committed,
9197   & stage_waiting_for_handler_insert,
9198   & stage_waiting_for_handler_lock,
9199   & stage_waiting_for_handler_open,
9200   & stage_waiting_for_insert,
9201   & stage_waiting_for_master_to_send_event,
9202   & stage_waiting_for_master_update,
9203   & stage_waiting_for_relay_log_space,
9204   & stage_waiting_for_slave_mutex_on_exit,
9205   & stage_waiting_for_slave_thread_to_start,
9206   & stage_waiting_for_table_flush,
9207   & stage_waiting_for_query_cache_lock,
9208   & stage_waiting_for_the_next_event_in_relay_log,
9209   & stage_waiting_for_the_slave_thread_to_advance_position,
9210   & stage_waiting_to_finalize_termination,
9211   & stage_worker_waiting_for_its_turn_to_commit,
9212   & stage_worker_waiting_for_commit_parent,
9213   & stage_suspending,
9214   & stage_starting,
9215   & stage_waiting_for_no_channel_reference
9216 };
9217 
9218 PSI_socket_key key_socket_tcpip, key_socket_unix, key_socket_client_connection;
9219 
9220 static PSI_socket_info all_server_sockets[]=
9221 {
9222   { &key_socket_tcpip, "server_tcpip_socket", PSI_FLAG_GLOBAL},
9223   { &key_socket_unix, "server_unix_socket", PSI_FLAG_GLOBAL},
9224   { &key_socket_client_connection, "client_connection", 0}
9225 };
9226 #endif /* HAVE_PSI_INTERFACE */
9227 
9228 PSI_memory_key key_memory_locked_table_list;
9229 PSI_memory_key key_memory_locked_thread_list;
9230 PSI_memory_key key_memory_thd_transactions;
9231 PSI_memory_key key_memory_delegate;
9232 PSI_memory_key key_memory_acl_mem;
9233 PSI_memory_key key_memory_acl_memex;
9234 PSI_memory_key key_memory_acl_cache;
9235 PSI_memory_key key_memory_thd_main_mem_root;
9236 PSI_memory_key key_memory_help;
9237 PSI_memory_key key_memory_new_frm_mem;
9238 PSI_memory_key key_memory_table_share;
9239 PSI_memory_key key_memory_gdl;
9240 PSI_memory_key key_memory_table_triggers_list;
9241 PSI_memory_key key_memory_servers;
9242 PSI_memory_key key_memory_prepared_statement_map;
9243 PSI_memory_key key_memory_prepared_statement_main_mem_root;
9244 PSI_memory_key key_memory_protocol_rset_root;
9245 PSI_memory_key key_memory_warning_info_warn_root;
9246 PSI_memory_key key_memory_sp_cache;
9247 PSI_memory_key key_memory_sp_head_main_root;
9248 PSI_memory_key key_memory_sp_head_execute_root;
9249 PSI_memory_key key_memory_sp_head_call_root;
9250 PSI_memory_key key_memory_table_mapping_root;
9251 PSI_memory_key key_memory_quick_range_select_root;
9252 PSI_memory_key key_memory_quick_index_merge_root;
9253 PSI_memory_key key_memory_quick_ror_intersect_select_root;
9254 PSI_memory_key key_memory_quick_ror_union_select_root;
9255 PSI_memory_key key_memory_quick_group_min_max_select_root;
9256 PSI_memory_key key_memory_test_quick_select_exec;
9257 PSI_memory_key key_memory_prune_partitions_exec;
9258 PSI_memory_key key_memory_binlog_recover_exec;
9259 PSI_memory_key key_memory_blob_mem_storage;
9260 PSI_memory_key key_memory_NAMED_ILINK_name;
9261 PSI_memory_key key_memory_Sys_var_charptr_value;
9262 PSI_memory_key key_memory_queue_item;
9263 PSI_memory_key key_memory_THD_db;
9264 PSI_memory_key key_memory_user_var_entry;
9265 PSI_memory_key key_memory_Slave_job_group_group_relay_log_name;
9266 PSI_memory_key key_memory_Relay_log_info_group_relay_log_name;
9267 PSI_memory_key key_memory_binlog_cache_mngr;
9268 PSI_memory_key key_memory_Row_data_memory_memory;
9269 PSI_memory_key key_memory_Gtid_state_to_string;
9270 PSI_memory_key key_memory_Owned_gtids_to_string;
9271 PSI_memory_key key_memory_Sort_param_tmp_buffer;
9272 PSI_memory_key key_memory_Filesort_info_merge;
9273 PSI_memory_key key_memory_Filesort_info_record_pointers;
9274 PSI_memory_key key_memory_handler_errmsgs;
9275 PSI_memory_key key_memory_handlerton;
9276 PSI_memory_key key_memory_XID;
9277 PSI_memory_key key_memory_host_cache_hostname;
9278 PSI_memory_key key_memory_user_var_entry_value;
9279 PSI_memory_key key_memory_User_level_lock;
9280 PSI_memory_key key_memory_MYSQL_LOG_name;
9281 PSI_memory_key key_memory_TC_LOG_MMAP_pages;
9282 PSI_memory_key key_memory_my_bitmap_map;
9283 PSI_memory_key key_memory_QUICK_RANGE_SELECT_mrr_buf_desc;
9284 PSI_memory_key key_memory_Event_queue_element_for_exec_names;
9285 PSI_memory_key key_memory_my_str_malloc;
9286 PSI_memory_key key_memory_MYSQL_BIN_LOG_basename;
9287 PSI_memory_key key_memory_MYSQL_BIN_LOG_index;
9288 PSI_memory_key key_memory_MYSQL_RELAY_LOG_basename;
9289 PSI_memory_key key_memory_MYSQL_RELAY_LOG_index;
9290 PSI_memory_key key_memory_rpl_filter;
9291 PSI_memory_key key_memory_errmsgs;
9292 PSI_memory_key key_memory_Gis_read_stream_err_msg;
9293 PSI_memory_key key_memory_Geometry_objects_data;
9294 PSI_memory_key key_memory_MYSQL_LOCK;
9295 PSI_memory_key key_memory_Event_scheduler_scheduler_param;
9296 PSI_memory_key key_memory_Owned_gtids_sidno_to_hash;
9297 PSI_memory_key key_memory_Mutex_cond_array_Mutex_cond;
9298 PSI_memory_key key_memory_TABLE_RULE_ENT;
9299 PSI_memory_key key_memory_Rpl_info_table;
9300 PSI_memory_key key_memory_Rpl_info_file_buffer;
9301 PSI_memory_key key_memory_db_worker_hash_entry;
9302 PSI_memory_key key_memory_rpl_slave_check_temp_dir;
9303 PSI_memory_key key_memory_rpl_slave_command_buffer;
9304 PSI_memory_key key_memory_binlog_ver_1_event;
9305 PSI_memory_key key_memory_SLAVE_INFO;
9306 PSI_memory_key key_memory_binlog_pos;
9307 PSI_memory_key key_memory_HASH_ROW_ENTRY;
9308 PSI_memory_key key_memory_binlog_statement_buffer;
9309 PSI_memory_key key_memory_partition_syntax_buffer;
9310 PSI_memory_key key_memory_READ_INFO;
9311 PSI_memory_key key_memory_JOIN_CACHE;
9312 PSI_memory_key key_memory_TABLE_sort_io_cache;
9313 PSI_memory_key key_memory_frm;
9314 PSI_memory_key key_memory_Unique_sort_buffer;
9315 PSI_memory_key key_memory_Unique_merge_buffer;
9316 PSI_memory_key key_memory_TABLE;
9317 PSI_memory_key key_memory_frm_extra_segment_buff;
9318 PSI_memory_key key_memory_frm_form_pos;
9319 PSI_memory_key key_memory_frm_string;
9320 PSI_memory_key key_memory_LOG_name;
9321 PSI_memory_key key_memory_DATE_TIME_FORMAT;
9322 PSI_memory_key key_memory_DDL_LOG_MEMORY_ENTRY;
9323 PSI_memory_key key_memory_ST_SCHEMA_TABLE;
9324 PSI_memory_key key_memory_ignored_db;
9325 PSI_memory_key key_memory_PROFILE;
9326 PSI_memory_key key_memory_st_mysql_plugin_dl;
9327 PSI_memory_key key_memory_st_mysql_plugin;
9328 PSI_memory_key key_memory_global_system_variables;
9329 PSI_memory_key key_memory_THD_variables;
9330 PSI_memory_key key_memory_Security_context;
9331 PSI_memory_key key_memory_shared_memory_name;
9332 PSI_memory_key key_memory_bison_stack;
9333 PSI_memory_key key_memory_THD_handler_tables_hash;
9334 PSI_memory_key key_memory_hash_index_key_buffer;
9335 PSI_memory_key key_memory_dboptions_hash;
9336 PSI_memory_key key_memory_user_conn;
9337 PSI_memory_key key_memory_LOG_POS_COORD;
9338 PSI_memory_key key_memory_XID_STATE;
9339 PSI_memory_key key_memory_MPVIO_EXT_auth_info;
9340 PSI_memory_key key_memory_opt_bin_logname;
9341 PSI_memory_key key_memory_Query_cache;
9342 PSI_memory_key key_memory_READ_RECORD_cache;
9343 PSI_memory_key key_memory_Quick_ranges;
9344 PSI_memory_key key_memory_File_query_log_name;
9345 PSI_memory_key key_memory_Table_trigger_dispatcher;
9346 PSI_memory_key key_memory_show_slave_status_io_gtid_set;
9347 PSI_memory_key key_memory_write_set_extraction;
9348 PSI_memory_key key_memory_thd_timer;
9349 PSI_memory_key key_memory_THD_Session_tracker;
9350 PSI_memory_key key_memory_THD_Session_sysvar_resource_manager;
9351 PSI_memory_key key_memory_get_all_tables;
9352 PSI_memory_key key_memory_fill_schema_schemata;
9353 PSI_memory_key key_memory_native_functions;
9354 PSI_memory_key key_memory_JSON;
9355 
9356 #ifdef HAVE_PSI_INTERFACE
9357 static PSI_memory_info all_server_memory[]=
9358 {
9359   { &key_memory_locked_table_list, "Locked_tables_list::m_locked_tables_root", 0},
9360   { &key_memory_locked_thread_list, "display_table_locks", PSI_FLAG_THREAD},
9361   { &key_memory_thd_transactions, "THD::transactions::mem_root", PSI_FLAG_THREAD},
9362   { &key_memory_delegate, "Delegate::memroot", 0},
9363   { &key_memory_acl_mem, "sql_acl_mem", PSI_FLAG_GLOBAL},
9364   { &key_memory_acl_memex, "sql_acl_memex", PSI_FLAG_GLOBAL},
9365   { &key_memory_acl_cache, "acl_cache", PSI_FLAG_GLOBAL},
9366   { &key_memory_thd_main_mem_root, "thd::main_mem_root", PSI_FLAG_THREAD},
9367   { &key_memory_help, "help", 0},
9368   { &key_memory_new_frm_mem, "new_frm_mem", 0},
9369   { &key_memory_table_share, "TABLE_SHARE::mem_root", PSI_FLAG_GLOBAL}, /* table definition cache */
9370   { &key_memory_gdl, "gdl", 0},
9371   { &key_memory_table_triggers_list, "Table_triggers_list", 0},
9372   { &key_memory_servers, "servers", 0},
9373   { &key_memory_prepared_statement_map, "Prepared_statement_map", PSI_FLAG_THREAD},
9374   { &key_memory_prepared_statement_main_mem_root, "Prepared_statement::main_mem_root", PSI_FLAG_THREAD},
9375   { &key_memory_protocol_rset_root, "Protocol_local::m_rset_root", PSI_FLAG_THREAD},
9376   { &key_memory_warning_info_warn_root, "Warning_info::m_warn_root", PSI_FLAG_THREAD},
9377   { &key_memory_sp_cache, "THD::sp_cache", 0},
9378   { &key_memory_sp_head_main_root, "sp_head::main_mem_root", 0},
9379   { &key_memory_sp_head_execute_root, "sp_head::execute_mem_root", PSI_FLAG_THREAD},
9380   { &key_memory_sp_head_call_root, "sp_head::call_mem_root", PSI_FLAG_THREAD},
9381   { &key_memory_table_mapping_root, "table_mapping::m_mem_root", 0},
9382   { &key_memory_quick_range_select_root, "QUICK_RANGE_SELECT::alloc", PSI_FLAG_THREAD},
9383   { &key_memory_quick_index_merge_root, "QUICK_INDEX_MERGE_SELECT::alloc", PSI_FLAG_THREAD},
9384   { &key_memory_quick_ror_intersect_select_root, "QUICK_ROR_INTERSECT_SELECT::alloc", PSI_FLAG_THREAD},
9385   { &key_memory_quick_ror_union_select_root, "QUICK_ROR_UNION_SELECT::alloc", PSI_FLAG_THREAD},
9386   { &key_memory_quick_group_min_max_select_root, "QUICK_GROUP_MIN_MAX_SELECT::alloc", PSI_FLAG_THREAD},
9387   { &key_memory_test_quick_select_exec, "test_quick_select", PSI_FLAG_THREAD},
9388   { &key_memory_prune_partitions_exec, "prune_partitions::exec", 0},
9389   { &key_memory_binlog_recover_exec, "MYSQL_BIN_LOG::recover", 0},
9390   { &key_memory_blob_mem_storage, "Blob_mem_storage::storage", 0},
9391 
9392   { &key_memory_NAMED_ILINK_name, "NAMED_ILINK::name", 0},
9393   { &key_memory_String_value, "String::value", 0},
9394   { &key_memory_Sys_var_charptr_value, "Sys_var_charptr::value", 0},
9395   { &key_memory_queue_item, "Queue::queue_item", 0},
9396   { &key_memory_THD_db, "THD::db", 0},
9397   { &key_memory_user_var_entry, "user_var_entry", 0},
9398   { &key_memory_Slave_job_group_group_relay_log_name, "Slave_job_group::group_relay_log_name", 0},
9399   { &key_memory_Relay_log_info_group_relay_log_name, "Relay_log_info::group_relay_log_name", 0},
9400   { &key_memory_binlog_cache_mngr, "binlog_cache_mngr", 0},
9401   { &key_memory_Row_data_memory_memory, "Row_data_memory::memory", 0},
9402 
9403   { &key_memory_Gtid_set_to_string, "Gtid_set::to_string", 0},
9404   { &key_memory_Gtid_state_to_string, "Gtid_state::to_string", 0},
9405   { &key_memory_Owned_gtids_to_string, "Owned_gtids::to_string", 0},
9406   { &key_memory_log_event, "Log_event", 0},
9407   { &key_memory_Incident_log_event_message, "Incident_log_event::message", 0},
9408   { &key_memory_Rows_query_log_event_rows_query, "Rows_query_log_event::rows_query", 0},
9409 
9410   { &key_memory_Sort_param_tmp_buffer, "Sort_param::tmp_buffer", 0},
9411   { &key_memory_Filesort_info_merge, "Filesort_info::merge", 0},
9412   { &key_memory_Filesort_info_record_pointers, "Filesort_info::record_pointers", 0},
9413   { &key_memory_Filesort_buffer_sort_keys, "Filesort_buffer::sort_keys", 0},
9414   { &key_memory_handler_errmsgs, "handler::errmsgs", 0},
9415   { &key_memory_handlerton, "handlerton", 0},
9416   { &key_memory_XID, "XID", 0},
9417   { &key_memory_host_cache_hostname, "host_cache::hostname", 0},
9418   { &key_memory_user_var_entry_value, "user_var_entry::value", 0},
9419   { &key_memory_User_level_lock, "User_level_lock", 0},
9420   { &key_memory_MYSQL_LOG_name, "MYSQL_LOG::name", 0},
9421   { &key_memory_TC_LOG_MMAP_pages, "TC_LOG_MMAP::pages", 0},
9422   { &key_memory_my_bitmap_map, "my_bitmap_map", 0},
9423   { &key_memory_QUICK_RANGE_SELECT_mrr_buf_desc, "QUICK_RANGE_SELECT::mrr_buf_desc", 0},
9424   { &key_memory_Event_queue_element_for_exec_names, "Event_queue_element_for_exec::names", 0},
9425   { &key_memory_my_str_malloc, "my_str_malloc", 0},
9426   { &key_memory_MYSQL_BIN_LOG_basename, "MYSQL_BIN_LOG::basename", 0},
9427   { &key_memory_MYSQL_BIN_LOG_index, "MYSQL_BIN_LOG::index", 0},
9428   { &key_memory_MYSQL_RELAY_LOG_basename, "MYSQL_RELAY_LOG::basename", 0},
9429   { &key_memory_MYSQL_RELAY_LOG_index, "MYSQL_RELAY_LOG::index", 0},
9430   { &key_memory_rpl_filter, "rpl_filter memory", 0},
9431   { &key_memory_errmsgs, "errmsgs", 0},
9432   { &key_memory_Gis_read_stream_err_msg, "Gis_read_stream::err_msg", 0},
9433   { &key_memory_Geometry_objects_data, "Geometry::ptr_and_wkb_data", 0},
9434   { &key_memory_MYSQL_LOCK, "MYSQL_LOCK", 0},
9435   { &key_memory_NET_buff, "NET::buff", 0},
9436   { &key_memory_NET_compress_packet, "NET::compress_packet", 0},
9437   { &key_memory_Event_scheduler_scheduler_param, "Event_scheduler::scheduler_param", 0},
9438   { &key_memory_Gtid_set_Interval_chunk, "Gtid_set::Interval_chunk", 0},
9439   { &key_memory_Owned_gtids_sidno_to_hash, "Owned_gtids::sidno_to_hash", 0},
9440   { &key_memory_Sid_map_Node, "Sid_map::Node", 0},
9441   { &key_memory_Gtid_state_group_commit_sidno, "Gtid_state::group_commit_sidno_locks", 0},
9442   { &key_memory_Mutex_cond_array_Mutex_cond, "Mutex_cond_array::Mutex_cond", 0},
9443   { &key_memory_TABLE_RULE_ENT, "TABLE_RULE_ENT", 0},
9444 
9445   { &key_memory_Rpl_info_table, "Rpl_info_table", 0},
9446   { &key_memory_Rpl_info_file_buffer, "Rpl_info_file::buffer", 0},
9447   { &key_memory_db_worker_hash_entry, "db_worker_hash_entry", 0},
9448   { &key_memory_rpl_slave_check_temp_dir, "rpl_slave::check_temp_dir", 0},
9449   { &key_memory_rpl_slave_command_buffer, "rpl_slave::command_buffer", 0},
9450   { &key_memory_binlog_ver_1_event, "binlog_ver_1_event", 0},
9451   { &key_memory_SLAVE_INFO, "SLAVE_INFO", 0},
9452   { &key_memory_binlog_pos, "binlog_pos", 0},
9453   { &key_memory_HASH_ROW_ENTRY, "HASH_ROW_ENTRY", 0},
9454   { &key_memory_binlog_statement_buffer, "binlog_statement_buffer", 0},
9455   { &key_memory_partition_syntax_buffer, "partition_syntax_buffer", 0},
9456   { &key_memory_READ_INFO, "READ_INFO", 0},
9457   { &key_memory_JOIN_CACHE, "JOIN_CACHE", 0},
9458   { &key_memory_TABLE_sort_io_cache, "TABLE::sort_io_cache", 0},
9459   { &key_memory_frm, "frm", 0},
9460   { &key_memory_Unique_sort_buffer, "Unique::sort_buffer", 0},
9461   { &key_memory_Unique_merge_buffer, "Unique::merge_buffer", 0},
9462   { &key_memory_TABLE, "TABLE", PSI_FLAG_GLOBAL}, /* Table cache */
9463   { &key_memory_frm_extra_segment_buff, "frm::extra_segment_buff", 0},
9464   { &key_memory_frm_form_pos, "frm::form_pos", 0},
9465   { &key_memory_frm_string, "frm::string", 0},
9466   { &key_memory_LOG_name, "LOG_name", 0},
9467   { &key_memory_DATE_TIME_FORMAT, "DATE_TIME_FORMAT", 0},
9468   { &key_memory_DDL_LOG_MEMORY_ENTRY, "DDL_LOG_MEMORY_ENTRY", 0},
9469   { &key_memory_ST_SCHEMA_TABLE, "ST_SCHEMA_TABLE", 0},
9470   { &key_memory_ignored_db, "ignored_db", 0},
9471   { &key_memory_PROFILE, "PROFILE", 0},
9472   { &key_memory_global_system_variables, "global_system_variables", 0},
9473   { &key_memory_THD_variables, "THD::variables", 0},
9474   { &key_memory_Security_context, "Security_context", 0},
9475   { &key_memory_shared_memory_name, "Shared_memory_name", 0},
9476   { &key_memory_bison_stack, "bison_stack", 0},
9477   { &key_memory_THD_handler_tables_hash, "THD::handler_tables_hash", 0},
9478   { &key_memory_hash_index_key_buffer, "hash_index_key_buffer", 0},
9479   { &key_memory_dboptions_hash, "dboptions_hash", 0},
9480   { &key_memory_user_conn, "user_conn", 0},
9481   { &key_memory_LOG_POS_COORD, "LOG_POS_COORD", 0},
9482   { &key_memory_XID_STATE, "XID_STATE", 0},
9483   { &key_memory_MPVIO_EXT_auth_info, "MPVIO_EXT::auth_info", 0},
9484   { &key_memory_opt_bin_logname, "opt_bin_logname", 0},
9485   { &key_memory_Query_cache, "Query_cache", PSI_FLAG_GLOBAL},
9486   { &key_memory_READ_RECORD_cache, "READ_RECORD_cache", 0},
9487   { &key_memory_Quick_ranges, "Quick_ranges", 0},
9488   { &key_memory_File_query_log_name, "File_query_log::name", 0},
9489   { &key_memory_Table_trigger_dispatcher, "Table_trigger_dispatcher::m_mem_root", 0},
9490   { &key_memory_thd_timer, "thd_timer", 0},
9491   { &key_memory_THD_Session_tracker, "THD::Session_tracker", 0},
9492   { &key_memory_THD_Session_sysvar_resource_manager, "THD::Session_sysvar_resource_manager", 0},
9493   { &key_memory_show_slave_status_io_gtid_set, "show_slave_status_io_gtid_set", 0},
9494   { &key_memory_write_set_extraction, "write_set_extraction", 0},
9495   { &key_memory_get_all_tables, "get_all_tables", 0},
9496   { &key_memory_fill_schema_schemata, "fill_schema_schemata", 0},
9497   { &key_memory_native_functions, "native_functions", PSI_FLAG_GLOBAL},
9498   { &key_memory_JSON, "JSON", 0 },
9499 };
9500 
9501 /* TODO: find a good header */
9502 extern "C" void init_client_psi_keys(void);
9503 
9504 /**
9505   Initialise all the performance schema instrumentation points
9506   used by the server.
9507 */
init_server_psi_keys(void)9508 void init_server_psi_keys(void)
9509 {
9510   const char* category= "sql";
9511   int count;
9512 
9513   count= array_elements(all_server_mutexes);
9514   mysql_mutex_register(category, all_server_mutexes, count);
9515 
9516   count= array_elements(all_server_rwlocks);
9517   mysql_rwlock_register(category, all_server_rwlocks, count);
9518 
9519   count= array_elements(all_server_conds);
9520   mysql_cond_register(category, all_server_conds, count);
9521 
9522   count= array_elements(all_server_threads);
9523   mysql_thread_register(category, all_server_threads, count);
9524 
9525   count= array_elements(all_server_files);
9526   mysql_file_register(category, all_server_files, count);
9527 
9528   count= array_elements(all_server_stages);
9529   mysql_stage_register(category, all_server_stages, count);
9530 
9531   count= array_elements(all_server_sockets);
9532   mysql_socket_register(category, all_server_sockets, count);
9533 
9534   count= array_elements(all_server_memory);
9535   mysql_memory_register(category, all_server_memory, count);
9536 
9537 #ifdef HAVE_PSI_STATEMENT_INTERFACE
9538   init_sql_statement_info();
9539   count= array_elements(sql_statement_info);
9540   mysql_statement_register(category, sql_statement_info, count);
9541 
9542   init_sp_psi_keys();
9543 
9544   init_scheduler_psi_keys();
9545 
9546   category= "com";
9547   init_com_statement_info();
9548 
9549   /*
9550     Register [0 .. COM_QUERY - 1] as "statement/com/..."
9551   */
9552   count= (int) COM_QUERY;
9553   mysql_statement_register(category, com_statement_info, count);
9554 
9555   /*
9556     Register [COM_QUERY + 1 .. COM_END] as "statement/com/..."
9557   */
9558   count= (int) COM_END - (int) COM_QUERY;
9559   mysql_statement_register(category, & com_statement_info[(int) COM_QUERY + 1], count);
9560 
9561   category= "abstract";
9562   /*
9563     Register [COM_QUERY] as "statement/abstract/com_query"
9564   */
9565   mysql_statement_register(category, & com_statement_info[(int) COM_QUERY], 1);
9566 
9567   /*
9568     When a new packet is received,
9569     it is instrumented as "statement/abstract/new_packet".
9570     Based on the packet type found, it later mutates to the
9571     proper narrow type, for example
9572     "statement/abstract/query" or "statement/com/ping".
9573     In cases of "statement/abstract/query", SQL queries are given to
9574     the parser, which mutates the statement type to an even more
9575     narrow classification, for example "statement/sql/select".
9576   */
9577   stmt_info_new_packet.m_key= 0;
9578   stmt_info_new_packet.m_name= "new_packet";
9579   stmt_info_new_packet.m_flags= PSI_FLAG_MUTABLE;
9580   mysql_statement_register(category, &stmt_info_new_packet, 1);
9581 
9582   /*
9583     Statements processed from the relay log are initially instrumented as
9584     "statement/abstract/relay_log". The parser will mutate the statement type to
9585     a more specific classification, for example "statement/sql/insert".
9586   */
9587   stmt_info_rpl.m_key= 0;
9588   stmt_info_rpl.m_name= "relay_log";
9589   stmt_info_rpl.m_flags= PSI_FLAG_MUTABLE;
9590   mysql_statement_register(category, &stmt_info_rpl, 1);
9591 #endif
9592 
9593   /* Common client and server code. */
9594   init_client_psi_keys();
9595   /* Vio */
9596   init_vio_psi_keys();
9597 }
9598 
9599 #endif /* HAVE_PSI_INTERFACE */
9600 
9601 #if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
9602 // update_named_pipe_full_access_group returns false on success, true on failure
update_named_pipe_full_access_group(const char * new_group_name)9603 bool update_named_pipe_full_access_group(const char *new_group_name)
9604 {
9605   if (named_pipe_acceptor) {
9606     return named_pipe_listener->update_named_pipe_full_access_group(
9607       new_group_name);
9608   }
9609   return true;
9610 }
9611 
9612 #endif  /* _WIN32 && !EMBEDDED_LIBRARY */
9613 
9614 
set_mysqld_opt_tracking_mode()9615 void set_mysqld_opt_tracking_mode()
9616 {
9617   my_atomic_store64(&mysql_bin_log.m_dependency_tracker.m_opt_tracking_mode,
9618           static_cast<int64>(mysql_bin_log.m_dependency_tracker.m_opt_tracking_mode_value));
9619 }
9620