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