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