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