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