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