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