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