1/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
2 Copyright (c) 2008, 2017, MariaDB Corporation.
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 "sql_plugin.h" // Includes mariadb.h
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" // path_starts_from_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"
44#include "sql_test.h" // mysql_print_status
45#include "item_create.h" // item_create_cleanup, item_create_init
46#include "sql_servers.h" // servers_free, servers_init
47#include "init.h" // unireg_init
48#include "derror.h" // init_errmessage
49#include "des_key_file.h" // load_des_key_file
50#include "sql_manager.h" // stop_handle_manager, start_handle_manager
51#include "sql_expression_cache.h" // subquery_cache_miss, subquery_cache_hit
52#include "sys_vars_shared.h"
53
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 "client_settings.h"
62#include "repl_failsafe.h"
63#include <sql_common.h>
64#include <my_stacktrace.h>
65#include "mysqld_suffix.h"
66#include "mysys_err.h"
67#include "events.h"
68#include "sql_audit.h"
69#include "probes_mysql.h"
70#include "scheduler.h"
71#include <waiting_threads.h>
72#include "debug_sync.h"
73#include "wsrep_mysqld.h"
74#include "wsrep_var.h"
75#include "wsrep_thd.h"
76#include "wsrep_sst.h"
77#include "proxy_protocol.h"
78
79#include "sql_callback.h"
80#include "threadpool.h"
81
82#ifdef HAVE_OPENSSL
83#include <ssl_compat.h>
84#endif
85
86#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
87#include "../storage/perfschema/pfs_server.h"
88#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
89#include <mysql/psi/mysql_idle.h>
90#include <mysql/psi/mysql_socket.h>
91#include <mysql/psi/mysql_statement.h>
92#include "mysql_com_server.h"
93
94#include "keycaches.h"
95#include "../storage/myisam/ha_myisam.h"
96#include "set_var.h"
97
98#include "rpl_injector.h"
99#include "semisync_master.h"
100#include "semisync_slave.h"
101
102#include "transaction.h"
103
104#ifdef HAVE_SYS_PRCTL_H
105#include <sys/prctl.h>
106#endif
107
108#include <thr_alarm.h>
109#include <ft_global.h>
110#include <errmsg.h>
111#include "sp_rcontext.h"
112#include "sp_cache.h"
113#include "sql_reload.h" // reload_acl_and_cache
114#include "pcre.h"
115
116#ifdef HAVE_POLL_H
117#include <poll.h>
118#endif
119
120#include <my_service_manager.h>
121
122#define mysqld_charset &my_charset_latin1
123
124/* We have HAVE_valgrind below as this speeds up the shutdown of MySQL */
125
126#if defined(SIGNALS_DONT_BREAK_READ) || defined(HAVE_valgrind) && defined(__linux__)
127#define HAVE_CLOSE_SERVER_SOCK 1
128#endif
129
130extern "C" { // Because of SCO 3.2V4.2
131#include <sys/stat.h>
132#ifndef __GNU_LIBRARY__
133#define __GNU_LIBRARY__ // Skip warnings in getopt.h
134#endif
135#include <my_getopt.h>
136#ifdef HAVE_SYSENT_H
137#include <sysent.h>
138#endif
139#ifdef HAVE_PWD_H
140#include <pwd.h> // For struct passwd
141#endif
142#include <my_net.h>
143
144#if !defined(__WIN__)
145#include <sys/resource.h>
146#ifdef HAVE_SYS_UN_H
147#include <sys/un.h>
148#endif
149#ifdef HAVE_SELECT_H
150#include <select.h>
151#endif
152#ifdef HAVE_SYS_SELECT_H
153#include <sys/select.h>
154#endif
155#include <sys/utsname.h>
156#endif /* __WIN__ */
157
158#include <my_libwrap.h>
159
160#ifdef HAVE_SYS_MMAN_H
161#include <sys/mman.h>
162#endif
163
164#ifdef __WIN__
165#include <crtdbg.h>
166#endif
167
168#ifdef HAVE_SOLARIS_LARGE_PAGES
169#include <sys/mman.h>
170#if defined(__sun__) && defined(__GNUC__) && defined(__cplusplus) \
171 && defined(_XOPEN_SOURCE)
172extern int getpagesizes(size_t *, int);
173extern int getpagesizes2(size_t *, int);
174extern int memcntl(caddr_t, size_t, int, caddr_t, int, int);
175#endif /* __sun__ ... */
176#endif /* HAVE_SOLARIS_LARGE_PAGES */
177
178#ifdef _AIX41
179int initgroups(const char *,unsigned int);
180#endif
181
182#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H) && !defined(HAVE_FEDISABLEEXCEPT)
183#include <ieeefp.h>
184#ifdef HAVE_FP_EXCEPT // Fix type conflict
185typedef fp_except fp_except_t;
186#endif
187#endif /* __FreeBSD__ && HAVE_IEEEFP_H && !HAVE_FEDISABLEEXCEPT */
188#ifdef HAVE_SYS_FPU_H
189/* for IRIX to use set_fpc_csr() */
190#include <sys/fpu.h>
191#endif
192#ifdef HAVE_FPU_CONTROL_H
193#include <fpu_control.h>
194#endif
195#if defined(__i386__) && !defined(HAVE_FPU_CONTROL_H)
196# define fpu_control_t unsigned int
197# define _FPU_EXTENDED 0x300
198# define _FPU_DOUBLE 0x200
199# if defined(__GNUC__) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590)
200# define _FPU_GETCW(cw) asm volatile ("fnstcw %0" : "=m" (*&cw))
201# define _FPU_SETCW(cw) asm volatile ("fldcw %0" : : "m" (*&cw))
202# else
203# define _FPU_GETCW(cw) (cw= 0)
204# define _FPU_SETCW(cw)
205# endif
206#endif
207
208#ifndef HAVE_FCNTL
209#define fcntl(X,Y,Z) 0
210#endif
211
212extern "C" my_bool reopen_fstreams(const char *filename,
213 FILE *outstream, FILE *errstream);
214
215inline void setup_fpu()
216{
217#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H) && !defined(HAVE_FEDISABLEEXCEPT)
218 /* We can't handle floating point exceptions with threads, so disable
219 this on freebsd
220 Don't fall for overflow, underflow,divide-by-zero or loss of precision.
221 fpsetmask() is deprecated in favor of fedisableexcept() in C99.
222 */
223#if defined(FP_X_DNML)
224 fpsetmask(~(FP_X_INV | FP_X_DNML | FP_X_OFL | FP_X_UFL | FP_X_DZ |
225 FP_X_IMP));
226#else
227 fpsetmask(~(FP_X_INV | FP_X_OFL | FP_X_UFL | FP_X_DZ |
228 FP_X_IMP));
229#endif /* FP_X_DNML */
230#endif /* __FreeBSD__ && HAVE_IEEEFP_H && !HAVE_FEDISABLEEXCEPT */
231
232#ifdef HAVE_FEDISABLEEXCEPT
233 fedisableexcept(FE_ALL_EXCEPT);
234#endif
235
236#ifdef HAVE_FESETROUND
237 /* Set FPU rounding mode to "round-to-nearest" */
238 fesetround(FE_TONEAREST);
239#endif /* HAVE_FESETROUND */
240
241 /*
242 x86 (32-bit) requires FPU precision to be explicitly set to 64 bit
243 (double precision) for portable results of floating point operations.
244 However, there is no need to do so if compiler is using SSE2 for floating
245 point, double values will be stored and processed in 64 bits anyway.
246 */
247#if defined(__i386__) && !defined(__SSE2_MATH__)
248#if defined(_WIN32)
249#if !defined(_WIN64)
250 _control87(_PC_53, MCW_PC);
251#endif /* !_WIN64 */
252#else /* !_WIN32 */
253 fpu_control_t cw;
254 _FPU_GETCW(cw);
255 cw= (cw & ~_FPU_EXTENDED) | _FPU_DOUBLE;
256 _FPU_SETCW(cw);
257#endif /* _WIN32 && */
258#endif /* __i386__ */
259
260#if defined(__sgi) && defined(HAVE_SYS_FPU_H)
261 /* Enable denormalized DOUBLE values support for IRIX */
262 union fpc_csr n;
263 n.fc_word = get_fpc_csr();
264 n.fc_struct.flush = 0;
265 set_fpc_csr(n.fc_word);
266#endif
267}
268
269} /* cplusplus */
270
271#define MYSQL_KILL_SIGNAL SIGTERM
272
273#include <my_pthread.h> // For thr_setconcurency()
274
275#ifdef SOLARIS
276extern "C" int gethostname(char *name, int namelen);
277#endif
278
279extern "C" sig_handler handle_fatal_signal(int sig);
280
281#if defined(__linux__)
282#define ENABLE_TEMP_POOL 1
283#else
284#define ENABLE_TEMP_POOL 0
285#endif
286
287int init_io_cache_encryption();
288
289/* Constants */
290
291#include <welcome_copyright_notice.h> // ORACLE_WELCOME_COPYRIGHT_NOTICE
292
293const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"};
294
295static const char *tc_heuristic_recover_names[]=
296{
297 "OFF", "COMMIT", "ROLLBACK", NullS
298};
299static TYPELIB tc_heuristic_recover_typelib=
300{
301 array_elements(tc_heuristic_recover_names)-1,"",
302 tc_heuristic_recover_names, NULL
303};
304
305const char *first_keyword= "first";
306const char *my_localhost= "localhost", *delayed_user= "DELAYED";
307
308bool opt_large_files= sizeof(my_off_t) > 4;
309static my_bool opt_autocommit; ///< for --autocommit command-line option
310
311/*
312 Used with --help for detailed option
313*/
314static my_bool opt_verbose= 0;
315
316/* Timer info to be used by the SQL layer */
317MY_TIMER_INFO sys_timer_info;
318
319/* static variables */
320
321#ifdef HAVE_PSI_INTERFACE
322#if (defined(_WIN32) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY)
323static PSI_thread_key key_thread_handle_con_namedpipes;
324static PSI_cond_key key_COND_handler_count;
325#endif /* _WIN32 || HAVE_SMEM && !EMBEDDED_LIBRARY */
326
327#if defined(HAVE_SMEM) && !defined(EMBEDDED_LIBRARY)
328static PSI_thread_key key_thread_handle_con_sharedmem;
329#endif /* HAVE_SMEM && !EMBEDDED_LIBRARY */
330
331#if (defined(_WIN32) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY)
332static PSI_thread_key key_thread_handle_con_sockets;
333#endif /* _WIN32 || HAVE_SMEM && !EMBEDDED_LIBRARY */
334
335#ifdef __WIN__
336static PSI_thread_key key_thread_handle_shutdown;
337#endif /* __WIN__ */
338
339#ifdef HAVE_OPENSSL10
340static PSI_rwlock_key key_rwlock_openssl;
341#endif
342#endif /* HAVE_PSI_INTERFACE */
343
344#ifdef HAVE_NPTL
345volatile sig_atomic_t ld_assume_kernel_is_set= 0;
346#endif
347
348/**
349 Statement instrumentation key for replication.
350*/
351#ifdef HAVE_PSI_STATEMENT_INTERFACE
352PSI_statement_info stmt_info_rpl;
353#endif
354
355/* the default log output is log tables */
356static bool lower_case_table_names_used= 0;
357static bool max_long_data_size_used= false;
358static bool volatile select_thread_in_use, signal_thread_in_use;
359static volatile bool ready_to_exit;
360static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0;
361static my_bool opt_short_log_format= 0, opt_silent_startup= 0;
362bool my_disable_leak_check= false;
363
364uint kill_cached_threads;
365static uint wake_thread;
366ulong max_used_connections;
367volatile ulong cached_thread_count= 0;
368static char *mysqld_user, *mysqld_chroot;
369static char *default_character_set_name;
370static char *character_set_filesystem_name;
371static char *lc_messages;
372static char *lc_time_names_name;
373char *my_bind_addr_str;
374static char *default_collation_name;
375char *default_storage_engine, *default_tmp_storage_engine;
376char *enforced_storage_engine=NULL;
377char *gtid_pos_auto_engines;
378plugin_ref *opt_gtid_pos_auto_plugins;
379static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME;
380static I_List<CONNECT> thread_cache;
381static bool binlog_format_used= false;
382LEX_STRING opt_init_connect, opt_init_slave;
383mysql_cond_t COND_thread_cache;
384static mysql_cond_t COND_flush_thread_cache;
385mysql_cond_t COND_slave_background;
386static DYNAMIC_ARRAY all_options;
387static longlong start_memory_used;
388
389/* Global variables */
390
391bool opt_bin_log, opt_bin_log_used=0, opt_ignore_builtin_innodb= 0;
392bool opt_bin_log_compress;
393uint opt_bin_log_compress_min_len;
394my_bool opt_log, debug_assert_if_crashed_table= 0, opt_help= 0;
395my_bool debug_assert_on_not_freed_memory= 0;
396my_bool disable_log_notes, opt_support_flashback= 0;
397static my_bool opt_abort;
398ulonglong log_output_options;
399my_bool opt_userstat_running;
400bool opt_error_log= IF_WIN(1,0);
401bool opt_disable_networking=0, opt_skip_show_db=0;
402bool opt_skip_name_resolve=0;
403my_bool opt_character_set_client_handshake= 1;
404bool opt_endinfo, using_udf_functions;
405my_bool locked_in_memory;
406bool opt_using_transactions;
407bool volatile abort_loop;
408bool volatile shutdown_in_progress;
409uint volatile global_disable_checkpoint;
410#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
411ulong slow_start_timeout;
412#endif
413/*
414 True if the bootstrap thread is running. Protected by LOCK_start_thread.
415 Used in bootstrap() function to determine if the bootstrap thread
416 has completed. Note, that we can't use 'thread_count' instead,
417 since in 5.1, in presence of the Event Scheduler, there may be
418 event threads running in parallel, so it's impossible to know
419 what value of 'thread_count' is a sign of completion of the
420 bootstrap thread.
421
422 At the same time, we can't start the event scheduler after
423 bootstrap either, since we want to be able to process event-related
424 SQL commands in the init file and in --bootstrap mode.
425*/
426bool volatile in_bootstrap= FALSE;
427/**
428 @brief 'grant_option' is used to indicate if privileges needs
429 to be checked, in which case the lock, LOCK_grant, is used
430 to protect access to the grant table.
431 @note This flag is dropped in 5.1
432 @see grant_init()
433 */
434bool volatile grant_option;
435
436my_bool opt_skip_slave_start = 0; ///< If set, slave is not autostarted
437my_bool opt_reckless_slave = 0;
438my_bool opt_enable_named_pipe= 0;
439my_bool opt_local_infile, opt_slave_compressed_protocol;
440my_bool opt_safe_user_create = 0;
441my_bool opt_show_slave_auth_info;
442my_bool opt_log_slave_updates= 0;
443my_bool opt_replicate_annotate_row_events= 0;
444my_bool opt_mysql56_temporal_format=0, strict_password_validation= 1;
445my_bool opt_explicit_defaults_for_timestamp= 0;
446char *opt_slave_skip_errors;
447char *opt_slave_transaction_retry_errors;
448
449/*
450 Legacy global handlerton. These will be removed (please do not add more).
451*/
452handlerton *heap_hton;
453handlerton *myisam_hton;
454handlerton *partition_hton;
455
456my_bool read_only= 0, opt_readonly= 0;
457my_bool use_temp_pool, relay_log_purge;
458my_bool relay_log_recovery;
459my_bool opt_sync_frm, opt_allow_suspicious_udfs;
460my_bool opt_secure_auth= 0;
461char* opt_secure_file_priv;
462my_bool lower_case_file_system= 0;
463my_bool opt_large_pages= 0;
464my_bool opt_super_large_pages= 0;
465my_bool opt_myisam_use_mmap= 0;
466uint opt_large_page_size= 0;
467#if defined(ENABLED_DEBUG_SYNC)
468MYSQL_PLUGIN_IMPORT uint opt_debug_sync_timeout= 0;
469#endif /* defined(ENABLED_DEBUG_SYNC) */
470my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
471ulong opt_replicate_events_marked_for_skip;
472
473/*
474 True if there is at least one per-hour limit for some user, so we should
475 check them before each query (and possibly reset counters when hour is
476 changed). False otherwise.
477*/
478volatile bool mqh_used = 0;
479my_bool opt_noacl;
480my_bool sp_automatic_privileges= 1;
481
482ulong opt_binlog_rows_event_max_size;
483my_bool opt_master_verify_checksum= 0;
484my_bool opt_slave_sql_verify_checksum= 1;
485const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS};
486volatile sig_atomic_t calling_initgroups= 0; /**< Used in SIGSEGV handler. */
487uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
488uint mysqld_extra_port;
489uint mysqld_port_timeout;
490ulong delay_key_write_options;
491uint protocol_version;
492uint lower_case_table_names;
493ulong tc_heuristic_recover= 0;
494int32 thread_count, service_thread_count;
495int32 slave_open_temp_tables;
496ulong thread_created;
497ulong back_log, connect_timeout, concurrency, server_id;
498ulong what_to_log;
499ulong slow_launch_time;
500ulong open_files_limit, max_binlog_size;
501ulong slave_trans_retries;
502ulong slave_trans_retry_interval;
503uint slave_net_timeout;
504ulong slave_exec_mode_options;
505ulong slave_run_triggers_for_rbr= 0;
506ulong slave_ddl_exec_mode_options= SLAVE_EXEC_MODE_IDEMPOTENT;
507ulonglong slave_type_conversions_options;
508ulong thread_cache_size=0;
509ulonglong binlog_cache_size=0;
510ulonglong binlog_file_cache_size=0;
511ulonglong max_binlog_cache_size=0;
512ulong slave_max_allowed_packet= 0;
513ulonglong binlog_stmt_cache_size=0;
514ulonglong max_binlog_stmt_cache_size=0;
515ulonglong query_cache_size=0;
516ulong query_cache_limit=0;
517ulong executed_events=0;
518query_id_t global_query_id;
519ulong aborted_threads, aborted_connects;
520ulong delayed_insert_timeout, delayed_insert_limit, delayed_queue_size;
521ulong delayed_insert_threads, delayed_insert_writes, delayed_rows_in_use;
522ulong delayed_insert_errors,flush_time;
523ulong specialflag=0;
524ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
525ulong binlog_stmt_cache_use= 0, binlog_stmt_cache_disk_use= 0;
526ulong max_connections, max_connect_errors;
527ulong extra_max_connections;
528uint max_digest_length= 0;
529ulong slave_retried_transactions;
530ulong transactions_multi_engine;
531ulong rpl_transactions_multi_engine;
532ulong transactions_gtid_foreign_engine;
533ulonglong slave_skipped_errors;
534ulong feature_files_opened_with_delayed_keys= 0, feature_check_constraint= 0;
535ulonglong denied_connections;
536my_decimal decimal_zero;
537long opt_secure_timestamp;
538
539/*
540 Maximum length of parameter value which can be set through
541 mysql_send_long_data() call.
542*/
543ulong max_long_data_size;
544
545bool max_user_connections_checking=0;
546/**
547 Limit of the total number of prepared statements in the server.
548 Is necessary to protect the server against out-of-memory attacks.
549*/
550uint max_prepared_stmt_count;
551/**
552 Current total number of prepared statements in the server. This number
553 is exact, and therefore may not be equal to the difference between
554 `com_stmt_prepare' and `com_stmt_close' (global status variables), as
555 the latter ones account for all registered attempts to prepare
556 a statement (including unsuccessful ones). Prepared statements are
557 currently connection-local: if the same SQL query text is prepared in
558 two different connections, this counts as two distinct prepared
559 statements.
560*/
561uint prepared_stmt_count=0;
562my_thread_id global_thread_id= 0;
563ulong current_pid;
564ulong slow_launch_threads = 0;
565uint sync_binlog_period= 0, sync_relaylog_period= 0,
566 sync_relayloginfo_period= 0, sync_masterinfo_period= 0;
567ulong expire_logs_days = 0;
568ulong rpl_recovery_rank=0;
569/**
570 Soft upper limit for number of sp_head objects that can be stored
571 in the sp_cache for one connection.
572*/
573ulong stored_program_cache_size= 0;
574
575ulong opt_slave_parallel_threads= 0;
576ulong opt_slave_domain_parallel_threads= 0;
577ulong opt_slave_parallel_mode= SLAVE_PARALLEL_CONSERVATIVE;
578ulong opt_binlog_commit_wait_count= 0;
579ulong opt_binlog_commit_wait_usec= 0;
580ulong opt_slave_parallel_max_queued= 131072;
581my_bool opt_gtid_ignore_duplicates= FALSE;
582
583const double log_10[] = {
584 1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007, 1e008, 1e009,
585 1e010, 1e011, 1e012, 1e013, 1e014, 1e015, 1e016, 1e017, 1e018, 1e019,
586 1e020, 1e021, 1e022, 1e023, 1e024, 1e025, 1e026, 1e027, 1e028, 1e029,
587 1e030, 1e031, 1e032, 1e033, 1e034, 1e035, 1e036, 1e037, 1e038, 1e039,
588 1e040, 1e041, 1e042, 1e043, 1e044, 1e045, 1e046, 1e047, 1e048, 1e049,
589 1e050, 1e051, 1e052, 1e053, 1e054, 1e055, 1e056, 1e057, 1e058, 1e059,
590 1e060, 1e061, 1e062, 1e063, 1e064, 1e065, 1e066, 1e067, 1e068, 1e069,
591 1e070, 1e071, 1e072, 1e073, 1e074, 1e075, 1e076, 1e077, 1e078, 1e079,
592 1e080, 1e081, 1e082, 1e083, 1e084, 1e085, 1e086, 1e087, 1e088, 1e089,
593 1e090, 1e091, 1e092, 1e093, 1e094, 1e095, 1e096, 1e097, 1e098, 1e099,
594 1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109,
595 1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119,
596 1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129,
597 1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139,
598 1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149,
599 1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159,
600 1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169,
601 1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179,
602 1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189,
603 1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199,
604 1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209,
605 1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219,
606 1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229,
607 1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239,
608 1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249,
609 1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259,
610 1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269,
611 1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279,
612 1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289,
613 1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299,
614 1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308
615};
616
617time_t server_start_time, flush_status_time;
618
619char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
620char *default_tz_name;
621char log_error_file[FN_REFLEN], glob_hostname[FN_REFLEN], *opt_log_basename;
622char mysql_real_data_home[FN_REFLEN],
623 lc_messages_dir[FN_REFLEN], reg_ext[FN_EXTLEN],
624 mysql_charsets_dir[FN_REFLEN],
625 *opt_init_file, *opt_tc_log_file;
626char *lc_messages_dir_ptr= lc_messages_dir, *log_error_file_ptr;
627char mysql_unpacked_real_data_home[FN_REFLEN];
628size_t mysql_unpacked_real_data_home_len;
629uint mysql_real_data_home_len, mysql_data_home_len= 1;
630uint reg_ext_length;
631const key_map key_map_empty(0);
632key_map key_map_full(0); // Will be initialized later
633
634DATE_TIME_FORMAT global_date_format, global_datetime_format, global_time_format;
635Time_zone *default_tz;
636
637const char *mysql_real_data_home_ptr= mysql_real_data_home;
638char server_version[SERVER_VERSION_LENGTH], *server_version_ptr;
639bool using_custom_server_version= false;
640char *mysqld_unix_port, *opt_mysql_tmpdir;
641ulong thread_handling;
642
643my_bool encrypt_binlog;
644my_bool encrypt_tmp_disk_tables, encrypt_tmp_files;
645
646/** name of reference on left expression in rewritten IN subquery */
647const LEX_CSTRING in_left_expr_name= {STRING_WITH_LEN("<left expr>") };
648/** name of additional condition */
649const LEX_CSTRING in_having_cond= {STRING_WITH_LEN("<IN HAVING>") };
650const LEX_CSTRING in_additional_cond= {STRING_WITH_LEN("<IN COND>") };
651
652/** Number of connection errors when selecting on the listening port */
653ulong connection_errors_select= 0;
654/** Number of connection errors when accepting sockets in the listening port. */
655ulong connection_errors_accept= 0;
656/** Number of connection errors from TCP wrappers. */
657ulong connection_errors_tcpwrap= 0;
658/** Number of connection errors from internal server errors. */
659ulong connection_errors_internal= 0;
660/** Number of connection errors from the server max_connection limit. */
661ulong connection_errors_max_connection= 0;
662/** Number of errors when reading the peer address. */
663ulong connection_errors_peer_addr= 0;
664
665/* classes for comparation parsing/processing */
666Eq_creator eq_creator;
667Ne_creator ne_creator;
668Gt_creator gt_creator;
669Lt_creator lt_creator;
670Ge_creator ge_creator;
671Le_creator le_creator;
672
673MYSQL_FILE *bootstrap_file;
674int bootstrap_error;
675
676I_List<THD> threads;
677Rpl_filter* cur_rpl_filter;
678Rpl_filter* global_rpl_filter;
679Rpl_filter* binlog_filter;
680
681THD *first_global_thread()
682{
683 if (threads.is_empty())
684 return NULL;
685 return threads.head();
686}
687
688THD *next_global_thread(THD *thd)
689{
690 if (threads.is_last(thd))
691 return NULL;
692 struct ilink *next= thd->next;
693 return static_cast<THD*>(next);
694}
695
696struct system_variables global_system_variables;
697/**
698 Following is just for options parsing, used with a difference against
699 global_system_variables.
700
701 TODO: something should be done to get rid of following variables
702*/
703const char *current_dbug_option="";
704
705struct system_variables max_system_variables;
706struct system_status_var global_status_var;
707
708MY_TMPDIR mysql_tmpdir_list;
709MY_BITMAP temp_pool;
710
711CHARSET_INFO *system_charset_info, *files_charset_info ;
712CHARSET_INFO *national_charset_info, *table_alias_charset;
713CHARSET_INFO *character_set_filesystem;
714CHARSET_INFO *error_message_charset_info;
715
716MY_LOCALE *my_default_lc_messages;
717MY_LOCALE *my_default_lc_time_names;
718
719SHOW_COMP_OPTION have_ssl, have_symlink, have_dlopen, have_query_cache;
720SHOW_COMP_OPTION have_geometry, have_rtree_keys;
721SHOW_COMP_OPTION have_crypt, have_compress;
722SHOW_COMP_OPTION have_profiling;
723SHOW_COMP_OPTION have_openssl;
724
725/* Thread specific variables */
726
727pthread_key(THD*, THR_THD);
728
729/*
730 LOCK_thread_count protects the following variables:
731 thread_count Number of threads with THD that servers queries.
732 threads Linked list of active THD's.
733 The effect of this is that one can't unlink and
734 delete a THD as long as one has locked
735 LOCK_thread_count.
736 ready_to_exit
737 delayed_insert_threads
738*/
739mysql_mutex_t LOCK_thread_count;
740
741/*
742 LOCK_start_thread is used to syncronize thread start and stop with
743 other threads.
744
745 It also protects these variables:
746 handler_count
747 in_bootstrap
748 select_thread_in_use
749 slave_init_thread_running
750 check_temp_dir() call
751*/
752mysql_mutex_t LOCK_start_thread;
753
754mysql_mutex_t LOCK_thread_cache;
755mysql_mutex_t
756 LOCK_status, LOCK_show_status, LOCK_error_log, LOCK_short_uuid_generator,
757 LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
758 LOCK_crypt,
759 LOCK_global_system_variables,
760 LOCK_user_conn, LOCK_slave_list,
761 LOCK_connection_count, LOCK_error_messages, LOCK_slave_background;
762
763mysql_mutex_t LOCK_stats, LOCK_global_user_client_stats,
764 LOCK_global_table_stats, LOCK_global_index_stats;
765
766/* This protects against changes in master_info_index */
767mysql_mutex_t LOCK_active_mi;
768
769/* This protects connection id.*/
770mysql_mutex_t LOCK_thread_id;
771
772/**
773 The below lock protects access to two global server variables:
774 max_prepared_stmt_count and prepared_stmt_count. These variables
775 set the limit and hold the current total number of prepared statements
776 in the server, respectively. As PREPARE/DEALLOCATE rate in a loaded
777 server may be fairly high, we need a dedicated lock.
778*/
779mysql_mutex_t LOCK_prepared_stmt_count;
780#ifdef HAVE_OPENSSL
781mysql_mutex_t LOCK_des_key_file;
782#endif
783mysql_rwlock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
784mysql_prlock_t LOCK_system_variables_hash;
785mysql_cond_t COND_thread_count, COND_start_thread;
786pthread_t signal_thread;
787pthread_attr_t connection_attrib;
788mysql_mutex_t LOCK_server_started;
789mysql_cond_t COND_server_started;
790
791int mysqld_server_started=0, mysqld_server_initialized= 0;
792File_parser_dummy_hook file_parser_dummy_hook;
793
794/* replication parameters, if master_host is not NULL, we are a slave */
795uint report_port= 0;
796ulong master_retry_count=0;
797char *master_info_file;
798char *relay_log_info_file, *report_user, *report_password, *report_host;
799char *opt_relay_logname = 0, *opt_relaylog_index_name=0;
800char *opt_logname, *opt_slow_logname, *opt_bin_logname;
801
802/* Static variables */
803
804static volatile sig_atomic_t kill_in_progress;
805my_bool opt_stack_trace;
806my_bool opt_expect_abort= 0, opt_bootstrap= 0;
807static my_bool opt_myisam_log;
808static int cleanup_done;
809static ulong opt_specialflag;
810static char *opt_binlog_index_name;
811char *mysql_home_ptr, *pidfile_name_ptr;
812/** Initial command line arguments (count), after load_defaults().*/
813static int defaults_argc;
814/**
815 Initial command line arguments (arguments), after load_defaults().
816 This memory is allocated by @c load_defaults() and should be freed
817 using @c free_defaults().
818 Do not modify defaults_argc / defaults_argv,
819 use remaining_argc / remaining_argv instead to parse the command
820 line arguments in multiple steps.
821*/
822static char **defaults_argv;
823/** Remaining command line arguments (count), filtered by handle_options().*/
824static int remaining_argc;
825/** Remaining command line arguments (arguments), filtered by handle_options().*/
826static char **remaining_argv;
827
828int orig_argc;
829char **orig_argv;
830
831static struct my_option pfs_early_options[]=
832{
833#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
834 {"performance_schema_instrument", OPT_PFS_INSTRUMENT,
835 "Default startup value for a performance schema instrument.",
836 &pfs_param.m_pfs_instrument, &pfs_param.m_pfs_instrument, 0, GET_STR,
837 OPT_ARG, 0, 0, 0, 0, 0, 0},
838 {"performance_schema_consumer_events_stages_current", 0,
839 "Default startup value for the events_stages_current consumer.",
840 &pfs_param.m_consumer_events_stages_current_enabled,
841 &pfs_param.m_consumer_events_stages_current_enabled, 0, GET_BOOL,
842 OPT_ARG, FALSE, 0, 0, 0, 0, 0},
843 {"performance_schema_consumer_events_stages_history", 0,
844 "Default startup value for the events_stages_history consumer.",
845 &pfs_param.m_consumer_events_stages_history_enabled,
846 &pfs_param.m_consumer_events_stages_history_enabled, 0,
847 GET_BOOL, OPT_ARG, FALSE, 0, 0, 0, 0, 0},
848 {"performance_schema_consumer_events_stages_history_long", 0,
849 "Default startup value for the events_stages_history_long consumer.",
850 &pfs_param.m_consumer_events_stages_history_long_enabled,
851 &pfs_param.m_consumer_events_stages_history_long_enabled, 0,
852 GET_BOOL, OPT_ARG, FALSE, 0, 0, 0, 0, 0},
853 {"performance_schema_consumer_events_statements_current", 0,
854 "Default startup value for the events_statements_current consumer.",
855 &pfs_param.m_consumer_events_statements_current_enabled,
856 &pfs_param.m_consumer_events_statements_current_enabled, 0,
857 GET_BOOL, OPT_ARG, TRUE, 0, 0, 0, 0, 0},
858 {"performance_schema_consumer_events_statements_history", 0,
859 "Default startup value for the events_statements_history consumer.",
860 &pfs_param.m_consumer_events_statements_history_enabled,
861 &pfs_param.m_consumer_events_statements_history_enabled, 0,
862 GET_BOOL, OPT_ARG, FALSE, 0, 0, 0, 0, 0},
863 {"performance_schema_consumer_events_statements_history_long", 0,
864 "Default startup value for the events_statements_history_long consumer.",
865 &pfs_param.m_consumer_events_statements_history_long_enabled,
866 &pfs_param.m_consumer_events_statements_history_long_enabled, 0,
867 GET_BOOL, OPT_ARG, FALSE, 0, 0, 0, 0, 0},
868 {"performance_schema_consumer_events_waits_current", 0,
869 "Default startup value for the events_waits_current consumer.",
870 &pfs_param.m_consumer_events_waits_current_enabled,
871 &pfs_param.m_consumer_events_waits_current_enabled, 0,
872 GET_BOOL, OPT_ARG, FALSE, 0, 0, 0, 0, 0},
873 {"performance_schema_consumer_events_waits_history", 0,
874 "Default startup value for the events_waits_history consumer.",
875 &pfs_param.m_consumer_events_waits_history_enabled,
876 &pfs_param.m_consumer_events_waits_history_enabled, 0,
877 GET_BOOL, OPT_ARG, FALSE, 0, 0, 0, 0, 0},
878 {"performance_schema_consumer_events_waits_history_long", 0,
879 "Default startup value for the events_waits_history_long consumer.",
880 &pfs_param.m_consumer_events_waits_history_long_enabled,
881 &pfs_param.m_consumer_events_waits_history_long_enabled, 0,
882 GET_BOOL, OPT_ARG, FALSE, 0, 0, 0, 0, 0},
883 {"performance_schema_consumer_global_instrumentation", 0,
884 "Default startup value for the global_instrumentation consumer.",
885 &pfs_param.m_consumer_global_instrumentation_enabled,
886 &pfs_param.m_consumer_global_instrumentation_enabled, 0,
887 GET_BOOL, OPT_ARG, TRUE, 0, 0, 0, 0, 0},
888 {"performance_schema_consumer_thread_instrumentation", 0,
889 "Default startup value for the thread_instrumentation consumer.",
890 &pfs_param.m_consumer_thread_instrumentation_enabled,
891 &pfs_param.m_consumer_thread_instrumentation_enabled, 0,
892 GET_BOOL, OPT_ARG, TRUE, 0, 0, 0, 0, 0},
893 {"performance_schema_consumer_statements_digest", 0,
894 "Default startup value for the statements_digest consumer.",
895 &pfs_param.m_consumer_statement_digest_enabled,
896 &pfs_param.m_consumer_statement_digest_enabled, 0,
897 GET_BOOL, OPT_ARG, TRUE, 0, 0, 0, 0, 0},
898#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
899 {"getopt-prefix-matching", 0,
900 "Recognize command-line options by their unambiguos prefixes.",
901 &my_getopt_prefix_matching, &my_getopt_prefix_matching, 0, GET_BOOL,
902 NO_ARG, 1, 0, 1, 0, 0, 0}
903};
904
905#ifdef HAVE_PSI_INTERFACE
906#ifdef HAVE_MMAP
907PSI_mutex_key key_PAGE_lock, key_LOCK_sync, key_LOCK_active, key_LOCK_pool,
908 key_LOCK_pending_checkpoint;
909#endif /* HAVE_MMAP */
910
911#ifdef HAVE_OPENSSL
912PSI_mutex_key key_LOCK_des_key_file;
913#endif /* HAVE_OPENSSL */
914
915PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list,
916 key_BINLOG_LOCK_binlog_background_thread,
917 key_LOCK_binlog_end_pos,
918 key_delayed_insert_mutex, key_hash_filo_lock, key_LOCK_active_mi,
919 key_LOCK_connection_count, key_LOCK_crypt, key_LOCK_delayed_create,
920 key_LOCK_delayed_insert, key_LOCK_delayed_status, key_LOCK_error_log,
921 key_LOCK_gdl, key_LOCK_global_system_variables,
922 key_LOCK_manager,
923 key_LOCK_prepared_stmt_count,
924 key_LOCK_rpl_status, key_LOCK_server_started,
925 key_LOCK_status, key_LOCK_show_status,
926 key_LOCK_system_variables_hash, key_LOCK_thd_data, key_LOCK_thd_kill,
927 key_LOCK_user_conn, key_LOCK_uuid_short_generator, key_LOG_LOCK_log,
928 key_master_info_data_lock, key_master_info_run_lock,
929 key_master_info_sleep_lock, key_master_info_start_stop_lock,
930 key_mutex_slave_reporting_capability_err_lock, key_relay_log_info_data_lock,
931 key_rpl_group_info_sleep_lock,
932 key_relay_log_info_log_space_lock, key_relay_log_info_run_lock,
933 key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data,
934 key_LOCK_error_messages, key_LOG_INFO_lock,
935 key_LOCK_start_thread,
936 key_LOCK_thread_count, key_LOCK_thread_cache,
937 key_PARTITION_LOCK_auto_inc;
938PSI_mutex_key key_RELAYLOG_LOCK_index;
939PSI_mutex_key key_LOCK_relaylog_end_pos;
940PSI_mutex_key key_LOCK_thread_id;
941PSI_mutex_key key_LOCK_slave_state, key_LOCK_binlog_state,
942 key_LOCK_rpl_thread, key_LOCK_rpl_thread_pool, key_LOCK_parallel_entry;
943PSI_mutex_key key_LOCK_binlog;
944
945PSI_mutex_key key_LOCK_stats,
946 key_LOCK_global_user_client_stats, key_LOCK_global_table_stats,
947 key_LOCK_global_index_stats,
948 key_LOCK_wakeup_ready, key_LOCK_wait_commit;
949PSI_mutex_key key_LOCK_gtid_waiting;
950
951PSI_mutex_key key_LOCK_after_binlog_sync;
952PSI_mutex_key key_LOCK_prepare_ordered, key_LOCK_commit_ordered,
953 key_LOCK_slave_background;
954PSI_mutex_key key_TABLE_SHARE_LOCK_share;
955PSI_mutex_key key_LOCK_ack_receiver;
956
957PSI_mutex_key key_TABLE_SHARE_LOCK_rotation;
958PSI_cond_key key_TABLE_SHARE_COND_rotation;
959
960static PSI_mutex_info all_server_mutexes[]=
961{
962#ifdef HAVE_MMAP
963 { &key_PAGE_lock, "PAGE::lock", 0},
964 { &key_LOCK_sync, "TC_LOG_MMAP::LOCK_sync", 0},
965 { &key_LOCK_active, "TC_LOG_MMAP::LOCK_active", 0},
966 { &key_LOCK_pool, "TC_LOG_MMAP::LOCK_pool", 0},
967 { &key_LOCK_pool, "TC_LOG_MMAP::LOCK_pending_checkpoint", 0},
968#endif /* HAVE_MMAP */
969
970#ifdef HAVE_OPENSSL
971 { &key_LOCK_des_key_file, "LOCK_des_key_file", PSI_FLAG_GLOBAL},
972#endif /* HAVE_OPENSSL */
973
974 { &key_BINLOG_LOCK_index, "MYSQL_BIN_LOG::LOCK_index", 0},
975 { &key_BINLOG_LOCK_xid_list, "MYSQL_BIN_LOG::LOCK_xid_list", 0},
976 { &key_BINLOG_LOCK_binlog_background_thread, "MYSQL_BIN_LOG::LOCK_binlog_background_thread", 0},
977 { &key_LOCK_binlog_end_pos, "MYSQL_BIN_LOG::LOCK_binlog_end_pos", 0 },
978 { &key_RELAYLOG_LOCK_index, "MYSQL_RELAY_LOG::LOCK_index", 0},
979 { &key_LOCK_relaylog_end_pos, "MYSQL_RELAY_LOG::LOCK_binlog_end_pos", 0},
980 { &key_delayed_insert_mutex, "Delayed_insert::mutex", 0},
981 { &key_hash_filo_lock, "hash_filo::lock", 0},
982 { &key_LOCK_active_mi, "LOCK_active_mi", PSI_FLAG_GLOBAL},
983 { &key_LOCK_connection_count, "LOCK_connection_count", PSI_FLAG_GLOBAL},
984 { &key_LOCK_thread_id, "LOCK_thread_id", PSI_FLAG_GLOBAL},
985 { &key_LOCK_crypt, "LOCK_crypt", PSI_FLAG_GLOBAL},
986 { &key_LOCK_delayed_create, "LOCK_delayed_create", PSI_FLAG_GLOBAL},
987 { &key_LOCK_delayed_insert, "LOCK_delayed_insert", PSI_FLAG_GLOBAL},
988 { &key_LOCK_delayed_status, "LOCK_delayed_status", PSI_FLAG_GLOBAL},
989 { &key_LOCK_error_log, "LOCK_error_log", PSI_FLAG_GLOBAL},
990 { &key_LOCK_gdl, "LOCK_gdl", PSI_FLAG_GLOBAL},
991 { &key_LOCK_global_system_variables, "LOCK_global_system_variables", PSI_FLAG_GLOBAL},
992 { &key_LOCK_manager, "LOCK_manager", PSI_FLAG_GLOBAL},
993 { &key_LOCK_prepared_stmt_count, "LOCK_prepared_stmt_count", PSI_FLAG_GLOBAL},
994 { &key_LOCK_rpl_status, "LOCK_rpl_status", PSI_FLAG_GLOBAL},
995 { &key_LOCK_server_started, "LOCK_server_started", PSI_FLAG_GLOBAL},
996 { &key_LOCK_status, "LOCK_status", PSI_FLAG_GLOBAL},
997 { &key_LOCK_show_status, "LOCK_show_status", PSI_FLAG_GLOBAL},
998 { &key_LOCK_system_variables_hash, "LOCK_system_variables_hash", PSI_FLAG_GLOBAL},
999 { &key_LOCK_stats, "LOCK_stats", PSI_FLAG_GLOBAL},
1000 { &key_LOCK_global_user_client_stats, "LOCK_global_user_client_stats", PSI_FLAG_GLOBAL},
1001 { &key_LOCK_global_table_stats, "LOCK_global_table_stats", PSI_FLAG_GLOBAL},
1002 { &key_LOCK_global_index_stats, "LOCK_global_index_stats", PSI_FLAG_GLOBAL},
1003 { &key_LOCK_wakeup_ready, "THD::LOCK_wakeup_ready", 0},
1004 { &key_LOCK_wait_commit, "wait_for_commit::LOCK_wait_commit", 0},
1005 { &key_LOCK_gtid_waiting, "gtid_waiting::LOCK_gtid_waiting", 0},
1006 { &key_LOCK_thd_data, "THD::LOCK_thd_data", 0},
1007 { &key_LOCK_thd_kill, "THD::LOCK_thd_kill", 0},
1008 { &key_LOCK_user_conn, "LOCK_user_conn", PSI_FLAG_GLOBAL},
1009 { &key_LOCK_uuid_short_generator, "LOCK_uuid_short_generator", PSI_FLAG_GLOBAL},
1010 { &key_LOG_LOCK_log, "LOG::LOCK_log", 0},
1011 { &key_master_info_data_lock, "Master_info::data_lock", 0},
1012 { &key_master_info_start_stop_lock, "Master_info::start_stop_lock", 0},
1013 { &key_master_info_run_lock, "Master_info::run_lock", 0},
1014 { &key_master_info_sleep_lock, "Master_info::sleep_lock", 0},
1015 { &key_mutex_slave_reporting_capability_err_lock, "Slave_reporting_capability::err_lock", 0},
1016 { &key_relay_log_info_data_lock, "Relay_log_info::data_lock", 0},
1017 { &key_relay_log_info_log_space_lock, "Relay_log_info::log_space_lock", 0},
1018 { &key_relay_log_info_run_lock, "Relay_log_info::run_lock", 0},
1019 { &key_rpl_group_info_sleep_lock, "Rpl_group_info::sleep_lock", 0},
1020 { &key_structure_guard_mutex, "Query_cache::structure_guard_mutex", 0},
1021 { &key_TABLE_SHARE_LOCK_ha_data, "TABLE_SHARE::LOCK_ha_data", 0},
1022 { &key_TABLE_SHARE_LOCK_share, "TABLE_SHARE::LOCK_share", 0},
1023 { &key_TABLE_SHARE_LOCK_rotation, "TABLE_SHARE::LOCK_rotation", 0},
1024 { &key_LOCK_error_messages, "LOCK_error_messages", PSI_FLAG_GLOBAL},
1025 { &key_LOCK_prepare_ordered, "LOCK_prepare_ordered", PSI_FLAG_GLOBAL},
1026 { &key_LOCK_after_binlog_sync, "LOCK_after_binlog_sync", PSI_FLAG_GLOBAL},
1027 { &key_LOCK_commit_ordered, "LOCK_commit_ordered", PSI_FLAG_GLOBAL},
1028 { &key_LOCK_slave_background, "LOCK_slave_background", PSI_FLAG_GLOBAL},
1029 { &key_LOG_INFO_lock, "LOG_INFO::lock", 0},
1030 { &key_LOCK_thread_count, "LOCK_thread_count", PSI_FLAG_GLOBAL},
1031 { &key_LOCK_thread_cache, "LOCK_thread_cache", PSI_FLAG_GLOBAL},
1032 { &key_PARTITION_LOCK_auto_inc, "HA_DATA_PARTITION::LOCK_auto_inc", 0},
1033 { &key_LOCK_slave_state, "LOCK_slave_state", 0},
1034 { &key_LOCK_start_thread, "LOCK_start_thread", PSI_FLAG_GLOBAL},
1035 { &key_LOCK_binlog_state, "LOCK_binlog_state", 0},
1036 { &key_LOCK_rpl_thread, "LOCK_rpl_thread", 0},
1037 { &key_LOCK_rpl_thread_pool, "LOCK_rpl_thread_pool", 0},
1038 { &key_LOCK_parallel_entry, "LOCK_parallel_entry", 0},
1039 { &key_LOCK_ack_receiver, "Ack_receiver::mutex", 0},
1040 { &key_LOCK_binlog, "LOCK_binlog", 0}
1041};
1042
1043PSI_rwlock_key key_rwlock_LOCK_grant, key_rwlock_LOCK_logger,
1044 key_rwlock_LOCK_sys_init_connect, key_rwlock_LOCK_sys_init_slave,
1045 key_rwlock_LOCK_system_variables_hash, key_rwlock_query_cache_query_lock,
1046 key_LOCK_SEQUENCE,
1047 key_rwlock_LOCK_vers_stats, key_rwlock_LOCK_stat_serial;
1048
1049static PSI_rwlock_info all_server_rwlocks[]=
1050{
1051#ifdef HAVE_OPENSSL10
1052 { &key_rwlock_openssl, "CRYPTO_dynlock_value::lock", 0},
1053#endif
1054 { &key_rwlock_LOCK_grant, "LOCK_grant", PSI_FLAG_GLOBAL},
1055 { &key_rwlock_LOCK_logger, "LOGGER::LOCK_logger", 0},
1056 { &key_rwlock_LOCK_sys_init_connect, "LOCK_sys_init_connect", PSI_FLAG_GLOBAL},
1057 { &key_rwlock_LOCK_sys_init_slave, "LOCK_sys_init_slave", PSI_FLAG_GLOBAL},
1058 { &key_LOCK_SEQUENCE, "LOCK_SEQUENCE", 0},
1059 { &key_rwlock_LOCK_system_variables_hash, "LOCK_system_variables_hash", PSI_FLAG_GLOBAL},
1060 { &key_rwlock_query_cache_query_lock, "Query_cache_query::lock", 0},
1061 { &key_rwlock_LOCK_vers_stats, "Vers_field_stats::lock", 0},
1062 { &key_rwlock_LOCK_stat_serial, "TABLE_SHARE::LOCK_stat_serial", 0}
1063};
1064
1065#ifdef HAVE_MMAP
1066PSI_cond_key key_PAGE_cond, key_COND_active, key_COND_pool;
1067#endif /* HAVE_MMAP */
1068
1069PSI_cond_key key_BINLOG_COND_xid_list,
1070 key_BINLOG_COND_bin_log_updated, key_BINLOG_COND_relay_log_updated,
1071 key_BINLOG_COND_binlog_background_thread,
1072 key_BINLOG_COND_binlog_background_thread_end,
1073 key_COND_cache_status_changed, key_COND_manager,
1074 key_COND_rpl_status, key_COND_server_started,
1075 key_delayed_insert_cond, key_delayed_insert_cond_client,
1076 key_item_func_sleep_cond, key_master_info_data_cond,
1077 key_master_info_start_cond, key_master_info_stop_cond,
1078 key_master_info_sleep_cond,
1079 key_relay_log_info_data_cond, key_relay_log_info_log_space_cond,
1080 key_relay_log_info_start_cond, key_relay_log_info_stop_cond,
1081 key_rpl_group_info_sleep_cond,
1082 key_TABLE_SHARE_cond, key_user_level_lock_cond,
1083 key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache,
1084 key_COND_start_thread, key_COND_binlog_send,
1085 key_BINLOG_COND_queue_busy;
1086PSI_cond_key key_RELAYLOG_COND_relay_log_updated,
1087 key_RELAYLOG_COND_bin_log_updated, key_COND_wakeup_ready,
1088 key_COND_wait_commit;
1089PSI_cond_key key_RELAYLOG_COND_queue_busy;
1090PSI_cond_key key_TC_LOG_MMAP_COND_queue_busy;
1091PSI_cond_key key_COND_rpl_thread_queue, key_COND_rpl_thread,
1092 key_COND_rpl_thread_stop, key_COND_rpl_thread_pool,
1093 key_COND_parallel_entry, key_COND_group_commit_orderer,
1094 key_COND_prepare_ordered, key_COND_slave_background;
1095PSI_cond_key key_COND_wait_gtid, key_COND_gtid_ignore_duplicates;
1096PSI_cond_key key_COND_ack_receiver;
1097
1098static PSI_cond_info all_server_conds[]=
1099{
1100#if (defined(_WIN32) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY)
1101 { &key_COND_handler_count, "COND_handler_count", PSI_FLAG_GLOBAL},
1102#endif /* _WIN32 || HAVE_SMEM && !EMBEDDED_LIBRARY */
1103#ifdef HAVE_MMAP
1104 { &key_PAGE_cond, "PAGE::cond", 0},
1105 { &key_COND_active, "TC_LOG_MMAP::COND_active", 0},
1106 { &key_COND_pool, "TC_LOG_MMAP::COND_pool", 0},
1107 { &key_TC_LOG_MMAP_COND_queue_busy, "TC_LOG_MMAP::COND_queue_busy", 0},
1108#endif /* HAVE_MMAP */
1109 { &key_BINLOG_COND_bin_log_updated, "MYSQL_BIN_LOG::COND_bin_log_updated", 0}, { &key_BINLOG_COND_relay_log_updated, "MYSQL_BIN_LOG::COND_relay_log_updated", 0},
1110 { &key_BINLOG_COND_xid_list, "MYSQL_BIN_LOG::COND_xid_list", 0},
1111 { &key_BINLOG_COND_binlog_background_thread, "MYSQL_BIN_LOG::COND_binlog_background_thread", 0},
1112 { &key_BINLOG_COND_binlog_background_thread_end, "MYSQL_BIN_LOG::COND_binlog_background_thread_end", 0},
1113 { &key_BINLOG_COND_queue_busy, "MYSQL_BIN_LOG::COND_queue_busy", 0},
1114 { &key_RELAYLOG_COND_relay_log_updated, "MYSQL_RELAY_LOG::COND_relay_log_updated", 0},
1115 { &key_RELAYLOG_COND_bin_log_updated, "MYSQL_RELAY_LOG::COND_bin_log_updated", 0},
1116 { &key_RELAYLOG_COND_queue_busy, "MYSQL_RELAY_LOG::COND_queue_busy", 0},
1117 { &key_COND_wakeup_ready, "THD::COND_wakeup_ready", 0},
1118 { &key_COND_wait_commit, "wait_for_commit::COND_wait_commit", 0},
1119 { &key_COND_cache_status_changed, "Query_cache::COND_cache_status_changed", 0},
1120 { &key_COND_manager, "COND_manager", PSI_FLAG_GLOBAL},
1121 { &key_COND_server_started, "COND_server_started", PSI_FLAG_GLOBAL},
1122 { &key_delayed_insert_cond, "Delayed_insert::cond", 0},
1123 { &key_delayed_insert_cond_client, "Delayed_insert::cond_client", 0},
1124 { &key_item_func_sleep_cond, "Item_func_sleep::cond", 0},
1125 { &key_master_info_data_cond, "Master_info::data_cond", 0},
1126 { &key_master_info_start_cond, "Master_info::start_cond", 0},
1127 { &key_master_info_stop_cond, "Master_info::stop_cond", 0},
1128 { &key_master_info_sleep_cond, "Master_info::sleep_cond", 0},
1129 { &key_relay_log_info_data_cond, "Relay_log_info::data_cond", 0},
1130 { &key_relay_log_info_log_space_cond, "Relay_log_info::log_space_cond", 0},
1131 { &key_relay_log_info_start_cond, "Relay_log_info::start_cond", 0},
1132 { &key_relay_log_info_stop_cond, "Relay_log_info::stop_cond", 0},
1133 { &key_rpl_group_info_sleep_cond, "Rpl_group_info::sleep_cond", 0},
1134 { &key_TABLE_SHARE_cond, "TABLE_SHARE::cond", 0},
1135 { &key_user_level_lock_cond, "User_level_lock::cond", 0},
1136 { &key_COND_thread_count, "COND_thread_count", PSI_FLAG_GLOBAL},
1137 { &key_COND_thread_cache, "COND_thread_cache", PSI_FLAG_GLOBAL},
1138 { &key_COND_flush_thread_cache, "COND_flush_thread_cache", PSI_FLAG_GLOBAL},
1139 { &key_COND_rpl_thread, "COND_rpl_thread", 0},
1140 { &key_COND_rpl_thread_queue, "COND_rpl_thread_queue", 0},
1141 { &key_COND_rpl_thread_stop, "COND_rpl_thread_stop", 0},
1142 { &key_COND_rpl_thread_pool, "COND_rpl_thread_pool", 0},
1143 { &key_COND_parallel_entry, "COND_parallel_entry", 0},
1144 { &key_COND_group_commit_orderer, "COND_group_commit_orderer", 0},
1145 { &key_COND_prepare_ordered, "COND_prepare_ordered", 0},
1146 { &key_COND_slave_background, "COND_slave_background", 0},
1147 { &key_COND_start_thread, "COND_start_thread", PSI_FLAG_GLOBAL},
1148 { &key_COND_wait_gtid, "COND_wait_gtid", 0},
1149 { &key_COND_gtid_ignore_duplicates, "COND_gtid_ignore_duplicates", 0},
1150 { &key_COND_ack_receiver, "Ack_receiver::cond", 0},
1151 { &key_COND_binlog_send, "COND_binlog_send", 0},
1152 { &key_TABLE_SHARE_COND_rotation, "TABLE_SHARE::COND_rotation", 0}
1153};
1154
1155PSI_thread_key key_thread_bootstrap, key_thread_delayed_insert,
1156 key_thread_handle_manager, key_thread_main,
1157 key_thread_one_connection, key_thread_signal_hand,
1158 key_thread_slave_background, key_rpl_parallel_thread;
1159PSI_thread_key key_thread_ack_receiver;
1160
1161static PSI_thread_info all_server_threads[]=
1162{
1163#if (defined(_WIN32) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY)
1164 { &key_thread_handle_con_namedpipes, "con_named_pipes", PSI_FLAG_GLOBAL},
1165#endif /* _WIN32 || HAVE_SMEM && !EMBEDDED_LIBRARY */
1166
1167#if defined(HAVE_SMEM) && !defined(EMBEDDED_LIBRARY)
1168 { &key_thread_handle_con_sharedmem, "con_shared_mem", PSI_FLAG_GLOBAL},
1169#endif /* HAVE_SMEM && !EMBEDDED_LIBRARY */
1170
1171#if (defined(_WIN32) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY)
1172 { &key_thread_handle_con_sockets, "con_sockets", PSI_FLAG_GLOBAL},
1173#endif /* _WIN32 || HAVE_SMEM && !EMBEDDED_LIBRARY */
1174
1175#ifdef __WIN__
1176 { &key_thread_handle_shutdown, "shutdown", PSI_FLAG_GLOBAL},
1177#endif /* __WIN__ */
1178
1179 { &key_thread_bootstrap, "bootstrap", PSI_FLAG_GLOBAL},
1180 { &key_thread_delayed_insert, "delayed_insert", 0},
1181 { &key_thread_handle_manager, "manager", PSI_FLAG_GLOBAL},
1182 { &key_thread_main, "main", PSI_FLAG_GLOBAL},
1183 { &key_thread_one_connection, "one_connection", 0},
1184 { &key_thread_signal_hand, "signal_handler", PSI_FLAG_GLOBAL},
1185 { &key_thread_slave_background, "slave_background", PSI_FLAG_GLOBAL},
1186 { &key_thread_ack_receiver, "Ack_receiver", PSI_FLAG_GLOBAL},
1187 { &key_rpl_parallel_thread, "rpl_parallel_thread", 0}
1188};
1189
1190#ifdef HAVE_MMAP
1191PSI_file_key key_file_map;
1192#endif /* HAVE_MMAP */
1193
1194PSI_file_key key_file_binlog, key_file_binlog_index, key_file_casetest,
1195 key_file_dbopt, key_file_des_key_file, key_file_ERRMSG, key_select_to_file,
1196 key_file_fileparser, key_file_frm, key_file_global_ddl_log, key_file_load,
1197 key_file_loadfile, key_file_log_event_data, key_file_log_event_info,
1198 key_file_master_info, key_file_misc, key_file_partition,
1199 key_file_pid, key_file_relay_log_info, key_file_send_file, key_file_tclog,
1200 key_file_trg, key_file_trn, key_file_init;
1201PSI_file_key key_file_query_log, key_file_slow_log;
1202PSI_file_key key_file_relaylog, key_file_relaylog_index;
1203PSI_file_key key_file_binlog_state;
1204
1205#endif /* HAVE_PSI_INTERFACE */
1206
1207#ifdef HAVE_PSI_STATEMENT_INTERFACE
1208PSI_statement_info stmt_info_new_packet;
1209#endif
1210
1211#ifndef EMBEDDED_LIBRARY
1212void net_before_header_psi(struct st_net *net, void *user_data, size_t /* unused: count */)
1213{
1214 THD *thd;
1215 thd= static_cast<THD*> (user_data);
1216 DBUG_ASSERT(thd != NULL);
1217
1218 /*
1219 We only come where when the server is IDLE, waiting for the next command.
1220 Technically, it is a wait on a socket, which may take a long time,
1221 because the call is blocking.
1222 Disable the socket instrumentation, to avoid recording a SOCKET event.
1223 Instead, start explicitly an IDLE event.
1224 */
1225 MYSQL_SOCKET_SET_STATE(net->vio->mysql_socket, PSI_SOCKET_STATE_IDLE);
1226 MYSQL_START_IDLE_WAIT(thd->m_idle_psi, &thd->m_idle_state);
1227}
1228
1229void net_after_header_psi(struct st_net *net, void *user_data,
1230 size_t /* unused: count */, my_bool rc)
1231{
1232 THD *thd;
1233 thd= static_cast<THD*> (user_data);
1234 DBUG_ASSERT(thd != NULL);
1235
1236 /*
1237 The server just got data for a network packet header,
1238 from the network layer.
1239 The IDLE event is now complete, since we now have a message to process.
1240 We need to:
1241 - start a new STATEMENT event
1242 - start a new STAGE event, within this statement,
1243 - start recording SOCKET WAITS events, within this stage.
1244 The proper order is critical to get events numbered correctly,
1245 and nested in the proper parent.
1246 */
1247 MYSQL_END_IDLE_WAIT(thd->m_idle_psi);
1248
1249 if (! rc)
1250 {
1251 thd->m_statement_psi= MYSQL_START_STATEMENT(&thd->m_statement_state,
1252 stmt_info_new_packet.m_key,
1253 thd->get_db(), thd->db.length,
1254 thd->charset());
1255
1256 THD_STAGE_INFO(thd, stage_init);
1257 }
1258
1259 /*
1260 TODO: consider recording a SOCKET event for the bytes just read,
1261 by also passing count here.
1262 */
1263 MYSQL_SOCKET_SET_STATE(net->vio->mysql_socket, PSI_SOCKET_STATE_ACTIVE);
1264}
1265
1266
1267void init_net_server_extension(THD *thd)
1268{
1269 /* Start with a clean state for connection events. */
1270 thd->m_idle_psi= NULL;
1271 thd->m_statement_psi= NULL;
1272 /* Hook up the NET_SERVER callback in the net layer. */
1273 thd->m_net_server_extension.m_user_data= thd;
1274 thd->m_net_server_extension.m_before_header= net_before_header_psi;
1275 thd->m_net_server_extension.m_after_header= net_after_header_psi;
1276 /* Activate this private extension for the mysqld server. */
1277 thd->net.extension= & thd->m_net_server_extension;
1278}
1279#else
1280void init_net_server_extension(THD *thd)
1281{
1282}
1283#endif /* EMBEDDED_LIBRARY */
1284
1285
1286/**
1287 A log message for the error log, buffered in memory.
1288 Log messages are temporarily buffered when generated before the error log
1289 is initialized, and then printed once the error log is ready.
1290*/
1291class Buffered_log : public Sql_alloc
1292{
1293public:
1294 Buffered_log(enum loglevel level, const char *message);
1295
1296 ~Buffered_log()
1297 {}
1298
1299 void print(void);
1300
1301private:
1302 /** Log message level. */
1303 enum loglevel m_level;
1304 /** Log message text. */
1305 String m_message;
1306};
1307
1308/**
1309 Constructor.
1310 @param level the message log level
1311 @param message the message text
1312*/
1313Buffered_log::Buffered_log(enum loglevel level, const char *message)
1314 : m_level(level), m_message()
1315{
1316 m_message.copy(message, strlen(message), &my_charset_latin1);
1317}
1318
1319/**
1320 Print a buffered log to the real log file.
1321*/
1322void Buffered_log::print()
1323{
1324 /*
1325 Since messages are buffered, they can be printed out
1326 of order with other entries in the log.
1327 Add "Buffered xxx" to the message text to prevent confusion.
1328 */
1329 switch(m_level)
1330 {
1331 case ERROR_LEVEL:
1332 sql_print_error("Buffered error: %s\n", m_message.c_ptr_safe());
1333 break;
1334 case WARNING_LEVEL:
1335 sql_print_warning("Buffered warning: %s\n", m_message.c_ptr_safe());
1336 break;
1337 case INFORMATION_LEVEL:
1338 /*
1339 Messages printed as "information" still end up in the mysqld *error* log,
1340 but with a [Note] tag instead of an [ERROR] tag.
1341 While this is probably fine for a human reading the log,
1342 it is upsetting existing automated scripts used to parse logs,
1343 because such scripts are likely to not already handle [Note] properly.
1344 INFORMATION_LEVEL messages are simply silenced, on purpose,
1345 to avoid un needed verbosity.
1346 */
1347 break;
1348 }
1349}
1350
1351/**
1352 Collection of all the buffered log messages.
1353*/
1354class Buffered_logs
1355{
1356public:
1357 Buffered_logs()
1358 {}
1359
1360 ~Buffered_logs()
1361 {}
1362
1363 void init();
1364 void cleanup();
1365
1366 void buffer(enum loglevel m_level, const char *msg);
1367 void print();
1368private:
1369 /**
1370 Memory root to use to store buffered logs.
1371 This memory root lifespan is between init and cleanup.
1372 Once the buffered logs are printed, they are not needed anymore,
1373 and all the memory used is reclaimed.
1374 */
1375 MEM_ROOT m_root;
1376 /** List of buffered log messages. */
1377 List<Buffered_log> m_list;
1378};
1379
1380void Buffered_logs::init()
1381{
1382 init_alloc_root(&m_root, "Buffered_logs", 1024, 0, MYF(0));
1383}
1384
1385void Buffered_logs::cleanup()
1386{
1387 m_list.delete_elements();
1388 free_root(&m_root, MYF(0));
1389}
1390
1391/**
1392 Add a log message to the buffer.
1393*/
1394void Buffered_logs::buffer(enum loglevel level, const char *msg)
1395{
1396 /*
1397 Do not let Sql_alloc::operator new(size_t) allocate memory,
1398 there is no memory root associated with the main() thread.
1399 Give explicitly the proper memory root to use to
1400 Sql_alloc::operator new(size_t, MEM_ROOT *) instead.
1401 */
1402 Buffered_log *log= new (&m_root) Buffered_log(level, msg);
1403 if (log)
1404 m_list.push_back(log, &m_root);
1405}
1406
1407/**
1408 Print buffered log messages.
1409*/
1410void Buffered_logs::print()
1411{
1412 Buffered_log *log;
1413 List_iterator_fast<Buffered_log> it(m_list);
1414 while ((log= it++))
1415 log->print();
1416}
1417
1418/** Logs reported before a logger is available. */
1419static Buffered_logs buffered_logs;
1420
1421static MYSQL_SOCKET unix_sock, base_ip_sock, extra_ip_sock;
1422struct my_rnd_struct sql_rand; ///< used by sql_class.cc:THD::THD()
1423
1424#ifndef EMBEDDED_LIBRARY
1425/**
1426 Error reporter that buffer log messages.
1427 @param level log message level
1428 @param format log message format string
1429*/
1430C_MODE_START
1431static void buffered_option_error_reporter(enum loglevel level,
1432 const char *format, ...)
1433{
1434 va_list args;
1435 char buffer[1024];
1436
1437 va_start(args, format);
1438 my_vsnprintf(buffer, sizeof(buffer), format, args);
1439 va_end(args);
1440 buffered_logs.buffer(level, buffer);
1441}
1442
1443
1444/**
1445 Character set and collation error reporter that prints to sql error log.
1446 @param level log message level
1447 @param format log message format string
1448
1449 This routine is used to print character set and collation
1450 warnings and errors inside an already running mysqld server,
1451 e.g. when a character set or collation is requested for the very first time
1452 and its initialization does not go well for some reasons.
1453
1454 Note: At early mysqld initialization stage,
1455 when error log is not yet available,
1456 we use buffered_option_error_reporter() instead,
1457 to print general character set subsystem initialization errors,
1458 such as Index.xml syntax problems, bad XML tag hierarchy, etc.
1459*/
1460static void charset_error_reporter(enum loglevel level,
1461 const char *format, ...)
1462{
1463 va_list args;
1464 va_start(args, format);
1465 vprint_msg_to_log(level, format, args);
1466 va_end(args);
1467}
1468C_MODE_END
1469
1470struct passwd *user_info;
1471static pthread_t select_thread;
1472#endif
1473
1474/* OS specific variables */
1475
1476#ifdef __WIN__
1477#undef getpid
1478#include <process.h>
1479
1480static mysql_cond_t COND_handler_count;
1481static uint handler_count;
1482static bool start_mode=0, use_opt_args;
1483static int opt_argc;
1484static char **opt_argv;
1485
1486#if !defined(EMBEDDED_LIBRARY)
1487static HANDLE hEventShutdown;
1488static char shutdown_event_name[40];
1489#include "nt_servc.h"
1490static NTService Service; ///< Service object for WinNT
1491#endif /* EMBEDDED_LIBRARY */
1492#endif /* __WIN__ */
1493
1494#ifdef _WIN32
1495static char pipe_name[512];
1496static SECURITY_ATTRIBUTES saPipeSecurity;
1497static SECURITY_DESCRIPTOR sdPipeDescriptor;
1498static HANDLE hPipe = INVALID_HANDLE_VALUE;
1499#endif
1500
1501#ifndef EMBEDDED_LIBRARY
1502bool mysqld_embedded=0;
1503#else
1504bool mysqld_embedded=1;
1505#endif
1506
1507my_bool plugins_are_initialized= FALSE;
1508
1509#ifndef DBUG_OFF
1510static const char* default_dbug_option;
1511#endif
1512#ifdef HAVE_LIBWRAP
1513const char *libwrapName= NULL;
1514int allow_severity = LOG_INFO;
1515int deny_severity = LOG_WARNING;
1516#endif
1517#ifdef HAVE_QUERY_CACHE
1518ulong query_cache_min_res_unit= QUERY_CACHE_MIN_RESULT_DATA_SIZE;
1519Query_cache query_cache;
1520#endif
1521#ifdef HAVE_SMEM
1522const char *shared_memory_base_name= default_shared_memory_base_name;
1523my_bool opt_enable_shared_memory;
1524HANDLE smem_event_connect_request= 0;
1525#endif
1526
1527my_bool opt_use_ssl = 0;
1528char *opt_ssl_ca= NULL, *opt_ssl_capath= NULL, *opt_ssl_cert= NULL,
1529 *opt_ssl_cipher= NULL, *opt_ssl_key= NULL, *opt_ssl_crl= NULL,
1530 *opt_ssl_crlpath= NULL;
1531
1532
1533static scheduler_functions thread_scheduler_struct, extra_thread_scheduler_struct;
1534scheduler_functions *thread_scheduler= &thread_scheduler_struct,
1535 *extra_thread_scheduler= &extra_thread_scheduler_struct;
1536
1537#ifdef HAVE_OPENSSL
1538#include <openssl/crypto.h>
1539#ifdef HAVE_OPENSSL10
1540typedef struct CRYPTO_dynlock_value
1541{
1542 mysql_rwlock_t lock;
1543} openssl_lock_t;
1544
1545static openssl_lock_t *openssl_stdlocks;
1546static openssl_lock_t *openssl_dynlock_create(const char *, int);
1547static void openssl_dynlock_destroy(openssl_lock_t *, const char *, int);
1548static void openssl_lock_function(int, int, const char *, int);
1549static void openssl_lock(int, openssl_lock_t *, const char *, int);
1550#endif /* HAVE_OPENSSL10 */
1551char *des_key_file;
1552#ifndef EMBEDDED_LIBRARY
1553struct st_VioSSLFd *ssl_acceptor_fd;
1554#endif
1555#endif /* HAVE_OPENSSL */
1556
1557/**
1558 Number of currently active user connections. The variable is protected by
1559 LOCK_connection_count.
1560*/
1561uint connection_count= 0, extra_connection_count= 0;
1562
1563my_bool opt_gtid_strict_mode= FALSE;
1564
1565
1566/* Function declarations */
1567
1568pthread_handler_t signal_hand(void *arg);
1569static int mysql_init_variables(void);
1570static int get_options(int *argc_ptr, char ***argv_ptr);
1571static bool add_terminator(DYNAMIC_ARRAY *options);
1572static bool add_many_options(DYNAMIC_ARRAY *, my_option *, size_t);
1573extern "C" my_bool mysqld_get_one_option(int, const struct my_option *, char *);
1574static int init_thread_environment();
1575static char *get_relative_path(const char *path);
1576static int fix_paths(void);
1577void handle_connections_sockets();
1578#ifdef _WIN32
1579pthread_handler_t handle_connections_sockets_thread(void *arg);
1580#endif
1581pthread_handler_t kill_server_thread(void *arg);
1582static void bootstrap(MYSQL_FILE *file);
1583static bool read_init_file(char *file_name);
1584#ifdef _WIN32
1585pthread_handler_t handle_connections_namedpipes(void *arg);
1586#endif
1587#ifdef HAVE_SMEM
1588pthread_handler_t handle_connections_shared_memory(void *arg);
1589#endif
1590pthread_handler_t handle_slave(void *arg);
1591static void clean_up(bool print_message);
1592static int test_if_case_insensitive(const char *dir_name);
1593
1594#ifndef EMBEDDED_LIBRARY
1595static bool pid_file_created= false;
1596static void usage(void);
1597static void start_signal_handler(void);
1598static void close_server_sock();
1599static void clean_up_mutexes(void);
1600static void wait_for_signal_thread_to_end(void);
1601static void create_pid_file();
1602ATTRIBUTE_NORETURN static void mysqld_exit(int exit_code);
1603#endif
1604static void delete_pid_file(myf flags);
1605static void end_ssl();
1606
1607
1608#ifndef EMBEDDED_LIBRARY
1609/****************************************************************************
1610** Code to end mysqld
1611****************************************************************************/
1612
1613static void close_connections(void)
1614{
1615#ifdef EXTRA_DEBUG
1616 int count=0;
1617#endif
1618 DBUG_ENTER("close_connections");
1619
1620 /* Clear thread cache */
1621 kill_cached_threads++;
1622 flush_thread_cache();
1623
1624 /* kill connection thread */
1625#if !defined(__WIN__)
1626 DBUG_PRINT("quit", ("waiting for select thread: %lu",
1627 (ulong)select_thread));
1628
1629 mysql_mutex_lock(&LOCK_start_thread);
1630 while (select_thread_in_use)
1631 {
1632 struct timespec abstime;
1633 int UNINIT_VAR(error);
1634 DBUG_PRINT("info",("Waiting for select thread"));
1635
1636#ifndef DONT_USE_THR_ALARM
1637 if (pthread_kill(select_thread, thr_client_alarm))
1638 break; // allready dead
1639#endif
1640 set_timespec(abstime, 2);
1641 for (uint tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
1642 {
1643 error= mysql_cond_timedwait(&COND_start_thread, &LOCK_start_thread,
1644 &abstime);
1645 if (error != EINTR)
1646 break;
1647 }
1648#ifdef EXTRA_DEBUG
1649 if (error != 0 && error != ETIMEDOUT && !count++)
1650 sql_print_error("Got error %d from mysql_cond_timedwait", error);
1651#endif
1652 close_server_sock();
1653 }
1654 mysql_mutex_unlock(&LOCK_start_thread);
1655#endif /* __WIN__ */
1656
1657
1658 /* Abort listening to new connections */
1659 DBUG_PRINT("quit",("Closing sockets"));
1660 if (!opt_disable_networking )
1661 {
1662 if (mysql_socket_getfd(base_ip_sock) != INVALID_SOCKET)
1663 {
1664 (void) mysql_socket_close(base_ip_sock);
1665 base_ip_sock= MYSQL_INVALID_SOCKET;
1666 }
1667 if (mysql_socket_getfd(extra_ip_sock) != INVALID_SOCKET)
1668 {
1669 (void) mysql_socket_close(extra_ip_sock);
1670 extra_ip_sock= MYSQL_INVALID_SOCKET;
1671 }
1672 }
1673#ifdef _WIN32
1674 if (hPipe != INVALID_HANDLE_VALUE && opt_enable_named_pipe)
1675 {
1676 HANDLE temp;
1677 DBUG_PRINT("quit", ("Closing named pipes") );
1678
1679 /* Create connection to the handle named pipe handler to break the loop */
1680 if ((temp = CreateFile(pipe_name,
1681 GENERIC_READ | GENERIC_WRITE,
1682 0,
1683 NULL,
1684 OPEN_EXISTING,
1685 0,
1686 NULL )) != INVALID_HANDLE_VALUE)
1687 {
1688 WaitNamedPipe(pipe_name, 1000);
1689 DWORD dwMode = PIPE_READMODE_BYTE | PIPE_WAIT;
1690 SetNamedPipeHandleState(temp, &dwMode, NULL, NULL);
1691 CancelIo(temp);
1692 DisconnectNamedPipe(temp);
1693 CloseHandle(temp);
1694 }
1695 }
1696#endif
1697#ifdef HAVE_SYS_UN_H
1698 if (mysql_socket_getfd(unix_sock) != INVALID_SOCKET)
1699 {
1700 (void) mysql_socket_close(unix_sock);
1701 (void) unlink(mysqld_unix_port);
1702 unix_sock= MYSQL_INVALID_SOCKET;
1703 }
1704#endif
1705 end_thr_alarm(0); // Abort old alarms.
1706
1707 /*
1708 First signal all threads that it's time to die
1709 This will give the threads some time to gracefully abort their
1710 statements and inform their clients that the server is about to die.
1711 */
1712
1713 THD *tmp;
1714 mysql_mutex_lock(&LOCK_thread_count); // For unlink from list
1715
1716 I_List_iterator<THD> it(threads);
1717 while ((tmp=it++))
1718 {
1719 DBUG_PRINT("quit",("Informing thread %ld that it's time to die",
1720 (ulong) tmp->thread_id));
1721 /* We skip slave threads on this first loop through. */
1722 if (tmp->slave_thread)
1723 continue;
1724
1725 /* cannot use 'continue' inside DBUG_EXECUTE_IF()... */
1726 if (DBUG_EVALUATE_IF("only_kill_system_threads", !tmp->system_thread, 0))
1727 continue;
1728
1729#ifdef WITH_WSREP
1730 /* skip wsrep system threads as well */
1731 if (WSREP(tmp) && (tmp->wsrep_exec_mode==REPL_RECV || tmp->wsrep_applier))
1732 continue;
1733#endif
1734 tmp->set_killed(KILL_SERVER_HARD);
1735 MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (tmp));
1736 mysql_mutex_lock(&tmp->LOCK_thd_kill);
1737 if (tmp->mysys_var)
1738 {
1739 tmp->mysys_var->abort=1;
1740 mysql_mutex_lock(&tmp->mysys_var->mutex);
1741 if (tmp->mysys_var->current_cond)
1742 {
1743 uint i;
1744 for (i=0; i < 2; i++)
1745 {
1746 int ret= mysql_mutex_trylock(tmp->mysys_var->current_mutex);
1747 mysql_cond_broadcast(tmp->mysys_var->current_cond);
1748 if (!ret)
1749 {
1750 /* Thread has surely got the signal, unlock and abort */
1751 mysql_mutex_unlock(tmp->mysys_var->current_mutex);
1752 break;
1753 }
1754 sleep(1);
1755 }
1756 }
1757 mysql_mutex_unlock(&tmp->mysys_var->mutex);
1758 }
1759 mysql_mutex_unlock(&tmp->LOCK_thd_kill);
1760 }
1761 mysql_mutex_unlock(&LOCK_thread_count); // For unlink from list
1762
1763 Events::deinit();
1764 slave_prepare_for_shutdown();
1765 mysql_bin_log.stop_background_thread();
1766 ack_receiver.stop();
1767
1768 /*
1769 Give threads time to die.
1770
1771 In 5.5, this was waiting 100 rounds @ 20 milliseconds/round, so as little
1772 as 2 seconds, depending on thread scheduling.
1773
1774 From 10.0, we increase this to 1000 rounds / 20 seconds. The rationale is
1775 that on a server with heavy I/O load, it is quite possible for eg. an
1776 fsync() of the binlog or whatever to cause something like LOCK_log to be
1777 held for more than 2 seconds. We do not want to force kill threads in
1778 such cases, if it can be avoided. Note that normally, the wait will be
1779 much smaller than even 2 seconds, this is only a safety fallback against
1780 stuck threads so server shutdown is not held up forever.
1781 */
1782 DBUG_PRINT("info", ("thread_count: %d", thread_count));
1783
1784 for (int i= 0; *(volatile int32*) &thread_count && i < 1000; i++)
1785 my_sleep(20000);
1786
1787 /*
1788 Force remaining threads to die by closing the connection to the client
1789 This will ensure that threads that are waiting for a command from the
1790 client on a blocking read call are aborted.
1791 */
1792
1793 for (;;)
1794 {
1795 mysql_mutex_lock(&LOCK_thread_count); // For unlink from list
1796 if (!(tmp=threads.get()))
1797 {
1798 mysql_mutex_unlock(&LOCK_thread_count);
1799 break;
1800 }
1801#ifndef __bsdi__ // Bug in BSDI kernel
1802 if (tmp->vio_ok())
1803 {
1804 if (global_system_variables.log_warnings)
1805 sql_print_warning(ER_DEFAULT(ER_FORCING_CLOSE),my_progname,
1806 (ulong) tmp->thread_id,
1807 (tmp->main_security_ctx.user ?
1808 tmp->main_security_ctx.user : ""));
1809 close_connection(tmp,ER_SERVER_SHUTDOWN);
1810 }
1811#endif
1812
1813#ifdef WITH_WSREP
1814 /*
1815 * WSREP_TODO:
1816 * this code block may turn out redundant. wsrep->disconnect()
1817 * should terminate slave threads gracefully, and we don't need
1818 * to signal them here.
1819 * The code here makes sure mysqld will not hang during shutdown
1820 * even if wsrep provider has problems in shutting down.
1821 */
1822 if (WSREP(tmp) && tmp->wsrep_exec_mode==REPL_RECV)
1823 {
1824 sql_print_information("closing wsrep system thread");
1825 tmp->set_killed(KILL_CONNECTION);
1826 MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (tmp));
1827 if (tmp->mysys_var)
1828 {
1829 tmp->mysys_var->abort=1;
1830 mysql_mutex_lock(&tmp->mysys_var->mutex);
1831 if (tmp->mysys_var->current_cond)
1832 {
1833 mysql_mutex_lock(tmp->mysys_var->current_mutex);
1834 mysql_cond_broadcast(tmp->mysys_var->current_cond);
1835 mysql_mutex_unlock(tmp->mysys_var->current_mutex);
1836 }
1837 mysql_mutex_unlock(&tmp->mysys_var->mutex);
1838 }
1839 }
1840#endif
1841 DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
1842 mysql_mutex_unlock(&LOCK_thread_count);
1843 }
1844 end_slave();
1845 /* All threads has now been aborted */
1846 DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count));
1847 mysql_mutex_lock(&LOCK_thread_count);
1848 while (thread_count || service_thread_count)
1849 {
1850 mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
1851 DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
1852 }
1853 mysql_mutex_unlock(&LOCK_thread_count);
1854
1855 DBUG_PRINT("quit",("close_connections thread"));
1856 DBUG_VOID_RETURN;
1857}
1858
1859
1860#ifdef HAVE_CLOSE_SERVER_SOCK
1861static void close_socket(MYSQL_SOCKET sock, const char *info)
1862{
1863 DBUG_ENTER("close_socket");
1864
1865 if (mysql_socket_getfd(sock) != INVALID_SOCKET)
1866 {
1867 DBUG_PRINT("info", ("calling shutdown on %s socket", info));
1868 (void) mysql_socket_shutdown(sock, SHUT_RDWR);
1869 }
1870 DBUG_VOID_RETURN;
1871}
1872#endif
1873
1874
1875static void close_server_sock()
1876{
1877#ifdef HAVE_CLOSE_SERVER_SOCK
1878 DBUG_ENTER("close_server_sock");
1879
1880 close_socket(base_ip_sock, "TCP/IP");
1881 close_socket(extra_ip_sock, "TCP/IP");
1882 close_socket(unix_sock, "unix/IP");
1883
1884 if (mysql_socket_getfd(unix_sock) != INVALID_SOCKET)
1885 (void) unlink(mysqld_unix_port);
1886 base_ip_sock= extra_ip_sock= unix_sock= MYSQL_INVALID_SOCKET;
1887
1888 DBUG_VOID_RETURN;
1889#endif
1890}
1891
1892#endif /*EMBEDDED_LIBRARY*/
1893
1894
1895/**
1896 Set shutdown user
1897
1898 @note this function may be called by multiple threads concurrently, thus
1899 it performs safe update of shutdown_user (first thread wins).
1900*/
1901
1902static volatile char *shutdown_user;
1903static void set_shutdown_user(THD *thd)
1904{
1905 char user_host_buff[MAX_USER_HOST_SIZE + 1];
1906 char *user, *expected_shutdown_user= 0;
1907
1908 make_user_name(thd, user_host_buff);
1909
1910 if ((user= my_strdup(user_host_buff, MYF(0))) &&
1911 !my_atomic_casptr((void **) &shutdown_user,
1912 (void **) &expected_shutdown_user, user))
1913 my_free(user);
1914}
1915
1916
1917void kill_mysql(THD *thd)
1918{
1919 DBUG_ENTER("kill_mysql");
1920
1921 if (thd)
1922 set_shutdown_user(thd);
1923
1924#if defined(SIGNALS_DONT_BREAK_READ) && !defined(EMBEDDED_LIBRARY)
1925 abort_loop=1; // Break connection loops
1926 close_server_sock(); // Force accept to wake up
1927#endif
1928
1929#if defined(__WIN__)
1930#if !defined(EMBEDDED_LIBRARY)
1931 {
1932 if (!SetEvent(hEventShutdown))
1933 {
1934 DBUG_PRINT("error",("Got error: %ld from SetEvent",GetLastError()));
1935 }
1936 /*
1937 or:
1938 HANDLE hEvent=OpenEvent(0, FALSE, "MySqlShutdown");
1939 SetEvent(hEventShutdown);
1940 CloseHandle(hEvent);
1941 */
1942 }
1943#endif
1944#elif defined(HAVE_PTHREAD_KILL)
1945 if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL))
1946 {
1947 DBUG_PRINT("error",("Got error %d from pthread_kill",errno)); /* purecov: inspected */
1948 }
1949#elif !defined(SIGNALS_DONT_BREAK_READ)
1950 kill(current_pid, MYSQL_KILL_SIGNAL);
1951#endif
1952 DBUG_PRINT("quit",("After pthread_kill"));
1953 shutdown_in_progress=1; // Safety if kill didn't work
1954#ifdef SIGNALS_DONT_BREAK_READ
1955 if (!kill_in_progress)
1956 {
1957 pthread_t tmp;
1958 int error;
1959 abort_loop=1;
1960 if (unlikely((error= mysql_thread_create(0, /* Not instrumented */
1961 &tmp, &connection_attrib,
1962 kill_server_thread, (void*) 0))))
1963 sql_print_error("Can't create thread to kill server (errno= %d).",
1964 error);
1965 }
1966#endif
1967 DBUG_VOID_RETURN;
1968}
1969
1970/**
1971 Force server down. Kill all connections and threads and exit.
1972
1973 @param sig_ptr Signal number that caused kill_server to be called.
1974
1975 @note
1976 A signal number of 0 mean that the function was not called
1977 from a signal handler and there is thus no signal to block
1978 or stop, we just want to kill the server.
1979*/
1980
1981#if !defined(__WIN__)
1982static void *kill_server(void *sig_ptr)
1983#define RETURN_FROM_KILL_SERVER return 0
1984#else
1985static void __cdecl kill_server(int sig_ptr)
1986#define RETURN_FROM_KILL_SERVER return
1987#endif
1988{
1989 DBUG_ENTER("kill_server");
1990#ifndef EMBEDDED_LIBRARY
1991 int sig=(int) (long) sig_ptr; // This is passed a int
1992 // if there is a signal during the kill in progress, ignore the other
1993 if (kill_in_progress) // Safety
1994 {
1995 DBUG_LEAVE;
1996 RETURN_FROM_KILL_SERVER;
1997 }
1998 kill_in_progress=TRUE;
1999 abort_loop=1; // This should be set
2000 if (sig != 0) // 0 is not a valid signal number
2001 my_sigset(sig, SIG_IGN); /* purify inspected */
2002 if (sig == MYSQL_KILL_SIGNAL || sig == 0)
2003 {
2004 char *user= (char *) my_atomic_loadptr((void**) &shutdown_user);
2005 sql_print_information(ER_DEFAULT(ER_NORMAL_SHUTDOWN), my_progname,
2006 user ? user : "unknown");
2007 if (user)
2008 my_free(user);
2009 }
2010 else
2011 sql_print_error(ER_DEFAULT(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */
2012
2013#ifdef HAVE_SMEM
2014 /*
2015 Send event to smem_event_connect_request for aborting
2016 */
2017 if (opt_enable_shared_memory)
2018 {
2019 if (!SetEvent(smem_event_connect_request))
2020 {
2021 DBUG_PRINT("error",
2022 ("Got error: %ld from SetEvent of smem_event_connect_request",
2023 GetLastError()));
2024 }
2025 }
2026#endif
2027
2028 /* Stop wsrep threads in case they are running. */
2029 if (wsrep_running_threads > 0)
2030 {
2031 wsrep_stop_replication(NULL);
2032 }
2033
2034 close_connections();
2035
2036 if (wsrep_inited == 1)
2037 wsrep_deinit(true);
2038
2039 if (sig != MYSQL_KILL_SIGNAL &&
2040 sig != 0)
2041 unireg_abort(1); /* purecov: inspected */
2042 else
2043 unireg_end();
2044
2045 /* purecov: begin deadcode */
2046 DBUG_LEAVE; // Must match DBUG_ENTER()
2047 my_thread_end();
2048 pthread_exit(0);
2049 /* purecov: end */
2050
2051 RETURN_FROM_KILL_SERVER; // Avoid compiler warnings
2052
2053#else /* EMBEDDED_LIBRARY*/
2054
2055 DBUG_LEAVE;
2056 RETURN_FROM_KILL_SERVER;
2057
2058#endif /* EMBEDDED_LIBRARY */
2059}
2060
2061
2062#if defined(USE_ONE_SIGNAL_HAND)
2063pthread_handler_t kill_server_thread(void *arg __attribute__((unused)))
2064{
2065 my_thread_init(); // Initialize new thread
2066 kill_server(0);
2067 /* purecov: begin deadcode */
2068 my_thread_end();
2069 pthread_exit(0);
2070 return 0;
2071 /* purecov: end */
2072}
2073#endif
2074
2075
2076extern "C" sig_handler print_signal_warning(int sig)
2077{
2078 if (global_system_variables.log_warnings)
2079 sql_print_warning("Got signal %d from thread %u", sig,
2080 (uint)my_thread_id());
2081#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY
2082 my_sigset(sig,print_signal_warning); /* int. thread system calls */
2083#endif
2084#if !defined(__WIN__)
2085 if (sig == SIGALRM)
2086 alarm(2); /* reschedule alarm */
2087#endif
2088}
2089
2090#ifndef EMBEDDED_LIBRARY
2091
2092static void init_error_log_mutex()
2093{
2094 mysql_mutex_init(key_LOCK_error_log, &LOCK_error_log, MY_MUTEX_INIT_FAST);
2095}
2096
2097
2098static void clean_up_error_log_mutex()
2099{
2100 mysql_mutex_destroy(&LOCK_error_log);
2101}
2102
2103
2104/**
2105 cleanup all memory and end program nicely.
2106
2107 If SIGNALS_DONT_BREAK_READ is defined, this function is called
2108 by the main thread. To get MySQL to shut down nicely in this case
2109 (Mac OS X) we have to call exit() instead if pthread_exit().
2110
2111 @note
2112 This function never returns.
2113*/
2114void unireg_end(void)
2115{
2116 clean_up(1);
2117 my_thread_end();
2118 sd_notify(0, "STATUS=MariaDB server is down");
2119#if defined(SIGNALS_DONT_BREAK_READ)
2120 exit(0);
2121#else
2122 pthread_exit(0); // Exit is in main thread
2123#endif
2124}
2125
2126
2127extern "C" void unireg_abort(int exit_code)
2128{
2129 DBUG_ENTER("unireg_abort");
2130
2131 if (opt_help)
2132 usage();
2133 if (exit_code)
2134 sql_print_error("Aborting\n");
2135 /* Don't write more notes to the log to not hide error message */
2136 disable_log_notes= 1;
2137
2138#ifdef WITH_WSREP
2139 /* Check if wsrep class is used. If yes, then cleanup wsrep */
2140 if (wsrep)
2141 {
2142 /*
2143 This is an abort situation, we cannot expect to gracefully close all
2144 wsrep threads here, we can only diconnect from service
2145 */
2146 wsrep_close_client_connections(FALSE);
2147 shutdown_in_progress= 1;
2148 wsrep->disconnect(wsrep);
2149 WSREP_INFO("Service disconnected.");
2150 wsrep_close_threads(NULL); /* this won't close all threads */
2151 sleep(1); /* so give some time to exit for those which can */
2152 WSREP_INFO("Some threads may fail to exit.");
2153
2154 /* In bootstrap mode we deinitialize wsrep here. */
2155 if (opt_bootstrap && wsrep_inited)
2156 wsrep_deinit(true);
2157 }
2158#endif // WITH_WSREP
2159
2160 clean_up(!opt_abort && (exit_code || !opt_bootstrap)); /* purecov: inspected */
2161 DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
2162 mysqld_exit(exit_code);
2163}
2164
2165
2166static void cleanup_tls()
2167{
2168 if (THR_THD)
2169 (void)pthread_key_delete(THR_THD);
2170}
2171
2172
2173static void mysqld_exit(int exit_code)
2174{
2175 DBUG_ENTER("mysqld_exit");
2176 /*
2177 Important note: we wait for the signal thread to end,
2178 but if a kill -15 signal was sent, the signal thread did
2179 spawn the kill_server_thread thread, which is running concurrently.
2180 */
2181 rpl_deinit_gtid_waiting();
2182 rpl_deinit_gtid_slave_state();
2183 wait_for_signal_thread_to_end();
2184 mysql_audit_finalize();
2185 clean_up_mutexes();
2186 clean_up_error_log_mutex();
2187 my_end((opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0));
2188#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
2189 shutdown_performance_schema(); // we do it as late as possible
2190#endif
2191 set_malloc_size_cb(NULL);
2192 if (opt_endinfo && global_status_var.global_memory_used)
2193 fprintf(stderr, "Warning: Memory not freed: %ld\n",
2194 (long) global_status_var.global_memory_used);
2195 if (!opt_debugging && !my_disable_leak_check && exit_code == 0)
2196 {
2197#ifdef SAFEMALLOC
2198 sf_report_leaked_memory(0);
2199#endif
2200 DBUG_SLOW_ASSERT(global_status_var.global_memory_used == 0);
2201 }
2202 cleanup_tls();
2203 DBUG_LEAVE;
2204 sd_notify(0, "STATUS=MariaDB server is down");
2205 exit(exit_code); /* purecov: inspected */
2206}
2207
2208#endif /* !EMBEDDED_LIBRARY */
2209
2210void clean_up(bool print_message)
2211{
2212 DBUG_PRINT("exit",("clean_up"));
2213 if (cleanup_done++)
2214 return; /* purecov: inspected */
2215
2216#ifdef HAVE_REPLICATION
2217 // We must call end_slave() as clean_up may have been called during startup
2218 end_slave();
2219 if (use_slave_mask)
2220 my_bitmap_free(&slave_error_mask);
2221#endif
2222 stop_handle_manager();
2223 release_ddl_log();
2224
2225 logger.cleanup_base();
2226
2227 injector::free_instance();
2228 mysql_bin_log.cleanup();
2229
2230 my_tz_free();
2231 my_dboptions_cache_free();
2232 ignore_db_dirs_free();
2233 servers_free(1);
2234#ifndef NO_EMBEDDED_ACCESS_CHECKS
2235 acl_free(1);
2236 grant_free();
2237#endif
2238 query_cache_destroy();
2239 hostname_cache_free();
2240 item_func_sleep_free();
2241 lex_free(); /* Free some memory */
2242 item_create_cleanup();
2243 tdc_start_shutdown();
2244#ifdef HAVE_REPLICATION
2245 semi_sync_master_deinit();
2246#endif
2247 plugin_shutdown();
2248 udf_free();
2249 ha_end();
2250 if (tc_log)
2251 tc_log->close();
2252 xid_cache_free();
2253 tdc_deinit();
2254 mdl_destroy();
2255 dflt_key_cache= 0;
2256 key_caches.delete_elements((void (*)(const char*, uchar*)) free_key_cache);
2257 wt_end();
2258 multi_keycache_free();
2259 sp_cache_end();
2260 free_status_vars();
2261 end_thr_alarm(1); /* Free allocated memory */
2262#ifndef EMBEDDED_LIBRARY
2263 end_thr_timer();
2264#endif
2265 my_free_open_file_info();
2266 if (defaults_argv)
2267 free_defaults(defaults_argv);
2268 free_tmpdir(&mysql_tmpdir_list);
2269 my_bitmap_free(&temp_pool);
2270 free_max_user_conn();
2271 free_global_user_stats();
2272 free_global_client_stats();
2273 free_global_table_stats();
2274 free_global_index_stats();
2275 delete_dynamic(&all_options); // This should be empty
2276 free_all_rpl_filters();
2277#ifdef HAVE_REPLICATION
2278 end_slave_list();
2279#endif
2280 wsrep_thr_deinit();
2281 my_uuid_end();
2282 delete type_handler_data;
2283 delete binlog_filter;
2284 delete global_rpl_filter;
2285 end_ssl();
2286#ifndef EMBEDDED_LIBRARY
2287 vio_end();
2288#endif /*!EMBEDDED_LIBRARY*/
2289#if defined(ENABLED_DEBUG_SYNC)
2290 /* End the debug sync facility. See debug_sync.cc. */
2291 debug_sync_end();
2292#endif /* defined(ENABLED_DEBUG_SYNC) */
2293
2294 delete_pid_file(MYF(0));
2295
2296 if (print_message && my_default_lc_messages && server_start_time)
2297 sql_print_information(ER_DEFAULT(ER_SHUTDOWN_COMPLETE),my_progname);
2298 MYSQL_CALLBACK(thread_scheduler, end, ());
2299 thread_scheduler= 0;
2300 mysql_library_end();
2301 finish_client_errs();
2302 cleanup_errmsgs();
2303 free_error_messages();
2304 /* Tell main we are ready */
2305 logger.cleanup_end();
2306 sys_var_end();
2307 free_charsets();
2308
2309 /*
2310 Signal mysqld_main() that it can exit
2311 do the broadcast inside the lock to ensure that my_end() is not called
2312 during broadcast()
2313 */
2314 mysql_mutex_lock(&LOCK_thread_count);
2315 ready_to_exit=1;
2316 mysql_cond_broadcast(&COND_thread_count);
2317 mysql_mutex_unlock(&LOCK_thread_count);
2318
2319 my_free(const_cast<char*>(log_bin_basename));
2320 my_free(const_cast<char*>(log_bin_index));
2321#ifndef EMBEDDED_LIBRARY
2322 my_free(const_cast<char*>(relay_log_basename));
2323 my_free(const_cast<char*>(relay_log_index));
2324#endif
2325 free_list(opt_plugin_load_list_ptr);
2326 destroy_proxy_protocol_networks();
2327
2328 /*
2329 The following lines may never be executed as the main thread may have
2330 killed us
2331 */
2332 DBUG_PRINT("quit", ("done with cleanup"));
2333} /* clean_up */
2334
2335
2336#ifndef EMBEDDED_LIBRARY
2337
2338/**
2339 This is mainly needed when running with purify, but it's still nice to
2340 know that all child threads have died when mysqld exits.
2341*/
2342static void wait_for_signal_thread_to_end()
2343{
2344 uint i;
2345 /*
2346 Wait up to 10 seconds for signal thread to die. We use this mainly to
2347 avoid getting warnings that my_thread_end has not been called
2348 */
2349 for (i= 0 ; i < 100 && signal_thread_in_use; i++)
2350 {
2351 if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL) == ESRCH)
2352 break;
2353 my_sleep(100); // Give it time to die
2354 }
2355}
2356#endif /*EMBEDDED_LIBRARY*/
2357
2358static void clean_up_mutexes()
2359{
2360 DBUG_ENTER("clean_up_mutexes");
2361 mysql_rwlock_destroy(&LOCK_grant);
2362 mysql_mutex_destroy(&LOCK_thread_count);
2363 mysql_mutex_destroy(&LOCK_thread_cache);
2364 mysql_mutex_destroy(&LOCK_start_thread);
2365 mysql_mutex_destroy(&LOCK_status);
2366 mysql_mutex_destroy(&LOCK_show_status);
2367 mysql_mutex_destroy(&LOCK_delayed_insert);
2368 mysql_mutex_destroy(&LOCK_delayed_status);
2369 mysql_mutex_destroy(&LOCK_delayed_create);
2370 mysql_mutex_destroy(&LOCK_crypt);
2371 mysql_mutex_destroy(&LOCK_user_conn);
2372 mysql_mutex_destroy(&LOCK_connection_count);
2373 mysql_mutex_destroy(&LOCK_thread_id);
2374 mysql_mutex_destroy(&LOCK_stats);
2375 mysql_mutex_destroy(&LOCK_global_user_client_stats);
2376 mysql_mutex_destroy(&LOCK_global_table_stats);
2377 mysql_mutex_destroy(&LOCK_global_index_stats);
2378#ifdef HAVE_OPENSSL
2379 mysql_mutex_destroy(&LOCK_des_key_file);
2380#ifdef HAVE_OPENSSL10
2381 for (int i= 0; i < CRYPTO_num_locks(); ++i)
2382 mysql_rwlock_destroy(&openssl_stdlocks[i].lock);
2383 OPENSSL_free(openssl_stdlocks);
2384#endif /* HAVE_OPENSSL10 */
2385#endif /* HAVE_OPENSSL */
2386#ifdef HAVE_REPLICATION
2387 mysql_mutex_destroy(&LOCK_rpl_status);
2388#endif /* HAVE_REPLICATION */
2389 mysql_mutex_destroy(&LOCK_active_mi);
2390 mysql_rwlock_destroy(&LOCK_sys_init_connect);
2391 mysql_rwlock_destroy(&LOCK_sys_init_slave);
2392 mysql_mutex_destroy(&LOCK_global_system_variables);
2393 mysql_prlock_destroy(&LOCK_system_variables_hash);
2394 mysql_mutex_destroy(&LOCK_short_uuid_generator);
2395 mysql_mutex_destroy(&LOCK_prepared_stmt_count);
2396 mysql_mutex_destroy(&LOCK_error_messages);
2397 mysql_cond_destroy(&COND_thread_count);
2398 mysql_cond_destroy(&COND_thread_cache);
2399 mysql_cond_destroy(&COND_start_thread);
2400 mysql_cond_destroy(&COND_flush_thread_cache);
2401 mysql_mutex_destroy(&LOCK_server_started);
2402 mysql_cond_destroy(&COND_server_started);
2403 mysql_mutex_destroy(&LOCK_prepare_ordered);
2404 mysql_cond_destroy(&COND_prepare_ordered);
2405 mysql_mutex_destroy(&LOCK_after_binlog_sync);
2406 mysql_mutex_destroy(&LOCK_commit_ordered);
2407 mysql_mutex_destroy(&LOCK_slave_background);
2408 mysql_cond_destroy(&COND_slave_background);
2409 DBUG_VOID_RETURN;
2410}
2411
2412
2413/****************************************************************************
2414** Init IP and UNIX socket
2415****************************************************************************/
2416
2417#ifdef EMBEDDED_LIBRARY
2418static void set_ports()
2419{
2420}
2421void close_connection(THD *thd, uint sql_errno)
2422{
2423}
2424#else
2425static void set_ports()
2426{
2427 char *env;
2428 if (!mysqld_port && !opt_disable_networking)
2429 { // Get port if not from commandline
2430 mysqld_port= MYSQL_PORT;
2431
2432 /*
2433 if builder specifically requested a default port, use that
2434 (even if it coincides with our factory default).
2435 only if they didn't do we check /etc/services (and, failing
2436 on that, fall back to the factory default of 3306).
2437 either default can be overridden by the environment variable
2438 MYSQL_TCP_PORT, which in turn can be overridden with command
2439 line options.
2440 */
2441
2442#if MYSQL_PORT_DEFAULT == 0
2443 struct servent *serv_ptr;
2444 if ((serv_ptr= getservbyname("mysql", "tcp")))
2445 SYSVAR_AUTOSIZE(mysqld_port, ntohs((u_short) serv_ptr->s_port));
2446#endif
2447 if ((env = getenv("MYSQL_TCP_PORT")))
2448 {
2449 mysqld_port= (uint) atoi(env);
2450 set_sys_var_value_origin(&mysqld_port, sys_var::ENV);
2451 }
2452 }
2453 if (!mysqld_unix_port)
2454 {
2455#ifdef __WIN__
2456 mysqld_unix_port= (char*) MYSQL_NAMEDPIPE;
2457#else
2458 mysqld_unix_port= (char*) MYSQL_UNIX_ADDR;
2459#endif
2460 if ((env = getenv("MYSQL_UNIX_PORT")))
2461 {
2462 mysqld_unix_port= env;
2463 set_sys_var_value_origin(&mysqld_unix_port, sys_var::ENV);
2464 }
2465 }
2466}
2467
2468/* Change to run as another user if started with --user */
2469
2470static struct passwd *check_user(const char *user)
2471{
2472 myf flags= 0;
2473 if (global_system_variables.log_warnings)
2474 flags|= MY_WME;
2475 if (!opt_bootstrap && !opt_help)
2476 flags|= MY_FAE;
2477
2478 struct passwd *tmp_user_info= my_check_user(user, MYF(flags));
2479
2480 if (!tmp_user_info && my_errno==EINVAL && (flags & MY_FAE))
2481 unireg_abort(1);
2482
2483 return tmp_user_info;
2484}
2485
2486static inline void allow_coredumps()
2487{
2488#ifdef PR_SET_DUMPABLE
2489 if (test_flags & TEST_CORE_ON_SIGNAL)
2490 {
2491 /* inform kernel that process is dumpable */
2492 (void) prctl(PR_SET_DUMPABLE, 1);
2493 }
2494#endif
2495}
2496
2497
2498static void set_user(const char *user, struct passwd *user_info_arg)
2499{
2500 /*
2501 We can get a SIGSEGV when calling initgroups() on some systems when NSS
2502 is configured to use LDAP and the server is statically linked. We set
2503 calling_initgroups as a flag to the SIGSEGV handler that is then used to
2504 output a specific message to help the user resolve this problem.
2505 */
2506 calling_initgroups= 1;
2507 int res= my_set_user(user, user_info_arg, MYF(MY_WME));
2508 calling_initgroups= 0;
2509 if (res)
2510 unireg_abort(1);
2511 allow_coredumps();
2512}
2513
2514#if !defined(__WIN__)
2515static void set_effective_user(struct passwd *user_info_arg)
2516{
2517 DBUG_ASSERT(user_info_arg != 0);
2518 if (setregid((gid_t)-1, user_info_arg->pw_gid) == -1)
2519 {
2520 sql_perror("setregid");
2521 unireg_abort(1);
2522 }
2523 if (setreuid((uid_t)-1, user_info_arg->pw_uid) == -1)
2524 {
2525 sql_perror("setreuid");
2526 unireg_abort(1);
2527 }
2528 allow_coredumps();
2529}
2530#endif
2531
2532/** Change root user if started with @c --chroot . */
2533static void set_root(const char *path)
2534{
2535#if !defined(__WIN__)
2536 if (chroot(path) == -1)
2537 {
2538 sql_perror("chroot");
2539 unireg_abort(1);
2540 }
2541 my_setwd("/", MYF(0));
2542#endif
2543}
2544
2545/**
2546 Activate usage of a tcp port
2547*/
2548
2549static MYSQL_SOCKET activate_tcp_port(uint port)
2550{
2551 struct addrinfo *ai, *a;
2552 struct addrinfo hints;
2553 int error;
2554 int arg;
2555 char port_buf[NI_MAXSERV];
2556 const char *real_bind_addr_str;
2557 MYSQL_SOCKET ip_sock= MYSQL_INVALID_SOCKET;
2558 DBUG_ENTER("activate_tcp_port");
2559 DBUG_PRINT("general",("IP Socket is %d",port));
2560
2561 bzero(&hints, sizeof (hints));
2562 hints.ai_flags= AI_PASSIVE;
2563 hints.ai_socktype= SOCK_STREAM;
2564 hints.ai_family= AF_UNSPEC;
2565
2566 if (my_bind_addr_str && strcmp(my_bind_addr_str, "*") == 0)
2567 real_bind_addr_str= NULL; // windows doesn't seem to support * here
2568 else
2569 real_bind_addr_str= my_bind_addr_str;
2570
2571 my_snprintf(port_buf, NI_MAXSERV, "%d", port);
2572 error= getaddrinfo(real_bind_addr_str, port_buf, &hints, &ai);
2573 if (unlikely(error != 0))
2574 {
2575 DBUG_PRINT("error",("Got error: %d from getaddrinfo()", error));
2576
2577 sql_print_error("%s: %s", ER_DEFAULT(ER_IPSOCK_ERROR), gai_strerror(error));
2578 unireg_abort(1); /* purecov: tested */
2579 }
2580
2581 /*
2582 special case: for wildcard addresses prefer ipv6 over ipv4,
2583 because we later switch off IPV6_V6ONLY, so ipv6 wildcard
2584 addresses will work for ipv4 too
2585 */
2586 if (!real_bind_addr_str && ai->ai_family == AF_INET && ai->ai_next
2587 && ai->ai_next->ai_family == AF_INET6)
2588 {
2589 a= ai;
2590 ai= ai->ai_next;
2591 a->ai_next= ai->ai_next;
2592 ai->ai_next= a;
2593 }
2594
2595 for (a= ai; a != NULL; a= a->ai_next)
2596 {
2597 ip_sock= mysql_socket_socket(key_socket_tcpip, a->ai_family,
2598 a->ai_socktype, a->ai_protocol);
2599
2600 char ip_addr[INET6_ADDRSTRLEN];
2601 if (vio_get_normalized_ip_string(a->ai_addr, a->ai_addrlen,
2602 ip_addr, sizeof (ip_addr)))
2603 {
2604 ip_addr[0]= 0;
2605 }
2606
2607 if (mysql_socket_getfd(ip_sock) == INVALID_SOCKET)
2608 {
2609 sql_print_message_func func= real_bind_addr_str ? sql_print_error
2610 : sql_print_warning;
2611 func("Failed to create a socket for %s '%s': errno: %d.",
2612 (a->ai_family == AF_INET) ? "IPv4" : "IPv6",
2613 (const char *) ip_addr, (int) socket_errno);
2614 }
2615 else
2616 {
2617 sql_print_information("Server socket created on IP: '%s'.",
2618 (const char *) ip_addr);
2619 break;
2620 }
2621 }
2622
2623 if (mysql_socket_getfd(ip_sock) == INVALID_SOCKET)
2624 {
2625 DBUG_PRINT("error",("Got error: %d from socket()",socket_errno));
2626 sql_perror(ER_DEFAULT(ER_IPSOCK_ERROR)); /* purecov: tested */
2627 unireg_abort(1); /* purecov: tested */
2628 }
2629
2630 mysql_socket_set_thread_owner(ip_sock);
2631
2632#ifndef __WIN__
2633 /*
2634 We should not use SO_REUSEADDR on windows as this would enable a
2635 user to open two mysqld servers with the same TCP/IP port.
2636 */
2637 arg= 1;
2638 (void) mysql_socket_setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,
2639 sizeof(arg));
2640#endif /* __WIN__ */
2641
2642#ifdef IPV6_V6ONLY
2643 /*
2644 For interoperability with older clients, IPv6 socket should
2645 listen on both IPv6 and IPv4 wildcard addresses.
2646 Turn off IPV6_V6ONLY option.
2647
2648 NOTE: this will work starting from Windows Vista only.
2649 On Windows XP dual stack is not available, so it will not
2650 listen on the corresponding IPv4-address.
2651 */
2652 if (a->ai_family == AF_INET6)
2653 {
2654 arg= 0;
2655 (void) mysql_socket_setsockopt(ip_sock, IPPROTO_IPV6, IPV6_V6ONLY,
2656 (char*)&arg, sizeof(arg));
2657 }
2658#endif
2659
2660#ifdef IP_FREEBIND
2661 arg= 1;
2662 (void) mysql_socket_setsockopt(ip_sock, IPPROTO_IP, IP_FREEBIND, (char*) &arg,
2663 sizeof(arg));
2664#endif
2665 /*
2666 Sometimes the port is not released fast enough when stopping and
2667 restarting the server. This happens quite often with the test suite
2668 on busy Linux systems. Retry to bind the address at these intervals:
2669 Sleep intervals: 1, 2, 4, 6, 9, 13, 17, 22, ...
2670 Retry at second: 1, 3, 7, 13, 22, 35, 52, 74, ...
2671 Limit the sequence by mysqld_port_timeout (set --port-open-timeout=#).
2672 */
2673 int ret;
2674 uint waited, retry, this_wait;
2675 for (waited= 0, retry= 1; ; retry++, waited+= this_wait)
2676 {
2677 if (((ret= mysql_socket_bind(ip_sock, a->ai_addr, a->ai_addrlen)) >= 0 ) ||
2678 (socket_errno != SOCKET_EADDRINUSE) ||
2679 (waited >= mysqld_port_timeout))
2680 break;
2681 sql_print_information("Retrying bind on TCP/IP port %u", port);
2682 this_wait= retry * retry / 3 + 1;
2683 sleep(this_wait);
2684 }
2685 freeaddrinfo(ai);
2686 if (ret < 0)
2687 {
2688 char buff[100];
2689 sprintf(buff, "Can't start server: Bind on TCP/IP port. Got error: %d",
2690 (int) socket_errno);
2691 sql_perror(buff);
2692 sql_print_error("Do you already have another mysqld server running on "
2693 "port: %u ?", port);
2694 unireg_abort(1);
2695 }
2696 if (mysql_socket_listen(ip_sock,(int) back_log) < 0)
2697 {
2698 sql_perror("Can't start server: listen() on TCP/IP port");
2699 sql_print_error("listen() on TCP/IP failed with error %d",
2700 socket_errno);
2701 unireg_abort(1);
2702 }
2703
2704#ifdef FD_CLOEXEC
2705 (void) fcntl(mysql_socket_getfd(ip_sock), F_SETFD, FD_CLOEXEC);
2706#endif
2707
2708 DBUG_RETURN(ip_sock);
2709}
2710
2711static void network_init(void)
2712{
2713#ifdef HAVE_SYS_UN_H
2714 struct sockaddr_un UNIXaddr;
2715 int arg;
2716#endif
2717 DBUG_ENTER("network_init");
2718
2719 if (MYSQL_CALLBACK_ELSE(thread_scheduler, init, (), 0))
2720 unireg_abort(1); /* purecov: inspected */
2721
2722 if (init_proxy_protocol_networks(my_proxy_protocol_networks))
2723 unireg_abort(1);
2724
2725 set_ports();
2726
2727 if (report_port == 0)
2728 {
2729 SYSVAR_AUTOSIZE(report_port, mysqld_port);
2730 }
2731#ifndef DBUG_OFF
2732 if (!opt_disable_networking)
2733 DBUG_ASSERT(report_port != 0);
2734#endif
2735 if (!opt_disable_networking && !opt_bootstrap)
2736 {
2737 if (mysqld_port)
2738 base_ip_sock= activate_tcp_port(mysqld_port);
2739 if (mysqld_extra_port)
2740 extra_ip_sock= activate_tcp_port(mysqld_extra_port);
2741 }
2742
2743#ifdef _WIN32
2744 /* create named pipe */
2745 if (mysqld_unix_port[0] && !opt_bootstrap &&
2746 opt_enable_named_pipe)
2747 {
2748
2749 strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\.\\pipe\\",
2750 mysqld_unix_port, NullS);
2751 bzero((char*) &saPipeSecurity, sizeof(saPipeSecurity));
2752 bzero((char*) &sdPipeDescriptor, sizeof(sdPipeDescriptor));
2753 if (!InitializeSecurityDescriptor(&sdPipeDescriptor,
2754 SECURITY_DESCRIPTOR_REVISION))
2755 {
2756 sql_perror("Can't start server : Initialize security descriptor");
2757 unireg_abort(1);
2758 }
2759 if (!SetSecurityDescriptorDacl(&sdPipeDescriptor, TRUE, NULL, FALSE))
2760 {
2761 sql_perror("Can't start server : Set security descriptor");
2762 unireg_abort(1);
2763 }
2764 saPipeSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
2765 saPipeSecurity.lpSecurityDescriptor = &sdPipeDescriptor;
2766 saPipeSecurity.bInheritHandle = FALSE;
2767 if ((hPipe= CreateNamedPipe(pipe_name,
2768 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE,
2769 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
2770 PIPE_UNLIMITED_INSTANCES,
2771 (int) global_system_variables.net_buffer_length,
2772 (int) global_system_variables.net_buffer_length,
2773 NMPWAIT_USE_DEFAULT_WAIT,
2774 &saPipeSecurity)) == INVALID_HANDLE_VALUE)
2775 {
2776 sql_perror("Create named pipe failed");
2777 unireg_abort(1);
2778 }
2779 }
2780#endif
2781
2782#if defined(HAVE_SYS_UN_H)
2783 /*
2784 ** Create the UNIX socket
2785 */
2786 if (mysqld_unix_port[0] && !opt_bootstrap)
2787 {
2788 DBUG_PRINT("general",("UNIX Socket is %s",mysqld_unix_port));
2789
2790 if (strlen(mysqld_unix_port) > (sizeof(UNIXaddr.sun_path) - 1))
2791 {
2792 sql_print_error("The socket file path is too long (> %u): %s",
2793 (uint) sizeof(UNIXaddr.sun_path) - 1, mysqld_unix_port);
2794 unireg_abort(1);
2795 }
2796 unix_sock= mysql_socket_socket(key_socket_unix, AF_UNIX, SOCK_STREAM, 0);
2797 if (mysql_socket_getfd(unix_sock) < 0)
2798 {
2799 sql_perror("Can't start server : UNIX Socket "); /* purecov: inspected */
2800 unireg_abort(1); /* purecov: inspected */
2801 }
2802
2803 mysql_socket_set_thread_owner(unix_sock);
2804
2805 bzero((char*) &UNIXaddr, sizeof(UNIXaddr));
2806 UNIXaddr.sun_family = AF_UNIX;
2807 strmov(UNIXaddr.sun_path, mysqld_unix_port);
2808 (void) unlink(mysqld_unix_port);
2809 arg= 1;
2810 (void) mysql_socket_setsockopt(unix_sock,SOL_SOCKET,SO_REUSEADDR,
2811 (char*)&arg, sizeof(arg));
2812 umask(0);
2813 if (mysql_socket_bind(unix_sock,
2814 reinterpret_cast<struct sockaddr *>(&UNIXaddr),
2815 sizeof(UNIXaddr)) < 0)
2816 {
2817 sql_perror("Can't start server : Bind on unix socket"); /* purecov: tested */
2818 sql_print_error("Do you already have another mysqld server running on socket: %s ?",mysqld_unix_port);
2819 unireg_abort(1); /* purecov: tested */
2820 }
2821 umask(((~my_umask) & 0666));
2822#if defined(S_IFSOCK) && defined(SECURE_SOCKETS)
2823 (void) chmod(mysqld_unix_port,S_IFSOCK); /* Fix solaris 2.6 bug */
2824#endif
2825 if (mysql_socket_listen(unix_sock,(int) back_log) < 0)
2826 sql_print_warning("listen() on Unix socket failed with error %d",
2827 socket_errno);
2828#ifdef FD_CLOEXEC
2829 (void) fcntl(mysql_socket_getfd(unix_sock), F_SETFD, FD_CLOEXEC);
2830#endif
2831 }
2832#endif
2833 DBUG_PRINT("info",("server started"));
2834 DBUG_VOID_RETURN;
2835}
2836
2837
2838/**
2839 Close a connection.
2840
2841 @param thd Thread handle.
2842 @param sql_errno The error code to send before disconnect.
2843
2844 @note
2845 For the connection that is doing shutdown, this is called twice
2846*/
2847
2848void close_connection(THD *thd, uint sql_errno)
2849{
2850 DBUG_ENTER("close_connection");
2851
2852 if (sql_errno)
2853 net_send_error(thd, sql_errno, ER_DEFAULT(sql_errno), NULL);
2854
2855 thd->print_aborted_warning(3, sql_errno ? ER_DEFAULT(sql_errno)
2856 : "CLOSE_CONNECTION");
2857
2858 thd->disconnect();
2859
2860 MYSQL_CONNECTION_DONE((int) sql_errno, thd->thread_id);
2861
2862 if (MYSQL_CONNECTION_DONE_ENABLED())
2863 {
2864 sleep(0); /* Workaround to avoid tailcall optimisation */
2865 }
2866 mysql_audit_notify_connection_disconnect(thd, sql_errno);
2867 DBUG_VOID_RETURN;
2868}
2869#endif /* EMBEDDED_LIBRARY */
2870
2871
2872/** Called when mysqld is aborted with ^C */
2873/* ARGSUSED */
2874extern "C" sig_handler end_mysqld_signal(int sig __attribute__((unused)))
2875{
2876 DBUG_ENTER("end_mysqld_signal");
2877 /* Don't call kill_mysql() if signal thread is not running */
2878 if (signal_thread_in_use)
2879 kill_mysql(); // Take down mysqld nicely
2880 DBUG_VOID_RETURN; /* purecov: deadcode */
2881}
2882
2883/*
2884 Decrease number of connections
2885
2886 SYNOPSIS
2887 dec_connection_count()
2888*/
2889
2890void dec_connection_count(scheduler_functions *scheduler)
2891{
2892 mysql_mutex_lock(&LOCK_connection_count);
2893 (*scheduler->connection_count)--;
2894 mysql_mutex_unlock(&LOCK_connection_count);
2895}
2896
2897
2898/*
2899 Send a signal to unblock close_conneciton() if there is no more
2900 threads running with a THD attached
2901
2902 It's safe to check for thread_count and service_thread_count outside
2903 of a mutex as we are only interested to see if they where decremented
2904 to 0 by a previous unlink_thd() call.
2905
2906 We should only signal COND_thread_count if both variables are 0,
2907 false positives are ok.
2908*/
2909
2910void signal_thd_deleted()
2911{
2912 if (!thread_count && !service_thread_count)
2913 {
2914 /* Signal close_connections() that all THD's are freed */
2915 mysql_mutex_lock(&LOCK_thread_count);
2916 mysql_cond_broadcast(&COND_thread_count);
2917 mysql_mutex_unlock(&LOCK_thread_count);
2918 }
2919}
2920
2921
2922/*
2923 Unlink thd from global list of available connections
2924
2925 SYNOPSIS
2926 unlink_thd()
2927 thd Thread handler
2928*/
2929
2930void unlink_thd(THD *thd)
2931{
2932 DBUG_ENTER("unlink_thd");
2933 DBUG_PRINT("enter", ("thd: %p", thd));
2934
2935 thd->cleanup();
2936 thd->add_status_to_global();
2937 unlink_not_visible_thd(thd);
2938
2939 /*
2940 Do not decrement when its wsrep system thread. wsrep_applier is set for
2941 applier as well as rollbacker threads.
2942 */
2943 if (IF_WSREP(!thd->wsrep_applier, 1))
2944 dec_connection_count(thd->scheduler);
2945
2946 thd->free_connection();
2947
2948 DBUG_VOID_RETURN;
2949}
2950
2951
2952/*
2953 Store thread in cache for reuse by new connections
2954
2955 SYNOPSIS
2956 cache_thread()
2957 thd Thread handler
2958
2959 NOTES
2960 LOCK_thread_cache is used to protect the cache variables
2961
2962 RETURN
2963 0 Thread was not put in cache
2964 1 Thread is to be reused by new connection.
2965 (ie, caller should return, not abort with pthread_exit())
2966*/
2967
2968
2969static bool cache_thread(THD *thd)
2970{
2971 struct timespec abstime;
2972 DBUG_ENTER("cache_thread");
2973 DBUG_ASSERT(thd);
2974
2975 mysql_mutex_lock(&LOCK_thread_cache);
2976 if (cached_thread_count < thread_cache_size &&
2977 ! abort_loop && !kill_cached_threads)
2978 {
2979 /* Don't kill the thread, just put it in cache for reuse */
2980 DBUG_PRINT("info", ("Adding thread to cache"));
2981 cached_thread_count++;
2982
2983 /*
2984 Delete the instrumentation for the job that just completed,
2985 before parking this pthread in the cache (blocked on COND_thread_cache).
2986 */
2987 PSI_CALL_delete_current_thread();
2988
2989#ifndef DBUG_OFF
2990 while (_db_is_pushed_())
2991 _db_pop_();
2992#endif
2993
2994 /* Clear warnings. */
2995 if (!thd->get_stmt_da()->is_warning_info_empty())
2996 thd->get_stmt_da()->clear_warning_info(thd->query_id);
2997
2998 set_timespec(abstime, THREAD_CACHE_TIMEOUT);
2999 while (!abort_loop && ! wake_thread && ! kill_cached_threads)
3000 {
3001 int error= mysql_cond_timedwait(&COND_thread_cache, &LOCK_thread_cache,
3002 &abstime);
3003 if (error == ETIMEDOUT || error == ETIME)
3004 {
3005 /*
3006 If timeout, end thread.
3007 If a new thread is requested (wake_thread is set), we will handle
3008 the call, even if we got a timeout (as we are already awake and free)
3009 */
3010 break;
3011 }
3012 }
3013 cached_thread_count--;
3014 if (kill_cached_threads)
3015 mysql_cond_signal(&COND_flush_thread_cache);
3016 if (wake_thread)
3017 {
3018 CONNECT *connect;
3019
3020 wake_thread--;
3021 connect= thread_cache.get();
3022 mysql_mutex_unlock(&LOCK_thread_cache);
3023
3024 if (!(connect->create_thd(thd)))
3025 {
3026 /* Out of resources. Free thread to get more resources */
3027 connect->close_and_delete();
3028 DBUG_RETURN(0);
3029 }
3030 delete connect;
3031
3032 /*
3033 We have to call store_globals to update mysys_var->id and lock_info
3034 with the new thread_id
3035 */
3036 thd->store_globals();
3037
3038 /*
3039 Create new instrumentation for the new THD job,
3040 and attach it to this running pthread.
3041 */
3042 PSI_thread *psi= PSI_CALL_new_thread(key_thread_one_connection,
3043 thd, thd->thread_id);
3044 PSI_CALL_set_thread(psi);
3045
3046 /* reset abort flag for the thread */
3047 thd->mysys_var->abort= 0;
3048 thd->thr_create_utime= microsecond_interval_timer();
3049 thd->start_utime= thd->thr_create_utime;
3050
3051 add_to_active_threads(thd);
3052 DBUG_RETURN(1);
3053 }
3054 }
3055 mysql_mutex_unlock(&LOCK_thread_cache);
3056 DBUG_RETURN(0);
3057}
3058
3059
3060/*
3061 End thread for the current connection
3062
3063 SYNOPSIS
3064 one_thread_per_connection_end()
3065 thd Thread handler. This may be null if we run out of resources.
3066 put_in_cache Store thread in cache, if there is room in it
3067 Normally this is true in all cases except when we got
3068 out of resources initializing the current thread
3069
3070 NOTES
3071 If thread is cached, we will wait until thread is scheduled to be
3072 reused and then we will return.
3073 If thread is not cached, we end the thread.
3074
3075 RETURN
3076 0 Signal to handle_one_connection to reuse connection
3077*/
3078
3079bool one_thread_per_connection_end(THD *thd, bool put_in_cache)
3080{
3081 DBUG_ENTER("one_thread_per_connection_end");
3082
3083 if (thd)
3084 {
3085 const bool wsrep_applier= IF_WSREP(thd->wsrep_applier, false);
3086
3087 unlink_thd(thd);
3088 if (!wsrep_applier && put_in_cache && cache_thread(thd))
3089 DBUG_RETURN(0); // Thread is reused
3090 delete thd;
3091 }
3092
3093 DBUG_PRINT("info", ("killing thread"));
3094 DBUG_LEAVE; // Must match DBUG_ENTER()
3095#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
3096 ERR_remove_state(0);
3097#endif
3098 my_thread_end();
3099
3100 pthread_exit(0);
3101 return 0; // Avoid compiler warnings
3102}
3103
3104
3105void flush_thread_cache()
3106{
3107 DBUG_ENTER("flush_thread_cache");
3108 mysql_mutex_lock(&LOCK_thread_cache);
3109 kill_cached_threads++;
3110 while (cached_thread_count)
3111 {
3112 mysql_cond_broadcast(&COND_thread_cache);
3113 mysql_cond_wait(&COND_flush_thread_cache, &LOCK_thread_cache);
3114 }
3115 kill_cached_threads--;
3116 mysql_mutex_unlock(&LOCK_thread_cache);
3117 DBUG_VOID_RETURN;
3118}
3119
3120
3121/******************************************************************************
3122 Setup a signal thread with handles all signals.
3123 Because Linux doesn't support schemas use a mutex to check that
3124 the signal thread is ready before continuing
3125******************************************************************************/
3126
3127#if defined(__WIN__)
3128
3129
3130/*
3131 On Windows, we use native SetConsoleCtrlHandler for handle events like Ctrl-C
3132 with graceful shutdown.
3133 Also, we do not use signal(), but SetUnhandledExceptionFilter instead - as it
3134 provides possibility to pass the exception to just-in-time debugger, collect
3135 dumps and potentially also the exception and thread context used to output
3136 callstack.
3137*/
3138
3139static BOOL WINAPI console_event_handler( DWORD type )
3140{
3141 DBUG_ENTER("console_event_handler");
3142#ifndef EMBEDDED_LIBRARY
3143 if(type == CTRL_C_EVENT)
3144 {
3145 /*
3146 Do not shutdown before startup is finished and shutdown
3147 thread is initialized. Otherwise there is a race condition
3148 between main thread doing initialization and CTRL-C thread doing
3149 cleanup, which can result into crash.
3150 */
3151#ifndef EMBEDDED_LIBRARY
3152 if(hEventShutdown)
3153 kill_mysql();
3154 else
3155#endif
3156 sql_print_warning("CTRL-C ignored during startup");
3157 DBUG_RETURN(TRUE);
3158 }
3159#endif
3160 DBUG_RETURN(FALSE);
3161}
3162
3163
3164
3165
3166#ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER
3167#define DEBUGGER_ATTACH_TIMEOUT 120
3168/*
3169 Wait for debugger to attach and break into debugger. If debugger is
3170 not attached, resume after timeout.
3171*/
3172static void wait_for_debugger(int timeout_sec)
3173{
3174 if(!IsDebuggerPresent())
3175 {
3176 int i;
3177 printf("Waiting for debugger to attach, pid=%u\n",GetCurrentProcessId());
3178 fflush(stdout);
3179 for(i= 0; i < timeout_sec; i++)
3180 {
3181 Sleep(1000);
3182 if(IsDebuggerPresent())
3183 {
3184 /* Break into debugger */
3185 __debugbreak();
3186 return;
3187 }
3188 }
3189 printf("pid=%u, debugger not attached after %d seconds, resuming\n",GetCurrentProcessId(),
3190 timeout_sec);
3191 fflush(stdout);
3192 }
3193}
3194#endif /* DEBUG_UNHANDLED_EXCEPTION_FILTER */
3195
3196LONG WINAPI my_unhandler_exception_filter(EXCEPTION_POINTERS *ex_pointers)
3197{
3198 static BOOL first_time= TRUE;
3199 if(!first_time)
3200 {
3201 /*
3202 This routine can be called twice, typically
3203 when detaching in JIT debugger.
3204 Return EXCEPTION_EXECUTE_HANDLER to terminate process.
3205 */
3206 return EXCEPTION_EXECUTE_HANDLER;
3207 }
3208 first_time= FALSE;
3209#ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER
3210 /*
3211 Unfortunately there is no clean way to debug unhandled exception filters,
3212 as debugger does not stop there(also documented in MSDN)
3213 To overcome, one could put a MessageBox, but this will not work in service.
3214 Better solution is to print error message and sleep some minutes
3215 until debugger is attached
3216 */
3217 wait_for_debugger(DEBUGGER_ATTACH_TIMEOUT);
3218#endif /* DEBUG_UNHANDLED_EXCEPTION_FILTER */
3219 __try
3220 {
3221 my_set_exception_pointers(ex_pointers);
3222 handle_fatal_signal(ex_pointers->ExceptionRecord->ExceptionCode);
3223 }
3224 __except(EXCEPTION_EXECUTE_HANDLER)
3225 {
3226 DWORD written;
3227 const char msg[] = "Got exception in exception handler!\n";
3228 WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),msg, sizeof(msg)-1,
3229 &written,NULL);
3230 }
3231 /*
3232 Return EXCEPTION_CONTINUE_SEARCH to give JIT debugger
3233 (drwtsn32 or vsjitdebugger) possibility to attach,
3234 if JIT debugger is configured.
3235 Windows Error reporting might generate a dump here.
3236 */
3237 return EXCEPTION_CONTINUE_SEARCH;
3238}
3239
3240
3241void init_signals(void)
3242{
3243 if(opt_console)
3244 SetConsoleCtrlHandler(console_event_handler,TRUE);
3245
3246 /* Avoid MessageBox()es*/
3247 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
3248 _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
3249 _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
3250 _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
3251 _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
3252 _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
3253
3254 /*
3255 Do not use SEM_NOGPFAULTERRORBOX in the following SetErrorMode (),
3256 because it would prevent JIT debugger and Windows error reporting
3257 from working. We need WER or JIT-debugging, since our own unhandled
3258 exception filter is not guaranteed to work in all situation
3259 (like heap corruption or stack overflow)
3260 */
3261 SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS
3262 | SEM_NOOPENFILEERRORBOX);
3263 SetUnhandledExceptionFilter(my_unhandler_exception_filter);
3264}
3265
3266
3267static void start_signal_handler(void)
3268{
3269#ifndef EMBEDDED_LIBRARY
3270 // Save vm id of this process
3271 if (!opt_bootstrap)
3272 create_pid_file();
3273#endif /* EMBEDDED_LIBRARY */
3274}
3275
3276
3277static void check_data_home(const char *path)
3278{}
3279
3280#endif /* __WIN__ */
3281
3282
3283#if BACKTRACE_DEMANGLE
3284#include <cxxabi.h>
3285extern "C" char *my_demangle(const char *mangled_name, int *status)
3286{
3287 return abi::__cxa_demangle(mangled_name, NULL, NULL, status);
3288}
3289#endif
3290
3291
3292/*
3293 pthread_attr_setstacksize() without so much platform-dependency
3294
3295 Return: The actual stack size if possible.
3296*/
3297
3298#ifndef EMBEDDED_LIBRARY
3299static size_t my_setstacksize(pthread_attr_t *attr, size_t stacksize)
3300{
3301 size_t guard_size __attribute__((unused))= 0;
3302
3303#if defined(__ia64__) || defined(__ia64)
3304 /*
3305 On IA64, half of the requested stack size is used for "normal stack"
3306 and half for "register stack". The space measured by check_stack_overrun
3307 is the "normal stack", so double the request to make sure we have the
3308 caller-expected amount of normal stack.
3309
3310 NOTE: there is no guarantee that the register stack can't grow faster
3311 than normal stack, so it's very unclear that we won't dump core due to
3312 stack overrun despite check_stack_overrun's efforts. Experimentation
3313 shows that in the execution_constants test, the register stack grows
3314 less than half as fast as normal stack, but perhaps other scenarios are
3315 less forgiving. If it turns out that more space is needed for the
3316 register stack, that could be forced (rather inefficiently) by using a
3317 multiplier higher than 2 here.
3318 */
3319 stacksize *= 2;
3320#endif
3321
3322 /*
3323 On many machines, the "guard space" is subtracted from the requested
3324 stack size, and that space is quite large on some platforms. So add
3325 it to our request, if we can find out what it is.
3326 */
3327#ifdef HAVE_PTHREAD_ATTR_GETGUARDSIZE
3328 if (pthread_attr_getguardsize(attr, &guard_size))
3329 guard_size = 0; /* if can't find it out, treat as 0 */
3330#endif
3331
3332 pthread_attr_setstacksize(attr, stacksize + guard_size);
3333
3334 /* Retrieve actual stack size if possible */
3335#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
3336 {
3337 size_t real_stack_size= 0;
3338 /* We must ignore real_stack_size = 0 as Solaris 2.9 can return 0 here */
3339 if (pthread_attr_getstacksize(attr, &real_stack_size) == 0 &&
3340 real_stack_size > guard_size)
3341 {
3342 real_stack_size -= guard_size;
3343 if (real_stack_size < stacksize)
3344 {
3345 if (global_system_variables.log_warnings)
3346 sql_print_warning("Asked for %zu thread stack, but got %zu",
3347 stacksize, real_stack_size);
3348 stacksize= real_stack_size;
3349 }
3350 }
3351 }
3352#endif /* !EMBEDDED_LIBRARY */
3353
3354#if defined(__ia64__) || defined(__ia64)
3355 stacksize /= 2;
3356#endif
3357 return stacksize;
3358}
3359#endif
3360
3361#ifdef DBUG_ASSERT_AS_PRINTF
3362extern "C" void
3363mariadb_dbug_assert_failed(const char *assert_expr, const char *file,
3364 unsigned long line)
3365{
3366 fprintf(stderr, "Warning: assertion failed: %s at %s line %lu\n",
3367 assert_expr, file, line);
3368 if (opt_stack_trace)
3369 {
3370 fprintf(stderr, "Attempting backtrace to find out the reason for the assert:\n");
3371 my_print_stacktrace(NULL, (ulong) my_thread_stack_size, 1);
3372 }
3373}
3374#endif /* DBUG_ASSERT_AS_PRINT */
3375
3376#if !defined(__WIN__)
3377#ifndef SA_RESETHAND
3378#define SA_RESETHAND 0
3379#endif /* SA_RESETHAND */
3380#ifndef SA_NODEFER
3381#define SA_NODEFER 0
3382#endif /* SA_NODEFER */
3383
3384#ifndef EMBEDDED_LIBRARY
3385
3386void init_signals(void)
3387{
3388 sigset_t set;
3389 struct sigaction sa;
3390 DBUG_ENTER("init_signals");
3391
3392 my_sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called!
3393
3394 if (opt_stack_trace || (test_flags & TEST_CORE_ON_SIGNAL))
3395 {
3396 sa.sa_flags = SA_RESETHAND | SA_NODEFER;
3397 sigemptyset(&sa.sa_mask);
3398 sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
3399
3400 my_init_stacktrace();
3401#if defined(__amiga__)
3402 sa.sa_handler=(void(*)())handle_fatal_signal;
3403#else
3404 sa.sa_handler=handle_fatal_signal;
3405#endif
3406 sigaction(SIGSEGV, &sa, NULL);
3407 sigaction(SIGABRT, &sa, NULL);
3408#ifdef SIGBUS
3409 sigaction(SIGBUS, &sa, NULL);
3410#endif
3411 sigaction(SIGILL, &sa, NULL);
3412 sigaction(SIGFPE, &sa, NULL);
3413 }
3414
3415#ifdef HAVE_GETRLIMIT
3416 if (test_flags & TEST_CORE_ON_SIGNAL)
3417 {
3418 /* Change limits so that we will get a core file */
3419 STRUCT_RLIMIT rl;
3420 rl.rlim_cur = rl.rlim_max = (rlim_t) RLIM_INFINITY;
3421 if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
3422 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");
3423 }
3424#endif
3425 (void) sigemptyset(&set);
3426 my_sigset(SIGPIPE,SIG_IGN);
3427 sigaddset(&set,SIGPIPE);
3428#ifndef IGNORE_SIGHUP_SIGQUIT
3429 sigaddset(&set,SIGQUIT);
3430 sigaddset(&set,SIGHUP);
3431#endif
3432 sigaddset(&set,SIGTERM);
3433
3434 /* Fix signals if blocked by parents (can happen on Mac OS X) */
3435 sigemptyset(&sa.sa_mask);
3436 sa.sa_flags = 0;
3437 sa.sa_handler = print_signal_warning;
3438 sigaction(SIGTERM, &sa, (struct sigaction*) 0);
3439 sa.sa_flags = 0;
3440 sa.sa_handler = print_signal_warning;
3441 sigaction(SIGHUP, &sa, (struct sigaction*) 0);
3442 if (thd_lib_detected != THD_LIB_LT)
3443 sigaddset(&set,THR_SERVER_ALARM);
3444 if (test_flags & TEST_SIGINT)
3445 {
3446 /* Allow SIGINT to break mysqld. This is for debugging with --gdb */
3447 my_sigset(SIGINT, end_mysqld_signal);
3448 sigdelset(&set, SIGINT);
3449 }
3450 else
3451 {
3452 sigaddset(&set,SIGINT);
3453#ifdef SIGTSTP
3454 sigaddset(&set,SIGTSTP);
3455#endif
3456 }
3457
3458 sigprocmask(SIG_SETMASK,&set,NULL);
3459 pthread_sigmask(SIG_SETMASK,&set,NULL);
3460 DBUG_VOID_RETURN;
3461}
3462
3463
3464static void start_signal_handler(void)
3465{
3466 int error;
3467 pthread_attr_t thr_attr;
3468 DBUG_ENTER("start_signal_handler");
3469
3470 (void) pthread_attr_init(&thr_attr);
3471 pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_SYSTEM);
3472 (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
3473 (void) my_setstacksize(&thr_attr,my_thread_stack_size);
3474
3475 mysql_mutex_lock(&LOCK_start_thread);
3476 if (unlikely((error= mysql_thread_create(key_thread_signal_hand,
3477 &signal_thread, &thr_attr,
3478 signal_hand, 0))))
3479 {
3480 sql_print_error("Can't create interrupt-thread (error %d, errno: %d)",
3481 error,errno);
3482 exit(1);
3483 }
3484 mysql_cond_wait(&COND_start_thread, &LOCK_start_thread);
3485 mysql_mutex_unlock(&LOCK_start_thread);
3486
3487 (void) pthread_attr_destroy(&thr_attr);
3488 DBUG_VOID_RETURN;
3489}
3490
3491
3492/** This threads handles all signals and alarms. */
3493/* ARGSUSED */
3494pthread_handler_t signal_hand(void *arg __attribute__((unused)))
3495{
3496 sigset_t set;
3497 int sig;
3498 my_thread_init(); // Init new thread
3499 DBUG_ENTER("signal_hand");
3500 signal_thread_in_use= 1;
3501
3502 /*
3503 Setup alarm handler
3504 This should actually be '+ max_number_of_slaves' instead of +10,
3505 but the +10 should be quite safe.
3506 */
3507 init_thr_alarm(thread_scheduler->max_threads + extra_max_connections +
3508 global_system_variables.max_insert_delayed_threads + 10);
3509 if (test_flags & TEST_SIGINT)
3510 {
3511 /* Allow SIGINT to break mysqld. This is for debugging with --gdb */
3512 (void) sigemptyset(&set);
3513 (void) sigaddset(&set,SIGINT);
3514 (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL);
3515 }
3516 (void) sigemptyset(&set); // Setup up SIGINT for debug
3517#ifdef USE_ONE_SIGNAL_HAND
3518 (void) sigaddset(&set,THR_SERVER_ALARM); // For alarms
3519#endif
3520#ifndef IGNORE_SIGHUP_SIGQUIT
3521 (void) sigaddset(&set,SIGQUIT);
3522 (void) sigaddset(&set,SIGHUP);
3523#endif
3524 (void) sigaddset(&set,SIGTERM);
3525 (void) sigaddset(&set,SIGTSTP);
3526
3527 /* Save pid to this process (or thread on Linux) */
3528 if (!opt_bootstrap)
3529 create_pid_file();
3530
3531 /*
3532 signal to start_signal_handler that we are ready
3533 This works by waiting for start_signal_handler to free mutex,
3534 after which we signal it that we are ready.
3535 At this point there is no other threads running, so there
3536 should not be any other mysql_cond_signal() calls.
3537 */
3538 mysql_mutex_lock(&LOCK_start_thread);
3539 mysql_cond_broadcast(&COND_start_thread);
3540 mysql_mutex_unlock(&LOCK_start_thread);
3541
3542 (void) pthread_sigmask(SIG_BLOCK,&set,NULL);
3543 for (;;)
3544 {
3545 int error; // Used when debugging
3546 if (shutdown_in_progress && !abort_loop)
3547 {
3548 sig= SIGTERM;
3549 error=0;
3550 }
3551 else
3552 while ((error=my_sigwait(&set,&sig)) == EINTR) ;
3553 if (cleanup_done)
3554 {
3555 DBUG_PRINT("quit",("signal_handler: calling my_thread_end()"));
3556 my_thread_end();
3557 DBUG_LEAVE; // Must match DBUG_ENTER()
3558 signal_thread_in_use= 0;
3559 pthread_exit(0); // Safety
3560 return 0; // Avoid compiler warnings
3561 }
3562 switch (sig) {
3563 case SIGTERM:
3564 case SIGQUIT:
3565 case SIGKILL:
3566#ifdef EXTRA_DEBUG
3567 sql_print_information("Got signal %d to shutdown mysqld",sig);
3568#endif
3569 /* switch to the old log message processing */
3570 logger.set_handlers(LOG_FILE, global_system_variables.sql_log_slow ? LOG_FILE:LOG_NONE,
3571 opt_log ? LOG_FILE:LOG_NONE);
3572 DBUG_PRINT("info",("Got signal: %d abort_loop: %d",sig,abort_loop));
3573 if (!abort_loop)
3574 {
3575 abort_loop=1; // mark abort for threads
3576 /* Delete the instrumentation for the signal thread */
3577 PSI_CALL_delete_current_thread();
3578#ifdef USE_ONE_SIGNAL_HAND
3579 pthread_t tmp;
3580 if (unlikely((error= mysql_thread_create(0, /* Not instrumented */
3581 &tmp, &connection_attrib,
3582 kill_server_thread,
3583 (void*) &sig))))
3584 sql_print_error("Can't create thread to kill server (errno= %d)",
3585 error);
3586#else
3587 kill_server((void*) sig); // MIT THREAD has a alarm thread
3588#endif
3589 }
3590 break;
3591 case SIGHUP:
3592 if (!abort_loop)
3593 {
3594 int not_used;
3595 mysql_print_status(); // Print some debug info
3596 reload_acl_and_cache((THD*) 0,
3597 (REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |
3598 REFRESH_GRANT |
3599 REFRESH_THREADS | REFRESH_HOSTS),
3600 (TABLE_LIST*) 0, &not_used); // Flush logs
3601 }
3602 /* reenable logs after the options were reloaded */
3603 if (log_output_options & LOG_NONE)
3604 {
3605 logger.set_handlers(LOG_FILE,
3606 global_system_variables.sql_log_slow ?
3607 LOG_TABLE : LOG_NONE,
3608 opt_log ? LOG_TABLE : LOG_NONE);
3609 }
3610 else
3611 {
3612 logger.set_handlers(LOG_FILE,
3613 global_system_variables.sql_log_slow ?
3614 log_output_options : LOG_NONE,
3615 opt_log ? log_output_options : LOG_NONE);
3616 }
3617 break;
3618#ifdef USE_ONE_SIGNAL_HAND
3619 case THR_SERVER_ALARM:
3620 process_alarm(sig); // Trigger alarms.
3621 break;
3622#endif
3623 default:
3624#ifdef EXTRA_DEBUG
3625 sql_print_warning("Got signal: %d error: %d",sig,error); /* purecov: tested */
3626#endif
3627 break; /* purecov: tested */
3628 }
3629 }
3630 return(0); /* purecov: deadcode */
3631}
3632
3633static void check_data_home(const char *path)
3634{}
3635
3636#endif /*!EMBEDDED_LIBRARY*/
3637#endif /* __WIN__*/
3638
3639
3640/**
3641 All global error messages are sent here where the first one is stored
3642 for the client.
3643*/
3644/* ARGSUSED */
3645extern "C" void my_message_sql(uint error, const char *str, myf MyFlags);
3646
3647void my_message_sql(uint error, const char *str, myf MyFlags)
3648{
3649 THD *thd= current_thd;
3650 Sql_condition::enum_warning_level level;
3651 sql_print_message_func func;
3652 DBUG_ENTER("my_message_sql");
3653 DBUG_PRINT("error", ("error: %u message: '%s' Flag: %lu", error, str,
3654 MyFlags));
3655
3656 DBUG_ASSERT(str != NULL);
3657 DBUG_ASSERT(error != 0);
3658
3659 if (MyFlags & ME_JUST_INFO)
3660 {
3661 level= Sql_condition::WARN_LEVEL_NOTE;
3662 func= sql_print_information;
3663 }
3664 else if (MyFlags & ME_JUST_WARNING)
3665 {
3666 level= Sql_condition::WARN_LEVEL_WARN;
3667 func= sql_print_warning;
3668 }
3669 else
3670 {
3671 level= Sql_condition::WARN_LEVEL_ERROR;
3672 func= sql_print_error;
3673 }
3674
3675 if (likely(thd))
3676 {
3677 if (unlikely(MyFlags & ME_FATALERROR))
3678 thd->is_fatal_error= 1;
3679 (void) thd->raise_condition(error, NULL, level, str);
3680 }
3681 else
3682 mysql_audit_general(0, MYSQL_AUDIT_GENERAL_ERROR, error, str);
3683
3684 /* When simulating OOM, skip writing to error log to avoid mtr errors */
3685 DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_VOID_RETURN;);
3686
3687 if (unlikely(!thd) || thd->log_all_errors || (MyFlags & ME_NOREFRESH))
3688 (*func)("%s: %s", my_progname_short, str); /* purecov: inspected */
3689 DBUG_VOID_RETURN;
3690}
3691
3692
3693extern "C" void *my_str_malloc_mysqld(size_t size);
3694
3695void *my_str_malloc_mysqld(size_t size)
3696{
3697 return my_malloc(size, MYF(MY_FAE));
3698}
3699
3700
3701#ifdef __WIN__
3702
3703pthread_handler_t handle_shutdown(void *arg)
3704{
3705 MSG msg;
3706 my_thread_init();
3707
3708 /* this call should create the message queue for this thread */
3709 PeekMessage(&msg, NULL, 1, 65534,PM_NOREMOVE);
3710#if !defined(EMBEDDED_LIBRARY)
3711 if (WaitForSingleObject(hEventShutdown,INFINITE)==WAIT_OBJECT_0)
3712#endif /* EMBEDDED_LIBRARY */
3713 kill_server(MYSQL_KILL_SIGNAL);
3714 return 0;
3715}
3716#endif
3717
3718#include <mysqld_default_groups.h>
3719
3720#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
3721static const int load_default_groups_sz=
3722sizeof(load_default_groups)/sizeof(load_default_groups[0]);
3723#endif
3724
3725
3726/**
3727 This function is used to check for stack overrun for pathological
3728 cases of regular expressions and 'like' expressions.
3729*/
3730extern "C" int
3731check_enough_stack_size_slow()
3732{
3733 uchar stack_top;
3734 THD *my_thd= current_thd;
3735 if (my_thd != NULL)
3736 return check_stack_overrun(my_thd, STACK_MIN_SIZE * 2, &stack_top);
3737 return 0;
3738}
3739
3740
3741/*
3742 The call to current_thd in check_enough_stack_size_slow is quite expensive,
3743 so we try to avoid it for the normal cases.
3744 The size of each stack frame for the wildcmp() routines is ~128 bytes,
3745 so checking *every* recursive call is not necessary.
3746 */
3747extern "C" int
3748check_enough_stack_size(int recurse_level)
3749{
3750 if (recurse_level % 16 != 0)
3751 return 0;
3752 return check_enough_stack_size_slow();
3753}
3754
3755
3756static void init_libstrings()
3757{
3758#ifndef EMBEDDED_LIBRARY
3759 my_string_stack_guard= check_enough_stack_size;
3760#endif
3761}
3762
3763ulonglong my_pcre_frame_size;
3764
3765static void init_pcre()
3766{
3767 pcre_malloc= pcre_stack_malloc= my_str_malloc_mysqld;
3768 pcre_free= pcre_stack_free= my_free;
3769 pcre_stack_guard= check_enough_stack_size_slow;
3770 /* See http://pcre.org/original/doc/html/pcrestack.html */
3771 my_pcre_frame_size= -pcre_exec(NULL, NULL, NULL, -999, -999, 0, NULL, 0);
3772 // pcre can underestimate its stack usage. Use a safe value, as in the manual
3773 set_if_bigger(my_pcre_frame_size, 500);
3774 my_pcre_frame_size += 16; // Again, safety margin, see the manual
3775}
3776
3777
3778/**
3779 Initialize one of the global date/time format variables.
3780
3781 @param format_type What kind of format should be supported
3782 @param var_ptr Pointer to variable that should be updated
3783
3784 @retval
3785 0 ok
3786 @retval
3787 1 error
3788*/
3789
3790static bool init_global_datetime_format(timestamp_type format_type,
3791 DATE_TIME_FORMAT *format)
3792{
3793 /*
3794 Get command line option
3795 format->format.str is already set by my_getopt
3796 */
3797 format->format.length= strlen(format->format.str);
3798
3799 if (parse_date_time_format(format_type, format))
3800 {
3801 fprintf(stderr, "Wrong date/time format specifier: %s\n",
3802 format->format.str);
3803 return true;
3804 }
3805 return false;
3806}
3807
3808#define COM_STATUS(X) (void*) offsetof(STATUS_VAR, X), SHOW_LONG_STATUS
3809#define STMT_STATUS(X) COM_STATUS(com_stat[(uint) X])
3810
3811SHOW_VAR com_status_vars[]= {
3812 {"admin_commands", COM_STATUS(com_other)},
3813 {"alter_db", STMT_STATUS(SQLCOM_ALTER_DB)},
3814 {"alter_db_upgrade", STMT_STATUS(SQLCOM_ALTER_DB_UPGRADE)},
3815 {"alter_event", STMT_STATUS(SQLCOM_ALTER_EVENT)},
3816 {"alter_function", STMT_STATUS(SQLCOM_ALTER_FUNCTION)},
3817 {"alter_procedure", STMT_STATUS(SQLCOM_ALTER_PROCEDURE)},
3818 {"alter_server", STMT_STATUS(SQLCOM_ALTER_SERVER)},
3819 {"alter_sequence", STMT_STATUS(SQLCOM_ALTER_SEQUENCE)},
3820 {"alter_table", STMT_STATUS(SQLCOM_ALTER_TABLE)},
3821 {"alter_tablespace", STMT_STATUS(SQLCOM_ALTER_TABLESPACE)},
3822 {"alter_user", STMT_STATUS(SQLCOM_ALTER_USER)},
3823 {"analyze", STMT_STATUS(SQLCOM_ANALYZE)},
3824 {"assign_to_keycache", STMT_STATUS(SQLCOM_ASSIGN_TO_KEYCACHE)},
3825 {"begin", STMT_STATUS(SQLCOM_BEGIN)},
3826 {"binlog", STMT_STATUS(SQLCOM_BINLOG_BASE64_EVENT)},
3827 {"call_procedure", STMT_STATUS(SQLCOM_CALL)},
3828 {"change_db", STMT_STATUS(SQLCOM_CHANGE_DB)},
3829 {"change_master", STMT_STATUS(SQLCOM_CHANGE_MASTER)},
3830 {"check", STMT_STATUS(SQLCOM_CHECK)},
3831 {"checksum", STMT_STATUS(SQLCOM_CHECKSUM)},
3832 {"commit", STMT_STATUS(SQLCOM_COMMIT)},
3833 {"compound_sql", STMT_STATUS(SQLCOM_COMPOUND)},
3834 {"create_db", STMT_STATUS(SQLCOM_CREATE_DB)},
3835 {"create_event", STMT_STATUS(SQLCOM_CREATE_EVENT)},
3836 {"create_function", STMT_STATUS(SQLCOM_CREATE_SPFUNCTION)},
3837 {"create_index", STMT_STATUS(SQLCOM_CREATE_INDEX)},
3838 {"create_package", STMT_STATUS(SQLCOM_CREATE_PACKAGE)},
3839 {"create_package_body", STMT_STATUS(SQLCOM_CREATE_PACKAGE_BODY)},
3840 {"create_procedure", STMT_STATUS(SQLCOM_CREATE_PROCEDURE)},
3841 {"create_role", STMT_STATUS(SQLCOM_CREATE_ROLE)},
3842 {"create_sequence", STMT_STATUS(SQLCOM_CREATE_SEQUENCE)},
3843 {"create_server", STMT_STATUS(SQLCOM_CREATE_SERVER)},
3844 {"create_table", STMT_STATUS(SQLCOM_CREATE_TABLE)},
3845 {"create_temporary_table", COM_STATUS(com_create_tmp_table)},
3846 {"create_trigger", STMT_STATUS(SQLCOM_CREATE_TRIGGER)},
3847 {"create_udf", STMT_STATUS(SQLCOM_CREATE_FUNCTION)},
3848 {"create_user", STMT_STATUS(SQLCOM_CREATE_USER)},
3849 {"create_view", STMT_STATUS(SQLCOM_CREATE_VIEW)},
3850 {"dealloc_sql", STMT_STATUS(SQLCOM_DEALLOCATE_PREPARE)},
3851 {"delete", STMT_STATUS(SQLCOM_DELETE)},
3852 {"delete_multi", STMT_STATUS(SQLCOM_DELETE_MULTI)},
3853 {"do", STMT_STATUS(SQLCOM_DO)},
3854 {"drop_db", STMT_STATUS(SQLCOM_DROP_DB)},
3855 {"drop_event", STMT_STATUS(SQLCOM_DROP_EVENT)},
3856 {"drop_function", STMT_STATUS(SQLCOM_DROP_FUNCTION)},
3857 {"drop_index", STMT_STATUS(SQLCOM_DROP_INDEX)},
3858 {"drop_procedure", STMT_STATUS(SQLCOM_DROP_PROCEDURE)},
3859 {"drop_package", STMT_STATUS(SQLCOM_DROP_PACKAGE)},
3860 {"drop_package_body", STMT_STATUS(SQLCOM_DROP_PACKAGE_BODY)},
3861 {"drop_role", STMT_STATUS(SQLCOM_DROP_ROLE)},
3862 {"drop_server", STMT_STATUS(SQLCOM_DROP_SERVER)},
3863 {"drop_sequence", STMT_STATUS(SQLCOM_DROP_SEQUENCE)},
3864 {"drop_table", STMT_STATUS(SQLCOM_DROP_TABLE)},
3865 {"drop_temporary_table", COM_STATUS(com_drop_tmp_table)},
3866 {"drop_trigger", STMT_STATUS(SQLCOM_DROP_TRIGGER)},
3867 {"drop_user", STMT_STATUS(SQLCOM_DROP_USER)},
3868 {"drop_view", STMT_STATUS(SQLCOM_DROP_VIEW)},
3869 {"empty_query", STMT_STATUS(SQLCOM_EMPTY_QUERY)},
3870 {"execute_immediate", STMT_STATUS(SQLCOM_EXECUTE_IMMEDIATE)},
3871 {"execute_sql", STMT_STATUS(SQLCOM_EXECUTE)},
3872 {"flush", STMT_STATUS(SQLCOM_FLUSH)},
3873 {"get_diagnostics", STMT_STATUS(SQLCOM_GET_DIAGNOSTICS)},
3874 {"grant", STMT_STATUS(SQLCOM_GRANT)},
3875 {"grant_role", STMT_STATUS(SQLCOM_GRANT_ROLE)},
3876 {"ha_close", STMT_STATUS(SQLCOM_HA_CLOSE)},
3877 {"ha_open", STMT_STATUS(SQLCOM_HA_OPEN)},
3878 {"ha_read", STMT_STATUS(SQLCOM_HA_READ)},
3879 {"help", STMT_STATUS(SQLCOM_HELP)},
3880 {"insert", STMT_STATUS(SQLCOM_INSERT)},
3881 {"insert_select", STMT_STATUS(SQLCOM_INSERT_SELECT)},
3882 {"install_plugin", STMT_STATUS(SQLCOM_INSTALL_PLUGIN)},
3883 {"kill", STMT_STATUS(SQLCOM_KILL)},
3884 {"load", STMT_STATUS(SQLCOM_LOAD)},
3885 {"lock_tables", STMT_STATUS(SQLCOM_LOCK_TABLES)},
3886 {"multi", COM_STATUS(com_multi)},
3887 {"optimize", STMT_STATUS(SQLCOM_OPTIMIZE)},
3888 {"preload_keys", STMT_STATUS(SQLCOM_PRELOAD_KEYS)},
3889 {"prepare_sql", STMT_STATUS(SQLCOM_PREPARE)},
3890 {"purge", STMT_STATUS(SQLCOM_PURGE)},
3891 {"purge_before_date", STMT_STATUS(SQLCOM_PURGE_BEFORE)},
3892 {"release_savepoint", STMT_STATUS(SQLCOM_RELEASE_SAVEPOINT)},
3893 {"rename_table", STMT_STATUS(SQLCOM_RENAME_TABLE)},
3894 {"rename_user", STMT_STATUS(SQLCOM_RENAME_USER)},
3895 {"repair", STMT_STATUS(SQLCOM_REPAIR)},
3896 {"replace", STMT_STATUS(SQLCOM_REPLACE)},
3897 {"replace_select", STMT_STATUS(SQLCOM_REPLACE_SELECT)},
3898 {"reset", STMT_STATUS(SQLCOM_RESET)},
3899 {"resignal", STMT_STATUS(SQLCOM_RESIGNAL)},
3900 {"revoke", STMT_STATUS(SQLCOM_REVOKE)},
3901 {"revoke_all", STMT_STATUS(SQLCOM_REVOKE_ALL)},
3902 {"revoke_role", STMT_STATUS(SQLCOM_REVOKE_ROLE)},
3903 {"rollback", STMT_STATUS(SQLCOM_ROLLBACK)},
3904 {"rollback_to_savepoint",STMT_STATUS(SQLCOM_ROLLBACK_TO_SAVEPOINT)},
3905 {"savepoint", STMT_STATUS(SQLCOM_SAVEPOINT)},
3906 {"select", STMT_STATUS(SQLCOM_SELECT)},
3907 {"set_option", STMT_STATUS(SQLCOM_SET_OPTION)},
3908 {"show_authors", STMT_STATUS(SQLCOM_SHOW_AUTHORS)},
3909 {"show_binlog_events", STMT_STATUS(SQLCOM_SHOW_BINLOG_EVENTS)},
3910 {"show_binlogs", STMT_STATUS(SQLCOM_SHOW_BINLOGS)},
3911 {"show_charsets", STMT_STATUS(SQLCOM_SHOW_CHARSETS)},
3912 {"show_collations", STMT_STATUS(SQLCOM_SHOW_COLLATIONS)},
3913 {"show_contributors", STMT_STATUS(SQLCOM_SHOW_CONTRIBUTORS)},
3914 {"show_create_db", STMT_STATUS(SQLCOM_SHOW_CREATE_DB)},
3915 {"show_create_event", STMT_STATUS(SQLCOM_SHOW_CREATE_EVENT)},
3916 {"show_create_func", STMT_STATUS(SQLCOM_SHOW_CREATE_FUNC)},
3917 {"show_create_package", STMT_STATUS(SQLCOM_SHOW_CREATE_PACKAGE)},
3918 {"show_create_package_body",STMT_STATUS(SQLCOM_SHOW_CREATE_PACKAGE_BODY)},
3919 {"show_create_proc", STMT_STATUS(SQLCOM_SHOW_CREATE_PROC)},
3920 {"show_create_table", STMT_STATUS(SQLCOM_SHOW_CREATE)},
3921 {"show_create_trigger", STMT_STATUS(SQLCOM_SHOW_CREATE_TRIGGER)},
3922 {"show_create_user", STMT_STATUS(SQLCOM_SHOW_CREATE_USER)},
3923 {"show_databases", STMT_STATUS(SQLCOM_SHOW_DATABASES)},
3924 {"show_engine_logs", STMT_STATUS(SQLCOM_SHOW_ENGINE_LOGS)},
3925 {"show_engine_mutex", STMT_STATUS(SQLCOM_SHOW_ENGINE_MUTEX)},
3926 {"show_engine_status", STMT_STATUS(SQLCOM_SHOW_ENGINE_STATUS)},
3927 {"show_errors", STMT_STATUS(SQLCOM_SHOW_ERRORS)},
3928 {"show_events", STMT_STATUS(SQLCOM_SHOW_EVENTS)},
3929 {"show_explain", STMT_STATUS(SQLCOM_SHOW_EXPLAIN)},
3930 {"show_fields", STMT_STATUS(SQLCOM_SHOW_FIELDS)},
3931#ifndef DBUG_OFF
3932 {"show_function_code", STMT_STATUS(SQLCOM_SHOW_FUNC_CODE)},
3933#endif
3934 {"show_function_status", STMT_STATUS(SQLCOM_SHOW_STATUS_FUNC)},
3935 {"show_generic", STMT_STATUS(SQLCOM_SHOW_GENERIC)},
3936 {"show_grants", STMT_STATUS(SQLCOM_SHOW_GRANTS)},
3937 {"show_keys", STMT_STATUS(SQLCOM_SHOW_KEYS)},
3938 {"show_master_status", STMT_STATUS(SQLCOM_SHOW_MASTER_STAT)},
3939 {"show_open_tables", STMT_STATUS(SQLCOM_SHOW_OPEN_TABLES)},
3940 {"show_package_status", STMT_STATUS(SQLCOM_SHOW_STATUS_PACKAGE)},
3941#ifndef DBUG_OFF
3942 {"show_package_body_code", STMT_STATUS(SQLCOM_SHOW_PACKAGE_BODY_CODE)},
3943#endif
3944 {"show_package_body_status", STMT_STATUS(SQLCOM_SHOW_STATUS_PACKAGE_BODY)},
3945 {"show_plugins", STMT_STATUS(SQLCOM_SHOW_PLUGINS)},
3946 {"show_privileges", STMT_STATUS(SQLCOM_SHOW_PRIVILEGES)},
3947#ifndef DBUG_OFF
3948 {"show_procedure_code", STMT_STATUS(SQLCOM_SHOW_PROC_CODE)},
3949#endif
3950 {"show_procedure_status",STMT_STATUS(SQLCOM_SHOW_STATUS_PROC)},
3951 {"show_processlist", STMT_STATUS(SQLCOM_SHOW_PROCESSLIST)},
3952 {"show_profile", STMT_STATUS(SQLCOM_SHOW_PROFILE)},
3953 {"show_profiles", STMT_STATUS(SQLCOM_SHOW_PROFILES)},
3954 {"show_relaylog_events", STMT_STATUS(SQLCOM_SHOW_RELAYLOG_EVENTS)},
3955 {"show_slave_hosts", STMT_STATUS(SQLCOM_SHOW_SLAVE_HOSTS)},
3956 {"show_slave_status", STMT_STATUS(SQLCOM_SHOW_SLAVE_STAT)},
3957 {"show_status", STMT_STATUS(SQLCOM_SHOW_STATUS)},
3958 {"show_storage_engines", STMT_STATUS(SQLCOM_SHOW_STORAGE_ENGINES)},
3959 {"show_table_status", STMT_STATUS(SQLCOM_SHOW_TABLE_STATUS)},
3960 {"show_tables", STMT_STATUS(SQLCOM_SHOW_TABLES)},
3961 {"show_triggers", STMT_STATUS(SQLCOM_SHOW_TRIGGERS)},
3962 {"show_variables", STMT_STATUS(SQLCOM_SHOW_VARIABLES)},
3963 {"show_warnings", STMT_STATUS(SQLCOM_SHOW_WARNS)},
3964 {"shutdown", STMT_STATUS(SQLCOM_SHUTDOWN)},
3965 {"signal", STMT_STATUS(SQLCOM_SIGNAL)},
3966 {"start_all_slaves", STMT_STATUS(SQLCOM_SLAVE_ALL_START)},
3967 {"start_slave", STMT_STATUS(SQLCOM_SLAVE_START)},
3968 {"stmt_close", COM_STATUS(com_stmt_close)},
3969 {"stmt_execute", COM_STATUS(com_stmt_execute)},
3970 {"stmt_fetch", COM_STATUS(com_stmt_fetch)},
3971 {"stmt_prepare", COM_STATUS(com_stmt_prepare)},
3972 {"stmt_reprepare", COM_STATUS(com_stmt_reprepare)},
3973 {"stmt_reset", COM_STATUS(com_stmt_reset)},
3974 {"stmt_send_long_data", COM_STATUS(com_stmt_send_long_data)},
3975 {"stop_all_slaves", STMT_STATUS(SQLCOM_SLAVE_ALL_STOP)},
3976 {"stop_slave", STMT_STATUS(SQLCOM_SLAVE_STOP)},
3977 {"truncate", STMT_STATUS(SQLCOM_TRUNCATE)},
3978 {"uninstall_plugin", STMT_STATUS(SQLCOM_UNINSTALL_PLUGIN)},
3979 {"unlock_tables", STMT_STATUS(SQLCOM_UNLOCK_TABLES)},
3980 {"update", STMT_STATUS(SQLCOM_UPDATE)},
3981 {"update_multi", STMT_STATUS(SQLCOM_UPDATE_MULTI)},
3982 {"xa_commit", STMT_STATUS(SQLCOM_XA_COMMIT)},
3983 {"xa_end", STMT_STATUS(SQLCOM_XA_END)},
3984 {"xa_prepare", STMT_STATUS(SQLCOM_XA_PREPARE)},
3985 {"xa_recover", STMT_STATUS(SQLCOM_XA_RECOVER)},
3986 {"xa_rollback", STMT_STATUS(SQLCOM_XA_ROLLBACK)},
3987 {"xa_start", STMT_STATUS(SQLCOM_XA_START)},
3988 {NullS, NullS, SHOW_LONG}
3989};
3990
3991
3992#ifdef HAVE_PSI_STATEMENT_INTERFACE
3993PSI_statement_info sql_statement_info[(uint) SQLCOM_END + 1];
3994PSI_statement_info com_statement_info[(uint) COM_END + 1];
3995
3996/**
3997 Initialize the command names array.
3998 Since we do not want to maintain a separate array,
3999 this is populated from data mined in com_status_vars,
4000 which already has one name for each command.
4001*/
4002void init_sql_statement_info()
4003{
4004 size_t first_com= offsetof(STATUS_VAR, com_stat[0]);
4005 size_t last_com= offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_END]);
4006 int record_size= offsetof(STATUS_VAR, com_stat[1])
4007 - offsetof(STATUS_VAR, com_stat[0]);
4008 size_t ptr;
4009 uint i;
4010 uint com_index;
4011
4012 static const char* dummy= "";
4013 for (i= 0; i < ((uint) SQLCOM_END + 1); i++)
4014 {
4015 sql_statement_info[i].m_name= dummy;
4016 sql_statement_info[i].m_flags= 0;
4017 }
4018
4019 SHOW_VAR *var= &com_status_vars[0];
4020 while (var->name != NULL)
4021 {
4022 ptr= (size_t)(var->value);
4023 if ((first_com <= ptr) && (ptr < last_com))
4024 {
4025 com_index= ((int)(ptr - first_com))/record_size;
4026 DBUG_ASSERT(com_index < (uint) SQLCOM_END);
4027 sql_statement_info[com_index].m_name= var->name;
4028 }
4029 var++;
4030 }
4031
4032 DBUG_ASSERT(strcmp(sql_statement_info[(uint) SQLCOM_SELECT].m_name, "select") == 0);
4033 DBUG_ASSERT(strcmp(sql_statement_info[(uint) SQLCOM_SIGNAL].m_name, "signal") == 0);
4034
4035 sql_statement_info[(uint) SQLCOM_END].m_name= "error";
4036}
4037
4038void init_com_statement_info()
4039{
4040 uint index;
4041
4042 for (index= 0; index < (uint) COM_END + 1; index++)
4043 {
4044 com_statement_info[index].m_name= command_name[index].str;
4045 com_statement_info[index].m_flags= 0;
4046 }
4047
4048 /* "statement/abstract/query" can mutate into "statement/sql/..." */
4049 com_statement_info[(uint) COM_QUERY].m_flags= PSI_FLAG_MUTABLE;
4050}
4051#endif
4052
4053
4054#ifdef SAFEMALLOC
4055/*
4056 Return the id for the current THD, to allow safemalloc to associate
4057 the memory with the right id.
4058*/
4059
4060extern "C" my_thread_id mariadb_dbug_id()
4061{
4062 THD *thd;
4063 if ((thd= current_thd) && thd->thread_dbug_id)
4064 {
4065 return thd->thread_dbug_id;
4066 }
4067 return my_thread_dbug_id();
4068}
4069#endif /* SAFEMALLOC */
4070
4071/* Thread Mem Usage By P.Linux */
4072extern "C" {
4073static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific)
4074{
4075 THD *thd= current_thd;
4076
4077 if (is_thread_specific) /* If thread specific memory */
4078 {
4079 /*
4080 When thread specfic is set, both mysqld_server_initialized and thd
4081 must be set
4082 */
4083 DBUG_ASSERT(mysqld_server_initialized && thd);
4084
4085 DBUG_PRINT("info", ("thd memory_used: %lld size: %lld",
4086 (longlong) thd->status_var.local_memory_used,
4087 size));
4088 thd->status_var.local_memory_used+= size;
4089 set_if_bigger(thd->status_var.max_local_memory_used,
4090 thd->status_var.local_memory_used);
4091 if (size > 0 &&
4092 thd->status_var.local_memory_used > (int64)thd->variables.max_mem_used &&
4093 likely(!thd->killed) && !thd->get_stmt_da()->is_set())
4094 {
4095 /* Ensure we don't get called here again */
4096 char buf[50], *buf2;
4097 thd->set_killed(KILL_QUERY);
4098 my_snprintf(buf, sizeof(buf), "--max-thread-mem-used=%llu",
4099 thd->variables.max_mem_used);
4100 if ((buf2= (char*) thd->alloc(256)))
4101 {
4102 my_snprintf(buf2, 256, ER_THD(thd, ER_OPTION_PREVENTS_STATEMENT), buf);
4103 thd->set_killed(KILL_QUERY, ER_OPTION_PREVENTS_STATEMENT, buf2);
4104 }
4105 }
4106 DBUG_ASSERT((longlong) thd->status_var.local_memory_used >= 0 ||
4107 !debug_assert_on_not_freed_memory);
4108 }
4109 else if (likely(thd))
4110 {
4111 DBUG_PRINT("info", ("global thd memory_used: %lld size: %lld",
4112 (longlong) thd->status_var.global_memory_used, size));
4113 thd->status_var.global_memory_used+= size;
4114 }
4115 else
4116 update_global_memory_status(size);
4117}
4118}
4119
4120
4121/**
4122 Create a replication file name or base for file names.
4123
4124 @param[in] opt Value of option, or NULL
4125 @param[in] def Default value if option value is not set.
4126 @param[in] ext Extension to use for the path
4127
4128 @returns Pointer to string containing the full file path, or NULL if
4129 it was not possible to create the path.
4130 */
4131static inline const char *
4132rpl_make_log_name(const char *opt,
4133 const char *def,
4134 const char *ext)
4135{
4136 DBUG_ENTER("rpl_make_log_name");
4137 DBUG_PRINT("enter", ("opt: %s, def: %s, ext: %s", opt, def, ext));
4138 char buff[FN_REFLEN];
4139 const char *base= opt ? opt : def;
4140 unsigned int options=
4141 MY_REPLACE_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH;
4142
4143 /* mysql_real_data_home_ptr may be null if no value of datadir has been
4144 specified through command-line or througha cnf file. If that is the
4145 case we make mysql_real_data_home_ptr point to mysql_real_data_home
4146 which, in that case holds the default path for data-dir.
4147 */
4148 if(mysql_real_data_home_ptr == NULL)
4149 mysql_real_data_home_ptr= mysql_real_data_home;
4150
4151 if (fn_format(buff, base, mysql_real_data_home_ptr, ext, options))
4152 DBUG_RETURN(my_strdup(buff, MYF(MY_WME)));
4153 else
4154 DBUG_RETURN(NULL);
4155}
4156
4157/* We have to setup my_malloc_size_cb_func early to catch all mallocs */
4158
4159static int init_early_variables()
4160{
4161 if (pthread_key_create(&THR_THD, NULL))
4162 {
4163 fprintf(stderr, "Fatal error: Can't create thread-keys\n");
4164 return 1;
4165 }
4166 set_current_thd(0);
4167 set_malloc_size_cb(my_malloc_size_cb_func);
4168 global_status_var.global_memory_used= 0;
4169 return 0;
4170}
4171
4172
4173static int init_common_variables()
4174{
4175 umask(((~my_umask) & 0666));
4176 connection_errors_select= 0;
4177 connection_errors_accept= 0;
4178 connection_errors_tcpwrap= 0;
4179 connection_errors_internal= 0;
4180 connection_errors_max_connection= 0;
4181 connection_errors_peer_addr= 0;
4182 my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
4183
4184 init_libstrings();
4185 tzset(); // Set tzname
4186
4187#ifdef SAFEMALLOC
4188 sf_malloc_dbug_id= mariadb_dbug_id;
4189#endif /* SAFEMALLOC */
4190#ifdef DBUG_ASSERT_AS_PRINTF
4191 my_dbug_assert_failed= mariadb_dbug_assert_failed;
4192#endif /* DBUG_ASSERT_AS_PRINTF */
4193
4194 if (!(type_handler_data= new Type_handler_data) ||
4195 type_handler_data->init())
4196 {
4197 sql_perror("Could not allocate type_handler_data");
4198 return 1;
4199 }
4200
4201 max_system_variables.pseudo_thread_id= ~(my_thread_id) 0;
4202 server_start_time= flush_status_time= my_time(0);
4203 my_disable_copystat_in_redel= 1;
4204
4205 global_rpl_filter= new Rpl_filter;
4206 binlog_filter= new Rpl_filter;
4207 if (!global_rpl_filter || !binlog_filter)
4208 {
4209 sql_perror("Could not allocate replication and binlog filters");
4210 exit(1);
4211 }
4212
4213#ifdef HAVE_OPENSSL
4214 if (check_openssl_compatibility())
4215 {
4216 sql_print_error("Incompatible OpenSSL version. Cannot continue...");
4217 exit(1);
4218 }
4219#endif
4220
4221 if (init_thread_environment() || mysql_init_variables())
4222 exit(1);
4223
4224 if (ignore_db_dirs_init())
4225 exit(1);
4226
4227#ifdef HAVE_TZNAME
4228 struct tm tm_tmp;
4229 localtime_r(&server_start_time,&tm_tmp);
4230 const char *tz_name= tzname[tm_tmp.tm_isdst != 0 ? 1 : 0];
4231#ifdef _WIN32
4232 /*
4233 Time zone name may be localized and contain non-ASCII characters,
4234 Convert from ANSI encoding to UTF8.
4235 */
4236 wchar_t wtz_name[sizeof(system_time_zone)];
4237 mbstowcs(wtz_name, tz_name, sizeof(system_time_zone)-1);
4238 WideCharToMultiByte(CP_UTF8,0, wtz_name, -1, system_time_zone,
4239 sizeof(system_time_zone) - 1, NULL, NULL);
4240#else
4241 strmake_buf(system_time_zone, tz_name);
4242#endif /* _WIN32 */
4243#endif /* HAVE_TZNAME */
4244
4245 /*
4246 We set SYSTEM time zone as reasonable default and
4247 also for failure of my_tz_init() and bootstrap mode.
4248 If user explicitly set time zone with --default-time-zone
4249 option we will change this value in my_tz_init().
4250 */
4251 global_system_variables.time_zone= my_tz_SYSTEM;
4252
4253#ifdef HAVE_PSI_INTERFACE
4254 /*
4255 Complete the mysql_bin_log initialization.
4256 Instrumentation keys are known only after the performance schema
4257 initialization, and can not be set in the MYSQL_BIN_LOG
4258 constructor (called before main()).
4259 */
4260 mysql_bin_log.set_psi_keys(key_BINLOG_LOCK_index,
4261 key_BINLOG_COND_relay_log_updated,
4262 key_BINLOG_COND_bin_log_updated,
4263 key_file_binlog,
4264 key_file_binlog_index,
4265 key_BINLOG_COND_queue_busy,
4266 key_LOCK_binlog_end_pos);
4267#endif
4268
4269 /*
4270 Init mutexes for the global MYSQL_BIN_LOG objects.
4271 As safe_mutex depends on what MY_INIT() does, we can't init the mutexes of
4272 global MYSQL_BIN_LOGs in their constructors, because then they would be
4273 inited before MY_INIT(). So we do it here.
4274 */
4275 mysql_bin_log.init_pthread_objects();
4276
4277 /* TODO: remove this when my_time_t is 64 bit compatible */
4278 if (!IS_TIME_T_VALID_FOR_TIMESTAMP(server_start_time))
4279 {
4280 sql_print_error("This MySQL server doesn't support dates later than 2038");
4281 exit(1);
4282 }
4283
4284 opt_log_basename= const_cast<char *>("mysql");
4285
4286 if (gethostname(glob_hostname,sizeof(glob_hostname)) < 0)
4287 {
4288 /*
4289 Get hostname of computer (used by 'show variables') and as default
4290 basename for the pid file if --log-basename is not given.
4291 */
4292 strmake(glob_hostname, STRING_WITH_LEN("localhost"));
4293 sql_print_warning("gethostname failed, using '%s' as hostname",
4294 glob_hostname);
4295 }
4296 else if (is_filename_allowed(glob_hostname, strlen(glob_hostname), FALSE))
4297 opt_log_basename= glob_hostname;
4298
4299 strmake(pidfile_name, opt_log_basename, sizeof(pidfile_name)-5);
4300 strmov(fn_ext(pidfile_name),".pid"); // Add proper extension
4301 SYSVAR_AUTOSIZE(pidfile_name_ptr, pidfile_name);
4302 set_sys_var_value_origin(&opt_tc_log_size, sys_var::AUTO);
4303
4304 /*
4305 The default-storage-engine entry in my_long_options should have a
4306 non-null default value. It was earlier intialized as
4307 (longlong)"MyISAM" in my_long_options but this triggered a
4308 compiler error in the Sun Studio 12 compiler. As a work-around we
4309 set the def_value member to 0 in my_long_options and initialize it
4310 to the correct value here.
4311
4312 From MySQL 5.5 onwards, the default storage engine is InnoDB
4313 (except in the embedded server, where the default continues to
4314 be MyISAM)
4315 */
4316#if defined(WITH_INNOBASE_STORAGE_ENGINE)
4317 default_storage_engine= const_cast<char *>("InnoDB");
4318#else
4319 default_storage_engine= const_cast<char *>("MyISAM");
4320#endif
4321 default_tmp_storage_engine= NULL;
4322 gtid_pos_auto_engines= const_cast<char *>("");
4323
4324 /*
4325 Add server status variables to the dynamic list of
4326 status variables that is shown by SHOW STATUS.
4327 Later, in plugin_init, and mysql_install_plugin
4328 new entries could be added to that list.
4329 */
4330 if (add_status_vars(status_vars))
4331 exit(1); // an error was already reported
4332
4333#ifndef DBUG_OFF
4334 /*
4335 We have few debug-only commands in com_status_vars, only visible in debug
4336 builds. for simplicity we enable the assert only in debug builds
4337
4338 There are 10 Com_ variables which don't have corresponding SQLCOM_ values:
4339 (TODO strictly speaking they shouldn't be here, should not have Com_ prefix
4340 that is. Perhaps Stmt_ ? Comstmt_ ? Prepstmt_ ?)
4341
4342 Com_admin_commands => com_other
4343 Com_create_temporary_table => com_create_tmp_table
4344 Com_drop_temporary_table => com_drop_tmp_table
4345 Com_stmt_close => com_stmt_close
4346 Com_stmt_execute => com_stmt_execute
4347 Com_stmt_fetch => com_stmt_fetch
4348 Com_stmt_prepare => com_stmt_prepare
4349 Com_stmt_reprepare => com_stmt_reprepare
4350 Com_stmt_reset => com_stmt_reset
4351 Com_stmt_send_long_data => com_stmt_send_long_data
4352
4353 With this correction the number of Com_ variables (number of elements in
4354 the array, excluding the last element - terminator) must match the number
4355 of SQLCOM_ constants.
4356 */
4357 compile_time_assert(sizeof(com_status_vars)/sizeof(com_status_vars[0]) - 1 ==
4358 SQLCOM_END + 11);
4359#endif
4360
4361 if (get_options(&remaining_argc, &remaining_argv))
4362 exit(1);
4363 if (IS_SYSVAR_AUTOSIZE(&server_version_ptr))
4364 set_server_version(server_version, sizeof(server_version));
4365
4366 if (!opt_abort)
4367 {
4368 if (IS_SYSVAR_AUTOSIZE(&server_version_ptr))
4369 sql_print_information("%s (mysqld %s) starting as process %lu ...",
4370 my_progname, server_version, (ulong) getpid());
4371 else
4372 {
4373 char real_server_version[SERVER_VERSION_LENGTH];
4374 set_server_version(real_server_version, sizeof(real_server_version));
4375 sql_print_information("%s (mysqld %s as %s) starting as process %lu ...",
4376 my_progname, real_server_version, server_version,
4377 (ulong) getpid());
4378 }
4379 }
4380
4381 sf_leaking_memory= 0; // no memory leaks from now on
4382
4383#ifndef EMBEDDED_LIBRARY
4384 if (opt_abort && !opt_verbose)
4385 unireg_abort(0);
4386#endif /*!EMBEDDED_LIBRARY*/
4387
4388 DBUG_PRINT("info",("%s Ver %s for %s on %s\n",my_progname,
4389 server_version, SYSTEM_TYPE,MACHINE_TYPE));
4390
4391#ifdef HAVE_LINUX_LARGE_PAGES
4392 /* Initialize large page size */
4393 if (opt_large_pages)
4394 {
4395 SYSVAR_AUTOSIZE(opt_large_page_size, my_get_large_page_size());
4396 if (opt_large_page_size)
4397 {
4398 DBUG_PRINT("info", ("Large page set, large_page_size = %d",
4399 opt_large_page_size));
4400 my_use_large_pages= 1;
4401 my_large_page_size= opt_large_page_size;
4402 }
4403 else
4404 SYSVAR_AUTOSIZE(opt_large_pages, 0);
4405 }
4406#endif /* HAVE_LINUX_LARGE_PAGES */
4407#ifdef HAVE_SOLARIS_LARGE_PAGES
4408#define LARGE_PAGESIZE (4*1024*1024) /* 4MB */
4409#define SUPER_LARGE_PAGESIZE (256*1024*1024) /* 256MB */
4410 if (opt_large_pages)
4411 {
4412 /*
4413 tell the kernel that we want to use 4/256MB page for heap storage
4414 and also for the stack. We use 4 MByte as default and if the
4415 super-large-page is set we increase it to 256 MByte. 256 MByte
4416 is for server installations with GBytes of RAM memory where
4417 the MySQL Server will have page caches and other memory regions
4418 measured in a number of GBytes.
4419 We use as big pages as possible which isn't bigger than the above
4420 desired page sizes.
4421 */
4422 int nelem;
4423 size_t max_desired_page_size;
4424 if (opt_super_large_pages)
4425 max_desired_page_size= SUPER_LARGE_PAGESIZE;
4426 else
4427 max_desired_page_size= LARGE_PAGESIZE;
4428 nelem = getpagesizes(NULL, 0);
4429 if (nelem > 0)
4430 {
4431 size_t *pagesize = (size_t *) malloc(sizeof(size_t) * nelem);
4432 if (pagesize != NULL && getpagesizes(pagesize, nelem) > 0)
4433 {
4434 size_t max_page_size= 0;
4435 for (int i= 0; i < nelem; i++)
4436 {
4437 if (pagesize[i] > max_page_size &&
4438 pagesize[i] <= max_desired_page_size)
4439 max_page_size= pagesize[i];
4440 }
4441 free(pagesize);
4442 if (max_page_size > 0)
4443 {
4444 struct memcntl_mha mpss;
4445
4446 mpss.mha_cmd= MHA_MAPSIZE_BSSBRK;
4447 mpss.mha_pagesize= max_page_size;
4448 mpss.mha_flags= 0;
4449 memcntl(NULL, 0, MC_HAT_ADVISE, (caddr_t)&mpss, 0, 0);
4450 mpss.mha_cmd= MHA_MAPSIZE_STACK;
4451 memcntl(NULL, 0, MC_HAT_ADVISE, (caddr_t)&mpss, 0, 0);
4452 }
4453 }
4454 }
4455 }
4456#endif /* HAVE_SOLARIS_LARGE_PAGES */
4457
4458
4459#if defined(HAVE_POOL_OF_THREADS)
4460 if (IS_SYSVAR_AUTOSIZE(&threadpool_size))
4461 SYSVAR_AUTOSIZE(threadpool_size, my_getncpus());
4462#endif
4463
4464 /* connections and databases needs lots of files */
4465 {
4466 uint files, wanted_files, max_open_files, min_tc_size, extra_files,
4467 min_connections;
4468 ulong org_max_connections, org_tc_size;
4469
4470 /* Number of files reserved for temporary files */
4471 extra_files= 30;
4472 min_connections= 10;
4473 /* MyISAM requires two file handles per table. */
4474 wanted_files= (extra_files + max_connections + extra_max_connections +
4475 tc_size * 2);
4476 min_tc_size= MY_MIN(tc_size, TABLE_OPEN_CACHE_MIN);
4477 org_max_connections= max_connections;
4478 org_tc_size= tc_size;
4479
4480 /*
4481 We are trying to allocate no less than max_connections*5 file
4482 handles (i.e. we are trying to set the limit so that they will
4483 be available). In addition, we allocate no less than how much
4484 was already allocated. However below we report a warning and
4485 recompute values only if we got less file handles than were
4486 explicitly requested. No warning and re-computation occur if we
4487 can't get max_connections*5 but still got no less than was
4488 requested (value of wanted_files).
4489 */
4490 max_open_files= MY_MAX(MY_MAX(wanted_files,
4491 (max_connections + extra_max_connections)*5),
4492 open_files_limit);
4493 files= my_set_max_open_files(max_open_files);
4494 SYSVAR_AUTOSIZE_IF_CHANGED(open_files_limit, files, ulong);
4495
4496 if (files < wanted_files && global_system_variables.log_warnings)
4497 sql_print_warning("Could not increase number of max_open_files to more than %u (request: %u)", files, wanted_files);
4498
4499 /*
4500 If we have requested too much file handles than we bring
4501 max_connections in supported bounds. Still leave at least
4502 'min_connections' connections
4503 */
4504 SYSVAR_AUTOSIZE_IF_CHANGED(max_connections,
4505 (ulong) MY_MAX(MY_MIN(files- extra_files-
4506 min_tc_size*2,
4507 max_connections),
4508 min_connections),
4509 ulong);
4510
4511 /*
4512 Decrease tc_size according to max_connections, but
4513 not below min_tc_size. Outer MY_MIN() ensures that we
4514 never increase tc_size automatically (that could
4515 happen if max_connections is decreased above).
4516 */
4517 SYSVAR_AUTOSIZE_IF_CHANGED(tc_size,
4518 (ulong) MY_MIN(MY_MAX((files - extra_files -
4519 max_connections) / 2,
4520 min_tc_size),
4521 tc_size), ulong);
4522 DBUG_PRINT("warning",
4523 ("Current limits: max_open_files: %u max_connections: %ld table_cache: %ld",
4524 files, max_connections, tc_size));
4525 if (global_system_variables.log_warnings > 1 &&
4526 (max_connections < org_max_connections ||
4527 tc_size < org_tc_size))
4528 sql_print_warning("Changed limits: max_open_files: %u max_connections: %lu (was %lu) table_cache: %lu (was %lu)",
4529 files, max_connections, org_max_connections,
4530 tc_size, org_tc_size);
4531 }
4532 /*
4533 Max_connections and tc_cache are now set.
4534 Now we can fix other variables depending on this variable.
4535 */
4536
4537 /* Fix host_cache_size */
4538 if (IS_SYSVAR_AUTOSIZE(&host_cache_size))
4539 {
4540 /*
4541 The default value is 128.
4542 The autoset value is 128, plus 1 for a value of max_connections
4543 up to 500, plus 1 for every increment of 20 over 500 in the
4544 max_connections value, capped at 2000.
4545 */
4546 uint size= (HOST_CACHE_SIZE + MY_MIN(max_connections, 500) +
4547 MY_MAX(((long) max_connections)-500,0)/20);
4548 SYSVAR_AUTOSIZE(host_cache_size, size);
4549 }
4550
4551 /* Fix back_log (back_log == 0 added for MySQL compatibility) */
4552 if (back_log == 0 || IS_SYSVAR_AUTOSIZE(&back_log))
4553 {
4554 /*
4555 The default value is 150.
4556 The autoset value is 50 + max_connections / 5 capped at 900
4557 */
4558 SYSVAR_AUTOSIZE(back_log, MY_MIN(900, (50 + max_connections / 5)));
4559 }
4560
4561 unireg_init(opt_specialflag); /* Set up extern variabels */
4562 if (!(my_default_lc_messages=
4563 my_locale_by_name(lc_messages)))
4564 {
4565 sql_print_error("Unknown locale: '%s'", lc_messages);
4566 return 1;
4567 }
4568
4569 if (init_errmessage()) /* Read error messages from file */
4570 return 1;
4571 global_system_variables.lc_messages= my_default_lc_messages;
4572 global_system_variables.errmsgs= my_default_lc_messages->errmsgs->errmsgs;
4573 init_client_errs();
4574 mysql_library_init(unused,unused,unused); /* for replication */
4575 lex_init();
4576 if (item_create_init())
4577 return 1;
4578 item_init();
4579 init_pcre();
4580 /*
4581 Process a comma-separated character set list and choose
4582 the first available character set. This is mostly for
4583 test purposes, to be able to start "mysqld" even if
4584 the requested character set is not available (see bug#18743).
4585 */
4586 for (;;)
4587 {
4588 char *next_character_set_name= strchr(default_character_set_name, ',');
4589 if (next_character_set_name)
4590 *next_character_set_name++= '\0';
4591 if (!(default_charset_info=
4592 get_charset_by_csname(default_character_set_name,
4593 MY_CS_PRIMARY, MYF(MY_WME))))
4594 {
4595 if (next_character_set_name)
4596 {
4597 default_character_set_name= next_character_set_name;
4598 default_collation_name= 0; // Ignore collation
4599 }
4600 else
4601 return 1; // Eof of the list
4602 }
4603 else
4604 break;
4605 }
4606
4607 if (default_collation_name)
4608 {
4609 CHARSET_INFO *default_collation;
4610 default_collation= get_charset_by_name(default_collation_name, MYF(0));
4611 if (!default_collation)
4612 {
4613#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
4614 buffered_logs.print();
4615 buffered_logs.cleanup();
4616#endif
4617 sql_print_error(ER_DEFAULT(ER_UNKNOWN_COLLATION), default_collation_name);
4618 return 1;
4619 }
4620 if (!my_charset_same(default_charset_info, default_collation))
4621 {
4622 sql_print_error(ER_DEFAULT(ER_COLLATION_CHARSET_MISMATCH),
4623 default_collation_name,
4624 default_charset_info->csname);
4625 return 1;
4626 }
4627 default_charset_info= default_collation;
4628 }
4629 /* Set collactions that depends on the default collation */
4630 global_system_variables.collation_server= default_charset_info;
4631 global_system_variables.collation_database= default_charset_info;
4632 if (is_supported_parser_charset(default_charset_info))
4633 {
4634 global_system_variables.collation_connection= default_charset_info;
4635 global_system_variables.character_set_results= default_charset_info;
4636 global_system_variables.character_set_client= default_charset_info;
4637 }
4638 else
4639 {
4640 sql_print_warning("'%s' can not be used as client character set. "
4641 "'%s' will be used as default client character set.",
4642 default_charset_info->csname,
4643 my_charset_latin1.csname);
4644 global_system_variables.collation_connection= &my_charset_latin1;
4645 global_system_variables.character_set_results= &my_charset_latin1;
4646 global_system_variables.character_set_client= &my_charset_latin1;
4647 }
4648
4649 if (!(character_set_filesystem=
4650 get_charset_by_csname(character_set_filesystem_name,
4651 MY_CS_PRIMARY, MYF(MY_WME))))
4652 return 1;
4653 global_system_variables.character_set_filesystem= character_set_filesystem;
4654
4655 if (!(my_default_lc_time_names=
4656 my_locale_by_name(lc_time_names_name)))
4657 {
4658 sql_print_error("Unknown locale: '%s'", lc_time_names_name);
4659 return 1;
4660 }
4661 global_system_variables.lc_time_names= my_default_lc_time_names;
4662
4663 /* check log options and issue warnings if needed */
4664 if (opt_log && opt_logname && *opt_logname &&
4665 !(log_output_options & (LOG_FILE | LOG_NONE)))
4666 sql_print_warning("Although a path was specified for the "
4667 "--log option, log tables are used. "
4668 "To enable logging to files use the --log-output option.");
4669
4670 if (global_system_variables.sql_log_slow && opt_slow_logname &&
4671 *opt_slow_logname &&
4672 !(log_output_options & (LOG_FILE | LOG_NONE)))
4673 sql_print_warning("Although a path was specified for the "
4674 "--log-slow-queries option, log tables are used. "
4675 "To enable logging to files use the --log-output=file option.");
4676
4677 if (!opt_logname || !*opt_logname)
4678 make_default_log_name(&opt_logname, ".log", false);
4679 if (!opt_slow_logname || !*opt_slow_logname)
4680 make_default_log_name(&opt_slow_logname, "-slow.log", false);
4681
4682#if defined(ENABLED_DEBUG_SYNC)
4683 /* Initialize the debug sync facility. See debug_sync.cc. */
4684 if (debug_sync_init())
4685 return 1; /* purecov: tested */
4686#endif /* defined(ENABLED_DEBUG_SYNC) */
4687
4688#if (ENABLE_TEMP_POOL)
4689 if (use_temp_pool && my_bitmap_init(&temp_pool,0,1024,1))
4690 return 1;
4691#else
4692 use_temp_pool= 0;
4693#endif
4694
4695 if (my_dboptions_cache_init())
4696 return 1;
4697
4698 /*
4699 Ensure that lower_case_table_names is set on system where we have case
4700 insensitive names. If this is not done the users MyISAM tables will
4701 get corrupted if accesses with names of different case.
4702 */
4703 DBUG_PRINT("info", ("lower_case_table_names: %d", lower_case_table_names));
4704 SYSVAR_AUTOSIZE(lower_case_file_system,
4705 test_if_case_insensitive(mysql_real_data_home));
4706 if (!lower_case_table_names && lower_case_file_system == 1)
4707 {
4708 if (lower_case_table_names_used)
4709 {
4710 sql_print_error("The server option 'lower_case_table_names' is "
4711 "configured to use case sensitive table names but the "
4712 "data directory resides on a case-insensitive file system. "
4713 "Please use a case sensitive file system for your data "
4714 "directory or switch to a case-insensitive table name "
4715 "mode.");
4716 return 1;
4717 }
4718 else
4719 {
4720 if (global_system_variables.log_warnings)
4721 sql_print_warning("Setting lower_case_table_names=2 because file "
4722 "system for %s is case insensitive", mysql_real_data_home);
4723 SYSVAR_AUTOSIZE(lower_case_table_names, 2);
4724 }
4725 }
4726 else if (lower_case_table_names == 2 &&
4727 !(lower_case_file_system= (lower_case_file_system == 1)))
4728 {
4729 if (global_system_variables.log_warnings)
4730 sql_print_warning("lower_case_table_names was set to 2, even though your "
4731 "the file system '%s' is case sensitive. Now setting "
4732 "lower_case_table_names to 0 to avoid future problems.",
4733 mysql_real_data_home);
4734 SYSVAR_AUTOSIZE(lower_case_table_names, 0);
4735 }
4736 else
4737 {
4738 lower_case_file_system= (lower_case_file_system == 1);
4739 }
4740
4741 /* Reset table_alias_charset, now that lower_case_table_names is set. */
4742 table_alias_charset= (lower_case_table_names ?
4743 files_charset_info :
4744 &my_charset_bin);
4745
4746 if (ignore_db_dirs_process_additions())
4747 {
4748 sql_print_error("An error occurred while storing ignore_db_dirs to a hash.");
4749 return 1;
4750 }
4751
4752 global_system_variables.in_subquery_conversion_threshold= IN_SUBQUERY_CONVERSION_THRESHOLD;
4753
4754 return 0;
4755}
4756
4757
4758static int init_thread_environment()
4759{
4760 DBUG_ENTER("init_thread_environment");
4761 mysql_mutex_init(key_LOCK_thread_count, &LOCK_thread_count, MY_MUTEX_INIT_FAST);
4762 mysql_mutex_init(key_LOCK_thread_cache, &LOCK_thread_cache, MY_MUTEX_INIT_FAST);
4763 mysql_mutex_init(key_LOCK_start_thread, &LOCK_start_thread, MY_MUTEX_INIT_FAST);
4764 mysql_mutex_init(key_LOCK_status, &LOCK_status, MY_MUTEX_INIT_FAST);
4765 mysql_mutex_init(key_LOCK_show_status, &LOCK_show_status, MY_MUTEX_INIT_SLOW);
4766 mysql_mutex_init(key_LOCK_delayed_insert,
4767 &LOCK_delayed_insert, MY_MUTEX_INIT_FAST);
4768 mysql_mutex_init(key_LOCK_delayed_status,
4769 &LOCK_delayed_status, MY_MUTEX_INIT_FAST);
4770 mysql_mutex_init(key_LOCK_delayed_create,
4771 &LOCK_delayed_create, MY_MUTEX_INIT_SLOW);
4772 mysql_mutex_init(key_LOCK_crypt, &LOCK_crypt, MY_MUTEX_INIT_FAST);
4773 mysql_mutex_init(key_LOCK_user_conn, &LOCK_user_conn, MY_MUTEX_INIT_FAST);
4774 mysql_mutex_init(key_LOCK_active_mi, &LOCK_active_mi, MY_MUTEX_INIT_FAST);
4775 mysql_mutex_init(key_LOCK_global_system_variables,
4776 &LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
4777 mysql_mutex_record_order(&LOCK_active_mi, &LOCK_global_system_variables);
4778 mysql_mutex_record_order(&LOCK_status, &LOCK_thread_count);
4779 mysql_prlock_init(key_rwlock_LOCK_system_variables_hash,
4780 &LOCK_system_variables_hash);
4781 mysql_mutex_init(key_LOCK_prepared_stmt_count,
4782 &LOCK_prepared_stmt_count, MY_MUTEX_INIT_FAST);
4783 mysql_mutex_init(key_LOCK_error_messages,
4784 &LOCK_error_messages, MY_MUTEX_INIT_FAST);
4785 mysql_mutex_init(key_LOCK_uuid_short_generator,
4786 &LOCK_short_uuid_generator, MY_MUTEX_INIT_FAST);
4787 mysql_mutex_init(key_LOCK_connection_count,
4788 &LOCK_connection_count, MY_MUTEX_INIT_FAST);
4789 mysql_mutex_init(key_LOCK_thread_id,
4790 &LOCK_thread_id, MY_MUTEX_INIT_FAST);
4791 mysql_mutex_init(key_LOCK_stats, &LOCK_stats, MY_MUTEX_INIT_FAST);
4792 mysql_mutex_init(key_LOCK_global_user_client_stats,
4793 &LOCK_global_user_client_stats, MY_MUTEX_INIT_FAST);
4794 mysql_mutex_init(key_LOCK_global_table_stats,
4795 &LOCK_global_table_stats, MY_MUTEX_INIT_FAST);
4796 mysql_mutex_init(key_LOCK_global_index_stats,
4797 &LOCK_global_index_stats, MY_MUTEX_INIT_FAST);
4798 mysql_mutex_init(key_LOCK_prepare_ordered, &LOCK_prepare_ordered,
4799 MY_MUTEX_INIT_SLOW);
4800 mysql_cond_init(key_COND_prepare_ordered, &COND_prepare_ordered, NULL);
4801 mysql_mutex_init(key_LOCK_after_binlog_sync, &LOCK_after_binlog_sync,
4802 MY_MUTEX_INIT_SLOW);
4803 mysql_mutex_init(key_LOCK_commit_ordered, &LOCK_commit_ordered,
4804 MY_MUTEX_INIT_SLOW);
4805 mysql_mutex_init(key_LOCK_slave_background, &LOCK_slave_background,
4806 MY_MUTEX_INIT_SLOW);
4807 mysql_cond_init(key_COND_slave_background, &COND_slave_background, NULL);
4808
4809#ifdef HAVE_OPENSSL
4810 mysql_mutex_init(key_LOCK_des_key_file,
4811 &LOCK_des_key_file, MY_MUTEX_INIT_FAST);
4812#ifdef HAVE_OPENSSL10
4813 openssl_stdlocks= (openssl_lock_t*) OPENSSL_malloc(CRYPTO_num_locks() *
4814 sizeof(openssl_lock_t));
4815 for (int i= 0; i < CRYPTO_num_locks(); ++i)
4816 mysql_rwlock_init(key_rwlock_openssl, &openssl_stdlocks[i].lock);
4817 CRYPTO_set_dynlock_create_callback(openssl_dynlock_create);
4818 CRYPTO_set_dynlock_destroy_callback(openssl_dynlock_destroy);
4819 CRYPTO_set_dynlock_lock_callback(openssl_lock);
4820 CRYPTO_set_locking_callback(openssl_lock_function);
4821#endif /* HAVE_OPENSSL10 */
4822#endif /* HAVE_OPENSSL */
4823 mysql_rwlock_init(key_rwlock_LOCK_sys_init_connect, &LOCK_sys_init_connect);
4824 mysql_rwlock_init(key_rwlock_LOCK_sys_init_slave, &LOCK_sys_init_slave);
4825 mysql_rwlock_init(key_rwlock_LOCK_grant, &LOCK_grant);
4826 mysql_cond_init(key_COND_thread_count, &COND_thread_count, NULL);
4827 mysql_cond_init(key_COND_thread_cache, &COND_thread_cache, NULL);
4828 mysql_cond_init(key_COND_start_thread, &COND_start_thread, NULL);
4829 mysql_cond_init(key_COND_flush_thread_cache, &COND_flush_thread_cache, NULL);
4830#ifdef HAVE_REPLICATION
4831 mysql_mutex_init(key_LOCK_rpl_status, &LOCK_rpl_status, MY_MUTEX_INIT_FAST);
4832#endif
4833 mysql_mutex_init(key_LOCK_server_started,
4834 &LOCK_server_started, MY_MUTEX_INIT_FAST);
4835 mysql_cond_init(key_COND_server_started, &COND_server_started, NULL);
4836 sp_cache_init();
4837#ifdef HAVE_EVENT_SCHEDULER
4838 Events::init_mutexes();
4839#endif
4840 init_show_explain_psi_keys();
4841 /* Parameter for threads created for connections */
4842 (void) pthread_attr_init(&connection_attrib);
4843 (void) pthread_attr_setdetachstate(&connection_attrib,
4844 PTHREAD_CREATE_DETACHED);
4845 pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM);
4846
4847#ifdef HAVE_REPLICATION
4848 rpl_init_gtid_slave_state();
4849 rpl_init_gtid_waiting();
4850#endif
4851
4852 DBUG_RETURN(0);
4853}
4854
4855
4856#ifdef HAVE_OPENSSL10
4857static openssl_lock_t *openssl_dynlock_create(const char *file, int line)
4858{
4859 openssl_lock_t *lock= new openssl_lock_t;
4860 mysql_rwlock_init(key_rwlock_openssl, &lock->lock);
4861 return lock;
4862}
4863
4864
4865static void openssl_dynlock_destroy(openssl_lock_t *lock, const char *file,
4866 int line)
4867{
4868 mysql_rwlock_destroy(&lock->lock);
4869 delete lock;
4870}
4871
4872
4873static void openssl_lock_function(int mode, int n, const char *file, int line)
4874{
4875 if (n < 0 || n > CRYPTO_num_locks())
4876 {
4877 /* Lock number out of bounds. */
4878 sql_print_error("Fatal: OpenSSL interface problem (n = %d)", n);
4879 abort();
4880 }
4881 openssl_lock(mode, &openssl_stdlocks[n], file, line);
4882}
4883
4884
4885static void openssl_lock(int mode, openssl_lock_t *lock, const char *file,
4886 int line)
4887{
4888 int err;
4889 char const *what;
4890
4891 switch (mode) {
4892 case CRYPTO_LOCK|CRYPTO_READ:
4893 what = "read lock";
4894 err= mysql_rwlock_rdlock(&lock->lock);
4895 break;
4896 case CRYPTO_LOCK|CRYPTO_WRITE:
4897 what = "write lock";
4898 err= mysql_rwlock_wrlock(&lock->lock);
4899 break;
4900 case CRYPTO_UNLOCK|CRYPTO_READ:
4901 case CRYPTO_UNLOCK|CRYPTO_WRITE:
4902 what = "unlock";
4903 err= mysql_rwlock_unlock(&lock->lock);
4904 break;
4905 default:
4906 /* Unknown locking mode. */
4907 sql_print_error("Fatal: OpenSSL interface problem (mode=0x%x)", mode);
4908 abort();
4909 }
4910 if (err)
4911 {
4912 sql_print_error("Fatal: can't %s OpenSSL lock", what);
4913 abort();
4914 }
4915}
4916#endif /* HAVE_OPENSSL10 */
4917
4918static void init_ssl()
4919{
4920#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
4921 if (opt_use_ssl)
4922 {
4923 enum enum_ssl_init_error error= SSL_INITERR_NOERROR;
4924
4925 /* having ssl_acceptor_fd != 0 signals the use of SSL */
4926 ssl_acceptor_fd= new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert,
4927 opt_ssl_ca, opt_ssl_capath,
4928 opt_ssl_cipher, &error,
4929 opt_ssl_crl, opt_ssl_crlpath);
4930 DBUG_PRINT("info",("ssl_acceptor_fd: %p", ssl_acceptor_fd));
4931 if (!ssl_acceptor_fd)
4932 {
4933 sql_print_warning("Failed to setup SSL");
4934 sql_print_warning("SSL error: %s", sslGetErrString(error));
4935 opt_use_ssl = 0;
4936 have_ssl= SHOW_OPTION_DISABLED;
4937 }
4938 if (global_system_variables.log_warnings > 0)
4939 {
4940 ulong err;
4941 while ((err= ERR_get_error()))
4942 sql_print_warning("SSL error: %s", ERR_error_string(err, NULL));
4943 }
4944 else
4945 ERR_remove_state(0);
4946 }
4947 else
4948 {
4949 have_ssl= SHOW_OPTION_DISABLED;
4950 }
4951 if (des_key_file)
4952 load_des_key_file(des_key_file);
4953#endif /* HAVE_OPENSSL && ! EMBEDDED_LIBRARY */
4954}
4955
4956
4957static void end_ssl()
4958{
4959#ifdef HAVE_OPENSSL
4960#ifndef EMBEDDED_LIBRARY
4961 if (ssl_acceptor_fd)
4962 {
4963 free_vio_ssl_acceptor_fd(ssl_acceptor_fd);
4964 ssl_acceptor_fd= 0;
4965 }
4966#endif /* ! EMBEDDED_LIBRARY */
4967#endif /* HAVE_OPENSSL */
4968}
4969
4970#ifdef _WIN32
4971/**
4972 Registers a file to be collected when Windows Error Reporting creates a crash
4973 report.
4974*/
4975#include <werapi.h>
4976static void add_file_to_crash_report(char *file)
4977{
4978 wchar_t wfile[MAX_PATH+1]= {0};
4979 if (mbstowcs(wfile, file, MAX_PATH) != (size_t)-1)
4980 {
4981 WerRegisterFile(wfile, WerRegFileTypeOther, WER_FILE_ANONYMOUS_DATA);
4982 }
4983}
4984#endif
4985
4986#define init_default_storage_engine(X,Y) \
4987 init_default_storage_engine_impl(#X, X, &global_system_variables.Y)
4988
4989static int init_default_storage_engine_impl(const char *opt_name,
4990 char *engine_name, plugin_ref *res)
4991{
4992 if (!engine_name)
4993 {
4994 *res= 0;
4995 return 0;
4996 }
4997
4998 LEX_CSTRING name= { engine_name, strlen(engine_name) };
4999 plugin_ref plugin;
5000 handlerton *hton;
5001 if ((plugin= ha_resolve_by_name(0, &name, false)))
5002 hton= plugin_hton(plugin);
5003 else
5004 {
5005 sql_print_error("Unknown/unsupported storage engine: %s", engine_name);
5006 return 1;
5007 }
5008 if (!ha_storage_engine_is_enabled(hton))
5009 {
5010 if (!opt_bootstrap)
5011 {
5012 sql_print_error("%s (%s) is not available", opt_name, engine_name);
5013 return 1;
5014 }
5015 DBUG_ASSERT(*res);
5016 }
5017 else
5018 {
5019 /*
5020 Need to unlock as global_system_variables.table_plugin
5021 was acquired during plugin_init()
5022 */
5023 mysql_mutex_lock(&LOCK_global_system_variables);
5024 if (*res)
5025 plugin_unlock(0, *res);
5026 *res= plugin;
5027 mysql_mutex_unlock(&LOCK_global_system_variables);
5028 }
5029 return 0;
5030}
5031
5032
5033static int
5034init_gtid_pos_auto_engines(void)
5035{
5036 plugin_ref *plugins;
5037
5038 /*
5039 For the command-line option --gtid_pos_auto_engines, we allow (and ignore)
5040 engines that are unknown. This is convenient, since it allows to set
5041 default auto-create engines that might not be used by particular users.
5042 The option sets a list of storage engines that will have gtid position
5043 table auto-created for them if needed. And if the engine is not available,
5044 then it will certainly not be needed.
5045 */
5046 if (gtid_pos_auto_engines)
5047 plugins= resolve_engine_list(NULL, gtid_pos_auto_engines,
5048 strlen(gtid_pos_auto_engines), false, false);
5049 else
5050 plugins= resolve_engine_list(NULL, "", 0, false, false);
5051 if (!plugins)
5052 return 1;
5053 mysql_mutex_lock(&LOCK_global_system_variables);
5054 opt_gtid_pos_auto_plugins= plugins;
5055 mysql_mutex_unlock(&LOCK_global_system_variables);
5056 return 0;
5057}
5058
5059
5060static int init_server_components()
5061{
5062 DBUG_ENTER("init_server_components");
5063 /*
5064 We need to call each of these following functions to ensure that
5065 all things are initialized so that unireg_abort() doesn't fail
5066 */
5067 mdl_init();
5068 if (tdc_init() || hostname_cache_init())
5069 unireg_abort(1);
5070
5071 query_cache_set_min_res_unit(query_cache_min_res_unit);
5072 query_cache_result_size_limit(query_cache_limit);
5073 /* if we set size of QC non zero in config then probably we want it ON */
5074 if (query_cache_size != 0 &&
5075 global_system_variables.query_cache_type == 0 &&
5076 !IS_SYSVAR_AUTOSIZE(&query_cache_size))
5077 {
5078 global_system_variables.query_cache_type= 1;
5079 }
5080 query_cache_init();
5081 DBUG_ASSERT(query_cache_size < ULONG_MAX);
5082 query_cache_resize((ulong)query_cache_size);
5083 my_rnd_init(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2);
5084 setup_fpu();
5085 init_thr_lock();
5086
5087#ifndef EMBEDDED_LIBRARY
5088 if (init_thr_timer(thread_scheduler->max_threads + extra_max_connections))
5089 {
5090 fprintf(stderr, "Can't initialize timers\n");
5091 unireg_abort(1);
5092 }
5093#endif
5094
5095 my_uuid_init((ulong) (my_rnd(&sql_rand))*12345,12345);
5096#ifdef HAVE_REPLICATION
5097 init_slave_list();
5098#endif
5099 wt_init();
5100
5101 /* Setup logs */
5102
5103 setup_log_handling();
5104
5105 /*
5106 Enable old-fashioned error log, except when the user has requested
5107 help information. Since the implementation of plugin server
5108 variables the help output is now written much later.
5109 */
5110#ifdef _WIN32
5111 if (opt_console)
5112 opt_error_log= false;
5113#endif
5114
5115 if (opt_error_log && !opt_abort)
5116 {
5117 if (!log_error_file_ptr[0])
5118 {
5119 fn_format(log_error_file, pidfile_name, mysql_data_home, ".err",
5120 MY_REPLACE_EXT); /* replace '.<domain>' by '.err', bug#4997 */
5121 SYSVAR_AUTOSIZE(log_error_file_ptr, log_error_file);
5122 }
5123 else
5124 {
5125 fn_format(log_error_file, log_error_file_ptr, mysql_data_home, ".err",
5126 MY_UNPACK_FILENAME | MY_SAFE_PATH);
5127 log_error_file_ptr= log_error_file;
5128 }
5129 if (!log_error_file[0])
5130 opt_error_log= 0; // Too long file name
5131 else
5132 {
5133 my_bool res;
5134#ifndef EMBEDDED_LIBRARY
5135 res= reopen_fstreams(log_error_file, stdout, stderr);
5136#else
5137 res= reopen_fstreams(log_error_file, NULL, stderr);
5138#endif
5139
5140 if (!res)
5141 setbuf(stderr, NULL);
5142
5143#ifdef _WIN32
5144 /* Add error log to windows crash reporting. */
5145 add_file_to_crash_report(log_error_file);
5146#endif
5147 }
5148 }
5149
5150 /* set up the hook before initializing plugins which may use it */
5151 error_handler_hook= my_message_sql;
5152 proc_info_hook= set_thd_stage_info;
5153
5154#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
5155 /*
5156 Parsing the performance schema command line option may have reported
5157 warnings/information messages.
5158 Now that the logger is finally available, and redirected
5159 to the proper file when the --log--error option is used,
5160 print the buffered messages to the log.
5161 */
5162 buffered_logs.print();
5163 buffered_logs.cleanup();
5164#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
5165
5166#ifndef EMBEDDED_LIBRARY
5167 /*
5168 Now that the logger is available, redirect character set
5169 errors directly to the logger
5170 (instead of the buffered_logs used at the server startup time).
5171 */
5172 my_charset_error_reporter= charset_error_reporter;
5173#endif
5174
5175 xid_cache_init();
5176
5177 /* need to configure logging before initializing storage engines */
5178 if (!opt_bin_log_used && !WSREP_ON)
5179 {
5180 if (opt_log_slave_updates)
5181 sql_print_warning("You need to use --log-bin to make "
5182 "--log-slave-updates work.");
5183 if (binlog_format_used)
5184 sql_print_warning("You need to use --log-bin to make "
5185 "--binlog-format work.");
5186 }
5187
5188 /* Check that we have not let the format to unspecified at this point */
5189 DBUG_ASSERT((uint)global_system_variables.binlog_format <=
5190 array_elements(binlog_format_names)-1);
5191
5192#ifdef HAVE_REPLICATION
5193 if (opt_log_slave_updates && replicate_same_server_id)
5194 {
5195 if (opt_bin_log)
5196 {
5197 sql_print_error("using --replicate-same-server-id in conjunction with "
5198 "--log-slave-updates is impossible, it would lead to "
5199 "infinite loops in this server.");
5200 unireg_abort(1);
5201 }
5202 else
5203 sql_print_warning("using --replicate-same-server-id in conjunction with "
5204 "--log-slave-updates would lead to infinite loops in "
5205 "this server. However this will be ignored as the "
5206 "--log-bin option is not defined.");
5207 }
5208#endif
5209
5210 if (opt_bin_log)
5211 {
5212 /* Reports an error and aborts, if the --log-bin's path
5213 is a directory.*/
5214 if (opt_bin_logname[0] &&
5215 opt_bin_logname[strlen(opt_bin_logname) - 1] == FN_LIBCHAR)
5216 {
5217 sql_print_error("Path '%s' is a directory name, please specify "
5218 "a file name for --log-bin option", opt_bin_logname);
5219 unireg_abort(1);
5220 }
5221
5222 /* Reports an error and aborts, if the --log-bin-index's path
5223 is a directory.*/
5224 if (opt_binlog_index_name &&
5225 opt_binlog_index_name[strlen(opt_binlog_index_name) - 1]
5226 == FN_LIBCHAR)
5227 {
5228 sql_print_error("Path '%s' is a directory name, please specify "
5229 "a file name for --log-bin-index option",
5230 opt_binlog_index_name);
5231 unireg_abort(1);
5232 }
5233
5234 char buf[FN_REFLEN];
5235 const char *ln;
5236 ln= mysql_bin_log.generate_name(opt_bin_logname, "-bin", 1, buf);
5237 if (!opt_bin_logname[0] && !opt_binlog_index_name)
5238 {
5239 /*
5240 User didn't give us info to name the binlog index file.
5241 Picking `hostname`-bin.index like did in 4.x, causes replication to
5242 fail if the hostname is changed later. So, we would like to instead
5243 require a name. But as we don't want to break many existing setups, we
5244 only give warning, not error.
5245 */
5246 sql_print_warning("No argument was provided to --log-bin and "
5247 "neither --log-basename or --log-bin-index where "
5248 "used; This may cause repliction to break when this "
5249 "server acts as a master and has its hostname "
5250 "changed! Please use '--log-basename=%s' or "
5251 "'--log-bin=%s' to avoid this problem.",
5252 opt_log_basename, ln);
5253 }
5254 if (ln == buf)
5255 opt_bin_logname= my_once_strdup(buf, MYF(MY_WME));
5256 }
5257
5258 /*
5259 Since some wsrep threads (THDs) are create before plugins are
5260 initialized, LOCK_plugin mutex needs to be initialized here.
5261 */
5262 plugin_mutex_init();
5263
5264 /*
5265 Wsrep initialization must happen at this point, because:
5266 - opt_bin_logname must be known when starting replication
5267 since SST may need it
5268 - SST may modify binlog index file, so it must be opened
5269 after SST has happened
5270
5271 We also (unconditionally) initialize wsrep LOCKs and CONDs.
5272 It is because they are used while accessing wsrep system
5273 variables even when a wsrep provider is not loaded.
5274 */
5275
5276 /* It's now safe to use thread specific memory */
5277 mysqld_server_initialized= 1;
5278
5279#ifndef EMBEDDED_LIBRARY
5280 wsrep_thr_init();
5281#endif
5282
5283 if (WSREP_ON && !wsrep_recovery && !opt_abort) /* WSREP BEFORE SE */
5284 {
5285 if (opt_bootstrap) // bootsrap option given - disable wsrep functionality
5286 {
5287 wsrep_provider_init(WSREP_NONE);
5288 if (wsrep_init())
5289 unireg_abort(1);
5290 }
5291 else // full wsrep initialization
5292 {
5293 // add basedir/bin to PATH to resolve wsrep script names
5294 char* const tmp_path= (char*)my_alloca(strlen(mysql_home) +
5295 strlen("/bin") + 1);
5296 if (tmp_path)
5297 {
5298 strcpy(tmp_path, mysql_home);
5299 strcat(tmp_path, "/bin");
5300 wsrep_prepend_PATH(tmp_path);
5301 }
5302 else
5303 {
5304 WSREP_ERROR("Could not append %s/bin to PATH", mysql_home);
5305 }
5306 my_afree(tmp_path);
5307
5308 if (wsrep_before_SE())
5309 {
5310 set_ports(); // this is also called in network_init() later but we need
5311 // to know mysqld_port now - lp:1071882
5312 wsrep_init_startup(true);
5313 }
5314 }
5315 }
5316
5317 if (opt_bin_log)
5318 {
5319 if (mysql_bin_log.open_index_file(opt_binlog_index_name, opt_bin_logname,
5320 TRUE))
5321 {
5322 unireg_abort(1);
5323 }
5324
5325 log_bin_basename=
5326 rpl_make_log_name(opt_bin_logname, pidfile_name,
5327 opt_bin_logname ? "" : "-bin");
5328 log_bin_index=
5329 rpl_make_log_name(opt_binlog_index_name, log_bin_basename, ".index");
5330 if (log_bin_basename == NULL || log_bin_index == NULL)
5331 {
5332 sql_print_error("Unable to create replication path names:"
5333 " out of memory or path names too long"
5334 " (path name exceeds " STRINGIFY_ARG(FN_REFLEN)
5335 " or file name exceeds " STRINGIFY_ARG(FN_LEN) ").");
5336 unireg_abort(1);
5337 }
5338 }
5339
5340#ifndef EMBEDDED_LIBRARY
5341 DBUG_PRINT("debug",
5342 ("opt_bin_logname: %s, opt_relay_logname: %s, pidfile_name: %s",
5343 opt_bin_logname, opt_relay_logname, pidfile_name));
5344 if (opt_relay_logname)
5345 {
5346 relay_log_basename=
5347 rpl_make_log_name(opt_relay_logname, pidfile_name,
5348 opt_relay_logname ? "" : "-relay-bin");
5349 relay_log_index=
5350 rpl_make_log_name(opt_relaylog_index_name, relay_log_basename, ".index");
5351 if (relay_log_basename == NULL || relay_log_index == NULL)
5352 {
5353 sql_print_error("Unable to create replication path names:"
5354 " out of memory or path names too long"
5355 " (path name exceeds " STRINGIFY_ARG(FN_REFLEN)
5356 " or file name exceeds " STRINGIFY_ARG(FN_LEN) ").");
5357 unireg_abort(1);
5358 }
5359 }
5360#endif /* !EMBEDDED_LIBRARY */
5361
5362 /* call ha_init_key_cache() on all key caches to init them */
5363 process_key_caches(&ha_init_key_cache, 0);
5364
5365 init_global_table_stats();
5366 init_global_index_stats();
5367
5368 /* Allow storage engine to give real error messages */
5369 if (unlikely(ha_init_errors()))
5370 DBUG_RETURN(1);
5371
5372 tc_log= 0; // ha_initialize_handlerton() needs that
5373
5374 if (plugin_init(&remaining_argc, remaining_argv,
5375 (opt_noacl ? PLUGIN_INIT_SKIP_PLUGIN_TABLE : 0) |
5376 (opt_abort ? PLUGIN_INIT_SKIP_INITIALIZATION : 0)))
5377 {
5378 sql_print_error("Failed to initialize plugins.");
5379 unireg_abort(1);
5380 }
5381 plugins_are_initialized= TRUE; /* Don't separate from init function */
5382
5383#ifdef HAVE_REPLICATION
5384 /*
5385 Semisync is not required by other components, which justifies its
5386 initialization at this point when thread specific memory is also available.
5387 */
5388 if (repl_semisync_master.init_object() ||
5389 repl_semisync_slave.init_object())
5390 {
5391 sql_print_error("Could not initialize semisync.");
5392 unireg_abort(1);
5393 }
5394#endif
5395
5396#ifndef EMBEDDED_LIBRARY
5397 {
5398 if (Session_tracker::server_boot_verify(system_charset_info))
5399 {
5400 sql_print_error("The variable session_track_system_variables has "
5401 "invalid values.");
5402 unireg_abort(1);
5403 }
5404 }
5405#endif //EMBEDDED_LIBRARY
5406
5407 /* we do want to exit if there are any other unknown options */
5408 if (remaining_argc > 1)
5409 {
5410 int ho_error;
5411 struct my_option no_opts[]=
5412 {
5413 {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
5414 };
5415 /*
5416 We need to eat any 'loose' arguments first before we conclude
5417 that there are unprocessed options.
5418 */
5419 my_getopt_skip_unknown= 0;
5420
5421 if ((ho_error= handle_options(&remaining_argc, &remaining_argv, no_opts,
5422 mysqld_get_one_option)))
5423 unireg_abort(ho_error);
5424 /* Add back the program name handle_options removes */
5425 remaining_argc++;
5426 remaining_argv--;
5427 my_getopt_skip_unknown= TRUE;
5428
5429 if (remaining_argc > 1)
5430 {
5431 fprintf(stderr, "%s: Too many arguments (first extra is '%s').\n",
5432 my_progname, remaining_argv[1]);
5433 unireg_abort(1);
5434 }
5435 }
5436
5437 if (init_io_cache_encryption())
5438 unireg_abort(1);
5439
5440 if (opt_abort)
5441 unireg_abort(0);
5442
5443 /* if the errmsg.sys is not loaded, terminate to maintain behaviour */
5444 if (!DEFAULT_ERRMSGS[0][0])
5445 unireg_abort(1);
5446
5447 /* We have to initialize the storage engines before CSV logging */
5448 if (ha_init())
5449 {
5450 sql_print_error("Can't init databases");
5451 unireg_abort(1);
5452 }
5453
5454 if (opt_bootstrap)
5455 log_output_options= LOG_FILE;
5456 else
5457 logger.init_log_tables();
5458
5459 if (log_output_options & LOG_NONE)
5460 {
5461 /*
5462 Issue a warining if there were specified additional options to the
5463 log-output along with NONE. Probably this wasn't what user wanted.
5464 */
5465 if ((log_output_options & LOG_NONE) && (log_output_options & ~LOG_NONE))
5466 sql_print_warning("There were other values specified to "
5467 "log-output besides NONE. Disabling slow "
5468 "and general logs anyway.");
5469 logger.set_handlers(LOG_FILE, LOG_NONE, LOG_NONE);
5470 }
5471 else
5472 {
5473 /* fall back to the log files if tables are not present */
5474 LEX_CSTRING csv_name={STRING_WITH_LEN("csv")};
5475 if (!plugin_is_ready(&csv_name, MYSQL_STORAGE_ENGINE_PLUGIN))
5476 {
5477 /* purecov: begin inspected */
5478 sql_print_error("CSV engine is not present, falling back to the "
5479 "log files");
5480 SYSVAR_AUTOSIZE(log_output_options,
5481 (log_output_options & ~LOG_TABLE) | LOG_FILE);
5482 /* purecov: end */
5483 }
5484
5485 logger.set_handlers(LOG_FILE,
5486 global_system_variables.sql_log_slow ?
5487 log_output_options:LOG_NONE,
5488 opt_log ? log_output_options:LOG_NONE);
5489 }
5490
5491 if (init_default_storage_engine(default_storage_engine, table_plugin))
5492 unireg_abort(1);
5493
5494 if (default_tmp_storage_engine && !*default_tmp_storage_engine)
5495 default_tmp_storage_engine= NULL;
5496
5497 if (enforced_storage_engine && !*enforced_storage_engine)
5498 enforced_storage_engine= NULL;
5499
5500 if (init_default_storage_engine(default_tmp_storage_engine, tmp_table_plugin))
5501 unireg_abort(1);
5502
5503 if (init_default_storage_engine(enforced_storage_engine, enforced_table_plugin))
5504 unireg_abort(1);
5505
5506 if (init_gtid_pos_auto_engines())
5507 unireg_abort(1);
5508
5509#ifdef USE_ARIA_FOR_TMP_TABLES
5510 if (!ha_storage_engine_is_enabled(maria_hton) && !opt_bootstrap)
5511 {
5512 sql_print_error("Aria engine is not enabled or did not start. The Aria engine must be enabled to continue as mysqld was configured with --with-aria-tmp-tables");
5513 unireg_abort(1);
5514 }
5515#endif
5516
5517#ifdef WITH_WSREP
5518 /*
5519 Now is the right time to initialize members of wsrep startup threads
5520 that rely on plugins and other related global system variables to be
5521 initialized. This initialization was not possible before, as plugins
5522 (and thus some global system variables) are initialized after wsrep
5523 startup threads are created.
5524 Note: This only needs to be done for rsync, xtrabackup based SST methods.
5525 */
5526 if (wsrep_before_SE())
5527 wsrep_plugins_post_init();
5528
5529 if (WSREP_ON && !opt_bin_log)
5530 {
5531 wsrep_emulate_bin_log= 1;
5532 }
5533#endif
5534
5535 tc_log= get_tc_log_implementation();
5536
5537 if (tc_log->open(opt_bin_log ? opt_bin_logname : opt_tc_log_file))
5538 {
5539 sql_print_error("Can't init tc log");
5540 unireg_abort(1);
5541 }
5542
5543 if (ha_recover(0))
5544 {
5545 unireg_abort(1);
5546 }
5547
5548 if (opt_bin_log)
5549 {
5550 int error;
5551 mysql_mutex_t *log_lock= mysql_bin_log.get_log_lock();
5552 mysql_mutex_lock(log_lock);
5553 error= mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0, 0,
5554 WRITE_CACHE, max_binlog_size, 0, TRUE);
5555 mysql_mutex_unlock(log_lock);
5556 if (unlikely(error))
5557 unireg_abort(1);
5558 }
5559
5560#ifdef HAVE_REPLICATION
5561 if (opt_bin_log && expire_logs_days)
5562 {
5563 time_t purge_time= server_start_time - expire_logs_days*24*60*60;
5564 if (purge_time >= 0)
5565 mysql_bin_log.purge_logs_before_date(purge_time);
5566 }
5567#endif
5568
5569 if (opt_myisam_log)
5570 (void) mi_log(1);
5571
5572#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && !defined(EMBEDDED_LIBRARY)
5573 if (locked_in_memory)
5574 {
5575 int error;
5576 if (user_info)
5577 {
5578 DBUG_ASSERT(!getuid());
5579 if (setreuid((uid_t) -1, 0) == -1)
5580 {
5581 sql_perror("setreuid");
5582 unireg_abort(1);
5583 }
5584 error= mlockall(MCL_CURRENT);
5585 set_user(mysqld_user, user_info);
5586 }
5587 else
5588 error= mlockall(MCL_CURRENT);
5589
5590 if (unlikely(error))
5591 {
5592 if (global_system_variables.log_warnings)
5593 sql_print_warning("Failed to lock memory. Errno: %d\n",errno);
5594 locked_in_memory= 0;
5595 }
5596 }
5597#else
5598 locked_in_memory= 0;
5599#endif
5600
5601 ft_init_stopwords();
5602
5603 init_max_user_conn();
5604 init_update_queries();
5605 init_global_user_stats();
5606 init_global_client_stats();
5607 if (!opt_bootstrap)
5608 servers_init(0);
5609 init_status_vars();
5610 DBUG_RETURN(0);
5611}
5612
5613
5614#ifndef EMBEDDED_LIBRARY
5615
5616static void create_shutdown_thread()
5617{
5618#ifdef __WIN__
5619 hEventShutdown=CreateEvent(0, FALSE, FALSE, shutdown_event_name);
5620 pthread_t hThread;
5621 int error;
5622 if (unlikely((error= mysql_thread_create(key_thread_handle_shutdown,
5623 &hThread, &connection_attrib,
5624 handle_shutdown, 0))))
5625 sql_print_warning("Can't create thread to handle shutdown requests"
5626 " (errno= %d)", error);
5627
5628 // On "Stop Service" we have to do regular shutdown
5629 Service.SetShutdownEvent(hEventShutdown);
5630#endif /* __WIN__ */
5631}
5632
5633#endif /* EMBEDDED_LIBRARY */
5634
5635#if (defined(_WIN32) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY)
5636static void handle_connections_methods()
5637{
5638 pthread_t hThread;
5639 int error;
5640 DBUG_ENTER("handle_connections_methods");
5641 if (hPipe == INVALID_HANDLE_VALUE &&
5642 (!have_tcpip || opt_disable_networking) &&
5643 !opt_enable_shared_memory)
5644 {
5645 sql_print_error("TCP/IP, --shared-memory, or --named-pipe should be configured on NT OS");
5646 unireg_abort(1); // Will not return
5647 }
5648
5649 mysql_mutex_lock(&LOCK_start_thread);
5650 mysql_cond_init(key_COND_handler_count, &COND_handler_count, NULL);
5651 handler_count=0;
5652 if (hPipe != INVALID_HANDLE_VALUE)
5653 {
5654 handler_count++;
5655 if ((error= mysql_thread_create(key_thread_handle_con_namedpipes,
5656 &hThread, &connection_attrib,
5657 handle_connections_namedpipes, 0)))
5658 {
5659 sql_print_warning("Can't create thread to handle named pipes"
5660 " (errno= %d)", error);
5661 handler_count--;
5662 }
5663 }
5664 if (have_tcpip && !opt_disable_networking)
5665 {
5666 handler_count++;
5667 if ((error= mysql_thread_create(key_thread_handle_con_sockets,
5668 &hThread, &connection_attrib,
5669 handle_connections_sockets_thread, 0)))
5670 {
5671 sql_print_warning("Can't create thread to handle TCP/IP",
5672 " (errno= %d)", error);
5673 handler_count--;
5674 }
5675 }
5676#ifdef HAVE_SMEM
5677 if (opt_enable_shared_memory)
5678 {
5679 handler_count++;
5680 if ((error= mysql_thread_create(key_thread_handle_con_sharedmem,
5681 &hThread, &connection_attrib,
5682 handle_connections_shared_memory, 0)))
5683 {
5684 sql_print_warning("Can't create thread to handle shared memory",
5685 " (errno= %d)", error);
5686 handler_count--;
5687 }
5688 }
5689#endif
5690
5691 while (handler_count > 0)
5692 mysql_cond_wait(&COND_handler_count, &LOCK_start_thread);
5693 mysql_mutex_unlock(&LOCK_start_thread);
5694 DBUG_VOID_RETURN;
5695}
5696
5697void decrement_handler_count()
5698{
5699 mysql_mutex_lock(&LOCK_start_thread);
5700 if (--handler_count == 0)
5701 mysql_cond_signal(&COND_handler_count);
5702 mysql_mutex_unlock(&LOCK_start_thread);
5703 my_thread_end();
5704}
5705#else
5706#define decrement_handler_count()
5707#endif /* defined(_WIN32) || defined(HAVE_SMEM) */
5708
5709
5710#ifndef EMBEDDED_LIBRARY
5711
5712#ifndef DBUG_OFF
5713/*
5714 Debugging helper function to keep the locale database
5715 (see sql_locale.cc) and max_month_name_length and
5716 max_day_name_length variable values in consistent state.
5717*/
5718static void test_lc_time_sz()
5719{
5720 DBUG_ENTER("test_lc_time_sz");
5721 for (MY_LOCALE **loc= my_locales; *loc; loc++)
5722 {
5723 size_t max_month_len= 0;
5724 size_t max_day_len= 0;
5725 for (const char **month= (*loc)->month_names->type_names; *month; month++)
5726 {
5727 set_if_bigger(max_month_len,
5728 my_numchars_mb(&my_charset_utf8_general_ci,
5729 *month, *month + strlen(*month)));
5730 }
5731 for (const char **day= (*loc)->day_names->type_names; *day; day++)
5732 {
5733 set_if_bigger(max_day_len,
5734 my_numchars_mb(&my_charset_utf8_general_ci,
5735 *day, *day + strlen(*day)));
5736 }
5737 if ((*loc)->max_month_name_length != max_month_len ||
5738 (*loc)->max_day_name_length != max_day_len)
5739 {
5740 DBUG_PRINT("Wrong max day name(or month name) length for locale:",
5741 ("%s", (*loc)->name));
5742 DBUG_ASSERT(0);
5743 }
5744 }
5745 DBUG_VOID_RETURN;
5746}
5747#endif//DBUG_OFF
5748
5749
5750#ifdef __WIN__
5751int win_main(int argc, char **argv)
5752#else
5753int mysqld_main(int argc, char **argv)
5754#endif
5755{
5756 /*
5757 Perform basic thread library and malloc initialization,
5758 to be able to read defaults files and parse options.
5759 */
5760 my_progname= argv[0];
5761 sf_leaking_memory= 1; // no safemalloc memory leak reports if we exit early
5762 mysqld_server_started= mysqld_server_initialized= 0;
5763
5764 if (init_early_variables())
5765 exit(1);
5766
5767#ifdef HAVE_NPTL
5768 ld_assume_kernel_is_set= (getenv("LD_ASSUME_KERNEL") != 0);
5769#endif
5770#ifndef _WIN32
5771 // For windows, my_init() is called from the win specific mysqld_main
5772 if (my_init()) // init my_sys library & pthreads
5773 {
5774 fprintf(stderr, "my_init() failed.");
5775 return 1;
5776 }
5777#endif
5778
5779 orig_argc= argc;
5780 orig_argv= argv;
5781 my_getopt_use_args_separator= TRUE;
5782 load_defaults_or_exit(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv);
5783 my_getopt_use_args_separator= FALSE;
5784 defaults_argc= argc;
5785 defaults_argv= argv;
5786 remaining_argc= argc;
5787 remaining_argv= argv;
5788
5789 /* Must be initialized early for comparison of options name */
5790 system_charset_info= &my_charset_utf8_general_ci;
5791
5792 sys_var_init();
5793
5794#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
5795 /*
5796 Initialize the array of performance schema instrument configurations.
5797 */
5798 init_pfs_instrument_array();
5799#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
5800 /*
5801 Logs generated while parsing the command line
5802 options are buffered and printed later.
5803 */
5804 buffered_logs.init();
5805 my_getopt_error_reporter= buffered_option_error_reporter;
5806 my_charset_error_reporter= buffered_option_error_reporter;
5807#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
5808 pfs_param.m_pfs_instrument= const_cast<char*>("");
5809#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
5810 my_timer_init(&sys_timer_info);
5811
5812 int ho_error __attribute__((unused))= handle_early_options();
5813
5814 /* fix tdc_size */
5815 if (IS_SYSVAR_AUTOSIZE(&tdc_size))
5816 {
5817 SYSVAR_AUTOSIZE(tdc_size, MY_MIN(400 + tdc_size / 2, 2000));
5818 }
5819
5820#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
5821 if (ho_error == 0)
5822 {
5823 if (pfs_param.m_enabled && !opt_help && !opt_bootstrap)
5824 {
5825 /* Add sizing hints from the server sizing parameters. */
5826 pfs_param.m_hints.m_table_definition_cache= tdc_size;
5827 pfs_param.m_hints.m_table_open_cache= tc_size;
5828 pfs_param.m_hints.m_max_connections= max_connections;
5829 pfs_param.m_hints.m_open_files_limit= open_files_limit;
5830 PSI_hook= initialize_performance_schema(&pfs_param);
5831 if (PSI_hook == NULL)
5832 {
5833 pfs_param.m_enabled= false;
5834 buffered_logs.buffer(WARNING_LEVEL,
5835 "Performance schema disabled (reason: init failed).");
5836 }
5837 }
5838 }
5839#else
5840 /*
5841 Other provider of the instrumentation interface should
5842 initialize PSI_hook here:
5843 - HAVE_PSI_INTERFACE is for the instrumentation interface
5844 - WITH_PERFSCHEMA_STORAGE_ENGINE is for one implementation
5845 of the interface,
5846 but there could be alternate implementations, which is why
5847 these two defines are kept separate.
5848 */
5849#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
5850
5851#ifdef HAVE_PSI_INTERFACE
5852 /*
5853 Obtain the current performance schema instrumentation interface,
5854 if available.
5855 */
5856 if (PSI_hook)
5857 {
5858 PSI *psi_server= (PSI*) PSI_hook->get_interface(PSI_CURRENT_VERSION);
5859 if (likely(psi_server != NULL))
5860 {
5861 set_psi_server(psi_server);
5862
5863 /*
5864 Now that we have parsed the command line arguments, and have
5865 initialized the performance schema itself, the next step is to
5866 register all the server instruments.
5867 */
5868 init_server_psi_keys();
5869 /* Instrument the main thread */
5870 PSI_thread *psi= PSI_CALL_new_thread(key_thread_main, NULL, 0);
5871 PSI_CALL_set_thread(psi);
5872
5873 /*
5874 Now that some instrumentation is in place,
5875 recreate objects which were initialised early,
5876 so that they are instrumented as well.
5877 */
5878 my_thread_global_reinit();
5879 }
5880 }
5881#endif /* HAVE_PSI_INTERFACE */
5882
5883 init_error_log_mutex();
5884
5885 /* Initialize audit interface globals. Audit plugins are inited later. */
5886 mysql_audit_initialize();
5887
5888 /*
5889 Perform basic logger initialization logger. Should be called after
5890 MY_INIT, as it initializes mutexes. Log tables are inited later.
5891 */
5892 logger.init_base();
5893
5894#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
5895 if (ho_error)
5896 {
5897 /*
5898 Parsing command line option failed,
5899 Since we don't have a workable remaining_argc/remaining_argv
5900 to continue the server initialization, this is as far as this
5901 code can go.
5902 This is the best effort to log meaningful messages:
5903 - messages will be printed to stderr, which is not redirected yet,
5904 - messages will be printed in the NT event log, for windows.
5905 */
5906 buffered_logs.print();
5907 buffered_logs.cleanup();
5908 /*
5909 Not enough initializations for unireg_abort()
5910 Using exit() for windows.
5911 */
5912 exit (ho_error);
5913 }
5914#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
5915
5916#ifdef _CUSTOMSTARTUPCONFIG_
5917 if (_cust_check_startup())
5918 {
5919 / * _cust_check_startup will report startup failure error * /
5920 exit(1);
5921 }
5922#endif
5923
5924 if (init_common_variables())
5925 unireg_abort(1); // Will do exit
5926
5927 init_signals();
5928
5929 ulonglong new_thread_stack_size;
5930 new_thread_stack_size= my_setstacksize(&connection_attrib,
5931 (size_t)my_thread_stack_size);
5932 if (new_thread_stack_size != my_thread_stack_size)
5933 SYSVAR_AUTOSIZE(my_thread_stack_size, new_thread_stack_size);
5934
5935 (void) thr_setconcurrency(concurrency); // 10 by default
5936
5937 select_thread=pthread_self();
5938 select_thread_in_use=1;
5939
5940#ifdef HAVE_LIBWRAP
5941 libwrapName= my_progname+dirname_length(my_progname);
5942 openlog(libwrapName, LOG_PID, LOG_AUTH);
5943#endif
5944
5945#ifndef DBUG_OFF
5946 test_lc_time_sz();
5947 srand((uint) time(NULL));
5948#endif
5949
5950 /*
5951 We have enough space for fiddling with the argv, continue
5952 */
5953 check_data_home(mysql_real_data_home);
5954 if (my_setwd(mysql_real_data_home, opt_abort ? 0 : MYF(MY_WME)) && !opt_abort)
5955 unireg_abort(1); /* purecov: inspected */
5956
5957 /* Atomic write initialization must be done as root */
5958 my_init_atomic_write();
5959
5960 if ((user_info= check_user(mysqld_user)))
5961 {
5962#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
5963 if (locked_in_memory) // getuid() == 0 here
5964 set_effective_user(user_info);
5965 else
5966#endif
5967 set_user(mysqld_user, user_info);
5968 }
5969
5970 if (WSREP_ON && wsrep_check_opts())
5971 global_system_variables.wsrep_on= 0;
5972
5973 /*
5974 The subsequent calls may take a long time : e.g. innodb log read.
5975 Thus set the long running service control manager timeout
5976 */
5977#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
5978 Service.SetSlowStarting(slow_start_timeout);
5979#endif
5980
5981 if (init_server_components())
5982 unireg_abort(1);
5983
5984 init_ssl();
5985 network_init();
5986
5987#ifdef __WIN__
5988 if (!opt_console)
5989 {
5990 FreeConsole(); // Remove window
5991 }
5992
5993 if (fileno(stdin) >= 0)
5994 {
5995 /* Disable CRLF translation (MDEV-9409). */
5996 _setmode(fileno(stdin), O_BINARY);
5997 }
5998#endif
5999
6000#ifdef WITH_WSREP
6001 // Recover and exit.
6002 if (wsrep_recovery)
6003 {
6004 select_thread_in_use= 0;
6005 if (WSREP_ON)
6006 wsrep_recover();
6007 else
6008 sql_print_information("WSREP: disabled, skipping position recovery");
6009 unireg_abort(0);
6010 }
6011#endif
6012
6013 /*
6014 init signals & alarm
6015 After this we can't quit by a simple unireg_abort
6016 */
6017 start_signal_handler(); // Creates pidfile
6018
6019 if (mysql_rm_tmp_tables() || acl_init(opt_noacl) ||
6020 my_tz_init((THD *)0, default_tz_name, opt_bootstrap))
6021 {
6022 abort_loop=1;
6023 select_thread_in_use=0;
6024
6025 (void) pthread_kill(signal_thread, MYSQL_KILL_SIGNAL);
6026
6027 delete_pid_file(MYF(MY_WME));
6028
6029 if (mysql_socket_getfd(unix_sock) != INVALID_SOCKET)
6030 unlink(mysqld_unix_port);
6031 exit(1);
6032 }
6033
6034 if (!opt_noacl)
6035 (void) grant_init();
6036
6037 udf_init();
6038
6039 if (opt_bootstrap) /* If running with bootstrap, do not start replication. */
6040 opt_skip_slave_start= 1;
6041
6042 binlog_unsafe_map_init();
6043
6044#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
6045 initialize_performance_schema_acl(opt_bootstrap);
6046#endif
6047
6048 initialize_information_schema_acl();
6049
6050 execute_ddl_log_recovery();
6051
6052 /*
6053 Change EVENTS_ORIGINAL to EVENTS_OFF (the default value) as there is no
6054 point in using ORIGINAL during startup
6055 */
6056 if (Events::opt_event_scheduler == Events::EVENTS_ORIGINAL)
6057 Events::opt_event_scheduler= Events::EVENTS_OFF;
6058
6059 Events::set_original_state(Events::opt_event_scheduler);
6060 if (Events::init((THD*) 0, opt_noacl || opt_bootstrap))
6061 unireg_abort(1);
6062
6063 if (WSREP_ON)
6064 {
6065 if (opt_bootstrap)
6066 {
6067 /*! bootstrap wsrep init was taken care of above */
6068 }
6069 else
6070 {
6071 wsrep_SE_initialized();
6072
6073 if (wsrep_before_SE())
6074 {
6075 /*! in case of no SST wsrep waits in view handler callback */
6076 wsrep_SE_init_grab();
6077 wsrep_SE_init_done();
6078 /*! in case of SST wsrep waits for wsrep->sst_received */
6079 if (wsrep_sst_continue())
6080 {
6081 WSREP_ERROR("Failed to signal the wsrep provider to continue.");
6082 }
6083 }
6084 else
6085 {
6086 wsrep_init_startup (false);
6087 }
6088
6089 wsrep_create_appliers(wsrep_slave_threads - 1);
6090 }
6091 }
6092
6093 if (opt_bootstrap)
6094 {
6095 select_thread_in_use= 0; // Allow 'kill' to work
6096 bootstrap(mysql_stdin);
6097 if (!kill_in_progress)
6098 unireg_abort(bootstrap_error ? 1 : 0);
6099 else
6100 {
6101 sleep(2); // Wait for kill
6102 exit(0);
6103 }
6104 }
6105
6106 create_shutdown_thread();
6107 start_handle_manager();
6108
6109 /* Copy default global rpl_filter to global_rpl_filter */
6110 copy_filter_setting(global_rpl_filter, get_or_create_rpl_filter("", 0));
6111
6112 /*
6113 init_slave() must be called after the thread keys are created.
6114 Some parts of the code (e.g. SHOW STATUS LIKE 'slave_running' and other
6115 places) assume that active_mi != 0, so let's fail if it's 0 (out of
6116 memory); a message has already been printed.
6117 */
6118 if (init_slave() && !active_mi)
6119 {
6120 unireg_abort(1);
6121 }
6122
6123 if (opt_init_file && *opt_init_file)
6124 {
6125 if (read_init_file(opt_init_file))
6126 unireg_abort(1);
6127 }
6128
6129 disable_log_notes= 0; /* Startup done, now we can give notes again */
6130
6131 if (IS_SYSVAR_AUTOSIZE(&server_version_ptr))
6132 sql_print_information(ER_DEFAULT(ER_STARTUP), my_progname, server_version,
6133 ((mysql_socket_getfd(unix_sock) == INVALID_SOCKET) ?
6134 (char*) "" : mysqld_unix_port),
6135 mysqld_port, MYSQL_COMPILATION_COMMENT);
6136 else
6137 {
6138 char real_server_version[2 * SERVER_VERSION_LENGTH + 10];
6139
6140 set_server_version(real_server_version, sizeof(real_server_version));
6141 strcat(real_server_version, "' as '");
6142 strcat(real_server_version, server_version);
6143
6144 sql_print_information(ER_DEFAULT(ER_STARTUP), my_progname,
6145 real_server_version,
6146 ((mysql_socket_getfd(unix_sock) == INVALID_SOCKET) ?
6147 (char*) "" : mysqld_unix_port),
6148 mysqld_port, MYSQL_COMPILATION_COMMENT);
6149 }
6150
6151#ifndef _WIN32
6152 // try to keep fd=0 busy
6153 if (!freopen("/dev/null", "r", stdin))
6154 {
6155 // fall back on failure
6156 fclose(stdin);
6157 }
6158#endif
6159
6160#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
6161 Service.SetRunning();
6162#endif
6163
6164 /* Signal threads waiting for server to be started */
6165 mysql_mutex_lock(&LOCK_server_started);
6166 mysqld_server_started= 1;
6167 mysql_cond_signal(&COND_server_started);
6168 mysql_mutex_unlock(&LOCK_server_started);
6169
6170 MYSQL_SET_STAGE(0 ,__FILE__, __LINE__);
6171
6172 /* Memory used when everything is setup */
6173 start_memory_used= global_status_var.global_memory_used;
6174
6175#if defined(_WIN32) || defined(HAVE_SMEM)
6176 handle_connections_methods();
6177#else
6178 handle_connections_sockets();
6179#endif /* _WIN32 || HAVE_SMEM */
6180
6181 /* (void) pthread_attr_destroy(&connection_attrib); */
6182
6183 DBUG_PRINT("quit",("Exiting main thread"));
6184
6185#ifndef __WIN__
6186 mysql_mutex_lock(&LOCK_start_thread);
6187 select_thread_in_use=0; // For close_connections
6188 mysql_cond_broadcast(&COND_start_thread);
6189 mysql_mutex_unlock(&LOCK_start_thread);
6190#endif /* __WIN__ */
6191
6192 /*
6193 Disable the main thread instrumentation,
6194 to avoid recording events during the shutdown.
6195 */
6196 PSI_CALL_delete_current_thread();
6197
6198 /* Wait until cleanup is done */
6199 mysql_mutex_lock(&LOCK_thread_count);
6200 while (!ready_to_exit)
6201 mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
6202 mysql_mutex_unlock(&LOCK_thread_count);
6203
6204#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
6205 if (start_mode)
6206 Service.Stop();
6207 else
6208 {
6209 Service.SetShutdownEvent(0);
6210 if (hEventShutdown)
6211 CloseHandle(hEventShutdown);
6212 }
6213#endif
6214#if (defined(HAVE_OPENSSL) && !defined(HAVE_YASSL)) && !defined(EMBEDDED_LIBRARY)
6215 ERR_remove_state(0);
6216#endif
6217 mysqld_exit(0);
6218 return 0;
6219}
6220
6221#endif /* !EMBEDDED_LIBRARY */
6222
6223
6224/****************************************************************************
6225 Main and thread entry function for Win32
6226 (all this is needed only to run mysqld as a service on WinNT)
6227****************************************************************************/
6228
6229#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
6230void mysql_service(void *p)
6231{
6232 if (my_thread_init())
6233 abort();
6234
6235 if (use_opt_args)
6236 win_main(opt_argc, opt_argv);
6237 else
6238 win_main(Service.my_argc, Service.my_argv);
6239
6240 my_thread_end();
6241}
6242
6243
6244/* Quote string if it contains space, else copy */
6245
6246static char *add_quoted_string(char *to, const char *from, char *to_end)
6247{
6248 uint length= (uint) (to_end-to);
6249
6250 if (!strchr(from, ' '))
6251 return strmake(to, from, length-1);
6252 return strxnmov(to, length-1, "\"", from, "\"", NullS);
6253}
6254
6255
6256/**
6257 Handle basic handling of services, like installation and removal.
6258
6259 @param argv Pointer to argument list
6260 @param servicename Internal name of service
6261 @param displayname Display name of service (in taskbar ?)
6262 @param file_path Path to this program
6263 @param startup_option Startup option to mysqld
6264
6265 @retval 0 option handled
6266 @retval 1 Could not handle option
6267*/
6268
6269static bool
6270default_service_handling(char **argv,
6271 const char *servicename,
6272 const char *displayname,
6273 const char *file_path,
6274 const char *extra_opt,
6275 const char *account_name)
6276{
6277 char path_and_service[FN_REFLEN+FN_REFLEN+32], *pos, *end;
6278 const char *opt_delim;
6279 end= path_and_service + sizeof(path_and_service)-3;
6280
6281 /* We have to quote filename if it contains spaces */
6282 pos= add_quoted_string(path_and_service, file_path, end);
6283 if (extra_opt && *extra_opt)
6284 {
6285 /*
6286 Add option after file_path. There will be zero or one extra option. It's
6287 assumed to be --defaults-file=file but isn't checked. The variable (not
6288 the option name) should be quoted if it contains a string.
6289 */
6290 *pos++= ' ';
6291 if ((opt_delim= strchr(extra_opt, '=')))
6292 {
6293 size_t length= ++opt_delim - extra_opt;
6294 pos= strnmov(pos, extra_opt, length);
6295 }
6296 else
6297 opt_delim= extra_opt;
6298
6299 pos= add_quoted_string(pos, opt_delim, end);
6300 }
6301 /* We must have servicename last */
6302 *pos++= ' ';
6303 (void) add_quoted_string(pos, servicename, end);
6304
6305 if (Service.got_service_option(argv, "install"))
6306 {
6307 Service.Install(1, servicename, displayname, path_and_service,
6308 account_name);
6309 return 0;
6310 }
6311 if (Service.got_service_option(argv, "install-manual"))
6312 {
6313 Service.Install(0, servicename, displayname, path_and_service,
6314 account_name);
6315 return 0;
6316 }
6317 if (Service.got_service_option(argv, "remove"))
6318 {
6319 Service.Remove(servicename);
6320 return 0;
6321 }
6322 return 1;
6323}
6324
6325
6326int mysqld_main(int argc, char **argv)
6327{
6328 my_progname= argv[0];
6329
6330 /*
6331 When several instances are running on the same machine, we
6332 need to have an unique named hEventShudown through the
6333 application PID e.g.: MySQLShutdown1890; MySQLShutdown2342
6334 */
6335 int10_to_str((int) GetCurrentProcessId(),strmov(shutdown_event_name,
6336 "MySQLShutdown"), 10);
6337
6338 /* Must be initialized early for comparison of service name */
6339 system_charset_info= &my_charset_utf8_general_ci;
6340
6341 if (my_init())
6342 {
6343 fprintf(stderr, "my_init() failed.");
6344 return 1;
6345 }
6346
6347
6348 char file_path[FN_REFLEN];
6349 my_path(file_path, argv[0], ""); /* Find name in path */
6350 fn_format(file_path,argv[0],file_path,"", MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_RESOLVE_SYMLINKS);
6351
6352 if (argc == 2)
6353 {
6354 if (!default_service_handling(argv, MYSQL_SERVICENAME, MYSQL_SERVICENAME,
6355 file_path, "", NULL))
6356 return 0;
6357
6358 if (Service.IsService(argv[1])) /* Start an optional service */
6359 {
6360 /*
6361 Only add the service name to the groups read from the config file
6362 if it's not "MySQL". (The default service name should be 'mysqld'
6363 but we started a bad tradition by calling it MySQL from the start
6364 and we are now stuck with it.
6365 */
6366 if (my_strcasecmp(system_charset_info, argv[1],"mysql"))
6367 load_default_groups[load_default_groups_sz-2]= argv[1];
6368 start_mode= 1;
6369 Service.Init(argv[1], mysql_service);
6370 return 0;
6371 }
6372 }
6373 else if (argc == 3) /* install or remove any optional service */
6374 {
6375 if (!default_service_handling(argv, argv[2], argv[2], file_path, "",
6376 NULL))
6377 return 0;
6378 if (Service.IsService(argv[2]))
6379 {
6380 /*
6381 mysqld was started as
6382 mysqld --defaults-file=my_path\my.ini service-name
6383 */
6384 use_opt_args=1;
6385 opt_argc= 2; // Skip service-name
6386 opt_argv=argv;
6387 start_mode= 1;
6388 if (my_strcasecmp(system_charset_info, argv[2],"mysql"))
6389 load_default_groups[load_default_groups_sz-2]= argv[2];
6390 Service.Init(argv[2], mysql_service);
6391 return 0;
6392 }
6393 }
6394 else if (argc == 4 || argc == 5)
6395 {
6396 /*
6397 This may seem strange, because we handle --local-service while
6398 preserving 4.1's behavior of allowing any one other argument that is
6399 passed to the service on startup. (The assumption is that this is
6400 --defaults-file=file, but that was not enforced in 4.1, so we don't
6401 enforce it here.)
6402 */
6403 const char *extra_opt= NullS;
6404 const char *account_name = NullS;
6405 int index;
6406 for (index = 3; index < argc; index++)
6407 {
6408 if (!strcmp(argv[index], "--local-service"))
6409 account_name= "NT AUTHORITY\\LocalService";
6410 else
6411 extra_opt= argv[index];
6412 }
6413
6414 if (argc == 4 || account_name)
6415 if (!default_service_handling(argv, argv[2], argv[2], file_path,
6416 extra_opt, account_name))
6417 return 0;
6418 }
6419 else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME))
6420 {
6421 /* start the default service */
6422 start_mode= 1;
6423 Service.Init(MYSQL_SERVICENAME, mysql_service);
6424 return 0;
6425 }
6426
6427 /* Start as standalone server */
6428 Service.my_argc=argc;
6429 Service.my_argv=argv;
6430 mysql_service(NULL);
6431 return 0;
6432}
6433#endif
6434
6435
6436/**
6437 Execute all commands from a file. Used by the mysql_install_db script to
6438 create MySQL privilege tables without having to start a full MySQL server
6439 and by read_init_file() if mysqld was started with the option --init-file.
6440*/
6441
6442static void bootstrap(MYSQL_FILE *file)
6443{
6444 DBUG_ENTER("bootstrap");
6445
6446 THD *thd= new THD(next_thread_id());
6447#ifdef WITH_WSREP
6448 thd->variables.wsrep_on= 0;
6449#endif
6450 thd->bootstrap=1;
6451 my_net_init(&thd->net,(st_vio*) 0, thd, MYF(0));
6452 thd->max_client_packet_length= thd->net.max_packet;
6453 thd->security_ctx->master_access= ~(ulong)0;
6454 in_bootstrap= TRUE;
6455
6456 bootstrap_file=file;
6457#ifndef EMBEDDED_LIBRARY // TODO: Enable this
6458 int error;
6459 if ((error= mysql_thread_create(key_thread_bootstrap,
6460 &thd->real_id, &connection_attrib,
6461 handle_bootstrap,
6462 (void*) thd)))
6463 {
6464 sql_print_warning("Can't create thread to handle bootstrap (errno= %d)",
6465 error);
6466 bootstrap_error=-1;
6467 delete thd;
6468 DBUG_VOID_RETURN;
6469 }
6470 /* Wait for thread to die */
6471 mysql_mutex_lock(&LOCK_thread_count);
6472 while (in_bootstrap)
6473 mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
6474 mysql_mutex_unlock(&LOCK_thread_count);
6475#else
6476 thd->mysql= 0;
6477 do_handle_bootstrap(thd);
6478#endif
6479
6480 DBUG_VOID_RETURN;
6481}
6482
6483
6484static bool read_init_file(char *file_name)
6485{
6486 MYSQL_FILE *file;
6487 DBUG_ENTER("read_init_file");
6488 DBUG_PRINT("enter",("name: %s",file_name));
6489 if (!(file= mysql_file_fopen(key_file_init, file_name,
6490 O_RDONLY, MYF(MY_WME))))
6491 DBUG_RETURN(TRUE);
6492 bootstrap(file);
6493 mysql_file_fclose(file, MYF(MY_WME));
6494 DBUG_RETURN(FALSE);
6495}
6496
6497
6498/**
6499 Increment number of created threads
6500*/
6501void inc_thread_created(void)
6502{
6503 statistic_increment(thread_created, &LOCK_status);
6504}
6505
6506#ifndef EMBEDDED_LIBRARY
6507
6508/*
6509 Simple scheduler that use the main thread to handle the request
6510
6511 NOTES
6512 This is only used for debugging, when starting mysqld with
6513 --thread-handling=no-threads or --one-thread
6514*/
6515
6516void handle_connection_in_main_thread(CONNECT *connect)
6517{
6518 thread_cache_size= 0; // Safety
6519 do_handle_one_connection(connect);
6520}
6521
6522
6523/*
6524 Scheduler that uses one thread per connection
6525*/
6526
6527void create_thread_to_handle_connection(CONNECT *connect)
6528{
6529 char error_message_buff[MYSQL_ERRMSG_SIZE];
6530 int error;
6531 DBUG_ENTER("create_thread_to_handle_connection");
6532
6533 /* Check if we can get thread from the cache */
6534 if (cached_thread_count > wake_thread)
6535 {
6536 mysql_mutex_lock(&LOCK_thread_cache);
6537 /* Recheck condition when we have the lock */
6538 if (cached_thread_count > wake_thread)
6539 {
6540 /* Get thread from cache */
6541 thread_cache.push_back(connect);
6542 wake_thread++;
6543 mysql_cond_signal(&COND_thread_cache);
6544 mysql_mutex_unlock(&LOCK_thread_cache);
6545 DBUG_PRINT("info",("Thread created"));
6546 DBUG_VOID_RETURN;
6547 }
6548 mysql_mutex_unlock(&LOCK_thread_cache);
6549 }
6550
6551 /* Create new thread to handle connection */
6552 inc_thread_created();
6553 DBUG_PRINT("info",(("creating thread %lu"), (ulong) connect->thread_id));
6554 connect->prior_thr_create_utime= microsecond_interval_timer();
6555
6556 if ((error= mysql_thread_create(key_thread_one_connection,
6557 &connect->real_id, &connection_attrib,
6558 handle_one_connection, (void*) connect)))
6559 {
6560 /* purecov: begin inspected */
6561 DBUG_PRINT("error", ("Can't create thread to handle request (error %d)",
6562 error));
6563 my_snprintf(error_message_buff, sizeof(error_message_buff),
6564 ER_DEFAULT(ER_CANT_CREATE_THREAD), error);
6565 connect->close_with_error(ER_CANT_CREATE_THREAD, error_message_buff,
6566 ER_OUT_OF_RESOURCES);
6567 DBUG_VOID_RETURN;
6568 /* purecov: end */
6569 }
6570 DBUG_PRINT("info",("Thread created"));
6571 DBUG_VOID_RETURN;
6572}
6573
6574
6575/**
6576 Create new thread to handle incoming connection.
6577
6578 This function will create new thread to handle the incoming
6579 connection. If there are idle cached threads one will be used.
6580 'thd' will be pushed into 'threads'.
6581
6582 In single-threaded mode (\#define ONE_THREAD) connection will be
6583 handled inside this function.
6584
6585 @param[in,out] thd Thread handle of future thread.
6586*/
6587
6588static void create_new_thread(CONNECT *connect)
6589{
6590 DBUG_ENTER("create_new_thread");
6591
6592 /*
6593 Don't allow too many connections. We roughly check here that we allow
6594 only (max_connections + 1) connections.
6595 */
6596
6597 mysql_mutex_lock(&LOCK_connection_count);
6598
6599 if (*connect->scheduler->connection_count >=
6600 *connect->scheduler->max_connections + 1|| abort_loop)
6601 {
6602 DBUG_PRINT("error",("Too many connections"));
6603
6604 mysql_mutex_unlock(&LOCK_connection_count);
6605 statistic_increment(denied_connections, &LOCK_status);
6606 statistic_increment(connection_errors_max_connection, &LOCK_status);
6607 connect->close_with_error(0, NullS, abort_loop ? ER_SERVER_SHUTDOWN : ER_CON_COUNT_ERROR);
6608 DBUG_VOID_RETURN;
6609 }
6610
6611 ++*connect->scheduler->connection_count;
6612
6613 if (connection_count + extra_connection_count > max_used_connections)
6614 max_used_connections= connection_count + extra_connection_count;
6615
6616 mysql_mutex_unlock(&LOCK_connection_count);
6617
6618 connect->thread_count_incremented= 1;
6619
6620 /*
6621 The initialization of thread_id is done in create_embedded_thd() for
6622 the embedded library.
6623 TODO: refactor this to avoid code duplication there
6624 */
6625 connect->thread_id= next_thread_id();
6626 connect->scheduler->add_connection(connect);
6627
6628 DBUG_VOID_RETURN;
6629}
6630#endif /* EMBEDDED_LIBRARY */
6631
6632
6633#ifdef SIGNALS_DONT_BREAK_READ
6634inline void kill_broken_server()
6635{
6636 /* hack to get around signals ignored in syscalls for problem OS's */
6637 if (mysql_socket_getfd(unix_sock) == INVALID_SOCKET ||
6638 (!opt_disable_networking &&
6639 mysql_socket_getfd(base_ip_sock) == INVALID_SOCKET))
6640 {
6641 select_thread_in_use = 0;
6642 /* The following call will never return */
6643 DBUG_PRINT("general", ("killing server because socket is closed"));
6644 kill_server((void*) MYSQL_KILL_SIGNAL);
6645 }
6646}
6647#define MAYBE_BROKEN_SYSCALL kill_broken_server();
6648#else
6649#define MAYBE_BROKEN_SYSCALL
6650#endif
6651
6652 /* Handle new connections and spawn new process to handle them */
6653
6654#ifndef EMBEDDED_LIBRARY
6655
6656void handle_connections_sockets()
6657{
6658 MYSQL_SOCKET sock= mysql_socket_invalid();
6659 MYSQL_SOCKET new_sock= mysql_socket_invalid();
6660 uint error_count=0;
6661 CONNECT *connect;
6662 struct sockaddr_storage cAddr;
6663 int ip_flags __attribute__((unused))=0;
6664 int socket_flags __attribute__((unused))= 0;
6665 int extra_ip_flags __attribute__((unused))=0;
6666 int flags=0,retval;
6667 bool is_unix_sock;
6668#ifdef HAVE_POLL
6669 int socket_count= 0;
6670 struct pollfd fds[3]; // for ip_sock, unix_sock and extra_ip_sock
6671 MYSQL_SOCKET pfs_fds[3]; // for performance schema
6672#define setup_fds(X) \
6673 mysql_socket_set_thread_owner(X); \
6674 pfs_fds[socket_count]= (X); \
6675 fds[socket_count].fd= mysql_socket_getfd(X); \
6676 fds[socket_count].events= POLLIN; \
6677 socket_count++
6678#else
6679#define setup_fds(X) FD_SET(mysql_socket_getfd(X),&clientFDs)
6680 fd_set readFDs,clientFDs;
6681 FD_ZERO(&clientFDs);
6682#endif
6683
6684 DBUG_ENTER("handle_connections_sockets");
6685
6686 if (mysql_socket_getfd(base_ip_sock) != INVALID_SOCKET)
6687 {
6688 setup_fds(base_ip_sock);
6689 ip_flags = fcntl(mysql_socket_getfd(base_ip_sock), F_GETFL, 0);
6690 }
6691 if (mysql_socket_getfd(extra_ip_sock) != INVALID_SOCKET)
6692 {
6693 setup_fds(extra_ip_sock);
6694 extra_ip_flags = fcntl(mysql_socket_getfd(extra_ip_sock), F_GETFL, 0);
6695 }
6696#ifdef HAVE_SYS_UN_H
6697 setup_fds(unix_sock);
6698 socket_flags=fcntl(mysql_socket_getfd(unix_sock), F_GETFL, 0);
6699#endif
6700
6701 sd_notify(0, "READY=1\n"
6702 "STATUS=Taking your SQL requests now...\n");
6703
6704 DBUG_PRINT("general",("Waiting for connections."));
6705 MAYBE_BROKEN_SYSCALL;
6706 while (!abort_loop)
6707 {
6708#ifdef HAVE_POLL
6709 retval= poll(fds, socket_count, -1);
6710#else
6711 readFDs=clientFDs;
6712 retval= select((int) 0,&readFDs,0,0,0);
6713#endif
6714
6715 if (retval < 0)
6716 {
6717 if (socket_errno != SOCKET_EINTR)
6718 {
6719 /*
6720 select(2)/poll(2) failed on the listening port.
6721 There is not much details to report about the client,
6722 increment the server global status variable.
6723 */
6724 statistic_increment(connection_errors_accept, &LOCK_status);
6725 if (!select_errors++ && !abort_loop) /* purecov: inspected */
6726 sql_print_error("mysqld: Got error %d from select",socket_errno); /* purecov: inspected */
6727 }
6728 MAYBE_BROKEN_SYSCALL
6729 continue;
6730 }
6731
6732 if (abort_loop)
6733 {
6734 MAYBE_BROKEN_SYSCALL;
6735 break;
6736 }
6737
6738 /* Is this a new connection request ? */
6739#ifdef HAVE_POLL
6740 for (int i= 0; i < socket_count; ++i)
6741 {
6742 if (fds[i].revents & POLLIN)
6743 {
6744 sock= pfs_fds[i];
6745 flags= fcntl(mysql_socket_getfd(sock), F_GETFL, 0);
6746 break;
6747 }
6748 }
6749#else // HAVE_POLL
6750 if (FD_ISSET(mysql_socket_getfd(base_ip_sock),&readFDs))
6751 {
6752 sock= base_ip_sock;
6753 flags= ip_flags;
6754 }
6755 else
6756 if (FD_ISSET(mysql_socket_getfd(extra_ip_sock),&readFDs))
6757 {
6758 sock= extra_ip_sock;
6759 flags= extra_ip_flags;
6760 }
6761 else
6762 {
6763 sock = unix_sock;
6764 flags= socket_flags;
6765 }
6766#endif // HAVE_POLL
6767
6768#if !defined(NO_FCNTL_NONBLOCK)
6769 if (!(test_flags & TEST_BLOCKING))
6770 {
6771#if defined(O_NONBLOCK)
6772 fcntl(mysql_socket_getfd(sock), F_SETFL, flags | O_NONBLOCK);
6773#elif defined(O_NDELAY)
6774 fcntl(mysql_socket_getfd(sock), F_SETFL, flags | O_NDELAY);
6775#endif
6776 }
6777#endif /* NO_FCNTL_NONBLOCK */
6778 for (uint retry=0; retry < MAX_ACCEPT_RETRY; retry++)
6779 {
6780 size_socket length= sizeof(struct sockaddr_storage);
6781 new_sock= mysql_socket_accept(key_socket_client_connection, sock,
6782 (struct sockaddr *)(&cAddr),
6783 &length);
6784 if (mysql_socket_getfd(new_sock) != INVALID_SOCKET ||
6785 (socket_errno != SOCKET_EINTR && socket_errno != SOCKET_EAGAIN))
6786 break;
6787 MAYBE_BROKEN_SYSCALL;
6788#if !defined(NO_FCNTL_NONBLOCK)
6789 if (!(test_flags & TEST_BLOCKING))
6790 {
6791 if (retry == MAX_ACCEPT_RETRY - 1)
6792 {
6793 // Try without O_NONBLOCK
6794 fcntl(mysql_socket_getfd(sock), F_SETFL, flags);
6795 }
6796 }
6797#endif
6798 }
6799#if !defined(NO_FCNTL_NONBLOCK)
6800 if (!(test_flags & TEST_BLOCKING))
6801 fcntl(mysql_socket_getfd(sock), F_SETFL, flags);
6802#endif
6803 if (mysql_socket_getfd(new_sock) == INVALID_SOCKET)
6804 {
6805 /*
6806 accept(2) failed on the listening port, after many retries.
6807 There is not much details to report about the client,
6808 increment the server global status variable.
6809 */
6810 statistic_increment(connection_errors_accept, &LOCK_status);
6811 if ((error_count++ & 255) == 0) // This can happen often
6812 sql_perror("Error in accept");
6813 MAYBE_BROKEN_SYSCALL;
6814 if (socket_errno == SOCKET_ENFILE || socket_errno == SOCKET_EMFILE)
6815 sleep(1); // Give other threads some time
6816 continue;
6817 }
6818#ifdef FD_CLOEXEC
6819 (void) fcntl(mysql_socket_getfd(new_sock), F_SETFD, FD_CLOEXEC);
6820#endif
6821
6822#ifdef HAVE_LIBWRAP
6823 {
6824 if (mysql_socket_getfd(sock) == mysql_socket_getfd(base_ip_sock) ||
6825 mysql_socket_getfd(sock) == mysql_socket_getfd(extra_ip_sock))
6826 {
6827 struct request_info req;
6828 signal(SIGCHLD, SIG_DFL);
6829 request_init(&req, RQ_DAEMON, libwrapName, RQ_FILE,
6830 mysql_socket_getfd(new_sock), NULL);
6831 my_fromhost(&req);
6832 if (!my_hosts_access(&req))
6833 {
6834 /*
6835 This may be stupid but refuse() includes an exit(0)
6836 which we surely don't want...
6837 clean_exit() - same stupid thing ...
6838 */
6839 syslog(deny_severity, "refused connect from %s",
6840 my_eval_client(&req));
6841
6842 /*
6843 C++ sucks (the gibberish in front just translates the supplied
6844 sink function pointer in the req structure from a void (*sink)();
6845 to a void(*sink)(int) if you omit the cast, the C++ compiler
6846 will cry...
6847 */
6848 if (req.sink)
6849 ((void (*)(int))req.sink)(req.fd);
6850
6851 (void) mysql_socket_shutdown(new_sock, SHUT_RDWR);
6852 (void) mysql_socket_close(new_sock);
6853 /*
6854 The connection was refused by TCP wrappers.
6855 There are no details (by client IP) available to update the
6856 host_cache.
6857 */
6858 statistic_increment(connection_errors_tcpwrap, &LOCK_status);
6859 continue;
6860 }
6861 }
6862 }
6863#endif /* HAVE_LIBWRAP */
6864
6865 DBUG_PRINT("info", ("Creating CONNECT for new connection"));
6866
6867 if ((connect= new CONNECT()))
6868 {
6869 is_unix_sock= (mysql_socket_getfd(sock) ==
6870 mysql_socket_getfd(unix_sock));
6871
6872 if (!(connect->vio=
6873 mysql_socket_vio_new(new_sock,
6874 is_unix_sock ? VIO_TYPE_SOCKET :
6875 VIO_TYPE_TCPIP,
6876 is_unix_sock ? VIO_LOCALHOST: 0)))
6877 {
6878 delete connect;
6879 connect= 0; // Error handling below
6880 }
6881 }
6882
6883 if (!connect)
6884 {
6885 /* Connect failure */
6886 (void) mysql_socket_shutdown(new_sock, SHUT_RDWR);
6887 (void) mysql_socket_close(new_sock);
6888 statistic_increment(aborted_connects,&LOCK_status);
6889 statistic_increment(connection_errors_internal, &LOCK_status);
6890 continue;
6891 }
6892
6893 if (is_unix_sock)
6894 connect->host= my_localhost;
6895
6896 if (mysql_socket_getfd(sock) == mysql_socket_getfd(extra_ip_sock))
6897 {
6898 connect->extra_port= 1;
6899 connect->scheduler= extra_thread_scheduler;
6900 }
6901 create_new_thread(connect);
6902 }
6903 sd_notify(0, "STOPPING=1\n"
6904 "STATUS=Shutdown in progress\n");
6905 DBUG_VOID_RETURN;
6906}
6907
6908
6909#ifdef _WIN32
6910pthread_handler_t handle_connections_sockets_thread(void *arg)
6911{
6912 my_thread_init();
6913 handle_connections_sockets();
6914 decrement_handler_count();
6915 return 0;
6916}
6917
6918pthread_handler_t handle_connections_namedpipes(void *arg)
6919{
6920 HANDLE hConnectedPipe;
6921 OVERLAPPED connectOverlapped= {0};
6922 my_thread_init();
6923 DBUG_ENTER("handle_connections_namedpipes");
6924 connectOverlapped.hEvent= CreateEvent(NULL, TRUE, FALSE, NULL);
6925 if (!connectOverlapped.hEvent)
6926 {
6927 sql_print_error("Can't create event, last error=%u", GetLastError());
6928 unireg_abort(1);
6929 }
6930 DBUG_PRINT("general",("Waiting for named pipe connections."));
6931 while (!abort_loop)
6932 {
6933 /* wait for named pipe connection */
6934 BOOL fConnected= ConnectNamedPipe(hPipe, &connectOverlapped);
6935 if (!fConnected && (GetLastError() == ERROR_IO_PENDING))
6936 {
6937 /*
6938 ERROR_IO_PENDING says async IO has started but not yet finished.
6939 GetOverlappedResult will wait for completion.
6940 */
6941 DWORD bytes;
6942 fConnected= GetOverlappedResult(hPipe, &connectOverlapped,&bytes, TRUE);
6943 }
6944 if (abort_loop)
6945 break;
6946 if (!fConnected)
6947 fConnected = GetLastError() == ERROR_PIPE_CONNECTED;
6948 if (!fConnected)
6949 {
6950 CloseHandle(hPipe);
6951 if ((hPipe= CreateNamedPipe(pipe_name,
6952 PIPE_ACCESS_DUPLEX |
6953 FILE_FLAG_OVERLAPPED,
6954 PIPE_TYPE_BYTE |
6955 PIPE_READMODE_BYTE |
6956 PIPE_WAIT,
6957 PIPE_UNLIMITED_INSTANCES,
6958 (int) global_system_variables.
6959 net_buffer_length,
6960 (int) global_system_variables.
6961 net_buffer_length,
6962 NMPWAIT_USE_DEFAULT_WAIT,
6963 &saPipeSecurity)) ==
6964 INVALID_HANDLE_VALUE)
6965 {
6966 sql_perror("Can't create new named pipe!");
6967 break; // Abort
6968 }
6969 }
6970 hConnectedPipe = hPipe;
6971 /* create new pipe for new connection */
6972 if ((hPipe = CreateNamedPipe(pipe_name,
6973 PIPE_ACCESS_DUPLEX |
6974 FILE_FLAG_OVERLAPPED,
6975 PIPE_TYPE_BYTE |
6976 PIPE_READMODE_BYTE |
6977 PIPE_WAIT,
6978 PIPE_UNLIMITED_INSTANCES,
6979 (int) global_system_variables.net_buffer_length,
6980 (int) global_system_variables.net_buffer_length,
6981 NMPWAIT_USE_DEFAULT_WAIT,
6982 &saPipeSecurity)) ==
6983 INVALID_HANDLE_VALUE)
6984 {
6985 sql_perror("Can't create new named pipe!");
6986 hPipe=hConnectedPipe;
6987 continue; // We have to try again
6988 }
6989 CONNECT *connect;
6990 if (!(connect= new CONNECT) ||
6991 !(connect->vio= vio_new_win32pipe(hConnectedPipe)))
6992 {
6993 DisconnectNamedPipe(hConnectedPipe);
6994 CloseHandle(hConnectedPipe);
6995 delete connect;
6996 statistic_increment(aborted_connects,&LOCK_status);
6997 statistic_increment(connection_errors_internal, &LOCK_status);
6998 continue;
6999 }
7000 connect->host= my_localhost;
7001 create_new_thread(connect);
7002 }
7003 CloseHandle(connectOverlapped.hEvent);
7004 DBUG_LEAVE;
7005 decrement_handler_count();
7006 return 0;
7007}
7008#endif /* _WIN32 */
7009
7010
7011#ifdef HAVE_SMEM
7012
7013/**
7014 Thread of shared memory's service.
7015
7016 @param arg Arguments of thread
7017*/
7018pthread_handler_t handle_connections_shared_memory(void *arg)
7019{
7020 /* file-mapping object, use for create shared memory */
7021 HANDLE handle_connect_file_map= 0;
7022 char *handle_connect_map= 0; // pointer on shared memory
7023 HANDLE event_connect_answer= 0;
7024 ulong smem_buffer_length= shared_memory_buffer_length + 4;
7025 ulong connect_number= 1;
7026 char *tmp= NULL;
7027 char *suffix_pos;
7028 char connect_number_char[22], *p;
7029 const char *errmsg= 0;
7030 SECURITY_ATTRIBUTES *sa_event= 0, *sa_mapping= 0;
7031 my_thread_init();
7032 DBUG_ENTER("handle_connections_shared_memorys");
7033 DBUG_PRINT("general",("Waiting for allocated shared memory."));
7034
7035 /*
7036 get enough space base-name + '_' + longest suffix we might ever send
7037 */
7038 if (!(tmp= (char *)my_malloc(strlen(shared_memory_base_name) + 32L,
7039 MYF(MY_FAE))))
7040 goto error;
7041
7042 if (my_security_attr_create(&sa_event, &errmsg,
7043 GENERIC_ALL, SYNCHRONIZE | EVENT_MODIFY_STATE))
7044 goto error;
7045
7046 if (my_security_attr_create(&sa_mapping, &errmsg,
7047 GENERIC_ALL, FILE_MAP_READ | FILE_MAP_WRITE))
7048 goto error;
7049
7050 /*
7051 The name of event and file-mapping events create agree next rule:
7052 shared_memory_base_name+unique_part
7053 Where:
7054 shared_memory_base_name is unique value for each server
7055 unique_part is unique value for each object (events and file-mapping)
7056 */
7057 suffix_pos= strxmov(tmp,shared_memory_base_name,"_",NullS);
7058 strmov(suffix_pos, "CONNECT_REQUEST");
7059 if ((smem_event_connect_request= CreateEvent(sa_event,
7060 FALSE, FALSE, tmp)) == 0)
7061 {
7062 errmsg= "Could not create request event";
7063 goto error;
7064 }
7065 strmov(suffix_pos, "CONNECT_ANSWER");
7066 if ((event_connect_answer= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
7067 {
7068 errmsg="Could not create answer event";
7069 goto error;
7070 }
7071 strmov(suffix_pos, "CONNECT_DATA");
7072 if ((handle_connect_file_map=
7073 CreateFileMapping(INVALID_HANDLE_VALUE, sa_mapping,
7074 PAGE_READWRITE, 0, sizeof(connect_number), tmp)) == 0)
7075 {
7076 errmsg= "Could not create file mapping";
7077 goto error;
7078 }
7079 if ((handle_connect_map= (char *)MapViewOfFile(handle_connect_file_map,
7080 FILE_MAP_WRITE,0,0,
7081 sizeof(DWORD))) == 0)
7082 {
7083 errmsg= "Could not create shared memory service";
7084 goto error;
7085 }
7086
7087 while (!abort_loop)
7088 {
7089 /* Wait a request from client */
7090 WaitForSingleObject(smem_event_connect_request,INFINITE);
7091
7092 /*
7093 it can be after shutdown command
7094 */
7095 if (abort_loop)
7096 goto error;
7097
7098 HANDLE handle_client_file_map= 0;
7099 char *handle_client_map= 0;
7100 HANDLE event_client_wrote= 0;
7101 HANDLE event_client_read= 0; // for transfer data server <-> client
7102 HANDLE event_server_wrote= 0;
7103 HANDLE event_server_read= 0;
7104 HANDLE event_conn_closed= 0;
7105 CONNECT *connect= 0;
7106
7107 p= int10_to_str(connect_number, connect_number_char, 10);
7108 /*
7109 The name of event and file-mapping events create agree next rule:
7110 shared_memory_base_name+unique_part+number_of_connection
7111 Where:
7112 shared_memory_base_name is uniquel value for each server
7113 unique_part is unique value for each object (events and file-mapping)
7114 number_of_connection is connection-number between server and client
7115 */
7116 suffix_pos= strxmov(tmp,shared_memory_base_name,"_",connect_number_char,
7117 "_",NullS);
7118 strmov(suffix_pos, "DATA");
7119 if ((handle_client_file_map=
7120 CreateFileMapping(INVALID_HANDLE_VALUE, sa_mapping,
7121 PAGE_READWRITE, 0, smem_buffer_length, tmp)) == 0)
7122 {
7123 errmsg= "Could not create file mapping";
7124 goto errorconn;
7125 }
7126 if ((handle_client_map= (char*)MapViewOfFile(handle_client_file_map,
7127 FILE_MAP_WRITE,0,0,
7128 smem_buffer_length)) == 0)
7129 {
7130 errmsg= "Could not create memory map";
7131 goto errorconn;
7132 }
7133 strmov(suffix_pos, "CLIENT_WROTE");
7134 if ((event_client_wrote= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
7135 {
7136 errmsg= "Could not create client write event";
7137 goto errorconn;
7138 }
7139 strmov(suffix_pos, "CLIENT_READ");
7140 if ((event_client_read= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
7141 {
7142 errmsg= "Could not create client read event";
7143 goto errorconn;
7144 }
7145 strmov(suffix_pos, "SERVER_READ");
7146 if ((event_server_read= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
7147 {
7148 errmsg= "Could not create server read event";
7149 goto errorconn;
7150 }
7151 strmov(suffix_pos, "SERVER_WROTE");
7152 if ((event_server_wrote= CreateEvent(sa_event,
7153 FALSE, FALSE, tmp)) == 0)
7154 {
7155 errmsg= "Could not create server write event";
7156 goto errorconn;
7157 }
7158 strmov(suffix_pos, "CONNECTION_CLOSED");
7159 if ((event_conn_closed= CreateEvent(sa_event,
7160 TRUE, FALSE, tmp)) == 0)
7161 {
7162 errmsg= "Could not create closed connection event";
7163 goto errorconn;
7164 }
7165 if (abort_loop)
7166 goto errorconn;
7167
7168 if (!(connect= new CONNECT))
7169 {
7170 errmsg= "Could not create CONNECT object";
7171 goto errorconn;
7172 }
7173
7174 /* Send number of connection to client */
7175 int4store(handle_connect_map, connect_number);
7176 if (!SetEvent(event_connect_answer))
7177 {
7178 errmsg= "Could not send answer event";
7179 goto errorconn;
7180 }
7181 /* Set event that client should receive data */
7182 if (!SetEvent(event_client_read))
7183 {
7184 errmsg= "Could not set client to read mode";
7185 goto errorconn;
7186 }
7187 if (!(connect->vio= vio_new_win32shared_memory(handle_client_file_map,
7188 handle_client_map,
7189 event_client_wrote,
7190 event_client_read,
7191 event_server_wrote,
7192 event_server_read,
7193 event_conn_closed)))
7194 {
7195 errmsg= "Could not create VIO object";
7196 goto errorconn;
7197 }
7198 connect->host= my_localhost; /* Host is unknown */
7199 create_new_thread(connect);
7200 connect_number++;
7201 continue;
7202
7203errorconn:
7204 /* Could not form connection; Free used handlers/memort and retry */
7205 if (errmsg)
7206 {
7207 char buff[180];
7208 strxmov(buff, "Can't create shared memory connection: ", errmsg, ".",
7209 NullS);
7210 sql_perror(buff);
7211 }
7212 if (handle_client_file_map)
7213 CloseHandle(handle_client_file_map);
7214 if (handle_client_map)
7215 UnmapViewOfFile(handle_client_map);
7216 if (event_server_wrote)
7217 CloseHandle(event_server_wrote);
7218 if (event_server_read)
7219 CloseHandle(event_server_read);
7220 if (event_client_wrote)
7221 CloseHandle(event_client_wrote);
7222 if (event_client_read)
7223 CloseHandle(event_client_read);
7224 if (event_conn_closed)
7225 CloseHandle(event_conn_closed);
7226
7227 delete connect;
7228 statistic_increment(aborted_connects,&LOCK_status);
7229 statistic_increment(connection_errors_internal, &LOCK_status);
7230 }
7231
7232 /* End shared memory handling */
7233error:
7234 if (tmp)
7235 my_free(tmp);
7236
7237 if (errmsg)
7238 {
7239 char buff[180];
7240 strxmov(buff, "Can't create shared memory service: ", errmsg, ".", NullS);
7241 sql_perror(buff);
7242 }
7243 my_security_attr_free(sa_event);
7244 my_security_attr_free(sa_mapping);
7245 if (handle_connect_map) UnmapViewOfFile(handle_connect_map);
7246 if (handle_connect_file_map) CloseHandle(handle_connect_file_map);
7247 if (event_connect_answer) CloseHandle(event_connect_answer);
7248 if (smem_event_connect_request) CloseHandle(smem_event_connect_request);
7249 DBUG_LEAVE;
7250 decrement_handler_count();
7251 return 0;
7252}
7253#endif /* HAVE_SMEM */
7254#endif /* EMBEDDED_LIBRARY */
7255
7256
7257/****************************************************************************
7258 Handle start options
7259******************************************************************************/
7260
7261
7262/**
7263 Process command line options flagged as 'early'.
7264 Some components needs to be initialized as early as possible,
7265 because the rest of the server initialization depends on them.
7266 Options that needs to be parsed early includes:
7267 - the performance schema, when compiled in,
7268 - options related to the help,
7269 - options related to the bootstrap
7270 The performance schema needs to be initialized as early as possible,
7271 before to-be-instrumented objects of the server are initialized.
7272*/
7273
7274int handle_early_options()
7275{
7276 int ho_error;
7277 DYNAMIC_ARRAY all_early_options;
7278
7279 my_getopt_register_get_addr(NULL);
7280 /* Skip unknown options so that they may be processed later */
7281 my_getopt_skip_unknown= TRUE;
7282
7283 /* prepare all_early_options array */
7284 my_init_dynamic_array(&all_early_options, sizeof(my_option), 100, 25, MYF(0));
7285 add_many_options(&all_early_options, pfs_early_options,
7286 array_elements(pfs_early_options));
7287 sys_var_add_options(&all_early_options, sys_var::PARSE_EARLY);
7288 add_terminator(&all_early_options);
7289
7290 ho_error= handle_options(&remaining_argc, &remaining_argv,
7291 (my_option*)(all_early_options.buffer),
7292 mysqld_get_one_option);
7293 if (ho_error == 0)
7294 {
7295 /* Add back the program name handle_options removes */
7296 remaining_argc++;
7297 remaining_argv--;
7298 }
7299
7300 delete_dynamic(&all_early_options);
7301
7302 return ho_error;
7303}
7304
7305
7306#define MYSQL_COMPATIBILITY_OPTION(option) \
7307 { option, OPT_MYSQL_COMPATIBILITY, \
7308 0, 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0 }
7309
7310#define MYSQL_TO_BE_IMPLEMENTED_OPTION(option) \
7311 { option, OPT_MYSQL_TO_BE_IMPLEMENTED, \
7312 0, 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0 }
7313
7314#define MYSQL_SUGGEST_ANALOG_OPTION(option, str) \
7315 { option, OPT_MYSQL_COMPATIBILITY, \
7316 0, 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0 }
7317
7318
7319/**
7320 System variables are automatically command-line options (few
7321 exceptions are documented in sys_var.h), so don't need
7322 to be listed here.
7323*/
7324
7325struct my_option my_long_options[]=
7326{
7327 {"help", '?', "Display this help and exit.",
7328 &opt_help, &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
7329 0, 0},
7330 {"allow-suspicious-udfs", 0,
7331 "Allows use of UDFs consisting of only one symbol xxx() "
7332 "without corresponding xxx_init() or xxx_deinit(). That also means "
7333 "that one can load any function from any library, for example exit() "
7334 "from libc.so",
7335 &opt_allow_suspicious_udfs, &opt_allow_suspicious_udfs,
7336 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7337 {"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax. This mode "
7338 "will also set transaction isolation level 'serializable'.", 0, 0, 0,
7339 GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
7340 /*
7341 Because Sys_var_bit does not support command-line options, we need to
7342 explicitly add one for --autocommit
7343 */
7344 {"autocommit", 0, "Set default value for autocommit (0 or 1)",
7345 &opt_autocommit, &opt_autocommit, 0,
7346 GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, NULL},
7347 {"binlog-do-db", OPT_BINLOG_DO_DB,
7348 "Tells the master it should log updates for the specified database, "
7349 "and exclude all others not explicitly mentioned.",
7350 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7351 {"binlog-ignore-db", OPT_BINLOG_IGNORE_DB,
7352 "Tells the master that updates to the given database should not be logged to the binary log.",
7353 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7354 {"binlog-row-event-max-size", 0,
7355 "The maximum size of a row-based binary log event in bytes. Rows will be "
7356 "grouped into events smaller than this size if possible. "
7357 "The value has to be a multiple of 256.",
7358 &opt_binlog_rows_event_max_size, &opt_binlog_rows_event_max_size,
7359 0, GET_ULONG, REQUIRED_ARG,
7360 /* def_value */ 8192, /* min_value */ 256, /* max_value */ UINT_MAX32-1,
7361 /* sub_size */ 0, /* block_size */ 256,
7362 /* app_type */ 0
7363 },
7364#ifndef DISABLE_GRANT_OPTIONS
7365 {"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts.", 0, 0, 0,
7366 GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
7367#endif
7368 {"character-set-client-handshake", 0,
7369 "Don't ignore client side character set value sent during handshake.",
7370 &opt_character_set_client_handshake,
7371 &opt_character_set_client_handshake,
7372 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
7373 {"character-set-filesystem", 0,
7374 "Set the filesystem character set.",
7375 &character_set_filesystem_name,
7376 &character_set_filesystem_name,
7377 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
7378 {"character-set-server", 'C', "Set the default character set.",
7379 &default_character_set_name, &default_character_set_name,
7380 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
7381 {"chroot", 'r', "Chroot mysqld daemon during startup.",
7382 &mysqld_chroot, &mysqld_chroot, 0, GET_STR, REQUIRED_ARG,
7383 0, 0, 0, 0, 0, 0},
7384 {"collation-server", 0, "Set the default collation.",
7385 &default_collation_name, &default_collation_name,
7386 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
7387 {"console", OPT_CONSOLE, "Write error output on screen; don't remove the console window on windows.",
7388 &opt_console, &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0,
7389 0, 0, 0},
7390 {"core-file", OPT_WANT_CORE, "Write core on errors.", 0, 0, 0, GET_NO_ARG,
7391 NO_ARG, 0, 0, 0, 0, 0, 0},
7392#ifdef DBUG_OFF
7393 {"debug", '#', "Built in DBUG debugger. Disabled in this build.",
7394 &current_dbug_option, &current_dbug_option, 0, GET_STR, OPT_ARG,
7395 0, 0, 0, 0, 0, 0},
7396#endif
7397#ifdef HAVE_REPLICATION
7398 {"debug-abort-slave-event-count", 0,
7399 "Option used by mysql-test for debugging and testing of replication.",
7400 &abort_slave_event_count, &abort_slave_event_count,
7401 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7402#endif /* HAVE_REPLICATION */
7403#ifndef DBUG_OFF
7404 {"debug-assert-on-error", 0,
7405 "Do an assert in various functions if we get a fatal error",
7406 &my_assert_on_error, &my_assert_on_error,
7407 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7408 {"debug-assert-if-crashed-table", 0,
7409 "Do an assert in handler::print_error() if we get a crashed table",
7410 &debug_assert_if_crashed_table, &debug_assert_if_crashed_table,
7411 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7412#endif
7413#ifdef HAVE_REPLICATION
7414 {"debug-disconnect-slave-event-count", 0,
7415 "Option used by mysql-test for debugging and testing of replication.",
7416 &disconnect_slave_event_count, &disconnect_slave_event_count,
7417 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7418#endif /* HAVE_REPLICATION */
7419 {"debug-exit-info", 'T', "Used for debugging. Use at your own risk.",
7420 0, 0, 0, GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
7421 {"debug-gdb", 0,
7422 "Set up signals usable for debugging.",
7423 &opt_debugging, &opt_debugging,
7424 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7425#ifdef HAVE_REPLICATION
7426 {"debug-max-binlog-dump-events", 0,
7427 "Option used by mysql-test for debugging and testing of replication.",
7428 &max_binlog_dump_events, &max_binlog_dump_events, 0,
7429 GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7430#endif /* HAVE_REPLICATION */
7431 {"debug-no-sync", 0,
7432 "Disables system sync calls. Only for running tests or debugging!",
7433 &my_disable_sync, &my_disable_sync, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7434#ifdef HAVE_REPLICATION
7435 {"debug-sporadic-binlog-dump-fail", 0,
7436 "Option used by mysql-test for debugging and testing of replication.",
7437 &opt_sporadic_binlog_dump_fail,
7438 &opt_sporadic_binlog_dump_fail, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
7439 0},
7440#endif /* HAVE_REPLICATION */
7441#ifndef DBUG_OFF
7442 {"debug-assert-on-not-freed-memory", 0,
7443 "Assert if we found problems with memory allocation",
7444 &debug_assert_on_not_freed_memory,
7445 &debug_assert_on_not_freed_memory, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
7446 0},
7447#endif /* DBUG_OFF */
7448 /* default-storage-engine should have "MyISAM" as def_value. Instead
7449 of initializing it here it is done in init_common_variables() due
7450 to a compiler bug in Sun Studio compiler. */
7451 {"default-storage-engine", 0, "The default storage engine for new tables",
7452 &default_storage_engine, 0, 0, GET_STR, REQUIRED_ARG,
7453 0, 0, 0, 0, 0, 0 },
7454 {"default-tmp-storage-engine", 0,
7455 "The default storage engine for user-created temporary tables",
7456 &default_tmp_storage_engine, 0, 0, GET_STR, REQUIRED_ARG,
7457 0, 0, 0, 0, 0, 0 },
7458 {"default-time-zone", 0, "Set the default time zone.",
7459 &default_tz_name, &default_tz_name,
7460 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
7461#if defined(ENABLED_DEBUG_SYNC)
7462 {"debug-sync-timeout", OPT_DEBUG_SYNC_TIMEOUT,
7463 "Enable the debug sync facility "
7464 "and optionally specify a default wait timeout in seconds. "
7465 "A zero value keeps the facility disabled.",
7466 &opt_debug_sync_timeout, 0,
7467 0, GET_UINT, OPT_ARG, 0, 0, UINT_MAX, 0, 0, 0},
7468#endif /* defined(ENABLED_DEBUG_SYNC) */
7469#ifdef HAVE_OPENSSL
7470 {"des-key-file", 0,
7471 "Load keys for des_encrypt() and des_encrypt from given file.",
7472 &des_key_file, &des_key_file, 0, GET_STR, REQUIRED_ARG,
7473 0, 0, 0, 0, 0, 0},
7474#endif /* HAVE_OPENSSL */
7475#ifdef HAVE_STACKTRACE
7476 {"stack-trace", 0 , "Print a symbolic stack trace on failure",
7477 &opt_stack_trace, &opt_stack_trace, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
7478#endif /* HAVE_STACKTRACE */
7479 {"enforce-storage-engine", 0, "Force the use of a storage engine for new tables",
7480 &enforced_storage_engine, 0, 0, GET_STR, REQUIRED_ARG,
7481 0, 0, 0, 0, 0, 0 },
7482 {"external-locking", 0, "Use system (external) locking (disabled by "
7483 "default). With this option enabled you can run myisamchk to test "
7484 "(not repair) tables while the MySQL server is running. Disable with "
7485 "--skip-external-locking.", &opt_external_locking, &opt_external_locking,
7486 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7487 /* We must always support the next option to make scripts like mysqltest
7488 easier to do */
7489 {"flashback", 0,
7490 "Setup the server to use flashback. This enables binary log in row mode and will enable extra logging for DDL's needed by flashback feature",
7491 &opt_support_flashback, &opt_support_flashback,
7492 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7493 {"gdb", 0,
7494 "Set up signals usable for debugging. Deprecated, use --debug-gdb instead.",
7495 &opt_debugging, &opt_debugging,
7496 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7497 {"gtid-pos-auto-engines", 0,
7498 "List of engines for which to automatically create a "
7499 "mysql.gtid_slave_pos_ENGINE table, if a transaction using that engine "
7500 "is replicated. This can be used to avoid introducing cross-engine "
7501 "transactions, if engines are used different from that used by table "
7502 "mysql.gtid_slave_pos",
7503 &gtid_pos_auto_engines, 0, 0, GET_STR, REQUIRED_ARG,
7504 0, 0, 0, 0, 0, 0 },
7505#ifdef HAVE_LARGE_PAGE_OPTION
7506 {"super-large-pages", 0, "Enable support for super large pages.",
7507 &opt_super_large_pages, &opt_super_large_pages, 0,
7508 GET_BOOL, OPT_ARG, 0, 0, 1, 0, 1, 0},
7509#endif
7510 {"language", 'L',
7511 "Client error messages in given language. May be given as a full path. "
7512 "Deprecated. Use --lc-messages-dir instead.",
7513 0, 0, 0,
7514 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7515 {"lc-messages", 0,
7516 "Set the language used for the error messages.",
7517 &lc_messages, &lc_messages, 0, GET_STR, REQUIRED_ARG,
7518 0, 0, 0, 0, 0, 0 },
7519 {"lc-time-names", 0,
7520 "Set the language used for the month names and the days of the week.",
7521 &lc_time_names_name, &lc_time_names_name,
7522 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
7523 {"log-basename", OPT_LOG_BASENAME,
7524 "Basename for all log files and the .pid file. This sets all log file "
7525 "names at once (in 'datadir') and is normally the only option you need "
7526 "for specifying log files. Sets names for --log-bin, --log-bin-index, "
7527 "--relay-log, --relay-log-index, --general-log-file, "
7528 "--log-slow-query-log-file, --log-error-file, and --pid-file",
7529 &opt_log_basename, &opt_log_basename, 0, GET_STR, REQUIRED_ARG,
7530 0, 0, 0, 0, 0, 0},
7531 {"log-bin", OPT_BIN_LOG,
7532 "Log update queries in binary format. Optional argument should be name for "
7533 "binary log. If not given "
7534 "'datadir'/'log-basename'-bin or 'datadir'/mysql-bin will be used (the later if "
7535 "--log-basename is not specified). We strongly recommend to use either "
7536 "--log-basename or specify a filename to ensure that replication doesn't "
7537 "stop if the real hostname of the computer changes.",
7538 &opt_bin_logname, &opt_bin_logname, 0, GET_STR,
7539 OPT_ARG, 0, 0, 0, 0, 0, 0},
7540 {"log-bin-index", 0,
7541 "File that holds the names for last binary log files.",
7542 &opt_binlog_index_name, &opt_binlog_index_name, 0, GET_STR,
7543 REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7544 {"relay-log-index", 0,
7545 "The location and name to use for the file that keeps a list of the last "
7546 "relay logs",
7547 &opt_relaylog_index_name, &opt_relaylog_index_name, 0, GET_STR,
7548 REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7549 {"log-isam", OPT_ISAM_LOG, "Log all MyISAM changes to file.",
7550 &myisam_log_filename, &myisam_log_filename, 0, GET_STR,
7551 OPT_ARG, 0, 0, 0, 0, 0, 0},
7552 {"log-short-format", 0,
7553 "Don't log extra information to update and slow-query logs.",
7554 &opt_short_log_format, &opt_short_log_format,
7555 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7556 {"log-tc", 0,
7557 "Path to transaction coordinator log (used for transactions that affect "
7558 "more than one storage engine, when binary log is disabled).",
7559 &opt_tc_log_file, &opt_tc_log_file, 0, GET_STR,
7560 REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7561 {"master-info-file", 0,
7562 "The location and name of the file that remembers the master and where "
7563 "the I/O replication thread is in the master's binlogs. Defaults to "
7564 "master.info",
7565 &master_info_file, &master_info_file, 0, GET_STR,
7566 REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7567 {"master-retry-count", 0,
7568 "The number of tries the slave will make to connect to the master before giving up.",
7569 &master_retry_count, &master_retry_count, 0, GET_ULONG,
7570 REQUIRED_ARG, 3600*24, 0, 0, 0, 0, 0},
7571#ifdef HAVE_REPLICATION
7572 {"init-rpl-role", 0, "Set the replication role",
7573 &rpl_status, &rpl_status, &rpl_role_typelib,
7574 GET_ENUM, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7575#endif /* HAVE_REPLICATION */
7576 {"memlock", 0, "Lock mysqld in memory.", &locked_in_memory,
7577 &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7578 {"old-style-user-limits", 0,
7579 "Enable old-style user limits (before 5.0.3, user resources were counted "
7580 "per each user+host vs. per account).",
7581 &opt_old_style_user_limits, &opt_old_style_user_limits,
7582 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7583 {"port-open-timeout", 0,
7584 "Maximum time in seconds to wait for the port to become free. "
7585 "(Default: No wait).", &mysqld_port_timeout, &mysqld_port_timeout, 0,
7586 GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7587 {"replicate-do-db", OPT_REPLICATE_DO_DB,
7588 "Tells the slave thread to restrict replication to the specified database. "
7589 "To specify more than one database, use the directive multiple times, "
7590 "once for each database. Note that this will only work if you do not use "
7591 "cross-database queries such as UPDATE some_db.some_table SET foo='bar' "
7592 "while having selected a different or no database. If you need cross "
7593 "database updates to work, make sure you have 3.23.28 or later, and use "
7594 "replicate-wild-do-table=db_name.%.",
7595 0, 0, 0, GET_STR | GET_ASK_ADDR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7596 {"replicate-do-table", OPT_REPLICATE_DO_TABLE,
7597 "Tells the slave thread to restrict replication to the specified table. "
7598 "To specify more than one table, use the directive multiple times, once "
7599 "for each table. This will work for cross-database updates, in contrast "
7600 "to replicate-do-db.", 0, 0, 0, GET_STR | GET_ASK_ADDR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7601 {"replicate-ignore-db", OPT_REPLICATE_IGNORE_DB,
7602 "Tells the slave thread to not replicate to the specified database. To "
7603 "specify more than one database to ignore, use the directive multiple "
7604 "times, once for each database. This option will not work if you use "
7605 "cross database updates. If you need cross database updates to work, "
7606 "make sure you have 3.23.28 or later, and use replicate-wild-ignore-"
7607 "table=db_name.%. ", 0, 0, 0, GET_STR | GET_ASK_ADDR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7608 {"replicate-ignore-table", OPT_REPLICATE_IGNORE_TABLE,
7609 "Tells the slave thread to not replicate to the specified table. To specify "
7610 "more than one table to ignore, use the directive multiple times, once for "
7611 "each table. This will work for cross-database updates, in contrast to "
7612 "replicate-ignore-db.", 0, 0, 0, GET_STR | GET_ASK_ADDR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7613 {"replicate-rewrite-db", OPT_REPLICATE_REWRITE_DB,
7614 "Updates to a database with a different name than the original. Example: "
7615 "replicate-rewrite-db=master_db_name->slave_db_name.",
7616 0, 0, 0, GET_STR | GET_ASK_ADDR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7617#ifdef HAVE_REPLICATION
7618 {"replicate-same-server-id", 0,
7619 "In replication, if set to 1, do not skip events having our server id. "
7620 "Default value is 0 (to break infinite loops in circular replication). "
7621 "Can't be set to 1 if --log-slave-updates is used.",
7622 &replicate_same_server_id, &replicate_same_server_id,
7623 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7624#endif
7625 {"replicate-wild-do-table", OPT_REPLICATE_WILD_DO_TABLE,
7626 "Tells the slave thread to restrict replication to the tables that match "
7627 "the specified wildcard pattern. To specify more than one table, use the "
7628 "directive multiple times, once for each table. This will work for cross-"
7629 "database updates. Example: replicate-wild-do-table=foo%.bar% will "
7630 "replicate only updates to tables in all databases that start with foo "
7631 "and whose table names start with bar.",
7632 0, 0, 0, GET_STR | GET_ASK_ADDR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7633 {"replicate-wild-ignore-table", OPT_REPLICATE_WILD_IGNORE_TABLE,
7634 "Tells the slave thread to not replicate to the tables that match the "
7635 "given wildcard pattern. To specify more than one table to ignore, use "
7636 "the directive multiple times, once for each table. This will work for "
7637 "cross-database updates. Example: replicate-wild-ignore-table=foo%.bar% "
7638 "will not do updates to tables in databases that start with foo and whose "
7639 "table names start with bar.",
7640 0, 0, 0, GET_STR | GET_ASK_ADDR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7641 {"safe-mode", OPT_SAFE, "Skip some optimize stages (for testing). Deprecated.",
7642 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
7643 {"safe-user-create", 0,
7644 "Don't allow new user creation by the user who has no write privileges to the mysql.user table.",
7645 &opt_safe_user_create, &opt_safe_user_create, 0, GET_BOOL,
7646 NO_ARG, 0, 0, 0, 0, 0, 0},
7647 {"show-slave-auth-info", 0,
7648 "Show user and password in SHOW SLAVE HOSTS on this master.",
7649 &opt_show_slave_auth_info, &opt_show_slave_auth_info, 0,
7650 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7651 {"silent-startup", OPT_SILENT, "Don't print [Note] to the error log during startup.",
7652 &opt_silent_startup, &opt_silent_startup, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7653 {"skip-bdb", OPT_DEPRECATED_OPTION,
7654 "Deprecated option; Exist only for compatibility with old my.cnf files",
7655 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
7656#ifndef DISABLE_GRANT_OPTIONS
7657 {"skip-grant-tables", 0,
7658 "Start without grant tables. This gives all users FULL ACCESS to all tables.",
7659 &opt_noacl, &opt_noacl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
7660 0},
7661#endif
7662 {"skip-host-cache", OPT_SKIP_HOST_CACHE, "Don't cache host names.", 0, 0, 0,
7663 GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
7664 {"skip-slave-start", 0,
7665 "If set, slave is not autostarted.", &opt_skip_slave_start,
7666 &opt_skip_slave_start, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7667#ifdef HAVE_REPLICATION
7668 {"slave-parallel-mode", OPT_SLAVE_PARALLEL_MODE,
7669 "Controls what transactions are applied in parallel when using "
7670 "--slave-parallel-threads. Possible values: \"optimistic\" tries to "
7671 "apply most transactional DML in parallel, and handles any conflicts "
7672 "with rollback and retry. \"conservative\" limits parallelism in an "
7673 "effort to avoid any conflicts. \"aggressive\" tries to maximise the "
7674 "parallelism, possibly at the cost of increased conflict rate. "
7675 "\"minimal\" only parallelizes the commit steps of transactions. "
7676 "\"none\" disables parallel apply completely.",
7677 &opt_slave_parallel_mode, &opt_slave_parallel_mode,
7678 &slave_parallel_mode_typelib, GET_ENUM | GET_ASK_ADDR, REQUIRED_ARG,
7679 SLAVE_PARALLEL_CONSERVATIVE, 0, 0, 0, 0, 0},
7680#endif
7681#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
7682 {"slow-start-timeout", 0,
7683 "Maximum number of milliseconds that the service control manager should wait "
7684 "before trying to kill the windows service during startup"
7685 "(Default: 15000).", &slow_start_timeout, &slow_start_timeout, 0,
7686 GET_ULONG, REQUIRED_ARG, 15000, 0, 0, 0, 0, 0},
7687#endif
7688#ifdef HAVE_OPENSSL
7689 {"ssl", 0,
7690 "Enable SSL for connection (automatically enabled if an ssl option is used).",
7691 &opt_use_ssl, &opt_use_ssl, 0, GET_BOOL, OPT_ARG, 0, 0, 0,
7692 0, 0, 0},
7693#endif
7694#ifdef __WIN__
7695 {"standalone", 0,
7696 "Dummy option to start as a standalone program (NT).", 0, 0, 0, GET_NO_ARG,
7697 NO_ARG, 0, 0, 0, 0, 0, 0},
7698#endif
7699 {"symbolic-links", 's', "Enable symbolic link support.",
7700 &my_use_symdir, &my_use_symdir, 0, GET_BOOL, NO_ARG,
7701 /*
7702 The system call realpath() produces warnings under valgrind and
7703 purify. These are not suppressed: instead we disable symlinks
7704 option if compiled with valgrind support.
7705 Also disable by default on Windows, due to high overhead for checking .sym
7706 files.
7707 */
7708 IF_VALGRIND(0,IF_WIN(0,1)), 0, 0, 0, 0, 0},
7709 {"sysdate-is-now", 0,
7710 "Non-default option to alias SYSDATE() to NOW() to make it safe-replicable. "
7711 "Since 5.0, SYSDATE() returns a `dynamic' value different for different "
7712 "invocations, even within the same statement.",
7713 &global_system_variables.sysdate_is_now,
7714 0, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
7715 {"tc-heuristic-recover", 0,
7716 "Decision to use in heuristic recover process",
7717 &tc_heuristic_recover, &tc_heuristic_recover,
7718 &tc_heuristic_recover_typelib, GET_ENUM, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7719 {"temp-pool", 0,
7720#if (ENABLE_TEMP_POOL)
7721 "Using this option will cause most temporary files created to use a small "
7722 "set of names, rather than a unique name for each new file.",
7723#else
7724 "This option is ignored on this OS.",
7725#endif
7726 &use_temp_pool, &use_temp_pool, 0, GET_BOOL, NO_ARG, 1,
7727 0, 0, 0, 0, 0},
7728 {"transaction-isolation", 0,
7729 "Default transaction isolation level",
7730 &global_system_variables.tx_isolation,
7731 &global_system_variables.tx_isolation, &tx_isolation_typelib,
7732 GET_ENUM, REQUIRED_ARG, ISO_REPEATABLE_READ, 0, 0, 0, 0, 0},
7733 {"transaction-read-only", 0,
7734 "Default transaction access mode. "
7735 "True if transactions are read-only.",
7736 &global_system_variables.tx_read_only,
7737 &global_system_variables.tx_read_only, 0,
7738 GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
7739 {"user", 'u', "Run mysqld daemon as user.", 0, 0, 0, GET_STR, REQUIRED_ARG,
7740 0, 0, 0, 0, 0, 0},
7741 {"verbose", 'v', "Used with --help option for detailed help.",
7742 &opt_verbose, &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7743 {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_STR,
7744 OPT_ARG, 0, 0, 0, 0, 0, 0},
7745 {"plugin-load", OPT_PLUGIN_LOAD,
7746 "Semicolon-separated list of plugins to load, where each plugin is "
7747 "specified as ether a plugin_name=library_file pair or only a library_file. "
7748 "If the latter case, all plugins from a given library_file will be loaded.",
7749 0, 0, 0,
7750 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7751 {"plugin-load-add", OPT_PLUGIN_LOAD_ADD,
7752 "Optional semicolon-separated list of plugins to load. This option adds "
7753 "to the list specified by --plugin-load in an incremental way. "
7754 "It can be specified many times, adding more plugins every time.",
7755 0, 0, 0,
7756 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7757 {"table_cache", 0, "Deprecated; use --table-open-cache instead.",
7758 &tc_size, &tc_size, 0, GET_ULONG,
7759 REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
7760#ifdef WITH_WSREP
7761 {"wsrep-new-cluster", 0, "Bootstrap a cluster. It works by overriding the "
7762 "current value of wsrep_cluster_address. It is recommended not to add this "
7763 "option to the config file as this will trigger bootstrap on every server "
7764 "start.", &wsrep_new_cluster, &wsrep_new_cluster, 0, GET_BOOL, NO_ARG,
7765 0, 0, 0, 0, 0, 0},
7766#endif
7767
7768 /* The following options exist in 5.6 but not in 10.0 */
7769 MYSQL_COMPATIBILITY_OPTION("log-raw"),
7770 MYSQL_COMPATIBILITY_OPTION("log-bin-use-v1-row-events"),
7771 MYSQL_TO_BE_IMPLEMENTED_OPTION("default-authentication-plugin"),
7772 MYSQL_COMPATIBILITY_OPTION("binlog-max-flush-queue-time"),
7773 MYSQL_COMPATIBILITY_OPTION("master-info-repository"),
7774 MYSQL_COMPATIBILITY_OPTION("relay-log-info-repository"),
7775 MYSQL_SUGGEST_ANALOG_OPTION("binlog-rows-query-log-events", "--binlog-annotate-row-events"),
7776 MYSQL_COMPATIBILITY_OPTION("binlog-order-commits"),
7777 MYSQL_TO_BE_IMPLEMENTED_OPTION("log-throttle-queries-not-using-indexes"),
7778 MYSQL_TO_BE_IMPLEMENTED_OPTION("end-markers-in-json"),
7779 MYSQL_TO_BE_IMPLEMENTED_OPTION("optimizer-trace"), // OPTIMIZER_TRACE
7780 MYSQL_TO_BE_IMPLEMENTED_OPTION("optimizer-trace-features"), // OPTIMIZER_TRACE
7781 MYSQL_TO_BE_IMPLEMENTED_OPTION("optimizer-trace-offset"), // OPTIMIZER_TRACE
7782 MYSQL_TO_BE_IMPLEMENTED_OPTION("optimizer-trace-limit"), // OPTIMIZER_TRACE
7783 MYSQL_TO_BE_IMPLEMENTED_OPTION("optimizer-trace-max-mem-size"), // OPTIMIZER_TRACE
7784 MYSQL_TO_BE_IMPLEMENTED_OPTION("eq-range-index-dive-limit"),
7785 MYSQL_COMPATIBILITY_OPTION("server-id-bits"),
7786 MYSQL_TO_BE_IMPLEMENTED_OPTION("slave-rows-search-algorithms"), // HAVE_REPLICATION
7787 MYSQL_TO_BE_IMPLEMENTED_OPTION("slave-allow-batching"), // HAVE_REPLICATION
7788 MYSQL_COMPATIBILITY_OPTION("slave-checkpoint-period"), // HAVE_REPLICATION
7789 MYSQL_COMPATIBILITY_OPTION("slave-checkpoint-group"), // HAVE_REPLICATION
7790 MYSQL_SUGGEST_ANALOG_OPTION("slave-pending-jobs-size-max", "--slave-parallel-max-queued"), // HAVE_REPLICATION
7791 MYSQL_TO_BE_IMPLEMENTED_OPTION("disconnect-on-expired-password"),
7792 MYSQL_TO_BE_IMPLEMENTED_OPTION("sha256-password-private-key-path"), // HAVE_OPENSSL && !HAVE_YASSL
7793 MYSQL_TO_BE_IMPLEMENTED_OPTION("sha256-password-public-key-path"), // HAVE_OPENSSL && !HAVE_YASSL
7794
7795 /* The following options exist in 5.5 and 5.6 but not in 10.0 */
7796 MYSQL_SUGGEST_ANALOG_OPTION("abort-slave-event-count", "--debug-abort-slave-event-count"),
7797 MYSQL_SUGGEST_ANALOG_OPTION("disconnect-slave-event-count", "--debug-disconnect-slave-event-count"),
7798 MYSQL_SUGGEST_ANALOG_OPTION("exit-info", "--debug-exit-info"),
7799 MYSQL_SUGGEST_ANALOG_OPTION("max-binlog-dump-events", "--debug-max-binlog-dump-events"),
7800 MYSQL_SUGGEST_ANALOG_OPTION("sporadic-binlog-dump-fail", "--debug-sporadic-binlog-dump-fail"),
7801 MYSQL_COMPATIBILITY_OPTION("new"),
7802 MYSQL_COMPATIBILITY_OPTION("show_compatibility_56"),
7803
7804 /* The following options were added after 5.6.10 */
7805 MYSQL_TO_BE_IMPLEMENTED_OPTION("rpl-stop-slave-timeout"),
7806 MYSQL_TO_BE_IMPLEMENTED_OPTION("validate-user-plugins") // NO_EMBEDDED_ACCESS_CHECKS
7807};
7808
7809static int show_queries(THD *thd, SHOW_VAR *var, char *buff,
7810 enum enum_var_type scope)
7811{
7812 var->type= SHOW_LONGLONG;
7813 var->value= &thd->query_id;
7814 return 0;
7815}
7816
7817
7818static int show_net_compression(THD *thd, SHOW_VAR *var, char *buff,
7819 enum enum_var_type scope)
7820{
7821 var->type= SHOW_MY_BOOL;
7822 var->value= &thd->net.compress;
7823 return 0;
7824}
7825
7826static int show_starttime(THD *thd, SHOW_VAR *var, char *buff,
7827 enum enum_var_type scope)
7828{
7829 var->type= SHOW_LONG;
7830 var->value= buff;
7831 *((long *)buff)= (long) (thd->query_start() - server_start_time);
7832 return 0;
7833}
7834
7835#ifdef ENABLED_PROFILING
7836static int show_flushstatustime(THD *thd, SHOW_VAR *var, char *buff,
7837 enum enum_var_type scope)
7838{
7839 var->type= SHOW_LONG;
7840 var->value= buff;
7841 *((long *)buff)= (long) (thd->query_start() - flush_status_time);
7842 return 0;
7843}
7844#endif
7845
7846#ifdef HAVE_REPLICATION
7847static int show_rpl_status(THD *thd, SHOW_VAR *var, char *buff,
7848 enum enum_var_type scope)
7849{
7850 var->type= SHOW_CHAR;
7851 var->value= const_cast<char*>(rpl_status_type[(int)rpl_status]);
7852 return 0;
7853}
7854
7855static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff,
7856 enum enum_var_type scope)
7857{
7858 Master_info *mi= NULL;
7859 bool UNINIT_VAR(tmp);
7860
7861 var->type= SHOW_MY_BOOL;
7862 var->value= buff;
7863
7864 if ((mi= get_master_info(&thd->variables.default_master_connection,
7865 Sql_condition::WARN_LEVEL_NOTE)))
7866 {
7867 tmp= (my_bool) (mi->slave_running == MYSQL_SLAVE_RUN_READING &&
7868 mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN);
7869 mi->release();
7870 }
7871 if (mi)
7872 *((my_bool *)buff)= tmp;
7873 else
7874 var->type= SHOW_UNDEF;
7875 return 0;
7876}
7877
7878
7879/* How many slaves are connected to this master */
7880
7881static int show_slaves_connected(THD *thd, SHOW_VAR *var, char *buff)
7882{
7883
7884 var->type= SHOW_LONGLONG;
7885 var->value= buff;
7886 mysql_mutex_lock(&LOCK_slave_list);
7887
7888 *((longlong *)buff)= slave_list.records;
7889
7890 mysql_mutex_unlock(&LOCK_slave_list);
7891 return 0;
7892}
7893
7894
7895/* How many masters this slave is connected to */
7896
7897
7898static int show_slaves_running(THD *thd, SHOW_VAR *var, char *buff)
7899{
7900 var->type= SHOW_LONGLONG;
7901 var->value= buff;
7902
7903 *((longlong *)buff)= any_slave_sql_running(false);
7904
7905 return 0;
7906}
7907
7908
7909static int show_slave_received_heartbeats(THD *thd, SHOW_VAR *var, char *buff,
7910 enum enum_var_type scope)
7911{
7912 Master_info *mi;
7913
7914 var->type= SHOW_LONGLONG;
7915 var->value= buff;
7916
7917 if ((mi= get_master_info(&thd->variables.default_master_connection,
7918 Sql_condition::WARN_LEVEL_NOTE)))
7919 {
7920 *((longlong *)buff)= mi->received_heartbeats;
7921 mi->release();
7922 }
7923 else
7924 var->type= SHOW_UNDEF;
7925 return 0;
7926}
7927
7928
7929static int show_heartbeat_period(THD *thd, SHOW_VAR *var, char *buff,
7930 enum enum_var_type scope)
7931{
7932 Master_info *mi;
7933
7934 var->type= SHOW_CHAR;
7935 var->value= buff;
7936
7937 if ((mi= get_master_info(&thd->variables.default_master_connection,
7938 Sql_condition::WARN_LEVEL_NOTE)))
7939 {
7940 sprintf(buff, "%.3f", mi->heartbeat_period);
7941 mi->release();
7942 }
7943 else
7944 var->type= SHOW_UNDEF;
7945 return 0;
7946}
7947
7948
7949#endif /* HAVE_REPLICATION */
7950
7951static int show_open_tables(THD *thd, SHOW_VAR *var, char *buff,
7952 enum enum_var_type scope)
7953{
7954 var->type= SHOW_LONG;
7955 var->value= buff;
7956 *((long *) buff)= (long) tc_records();
7957 return 0;
7958}
7959
7960static int show_prepared_stmt_count(THD *thd, SHOW_VAR *var, char *buff,
7961 enum enum_var_type scope)
7962{
7963 var->type= SHOW_LONG;
7964 var->value= buff;
7965 mysql_mutex_lock(&LOCK_prepared_stmt_count);
7966 *((long *)buff)= (long)prepared_stmt_count;
7967 mysql_mutex_unlock(&LOCK_prepared_stmt_count);
7968 return 0;
7969}
7970
7971static int show_table_definitions(THD *thd, SHOW_VAR *var, char *buff,
7972 enum enum_var_type scope)
7973{
7974 var->type= SHOW_LONG;
7975 var->value= buff;
7976 *((long *) buff)= (long) tdc_records();
7977 return 0;
7978}
7979
7980
7981static int show_flush_commands(THD *thd, SHOW_VAR *var, char *buff,
7982 enum enum_var_type scope)
7983{
7984 var->type= SHOW_LONGLONG;
7985 var->value= buff;
7986 *((longlong *) buff)= (longlong)tdc_refresh_version();
7987 return 0;
7988}
7989
7990
7991#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
7992/* Functions relying on CTX */
7993static int show_ssl_ctx_sess_accept(THD *thd, SHOW_VAR *var, char *buff,
7994 enum enum_var_type scope)
7995{
7996 var->type= SHOW_LONG;
7997 var->value= buff;
7998 *((long *)buff)= (!ssl_acceptor_fd ? 0 :
7999 SSL_CTX_sess_accept(ssl_acceptor_fd->ssl_context));
8000 return 0;
8001}
8002
8003static int show_ssl_ctx_sess_accept_good(THD *thd, SHOW_VAR *var, char *buff,
8004 enum enum_var_type scope)
8005{
8006 var->type= SHOW_LONG;
8007 var->value= buff;
8008 *((long *)buff)= (!ssl_acceptor_fd ? 0 :
8009 SSL_CTX_sess_accept_good(ssl_acceptor_fd->ssl_context));
8010 return 0;
8011}
8012
8013static int show_ssl_ctx_sess_connect_good(THD *thd, SHOW_VAR *var, char *buff,
8014 enum enum_var_type scope)
8015{
8016 var->type= SHOW_LONG;
8017 var->value= buff;
8018 *((long *)buff)= (!ssl_acceptor_fd ? 0 :
8019 SSL_CTX_sess_connect_good(ssl_acceptor_fd->ssl_context));
8020 return 0;
8021}
8022
8023static int show_ssl_ctx_sess_accept_renegotiate(THD *thd, SHOW_VAR *var,
8024 char *buff,
8025 enum enum_var_type scope)
8026{
8027 var->type= SHOW_LONG;
8028 var->value= buff;
8029 *((long *)buff)= (!ssl_acceptor_fd ? 0 :
8030 SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context));
8031 return 0;
8032}
8033
8034static int show_ssl_ctx_sess_connect_renegotiate(THD *thd, SHOW_VAR *var,
8035 char *buff,
8036 enum enum_var_type scope)
8037{
8038 var->type= SHOW_LONG;
8039 var->value= buff;
8040 *((long *)buff)= (!ssl_acceptor_fd ? 0 :
8041 SSL_CTX_sess_connect_renegotiate(ssl_acceptor_fd->ssl_context));
8042 return 0;
8043}
8044
8045static int show_ssl_ctx_sess_cb_hits(THD *thd, SHOW_VAR *var, char *buff,
8046 enum enum_var_type scope)
8047{
8048 var->type= SHOW_LONG;
8049 var->value= buff;
8050 *((long *)buff)= (!ssl_acceptor_fd ? 0 :
8051 SSL_CTX_sess_cb_hits(ssl_acceptor_fd->ssl_context));
8052 return 0;
8053}
8054
8055static int show_ssl_ctx_sess_hits(THD *thd, SHOW_VAR *var, char *buff,
8056 enum enum_var_type scope)
8057{
8058 var->type= SHOW_LONG;
8059 var->value= buff;
8060 *((long *)buff)= (!ssl_acceptor_fd ? 0 :
8061 SSL_CTX_sess_hits(ssl_acceptor_fd->ssl_context));
8062 return 0;
8063}
8064
8065static int show_ssl_ctx_sess_cache_full(THD *thd, SHOW_VAR *var, char *buff,
8066 enum enum_var_type scope)
8067{
8068 var->type= SHOW_LONG;
8069 var->value= buff;
8070 *((long *)buff)= (!ssl_acceptor_fd ? 0 :
8071 SSL_CTX_sess_cache_full(ssl_acceptor_fd->ssl_context));
8072 return 0;
8073}
8074
8075static int show_ssl_ctx_sess_misses(THD *thd, SHOW_VAR *var, char *buff,
8076 enum enum_var_type scope)
8077{
8078 var->type= SHOW_LONG;
8079 var->value= buff;
8080 *((long *)buff)= (!ssl_acceptor_fd ? 0 :
8081 SSL_CTX_sess_misses(ssl_acceptor_fd->ssl_context));
8082 return 0;
8083}
8084
8085static int show_ssl_ctx_sess_timeouts(THD *thd, SHOW_VAR *var, char *buff,
8086 enum enum_var_type scope)
8087{
8088 var->type= SHOW_LONG;
8089 var->value= buff;
8090 *((long *)buff)= (!ssl_acceptor_fd ? 0 :
8091 SSL_CTX_sess_timeouts(ssl_acceptor_fd->ssl_context));
8092 return 0;
8093}
8094
8095static int show_ssl_ctx_sess_number(THD *thd, SHOW_VAR *var, char *buff,
8096 enum enum_var_type scope)
8097{
8098 var->type= SHOW_LONG;
8099 var->value= buff;
8100 *((long *)buff)= (!ssl_acceptor_fd ? 0 :
8101 SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context));
8102 return 0;
8103}
8104
8105static int show_ssl_ctx_sess_connect(THD *thd, SHOW_VAR *var, char *buff,
8106 enum enum_var_type scope)
8107{
8108 var->type= SHOW_LONG;
8109 var->value= buff;
8110 *((long *)buff)= (!ssl_acceptor_fd ? 0 :
8111 SSL_CTX_sess_connect(ssl_acceptor_fd->ssl_context));
8112 return 0;
8113}
8114
8115static int show_ssl_ctx_sess_get_cache_size(THD *thd, SHOW_VAR *var,
8116 char *buff,
8117 enum enum_var_type scope)
8118{
8119 var->type= SHOW_LONG;
8120 var->value= buff;
8121 *((long *)buff)= (!ssl_acceptor_fd ? 0 :
8122 SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context));
8123 return 0;
8124}
8125
8126static int show_ssl_ctx_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff,
8127 enum enum_var_type scope)
8128{
8129 var->type= SHOW_LONG;
8130 var->value= buff;
8131 *((long *)buff)= (!ssl_acceptor_fd ? 0 :
8132 SSL_CTX_get_verify_mode(ssl_acceptor_fd->ssl_context));
8133 return 0;
8134}
8135
8136static int show_ssl_ctx_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff,
8137 enum enum_var_type scope)
8138{
8139 var->type= SHOW_LONG;
8140 var->value= buff;
8141 *((long *)buff)= (!ssl_acceptor_fd ? 0 :
8142 SSL_CTX_get_verify_depth(ssl_acceptor_fd->ssl_context));
8143 return 0;
8144}
8145
8146static int show_ssl_ctx_get_session_cache_mode(THD *thd, SHOW_VAR *var,
8147 char *buff,
8148 enum enum_var_type scope)
8149{
8150 var->type= SHOW_CHAR;
8151 if (!ssl_acceptor_fd)
8152 var->value= const_cast<char*>("NONE");
8153 else
8154 switch (SSL_CTX_get_session_cache_mode(ssl_acceptor_fd->ssl_context))
8155 {
8156 case SSL_SESS_CACHE_OFF:
8157 var->value= const_cast<char*>("OFF"); break;
8158 case SSL_SESS_CACHE_CLIENT:
8159 var->value= const_cast<char*>("CLIENT"); break;
8160 case SSL_SESS_CACHE_SERVER:
8161 var->value= const_cast<char*>("SERVER"); break;
8162 case SSL_SESS_CACHE_BOTH:
8163 var->value= const_cast<char*>("BOTH"); break;
8164 case SSL_SESS_CACHE_NO_AUTO_CLEAR:
8165 var->value= const_cast<char*>("NO_AUTO_CLEAR"); break;
8166 case SSL_SESS_CACHE_NO_INTERNAL_LOOKUP:
8167 var->value= const_cast<char*>("NO_INTERNAL_LOOKUP"); break;
8168 default:
8169 var->value= const_cast<char*>("Unknown"); break;
8170 }
8171 return 0;
8172}
8173
8174/*
8175 Functions relying on SSL
8176 Note: In the show_ssl_* functions, we need to check if we have a
8177 valid vio-object since this isn't always true, specifically
8178 when session_status or global_status is requested from
8179 inside an Event.
8180 */
8181
8182static int show_ssl_get_version(THD *thd, SHOW_VAR *var, char *buff,
8183 enum enum_var_type scope)
8184{
8185 var->type= SHOW_CHAR;
8186 if( thd->vio_ok() && thd->net.vio->ssl_arg )
8187 var->value= const_cast<char*>(SSL_get_version((SSL*) thd->net.vio->ssl_arg));
8188 else
8189 var->value= const_cast<char*>("");
8190 return 0;
8191}
8192
8193static int show_ssl_session_reused(THD *thd, SHOW_VAR *var, char *buff,
8194 enum enum_var_type scope)
8195{
8196 var->type= SHOW_LONG;
8197 var->value= buff;
8198 if( thd->vio_ok() && thd->net.vio->ssl_arg )
8199 *((long *)buff)= (long)SSL_session_reused((SSL*) thd->net.vio->ssl_arg);
8200 else
8201 *((long *)buff)= 0;
8202 return 0;
8203}
8204
8205static int show_ssl_get_default_timeout(THD *thd, SHOW_VAR *var, char *buff,
8206 enum enum_var_type scope)
8207{
8208 var->type= SHOW_LONG;
8209 var->value= buff;
8210 if( thd->vio_ok() && thd->net.vio->ssl_arg )
8211 *((long *)buff)= (long)SSL_get_default_timeout((SSL*)thd->net.vio->ssl_arg);
8212 else
8213 *((long *)buff)= 0;
8214 return 0;
8215}
8216
8217static int show_ssl_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff,
8218 enum enum_var_type scope)
8219{
8220 var->type= SHOW_LONG;
8221 var->value= buff;
8222 if( thd->net.vio && thd->net.vio->ssl_arg )
8223 *((long *)buff)= (long)SSL_get_verify_mode((SSL*)thd->net.vio->ssl_arg);
8224 else
8225 *((long *)buff)= 0;
8226 return 0;
8227}
8228
8229static int show_ssl_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff,
8230 enum enum_var_type scope)
8231{
8232 var->type= SHOW_LONG;
8233 var->value= buff;
8234 if( thd->vio_ok() && thd->net.vio->ssl_arg )
8235 *((long *)buff)= (long)SSL_get_verify_depth((SSL*)thd->net.vio->ssl_arg);
8236 else
8237 *((long *)buff)= 0;
8238 return 0;
8239}
8240
8241static int show_ssl_get_cipher(THD *thd, SHOW_VAR *var, char *buff,
8242 enum enum_var_type scope)
8243{
8244 var->type= SHOW_CHAR;
8245 if( thd->vio_ok() && thd->net.vio->ssl_arg )
8246 var->value= const_cast<char*>(SSL_get_cipher((SSL*) thd->net.vio->ssl_arg));
8247 else
8248 var->value= const_cast<char*>("");
8249 return 0;
8250}
8251
8252static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff,
8253 enum enum_var_type scope)
8254{
8255 var->type= SHOW_CHAR;
8256 var->value= buff;
8257 if (thd->vio_ok() && thd->net.vio->ssl_arg)
8258 {
8259 int i;
8260 const char *p;
8261 char *end= buff + SHOW_VAR_FUNC_BUFF_SIZE;
8262 for (i=0; (p= SSL_get_cipher_list((SSL*) thd->net.vio->ssl_arg,i)) &&
8263 buff < end; i++)
8264 {
8265 buff= strnmov(buff, p, end-buff-1);
8266 *buff++= ':';
8267 }
8268 if (i)
8269 buff--;
8270 }
8271 *buff=0;
8272 return 0;
8273}
8274
8275#define SHOW_FNAME(name) \
8276 rpl_semi_sync_master_show_##name
8277
8278#define DEF_SHOW_FUNC(name, show_type) \
8279 static int SHOW_FNAME(name)(MYSQL_THD thd, SHOW_VAR *var, char *buff) \
8280 { \
8281 repl_semisync_master.set_export_stats(); \
8282 var->type= show_type; \
8283 var->value= (char *)&rpl_semi_sync_master_##name; \
8284 return 0; \
8285 }
8286
8287DEF_SHOW_FUNC(status, SHOW_BOOL)
8288DEF_SHOW_FUNC(clients, SHOW_LONG)
8289DEF_SHOW_FUNC(wait_sessions, SHOW_LONG)
8290DEF_SHOW_FUNC(trx_wait_time, SHOW_LONGLONG)
8291DEF_SHOW_FUNC(trx_wait_num, SHOW_LONGLONG)
8292DEF_SHOW_FUNC(net_wait_time, SHOW_LONGLONG)
8293DEF_SHOW_FUNC(net_wait_num, SHOW_LONGLONG)
8294DEF_SHOW_FUNC(avg_net_wait_time, SHOW_LONG)
8295DEF_SHOW_FUNC(avg_trx_wait_time, SHOW_LONG)
8296
8297#ifdef HAVE_YASSL
8298
8299static char *
8300my_asn1_time_to_string(const ASN1_TIME *time, char *buf, size_t len)
8301{
8302 return yaSSL_ASN1_TIME_to_string(time, buf, len);
8303}
8304
8305#else /* openssl */
8306
8307static char *
8308my_asn1_time_to_string(const ASN1_TIME *time, char *buf, size_t len)
8309{
8310 int n_read;
8311 char *res= NULL;
8312 BIO *bio= BIO_new(BIO_s_mem());
8313
8314 if (bio == NULL)
8315 return NULL;
8316
8317 if (!ASN1_TIME_print(bio, time))
8318 goto end;
8319
8320 n_read= BIO_read(bio, buf, (int) (len - 1));
8321
8322 if (n_read > 0)
8323 {
8324 buf[n_read]= 0;
8325 res= buf;
8326 }
8327
8328end:
8329 BIO_free(bio);
8330 return res;
8331}
8332
8333#endif
8334
8335
8336/**
8337 Handler function for the 'ssl_get_server_not_before' variable
8338
8339 @param thd the mysql thread structure
8340 @param var the data for the variable
8341 @param[out] buf the string to put the value of the variable into
8342
8343 @return status
8344 @retval 0 success
8345*/
8346
8347static int
8348show_ssl_get_server_not_before(THD *thd, SHOW_VAR *var, char *buff,
8349 enum enum_var_type scope)
8350{
8351 var->type= SHOW_CHAR;
8352 if(thd->vio_ok() && thd->net.vio->ssl_arg)
8353 {
8354 SSL *ssl= (SSL*) thd->net.vio->ssl_arg;
8355 X509 *cert= SSL_get_certificate(ssl);
8356 const ASN1_TIME *not_before= X509_get0_notBefore(cert);
8357
8358 var->value= my_asn1_time_to_string(not_before, buff,
8359 SHOW_VAR_FUNC_BUFF_SIZE);
8360 if (!var->value)
8361 return 1;
8362 var->value= buff;
8363 }
8364 else
8365 var->value= empty_c_string;
8366 return 0;
8367}
8368
8369
8370/**
8371 Handler function for the 'ssl_get_server_not_after' variable
8372
8373 @param thd the mysql thread structure
8374 @param var the data for the variable
8375 @param[out] buf the string to put the value of the variable into
8376
8377 @return status
8378 @retval 0 success
8379*/
8380
8381static int
8382show_ssl_get_server_not_after(THD *thd, SHOW_VAR *var, char *buff,
8383 enum enum_var_type scope)
8384{
8385 var->type= SHOW_CHAR;
8386 if(thd->vio_ok() && thd->net.vio->ssl_arg)
8387 {
8388 SSL *ssl= (SSL*) thd->net.vio->ssl_arg;
8389 X509 *cert= SSL_get_certificate(ssl);
8390 const ASN1_TIME *not_after= X509_get0_notAfter(cert);
8391
8392 var->value= my_asn1_time_to_string(not_after, buff,
8393 SHOW_VAR_FUNC_BUFF_SIZE);
8394 if (!var->value)
8395 return 1;
8396 }
8397 else
8398 var->value= empty_c_string;
8399 return 0;
8400}
8401
8402#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
8403
8404static int show_default_keycache(THD *thd, SHOW_VAR *var, char *buff,
8405 enum enum_var_type scope)
8406{
8407 struct st_data {
8408 KEY_CACHE_STATISTICS stats;
8409 SHOW_VAR var[9];
8410 } *data;
8411 SHOW_VAR *v;
8412
8413 data=(st_data *)buff;
8414 v= data->var;
8415
8416 var->type= SHOW_ARRAY;
8417 var->value= v;
8418
8419 get_key_cache_statistics(dflt_key_cache, 0, &data->stats);
8420
8421#define set_one_keycache_var(X,Y) \
8422 v->name= X; \
8423 v->type= SHOW_LONGLONG; \
8424 v->value= &data->stats.Y; \
8425 v++;
8426
8427 set_one_keycache_var("blocks_not_flushed", blocks_changed);
8428 set_one_keycache_var("blocks_unused", blocks_unused);
8429 set_one_keycache_var("blocks_used", blocks_used);
8430 set_one_keycache_var("blocks_warm", blocks_warm);
8431 set_one_keycache_var("read_requests", read_requests);
8432 set_one_keycache_var("reads", reads);
8433 set_one_keycache_var("write_requests", write_requests);
8434 set_one_keycache_var("writes", writes);
8435
8436 v->name= 0;
8437
8438 DBUG_ASSERT((char*)(v+1) <= buff + SHOW_VAR_FUNC_BUFF_SIZE);
8439
8440#undef set_one_keycache_var
8441
8442 return 0;
8443}
8444
8445
8446static int show_memory_used(THD *thd, SHOW_VAR *var, char *buff,
8447 struct system_status_var *status_var,
8448 enum enum_var_type scope)
8449{
8450 var->type= SHOW_LONGLONG;
8451 var->value= buff;
8452 if (scope == OPT_GLOBAL)
8453 *(longlong*) buff= (status_var->global_memory_used +
8454 status_var->local_memory_used);
8455 else
8456 *(longlong*) buff= status_var->local_memory_used;
8457 return 0;
8458}
8459
8460
8461#ifndef DBUG_OFF
8462static int debug_status_func(THD *thd, SHOW_VAR *var, char *buff,
8463 enum enum_var_type scope)
8464{
8465#define add_var(X,Y,Z) \
8466 v->name= X; \
8467 v->value= (char*)Y; \
8468 v->type= Z; \
8469 v++;
8470
8471 var->type= SHOW_ARRAY;
8472 var->value= buff;
8473
8474 SHOW_VAR *v= (SHOW_VAR *)buff;
8475
8476 if (_db_keyword_(0, "role_merge_stats", 1))
8477 {
8478 static SHOW_VAR roles[]= {
8479 {"global", &role_global_merges, SHOW_ULONG},
8480 {"db", &role_db_merges, SHOW_ULONG},
8481 {"table", &role_table_merges, SHOW_ULONG},
8482 {"column", &role_column_merges, SHOW_ULONG},
8483 {"routine", &role_routine_merges, SHOW_ULONG},
8484 {NullS, NullS, SHOW_LONG}
8485 };
8486
8487 add_var("role_merges", roles, SHOW_ARRAY);
8488 }
8489
8490 v->name= 0;
8491
8492#undef add_var
8493
8494 return 0;
8495}
8496#endif
8497
8498#ifdef HAVE_POOL_OF_THREADS
8499int show_threadpool_idle_threads(THD *thd, SHOW_VAR *var, char *buff,
8500 enum enum_var_type scope)
8501{
8502 var->type= SHOW_INT;
8503 var->value= buff;
8504 *(int *)buff= tp_get_idle_thread_count();
8505 return 0;
8506}
8507#endif
8508
8509/*
8510 Variables shown by SHOW STATUS in alphabetical order
8511*/
8512
8513SHOW_VAR status_vars[]= {
8514 {"Aborted_clients", (char*) &aborted_threads, SHOW_LONG},
8515 {"Aborted_connects", (char*) &aborted_connects, SHOW_LONG},
8516 {"Acl", (char*) acl_statistics, SHOW_ARRAY},
8517 {"Access_denied_errors", (char*) offsetof(STATUS_VAR, access_denied_errors), SHOW_LONG_STATUS},
8518 {"Binlog_bytes_written", (char*) offsetof(STATUS_VAR, binlog_bytes_written), SHOW_LONGLONG_STATUS},
8519 {"Binlog_cache_disk_use", (char*) &binlog_cache_disk_use, SHOW_LONG},
8520 {"Binlog_cache_use", (char*) &binlog_cache_use, SHOW_LONG},
8521 {"Binlog_stmt_cache_disk_use",(char*) &binlog_stmt_cache_disk_use, SHOW_LONG},
8522 {"Binlog_stmt_cache_use", (char*) &binlog_stmt_cache_use, SHOW_LONG},
8523 {"Busy_time", (char*) offsetof(STATUS_VAR, busy_time), SHOW_DOUBLE_STATUS},
8524 {"Bytes_received", (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONGLONG_STATUS},
8525 {"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS},
8526 {"Column_compressions", (char*) offsetof(STATUS_VAR, column_compressions), SHOW_LONG_STATUS},
8527 {"Column_decompressions", (char*) offsetof(STATUS_VAR, column_decompressions), SHOW_LONG_STATUS},
8528 {"Com", (char*) com_status_vars, SHOW_ARRAY},
8529 {"Compression", (char*) &show_net_compression, SHOW_SIMPLE_FUNC},
8530 {"Connections", (char*) &global_thread_id, SHOW_LONG_NOFLUSH},
8531 {"Connection_errors_accept", (char*) &connection_errors_accept, SHOW_LONG},
8532 {"Connection_errors_internal", (char*) &connection_errors_internal, SHOW_LONG},
8533 {"Connection_errors_max_connections", (char*) &connection_errors_max_connection, SHOW_LONG},
8534 {"Connection_errors_peer_address", (char*) &connection_errors_peer_addr, SHOW_LONG},
8535 {"Connection_errors_select", (char*) &connection_errors_select, SHOW_LONG},
8536 {"Connection_errors_tcpwrap", (char*) &connection_errors_tcpwrap, SHOW_LONG},
8537 {"Cpu_time", (char*) offsetof(STATUS_VAR, cpu_time), SHOW_DOUBLE_STATUS},
8538 {"Created_tmp_disk_tables", (char*) offsetof(STATUS_VAR, created_tmp_disk_tables_), SHOW_LONG_STATUS},
8539 {"Created_tmp_files", (char*) &my_tmp_file_created, SHOW_LONG},
8540 {"Created_tmp_tables", (char*) offsetof(STATUS_VAR, created_tmp_tables_), SHOW_LONG_STATUS},
8541#ifndef DBUG_OFF
8542 {"Debug", (char*) &debug_status_func, SHOW_FUNC},
8543#endif
8544 {"Delayed_errors", (char*) &delayed_insert_errors, SHOW_LONG},
8545 {"Delayed_insert_threads", (char*) &delayed_insert_threads, SHOW_LONG_NOFLUSH},
8546 {"Delayed_writes", (char*) &delayed_insert_writes, SHOW_LONG},
8547 {"Delete_scan", (char*) offsetof(STATUS_VAR, delete_scan_count), SHOW_LONG_STATUS},
8548 {"Empty_queries", (char*) offsetof(STATUS_VAR, empty_queries), SHOW_LONG_STATUS},
8549 {"Executed_events", (char*) &executed_events, SHOW_LONG_NOFLUSH },
8550 {"Executed_triggers", (char*) offsetof(STATUS_VAR, executed_triggers), SHOW_LONG_STATUS},
8551 {"Feature_check_constraint", (char*) &feature_check_constraint, SHOW_LONG },
8552 {"Feature_custom_aggregate_functions", (char*) offsetof(STATUS_VAR, feature_custom_aggregate_functions), SHOW_LONG_STATUS},
8553 {"Feature_delay_key_write", (char*) &feature_files_opened_with_delayed_keys, SHOW_LONG },
8554 {"Feature_dynamic_columns", (char*) offsetof(STATUS_VAR, feature_dynamic_columns), SHOW_LONG_STATUS},
8555 {"Feature_fulltext", (char*) offsetof(STATUS_VAR, feature_fulltext), SHOW_LONG_STATUS},
8556 {"Feature_gis", (char*) offsetof(STATUS_VAR, feature_gis), SHOW_LONG_STATUS},
8557 {"Feature_invisible_columns", (char*) offsetof(STATUS_VAR, feature_invisible_columns), SHOW_LONG_STATUS},
8558 {"Feature_json", (char*) offsetof(STATUS_VAR, feature_json), SHOW_LONG_STATUS},
8559 {"Feature_locale", (char*) offsetof(STATUS_VAR, feature_locale), SHOW_LONG_STATUS},
8560 {"Feature_subquery", (char*) offsetof(STATUS_VAR, feature_subquery), SHOW_LONG_STATUS},
8561 {"Feature_system_versioning", (char*) offsetof(STATUS_VAR, feature_system_versioning), SHOW_LONG_STATUS},
8562 {"Feature_timezone", (char*) offsetof(STATUS_VAR, feature_timezone), SHOW_LONG_STATUS},
8563 {"Feature_trigger", (char*) offsetof(STATUS_VAR, feature_trigger), SHOW_LONG_STATUS},
8564 {"Feature_window_functions", (char*) offsetof(STATUS_VAR, feature_window_functions), SHOW_LONG_STATUS},
8565 {"Feature_xml", (char*) offsetof(STATUS_VAR, feature_xml), SHOW_LONG_STATUS},
8566 {"Flush_commands", (char*) &show_flush_commands, SHOW_SIMPLE_FUNC},
8567 {"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
8568 {"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS},
8569 {"Handler_discover", (char*) offsetof(STATUS_VAR, ha_discover_count), SHOW_LONG_STATUS},
8570 {"Handler_external_lock", (char*) offsetof(STATUS_VAR, ha_external_lock_count), SHOW_LONG_STATUS},
8571 {"Handler_icp_attempts", (char*) offsetof(STATUS_VAR, ha_icp_attempts), SHOW_LONG_STATUS},
8572 {"Handler_icp_match", (char*) offsetof(STATUS_VAR, ha_icp_match), SHOW_LONG_STATUS},
8573 {"Handler_mrr_init", (char*) offsetof(STATUS_VAR, ha_mrr_init_count), SHOW_LONG_STATUS},
8574 {"Handler_mrr_key_refills", (char*) offsetof(STATUS_VAR, ha_mrr_key_refills_count), SHOW_LONG_STATUS},
8575 {"Handler_mrr_rowid_refills",(char*) offsetof(STATUS_VAR, ha_mrr_rowid_refills_count), SHOW_LONG_STATUS},
8576 {"Handler_prepare", (char*) offsetof(STATUS_VAR, ha_prepare_count), SHOW_LONG_STATUS},
8577 {"Handler_read_first", (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS},
8578 {"Handler_read_key", (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS},
8579 {"Handler_read_last", (char*) offsetof(STATUS_VAR, ha_read_last_count), SHOW_LONG_STATUS},
8580 {"Handler_read_next", (char*) offsetof(STATUS_VAR, ha_read_next_count), SHOW_LONG_STATUS},
8581 {"Handler_read_prev", (char*) offsetof(STATUS_VAR, ha_read_prev_count), SHOW_LONG_STATUS},
8582 {"Handler_read_retry", (char*) offsetof(STATUS_VAR, ha_read_retry_count), SHOW_LONG_STATUS},
8583 {"Handler_read_rnd", (char*) offsetof(STATUS_VAR, ha_read_rnd_count), SHOW_LONG_STATUS},
8584 {"Handler_read_rnd_deleted", (char*) offsetof(STATUS_VAR, ha_read_rnd_deleted_count), SHOW_LONG_STATUS},
8585 {"Handler_read_rnd_next", (char*) offsetof(STATUS_VAR, ha_read_rnd_next_count), SHOW_LONG_STATUS},
8586 {"Handler_rollback", (char*) offsetof(STATUS_VAR, ha_rollback_count), SHOW_LONG_STATUS},
8587 {"Handler_savepoint", (char*) offsetof(STATUS_VAR, ha_savepoint_count), SHOW_LONG_STATUS},
8588 {"Handler_savepoint_rollback",(char*) offsetof(STATUS_VAR, ha_savepoint_rollback_count), SHOW_LONG_STATUS},
8589 {"Handler_tmp_delete", (char*) offsetof(STATUS_VAR, ha_tmp_delete_count), SHOW_LONG_STATUS},
8590 {"Handler_tmp_update", (char*) offsetof(STATUS_VAR, ha_tmp_update_count), SHOW_LONG_STATUS},
8591 {"Handler_tmp_write", (char*) offsetof(STATUS_VAR, ha_tmp_write_count), SHOW_LONG_STATUS},
8592 {"Handler_update", (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS},
8593 {"Handler_write", (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS},
8594 {"Key", (char*) &show_default_keycache, SHOW_FUNC},
8595 {"Last_query_cost", (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS},
8596 {"Max_statement_time_exceeded", (char*) offsetof(STATUS_VAR, max_statement_time_exceeded), SHOW_LONG_STATUS},
8597 {"Master_gtid_wait_count", (char*) offsetof(STATUS_VAR, master_gtid_wait_count), SHOW_LONGLONG_STATUS},
8598 {"Master_gtid_wait_timeouts", (char*) offsetof(STATUS_VAR, master_gtid_wait_timeouts), SHOW_LONGLONG_STATUS},
8599 {"Master_gtid_wait_time", (char*) offsetof(STATUS_VAR, master_gtid_wait_time), SHOW_LONGLONG_STATUS},
8600 {"Max_used_connections", (char*) &max_used_connections, SHOW_LONG},
8601 {"Memory_used", (char*) &show_memory_used, SHOW_SIMPLE_FUNC},
8602 {"Memory_used_initial", (char*) &start_memory_used, SHOW_LONGLONG},
8603 {"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use, SHOW_LONG_NOFLUSH},
8604 {"Open_files", (char*) &my_file_opened, SHOW_LONG_NOFLUSH},
8605 {"Open_streams", (char*) &my_stream_opened, SHOW_LONG_NOFLUSH},
8606 {"Open_table_definitions", (char*) &show_table_definitions, SHOW_SIMPLE_FUNC},
8607 {"Open_tables", (char*) &show_open_tables, SHOW_SIMPLE_FUNC},
8608 {"Opened_files", (char*) &my_file_total_opened, SHOW_LONG_NOFLUSH},
8609 {"Opened_plugin_libraries", (char*) &dlopen_count, SHOW_LONG},
8610 {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS},
8611 {"Opened_tables", (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS},
8612 {"Opened_views", (char*) offsetof(STATUS_VAR, opened_views), SHOW_LONG_STATUS},
8613 {"Prepared_stmt_count", (char*) &show_prepared_stmt_count, SHOW_SIMPLE_FUNC},
8614 {"Rows_sent", (char*) offsetof(STATUS_VAR, rows_sent), SHOW_LONGLONG_STATUS},
8615 {"Rows_read", (char*) offsetof(STATUS_VAR, rows_read), SHOW_LONGLONG_STATUS},
8616 {"Rows_tmp_read", (char*) offsetof(STATUS_VAR, rows_tmp_read), SHOW_LONGLONG_STATUS},
8617#ifdef HAVE_REPLICATION
8618 {"Rpl_semi_sync_master_status", (char*) &SHOW_FNAME(status), SHOW_FUNC},
8619 {"Rpl_semi_sync_master_clients", (char*) &SHOW_FNAME(clients), SHOW_FUNC},
8620 {"Rpl_semi_sync_master_yes_tx", (char*) &rpl_semi_sync_master_yes_transactions, SHOW_LONG},
8621 {"Rpl_semi_sync_master_no_tx", (char*) &rpl_semi_sync_master_no_transactions, SHOW_LONG},
8622 {"Rpl_semi_sync_master_wait_sessions", (char*) &SHOW_FNAME(wait_sessions), SHOW_FUNC},
8623 {"Rpl_semi_sync_master_no_times", (char*) &rpl_semi_sync_master_off_times, SHOW_LONG},
8624 {"Rpl_semi_sync_master_timefunc_failures", (char*) &rpl_semi_sync_master_timefunc_fails, SHOW_LONG},
8625 {"Rpl_semi_sync_master_wait_pos_backtraverse", (char*) &rpl_semi_sync_master_wait_pos_backtraverse, SHOW_LONG},
8626 {"Rpl_semi_sync_master_tx_wait_time", (char*) &SHOW_FNAME(trx_wait_time), SHOW_FUNC},
8627 {"Rpl_semi_sync_master_tx_waits", (char*) &SHOW_FNAME(trx_wait_num), SHOW_FUNC},
8628 {"Rpl_semi_sync_master_tx_avg_wait_time", (char*) &SHOW_FNAME(avg_trx_wait_time), SHOW_FUNC},
8629 {"Rpl_semi_sync_master_net_wait_time", (char*) &SHOW_FNAME(net_wait_time), SHOW_FUNC},
8630 {"Rpl_semi_sync_master_net_waits", (char*) &SHOW_FNAME(net_wait_num), SHOW_FUNC},
8631 {"Rpl_semi_sync_master_net_avg_wait_time", (char*) &SHOW_FNAME(avg_net_wait_time), SHOW_FUNC},
8632 {"Rpl_semi_sync_master_request_ack", (char*) &rpl_semi_sync_master_request_ack, SHOW_LONGLONG},
8633 {"Rpl_semi_sync_master_get_ack", (char*)&rpl_semi_sync_master_get_ack, SHOW_LONGLONG},
8634 {"Rpl_semi_sync_slave_status", (char*) &rpl_semi_sync_slave_status, SHOW_BOOL},
8635 {"Rpl_semi_sync_slave_send_ack", (char*) &rpl_semi_sync_slave_send_ack, SHOW_LONGLONG},
8636#endif /* HAVE_REPLICATION */
8637#ifdef HAVE_QUERY_CACHE
8638 {"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks, SHOW_LONG_NOFLUSH},
8639 {"Qcache_free_memory", (char*) &query_cache.free_memory, SHOW_LONG_NOFLUSH},
8640 {"Qcache_hits", (char*) &query_cache.hits, SHOW_LONG},
8641 {"Qcache_inserts", (char*) &query_cache.inserts, SHOW_LONG},
8642 {"Qcache_lowmem_prunes", (char*) &query_cache.lowmem_prunes, SHOW_LONG},
8643 {"Qcache_not_cached", (char*) &query_cache.refused, SHOW_LONG},
8644 {"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache, SHOW_LONG_NOFLUSH},
8645 {"Qcache_total_blocks", (char*) &query_cache.total_blocks, SHOW_LONG_NOFLUSH},
8646#endif /*HAVE_QUERY_CACHE*/
8647 {"Queries", (char*) &show_queries, SHOW_SIMPLE_FUNC},
8648 {"Questions", (char*) offsetof(STATUS_VAR, questions), SHOW_LONG_STATUS},
8649#ifdef HAVE_REPLICATION
8650 {"Rpl_status", (char*) &show_rpl_status, SHOW_SIMPLE_FUNC},
8651#endif
8652 {"Select_full_join", (char*) offsetof(STATUS_VAR, select_full_join_count_), SHOW_LONG_STATUS},
8653 {"Select_full_range_join", (char*) offsetof(STATUS_VAR, select_full_range_join_count_), SHOW_LONG_STATUS},
8654 {"Select_range", (char*) offsetof(STATUS_VAR, select_range_count_), SHOW_LONG_STATUS},
8655 {"Select_range_check", (char*) offsetof(STATUS_VAR, select_range_check_count_), SHOW_LONG_STATUS},
8656 {"Select_scan", (char*) offsetof(STATUS_VAR, select_scan_count_), SHOW_LONG_STATUS},
8657 {"Slave_open_temp_tables", (char*) &slave_open_temp_tables, SHOW_INT},
8658#ifdef HAVE_REPLICATION
8659 {"Slaves_connected", (char*) &show_slaves_connected, SHOW_SIMPLE_FUNC },
8660 {"Slaves_running", (char*) &show_slaves_running, SHOW_SIMPLE_FUNC },
8661 {"Slave_connections", (char*) offsetof(STATUS_VAR, com_register_slave), SHOW_LONG_STATUS},
8662 {"Slave_heartbeat_period", (char*) &show_heartbeat_period, SHOW_SIMPLE_FUNC},
8663 {"Slave_received_heartbeats",(char*) &show_slave_received_heartbeats, SHOW_SIMPLE_FUNC},
8664 {"Slave_retried_transactions",(char*)&slave_retried_transactions, SHOW_LONG},
8665 {"Slave_running", (char*) &show_slave_running, SHOW_SIMPLE_FUNC},
8666 {"Slave_skipped_errors", (char*) &slave_skipped_errors, SHOW_LONGLONG},
8667#endif
8668 {"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONG},
8669 {"Slow_queries", (char*) offsetof(STATUS_VAR, long_query_count), SHOW_LONG_STATUS},
8670 {"Sort_merge_passes", (char*) offsetof(STATUS_VAR, filesort_merge_passes_), SHOW_LONG_STATUS},
8671 {"Sort_priority_queue_sorts",(char*) offsetof(STATUS_VAR, filesort_pq_sorts_), SHOW_LONG_STATUS},
8672 {"Sort_range", (char*) offsetof(STATUS_VAR, filesort_range_count_), SHOW_LONG_STATUS},
8673 {"Sort_rows", (char*) offsetof(STATUS_VAR, filesort_rows_), SHOW_LONG_STATUS},
8674 {"Sort_scan", (char*) offsetof(STATUS_VAR, filesort_scan_count_), SHOW_LONG_STATUS},
8675#ifdef HAVE_OPENSSL
8676#ifndef EMBEDDED_LIBRARY
8677 {"Ssl_accept_renegotiates", (char*) &show_ssl_ctx_sess_accept_renegotiate, SHOW_SIMPLE_FUNC},
8678 {"Ssl_accepts", (char*) &show_ssl_ctx_sess_accept, SHOW_SIMPLE_FUNC},
8679 {"Ssl_callback_cache_hits", (char*) &show_ssl_ctx_sess_cb_hits, SHOW_SIMPLE_FUNC},
8680 {"Ssl_cipher", (char*) &show_ssl_get_cipher, SHOW_SIMPLE_FUNC},
8681 {"Ssl_cipher_list", (char*) &show_ssl_get_cipher_list, SHOW_SIMPLE_FUNC},
8682 {"Ssl_client_connects", (char*) &show_ssl_ctx_sess_connect, SHOW_SIMPLE_FUNC},
8683 {"Ssl_connect_renegotiates", (char*) &show_ssl_ctx_sess_connect_renegotiate, SHOW_SIMPLE_FUNC},
8684 {"Ssl_ctx_verify_depth", (char*) &show_ssl_ctx_get_verify_depth, SHOW_SIMPLE_FUNC},
8685 {"Ssl_ctx_verify_mode", (char*) &show_ssl_ctx_get_verify_mode, SHOW_SIMPLE_FUNC},
8686 {"Ssl_default_timeout", (char*) &show_ssl_get_default_timeout, SHOW_SIMPLE_FUNC},
8687 {"Ssl_finished_accepts", (char*) &show_ssl_ctx_sess_accept_good, SHOW_SIMPLE_FUNC},
8688 {"Ssl_finished_connects", (char*) &show_ssl_ctx_sess_connect_good, SHOW_SIMPLE_FUNC},
8689 {"Ssl_server_not_after", (char*) &show_ssl_get_server_not_after, SHOW_SIMPLE_FUNC},
8690 {"Ssl_server_not_before", (char*) &show_ssl_get_server_not_before, SHOW_SIMPLE_FUNC},
8691 {"Ssl_session_cache_hits", (char*) &show_ssl_ctx_sess_hits, SHOW_SIMPLE_FUNC},
8692 {"Ssl_session_cache_misses", (char*) &show_ssl_ctx_sess_misses, SHOW_SIMPLE_FUNC},
8693 {"Ssl_session_cache_mode", (char*) &show_ssl_ctx_get_session_cache_mode, SHOW_SIMPLE_FUNC},
8694 {"Ssl_session_cache_overflows", (char*) &show_ssl_ctx_sess_cache_full, SHOW_SIMPLE_FUNC},
8695 {"Ssl_session_cache_size", (char*) &show_ssl_ctx_sess_get_cache_size, SHOW_SIMPLE_FUNC},
8696 {"Ssl_session_cache_timeouts", (char*) &show_ssl_ctx_sess_timeouts, SHOW_SIMPLE_FUNC},
8697 {"Ssl_sessions_reused", (char*) &show_ssl_session_reused, SHOW_SIMPLE_FUNC},
8698 {"Ssl_used_session_cache_entries",(char*) &show_ssl_ctx_sess_number, SHOW_SIMPLE_FUNC},
8699 {"Ssl_verify_depth", (char*) &show_ssl_get_verify_depth, SHOW_SIMPLE_FUNC},
8700 {"Ssl_verify_mode", (char*) &show_ssl_get_verify_mode, SHOW_SIMPLE_FUNC},
8701 {"Ssl_version", (char*) &show_ssl_get_version, SHOW_SIMPLE_FUNC},
8702#endif
8703#endif /* HAVE_OPENSSL */
8704 {"Syncs", (char*) &my_sync_count, SHOW_LONG_NOFLUSH},
8705 /*
8706 Expression cache used only for caching subqueries now, so its statistic
8707 variables we call subquery_cache*.
8708 */
8709 {"Subquery_cache_hit", (char*) &subquery_cache_hit, SHOW_LONG},
8710 {"Subquery_cache_miss", (char*) &subquery_cache_miss, SHOW_LONG},
8711 {"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG},
8712 {"Table_locks_waited", (char*) &locks_waited, SHOW_LONG},
8713 {"Table_open_cache_active_instances", (char*) &tc_active_instances, SHOW_UINT},
8714 {"Table_open_cache_hits", (char*) offsetof(STATUS_VAR, table_open_cache_hits), SHOW_LONGLONG_STATUS},
8715 {"Table_open_cache_misses", (char*) offsetof(STATUS_VAR, table_open_cache_misses), SHOW_LONGLONG_STATUS},
8716 {"Table_open_cache_overflows", (char*) offsetof(STATUS_VAR, table_open_cache_overflows), SHOW_LONGLONG_STATUS},
8717#ifdef HAVE_MMAP
8718 {"Tc_log_max_pages_used", (char*) &tc_log_max_pages_used, SHOW_LONG},
8719 {"Tc_log_page_size", (char*) &tc_log_page_size, SHOW_LONG_NOFLUSH},
8720 {"Tc_log_page_waits", (char*) &tc_log_page_waits, SHOW_LONG},
8721#endif
8722#ifdef HAVE_POOL_OF_THREADS
8723 {"Threadpool_idle_threads", (char *) &show_threadpool_idle_threads, SHOW_SIMPLE_FUNC},
8724 {"Threadpool_threads", (char *) &tp_stats.num_worker_threads, SHOW_INT},
8725#endif
8726 {"Threads_cached", (char*) &cached_thread_count, SHOW_LONG_NOFLUSH},
8727 {"Threads_connected", (char*) &connection_count, SHOW_INT},
8728 {"Threads_created", (char*) &thread_created, SHOW_LONG_NOFLUSH},
8729 {"Threads_running", (char*) offsetof(STATUS_VAR, threads_running), SHOW_UINT32_STATUS},
8730 {"Transactions_multi_engine", (char*) &transactions_multi_engine, SHOW_LONG},
8731 {"Rpl_transactions_multi_engine", (char*) &rpl_transactions_multi_engine, SHOW_LONG},
8732 {"Transactions_gtid_foreign_engine", (char*) &transactions_gtid_foreign_engine, SHOW_LONG},
8733 {"Update_scan", (char*) offsetof(STATUS_VAR, update_scan_count), SHOW_LONG_STATUS},
8734 {"Uptime", (char*) &show_starttime, SHOW_SIMPLE_FUNC},
8735#ifdef ENABLED_PROFILING
8736 {"Uptime_since_flush_status",(char*) &show_flushstatustime, SHOW_SIMPLE_FUNC},
8737#endif
8738#ifdef WITH_WSREP
8739 {"wsrep", (char*) &wsrep_show_status, SHOW_FUNC},
8740#endif
8741 {NullS, NullS, SHOW_LONG}
8742};
8743
8744static bool add_terminator(DYNAMIC_ARRAY *options)
8745{
8746 my_option empty_element= {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0};
8747 return insert_dynamic(options, (uchar *)&empty_element);
8748}
8749
8750static bool add_many_options(DYNAMIC_ARRAY *options, my_option *list,
8751 size_t elements)
8752{
8753 for (my_option *opt= list; opt < list + elements; opt++)
8754 if (insert_dynamic(options, opt))
8755 return 1;
8756 return 0;
8757}
8758
8759#ifndef EMBEDDED_LIBRARY
8760static void print_version(void)
8761{
8762 if (IS_SYSVAR_AUTOSIZE(&server_version_ptr))
8763 set_server_version(server_version, sizeof(server_version));
8764
8765 printf("%s Ver %s for %s on %s (%s)\n",my_progname,
8766 server_version,SYSTEM_TYPE,MACHINE_TYPE, MYSQL_COMPILATION_COMMENT);
8767}
8768
8769/** Compares two options' names, treats - and _ the same */
8770static int option_cmp(my_option *a, my_option *b)
8771{
8772 const char *sa= a->name;
8773 const char *sb= b->name;
8774 for (; *sa || *sb; sa++, sb++)
8775 {
8776 if (*sa < *sb)
8777 {
8778 if (*sa == '-' && *sb == '_')
8779 continue;
8780 else
8781 return -1;
8782 }
8783 if (*sa > *sb)
8784 {
8785 if (*sa == '_' && *sb == '-')
8786 continue;
8787 else
8788 return 1;
8789 }
8790 }
8791 return 0;
8792}
8793
8794static void print_help()
8795{
8796 MEM_ROOT mem_root;
8797 init_alloc_root(&mem_root, "help", 4096, 4096, MYF(0));
8798
8799 pop_dynamic(&all_options);
8800 add_many_options(&all_options, pfs_early_options,
8801 array_elements(pfs_early_options));
8802 sys_var_add_options(&all_options, sys_var::PARSE_EARLY);
8803 add_plugin_options(&all_options, &mem_root);
8804 sort_dynamic(&all_options, (qsort_cmp) option_cmp);
8805 sort_dynamic(&all_options, (qsort_cmp) option_cmp);
8806 add_terminator(&all_options);
8807
8808 my_print_help((my_option*) all_options.buffer);
8809
8810 /* Add variables that must be shown but not changed, like version numbers */
8811 pop_dynamic(&all_options);
8812 sys_var_add_options(&all_options, sys_var::GETOPT_ONLY_HELP);
8813 sort_dynamic(&all_options, (qsort_cmp) option_cmp);
8814 add_terminator(&all_options);
8815 my_print_variables((my_option*) all_options.buffer);
8816
8817 free_root(&mem_root, MYF(0));
8818}
8819
8820static void usage(void)
8821{
8822 DBUG_ENTER("usage");
8823 if (!(default_charset_info= get_charset_by_csname(default_character_set_name,
8824 MY_CS_PRIMARY,
8825 MYF(MY_WME))))
8826 exit(1);
8827 if (!default_collation_name)
8828 default_collation_name= (char*) default_charset_info->name;
8829 print_version();
8830 puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000"));
8831 puts("Starts the MariaDB database server.\n");
8832 printf("Usage: %s [OPTIONS]\n", my_progname);
8833 if (!opt_verbose)
8834 puts("\nFor more help options (several pages), use mysqld --verbose --help.");
8835 else
8836 {
8837#ifdef __WIN__
8838 puts("NT and Win32 specific options:\n"
8839 " --install Install the default service (NT).\n"
8840 " --install-manual Install the default service started manually (NT).\n"
8841 " --install service_name Install an optional service (NT).\n"
8842 " --install-manual service_name Install an optional service started manually (NT).\n"
8843 " --remove Remove the default service from the service list (NT).\n"
8844 " --remove service_name Remove the service_name from the service list (NT).\n"
8845 " --enable-named-pipe Only to be used for the default server (NT).\n"
8846 " --standalone Dummy option to start as a standalone server (NT).");
8847 puts("");
8848#endif
8849 print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
8850 puts("");
8851 set_ports();
8852
8853 /* Print out all the options including plugin supplied options */
8854 print_help();
8855
8856 if (! plugins_are_initialized)
8857 {
8858 puts("\nPlugins have parameters that are not reflected in this list"
8859 "\nbecause execution stopped before plugins were initialized.");
8860 }
8861
8862 puts("\nTo see what values a running MySQL server is using, type"
8863 "\n'mysqladmin variables' instead of 'mysqld --verbose --help'.");
8864 }
8865 DBUG_VOID_RETURN;
8866}
8867#endif /*!EMBEDDED_LIBRARY*/
8868
8869/**
8870 Initialize MySQL global variables to default values.
8871
8872 @note
8873 The reason to set a lot of global variables to zero is to allow one to
8874 restart the embedded server with a clean environment
8875 It's also needed on some exotic platforms where global variables are
8876 not set to 0 when a program starts.
8877
8878 We don't need to set variables refered to in my_long_options
8879 as these are initialized by my_getopt.
8880*/
8881
8882static int mysql_init_variables(void)
8883{
8884 /* Things reset to zero */
8885 opt_skip_slave_start= opt_reckless_slave = 0;
8886 mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0;
8887#if defined(HAVE_REALPATH) && !defined(HAVE_valgrind) && !defined(HAVE_BROKEN_REALPATH)
8888 /* We can only test for sub paths if my_symlink.c is using realpath */
8889 mysys_test_invalid_symlink= path_starts_from_data_home_dir;
8890#endif
8891 opt_log= 0;
8892 opt_bin_log= opt_bin_log_used= 0;
8893 opt_disable_networking= opt_skip_show_db=0;
8894 opt_skip_name_resolve= 0;
8895 opt_ignore_builtin_innodb= 0;
8896 opt_logname= opt_binlog_index_name= opt_slow_logname= 0;
8897 opt_log_basename= 0;
8898 opt_tc_log_file= (char *)"tc.log"; // no hostname in tc_log file name !
8899 opt_secure_auth= 0;
8900 opt_bootstrap= opt_myisam_log= 0;
8901 disable_log_notes= 0;
8902 mqh_used= 0;
8903 kill_in_progress= 0;
8904 cleanup_done= 0;
8905 test_flags= select_errors= dropping_tables= ha_open_options=0;
8906 thread_count= kill_cached_threads= wake_thread= 0;
8907 service_thread_count= 0;
8908 slave_open_temp_tables= 0;
8909 cached_thread_count= 0;
8910 opt_endinfo= using_udf_functions= 0;
8911 opt_using_transactions= 0;
8912 abort_loop= select_thread_in_use= signal_thread_in_use= 0;
8913 ready_to_exit= shutdown_in_progress= grant_option= 0;
8914 aborted_threads= aborted_connects= 0;
8915 subquery_cache_miss= subquery_cache_hit= 0;
8916 delayed_insert_threads= delayed_insert_writes= delayed_rows_in_use= 0;
8917 delayed_insert_errors= thread_created= 0;
8918 specialflag= 0;
8919 binlog_cache_use= binlog_cache_disk_use= 0;
8920 max_used_connections= slow_launch_threads = 0;
8921 mysqld_user= mysqld_chroot= opt_init_file= opt_bin_logname = 0;
8922 prepared_stmt_count= 0;
8923 mysqld_unix_port= opt_mysql_tmpdir= my_bind_addr_str= NullS;
8924 bzero((uchar*) &mysql_tmpdir_list, sizeof(mysql_tmpdir_list));
8925 /* Clear all except global_memory_used */
8926 bzero((char*) &global_status_var, offsetof(STATUS_VAR,
8927 last_cleared_system_status_var));
8928 opt_large_pages= 0;
8929 opt_super_large_pages= 0;
8930#if defined(ENABLED_DEBUG_SYNC)
8931 opt_debug_sync_timeout= 0;
8932#endif /* defined(ENABLED_DEBUG_SYNC) */
8933 key_map_full.set_all();
8934
8935 /* Character sets */
8936 system_charset_info= &my_charset_utf8_general_ci;
8937 files_charset_info= &my_charset_utf8_general_ci;
8938 national_charset_info= &my_charset_utf8_general_ci;
8939 table_alias_charset= &my_charset_bin;
8940 character_set_filesystem= &my_charset_bin;
8941
8942 opt_specialflag= SPECIAL_ENGLISH;
8943 unix_sock= base_ip_sock= extra_ip_sock= MYSQL_INVALID_SOCKET;
8944 mysql_home_ptr= mysql_home;
8945 log_error_file_ptr= log_error_file;
8946 protocol_version= PROTOCOL_VERSION;
8947 what_to_log= ~(1UL << COM_TIME);
8948 denied_connections= 0;
8949 executed_events= 0;
8950 global_query_id= 1;
8951 global_thread_id= 0;
8952 strnmov(server_version, MYSQL_SERVER_VERSION, sizeof(server_version)-1);
8953 threads.empty();
8954 thread_cache.empty();
8955 key_caches.empty();
8956 if (!(dflt_key_cache= get_or_create_key_cache(default_key_cache_base.str,
8957 default_key_cache_base.length)))
8958 {
8959 sql_print_error("Cannot allocate the keycache");
8960 return 1;
8961 }
8962
8963 /* set key_cache_hash.default_value = dflt_key_cache */
8964 multi_keycache_init();
8965
8966 /* Set directory paths */
8967 mysql_real_data_home_len=
8968 (uint)(strmake_buf(mysql_real_data_home,
8969 get_relative_path(MYSQL_DATADIR)) - mysql_real_data_home);
8970 /* Replication parameters */
8971 master_info_file= (char*) "master.info",
8972 relay_log_info_file= (char*) "relay-log.info";
8973 report_user= report_password = report_host= 0; /* TO BE DELETED */
8974 opt_relay_logname= opt_relaylog_index_name= 0;
8975 slave_retried_transactions= 0;
8976 transactions_multi_engine= 0;
8977 rpl_transactions_multi_engine= 0;
8978 transactions_gtid_foreign_engine= 0;
8979 log_bin_basename= NULL;
8980 log_bin_index= NULL;
8981
8982 /* Variables in libraries */
8983 charsets_dir= 0;
8984 default_character_set_name= (char*) MYSQL_DEFAULT_CHARSET_NAME;
8985 default_collation_name= compiled_default_collation_name;
8986 character_set_filesystem_name= (char*) "binary";
8987 lc_messages= (char*) "en_US";
8988 lc_time_names_name= (char*) "en_US";
8989
8990 /* Variables that depends on compile options */
8991#ifndef DBUG_OFF
8992 default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace",
8993 "d:t:i:o,/tmp/mysqld.trace");
8994 current_dbug_option= default_dbug_option;
8995#endif
8996 opt_error_log= IF_WIN(1,0);
8997#ifdef ENABLED_PROFILING
8998 have_profiling = SHOW_OPTION_YES;
8999#else
9000 have_profiling = SHOW_OPTION_NO;
9001#endif
9002
9003#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
9004 have_ssl=SHOW_OPTION_YES;
9005#if defined(HAVE_YASSL)
9006 have_openssl= SHOW_OPTION_NO;
9007#else
9008 have_openssl= SHOW_OPTION_YES;
9009#endif
9010#else
9011 have_openssl= have_ssl= SHOW_OPTION_NO;
9012#endif
9013#ifdef HAVE_BROKEN_REALPATH
9014 have_symlink=SHOW_OPTION_NO;
9015#else
9016 have_symlink=SHOW_OPTION_YES;
9017#endif
9018#ifdef HAVE_DLOPEN
9019 have_dlopen=SHOW_OPTION_YES;
9020#else
9021 have_dlopen=SHOW_OPTION_NO;
9022#endif
9023#ifdef HAVE_QUERY_CACHE
9024 have_query_cache=SHOW_OPTION_YES;
9025#else
9026 have_query_cache=SHOW_OPTION_NO;
9027#endif
9028#ifdef HAVE_SPATIAL
9029 have_geometry=SHOW_OPTION_YES;
9030#else
9031 have_geometry=SHOW_OPTION_NO;
9032#endif
9033#ifdef HAVE_RTREE_KEYS
9034 have_rtree_keys=SHOW_OPTION_YES;
9035#else
9036 have_rtree_keys=SHOW_OPTION_NO;
9037#endif
9038#ifdef HAVE_CRYPT
9039 have_crypt=SHOW_OPTION_YES;
9040#else
9041 have_crypt=SHOW_OPTION_NO;
9042#endif
9043#ifdef HAVE_COMPRESS
9044 have_compress= SHOW_OPTION_YES;
9045#else
9046 have_compress= SHOW_OPTION_NO;
9047#endif
9048#ifdef HAVE_LIBWRAP
9049 libwrapName= NullS;
9050#endif
9051#ifdef HAVE_OPENSSL
9052 des_key_file = 0;
9053#ifndef EMBEDDED_LIBRARY
9054 ssl_acceptor_fd= 0;
9055#endif /* ! EMBEDDED_LIBRARY */
9056#endif /* HAVE_OPENSSL */
9057#ifdef HAVE_SMEM
9058 shared_memory_base_name= default_shared_memory_base_name;
9059#endif
9060
9061#if defined(__WIN__)
9062 /* Allow Win32 users to move MySQL anywhere */
9063 {
9064 char prg_dev[LIBLEN];
9065 char executing_path_name[LIBLEN];
9066 if (!test_if_hard_path(my_progname))
9067 {
9068 // we don't want to use GetModuleFileName inside of my_path since
9069 // my_path is a generic path dereferencing function and here we care
9070 // only about the executing binary.
9071 GetModuleFileName(NULL, executing_path_name, sizeof(executing_path_name));
9072 my_path(prg_dev, executing_path_name, NULL);
9073 }
9074 else
9075 my_path(prg_dev, my_progname, "mysql/bin");
9076 strcat(prg_dev,"/../"); // Remove 'bin' to get base dir
9077 cleanup_dirname(mysql_home,prg_dev);
9078 }
9079#else
9080 const char *tmpenv;
9081 if (!(tmpenv = getenv("MY_BASEDIR_VERSION")))
9082 tmpenv = DEFAULT_MYSQL_HOME;
9083 strmake_buf(mysql_home, tmpenv);
9084 set_sys_var_value_origin(&mysql_home_ptr, sys_var::ENV);
9085#endif
9086
9087 if (wsrep_init_vars())
9088 return 1;
9089
9090 return 0;
9091}
9092
9093my_bool
9094mysqld_get_one_option(int optid, const struct my_option *opt, char *argument)
9095{
9096 if (opt->app_type)
9097 {
9098 sys_var *var= (sys_var*) opt->app_type;
9099 if (argument == autoset_my_option)
9100 {
9101 var->value_origin= sys_var::AUTO;
9102 return 0;
9103 }
9104 var->value_origin= sys_var::CONFIG;
9105 }
9106
9107 switch(optid) {
9108 case '#':
9109#ifndef DBUG_OFF
9110 if (!argument)
9111 argument= (char*) default_dbug_option;
9112 if (argument[0] == '0' && !argument[1])
9113 {
9114 DEBUGGER_OFF;
9115 break;
9116 }
9117 DEBUGGER_ON;
9118 if (argument[0] == '1' && !argument[1])
9119 break;
9120 DBUG_SET_INITIAL(argument);
9121 current_dbug_option= argument;
9122 opt_endinfo=1; /* unireg: memory allocation */
9123#else
9124 sql_print_warning("'%s' is disabled in this build", opt->name);
9125#endif
9126 break;
9127 case OPT_DEPRECATED_OPTION:
9128 sql_print_warning("'%s' is deprecated. It does nothing and exists only "
9129 "for compatibility with old my.cnf files.",
9130 opt->name);
9131 break;
9132 case OPT_MYSQL_COMPATIBILITY:
9133 sql_print_warning("'%s' is MySQL 5.6 / 5.7 compatible option. Not used or "
9134 "needed in MariaDB.", opt->name);
9135 break;
9136 case OPT_MYSQL_TO_BE_IMPLEMENTED:
9137 sql_print_warning("'%s' is MySQL 5.6 / 5.7 compatible option. To be "
9138 "implemented in later versions.", opt->name);
9139 break;
9140 case 'a':
9141 SYSVAR_AUTOSIZE(global_system_variables.sql_mode, MODE_ANSI);
9142 SYSVAR_AUTOSIZE(global_system_variables.tx_isolation, ISO_SERIALIZABLE);
9143 break;
9144 case 'b':
9145 strmake_buf(mysql_home, argument);
9146 break;
9147 case 'C':
9148 if (default_collation_name == compiled_default_collation_name)
9149 default_collation_name= 0;
9150 break;
9151 case 'h':
9152 strmake_buf(mysql_real_data_home, argument);
9153 /* Correct pointer set by my_getopt (for embedded library) */
9154 mysql_real_data_home_ptr= mysql_real_data_home;
9155 break;
9156 case 'u':
9157 if (!mysqld_user || !strcmp(mysqld_user, argument))
9158 mysqld_user= argument;
9159 else
9160 sql_print_warning("Ignoring user change to '%s' because the user was set to '%s' earlier on the command line\n", argument, mysqld_user);
9161 break;
9162 case 'L':
9163 strmake_buf(lc_messages_dir, argument);
9164 break;
9165 case OPT_BINLOG_FORMAT:
9166 binlog_format_used= true;
9167 break;
9168#include <sslopt-case.h>
9169 case 'V':
9170 if (argument)
9171 {
9172 strmake(server_version, argument, sizeof(server_version) - 1);
9173 set_sys_var_value_origin(&server_version_ptr, sys_var::CONFIG);
9174 using_custom_server_version= true;
9175 }
9176#ifndef EMBEDDED_LIBRARY
9177 else
9178 {
9179 print_version();
9180 opt_abort= 1; // Abort after parsing all options
9181 }
9182#endif /*EMBEDDED_LIBRARY*/
9183 break;
9184 case 'W':
9185 if (!argument)
9186 global_system_variables.log_warnings++;
9187 else if (argument == disabled_my_option)
9188 global_system_variables.log_warnings= 0L;
9189 else
9190 global_system_variables.log_warnings= atoi(argument);
9191 break;
9192 case 'T':
9193 test_flags= argument ? (uint) atoi(argument) : 0;
9194 opt_endinfo=1;
9195 break;
9196 case OPT_THREAD_CONCURRENCY:
9197 WARN_DEPRECATED_NO_REPLACEMENT(NULL, "THREAD_CONCURRENCY");
9198 break;
9199 case (int) OPT_ISAM_LOG:
9200 opt_myisam_log=1;
9201 break;
9202 case (int) OPT_BIN_LOG:
9203 opt_bin_log= MY_TEST(argument != disabled_my_option);
9204 opt_bin_log_used= 1;
9205 break;
9206 case (int) OPT_LOG_BASENAME:
9207 {
9208 if (opt_log_basename[0] == 0 || strchr(opt_log_basename, FN_EXTCHAR) ||
9209 strchr(opt_log_basename,FN_LIBCHAR) ||
9210 !is_filename_allowed(opt_log_basename, strlen(opt_log_basename), FALSE))
9211 {
9212 sql_print_error("Wrong argument for --log-basename. It can't be empty or contain '.' or '" FN_DIRSEP "'. It must be valid filename.");
9213 return 1;
9214 }
9215 if (log_error_file_ptr != disabled_my_option)
9216 SYSVAR_AUTOSIZE(log_error_file_ptr, opt_log_basename);
9217
9218 /* General log file */
9219 make_default_log_name(&opt_logname, ".log", false);
9220 /* Slow query log file */
9221 make_default_log_name(&opt_slow_logname, "-slow.log", false);
9222 /* Binary log file */
9223 make_default_log_name(&opt_bin_logname, "-bin", true);
9224 /* Binary log index file */
9225 make_default_log_name(&opt_binlog_index_name, "-bin.index", true);
9226 set_sys_var_value_origin(&opt_logname, sys_var::AUTO);
9227 set_sys_var_value_origin(&opt_slow_logname, sys_var::AUTO);
9228 if (!opt_logname || !opt_slow_logname || !opt_bin_logname ||
9229 !opt_binlog_index_name)
9230 return 1;
9231
9232#ifdef HAVE_REPLICATION
9233 /* Relay log file */
9234 make_default_log_name(&opt_relay_logname, "-relay-bin", true);
9235 /* Relay log index file */
9236 make_default_log_name(&opt_relaylog_index_name, "-relay-bin.index", true);
9237 set_sys_var_value_origin(&opt_relay_logname, sys_var::AUTO);
9238 if (!opt_relay_logname || !opt_relaylog_index_name)
9239 return 1;
9240#endif
9241
9242 SYSVAR_AUTOSIZE(pidfile_name_ptr, pidfile_name);
9243 /* PID file */
9244 strmake(pidfile_name, argument, sizeof(pidfile_name)-5);
9245 strmov(fn_ext(pidfile_name),".pid");
9246
9247 /* check for errors */
9248 if (!pidfile_name_ptr)
9249 return 1; // out of memory error
9250 break;
9251 }
9252#ifdef HAVE_REPLICATION
9253 case (int)OPT_REPLICATE_IGNORE_DB:
9254 {
9255 cur_rpl_filter->add_ignore_db(argument);
9256 break;
9257 }
9258 case (int)OPT_REPLICATE_DO_DB:
9259 {
9260 cur_rpl_filter->add_do_db(argument);
9261 break;
9262 }
9263 case (int)OPT_REPLICATE_REWRITE_DB:
9264 {
9265 /* See also OPT_REWRITE_DB handling in client/mysqlbinlog.cc */
9266 char* key = argument,*p, *val;
9267
9268 if (!(p= strstr(argument, "->")))
9269 {
9270 sql_print_error("Bad syntax in replicate-rewrite-db - missing '->'!\n");
9271 return 1;
9272 }
9273 val= p--;
9274 while (my_isspace(mysqld_charset, *p) && p > argument)
9275 *p-- = 0;
9276 if (p == argument)
9277 {
9278 sql_print_error("Bad syntax in replicate-rewrite-db - empty FROM db!\n");
9279 return 1;
9280 }
9281 *val= 0;
9282 val+= 2;
9283 while (*val && my_isspace(mysqld_charset, *val))
9284 val++;
9285 if (!*val)
9286 {
9287 sql_print_error("Bad syntax in replicate-rewrite-db - empty TO db!\n");
9288 return 1;
9289 }
9290
9291 cur_rpl_filter->add_db_rewrite(key, val);
9292 break;
9293 }
9294 case (int)OPT_SLAVE_PARALLEL_MODE:
9295 {
9296 /* Store latest mode for Master::Info */
9297 cur_rpl_filter->set_parallel_mode
9298 ((enum_slave_parallel_mode)opt_slave_parallel_mode);
9299 break;
9300 }
9301
9302 case (int)OPT_BINLOG_IGNORE_DB:
9303 {
9304 binlog_filter->add_ignore_db(argument);
9305 break;
9306 }
9307 case (int)OPT_BINLOG_DO_DB:
9308 {
9309 binlog_filter->add_do_db(argument);
9310 break;
9311 }
9312 case (int)OPT_REPLICATE_DO_TABLE:
9313 {
9314 if (cur_rpl_filter->add_do_table(argument))
9315 {
9316 sql_print_error("Could not add do table rule '%s'!\n", argument);
9317 return 1;
9318 }
9319 break;
9320 }
9321 case (int)OPT_REPLICATE_WILD_DO_TABLE:
9322 {
9323 if (cur_rpl_filter->add_wild_do_table(argument))
9324 {
9325 sql_print_error("Could not add do table rule '%s'!\n", argument);
9326 return 1;
9327 }
9328 break;
9329 }
9330 case (int)OPT_REPLICATE_WILD_IGNORE_TABLE:
9331 {
9332 if (cur_rpl_filter->add_wild_ignore_table(argument))
9333 {
9334 sql_print_error("Could not add ignore table rule '%s'!\n", argument);
9335 return 1;
9336 }
9337 break;
9338 }
9339 case (int)OPT_REPLICATE_IGNORE_TABLE:
9340 {
9341 if (cur_rpl_filter->add_ignore_table(argument))
9342 {
9343 sql_print_error("Could not add ignore table rule '%s'!\n", argument);
9344 return 1;
9345 }
9346 break;
9347 }
9348#endif /* HAVE_REPLICATION */
9349 case (int) OPT_SAFE:
9350 opt_specialflag|= SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC;
9351 SYSVAR_AUTOSIZE(delay_key_write_options, (uint) DELAY_KEY_WRITE_NONE);
9352 SYSVAR_AUTOSIZE(myisam_recover_options, HA_RECOVER_DEFAULT);
9353 ha_open_options&= ~(HA_OPEN_DELAY_KEY_WRITE);
9354#ifdef HAVE_QUERY_CACHE
9355 SYSVAR_AUTOSIZE(query_cache_size, 0);
9356#endif
9357 sql_print_warning("The syntax '--safe-mode' is deprecated and will be "
9358 "removed in a future release.");
9359 break;
9360 case (int) OPT_SKIP_HOST_CACHE:
9361 opt_specialflag|= SPECIAL_NO_HOST_CACHE;
9362 break;
9363 case (int) OPT_SKIP_RESOLVE:
9364 opt_skip_name_resolve= 1;
9365 opt_specialflag|=SPECIAL_NO_RESOLVE;
9366 break;
9367 case (int) OPT_WANT_CORE:
9368 test_flags |= TEST_CORE_ON_SIGNAL;
9369 break;
9370 case OPT_CONSOLE:
9371 if (opt_console)
9372 opt_error_log= 0; // Force logs to stdout
9373 break;
9374 case OPT_BOOTSTRAP:
9375 opt_noacl=opt_bootstrap=1;
9376 break;
9377 case OPT_SERVER_ID:
9378 ::server_id= global_system_variables.server_id;
9379 break;
9380 case OPT_LOWER_CASE_TABLE_NAMES:
9381 lower_case_table_names_used= 1;
9382 break;
9383#if defined(ENABLED_DEBUG_SYNC)
9384 case OPT_DEBUG_SYNC_TIMEOUT:
9385 /*
9386 Debug Sync Facility. See debug_sync.cc.
9387 Default timeout for WAIT_FOR action.
9388 Default value is zero (facility disabled).
9389 If option is given without an argument, supply a non-zero value.
9390 */
9391 if (!argument)
9392 {
9393 /* purecov: begin tested */
9394 opt_debug_sync_timeout= DEBUG_SYNC_DEFAULT_WAIT_TIMEOUT;
9395 /* purecov: end */
9396 }
9397 break;
9398#endif /* defined(ENABLED_DEBUG_SYNC) */
9399 case OPT_LOG_ERROR:
9400 /*
9401 "No --log-error" == "write errors to stderr",
9402 "--log-error without argument" == "write errors to a file".
9403 */
9404 if (argument == NULL) /* no argument */
9405 log_error_file_ptr= const_cast<char*>("");
9406 break;
9407 case OPT_IGNORE_DB_DIRECTORY:
9408 opt_ignore_db_dirs= NULL; // will be set in ignore_db_dirs_process_additions
9409 if (*argument == 0)
9410 ignore_db_dirs_reset();
9411 else
9412 {
9413 if (push_ignored_db_dir(argument))
9414 {
9415 sql_print_error("Can't start server: "
9416 "cannot process --ignore-db-dir=%.*s",
9417 FN_REFLEN, argument);
9418 return 1;
9419 }
9420 }
9421 break;
9422 case OPT_PLUGIN_LOAD:
9423 free_list(opt_plugin_load_list_ptr);
9424 /* fall through */
9425 case OPT_PLUGIN_LOAD_ADD:
9426 opt_plugin_load_list_ptr->push_back(new i_string(argument));
9427 break;
9428 case OPT_MAX_LONG_DATA_SIZE:
9429 max_long_data_size_used= true;
9430 break;
9431 case OPT_PFS_INSTRUMENT:
9432 {
9433#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
9434#ifndef EMBEDDED_LIBRARY
9435 /* Parse instrument name and value from argument string */
9436 char* name = argument,*p, *val;
9437
9438 /* Assignment required */
9439 if (!(p= strchr(argument, '=')))
9440 {
9441 my_getopt_error_reporter(WARNING_LEVEL,
9442 "Missing value for performance_schema_instrument "
9443 "'%s'", argument);
9444 return 0;
9445 }
9446
9447 /* Option value */
9448 val= p + 1;
9449 if (!*val)
9450 {
9451 my_getopt_error_reporter(WARNING_LEVEL,
9452 "Missing value for performance_schema_instrument "
9453 "'%s'", argument);
9454 return 0;
9455 }
9456
9457 /* Trim leading spaces from instrument name */
9458 while (*name && my_isspace(mysqld_charset, *name))
9459 name++;
9460
9461 /* Trim trailing spaces and slashes from instrument name */
9462 while (p > argument && (my_isspace(mysqld_charset, p[-1]) || p[-1] == '/'))
9463 p--;
9464 *p= 0;
9465
9466 if (!*name)
9467 {
9468 my_getopt_error_reporter(WARNING_LEVEL,
9469 "Invalid instrument name for "
9470 "performance_schema_instrument '%s'", argument);
9471 return 0;
9472 }
9473
9474 /* Trim leading spaces from option value */
9475 while (*val && my_isspace(mysqld_charset, *val))
9476 val++;
9477
9478 /* Trim trailing spaces from option value */
9479 if ((p= my_strchr(mysqld_charset, val, val+strlen(val), ' ')) != NULL)
9480 *p= 0;
9481
9482 if (!*val)
9483 {
9484 my_getopt_error_reporter(WARNING_LEVEL,
9485 "Invalid value for performance_schema_instrument "
9486 "'%s'", argument);
9487 return 0;
9488 }
9489
9490 /* Add instrument name and value to array of configuration options */
9491 if (add_pfs_instr_to_array(name, val))
9492 {
9493 my_getopt_error_reporter(WARNING_LEVEL,
9494 "Invalid value for performance_schema_instrument "
9495 "'%s'", argument);
9496 return 0;
9497 }
9498#endif /* EMBEDDED_LIBRARY */
9499#endif
9500 break;
9501 }
9502#ifdef WITH_WSREP
9503 case OPT_WSREP_CAUSAL_READS:
9504 {
9505 if (global_system_variables.wsrep_causal_reads)
9506 {
9507 WSREP_WARN("option --wsrep-causal-reads is deprecated");
9508 if (!(global_system_variables.wsrep_sync_wait & WSREP_SYNC_WAIT_BEFORE_READ))
9509 {
9510 WSREP_WARN("--wsrep-causal-reads=ON takes precedence over --wsrep-sync-wait=%u. "
9511 "WSREP_SYNC_WAIT_BEFORE_READ is on",
9512 global_system_variables.wsrep_sync_wait);
9513 global_system_variables.wsrep_sync_wait |= WSREP_SYNC_WAIT_BEFORE_READ;
9514 }
9515 }
9516 else
9517 {
9518 if (global_system_variables.wsrep_sync_wait & WSREP_SYNC_WAIT_BEFORE_READ) {
9519 WSREP_WARN("--wsrep-sync-wait=%u takes precedence over --wsrep-causal-reads=OFF. "
9520 "WSREP_SYNC_WAIT_BEFORE_READ is on",
9521 global_system_variables.wsrep_sync_wait);
9522 global_system_variables.wsrep_causal_reads = 1;
9523 }
9524 }
9525 break;
9526 }
9527 case OPT_WSREP_SYNC_WAIT:
9528 global_system_variables.wsrep_causal_reads=
9529 MY_TEST(global_system_variables.wsrep_sync_wait &
9530 WSREP_SYNC_WAIT_BEFORE_READ);
9531 break;
9532#endif /* WITH_WSREP */
9533 }
9534 return 0;
9535}
9536
9537
9538/** Handle arguments for multiple key caches. */
9539
9540C_MODE_START
9541
9542static void*
9543mysql_getopt_value(const char *name, uint length,
9544 const struct my_option *option, int *error)
9545{
9546 if (error)
9547 *error= 0;
9548 switch (option->id) {
9549 case OPT_KEY_BUFFER_SIZE:
9550 case OPT_KEY_CACHE_BLOCK_SIZE:
9551 case OPT_KEY_CACHE_DIVISION_LIMIT:
9552 case OPT_KEY_CACHE_AGE_THRESHOLD:
9553 case OPT_KEY_CACHE_PARTITIONS:
9554 case OPT_KEY_CACHE_CHANGED_BLOCKS_HASH_SIZE:
9555 {
9556 KEY_CACHE *key_cache;
9557 if (unlikely(!(key_cache= get_or_create_key_cache(name, length))))
9558 {
9559 if (error)
9560 *error= EXIT_OUT_OF_MEMORY;
9561 return 0;
9562 }
9563 switch (option->id) {
9564 case OPT_KEY_BUFFER_SIZE:
9565 return &key_cache->param_buff_size;
9566 case OPT_KEY_CACHE_BLOCK_SIZE:
9567 return &key_cache->param_block_size;
9568 case OPT_KEY_CACHE_DIVISION_LIMIT:
9569 return &key_cache->param_division_limit;
9570 case OPT_KEY_CACHE_AGE_THRESHOLD:
9571 return &key_cache->param_age_threshold;
9572 case OPT_KEY_CACHE_PARTITIONS:
9573 return (uchar**) &key_cache->param_partitions;
9574 case OPT_KEY_CACHE_CHANGED_BLOCKS_HASH_SIZE:
9575 return (uchar**) &key_cache->changed_blocks_hash_size;
9576 }
9577 }
9578 /* We return in all cases above. Let us silence -Wimplicit-fallthrough */
9579 DBUG_ASSERT(0);
9580#ifdef HAVE_REPLICATION
9581 /* fall through */
9582 case OPT_REPLICATE_DO_DB:
9583 case OPT_REPLICATE_DO_TABLE:
9584 case OPT_REPLICATE_IGNORE_DB:
9585 case OPT_REPLICATE_IGNORE_TABLE:
9586 case OPT_REPLICATE_WILD_DO_TABLE:
9587 case OPT_REPLICATE_WILD_IGNORE_TABLE:
9588 case OPT_REPLICATE_REWRITE_DB:
9589 case OPT_SLAVE_PARALLEL_MODE:
9590 {
9591 /* Store current filter for mysqld_get_one_option() */
9592 if (!(cur_rpl_filter= get_or_create_rpl_filter(name, length)))
9593 {
9594 if (error)
9595 *error= EXIT_OUT_OF_MEMORY;
9596 }
9597 if (option->id == OPT_SLAVE_PARALLEL_MODE)
9598 {
9599 /*
9600 Ensure parallel_mode variable is shown in --help. The other
9601 variables are not easily printable here.
9602 */
9603 return (char**) &opt_slave_parallel_mode;
9604 }
9605 return 0;
9606 }
9607#endif
9608 }
9609 return option->value;
9610}
9611
9612static void option_error_reporter(enum loglevel level, const char *format, ...)
9613{
9614 va_list args;
9615 va_start(args, format);
9616
9617 /* Don't print warnings for --loose options during bootstrap */
9618 if (level == ERROR_LEVEL || !opt_bootstrap ||
9619 global_system_variables.log_warnings)
9620 {
9621 vprint_msg_to_log(level, format, args);
9622 }
9623 va_end(args);
9624}
9625
9626C_MODE_END
9627
9628/**
9629 Get server options from the command line,
9630 and perform related server initializations.
9631 @param [in, out] argc_ptr command line options (count)
9632 @param [in, out] argv_ptr command line options (values)
9633 @return 0 on success
9634
9635 @todo
9636 - FIXME add EXIT_TOO_MANY_ARGUMENTS to "mysys_err.h" and return that code?
9637*/
9638static int get_options(int *argc_ptr, char ***argv_ptr)
9639{
9640 int ho_error;
9641
9642 my_getopt_register_get_addr(mysql_getopt_value);
9643 my_getopt_error_reporter= option_error_reporter;
9644
9645 /* prepare all_options array */
9646 my_init_dynamic_array(&all_options, sizeof(my_option),
9647 array_elements(my_long_options) +
9648 sys_var_elements(),
9649 array_elements(my_long_options)/4, MYF(0));
9650 add_many_options(&all_options, my_long_options, array_elements(my_long_options));
9651 sys_var_add_options(&all_options, 0);
9652 add_terminator(&all_options);
9653
9654 /* Skip unknown options so that they may be processed later by plugins */
9655 my_getopt_skip_unknown= TRUE;
9656
9657 if ((ho_error= handle_options(argc_ptr, argv_ptr, (my_option*)(all_options.buffer),
9658 mysqld_get_one_option)))
9659 return ho_error;
9660
9661 if (!opt_help)
9662 delete_dynamic(&all_options);
9663 else
9664 opt_abort= 1;
9665
9666 /* Add back the program name handle_options removes */
9667 (*argc_ptr)++;
9668 (*argv_ptr)--;
9669
9670 disable_log_notes= opt_silent_startup;
9671
9672 /*
9673 Options have been parsed. Now some of them need additional special
9674 handling, like custom value checking, checking of incompatibilites
9675 between options, setting of multiple variables, etc.
9676 Do them here.
9677 */
9678 if (global_system_variables.net_buffer_length >
9679 global_system_variables.max_allowed_packet)
9680 {
9681 sql_print_warning("net_buffer_length (%lu) is set to be larger "
9682 "than max_allowed_packet (%lu). Please rectify.",
9683 global_system_variables.net_buffer_length,
9684 global_system_variables.max_allowed_packet);
9685 }
9686
9687 if (log_error_file_ptr != disabled_my_option)
9688 opt_error_log= 1;
9689 else
9690 log_error_file_ptr= const_cast<char*>("");
9691
9692 opt_init_connect.length=strlen(opt_init_connect.str);
9693 opt_init_slave.length=strlen(opt_init_slave.str);
9694
9695 if (global_system_variables.low_priority_updates)
9696 thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY;
9697
9698 if (ft_boolean_check_syntax_string((uchar*) ft_boolean_syntax))
9699 {
9700 sql_print_error("Invalid ft-boolean-syntax string: %s\n",
9701 ft_boolean_syntax);
9702 return 1;
9703 }
9704
9705 if (opt_disable_networking)
9706 mysqld_port= mysqld_extra_port= 0;
9707
9708 if (opt_skip_show_db)
9709 opt_specialflag|= SPECIAL_SKIP_SHOW_DB;
9710
9711 if (myisam_flush)
9712 flush_time= 0;
9713
9714#ifdef HAVE_REPLICATION
9715 if (init_slave_skip_errors(opt_slave_skip_errors))
9716 return 1;
9717 if (init_slave_transaction_retry_errors(opt_slave_transaction_retry_errors))
9718 return 1;
9719#endif
9720
9721 if (global_system_variables.max_join_size == HA_POS_ERROR)
9722 global_system_variables.option_bits|= OPTION_BIG_SELECTS;
9723 else
9724 global_system_variables.option_bits&= ~OPTION_BIG_SELECTS;
9725
9726 if (opt_support_flashback)
9727 {
9728 /* Force binary logging */
9729 if (!opt_bin_logname)
9730 opt_bin_logname= (char*) ""; // Use default name
9731 opt_bin_log= opt_bin_log_used= 1;
9732
9733 /* Force format to row */
9734 binlog_format_used= 1;
9735 global_system_variables.binlog_format= BINLOG_FORMAT_ROW;
9736 }
9737
9738 if (!opt_bootstrap && WSREP_PROVIDER_EXISTS &&
9739 global_system_variables.binlog_format != BINLOG_FORMAT_ROW)
9740 {
9741
9742 WSREP_ERROR ("Only binlog_format = 'ROW' is currently supported. "
9743 "Configured value: '%s'. Please adjust your configuration.",
9744 binlog_format_names[global_system_variables.binlog_format]);
9745 return 1;
9746 }
9747
9748 // Synchronize @@global.autocommit on --autocommit
9749 const ulonglong turn_bit_on= opt_autocommit ?
9750 OPTION_AUTOCOMMIT : OPTION_NOT_AUTOCOMMIT;
9751 global_system_variables.option_bits=
9752 (global_system_variables.option_bits &
9753 ~(OPTION_NOT_AUTOCOMMIT | OPTION_AUTOCOMMIT)) | turn_bit_on;
9754
9755 global_system_variables.sql_mode=
9756 expand_sql_mode(global_system_variables.sql_mode);
9757#if !defined(HAVE_REALPATH) || defined(HAVE_BROKEN_REALPATH)
9758 my_use_symdir=0;
9759 my_disable_symlinks=1;
9760 have_symlink=SHOW_OPTION_NO;
9761#else
9762 if (!my_use_symdir)
9763 {
9764 my_disable_symlinks=1;
9765 have_symlink=SHOW_OPTION_DISABLED;
9766 }
9767#endif
9768 if (opt_debugging)
9769 {
9770 /* Allow break with SIGINT, no core or stack trace */
9771 test_flags|= TEST_SIGINT;
9772 opt_stack_trace= 1;
9773 test_flags&= ~TEST_CORE_ON_SIGNAL;
9774 }
9775 /* Set global MyISAM variables from delay_key_write_options */
9776 fix_delay_key_write(0, 0, OPT_GLOBAL);
9777
9778#ifndef EMBEDDED_LIBRARY
9779 if (mysqld_chroot)
9780 set_root(mysqld_chroot);
9781#else
9782 SYSVAR_AUTOSIZE(thread_handling, SCHEDULER_NO_THREADS);
9783 max_allowed_packet= global_system_variables.max_allowed_packet;
9784 net_buffer_length= global_system_variables.net_buffer_length;
9785#endif
9786 if (fix_paths())
9787 return 1;
9788
9789 /*
9790 Set some global variables from the global_system_variables
9791 In most cases the global variables will not be used
9792 */
9793 my_disable_locking= myisam_single_user= MY_TEST(opt_external_locking == 0);
9794 my_default_record_cache_size=global_system_variables.read_buff_size;
9795
9796 /*
9797 Log mysys errors when we don't have a thd or thd->log_all_errors is set
9798 (recovery) to the log. This is mainly useful for debugging strange system
9799 errors.
9800 */
9801 if (global_system_variables.log_warnings >= 10)
9802 my_global_flags= MY_WME | ME_JUST_INFO;
9803 /* Log all errors not handled by thd->handle_error() to my_message_sql() */
9804 if (global_system_variables.log_warnings >= 11)
9805 my_global_flags|= ME_NOREFRESH;
9806 if (my_assert_on_error)
9807 debug_assert_if_crashed_table= 1;
9808
9809 global_system_variables.long_query_time= (ulonglong)
9810 (global_system_variables.long_query_time_double * 1e6 + 0.1);
9811 global_system_variables.max_statement_time= (ulonglong)
9812 (global_system_variables.max_statement_time_double * 1e6 + 0.1);
9813
9814 if (opt_short_log_format)
9815 opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT;
9816
9817 if (init_global_datetime_format(MYSQL_TIMESTAMP_DATE,
9818 &global_date_format) ||
9819 init_global_datetime_format(MYSQL_TIMESTAMP_TIME,
9820 &global_time_format) ||
9821 init_global_datetime_format(MYSQL_TIMESTAMP_DATETIME,
9822 &global_datetime_format))
9823 return 1;
9824
9825#ifdef EMBEDDED_LIBRARY
9826 one_thread_scheduler(thread_scheduler);
9827 one_thread_scheduler(extra_thread_scheduler);
9828#else
9829
9830 if (thread_handling <= SCHEDULER_ONE_THREAD_PER_CONNECTION)
9831 one_thread_per_connection_scheduler(thread_scheduler, &max_connections,
9832 &connection_count);
9833 else if (thread_handling == SCHEDULER_NO_THREADS)
9834 one_thread_scheduler(thread_scheduler);
9835 else
9836 pool_of_threads_scheduler(thread_scheduler, &max_connections,
9837 &connection_count);
9838
9839 one_thread_per_connection_scheduler(extra_thread_scheduler,
9840 &extra_max_connections,
9841 &extra_connection_count);
9842#endif
9843
9844 opt_readonly= read_only;
9845
9846 /*
9847 If max_long_data_size is not specified explicitly use
9848 value of max_allowed_packet.
9849 */
9850 if (!max_long_data_size_used)
9851 SYSVAR_AUTOSIZE(max_long_data_size,
9852 global_system_variables.max_allowed_packet);
9853
9854 /* Remember if max_user_connections was 0 at startup */
9855 max_user_connections_checking= global_system_variables.max_user_connections != 0;
9856
9857#ifdef HAVE_REPLICATION
9858 {
9859 sys_var *max_relay_log_size_var, *max_binlog_size_var;
9860 /* If max_relay_log_size is 0, then set it to max_binlog_size */
9861 if (!global_system_variables.max_relay_log_size)
9862 SYSVAR_AUTOSIZE(global_system_variables.max_relay_log_size,
9863 max_binlog_size);
9864
9865 /*
9866 Fix so that DEFAULT and limit checking works with max_relay_log_size
9867 (Yes, this is a hack, but it's required as the definition of
9868 max_relay_log_size allows it to be set to 0).
9869 */
9870 max_relay_log_size_var= intern_find_sys_var(STRING_WITH_LEN("max_relay_log_size"));
9871 max_binlog_size_var= intern_find_sys_var(STRING_WITH_LEN("max_binlog_size"));
9872 if (max_binlog_size_var && max_relay_log_size_var)
9873 {
9874 max_relay_log_size_var->option.min_value=
9875 max_binlog_size_var->option.min_value;
9876 max_relay_log_size_var->option.def_value=
9877 max_binlog_size_var->option.def_value;
9878 }
9879 }
9880#endif
9881
9882 /* Ensure that some variables are not set higher than needed */
9883 if (thread_cache_size > max_connections)
9884 SYSVAR_AUTOSIZE(thread_cache_size, max_connections);
9885
9886 return 0;
9887}
9888
9889
9890/*
9891 Create version name for running mysqld version
9892 We automaticly add suffixes -debug, -embedded and -log to the version
9893 name to make the version more descriptive.
9894 (MYSQL_SERVER_SUFFIX is set by the compilation environment)
9895*/
9896
9897void set_server_version(char *buf, size_t size)
9898{
9899 bool is_log= opt_log || global_system_variables.sql_log_slow || opt_bin_log;
9900 bool is_debug= IF_DBUG(!strstr(MYSQL_SERVER_SUFFIX_STR, "-debug"), 0);
9901 strxnmov(buf, size - 1,
9902 MYSQL_SERVER_VERSION,
9903 MYSQL_SERVER_SUFFIX_STR,
9904 IF_EMBEDDED("-embedded", ""),
9905 is_debug ? "-debug" : "",
9906 is_log ? "-log" : "",
9907 NullS);
9908}
9909
9910
9911static char *get_relative_path(const char *path)
9912{
9913 if (test_if_hard_path(path) &&
9914 is_prefix(path,DEFAULT_MYSQL_HOME) &&
9915 strcmp(DEFAULT_MYSQL_HOME,FN_ROOTDIR))
9916 {
9917 path+=(uint) strlen(DEFAULT_MYSQL_HOME);
9918 while (*path == FN_LIBCHAR || *path == FN_LIBCHAR2)
9919 path++;
9920 }
9921 return (char*) path;
9922}
9923
9924
9925/**
9926 Fix filename and replace extension where 'dir' is relative to
9927 mysql_real_data_home.
9928 @return
9929 1 if len(path) > FN_REFLEN
9930*/
9931
9932bool
9933fn_format_relative_to_data_home(char * to, const char *name,
9934 const char *dir, const char *extension)
9935{
9936 char tmp_path[FN_REFLEN];
9937 if (!test_if_hard_path(dir))
9938 {
9939 strxnmov(tmp_path,sizeof(tmp_path)-1, mysql_real_data_home,
9940 dir, NullS);
9941 dir=tmp_path;
9942 }
9943 return !fn_format(to, name, dir, extension,
9944 MY_APPEND_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH);
9945}
9946
9947
9948/**
9949 Test a file path to determine if the path is compatible with the secure file
9950 path restriction.
9951
9952 @param path null terminated character string
9953
9954 @return
9955 @retval TRUE The path is secure
9956 @retval FALSE The path isn't secure
9957*/
9958
9959bool is_secure_file_path(char *path)
9960{
9961 char buff1[FN_REFLEN], buff2[FN_REFLEN];
9962 size_t opt_secure_file_priv_len;
9963 /*
9964 All paths are secure if opt_secure_file_path is 0
9965 */
9966 if (!opt_secure_file_priv)
9967 return TRUE;
9968
9969 opt_secure_file_priv_len= strlen(opt_secure_file_priv);
9970
9971 if (strlen(path) >= FN_REFLEN)
9972 return FALSE;
9973
9974 if (my_realpath(buff1, path, 0))
9975 {
9976 /*
9977 The supplied file path might have been a file and not a directory.
9978 */
9979 size_t length= dirname_length(path); // Guaranteed to be < FN_REFLEN
9980 memcpy(buff2, path, length);
9981 buff2[length]= '\0';
9982 if (length == 0 || my_realpath(buff1, buff2, 0))
9983 return FALSE;
9984 }
9985 convert_dirname(buff2, buff1, NullS);
9986 if (!lower_case_file_system)
9987 {
9988 if (strncmp(opt_secure_file_priv, buff2, opt_secure_file_priv_len))
9989 return FALSE;
9990 }
9991 else
9992 {
9993 if (files_charset_info->coll->strnncoll(files_charset_info,
9994 (uchar *) buff2, strlen(buff2),
9995 (uchar *) opt_secure_file_priv,
9996 opt_secure_file_priv_len,
9997 TRUE))
9998 return FALSE;
9999 }
10000 return TRUE;
10001}
10002
10003
10004static int fix_paths(void)
10005{
10006 char buff[FN_REFLEN],*pos;
10007 DBUG_ENTER("fix_paths");
10008
10009 convert_dirname(mysql_home,mysql_home,NullS);
10010 /* Resolve symlinks to allow 'mysql_home' to be a relative symlink */
10011 my_realpath(mysql_home,mysql_home,MYF(0));
10012 /* Ensure that mysql_home ends in FN_LIBCHAR */
10013 pos=strend(mysql_home);
10014 if (pos[-1] != FN_LIBCHAR)
10015 {
10016 pos[0]= FN_LIBCHAR;
10017 pos[1]= 0;
10018 }
10019 convert_dirname(lc_messages_dir, lc_messages_dir, NullS);
10020 convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
10021 (void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir
10022 (void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home);
10023 (void) my_load_path(pidfile_name, pidfile_name_ptr, mysql_real_data_home);
10024
10025 convert_dirname(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr :
10026 get_relative_path(PLUGINDIR), NullS);
10027 (void) my_load_path(opt_plugin_dir, opt_plugin_dir, mysql_home);
10028 opt_plugin_dir_ptr= opt_plugin_dir;
10029 pidfile_name_ptr= pidfile_name;
10030
10031 my_realpath(mysql_unpacked_real_data_home, mysql_real_data_home, MYF(0));
10032 mysql_unpacked_real_data_home_len=
10033 strlen(mysql_unpacked_real_data_home);
10034 if (mysql_unpacked_real_data_home[mysql_unpacked_real_data_home_len-1] == FN_LIBCHAR)
10035 --mysql_unpacked_real_data_home_len;
10036
10037 char *sharedir=get_relative_path(SHAREDIR);
10038 if (test_if_hard_path(sharedir))
10039 strmake_buf(buff, sharedir); /* purecov: tested */
10040 else
10041 strxnmov(buff,sizeof(buff)-1,mysql_home,sharedir,NullS);
10042 convert_dirname(buff,buff,NullS);
10043 (void) my_load_path(lc_messages_dir, lc_messages_dir, buff);
10044
10045 /* If --character-sets-dir isn't given, use shared library dir */
10046 if (charsets_dir)
10047 {
10048 strmake_buf(mysql_charsets_dir, charsets_dir);
10049 charsets_dir= mysql_charsets_dir;
10050 }
10051 else
10052 {
10053 strxnmov(mysql_charsets_dir, sizeof(mysql_charsets_dir)-1, buff,
10054 CHARSET_DIR, NullS);
10055 SYSVAR_AUTOSIZE(charsets_dir, mysql_charsets_dir);
10056 }
10057 (void) my_load_path(mysql_charsets_dir, mysql_charsets_dir, buff);
10058 convert_dirname(mysql_charsets_dir, mysql_charsets_dir, NullS);
10059
10060 if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir))
10061 DBUG_RETURN(1);
10062 if (!opt_mysql_tmpdir)
10063 opt_mysql_tmpdir= mysql_tmpdir;
10064#ifdef HAVE_REPLICATION
10065 if (!slave_load_tmpdir)
10066 SYSVAR_AUTOSIZE(slave_load_tmpdir, mysql_tmpdir);
10067#endif /* HAVE_REPLICATION */
10068 /*
10069 Convert the secure-file-priv option to system format, allowing
10070 a quick strcmp to check if read or write is in an allowed dir
10071 */
10072 if (opt_secure_file_priv)
10073 {
10074 if (*opt_secure_file_priv == 0)
10075 {
10076 my_free(opt_secure_file_priv);
10077 opt_secure_file_priv= 0;
10078 }
10079 else
10080 {
10081 if (strlen(opt_secure_file_priv) >= FN_REFLEN)
10082 opt_secure_file_priv[FN_REFLEN-1]= '\0';
10083 if (my_realpath(buff, opt_secure_file_priv, 0))
10084 {
10085 sql_print_warning("Failed to normalize the argument for --secure-file-priv.");
10086 DBUG_RETURN(1);
10087 }
10088 char *secure_file_real_path= (char *)my_malloc(FN_REFLEN, MYF(MY_FAE));
10089 convert_dirname(secure_file_real_path, buff, NullS);
10090 my_free(opt_secure_file_priv);
10091 opt_secure_file_priv= secure_file_real_path;
10092 }
10093 }
10094 DBUG_RETURN(0);
10095}
10096
10097/**
10098 Check if file system used for databases is case insensitive.
10099
10100 @param dir_name Directory to test
10101
10102 @retval -1 Don't know (Test failed)
10103 @retval 0 File system is case sensitive
10104 @retval 1 File system is case insensitive
10105*/
10106
10107static int test_if_case_insensitive(const char *dir_name)
10108{
10109 int result= 0;
10110 File file;
10111 char buff[FN_REFLEN], buff2[FN_REFLEN];
10112 MY_STAT stat_info;
10113 DBUG_ENTER("test_if_case_insensitive");
10114
10115 fn_format(buff, opt_log_basename, dir_name, ".lower-test",
10116 MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_REPLACE_DIR);
10117 fn_format(buff2, opt_log_basename, dir_name, ".LOWER-TEST",
10118 MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_REPLACE_DIR);
10119 mysql_file_delete(key_file_casetest, buff2, MYF(0));
10120 if ((file= mysql_file_create(key_file_casetest,
10121 buff, 0666, O_RDWR, MYF(0))) < 0)
10122 {
10123 if (!opt_abort)
10124 sql_print_warning("Can't create test file %s", buff);
10125 DBUG_RETURN(-1);
10126 }
10127 mysql_file_close(file, MYF(0));
10128 if (mysql_file_stat(key_file_casetest, buff2, &stat_info, MYF(0)))
10129 result= 1; // Can access file
10130 mysql_file_delete(key_file_casetest, buff, MYF(MY_WME));
10131 DBUG_PRINT("exit", ("result: %d", result));
10132 DBUG_RETURN(result);
10133}
10134
10135
10136#ifndef EMBEDDED_LIBRARY
10137
10138/**
10139 Create file to store pid number.
10140*/
10141static void create_pid_file()
10142{
10143 File file;
10144 if ((file= mysql_file_create(key_file_pid, pidfile_name, 0664,
10145 O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0)
10146 {
10147 char buff[MAX_BIGINT_WIDTH + 1], *end;
10148 end= int10_to_str((long) getpid(), buff, 10);
10149 *end++= '\n';
10150 if (!mysql_file_write(file, (uchar*) buff, (uint) (end-buff),
10151 MYF(MY_WME | MY_NABP)))
10152 {
10153 mysql_file_close(file, MYF(0));
10154 pid_file_created= true;
10155 return;
10156 }
10157 mysql_file_close(file, MYF(0));
10158 }
10159 sql_perror("Can't start server: can't create PID file");
10160 exit(1);
10161}
10162#endif /* EMBEDDED_LIBRARY */
10163
10164
10165/**
10166 Remove the process' pid file.
10167
10168 @param flags file operation flags
10169*/
10170
10171static void delete_pid_file(myf flags)
10172{
10173#ifndef EMBEDDED_LIBRARY
10174 if (pid_file_created)
10175 {
10176 mysql_file_delete(key_file_pid, pidfile_name, flags);
10177 pid_file_created= false;
10178 }
10179#endif /* EMBEDDED_LIBRARY */
10180 return;
10181}
10182
10183
10184/** Clear most status variables. */
10185void refresh_status(THD *thd)
10186{
10187 mysql_mutex_lock(&LOCK_status);
10188
10189 /* Add thread's status variabes to global status */
10190 add_to_status(&global_status_var, &thd->status_var);
10191
10192 /* Reset thread's status variables */
10193 thd->set_status_var_init();
10194 thd->status_var.global_memory_used= 0;
10195 bzero((uchar*) &thd->org_status_var, sizeof(thd->org_status_var));
10196 thd->start_bytes_received= 0;
10197
10198 /* Reset some global variables */
10199 reset_status_vars();
10200#ifdef WITH_WSREP
10201 if (WSREP_ON)
10202 wsrep->stats_reset(wsrep);
10203#endif /* WITH_WSREP */
10204
10205 /* Reset the counters of all key caches (default and named). */
10206 process_key_caches(reset_key_cache_counters, 0);
10207 flush_status_time= time((time_t*) 0);
10208 mysql_mutex_unlock(&LOCK_status);
10209
10210 /*
10211 Set max_used_connections to the number of currently open
10212 connections. This is not perfect, but status data is not exact anyway.
10213 */
10214 max_used_connections= connection_count + extra_connection_count;
10215}
10216
10217#ifdef HAVE_PSI_INTERFACE
10218static PSI_file_info all_server_files[]=
10219{
10220#ifdef HAVE_MMAP
10221 { &key_file_map, "map", 0},
10222#endif /* HAVE_MMAP */
10223 { &key_file_binlog, "binlog", 0},
10224 { &key_file_binlog_index, "binlog_index", 0},
10225 { &key_file_relaylog, "relaylog", 0},
10226 { &key_file_relaylog_index, "relaylog_index", 0},
10227 { &key_file_casetest, "casetest", 0},
10228 { &key_file_dbopt, "dbopt", 0},
10229 { &key_file_des_key_file, "des_key_file", 0},
10230 { &key_file_ERRMSG, "ERRMSG", 0},
10231 { &key_select_to_file, "select_to_file", 0},
10232 { &key_file_fileparser, "file_parser", 0},
10233 { &key_file_frm, "FRM", 0},
10234 { &key_file_global_ddl_log, "global_ddl_log", 0},
10235 { &key_file_load, "load", 0},
10236 { &key_file_loadfile, "LOAD_FILE", 0},
10237 { &key_file_log_event_data, "log_event_data", 0},
10238 { &key_file_log_event_info, "log_event_info", 0},
10239 { &key_file_master_info, "master_info", 0},
10240 { &key_file_misc, "misc", 0},
10241 { &key_file_partition, "partition", 0},
10242 { &key_file_pid, "pid", 0},
10243 { &key_file_query_log, "query_log", 0},
10244 { &key_file_relay_log_info, "relay_log_info", 0},
10245 { &key_file_send_file, "send_file", 0},
10246 { &key_file_slow_log, "slow_log", 0},
10247 { &key_file_tclog, "tclog", 0},
10248 { &key_file_trg, "trigger_name", 0},
10249 { &key_file_trn, "trigger", 0},
10250 { &key_file_init, "init", 0},
10251 { &key_file_binlog_state, "binlog_state", 0}
10252};
10253#endif /* HAVE_PSI_INTERFACE */
10254
10255PSI_stage_info stage_after_apply_event= { 0, "After apply log event", 0};
10256PSI_stage_info stage_after_create= { 0, "After create", 0};
10257PSI_stage_info stage_after_opening_tables= { 0, "After opening tables", 0};
10258PSI_stage_info stage_after_table_lock= { 0, "After table lock", 0};
10259PSI_stage_info stage_allocating_local_table= { 0, "Allocating local table", 0};
10260PSI_stage_info stage_alter_inplace_prepare= { 0, "Preparing for alter table", 0};
10261PSI_stage_info stage_alter_inplace= { 0, "Altering table", 0};
10262PSI_stage_info stage_alter_inplace_commit= { 0, "Committing alter table to storage engine", 0};
10263PSI_stage_info stage_apply_event= { 0, "Apply log event", 0};
10264PSI_stage_info stage_changing_master= { 0, "Changing master", 0};
10265PSI_stage_info stage_checking_master_version= { 0, "Checking master version", 0};
10266PSI_stage_info stage_checking_permissions= { 0, "Checking permissions", 0};
10267PSI_stage_info stage_checking_privileges_on_cached_query= { 0, "Checking privileges on cached query", 0};
10268PSI_stage_info stage_checking_query_cache_for_query= { 0, "Checking query cache for query", 0};
10269PSI_stage_info stage_cleaning_up= { 0, "Reset for next command", 0};
10270PSI_stage_info stage_closing_tables= { 0, "Closing tables", 0};
10271PSI_stage_info stage_connecting_to_master= { 0, "Connecting to master", 0};
10272PSI_stage_info stage_converting_heap_to_myisam= { 0, "Converting HEAP to " TMP_ENGINE_NAME, 0};
10273PSI_stage_info stage_copying_to_group_table= { 0, "Copying to group table", 0};
10274PSI_stage_info stage_copying_to_tmp_table= { 0, "Copying to tmp table", 0};
10275PSI_stage_info stage_copy_to_tmp_table= { 0, "Copy to tmp table", 0};
10276PSI_stage_info stage_creating_delayed_handler= { 0, "Creating delayed handler", 0};
10277PSI_stage_info stage_creating_sort_index= { 0, "Creating sort index", 0};
10278PSI_stage_info stage_creating_table= { 0, "Creating table", 0};
10279PSI_stage_info stage_creating_tmp_table= { 0, "Creating tmp table", 0};
10280PSI_stage_info stage_deleting_from_main_table= { 0, "Deleting from main table", 0};
10281PSI_stage_info stage_deleting_from_reference_tables= { 0, "Deleting from reference tables", 0};
10282PSI_stage_info stage_discard_or_import_tablespace= { 0, "Discard_or_import_tablespace", 0};
10283PSI_stage_info stage_enabling_keys= { 0, "Enabling keys", 0};
10284PSI_stage_info stage_end= { 0, "End of update loop", 0};
10285PSI_stage_info stage_executing= { 0, "Executing", 0};
10286PSI_stage_info stage_execution_of_init_command= { 0, "Execution of init_command", 0};
10287PSI_stage_info stage_explaining= { 0, "Explaining", 0};
10288PSI_stage_info stage_finding_key_cache= { 0, "Finding key cache", 0};
10289PSI_stage_info stage_finished_reading_one_binlog_switching_to_next_binlog= { 0, "Finished reading one binlog; switching to next binlog", 0};
10290PSI_stage_info stage_flushing_relay_log_and_master_info_repository= { 0, "Flushing relay log and master info repository.", 0};
10291PSI_stage_info stage_flushing_relay_log_info_file= { 0, "Flushing relay-log info file.", 0};
10292PSI_stage_info stage_freeing_items= { 0, "Freeing items", 0};
10293PSI_stage_info stage_fulltext_initialization= { 0, "Fulltext initialization", 0};
10294PSI_stage_info stage_got_handler_lock= { 0, "Got handler lock", 0};
10295PSI_stage_info stage_got_old_table= { 0, "Got old table", 0};
10296PSI_stage_info stage_init= { 0, "Init", 0};
10297PSI_stage_info stage_init_update= { 0, "Init for update", 0};
10298PSI_stage_info stage_insert= { 0, "Insert", 0};
10299PSI_stage_info stage_invalidating_query_cache_entries_table= { 0, "Invalidating query cache entries (table)", 0};
10300PSI_stage_info stage_invalidating_query_cache_entries_table_list= { 0, "Invalidating query cache entries (table list)", 0};
10301PSI_stage_info stage_killing_slave= { 0, "Killing slave", 0};
10302PSI_stage_info stage_logging_slow_query= { 0, "Logging slow query", 0};
10303PSI_stage_info stage_making_temp_file_append_before_load_data= { 0, "Making temporary file (append) before replaying LOAD DATA INFILE.", 0};
10304PSI_stage_info stage_making_temp_file_create_before_load_data= { 0, "Making temporary file (create) before replaying LOAD DATA INFILE.", 0};
10305PSI_stage_info stage_manage_keys= { 0, "Manage keys", 0};
10306PSI_stage_info stage_master_has_sent_all_binlog_to_slave= { 0, "Master has sent all binlog to slave; waiting for binlog to be updated", 0};
10307PSI_stage_info stage_opening_tables= { 0, "Opening tables", 0};
10308PSI_stage_info stage_optimizing= { 0, "Optimizing", 0};
10309PSI_stage_info stage_preparing= { 0, "Preparing", 0};
10310PSI_stage_info stage_purging_old_relay_logs= { 0, "Purging old relay logs", 0};
10311PSI_stage_info stage_query_end= { 0, "Query end", 0};
10312PSI_stage_info stage_starting_cleanup= { 0, "Starting cleanup", 0};
10313PSI_stage_info stage_rollback= { 0, "Rollback", 0};
10314PSI_stage_info stage_rollback_implicit= { 0, "Rollback_implicit", 0};
10315PSI_stage_info stage_commit= { 0, "Commit", 0};
10316PSI_stage_info stage_commit_implicit= { 0, "Commit_implicit", 0};
10317PSI_stage_info stage_queueing_master_event_to_the_relay_log= { 0, "Queueing master event to the relay log", 0};
10318PSI_stage_info stage_reading_event_from_the_relay_log= { 0, "Reading event from the relay log", 0};
10319PSI_stage_info stage_recreating_table= { 0, "Recreating table", 0};
10320PSI_stage_info stage_registering_slave_on_master= { 0, "Registering slave on master", 0};
10321PSI_stage_info stage_removing_duplicates= { 0, "Removing duplicates", 0};
10322PSI_stage_info stage_removing_tmp_table= { 0, "Removing tmp table", 0};
10323PSI_stage_info stage_rename= { 0, "Rename", 0};
10324PSI_stage_info stage_rename_result_table= { 0, "Rename result table", 0};
10325PSI_stage_info stage_requesting_binlog_dump= { 0, "Requesting binlog dump", 0};
10326PSI_stage_info stage_reschedule= { 0, "Reschedule", 0};
10327PSI_stage_info stage_searching_rows_for_update= { 0, "Searching rows for update", 0};
10328PSI_stage_info stage_sending_binlog_event_to_slave= { 0, "Sending binlog event to slave", 0};
10329PSI_stage_info stage_sending_cached_result_to_client= { 0, "Sending cached result to client", 0};
10330PSI_stage_info stage_sending_data= { 0, "Sending data", 0};
10331PSI_stage_info stage_setup= { 0, "Setup", 0};
10332PSI_stage_info stage_show_explain= { 0, "Show explain", 0};
10333PSI_stage_info stage_slave_has_read_all_relay_log= { 0, "Slave has read all relay log; waiting for the slave I/O thread to update it", 0};
10334PSI_stage_info stage_sorting= { 0, "Sorting", 0};
10335PSI_stage_info stage_sorting_for_group= { 0, "Sorting for group", 0};
10336PSI_stage_info stage_sorting_for_order= { 0, "Sorting for order", 0};
10337PSI_stage_info stage_sorting_result= { 0, "Sorting result", 0};
10338PSI_stage_info stage_statistics= { 0, "Statistics", 0};
10339PSI_stage_info stage_sql_thd_waiting_until_delay= { 0, "Waiting until MASTER_DELAY seconds after master executed event", 0 };
10340PSI_stage_info stage_storing_result_in_query_cache= { 0, "Storing result in query cache", 0};
10341PSI_stage_info stage_storing_row_into_queue= { 0, "Storing row into queue", 0};
10342PSI_stage_info stage_system_lock= { 0, "System lock", 0};
10343PSI_stage_info stage_unlocking_tables= { 0, "Unlocking tables", 0};
10344PSI_stage_info stage_table_lock= { 0, "Table lock", 0};
10345PSI_stage_info stage_filling_schema_table= { 0, "Filling schema table", 0};
10346PSI_stage_info stage_update= { 0, "Update", 0};
10347PSI_stage_info stage_updating= { 0, "Updating", 0};
10348PSI_stage_info stage_updating_main_table= { 0, "Updating main table", 0};
10349PSI_stage_info stage_updating_reference_tables= { 0, "Updating reference tables", 0};
10350PSI_stage_info stage_upgrading_lock= { 0, "Upgrading lock", 0};
10351PSI_stage_info stage_user_lock= { 0, "User lock", 0};
10352PSI_stage_info stage_user_sleep= { 0, "User sleep", 0};
10353PSI_stage_info stage_verifying_table= { 0, "Verifying table", 0};
10354PSI_stage_info stage_waiting_for_delay_list= { 0, "Waiting for delay_list", 0};
10355PSI_stage_info stage_waiting_for_gtid_to_be_written_to_binary_log= { 0, "Waiting for GTID to be written to binary log", 0};
10356PSI_stage_info stage_waiting_for_handler_insert= { 0, "Waiting for handler insert", 0};
10357PSI_stage_info stage_waiting_for_handler_lock= { 0, "Waiting for handler lock", 0};
10358PSI_stage_info stage_waiting_for_handler_open= { 0, "Waiting for handler open", 0};
10359PSI_stage_info stage_waiting_for_insert= { 0, "Waiting for INSERT", 0};
10360PSI_stage_info stage_waiting_for_master_to_send_event= { 0, "Waiting for master to send event", 0};
10361PSI_stage_info stage_waiting_for_master_update= { 0, "Waiting for master update", 0};
10362PSI_stage_info stage_waiting_for_relay_log_space= { 0, "Waiting for the slave SQL thread to free enough relay log space", 0};
10363PSI_stage_info stage_waiting_for_semi_sync_ack_from_slave=
10364{ 0, "Waiting for semi-sync ACK from slave", 0};
10365PSI_stage_info stage_waiting_for_semi_sync_slave={ 0, "Waiting for semi-sync slave connection", 0};
10366PSI_stage_info stage_reading_semi_sync_ack={ 0, "Reading semi-sync ACK from slave", 0};
10367PSI_stage_info stage_waiting_for_slave_mutex_on_exit= { 0, "Waiting for slave mutex on exit", 0};
10368PSI_stage_info stage_waiting_for_slave_thread_to_start= { 0, "Waiting for slave thread to start", 0};
10369PSI_stage_info stage_waiting_for_table_flush= { 0, "Waiting for table flush", 0};
10370PSI_stage_info stage_waiting_for_query_cache_lock= { 0, "Waiting for query cache lock", 0};
10371PSI_stage_info stage_waiting_for_the_next_event_in_relay_log= { 0, "Waiting for the next event in relay log", 0};
10372PSI_stage_info stage_waiting_for_the_slave_thread_to_advance_position= { 0, "Waiting for the slave SQL thread to advance position", 0};
10373PSI_stage_info stage_waiting_to_finalize_termination= { 0, "Waiting to finalize termination", 0};
10374PSI_stage_info stage_waiting_to_get_readlock= { 0, "Waiting to get readlock", 0};
10375PSI_stage_info stage_binlog_waiting_background_tasks= { 0, "Waiting for background binlog tasks", 0};
10376PSI_stage_info stage_binlog_write= { 0, "Writing to binlog", 0};
10377PSI_stage_info stage_binlog_processing_checkpoint_notify= { 0, "Processing binlog checkpoint notification", 0};
10378PSI_stage_info stage_binlog_stopping_background_thread= { 0, "Stopping binlog background thread", 0};
10379PSI_stage_info stage_waiting_for_work_from_sql_thread= { 0, "Waiting for work from SQL thread", 0};
10380PSI_stage_info stage_waiting_for_prior_transaction_to_commit= { 0, "Waiting for prior transaction to commit", 0};
10381PSI_stage_info stage_waiting_for_prior_transaction_to_start_commit= { 0, "Waiting for prior transaction to start commit before starting next transaction", 0};
10382PSI_stage_info stage_waiting_for_room_in_worker_thread= { 0, "Waiting for room in worker thread event queue", 0};
10383PSI_stage_info stage_waiting_for_workers_idle= { 0, "Waiting for worker threads to be idle", 0};
10384PSI_stage_info stage_waiting_for_ftwrl= { 0, "Waiting due to global read lock", 0};
10385PSI_stage_info stage_waiting_for_ftwrl_threads_to_pause= { 0, "Waiting for worker threads to pause for global read lock", 0};
10386PSI_stage_info stage_waiting_for_rpl_thread_pool= { 0, "Waiting while replication worker thread pool is busy", 0};
10387PSI_stage_info stage_master_gtid_wait_primary= { 0, "Waiting in MASTER_GTID_WAIT() (primary waiter)", 0};
10388PSI_stage_info stage_master_gtid_wait= { 0, "Waiting in MASTER_GTID_WAIT()", 0};
10389PSI_stage_info stage_gtid_wait_other_connection= { 0, "Waiting for other master connection to process GTID received on multiple master connections", 0};
10390PSI_stage_info stage_slave_background_process_request= { 0, "Processing requests", 0};
10391PSI_stage_info stage_slave_background_wait_request= { 0, "Waiting for requests", 0};
10392PSI_stage_info stage_waiting_for_deadlock_kill= { 0, "Waiting for parallel replication deadlock handling to complete", 0};
10393
10394#ifdef HAVE_PSI_INTERFACE
10395
10396PSI_stage_info *all_server_stages[]=
10397{
10398 & stage_after_apply_event,
10399 & stage_after_create,
10400 & stage_after_opening_tables,
10401 & stage_after_table_lock,
10402 & stage_allocating_local_table,
10403 & stage_alter_inplace,
10404 & stage_alter_inplace_commit,
10405 & stage_alter_inplace_prepare,
10406 & stage_apply_event,
10407 & stage_binlog_write,
10408 & stage_binlog_processing_checkpoint_notify,
10409 & stage_binlog_stopping_background_thread,
10410 & stage_binlog_waiting_background_tasks,
10411 & stage_changing_master,
10412 & stage_checking_master_version,
10413 & stage_checking_permissions,
10414 & stage_checking_privileges_on_cached_query,
10415 & stage_checking_query_cache_for_query,
10416 & stage_cleaning_up,
10417 & stage_closing_tables,
10418 & stage_commit,
10419 & stage_commit_implicit,
10420 & stage_connecting_to_master,
10421 & stage_converting_heap_to_myisam,
10422 & stage_copy_to_tmp_table,
10423 & stage_copying_to_group_table,
10424 & stage_copying_to_tmp_table,
10425 & stage_creating_delayed_handler,
10426 & stage_creating_sort_index,
10427 & stage_creating_table,
10428 & stage_creating_tmp_table,
10429 & stage_deleting_from_main_table,
10430 & stage_deleting_from_reference_tables,
10431 & stage_discard_or_import_tablespace,
10432 & stage_enabling_keys,
10433 & stage_end,
10434 & stage_executing,
10435 & stage_execution_of_init_command,
10436 & stage_explaining,
10437 & stage_finding_key_cache,
10438 & stage_finished_reading_one_binlog_switching_to_next_binlog,
10439 & stage_flushing_relay_log_and_master_info_repository,
10440 & stage_flushing_relay_log_info_file,
10441 & stage_freeing_items,
10442 & stage_fulltext_initialization,
10443 & stage_got_handler_lock,
10444 & stage_got_old_table,
10445 & stage_init,
10446 & stage_init_update,
10447 & stage_insert,
10448 & stage_invalidating_query_cache_entries_table,
10449 & stage_invalidating_query_cache_entries_table_list,
10450 & stage_killing_slave,
10451 & stage_logging_slow_query,
10452 & stage_making_temp_file_append_before_load_data,
10453 & stage_making_temp_file_create_before_load_data,
10454 & stage_manage_keys,
10455 & stage_master_has_sent_all_binlog_to_slave,
10456 & stage_opening_tables,
10457 & stage_optimizing,
10458 & stage_preparing,
10459 & stage_purging_old_relay_logs,
10460 & stage_starting_cleanup,
10461 & stage_query_end,
10462 & stage_queueing_master_event_to_the_relay_log,
10463 & stage_reading_event_from_the_relay_log,
10464 & stage_recreating_table,
10465 & stage_registering_slave_on_master,
10466 & stage_removing_duplicates,
10467 & stage_removing_tmp_table,
10468 & stage_rename,
10469 & stage_rename_result_table,
10470 & stage_requesting_binlog_dump,
10471 & stage_reschedule,
10472 & stage_rollback,
10473 & stage_rollback_implicit,
10474 & stage_searching_rows_for_update,
10475 & stage_sending_binlog_event_to_slave,
10476 & stage_sending_cached_result_to_client,
10477 & stage_sending_data,
10478 & stage_setup,
10479 & stage_show_explain,
10480 & stage_slave_has_read_all_relay_log,
10481 & stage_sorting,
10482 & stage_sorting_for_group,
10483 & stage_sorting_for_order,
10484 & stage_sorting_result,
10485 & stage_sql_thd_waiting_until_delay,
10486 & stage_statistics,
10487 & stage_storing_result_in_query_cache,
10488 & stage_storing_row_into_queue,
10489 & stage_system_lock,
10490 & stage_unlocking_tables,
10491 & stage_table_lock,
10492 & stage_filling_schema_table,
10493 & stage_update,
10494 & stage_updating,
10495 & stage_updating_main_table,
10496 & stage_updating_reference_tables,
10497 & stage_upgrading_lock,
10498 & stage_user_lock,
10499 & stage_user_sleep,
10500 & stage_verifying_table,
10501 & stage_waiting_for_delay_list,
10502 & stage_waiting_for_gtid_to_be_written_to_binary_log,
10503 & stage_waiting_for_handler_insert,
10504 & stage_waiting_for_handler_lock,
10505 & stage_waiting_for_handler_open,
10506 & stage_waiting_for_insert,
10507 & stage_waiting_for_master_to_send_event,
10508 & stage_waiting_for_master_update,
10509 & stage_waiting_for_prior_transaction_to_commit,
10510 & stage_waiting_for_prior_transaction_to_start_commit,
10511 & stage_waiting_for_query_cache_lock,
10512 & stage_waiting_for_relay_log_space,
10513 & stage_waiting_for_room_in_worker_thread,
10514 & stage_waiting_for_slave_mutex_on_exit,
10515 & stage_waiting_for_slave_thread_to_start,
10516 & stage_waiting_for_table_flush,
10517 & stage_waiting_for_the_next_event_in_relay_log,
10518 & stage_waiting_for_the_slave_thread_to_advance_position,
10519 & stage_waiting_for_work_from_sql_thread,
10520 & stage_waiting_to_finalize_termination,
10521 & stage_waiting_to_get_readlock,
10522 & stage_master_gtid_wait_primary,
10523 & stage_master_gtid_wait,
10524 & stage_gtid_wait_other_connection,
10525 & stage_slave_background_process_request,
10526 & stage_slave_background_wait_request,
10527 & stage_waiting_for_semi_sync_ack_from_slave,
10528 & stage_waiting_for_semi_sync_slave,
10529 & stage_reading_semi_sync_ack,
10530 & stage_waiting_for_deadlock_kill
10531};
10532
10533PSI_socket_key key_socket_tcpip, key_socket_unix, key_socket_client_connection;
10534
10535static PSI_socket_info all_server_sockets[]=
10536{
10537 { &key_socket_tcpip, "server_tcpip_socket", PSI_FLAG_GLOBAL},
10538 { &key_socket_unix, "server_unix_socket", PSI_FLAG_GLOBAL},
10539 { &key_socket_client_connection, "client_connection", 0}
10540};
10541
10542/**
10543 Initialise all the performance schema instrumentation points
10544 used by the server.
10545*/
10546void init_server_psi_keys(void)
10547{
10548 const char* category= "sql";
10549 int count;
10550
10551 count= array_elements(all_server_mutexes);
10552 mysql_mutex_register(category, all_server_mutexes, count);
10553
10554 count= array_elements(all_server_rwlocks);
10555 mysql_rwlock_register(category, all_server_rwlocks, count);
10556
10557 count= array_elements(all_server_conds);
10558 mysql_cond_register(category, all_server_conds, count);
10559
10560 count= array_elements(all_server_threads);
10561 mysql_thread_register(category, all_server_threads, count);
10562
10563 count= array_elements(all_server_files);
10564 mysql_file_register(category, all_server_files, count);
10565
10566 count= array_elements(all_server_stages);
10567 mysql_stage_register(category, all_server_stages, count);
10568
10569 count= array_elements(all_server_sockets);
10570 mysql_socket_register(category, all_server_sockets, count);
10571
10572#ifdef HAVE_PSI_STATEMENT_INTERFACE
10573 init_sql_statement_info();
10574 count= array_elements(sql_statement_info);
10575 mysql_statement_register(category, sql_statement_info, count);
10576
10577 category= "com";
10578 init_com_statement_info();
10579
10580 /*
10581 Register [0 .. COM_QUERY - 1] as "statement/com/..."
10582 */
10583 count= (int) COM_QUERY;
10584 mysql_statement_register(category, com_statement_info, count);
10585
10586 /*
10587 Register [COM_QUERY + 1 .. COM_END] as "statement/com/..."
10588 */
10589 count= (int) COM_END - (int) COM_QUERY;
10590 mysql_statement_register(category, & com_statement_info[(int) COM_QUERY + 1], count);
10591
10592 category= "abstract";
10593 /*
10594 Register [COM_QUERY] as "statement/abstract/com_query"
10595 */
10596 mysql_statement_register(category, & com_statement_info[(int) COM_QUERY], 1);
10597
10598 /*
10599 When a new packet is received,
10600 it is instrumented as "statement/abstract/new_packet".
10601 Based on the packet type found, it later mutates to the
10602 proper narrow type, for example
10603 "statement/abstract/query" or "statement/com/ping".
10604 In cases of "statement/abstract/query", SQL queries are given to
10605 the parser, which mutates the statement type to an even more
10606 narrow classification, for example "statement/sql/select".
10607 */
10608 stmt_info_new_packet.m_key= 0;
10609 stmt_info_new_packet.m_name= "new_packet";
10610 stmt_info_new_packet.m_flags= PSI_FLAG_MUTABLE;
10611 mysql_statement_register(category, &stmt_info_new_packet, 1);
10612
10613 /*
10614 Statements processed from the relay log are initially instrumented as
10615 "statement/abstract/relay_log". The parser will mutate the statement type to
10616 a more specific classification, for example "statement/sql/insert".
10617 */
10618 stmt_info_rpl.m_key= 0;
10619 stmt_info_rpl.m_name= "relay_log";
10620 stmt_info_rpl.m_flags= PSI_FLAG_MUTABLE;
10621 mysql_statement_register(category, &stmt_info_rpl, 1);
10622#endif
10623}
10624
10625#endif /* HAVE_PSI_INTERFACE */
10626
10627
10628/*
10629 Connection ID allocation.
10630
10631 We need to maintain thread_ids in the 32bit range,
10632 because this is how it is passed to the client in the protocol.
10633
10634 The idea is to maintain a id range, initially set to
10635 (0,UINT32_MAX). Whenever new id is needed, we increment the
10636 lower limit and return its new value.
10637
10638 On "overflow", if id can not be generated anymore(i.e lower == upper -1),
10639 we recalculate the range boundaries.
10640 To do that, we first collect thread ids that are in use, by traversing
10641 THD list, and find largest region within (0,UINT32_MAX), that is still free.
10642
10643*/
10644
10645static my_thread_id thread_id_max= UINT_MAX32;
10646
10647#include <vector>
10648#include <algorithm>
10649
10650/*
10651 Find largest unused thread_id range.
10652
10653 i.e for every number N within the returned range,
10654 there is no existing connection with thread_id equal to N.
10655
10656 The range is exclusive, lower bound is always >=0 and
10657 upper bound <=MAX_UINT32.
10658
10659 @param[out] low - lower bound for the range
10660 @param[out] high - upper bound for the range
10661*/
10662static void recalculate_thread_id_range(my_thread_id *low, my_thread_id *high)
10663{
10664 std::vector<my_thread_id> ids;
10665
10666 // Add sentinels
10667 ids.push_back(0);
10668 ids.push_back(UINT_MAX32);
10669
10670 mysql_mutex_lock(&LOCK_thread_count);
10671
10672 I_List_iterator<THD> it(threads);
10673 THD *thd;
10674 while ((thd=it++))
10675 ids.push_back(thd->thread_id);
10676
10677 mysql_mutex_unlock(&LOCK_thread_count);
10678
10679 std::sort(ids.begin(), ids.end());
10680 my_thread_id max_gap= 0;
10681 for (size_t i= 0; i < ids.size() - 1; i++)
10682 {
10683 my_thread_id gap= ids[i+1] - ids[i];
10684 if (gap > max_gap)
10685 {
10686 *low= ids[i];
10687 *high= ids[i+1];
10688 max_gap= gap;
10689 }
10690 }
10691
10692 if (max_gap < 2)
10693 {
10694 /* Can't find free id. This is not really possible,
10695 we'd need 2^32 connections for this to happen.*/
10696 sql_print_error("Cannot find free connection id.");
10697 abort();
10698 }
10699}
10700
10701
10702my_thread_id next_thread_id(void)
10703{
10704 my_thread_id retval;
10705 DBUG_EXECUTE_IF("thread_id_overflow", global_thread_id= thread_id_max-2;);
10706
10707 mysql_mutex_lock(&LOCK_thread_id);
10708
10709 if (unlikely(global_thread_id == thread_id_max - 1))
10710 {
10711 recalculate_thread_id_range(&global_thread_id, &thread_id_max);
10712 }
10713
10714 retval= ++global_thread_id;
10715
10716 mysql_mutex_unlock(&LOCK_thread_id);
10717 return retval;
10718}
10719