mysqld.cc 342 KB
Newer Older
1
/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
Sergei Golubchik's avatar
Sergei Golubchik committed
2
   Copyright (c) 2008, 2014, SkySQL Ab.
3

unknown's avatar
unknown committed
4 5
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
unknown's avatar
unknown committed
6
   the Free Software Foundation; version 2 of the License.
7

unknown's avatar
unknown committed
8 9 10 11
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
12

unknown's avatar
unknown committed
13 14
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
15
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA */
unknown's avatar
unknown committed
16

17
#include "sql_plugin.h"                         // Includes my_global.h
18 19 20 21 22 23 24 25 26 27 28 29 30
#include "sql_priv.h"
#include "unireg.h"
#include <signal.h>
#ifndef __WIN__
#include <netdb.h>        // getservbyname, servent
#endif
#include "sql_parse.h"    // test_if_data_home_dir
#include "sql_cache.h"    // query_cache, query_cache_*
#include "sql_locale.h"   // MY_LOCALES, my_locales, my_locale_by_name
#include "sql_show.h"     // free_status_vars, add_status_vars,
                          // reset_status_vars
#include "strfunc.h"      // find_set_from_flags
#include "parse_file.h"   // File_parser_dummy_hook
31 32
#include "sql_db.h"       // my_dboptions_cache_free
                          // my_dboptions_cache_init
33 34 35 36 37 38 39 40 41 42
#include "sql_table.h"    // release_ddl_log, execute_ddl_log_recovery
#include "sql_connect.h"  // free_max_user_conn, init_max_user_conn,
                          // handle_one_connection
#include "sql_time.h"     // known_date_time_formats,
                          // get_date_time_format_str,
                          // date_time_format_make
#include "tztime.h"       // my_tz_free, my_tz_init, my_tz_SYSTEM
#include "hostname.h"     // hostname_cache_free, hostname_cache_init
#include "sql_acl.h"      // acl_free, grant_free, acl_init,
                          // grant_init
43
#include "sql_base.h"
44 45 46 47 48 49 50 51
#include "sql_test.h"     // mysql_print_status
#include "item_create.h"  // item_create_cleanup, item_create_init
#include "sql_servers.h"  // servers_free, servers_init
#include "init.h"         // unireg_init
#include "derror.h"       // init_errmessage
#include "derror.h"       // init_errmessage
#include "des_key_file.h" // load_des_key_file
#include "sql_manager.h"  // stop_handle_manager, start_handle_manager
52
#include "sql_expression_cache.h" // subquery_cache_miss, subquery_cache_hit
53
#include "sys_vars_shared.h"
Sergei Golubchik's avatar
Sergei Golubchik committed
54

unknown's avatar
unknown committed
55
#include <m_ctype.h>
56
#include <my_dir.h>
57
#include <my_bit.h>
58
#include "slave.h"
59
#include "rpl_mi.h"
60
#include "sql_repl.h"
unknown's avatar
unknown committed
61
#include "rpl_filter.h"
62
#include "client_settings.h"
63
#include "repl_failsafe.h"
64
#include <sql_common.h>
65
#include <my_stacktrace.h>
66
#include "mysqld_suffix.h"
unknown's avatar
Merge  
unknown committed
67
#include "mysys_err.h"
68
#include "events.h"
69
#include "sql_audit.h"
70
#include "probes_mysql.h"
71
#include "scheduler.h"
72
#include <waiting_threads.h>
73
#include "debug_sync.h"
74 75 76 77 78
#include "wsrep_mysqld.h"
#include "wsrep_var.h"
#include "wsrep_thd.h"
#include "wsrep_sst.h"

79
#include "sql_callback.h"
80
#include "threadpool.h"
81

Marc Alff's avatar
Marc Alff committed
82 83 84
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
#include "../storage/perfschema/pfs_server.h"
#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
85 86 87 88
#include <mysql/psi/mysql_idle.h>
#include <mysql/psi/mysql_socket.h>
#include <mysql/psi/mysql_statement.h>
#include "mysql_com_server.h"
Marc Alff's avatar
Marc Alff committed
89

90
#include "keycaches.h"
91
#include "../storage/myisam/ha_myisam.h"
92
#include "set_var.h"
93

94 95
#include "rpl_injector.h"

He Zhenxing's avatar
He Zhenxing committed
96 97
#include "rpl_handler.h"

98 99
#ifdef HAVE_SYS_PRCTL_H
#include <sys/prctl.h>
100 101
#endif

unknown's avatar
unknown committed
102 103
#include <thr_alarm.h>
#include <ft_global.h>
104
#include <errmsg.h>
unknown's avatar
Merge  
unknown committed
105 106
#include "sp_rcontext.h"
#include "sp_cache.h"
107
#include "sql_reload.h"  // reload_acl_and_cache
unknown's avatar
unknown committed
108

109 110
#ifdef HAVE_POLL_H
#include <poll.h>
111 112
#endif

unknown's avatar
unknown committed
113
#define mysqld_charset &my_charset_latin1
114

115
/* We have HAVE_valgrind below as this speeds up the shutdown of MySQL */
116

117
#if defined(SIGNALS_DONT_BREAK_READ) || defined(HAVE_valgrind) && defined(__linux__)
unknown's avatar
unknown committed
118
#define HAVE_CLOSE_SERVER_SOCK 1
119
#endif
unknown's avatar
unknown committed
120

unknown's avatar
unknown committed
121 122 123
extern "C" {					// Because of SCO 3.2V4.2
#include <sys/stat.h>
#ifndef __GNU_LIBRARY__
124
#define __GNU_LIBRARY__				// Skip warnings in getopt.h
unknown's avatar
unknown committed
125
#endif
126
#include <my_getopt.h>
unknown's avatar
unknown committed
127 128 129 130 131 132 133 134 135
#ifdef HAVE_SYSENT_H
#include <sysent.h>
#endif
#ifdef HAVE_PWD_H
#include <pwd.h>				// For getpwent
#endif
#ifdef HAVE_GRP_H
#include <grp.h>
#endif
unknown's avatar
Merge  
unknown committed
136
#include <my_net.h>
unknown's avatar
unknown committed
137

138
#if !defined(__WIN__)
unknown's avatar
unknown committed
139 140
#include <sys/resource.h>
#ifdef HAVE_SYS_UN_H
141
#include <sys/un.h>
unknown's avatar
unknown committed
142 143
#endif
#ifdef HAVE_SELECT_H
144
#include <select.h>
unknown's avatar
unknown committed
145 146 147 148 149
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#include <sys/utsname.h>
unknown's avatar
unknown committed
150
#endif /* __WIN__ */
unknown's avatar
unknown committed
151

152
#include <my_libwrap.h>
unknown's avatar
unknown committed
153

154 155 156 157
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif

158 159 160 161
#ifdef __WIN__ 
#include <crtdbg.h>
#endif

162 163 164 165 166 167 168 169 170 171
#ifdef HAVE_SOLARIS_LARGE_PAGES
#include <sys/mman.h>
#if defined(__sun__) && defined(__GNUC__) && defined(__cplusplus) \
    && defined(_XOPEN_SOURCE)
extern int getpagesizes(size_t *, int);
extern int getpagesizes2(size_t *, int);
extern int memcntl(caddr_t, size_t, int, caddr_t, int, int);
#endif /* __sun__ ... */
#endif /* HAVE_SOLARIS_LARGE_PAGES */

unknown's avatar
unknown committed
172
#ifdef _AIX41
unknown's avatar
unknown committed
173
int initgroups(const char *,unsigned int);
unknown's avatar
unknown committed
174 175
#endif

176
#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H) && !defined(HAVE_FEDISABLEEXCEPT)
unknown's avatar
unknown committed
177 178 179 180
#include <ieeefp.h>
#ifdef HAVE_FP_EXCEPT				// Fix type conflict
typedef fp_except fp_except_t;
#endif
181
#endif /* __FreeBSD__ && HAVE_IEEEFP_H && !HAVE_FEDISABLEEXCEPT */
182 183 184 185
#ifdef HAVE_SYS_FPU_H
/* for IRIX to use set_fpc_csr() */
#include <sys/fpu.h>
#endif
186 187 188
#ifdef HAVE_FPU_CONTROL_H
#include <fpu_control.h>
#endif
189 190 191 192
#if defined(__i386__) && !defined(HAVE_FPU_CONTROL_H)
# define fpu_control_t unsigned int
# define _FPU_EXTENDED 0x300
# define _FPU_DOUBLE 0x200
193
# if defined(__GNUC__) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590)
194 195
#  define _FPU_GETCW(cw) asm volatile ("fnstcw %0" : "=m" (*&cw))
#  define _FPU_SETCW(cw) asm volatile ("fldcw %0" : : "m" (*&cw))
196 197 198 199 200
# else
#  define _FPU_GETCW(cw) (cw= 0)
#  define _FPU_SETCW(cw)
# endif
#endif
unknown's avatar
unknown committed
201

Sergei Golubchik's avatar
Sergei Golubchik committed
202 203 204 205
#ifndef HAVE_FCNTL
#define fcntl(X,Y,Z) 0
#endif

206 207 208
extern "C" my_bool reopen_fstreams(const char *filename,
                                   FILE *outstream, FILE *errstream);

209
inline void setup_fpu()
unknown's avatar
unknown committed
210
{
211
#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H) && !defined(HAVE_FEDISABLEEXCEPT)
unknown's avatar
unknown committed
212
  /* We can't handle floating point exceptions with threads, so disable
unknown's avatar
unknown committed
213
     this on freebsd
214 215
     Don't fall for overflow, underflow,divide-by-zero or loss of precision.
     fpsetmask() is deprecated in favor of fedisableexcept() in C99.
unknown's avatar
unknown committed
216
  */
217
#if defined(FP_X_DNML)
unknown's avatar
unknown committed
218 219
  fpsetmask(~(FP_X_INV | FP_X_DNML | FP_X_OFL | FP_X_UFL | FP_X_DZ |
	      FP_X_IMP));
unknown's avatar
unknown committed
220
#else
221 222
  fpsetmask(~(FP_X_INV |             FP_X_OFL | FP_X_UFL | FP_X_DZ |
              FP_X_IMP));
223 224 225 226 227 228
#endif /* FP_X_DNML */
#endif /* __FreeBSD__ && HAVE_IEEEFP_H && !HAVE_FEDISABLEEXCEPT */

#ifdef HAVE_FEDISABLEEXCEPT
  fedisableexcept(FE_ALL_EXCEPT);
#endif
229

230 231 232 233
#ifdef HAVE_FESETROUND
    /* Set FPU rounding mode to "round-to-nearest" */
  fesetround(FE_TONEAREST);
#endif /* HAVE_FESETROUND */
234 235

  /*
236 237 238 239
    x86 (32-bit) requires FPU precision to be explicitly set to 64 bit
    (double precision) for portable results of floating point operations.
    However, there is no need to do so if compiler is using SSE2 for floating
    point, double values will be stored and processed in 64 bits anyway.
240
  */
241
#if defined(__i386__) && !defined(__SSE2_MATH__)
242 243 244 245 246 247 248 249 250 251 252 253
#if defined(_WIN32)
#if !defined(_WIN64)
  _control87(_PC_53, MCW_PC);
#endif /* !_WIN64 */
#else /* !_WIN32 */
  fpu_control_t cw;
  _FPU_GETCW(cw);
  cw= (cw & ~_FPU_EXTENDED) | _FPU_DOUBLE;
  _FPU_SETCW(cw);
#endif /* _WIN32 && */
#endif /* __i386__ */

254
#if defined(__sgi) && defined(HAVE_SYS_FPU_H)
255
  /* Enable denormalized DOUBLE values support for IRIX */
256 257 258 259 260
  union fpc_csr n;
  n.fc_word = get_fpc_csr();
  n.fc_struct.flush = 0;
  set_fpc_csr(n.fc_word);
#endif
261
}
unknown's avatar
unknown committed
262

unknown's avatar
unknown committed
263 264
} /* cplusplus */

unknown's avatar
unknown committed
265
#define MYSQL_KILL_SIGNAL SIGTERM
unknown's avatar
unknown committed
266 267 268 269 270 271 272

#include <my_pthread.h>			// For thr_setconcurency()

#ifdef SOLARIS
extern "C" int gethostname(char *name, int namelen);
#endif

273
extern "C" sig_handler handle_fatal_signal(int sig);
274

275 276 277
#if defined(__linux__)
#define ENABLE_TEMP_POOL 1
#else
Vladislav Vaintroub's avatar
Vladislav Vaintroub committed
278
#define ENABLE_TEMP_POOL 0
279 280
#endif

unknown's avatar
unknown committed
281
/* Constants */
282

283 284
#include <welcome_copyright_notice.h> // ORACLE_WELCOME_COPYRIGHT_NOTICE

unknown's avatar
unknown committed
285
const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"};
286

unknown's avatar
unknown committed
287 288 289 290 291 292 293 294 295
static const char *tc_heuristic_recover_names[]=
{
  "COMMIT", "ROLLBACK", NullS
};
static TYPELIB tc_heuristic_recover_typelib=
{
  array_elements(tc_heuristic_recover_names)-1,"",
  tc_heuristic_recover_names, NULL
};
unknown's avatar
unknown committed
296

unknown's avatar
unknown committed
297
const char *first_keyword= "first", *binary_keyword= "BINARY";
unknown's avatar
unknown committed
298
const char *my_localhost= "localhost", *delayed_user= "DELAYED";
299

unknown's avatar
unknown committed
300
bool opt_large_files= sizeof(my_off_t) > 4;
301
static my_bool opt_autocommit; ///< for --autocommit command-line option
302 303 304 305

/*
  Used with --help for detailed option
*/
306
static my_bool opt_verbose= 0;
307

308
arg_cmp_func Arg_comparator::comparator_matrix[6][2] =
309 310 311
{{&Arg_comparator::compare_string,     &Arg_comparator::compare_e_string},
 {&Arg_comparator::compare_real,       &Arg_comparator::compare_e_real},
 {&Arg_comparator::compare_int_signed, &Arg_comparator::compare_e_int},
unknown's avatar
Merge  
unknown committed
312
 {&Arg_comparator::compare_row,        &Arg_comparator::compare_e_row},
313 314
 {&Arg_comparator::compare_decimal,    &Arg_comparator::compare_e_decimal},
 {&Arg_comparator::compare_datetime,   &Arg_comparator::compare_e_datetime}};
unknown's avatar
unknown committed
315

unknown's avatar
unknown committed
316 317
/* static variables */

Marc Alff's avatar
Marc Alff committed
318 319 320
#ifdef HAVE_PSI_INTERFACE
#if (defined(_WIN32) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY)
static PSI_thread_key key_thread_handle_con_namedpipes;
Marc Alff's avatar
Marc Alff committed
321
static PSI_cond_key key_COND_handler_count;
Marc Alff's avatar
Marc Alff committed
322 323 324 325 326 327 328 329 330 331 332 333 334
#endif /* _WIN32 || HAVE_SMEM && !EMBEDDED_LIBRARY */

#if defined(HAVE_SMEM) && !defined(EMBEDDED_LIBRARY)
static PSI_thread_key key_thread_handle_con_sharedmem;
#endif /* HAVE_SMEM && !EMBEDDED_LIBRARY */

#if (defined(_WIN32) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY)
static PSI_thread_key key_thread_handle_con_sockets;
#endif /* _WIN32 || HAVE_SMEM && !EMBEDDED_LIBRARY */

#ifdef __WIN__
static PSI_thread_key key_thread_handle_shutdown;
#endif /* __WIN__ */
335 336 337 338

#if defined (HAVE_OPENSSL) && !defined(HAVE_YASSL)
static PSI_rwlock_key key_rwlock_openssl;
#endif
Marc Alff's avatar
Marc Alff committed
339 340
#endif /* HAVE_PSI_INTERFACE */

341 342 343 344
#ifdef HAVE_NPTL
volatile sig_atomic_t ld_assume_kernel_is_set= 0;
#endif

Sergei Golubchik's avatar
Sergei Golubchik committed
345 346 347 348 349 350 351
/**
  Statement instrumentation key for replication.
*/
#ifdef HAVE_PSI_STATEMENT_INTERFACE
PSI_statement_info stmt_info_rpl;
#endif

352
/* the default log output is log tables */
unknown's avatar
unknown committed
353
static bool lower_case_table_names_used= 0;
354
static bool max_long_data_size_used= false;
unknown's avatar
unknown committed
355
static bool volatile select_thread_in_use, signal_thread_in_use;
356
static volatile bool ready_to_exit;
unknown's avatar
unknown committed
357 358
static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0;
static my_bool opt_short_log_format= 0;
359 360
uint kill_cached_threads;
static uint wake_thread;
Michael Widenius's avatar
Michael Widenius committed
361
ulong max_used_connections;
unknown's avatar
unknown committed
362
static volatile ulong cached_thread_count= 0;
363
static char *mysqld_user, *mysqld_chroot;
unknown's avatar
unknown committed
364
static char *default_character_set_name;
unknown's avatar
unknown committed
365
static char *character_set_filesystem_name;
366
static char *lc_messages;
367
static char *lc_time_names_name;
368
char *my_bind_addr_str;
369
static char *default_collation_name;
370
char *default_storage_engine, *default_tmp_storage_engine;
371
static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME;
unknown's avatar
unknown committed
372
static I_List<THD> thread_cache;
373 374
static bool binlog_format_used= false;
LEX_STRING opt_init_connect, opt_init_slave;
375 376
mysql_cond_t COND_thread_cache;
static mysql_cond_t COND_flush_thread_cache;
377
mysql_cond_t COND_slave_init;
378
static DYNAMIC_ARRAY all_options;
unknown's avatar
unknown committed
379

unknown's avatar
unknown committed
380
/* Global variables */
unknown's avatar
unknown committed
381

382
bool opt_bin_log, opt_bin_log_used=0, opt_ignore_builtin_innodb= 0;
Monty's avatar
Monty committed
383
my_bool opt_log, debug_assert_if_crashed_table= 0, opt_help= 0;
384
static my_bool opt_abort;
385
ulonglong log_output_options;
Sergei Golubchik's avatar
Sergei Golubchik committed
386
my_bool opt_userstat_running;
387
my_bool opt_log_queries_not_using_indexes= 0;
388
bool opt_error_log= IF_WIN(1,0);
unknown's avatar
unknown committed
389
bool opt_disable_networking=0, opt_skip_show_db=0;
390
bool opt_skip_name_resolve=0;
391
my_bool opt_character_set_client_handshake= 1;
unknown's avatar
unknown committed
392
bool server_id_supplied = 0;
393
bool opt_endinfo, using_udf_functions;
394
my_bool locked_in_memory;
395
bool opt_using_transactions;
unknown's avatar
unknown committed
396
bool volatile abort_loop;
397
bool volatile shutdown_in_progress;
Sergei Golubchik's avatar
Sergei Golubchik committed
398
uint volatile global_disable_checkpoint;
399 400 401
#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
ulong slow_start_timeout;
#endif
402 403 404 405 406 407 408 409 410 411 412 413 414 415 416
/*
  True if the bootstrap thread is running. Protected by LOCK_thread_count,
  just like thread_count.
  Used in bootstrap() function to determine if the bootstrap thread
  has completed. Note, that we can't use 'thread_count' instead,
  since in 5.1, in presence of the Event Scheduler, there may be
  event threads running in parallel, so it's impossible to know
  what value of 'thread_count' is a sign of completion of the
  bootstrap thread.

  At the same time, we can't start the event scheduler after
  bootstrap either, since we want to be able to process event-related
  SQL commands in the init file and in --bootstrap mode.
*/
bool in_bootstrap= FALSE;
417 418 419 420
/**
   @brief 'grant_option' is used to indicate if privileges needs
   to be checked, in which case the lock, LOCK_grant, is used
   to protect access to the grant table.
421
   @note This flag is dropped in 5.1
422 423 424
   @see grant_init()
 */
bool volatile grant_option;
unknown's avatar
unknown committed
425

unknown's avatar
unknown committed
426
my_bool opt_skip_slave_start = 0; ///< If set, slave is not autostarted
unknown's avatar
unknown committed
427
my_bool opt_reckless_slave = 0;
unknown's avatar
unknown committed
428 429
my_bool opt_enable_named_pipe= 0;
my_bool opt_local_infile, opt_slave_compressed_protocol;
430 431
my_bool opt_safe_user_create = 0;
my_bool opt_show_slave_auth_info;
432
my_bool opt_log_slave_updates= 0;
433
my_bool opt_replicate_annotate_row_events= 0;
434
my_bool opt_mysql56_temporal_format=0, strict_password_validation= 1;
435 436
char *opt_slave_skip_errors;

437 438 439 440 441
/*
  Legacy global handlerton. These will be removed (please do not add more).
*/
handlerton *heap_hton;
handlerton *myisam_hton;
442
handlerton *partition_hton;
443

444 445
my_bool read_only= 0, opt_readonly= 0;
my_bool use_temp_pool, relay_log_purge;
446
my_bool relay_log_recovery;
unknown's avatar
unknown committed
447
my_bool opt_sync_frm, opt_allow_suspicious_udfs;
448
my_bool opt_secure_auth= 0;
449
char* opt_secure_file_priv;
450
my_bool opt_log_slow_admin_statements= 0;
451
my_bool opt_log_slow_slave_statements= 0;
unknown's avatar
unknown committed
452
my_bool lower_case_file_system= 0;
453
my_bool opt_large_pages= 0;
454
my_bool opt_super_large_pages= 0;
unknown's avatar
unknown committed
455
my_bool opt_myisam_use_mmap= 0;
456
uint   opt_large_page_size= 0;
457
#if defined(ENABLED_DEBUG_SYNC)
458
MYSQL_PLUGIN_IMPORT uint    opt_debug_sync_timeout= 0;
459
#endif /* defined(ENABLED_DEBUG_SYNC) */
460
my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
461
ulong opt_replicate_events_marked_for_skip;
462

unknown's avatar
Merge  
unknown committed
463 464 465 466 467
/*
  True if there is at least one per-hour limit for some user, so we should
  check them before each query (and possibly reset counters when hour is
  changed). False otherwise.
*/
unknown's avatar
unknown committed
468
volatile bool mqh_used = 0;
469
my_bool opt_noacl;
unknown's avatar
Merge  
unknown committed
470
my_bool sp_automatic_privileges= 1;
471

472
ulong opt_binlog_rows_event_max_size;
473 474
my_bool opt_master_verify_checksum= 0;
my_bool opt_slave_sql_verify_checksum= 1;
unknown's avatar
unknown committed
475
const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS};
476
#ifdef HAVE_INITGROUPS
477
volatile sig_atomic_t calling_initgroups= 0; /**< Used in SIGSEGV handler. */
478
#endif
479
uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
480
uint mysqld_extra_port;
481
uint mysqld_port_timeout;
Georgi Kodinov's avatar
merge  
Georgi Kodinov committed
482
ulong delay_key_write_options;
483
uint protocol_version;
unknown's avatar
unknown committed
484
uint lower_case_table_names;
Georgi Kodinov's avatar
merge  
Georgi Kodinov committed
485
ulong tc_heuristic_recover= 0;
Michael Widenius's avatar
Michael Widenius committed
486
int32 thread_count;
487
int32 thread_running;
Michael Widenius's avatar
Michael Widenius committed
488
int32 slave_open_temp_tables;
489
ulong thread_created;
490
ulong back_log, connect_timeout, concurrency, server_id;
491
ulong what_to_log;
Michael Widenius's avatar
Michael Widenius committed
492
ulong slow_launch_time;
493
ulong open_files_limit, max_binlog_size;
494 495
ulong slave_trans_retries;
uint  slave_net_timeout;
496
ulong slave_exec_mode_options;
497
ulong slave_run_triggers_for_rbr= 0;
498
ulong slave_ddl_exec_mode_options= SLAVE_EXEC_MODE_IDEMPOTENT;
unknown's avatar
unknown committed
499
ulonglong slave_type_conversions_options;
500
ulong thread_cache_size=0;
501 502
ulonglong binlog_cache_size=0;
ulonglong max_binlog_cache_size=0;
503
ulong slave_max_allowed_packet= 0;
504 505 506
ulonglong binlog_stmt_cache_size=0;
ulonglong  max_binlog_stmt_cache_size=0;
ulonglong query_cache_size=0;
507
ulong query_cache_limit=0;
508
ulong executed_events=0;
509
query_id_t global_query_id;
unknown's avatar
unknown committed
510
ulong aborted_threads, aborted_connects;
unknown's avatar
unknown committed
511 512
ulong delayed_insert_timeout, delayed_insert_limit, delayed_queue_size;
ulong delayed_insert_threads, delayed_insert_writes, delayed_rows_in_use;
unknown's avatar
unknown committed
513
ulong delayed_insert_errors,flush_time;
unknown's avatar
Merge  
unknown committed
514
ulong specialflag=0;
515
ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
516
ulong binlog_stmt_cache_use= 0, binlog_stmt_cache_disk_use= 0;
unknown's avatar
unknown committed
517
ulong max_connections, max_connect_errors;
518
ulong extra_max_connections;
519
ulong slave_retried_transactions;
520
ulong feature_files_opened_with_delayed_keys;
521
ulonglong denied_connections;
Sergei Golubchik's avatar
Sergei Golubchik committed
522
my_decimal decimal_zero;
Sergei Golubchik's avatar
Sergei Golubchik committed
523

524 525 526 527 528
/*
  Maximum length of parameter value which can be set through
  mysql_send_long_data() call.
*/
ulong max_long_data_size;
Sergei Golubchik's avatar
Sergei Golubchik committed
529

530 531 532 533
/* Limits for internal temporary tables (MyISAM or Aria) */
uint internal_tmp_table_max_key_length;
uint internal_tmp_table_max_key_segments;

534
bool max_user_connections_checking=0;
unknown's avatar
unknown committed
535
/**
536 537 538 539
  Limit of the total number of prepared statements in the server.
  Is necessary to protect the server against out-of-memory attacks.
*/
ulong max_prepared_stmt_count;
unknown's avatar
unknown committed
540
/**
541 542 543 544 545 546 547 548 549 550
  Current total number of prepared statements in the server. This number
  is exact, and therefore may not be equal to the difference between
  `com_stmt_prepare' and `com_stmt_close' (global status variables), as
  the latter ones account for all registered attempts to prepare
  a statement (including unsuccessful ones).  Prepared statements are
  currently connection-local: if the same SQL query text is prepared in
  two different connections, this counts as two distinct prepared
  statements.
*/
ulong prepared_stmt_count=0;
unknown's avatar
unknown committed
551
ulong thread_id=1L,current_pid;
552
ulong slow_launch_threads = 0;
553 554
uint sync_binlog_period= 0, sync_relaylog_period= 0,
     sync_relayloginfo_period= 0, sync_masterinfo_period= 0;
unknown's avatar
unknown committed
555
ulong expire_logs_days = 0;
unknown's avatar
unknown committed
556
ulong rpl_recovery_rank=0;
557 558 559 560 561
/**
  Soft upper limit for number of sp_head objects that can be stored
  in the sp_cache for one connection.
*/
ulong stored_program_cache_size= 0;
unknown's avatar
unknown committed
562

563
ulong opt_slave_parallel_threads= 0;
unknown's avatar
unknown committed
564
ulong opt_slave_domain_parallel_threads= 0;
565 566
ulonglong opt_slave_parallel_mode=
  SLAVE_PARALLEL_DOMAIN | SLAVE_PARALLEL_FOLLOW_MASTER_COMMIT;
567 568
ulong opt_binlog_commit_wait_count= 0;
ulong opt_binlog_commit_wait_usec= 0;
unknown's avatar
unknown committed
569
ulong opt_slave_parallel_max_queued= 131072;
570
my_bool opt_gtid_ignore_duplicates= FALSE;
571

572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604
const double log_10[] = {
  1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007, 1e008, 1e009,
  1e010, 1e011, 1e012, 1e013, 1e014, 1e015, 1e016, 1e017, 1e018, 1e019,
  1e020, 1e021, 1e022, 1e023, 1e024, 1e025, 1e026, 1e027, 1e028, 1e029,
  1e030, 1e031, 1e032, 1e033, 1e034, 1e035, 1e036, 1e037, 1e038, 1e039,
  1e040, 1e041, 1e042, 1e043, 1e044, 1e045, 1e046, 1e047, 1e048, 1e049,
  1e050, 1e051, 1e052, 1e053, 1e054, 1e055, 1e056, 1e057, 1e058, 1e059,
  1e060, 1e061, 1e062, 1e063, 1e064, 1e065, 1e066, 1e067, 1e068, 1e069,
  1e070, 1e071, 1e072, 1e073, 1e074, 1e075, 1e076, 1e077, 1e078, 1e079,
  1e080, 1e081, 1e082, 1e083, 1e084, 1e085, 1e086, 1e087, 1e088, 1e089,
  1e090, 1e091, 1e092, 1e093, 1e094, 1e095, 1e096, 1e097, 1e098, 1e099,
  1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109,
  1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119,
  1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129,
  1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139,
  1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149,
  1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159,
  1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169,
  1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179,
  1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189,
  1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199,
  1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209,
  1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219,
  1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229,
  1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239,
  1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249,
  1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259,
  1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269,
  1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279,
  1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289,
  1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299,
  1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308
};
unknown's avatar
unknown committed
605

606
time_t server_start_time, flush_status_time;
607

608 609
char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
char *default_tz_name;
610
char log_error_file[FN_REFLEN], glob_hostname[FN_REFLEN], *opt_log_basename;
unknown's avatar
unknown committed
611
char mysql_real_data_home[FN_REFLEN],
612 613
     lc_messages_dir[FN_REFLEN], reg_ext[FN_EXTLEN],
     mysql_charsets_dir[FN_REFLEN],
614
     *opt_init_file, *opt_tc_log_file;
615
char *lc_messages_dir_ptr= lc_messages_dir, *log_error_file_ptr;
616
char mysql_unpacked_real_data_home[FN_REFLEN];
617
int mysql_unpacked_real_data_home_len;
618
uint mysql_real_data_home_len, mysql_data_home_len= 1;
619
uint reg_ext_length;
620 621 622
const key_map key_map_empty(0);
key_map key_map_full(0);                        // Will be initialized later

623 624
DATE_TIME_FORMAT global_date_format, global_datetime_format, global_time_format;
Time_zone *default_tz;
625

626
const char *mysql_real_data_home_ptr= mysql_real_data_home;
627
char server_version[SERVER_VERSION_LENGTH];
628
char *mysqld_unix_port, *opt_mysql_tmpdir;
Georgi Kodinov's avatar
merge  
Georgi Kodinov committed
629
ulong thread_handling;
630

631
/** name of reference on left expression in rewritten IN subquery */
632
const char *in_left_expr_name= "<left expr>";
unknown's avatar
unknown committed
633
/** name of additional condition */
634
const char *in_additional_cond= "<IN COND>";
635 636
const char *in_having_cond= "<IN HAVING>";

unknown's avatar
unknown committed
637 638 639 640 641 642 643 644 645 646 647 648 649
/** Number of connection errors when selecting on the listening port */
ulong connection_errors_select= 0;
/** Number of connection errors when accepting sockets in the listening port. */
ulong connection_errors_accept= 0;
/** Number of connection errors from TCP wrappers. */
ulong connection_errors_tcpwrap= 0;
/** Number of connection errors from internal server errors. */
ulong connection_errors_internal= 0;
/** Number of connection errors from the server max_connection limit. */
ulong connection_errors_max_connection= 0;
/** Number of errors when reading the peer address. */
ulong connection_errors_peer_addr= 0;

unknown's avatar
unknown committed
650 651 652 653 654 655 656 657
/* classes for comparation parsing/processing */
Eq_creator eq_creator;
Ne_creator ne_creator;
Gt_creator gt_creator;
Lt_creator lt_creator;
Ge_creator ge_creator;
Le_creator le_creator;

Marc Alff's avatar
Marc Alff committed
658
MYSQL_FILE *bootstrap_file;
unknown's avatar
Merge  
unknown committed
659
int bootstrap_error;
unknown's avatar
unknown committed
660

unknown's avatar
unknown committed
661
I_List<THD> threads;
662 663
Rpl_filter* cur_rpl_filter;
Rpl_filter* global_rpl_filter;
unknown's avatar
unknown committed
664
Rpl_filter* binlog_filter;
unknown's avatar
unknown committed
665

666 667 668 669 670 671 672 673 674 675 676 677 678 679 680
THD *first_global_thread()
{
  if (threads.is_empty())
    return NULL;
  return threads.head();
}

THD *next_global_thread(THD *thd)
{
  if (threads.is_last(thd))
    return NULL;
  struct ilink *next= thd->next;
  return static_cast<THD*>(next);
}

unknown's avatar
unknown committed
681 682
struct system_variables global_system_variables;
struct system_variables max_system_variables;
unknown's avatar
Merge  
unknown committed
683
struct system_status_var global_status_var;
unknown's avatar
unknown committed
684

unknown's avatar
unknown committed
685
MY_TMPDIR mysql_tmpdir_list;
686
MY_BITMAP temp_pool;
unknown's avatar
unknown committed
687

688 689
CHARSET_INFO *system_charset_info, *files_charset_info ;
CHARSET_INFO *national_charset_info, *table_alias_charset;
unknown's avatar
unknown committed
690
CHARSET_INFO *character_set_filesystem;
Marc Alff's avatar
Marc Alff committed
691
CHARSET_INFO *error_message_charset_info;
692

693
MY_LOCALE *my_default_lc_messages;
694 695
MY_LOCALE *my_default_lc_time_names;

696
SHOW_COMP_OPTION have_ssl, have_symlink, have_dlopen, have_query_cache;
697
SHOW_COMP_OPTION have_geometry, have_rtree_keys;
unknown's avatar
unknown committed
698
SHOW_COMP_OPTION have_crypt, have_compress;
699
SHOW_COMP_OPTION have_profiling;
700
SHOW_COMP_OPTION have_openssl;
unknown's avatar
unknown committed
701 702

/* Thread specific variables */
703

unknown's avatar
unknown committed
704
pthread_key(MEM_ROOT**,THR_MALLOC);
unknown's avatar
unknown committed
705
pthread_key(THD*, THR_THD);
Michael Widenius's avatar
Michael Widenius committed
706
mysql_mutex_t LOCK_thread_count, LOCK_thread_cache;
707
mysql_mutex_t
708
  LOCK_status, LOCK_show_status, LOCK_error_log, LOCK_short_uuid_generator,
Marc Alff's avatar
Marc Alff committed
709 710 711 712
  LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
  LOCK_crypt,
  LOCK_global_system_variables,
  LOCK_user_conn, LOCK_slave_list, LOCK_active_mi,
713
  LOCK_connection_count, LOCK_error_messages, LOCK_slave_init;
Sergei Golubchik's avatar
Sergei Golubchik committed
714 715 716

mysql_mutex_t LOCK_stats, LOCK_global_user_client_stats,
              LOCK_global_table_stats, LOCK_global_index_stats;
717

unknown's avatar
unknown committed
718
/**
719 720 721 722 723 724
  The below lock protects access to two global server variables:
  max_prepared_stmt_count and prepared_stmt_count. These variables
  set the limit and hold the current total number of prepared statements
  in the server, respectively. As PREPARE/DEALLOCATE rate in a loaded
  server may be fairly high, we need a dedicated lock.
*/
Marc Alff's avatar
Marc Alff committed
725
mysql_mutex_t LOCK_prepared_stmt_count;
726
#ifdef HAVE_OPENSSL
Marc Alff's avatar
Marc Alff committed
727
mysql_mutex_t LOCK_des_key_file;
728
#endif
Marc Alff's avatar
Marc Alff committed
729 730
mysql_rwlock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
mysql_rwlock_t LOCK_system_variables_hash;
Marc Alff's avatar
Marc Alff committed
731
mysql_cond_t COND_thread_count;
unknown's avatar
unknown committed
732 733
pthread_t signal_thread;
pthread_attr_t connection_attrib;
Marc Alff's avatar
Marc Alff committed
734 735
mysql_mutex_t LOCK_server_started;
mysql_cond_t COND_server_started;
unknown's avatar
unknown committed
736

737
int mysqld_server_started=0, mysqld_server_initialized= 0;
738 739
File_parser_dummy_hook file_parser_dummy_hook;

unknown's avatar
unknown committed
740
/* replication parameters, if master_host is not NULL, we are a slave */
741
uint report_port= 0;
unknown's avatar
unknown committed
742
ulong master_retry_count=0;
743
char *master_info_file;
unknown's avatar
unknown committed
744
char *relay_log_info_file, *report_user, *report_password, *report_host;
unknown's avatar
unknown committed
745
char *opt_relay_logname = 0, *opt_relaylog_index_name=0;
746
char *opt_logname, *opt_slow_logname, *opt_bin_logname;
unknown's avatar
unknown committed
747 748 749

/* Static variables */

750
static volatile sig_atomic_t kill_in_progress;
Michael Widenius's avatar
Michael Widenius committed
751
my_bool opt_stack_trace;
752 753
my_bool opt_expect_abort= 0, opt_bootstrap= 0;
static my_bool opt_myisam_log;
unknown's avatar
unknown committed
754
static int cleanup_done;
755
static ulong opt_specialflag;
Sergei Golubchik's avatar
Sergei Golubchik committed
756
static char *opt_binlog_index_name;
757
char *mysql_home_ptr, *pidfile_name_ptr;
Marc Alff's avatar
Marc Alff committed
758
/** Initial command line arguments (count), after load_defaults().*/
unknown's avatar
unknown committed
759
static int defaults_argc;
Marc Alff's avatar
Marc Alff committed
760 761 762 763 764 765 766 767
/**
  Initial command line arguments (arguments), after load_defaults().
  This memory is allocated by @c load_defaults() and should be freed
  using @c free_defaults().
  Do not modify defaults_argc / defaults_argv,
  use remaining_argc / remaining_argv instead to parse the command
  line arguments in multiple steps.
*/
unknown's avatar
unknown committed
768
static char **defaults_argv;
Marc Alff's avatar
Marc Alff committed
769 770 771 772
/** Remaining command line arguments (count), filtered by handle_options().*/
static int remaining_argc;
/** Remaining command line arguments (arguments), filtered by handle_options().*/
static char **remaining_argv;
unknown's avatar
unknown committed
773

774 775 776
int orig_argc;
char **orig_argv;

777
static struct my_option pfs_early_options[]=
778
{
779
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843
  {"performance_schema_instrument", OPT_PFS_INSTRUMENT,
    "Default startup value for a performance schema instrument.",
    &pfs_param.m_pfs_instrument, &pfs_param.m_pfs_instrument, 0, GET_STR,
    OPT_ARG, 0, 0, 0, 0, 0, 0},
  {"performance_schema_consumer_events_stages_current", 0,
    "Default startup value for the events_stages_current consumer.",
    &pfs_param.m_consumer_events_stages_current_enabled,
    &pfs_param.m_consumer_events_stages_current_enabled, 0, GET_BOOL,
    OPT_ARG, FALSE, 0, 0, 0, 0, 0},
  {"performance_schema_consumer_events_stages_history", 0,
    "Default startup value for the events_stages_history consumer.",
    &pfs_param.m_consumer_events_stages_history_enabled,
    &pfs_param.m_consumer_events_stages_history_enabled, 0,
    GET_BOOL, OPT_ARG, FALSE, 0, 0, 0, 0, 0},
  {"performance_schema_consumer_events_stages_history_long", 0,
    "Default startup value for the events_stages_history_long consumer.",
    &pfs_param.m_consumer_events_stages_history_long_enabled,
    &pfs_param.m_consumer_events_stages_history_long_enabled, 0,
    GET_BOOL, OPT_ARG, FALSE, 0, 0, 0, 0, 0},
  {"performance_schema_consumer_events_statements_current", 0,
    "Default startup value for the events_statements_current consumer.",
    &pfs_param.m_consumer_events_statements_current_enabled,
    &pfs_param.m_consumer_events_statements_current_enabled, 0,
    GET_BOOL, OPT_ARG, TRUE, 0, 0, 0, 0, 0},
  {"performance_schema_consumer_events_statements_history", 0,
    "Default startup value for the events_statements_history consumer.",
    &pfs_param.m_consumer_events_statements_history_enabled,
    &pfs_param.m_consumer_events_statements_history_enabled, 0,
    GET_BOOL, OPT_ARG, FALSE, 0, 0, 0, 0, 0},
  {"performance_schema_consumer_events_statements_history_long", 0,
    "Default startup value for the events_statements_history_long consumer.",
    &pfs_param.m_consumer_events_statements_history_long_enabled,
    &pfs_param.m_consumer_events_statements_history_long_enabled, 0,
    GET_BOOL, OPT_ARG, FALSE, 0, 0, 0, 0, 0},
  {"performance_schema_consumer_events_waits_current", 0,
    "Default startup value for the events_waits_current consumer.",
    &pfs_param.m_consumer_events_waits_current_enabled,
    &pfs_param.m_consumer_events_waits_current_enabled, 0,
    GET_BOOL, OPT_ARG, FALSE, 0, 0, 0, 0, 0},
  {"performance_schema_consumer_events_waits_history", 0,
    "Default startup value for the events_waits_history consumer.",
    &pfs_param.m_consumer_events_waits_history_enabled,
    &pfs_param.m_consumer_events_waits_history_enabled, 0,
    GET_BOOL, OPT_ARG, FALSE, 0, 0, 0, 0, 0},
  {"performance_schema_consumer_events_waits_history_long", 0,
    "Default startup value for the events_waits_history_long consumer.",
    &pfs_param.m_consumer_events_waits_history_long_enabled,
    &pfs_param.m_consumer_events_waits_history_long_enabled, 0,
    GET_BOOL, OPT_ARG, FALSE, 0, 0, 0, 0, 0},
  {"performance_schema_consumer_global_instrumentation", 0,
    "Default startup value for the global_instrumentation consumer.",
    &pfs_param.m_consumer_global_instrumentation_enabled,
    &pfs_param.m_consumer_global_instrumentation_enabled, 0,
    GET_BOOL, OPT_ARG, TRUE, 0, 0, 0, 0, 0},
  {"performance_schema_consumer_thread_instrumentation", 0,
    "Default startup value for the thread_instrumentation consumer.",
    &pfs_param.m_consumer_thread_instrumentation_enabled,
    &pfs_param.m_consumer_thread_instrumentation_enabled, 0,
    GET_BOOL, OPT_ARG, TRUE, 0, 0, 0, 0, 0},
  {"performance_schema_consumer_statements_digest", 0,
    "Default startup value for the statements_digest consumer.",
    &pfs_param.m_consumer_statement_digest_enabled,
    &pfs_param.m_consumer_statement_digest_enabled, 0,
    GET_BOOL, OPT_ARG, TRUE, 0, 0, 0, 0, 0}
844
#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
845 846
};

847 848
#ifdef HAVE_PSI_INTERFACE
#ifdef HAVE_MMAP
849 850
PSI_mutex_key key_PAGE_lock, key_LOCK_sync, key_LOCK_active, key_LOCK_pool,
  key_LOCK_pending_checkpoint;
851 852 853 854 855 856
#endif /* HAVE_MMAP */

#ifdef HAVE_OPENSSL
PSI_mutex_key key_LOCK_des_key_file;
#endif /* HAVE_OPENSSL */

857
PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list,
858
  key_BINLOG_LOCK_binlog_background_thread,
859
  m_key_LOCK_binlog_end_pos,
860 861 862 863 864 865
  key_delayed_insert_mutex, key_hash_filo_lock, key_LOCK_active_mi,
  key_LOCK_connection_count, key_LOCK_crypt, key_LOCK_delayed_create,
  key_LOCK_delayed_insert, key_LOCK_delayed_status, key_LOCK_error_log,
  key_LOCK_gdl, key_LOCK_global_system_variables,
  key_LOCK_manager,
  key_LOCK_prepared_stmt_count,
866 867
  key_LOCK_rpl_status, key_LOCK_server_started,
  key_LOCK_status, key_LOCK_show_status,
868
  key_LOCK_system_variables_hash, key_LOCK_thd_data,
869 870
  key_LOCK_user_conn, key_LOCK_uuid_short_generator, key_LOG_LOCK_log,
  key_master_info_data_lock, key_master_info_run_lock,
Sergei Golubchik's avatar
Sergei Golubchik committed
871
  key_master_info_sleep_lock,
872
  key_mutex_slave_reporting_capability_err_lock, key_relay_log_info_data_lock,
Michael Widenius's avatar
Michael Widenius committed
873
  key_rpl_group_info_sleep_lock,
874
  key_relay_log_info_log_space_lock, key_relay_log_info_run_lock,
875
  key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data,
Michael Widenius's avatar
Michael Widenius committed
876 877
  key_LOCK_error_messages, key_LOG_INFO_lock,
  key_LOCK_thread_count, key_LOCK_thread_cache,
878 879
  key_PARTITION_LOCK_auto_inc;
PSI_mutex_key key_RELAYLOG_LOCK_index;
880
PSI_mutex_key key_LOCK_slave_state, key_LOCK_binlog_state,
881
  key_LOCK_rpl_thread, key_LOCK_rpl_thread_pool, key_LOCK_parallel_entry;
882 883 884

PSI_mutex_key key_LOCK_stats,
  key_LOCK_global_user_client_stats, key_LOCK_global_table_stats,
Sergei Golubchik's avatar
Sergei Golubchik committed
885
  key_LOCK_global_index_stats,
886
  key_LOCK_wakeup_ready, key_LOCK_wait_commit;
887
PSI_mutex_key key_LOCK_gtid_waiting;
Sergei Golubchik's avatar
Sergei Golubchik committed
888

889
PSI_mutex_key key_LOCK_after_binlog_sync;
890
PSI_mutex_key key_LOCK_prepare_ordered, key_LOCK_commit_ordered,
891
  key_LOCK_slave_init;
Sergei Golubchik's avatar
Sergei Golubchik committed
892
PSI_mutex_key key_TABLE_SHARE_LOCK_share;
893 894 895 896 897 898 899 900

static PSI_mutex_info all_server_mutexes[]=
{
#ifdef HAVE_MMAP
  { &key_PAGE_lock, "PAGE::lock", 0},
  { &key_LOCK_sync, "TC_LOG_MMAP::LOCK_sync", 0},
  { &key_LOCK_active, "TC_LOG_MMAP::LOCK_active", 0},
  { &key_LOCK_pool, "TC_LOG_MMAP::LOCK_pool", 0},
901
  { &key_LOCK_pool, "TC_LOG_MMAP::LOCK_pending_checkpoint", 0},
902 903 904 905 906 907 908
#endif /* HAVE_MMAP */

#ifdef HAVE_OPENSSL
  { &key_LOCK_des_key_file, "LOCK_des_key_file", PSI_FLAG_GLOBAL},
#endif /* HAVE_OPENSSL */

  { &key_BINLOG_LOCK_index, "MYSQL_BIN_LOG::LOCK_index", 0},
909
  { &key_BINLOG_LOCK_xid_list, "MYSQL_BIN_LOG::LOCK_xid_list", 0},
910
  { &key_BINLOG_LOCK_binlog_background_thread, "MYSQL_BIN_LOG::LOCK_binlog_background_thread", 0},
911
  { &m_key_LOCK_binlog_end_pos, "MYSQL_BIN_LOG::LOCK_binlog_end_pos", 0 },
912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928
  { &key_RELAYLOG_LOCK_index, "MYSQL_RELAY_LOG::LOCK_index", 0},
  { &key_delayed_insert_mutex, "Delayed_insert::mutex", 0},
  { &key_hash_filo_lock, "hash_filo::lock", 0},
  { &key_LOCK_active_mi, "LOCK_active_mi", PSI_FLAG_GLOBAL},
  { &key_LOCK_connection_count, "LOCK_connection_count", PSI_FLAG_GLOBAL},
  { &key_LOCK_crypt, "LOCK_crypt", PSI_FLAG_GLOBAL},
  { &key_LOCK_delayed_create, "LOCK_delayed_create", PSI_FLAG_GLOBAL},
  { &key_LOCK_delayed_insert, "LOCK_delayed_insert", PSI_FLAG_GLOBAL},
  { &key_LOCK_delayed_status, "LOCK_delayed_status", PSI_FLAG_GLOBAL},
  { &key_LOCK_error_log, "LOCK_error_log", PSI_FLAG_GLOBAL},
  { &key_LOCK_gdl, "LOCK_gdl", PSI_FLAG_GLOBAL},
  { &key_LOCK_global_system_variables, "LOCK_global_system_variables", PSI_FLAG_GLOBAL},
  { &key_LOCK_manager, "LOCK_manager", PSI_FLAG_GLOBAL},
  { &key_LOCK_prepared_stmt_count, "LOCK_prepared_stmt_count", PSI_FLAG_GLOBAL},
  { &key_LOCK_rpl_status, "LOCK_rpl_status", PSI_FLAG_GLOBAL},
  { &key_LOCK_server_started, "LOCK_server_started", PSI_FLAG_GLOBAL},
  { &key_LOCK_status, "LOCK_status", PSI_FLAG_GLOBAL},
929
  { &key_LOCK_show_status, "LOCK_show_status", PSI_FLAG_GLOBAL},
930 931 932 933 934
  { &key_LOCK_system_variables_hash, "LOCK_system_variables_hash", PSI_FLAG_GLOBAL},
  { &key_LOCK_stats, "LOCK_stats", PSI_FLAG_GLOBAL},
  { &key_LOCK_global_user_client_stats, "LOCK_global_user_client_stats", PSI_FLAG_GLOBAL},
  { &key_LOCK_global_table_stats, "LOCK_global_table_stats", PSI_FLAG_GLOBAL},
  { &key_LOCK_global_index_stats, "LOCK_global_index_stats", PSI_FLAG_GLOBAL},
Sergei Golubchik's avatar
Sergei Golubchik committed
935
  { &key_LOCK_wakeup_ready, "THD::LOCK_wakeup_ready", 0},
936
  { &key_LOCK_wait_commit, "wait_for_commit::LOCK_wait_commit", 0},
937
  { &key_LOCK_gtid_waiting, "gtid_waiting::LOCK_gtid_waiting", 0},
938 939
  { &key_LOCK_thd_data, "THD::LOCK_thd_data", 0},
  { &key_LOCK_user_conn, "LOCK_user_conn", PSI_FLAG_GLOBAL},
Sergei Golubchik's avatar
Sergei Golubchik committed
940
  { &key_LOCK_uuid_short_generator, "LOCK_uuid_short_generator", PSI_FLAG_GLOBAL},
941 942 943
  { &key_LOG_LOCK_log, "LOG::LOCK_log", 0},
  { &key_master_info_data_lock, "Master_info::data_lock", 0},
  { &key_master_info_run_lock, "Master_info::run_lock", 0},
Sergei Golubchik's avatar
Sergei Golubchik committed
944
  { &key_master_info_sleep_lock, "Master_info::sleep_lock", 0},
945 946 947 948
  { &key_mutex_slave_reporting_capability_err_lock, "Slave_reporting_capability::err_lock", 0},
  { &key_relay_log_info_data_lock, "Relay_log_info::data_lock", 0},
  { &key_relay_log_info_log_space_lock, "Relay_log_info::log_space_lock", 0},
  { &key_relay_log_info_run_lock, "Relay_log_info::run_lock", 0},
Michael Widenius's avatar
Michael Widenius committed
949
  { &key_rpl_group_info_sleep_lock, "Rpl_group_info::sleep_lock", 0},
950 951
  { &key_structure_guard_mutex, "Query_cache::structure_guard_mutex", 0},
  { &key_TABLE_SHARE_LOCK_ha_data, "TABLE_SHARE::LOCK_ha_data", 0},
Sergei Golubchik's avatar
Sergei Golubchik committed
952
  { &key_TABLE_SHARE_LOCK_share, "TABLE_SHARE::LOCK_share", 0},
953
  { &key_LOCK_error_messages, "LOCK_error_messages", PSI_FLAG_GLOBAL},
Sergei Golubchik's avatar
Sergei Golubchik committed
954
  { &key_LOCK_prepare_ordered, "LOCK_prepare_ordered", PSI_FLAG_GLOBAL},
955
  { &key_LOCK_after_binlog_sync, "LOCK_after_binlog_sync", PSI_FLAG_GLOBAL},
Sergei Golubchik's avatar
Sergei Golubchik committed
956
  { &key_LOCK_commit_ordered, "LOCK_commit_ordered", PSI_FLAG_GLOBAL},
957
  { &key_LOCK_slave_init, "LOCK_slave_init", PSI_FLAG_GLOBAL},
958 959
  { &key_LOG_INFO_lock, "LOG_INFO::lock", 0},
  { &key_LOCK_thread_count, "LOCK_thread_count", PSI_FLAG_GLOBAL},
Michael Widenius's avatar
Michael Widenius committed
960
  { &key_LOCK_thread_cache, "LOCK_thread_cache", PSI_FLAG_GLOBAL},
961
  { &key_PARTITION_LOCK_auto_inc, "HA_DATA_PARTITION::LOCK_auto_inc", 0},
unknown's avatar
unknown committed
962
  { &key_LOCK_slave_state, "LOCK_slave_state", 0},
963 964
  { &key_LOCK_binlog_state, "LOCK_binlog_state", 0},
  { &key_LOCK_rpl_thread, "LOCK_rpl_thread", 0},
965 966
  { &key_LOCK_rpl_thread_pool, "LOCK_rpl_thread_pool", 0},
  { &key_LOCK_parallel_entry, "LOCK_parallel_entry", 0}
967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986
};

PSI_rwlock_key key_rwlock_LOCK_grant, key_rwlock_LOCK_logger,
  key_rwlock_LOCK_sys_init_connect, key_rwlock_LOCK_sys_init_slave,
  key_rwlock_LOCK_system_variables_hash, key_rwlock_query_cache_query_lock;

static PSI_rwlock_info all_server_rwlocks[]=
{
#if defined (HAVE_OPENSSL) && !defined(HAVE_YASSL)
  { &key_rwlock_openssl, "CRYPTO_dynlock_value::lock", 0},
#endif
  { &key_rwlock_LOCK_grant, "LOCK_grant", PSI_FLAG_GLOBAL},
  { &key_rwlock_LOCK_logger, "LOGGER::LOCK_logger", 0},
  { &key_rwlock_LOCK_sys_init_connect, "LOCK_sys_init_connect", PSI_FLAG_GLOBAL},
  { &key_rwlock_LOCK_sys_init_slave, "LOCK_sys_init_slave", PSI_FLAG_GLOBAL},
  { &key_rwlock_LOCK_system_variables_hash, "LOCK_system_variables_hash", PSI_FLAG_GLOBAL},
  { &key_rwlock_query_cache_query_lock, "Query_cache_query::lock", 0}
};

#ifdef HAVE_MMAP
987
PSI_cond_key key_PAGE_cond, key_COND_active, key_COND_pool;
988 989
#endif /* HAVE_MMAP */

990
PSI_cond_key key_BINLOG_COND_xid_list, key_BINLOG_update_cond,
991 992
  key_BINLOG_COND_binlog_background_thread,
  key_BINLOG_COND_binlog_background_thread_end,
993 994 995 996 997
  key_COND_cache_status_changed, key_COND_manager,
  key_COND_rpl_status, key_COND_server_started,
  key_delayed_insert_cond, key_delayed_insert_cond_client,
  key_item_func_sleep_cond, key_master_info_data_cond,
  key_master_info_start_cond, key_master_info_stop_cond,
Sergei Golubchik's avatar
Sergei Golubchik committed
998
  key_master_info_sleep_cond,
999 1000
  key_relay_log_info_data_cond, key_relay_log_info_log_space_cond,
  key_relay_log_info_start_cond, key_relay_log_info_stop_cond,
Michael Widenius's avatar
Michael Widenius committed
1001
  key_rpl_group_info_sleep_cond,
1002
  key_TABLE_SHARE_cond, key_user_level_lock_cond,
1003 1004
  key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache,
  key_BINLOG_COND_queue_busy;
1005 1006
PSI_cond_key key_RELAYLOG_update_cond, key_COND_wakeup_ready,
  key_COND_wait_commit;
1007 1008
PSI_cond_key key_RELAYLOG_COND_queue_busy;
PSI_cond_key key_TC_LOG_MMAP_COND_queue_busy;
unknown's avatar
unknown committed
1009 1010 1011
PSI_cond_key key_COND_rpl_thread_queue, key_COND_rpl_thread,
  key_COND_rpl_thread_pool,
  key_COND_parallel_entry, key_COND_group_commit_orderer,
1012
  key_COND_prepare_ordered, key_COND_slave_init;
1013
PSI_cond_key key_COND_wait_gtid, key_COND_gtid_ignore_duplicates;
1014 1015 1016 1017 1018 1019 1020 1021 1022 1023

static PSI_cond_info all_server_conds[]=
{
#if (defined(_WIN32) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY)
  { &key_COND_handler_count, "COND_handler_count", PSI_FLAG_GLOBAL},
#endif /* _WIN32 || HAVE_SMEM && !EMBEDDED_LIBRARY */
#ifdef HAVE_MMAP
  { &key_PAGE_cond, "PAGE::cond", 0},
  { &key_COND_active, "TC_LOG_MMAP::COND_active", 0},
  { &key_COND_pool, "TC_LOG_MMAP::COND_pool", 0},
1024
  { &key_TC_LOG_MMAP_COND_queue_busy, "TC_LOG_MMAP::COND_queue_busy", 0},
1025
#endif /* HAVE_MMAP */
1026
  { &key_BINLOG_COND_xid_list, "MYSQL_BIN_LOG::COND_xid_list", 0},
1027
  { &key_BINLOG_update_cond, "MYSQL_BIN_LOG::update_cond", 0},
1028 1029
  { &key_BINLOG_COND_binlog_background_thread, "MYSQL_BIN_LOG::COND_binlog_background_thread", 0},
  { &key_BINLOG_COND_binlog_background_thread_end, "MYSQL_BIN_LOG::COND_binlog_background_thread_end", 0},
1030
  { &key_BINLOG_COND_queue_busy, "MYSQL_BIN_LOG::COND_queue_busy", 0},
1031
  { &key_RELAYLOG_update_cond, "MYSQL_RELAY_LOG::update_cond", 0},
1032
  { &key_RELAYLOG_COND_queue_busy, "MYSQL_RELAY_LOG::COND_queue_busy", 0},
Sergei Golubchik's avatar
Sergei Golubchik committed
1033
  { &key_COND_wakeup_ready, "THD::COND_wakeup_ready", 0},
1034
  { &key_COND_wait_commit, "wait_for_commit::COND_wait_commit", 0},
1035 1036 1037 1038 1039 1040 1041 1042 1043
  { &key_COND_cache_status_changed, "Query_cache::COND_cache_status_changed", 0},
  { &key_COND_manager, "COND_manager", PSI_FLAG_GLOBAL},
  { &key_COND_server_started, "COND_server_started", PSI_FLAG_GLOBAL},
  { &key_delayed_insert_cond, "Delayed_insert::cond", 0},
  { &key_delayed_insert_cond_client, "Delayed_insert::cond_client", 0},
  { &key_item_func_sleep_cond, "Item_func_sleep::cond", 0},
  { &key_master_info_data_cond, "Master_info::data_cond", 0},
  { &key_master_info_start_cond, "Master_info::start_cond", 0},
  { &key_master_info_stop_cond, "Master_info::stop_cond", 0},
Sergei Golubchik's avatar
Sergei Golubchik committed
1044
  { &key_master_info_sleep_cond, "Master_info::sleep_cond", 0},
1045 1046 1047 1048
  { &key_relay_log_info_data_cond, "Relay_log_info::data_cond", 0},
  { &key_relay_log_info_log_space_cond, "Relay_log_info::log_space_cond", 0},
  { &key_relay_log_info_start_cond, "Relay_log_info::start_cond", 0},
  { &key_relay_log_info_stop_cond, "Relay_log_info::stop_cond", 0},
Michael Widenius's avatar
Michael Widenius committed
1049
  { &key_rpl_group_info_sleep_cond, "Rpl_group_info::sleep_cond", 0},
1050 1051 1052 1053
  { &key_TABLE_SHARE_cond, "TABLE_SHARE::cond", 0},
  { &key_user_level_lock_cond, "User_level_lock::cond", 0},
  { &key_COND_thread_count, "COND_thread_count", PSI_FLAG_GLOBAL},
  { &key_COND_thread_cache, "COND_thread_cache", PSI_FLAG_GLOBAL},
1054 1055
  { &key_COND_flush_thread_cache, "COND_flush_thread_cache", PSI_FLAG_GLOBAL},
  { &key_COND_rpl_thread, "COND_rpl_thread", 0},
unknown's avatar
unknown committed
1056
  { &key_COND_rpl_thread_queue, "COND_rpl_thread_queue", 0},
1057
  { &key_COND_rpl_thread_pool, "COND_rpl_thread_pool", 0},
1058
  { &key_COND_parallel_entry, "COND_parallel_entry", 0},
unknown's avatar
unknown committed
1059
  { &key_COND_group_commit_orderer, "COND_group_commit_orderer", 0},
1060
  { &key_COND_prepare_ordered, "COND_prepare_ordered", 0},
1061
  { &key_COND_slave_init, "COND_slave_init", 0},
1062 1063
  { &key_COND_wait_gtid, "COND_wait_gtid", 0},
  { &key_COND_gtid_ignore_duplicates, "COND_gtid_ignore_duplicates", 0}
1064 1065 1066 1067
};

PSI_thread_key key_thread_bootstrap, key_thread_delayed_insert,
  key_thread_handle_manager, key_thread_main,
1068
  key_thread_one_connection, key_thread_signal_hand,
1069
  key_thread_slave_init, key_rpl_parallel_thread;
1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093

static PSI_thread_info all_server_threads[]=
{
#if (defined(_WIN32) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY)
  { &key_thread_handle_con_namedpipes, "con_named_pipes", PSI_FLAG_GLOBAL},
#endif /* _WIN32 || HAVE_SMEM && !EMBEDDED_LIBRARY */

#if defined(HAVE_SMEM) && !defined(EMBEDDED_LIBRARY)
  { &key_thread_handle_con_sharedmem, "con_shared_mem", PSI_FLAG_GLOBAL},
#endif /* HAVE_SMEM && !EMBEDDED_LIBRARY */

#if (defined(_WIN32) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY)
  { &key_thread_handle_con_sockets, "con_sockets", PSI_FLAG_GLOBAL},
#endif /* _WIN32 || HAVE_SMEM && !EMBEDDED_LIBRARY */

#ifdef __WIN__
  { &key_thread_handle_shutdown, "shutdown", PSI_FLAG_GLOBAL},
#endif /* __WIN__ */

  { &key_thread_bootstrap, "bootstrap", PSI_FLAG_GLOBAL},
  { &key_thread_delayed_insert, "delayed_insert", 0},
  { &key_thread_handle_manager, "manager", PSI_FLAG_GLOBAL},
  { &key_thread_main, "main", PSI_FLAG_GLOBAL},
  { &key_thread_one_connection, "one_connection", 0},
1094
  { &key_thread_signal_hand, "signal_handler", PSI_FLAG_GLOBAL},
1095 1096
  { &key_thread_slave_init, "slave_init", PSI_FLAG_GLOBAL},
  { &key_rpl_parallel_thread, "rpl_parallel_thread", 0}
1097 1098
};

1099 1100 1101 1102
#ifdef HAVE_MMAP
PSI_file_key key_file_map;
#endif /* HAVE_MMAP */

1103 1104 1105 1106 1107 1108 1109 1110 1111
PSI_file_key key_file_binlog, key_file_binlog_index, key_file_casetest,
  key_file_dbopt, key_file_des_key_file, key_file_ERRMSG, key_select_to_file,
  key_file_fileparser, key_file_frm, key_file_global_ddl_log, key_file_load,
  key_file_loadfile, key_file_log_event_data, key_file_log_event_info,
  key_file_master_info, key_file_misc, key_file_partition,
  key_file_pid, key_file_relay_log_info, key_file_send_file, key_file_tclog,
  key_file_trg, key_file_trn, key_file_init;
PSI_file_key key_file_query_log, key_file_slow_log;
PSI_file_key key_file_relaylog, key_file_relaylog_index;
1112
PSI_file_key key_file_binlog_state;
1113

1114
#endif /* HAVE_PSI_INTERFACE */
1115

1116 1117 1118 1119 1120 1121
#ifdef HAVE_PSI_STATEMENT_INTERFACE
PSI_statement_info stmt_info_new_packet;
#endif

#ifndef EMBEDDED_LIBRARY
void net_before_header_psi(struct st_net *net, void *user_data, size_t /* unused: count */)
1122
{
1123 1124 1125
  THD *thd;
  thd= static_cast<THD*> (user_data);
  DBUG_ASSERT(thd != NULL);
1126

1127 1128 1129 1130 1131 1132 1133 1134 1135
  /*
    We only come where when the server is IDLE, waiting for the next command.
    Technically, it is a wait on a socket, which may take a long time,
    because the call is blocking.
    Disable the socket instrumentation, to avoid recording a SOCKET event.
    Instead, start explicitly an IDLE event.
  */
  MYSQL_SOCKET_SET_STATE(net->vio->mysql_socket, PSI_SOCKET_STATE_IDLE);
  MYSQL_START_IDLE_WAIT(thd->m_idle_psi, &thd->m_idle_state);
1136
}
1137

1138 1139
void net_after_header_psi(struct st_net *net, void *user_data,
                          size_t /* unused: count */, my_bool rc)
1140 1141 1142 1143
{
  THD *thd;
  thd= static_cast<THD*> (user_data);
  DBUG_ASSERT(thd != NULL);
1144

1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156
  /*
    The server just got data for a network packet header,
    from the network layer.
    The IDLE event is now complete, since we now have a message to process.
    We need to:
    - start a new STATEMENT event
    - start a new STAGE event, within this statement,
    - start recording SOCKET WAITS events, within this stage.
    The proper order is critical to get events numbered correctly,
    and nested in the proper parent.
  */
  MYSQL_END_IDLE_WAIT(thd->m_idle_psi);
1157

1158
  if (! rc)
1159
  {
1160 1161 1162 1163
    thd->m_statement_psi= MYSQL_START_STATEMENT(&thd->m_statement_state,
                                                stmt_info_new_packet.m_key,
                                                thd->db, thd->db_length,
                                                thd->charset());
1164

1165
    THD_STAGE_INFO(thd, stage_init);
1166
  }
1167 1168 1169 1170 1171 1172

  /*
    TODO: consider recording a SOCKET event for the bytes just read,
    by also passing count here.
  */
  MYSQL_SOCKET_SET_STATE(net->vio->mysql_socket, PSI_SOCKET_STATE_ACTIVE);
1173 1174
}

1175

1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188
void init_net_server_extension(THD *thd)
{
  /* Start with a clean state for connection events. */
  thd->m_idle_psi= NULL;
  thd->m_statement_psi= NULL;
  /* Hook up the NET_SERVER callback in the net layer. */
  thd->m_net_server_extension.m_user_data= thd;
  thd->m_net_server_extension.m_before_header= net_before_header_psi;
  thd->m_net_server_extension.m_after_header= net_after_header_psi;
  /* Activate this private extension for the mysqld server. */
  thd->net.extension= & thd->m_net_server_extension;
}
#endif /* EMBEDDED_LIBRARY */
1189

Marc Alff's avatar
Marc Alff committed
1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241
/**
  A log message for the error log, buffered in memory.
  Log messages are temporarily buffered when generated before the error log
  is initialized, and then printed once the error log is ready.
*/
class Buffered_log : public Sql_alloc
{
public:
  Buffered_log(enum loglevel level, const char *message);

  ~Buffered_log()
  {}

  void print(void);

private:
  /** Log message level. */
  enum loglevel m_level;
  /** Log message text. */
  String m_message;
};

/**
  Constructor.
  @param level          the message log level
  @param message        the message text
*/
Buffered_log::Buffered_log(enum loglevel level, const char *message)
  : m_level(level), m_message()
{
  m_message.copy(message, strlen(message), &my_charset_latin1);
}

/**
  Print a buffered log to the real log file.
*/
void Buffered_log::print()
{
  /*
    Since messages are buffered, they can be printed out
    of order with other entries in the log.
    Add "Buffered xxx" to the message text to prevent confusion.
  */
  switch(m_level)
  {
  case ERROR_LEVEL:
    sql_print_error("Buffered error: %s\n", m_message.c_ptr_safe());
    break;
  case WARNING_LEVEL:
    sql_print_warning("Buffered warning: %s\n", m_message.c_ptr_safe());
    break;
  case INFORMATION_LEVEL:
1242 1243 1244 1245 1246 1247 1248 1249 1250
    /*
      Messages printed as "information" still end up in the mysqld *error* log,
      but with a [Note] tag instead of an [ERROR] tag.
      While this is probably fine for a human reading the log,
      it is upsetting existing automated scripts used to parse logs,
      because such scripts are likely to not already handle [Note] properly.
      INFORMATION_LEVEL messages are simply silenced, on purpose,
      to avoid un needed verbosity.
    */
Marc Alff's avatar
Marc Alff committed
1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285
    break;
  }
}

/**
  Collection of all the buffered log messages.
*/
class Buffered_logs
{
public:
  Buffered_logs()
  {}

  ~Buffered_logs()
  {}

  void init();
  void cleanup();

  void buffer(enum loglevel m_level, const char *msg);
  void print();
private:
  /**
    Memory root to use to store buffered logs.
    This memory root lifespan is between init and cleanup.
    Once the buffered logs are printed, they are not needed anymore,
    and all the memory used is reclaimed.
  */
  MEM_ROOT m_root;
  /** List of buffered log messages. */
  List<Buffered_log> m_list;
};

void Buffered_logs::init()
{
1286
  init_alloc_root(&m_root, 1024, 0, MYF(0));
Marc Alff's avatar
Marc Alff committed
1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324
}

void Buffered_logs::cleanup()
{
  m_list.delete_elements();
  free_root(&m_root, MYF(0));
}

/**
  Add a log message to the buffer.
*/
void Buffered_logs::buffer(enum loglevel level, const char *msg)
{
  /*
    Do not let Sql_alloc::operator new(size_t) allocate memory,
    there is no memory root associated with the main() thread.
    Give explicitly the proper memory root to use to
    Sql_alloc::operator new(size_t, MEM_ROOT *) instead.
  */
  Buffered_log *log= new (&m_root) Buffered_log(level, msg);
  if (log)
    m_list.push_back(log, &m_root);
}

/**
  Print buffered log messages.
*/
void Buffered_logs::print()
{
  Buffered_log *log;
  List_iterator_fast<Buffered_log> it(m_list);
  while ((log= it++))
    log->print();
}

/** Logs reported before a logger is available. */
static Buffered_logs buffered_logs;

1325 1326 1327
static MYSQL_SOCKET unix_sock, base_ip_sock, extra_ip_sock;
struct my_rnd_struct sql_rand; ///< used by sql_class.cc:THD::THD()

1328
#ifndef EMBEDDED_LIBRARY
Marc Alff's avatar
Marc Alff committed
1329 1330 1331 1332 1333
/**
  Error reporter that buffer log messages.
  @param level          log message level
  @param format         log message format string
*/
1334
C_MODE_START
1335 1336
static void buffered_option_error_reporter(enum loglevel level,
                                           const char *format, ...)
Marc Alff's avatar
Marc Alff committed
1337 1338 1339 1340 1341 1342 1343 1344 1345 1346
{
  va_list args;
  char buffer[1024];

  va_start(args, format);
  my_vsnprintf(buffer, sizeof(buffer), format, args);
  va_end(args);
  buffered_logs.buffer(level, buffer);
}

1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373

/**
  Character set and collation error reporter that prints to sql error log.
  @param level          log message level
  @param format         log message format string

  This routine is used to print character set and collation
  warnings and errors inside an already running mysqld server,
  e.g. when a character set or collation is requested for the very first time
  and its initialization does not go well for some reasons.

  Note: At early mysqld initialization stage,
  when error log is not yet available,
  we use buffered_option_error_reporter() instead,
  to print general character set subsystem initialization errors,
  such as Index.xml syntax problems, bad XML tag hierarchy, etc.
*/
static void charset_error_reporter(enum loglevel level,
                                   const char *format, ...)
{
  va_list args;
  va_start(args, format);
  vprint_msg_to_log(level, format, args);
  va_end(args);                      
}
C_MODE_END

unknown's avatar
unknown committed
1374 1375 1376 1377
struct passwd *user_info;
static pthread_t select_thread;
#endif

unknown's avatar
unknown committed
1378 1379
/* OS specific variables */

unknown's avatar
unknown committed
1380 1381 1382
#ifdef __WIN__
#undef	 getpid
#include <process.h>
unknown's avatar
unknown committed
1383

Marc Alff's avatar
Marc Alff committed
1384
static mysql_cond_t COND_handler_count;
unknown's avatar
unknown committed
1385 1386 1387 1388 1389
static uint handler_count;
static bool start_mode=0, use_opt_args;
static int opt_argc;
static char **opt_argv;

unknown's avatar
unknown committed
1390
#if !defined(EMBEDDED_LIBRARY)
unknown's avatar
unknown committed
1391
static HANDLE hEventShutdown;
1392
static char shutdown_event_name[40];
unknown's avatar
unknown committed
1393
#include "nt_servc.h"
unknown's avatar
unknown committed
1394
static	 NTService  Service;	      ///< Service object for WinNT
unknown's avatar
unknown committed
1395 1396 1397
#endif /* EMBEDDED_LIBRARY */
#endif /* __WIN__ */

Vladislav Vaintroub's avatar
Vladislav Vaintroub committed
1398
#ifdef _WIN32
1399
static char pipe_name[512];
unknown's avatar
unknown committed
1400 1401 1402
static SECURITY_ATTRIBUTES saPipeSecurity;
static SECURITY_DESCRIPTOR sdPipeDescriptor;
static HANDLE hPipe = INVALID_HANDLE_VALUE;
unknown's avatar
unknown committed
1403
#endif
unknown's avatar
unknown committed
1404

unknown's avatar
unknown committed
1405
#ifndef EMBEDDED_LIBRARY
1406
bool mysqld_embedded=0;
unknown's avatar
unknown committed
1407
#else
1408
bool mysqld_embedded=1;
unknown's avatar
unknown committed
1409 1410
#endif

1411
my_bool plugins_are_initialized= FALSE;
1412

unknown's avatar
unknown committed
1413
#ifndef DBUG_OFF
1414
static const char* default_dbug_option;
unknown's avatar
unknown committed
1415
#endif
1416
const char *current_dbug_option="";
unknown's avatar
unknown committed
1417
#ifdef HAVE_LIBWRAP
1418
const char *libwrapName= NULL;
1419 1420
int allow_severity = LOG_INFO;
int deny_severity = LOG_WARNING;
unknown's avatar
unknown committed
1421 1422 1423 1424 1425 1426 1427
#endif
#ifdef HAVE_QUERY_CACHE
ulong query_cache_min_res_unit= QUERY_CACHE_MIN_RESULT_DATA_SIZE;
Query_cache query_cache;
#endif
#ifdef HAVE_SMEM
char *shared_memory_base_name= default_shared_memory_base_name;
1428
my_bool opt_enable_shared_memory;
1429
HANDLE smem_event_connect_request= 0;
unknown's avatar
unknown committed
1430 1431
#endif

1432 1433
my_bool opt_use_ssl  = 0;
char *opt_ssl_ca= NULL, *opt_ssl_capath= NULL, *opt_ssl_cert= NULL,
1434 1435 1436
  *opt_ssl_cipher= NULL, *opt_ssl_key= NULL, *opt_ssl_crl= NULL,
  *opt_ssl_crlpath= NULL;

1437

Sergei Golubchik's avatar
Sergei Golubchik committed
1438 1439 1440
static scheduler_functions thread_scheduler_struct, extra_thread_scheduler_struct;
scheduler_functions *thread_scheduler= &thread_scheduler_struct,
                    *extra_thread_scheduler= &extra_thread_scheduler_struct;
unknown's avatar
unknown committed
1441

unknown's avatar
unknown committed
1442
#ifdef HAVE_OPENSSL
1443
#include <openssl/crypto.h>
unknown's avatar
unknown committed
1444
#ifndef HAVE_YASSL
1445 1446
typedef struct CRYPTO_dynlock_value
{
Marc Alff's avatar
Marc Alff committed
1447
  mysql_rwlock_t lock;
1448 1449 1450 1451 1452 1453 1454 1455
} openssl_lock_t;

static openssl_lock_t *openssl_stdlocks;
static openssl_lock_t *openssl_dynlock_create(const char *, int);
static void openssl_dynlock_destroy(openssl_lock_t *, const char *, int);
static void openssl_lock_function(int, int, const char *, int);
static void openssl_lock(int, openssl_lock_t *, const char *, int);
static unsigned long openssl_id_function();
unknown's avatar
unknown committed
1456
#endif
unknown's avatar
unknown committed
1457
char *des_key_file;
Konstantin Osipov's avatar
Konstantin Osipov committed
1458
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
1459
struct st_VioSSLFd *ssl_acceptor_fd;
Konstantin Osipov's avatar
Konstantin Osipov committed
1460
#endif
unknown's avatar
unknown committed
1461 1462
#endif /* HAVE_OPENSSL */

1463 1464 1465 1466
/**
  Number of currently active user connections. The variable is protected by
  LOCK_connection_count.
*/
1467
uint connection_count= 0, extra_connection_count= 0;
unknown's avatar
unknown committed
1468

1469
my_bool opt_gtid_strict_mode= FALSE;
1470 1471


unknown's avatar
unknown committed
1472 1473
/* Function declarations */

1474
pthread_handler_t signal_hand(void *arg);
1475
static int mysql_init_variables(void);
Marc Alff's avatar
Marc Alff committed
1476 1477
static int get_options(int *argc_ptr, char ***argv_ptr);
static bool add_terminator(DYNAMIC_ARRAY *options);
1478
static bool add_many_options(DYNAMIC_ARRAY *, my_option *, size_t);
1479
extern "C" my_bool mysqld_get_one_option(int, const struct my_option *, char *);
1480
static int init_thread_environment();
unknown's avatar
unknown committed
1481
static char *get_relative_path(const char *path);
1482
static int fix_paths(void);
1483 1484 1485 1486
void handle_connections_sockets();
#ifdef _WIN32
pthread_handler_t handle_connections_sockets_thread(void *arg);
#endif
1487
pthread_handler_t kill_server_thread(void *arg);
Marc Alff's avatar
Marc Alff committed
1488
static void bootstrap(MYSQL_FILE *file);
unknown's avatar
unknown committed
1489
static bool read_init_file(char *file_name);
Vladislav Vaintroub's avatar
Vladislav Vaintroub committed
1490
#ifdef _WIN32
1491
pthread_handler_t handle_connections_namedpipes(void *arg);
unknown's avatar
unknown committed
1492
#endif
1493
#ifdef HAVE_SMEM
1494
pthread_handler_t handle_connections_shared_memory(void *arg);
1495
#endif
1496
pthread_handler_t handle_slave(void *arg);
unknown's avatar
unknown committed
1497
static void clean_up(bool print_message);
1498 1499 1500
static int test_if_case_insensitive(const char *dir_name);

#ifndef EMBEDDED_LIBRARY
1501
static bool pid_file_created= false;
1502
static void usage(void);
1503 1504
static void start_signal_handler(void);
static void close_server_sock();
unknown's avatar
unknown committed
1505
static void clean_up_mutexes(void);
1506
static void wait_for_signal_thread_to_end(void);
1507
static void create_pid_file();
1508
static void mysqld_exit(int exit_code) __attribute__((noreturn));
1509
#endif
1510
static void delete_pid_file(myf flags);
Konstantin Osipov's avatar
Konstantin Osipov committed
1511
static void end_ssl();
1512

1513 1514

#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530
/****************************************************************************
** Code to end mysqld
****************************************************************************/

static void close_connections(void)
{
#ifdef EXTRA_DEBUG
  int count=0;
#endif
  DBUG_ENTER("close_connections");

  /* Clear thread cache */
  kill_cached_threads++;
  flush_thread_cache();

  /* kill connection thread */
1531
#if !defined(__WIN__)
unknown's avatar
unknown committed
1532 1533
  DBUG_PRINT("quit", ("waiting for select thread: 0x%lx",
                      (ulong) select_thread));
Marc Alff's avatar
Marc Alff committed
1534
  mysql_mutex_lock(&LOCK_thread_count);
unknown's avatar
unknown committed
1535 1536 1537 1538 1539 1540

  while (select_thread_in_use)
  {
    struct timespec abstime;
    int error;
    LINT_INIT(error);
unknown's avatar
unknown committed
1541
    DBUG_PRINT("info",("Waiting for select thread"));
1542

unknown's avatar
unknown committed
1543
#ifndef DONT_USE_THR_ALARM
1544
    if (pthread_kill(select_thread, thr_client_alarm))
unknown's avatar
unknown committed
1545 1546
      break;					// allready dead
#endif
1547
    set_timespec(abstime, 2);
1548
    for (uint tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
unknown's avatar
unknown committed
1549
    {
Marc Alff's avatar
Marc Alff committed
1550 1551
      error= mysql_cond_timedwait(&COND_thread_count, &LOCK_thread_count,
                                  &abstime);
unknown's avatar
unknown committed
1552 1553 1554 1555
      if (error != EINTR)
	break;
    }
#ifdef EXTRA_DEBUG
1556
    if (error != 0 && error != ETIMEDOUT && !count++)
Marc Alff's avatar
Marc Alff committed
1557
      sql_print_error("Got error %d from mysql_cond_timedwait", error);
unknown's avatar
unknown committed
1558
#endif
unknown's avatar
unknown committed
1559
    close_server_sock();
unknown's avatar
unknown committed
1560
  }
Marc Alff's avatar
Marc Alff committed
1561
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
1562 1563 1564 1565 1566
#endif /* __WIN__ */


  /* Abort listening to new connections */
  DBUG_PRINT("quit",("Closing sockets"));
unknown's avatar
Merge  
unknown committed
1567
  if (!opt_disable_networking )
unknown's avatar
unknown committed
1568
  {
1569
    if (mysql_socket_getfd(base_ip_sock) != INVALID_SOCKET)
unknown's avatar
unknown committed
1570
    {
Sergei Golubchik's avatar
c  
Sergei Golubchik committed
1571
      (void) mysql_socket_shutdown(base_ip_sock, SHUT_RDWR);
1572 1573
      (void) mysql_socket_close(base_ip_sock);
      base_ip_sock= MYSQL_INVALID_SOCKET;
1574
    }
1575
    if (mysql_socket_getfd(extra_ip_sock) != INVALID_SOCKET)
unknown's avatar
unknown committed
1576
    {
Sergei Golubchik's avatar
c  
Sergei Golubchik committed
1577
      (void) mysql_socket_shutdown(extra_ip_sock, SHUT_RDWR);
1578 1579
      (void) mysql_socket_close(extra_ip_sock);
      extra_ip_sock= MYSQL_INVALID_SOCKET;
unknown's avatar
unknown committed
1580 1581
    }
  }
Vladislav Vaintroub's avatar
Vladislav Vaintroub committed
1582
#ifdef _WIN32
unknown's avatar
unknown committed
1583
  if (hPipe != INVALID_HANDLE_VALUE && opt_enable_named_pipe)
unknown's avatar
unknown committed
1584
  {
unknown's avatar
merge  
unknown committed
1585
    HANDLE temp;
unknown's avatar
Merge  
unknown committed
1586
    DBUG_PRINT("quit", ("Closing named pipes") );
1587

unknown's avatar
merge  
unknown committed
1588
    /* Create connection to the handle named pipe handler to break the loop */
1589
    if ((temp = CreateFile(pipe_name,
unknown's avatar
merge  
unknown committed
1590 1591 1592 1593 1594 1595 1596
			   GENERIC_READ | GENERIC_WRITE,
			   0,
			   NULL,
			   OPEN_EXISTING,
			   0,
			   NULL )) != INVALID_HANDLE_VALUE)
    {
1597
      WaitNamedPipe(pipe_name, 1000);
unknown's avatar
merge  
unknown committed
1598 1599 1600 1601 1602 1603
      DWORD dwMode = PIPE_READMODE_BYTE | PIPE_WAIT;
      SetNamedPipeHandleState(temp, &dwMode, NULL, NULL);
      CancelIo(temp);
      DisconnectNamedPipe(temp);
      CloseHandle(temp);
    }
unknown's avatar
unknown committed
1604 1605 1606
  }
#endif
#ifdef HAVE_SYS_UN_H
1607
  if (mysql_socket_getfd(unix_sock) != INVALID_SOCKET)
unknown's avatar
unknown committed
1608
  {
Sergei Golubchik's avatar
c  
Sergei Golubchik committed
1609
    (void) mysql_socket_shutdown(unix_sock, SHUT_RDWR);
1610
    (void) mysql_socket_close(unix_sock);
1611
    (void) unlink(mysqld_unix_port);
1612
    unix_sock= MYSQL_INVALID_SOCKET;
unknown's avatar
unknown committed
1613 1614
  }
#endif
1615
  end_thr_alarm(0);			 // Abort old alarms.
unknown's avatar
unknown committed
1616

1617 1618 1619 1620 1621
  /*
    First signal all threads that it's time to die
    This will give the threads some time to gracefully abort their
    statements and inform their clients that the server is about to die.
  */
unknown's avatar
unknown committed
1622 1623

  THD *tmp;
Marc Alff's avatar
Marc Alff committed
1624
  mysql_mutex_lock(&LOCK_thread_count); // For unlink from list
unknown's avatar
unknown committed
1625 1626 1627 1628 1629 1630

  I_List_iterator<THD> it(threads);
  while ((tmp=it++))
  {
    DBUG_PRINT("quit",("Informing thread %ld that it's time to die",
		       tmp->thread_id));
1631
    /* We skip slave threads & scheduler on this first loop through. */
1632
    if (tmp->slave_thread)
1633
      continue;
1634

1635 1636 1637 1638 1639
#ifdef WITH_WSREP
    /* skip wsrep system threads as well */
    if (WSREP(tmp) && (tmp->wsrep_exec_mode==REPL_RECV || tmp->wsrep_applier))
      continue;
#endif
1640
    tmp->killed= KILL_SERVER_HARD;
Sergei Golubchik's avatar
Sergei Golubchik committed
1641
    MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (tmp));
1642
    mysql_mutex_lock(&tmp->LOCK_thd_data);
unknown's avatar
unknown committed
1643 1644 1645
    if (tmp->mysys_var)
    {
      tmp->mysys_var->abort=1;
Marc Alff's avatar
Marc Alff committed
1646
      mysql_mutex_lock(&tmp->mysys_var->mutex);
unknown's avatar
unknown committed
1647
      if (tmp->mysys_var->current_cond)
unknown's avatar
unknown committed
1648
      {
1649 1650 1651
        uint i;
        for (i=0; i < 2; i++)
        {
Sergei Golubchik's avatar
Sergei Golubchik committed
1652 1653
          int ret= mysql_mutex_trylock(tmp->mysys_var->current_mutex);
          mysql_cond_broadcast(tmp->mysys_var->current_cond);
1654 1655 1656
          if (!ret)
          {
            /* Thread has surely got the signal, unlock and abort */
Sergei Golubchik's avatar
Sergei Golubchik committed
1657
            mysql_mutex_unlock(tmp->mysys_var->current_mutex);
1658 1659 1660 1661
            break;
          }
          sleep(1);
        }
unknown's avatar
unknown committed
1662
      }
Marc Alff's avatar
Marc Alff committed
1663
      mysql_mutex_unlock(&tmp->mysys_var->mutex);
unknown's avatar
unknown committed
1664
    }
1665
    mysql_mutex_unlock(&tmp->LOCK_thd_data);
unknown's avatar
unknown committed
1666
  }
Marc Alff's avatar
Marc Alff committed
1667
  mysql_mutex_unlock(&LOCK_thread_count); // For unlink from list
unknown's avatar
unknown committed
1668

1669
  Events::deinit();
1670 1671
  end_slave();

1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686
  /*
    Give threads time to die.

    In 5.5, this was waiting 100 rounds @ 20 milliseconds/round, so as little
    as 2 seconds, depending on thread scheduling.

    From 10.0, we increase this to 1000 rounds / 20 seconds. The rationale is
    that on a server with heavy I/O load, it is quite possible for eg. an
    fsync() of the binlog or whatever to cause something like LOCK_log to be
    held for more than 2 seconds. We do not want to force kill threads in
    such cases, if it can be avoided. Note that normally, the wait will be
    much smaller than even 2 seconds, this is only a safety fallback against
    stuck threads so server shutdown is not held up forever.
  */
  for (int i= 0; *(volatile int32*) &thread_count && i < 1000; i++)
1687
    my_sleep(20000);
unknown's avatar
unknown committed
1688

1689 1690 1691 1692 1693
  /*
    Force remaining threads to die by closing the connection to the client
    This will ensure that threads that are waiting for a command from the
    client on a blocking read call are aborted.
  */
unknown's avatar
unknown committed
1694 1695 1696 1697

  for (;;)
  {
    DBUG_PRINT("quit",("Locking LOCK_thread_count"));
Marc Alff's avatar
Marc Alff committed
1698
    mysql_mutex_lock(&LOCK_thread_count); // For unlink from list
unknown's avatar
unknown committed
1699 1700 1701
    if (!(tmp=threads.get()))
    {
      DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
Marc Alff's avatar
Marc Alff committed
1702
      mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
1703 1704 1705
      break;
    }
#ifndef __bsdi__				// Bug in BSDI kernel
1706
    if (tmp->vio_ok())
unknown's avatar
unknown committed
1707
    {
1708
      if (global_system_variables.log_warnings)
1709
        sql_print_warning(ER_DEFAULT(ER_FORCING_CLOSE),my_progname,
1710
                          tmp->thread_id,
1711 1712
                          (tmp->main_security_ctx.user ?
                           tmp->main_security_ctx.user : ""));
Sergei Golubchik's avatar
Sergei Golubchik committed
1713
      close_connection(tmp,ER_SERVER_SHUTDOWN);
unknown's avatar
unknown committed
1714
    }
1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742
#endif
#ifdef WITH_WSREP
    /*
     * WSREP_TODO:
     *       this code block may turn out redundant. wsrep->disconnect()
     *       should terminate slave threads gracefully, and we don't need
     *       to signal them here. 
     *       The code here makes sure mysqld will not hang during shutdown
     *       even if wsrep provider has problems in shutting down.
     */
    if (WSREP(tmp) && tmp->wsrep_exec_mode==REPL_RECV)
    {
      sql_print_information("closing wsrep system thread");
      tmp->killed= KILL_CONNECTION;
      MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (tmp));
      if (tmp->mysys_var)
      {
        tmp->mysys_var->abort=1;
        mysql_mutex_lock(&tmp->mysys_var->mutex);
        if (tmp->mysys_var->current_cond)
        {
          mysql_mutex_lock(tmp->mysys_var->current_mutex);
          mysql_cond_broadcast(tmp->mysys_var->current_cond);
          mysql_mutex_unlock(tmp->mysys_var->current_mutex);
        }
        mysql_mutex_unlock(&tmp->mysys_var->mutex);
      }
    }
unknown's avatar
unknown committed
1743 1744
#endif
    DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
Marc Alff's avatar
Marc Alff committed
1745
    mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
1746 1747 1748
  }
  /* All threads has now been aborted */
  DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count));
Marc Alff's avatar
Marc Alff committed
1749
  mysql_mutex_lock(&LOCK_thread_count);
unknown's avatar
unknown committed
1750 1751
  while (thread_count)
  {
Marc Alff's avatar
Marc Alff committed
1752
    mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
unknown's avatar
unknown committed
1753 1754
    DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
  }
Marc Alff's avatar
Marc Alff committed
1755
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
1756 1757 1758 1759 1760

  DBUG_PRINT("quit",("close_connections thread"));
  DBUG_VOID_RETURN;
}

1761

1762
#ifdef HAVE_CLOSE_SERVER_SOCK
1763
static void close_socket(MYSQL_SOCKET sock, const char *info)
unknown's avatar
unknown committed
1764
{
1765 1766
  DBUG_ENTER("close_socket");

1767
  if (mysql_socket_getfd(sock) != INVALID_SOCKET)
unknown's avatar
unknown committed
1768
  {
1769
    DBUG_PRINT("info", ("calling shutdown on %s socket", info));
Sergei Golubchik's avatar
c  
Sergei Golubchik committed
1770
    (void) mysql_socket_shutdown(sock, SHUT_RDWR);
unknown's avatar
unknown committed
1771
  }
1772 1773
  DBUG_VOID_RETURN;
}
1774
#endif
1775 1776


1777
static void close_server_sock()
unknown's avatar
unknown committed
1778
{
1779
#ifdef HAVE_CLOSE_SERVER_SOCK
unknown's avatar
unknown committed
1780
  DBUG_ENTER("close_server_sock");
1781 1782 1783 1784 1785

  close_socket(base_ip_sock, "TCP/IP");
  close_socket(extra_ip_sock, "TCP/IP");
  close_socket(unix_sock, "unix/IP");

1786
  if (mysql_socket_getfd(unix_sock) != INVALID_SOCKET)
Konstantin Osipov's avatar
Konstantin Osipov committed
1787
    (void) unlink(mysqld_unix_port);
1788
  base_ip_sock= extra_ip_sock= unix_sock= MYSQL_INVALID_SOCKET;
Sergei Golubchik's avatar
Sergei Golubchik committed
1789

unknown's avatar
unknown committed
1790 1791
  DBUG_VOID_RETURN;
#endif
1792
}
unknown's avatar
unknown committed
1793

1794 1795
#endif /*EMBEDDED_LIBRARY*/

1796

unknown's avatar
unknown committed
1797 1798 1799 1800
void kill_mysql(void)
{
  DBUG_ENTER("kill_mysql");

1801
#if defined(SIGNALS_DONT_BREAK_READ) && !defined(EMBEDDED_LIBRARY)
1802 1803
  abort_loop=1;					// Break connection loops
  close_server_sock();				// Force accept to wake up
1804
#endif
unknown's avatar
unknown committed
1805

unknown's avatar
unknown committed
1806
#if defined(__WIN__)
unknown's avatar
unknown committed
1807
#if !defined(EMBEDDED_LIBRARY)
unknown's avatar
unknown committed
1808 1809 1810 1811 1812
  {
    if (!SetEvent(hEventShutdown))
    {
      DBUG_PRINT("error",("Got error: %ld from SetEvent",GetLastError()));
    }
1813 1814 1815 1816 1817 1818
    /*
      or:
      HANDLE hEvent=OpenEvent(0, FALSE, "MySqlShutdown");
      SetEvent(hEventShutdown);
      CloseHandle(hEvent);
    */
unknown's avatar
unknown committed
1819
  }
unknown's avatar
unknown committed
1820
#endif
unknown's avatar
unknown committed
1821
#elif defined(HAVE_PTHREAD_KILL)
1822
  if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL))
unknown's avatar
unknown committed
1823 1824 1825 1826
  {
    DBUG_PRINT("error",("Got error %d from pthread_kill",errno)); /* purecov: inspected */
  }
#elif !defined(SIGNALS_DONT_BREAK_READ)
1827
  kill(current_pid, MYSQL_KILL_SIGNAL);
unknown's avatar
unknown committed
1828
#endif
unknown's avatar
unknown committed
1829 1830 1831
  DBUG_PRINT("quit",("After pthread_kill"));
  shutdown_in_progress=1;			// Safety if kill didn't work
#ifdef SIGNALS_DONT_BREAK_READ
1832
  if (!kill_in_progress)
unknown's avatar
unknown committed
1833 1834
  {
    pthread_t tmp;
1835
    int error;
unknown's avatar
unknown committed
1836
    abort_loop=1;
1837 1838 1839 1840
    if ((error= mysql_thread_create(0, /* Not instrumented */
                                    &tmp, &connection_attrib,
                                    kill_server_thread, (void*) 0)))
      sql_print_error("Can't create thread to kill server (errno= %d).", error);
unknown's avatar
unknown committed
1841
  }
1842
#endif
unknown's avatar
unknown committed
1843
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
1844 1845
}

unknown's avatar
unknown committed
1846 1847
/**
  Force server down. Kill all connections and threads and exit.
1848

unknown's avatar
unknown committed
1849
  @param  sig_ptr       Signal number that caused kill_server to be called.
1850

unknown's avatar
unknown committed
1851
  @note
1852 1853 1854 1855
    A signal number of 0 mean that the function was not called
    from a signal handler and there is thus no signal to block
    or stop, we just want to kill the server.
*/
unknown's avatar
unknown committed
1856

1857
#if !defined(__WIN__)
unknown's avatar
unknown committed
1858
static void *kill_server(void *sig_ptr)
1859
#define RETURN_FROM_KILL_SERVER return 0
unknown's avatar
unknown committed
1860 1861
#else
static void __cdecl kill_server(int sig_ptr)
1862
#define RETURN_FROM_KILL_SERVER return
unknown's avatar
unknown committed
1863 1864 1865
#endif
{
  DBUG_ENTER("kill_server");
1866
#ifndef EMBEDDED_LIBRARY
unknown's avatar
Merge  
unknown committed
1867
  int sig=(int) (long) sig_ptr;			// This is passed a int
1868
  // if there is a signal during the kill in progress, ignore the other
unknown's avatar
unknown committed
1869
  if (kill_in_progress)				// Safety
1870 1871
  {
    DBUG_LEAVE;
unknown's avatar
unknown committed
1872
    RETURN_FROM_KILL_SERVER;
1873
  }
unknown's avatar
unknown committed
1874 1875
  kill_in_progress=TRUE;
  abort_loop=1;					// This should be set
1876
  if (sig != 0) // 0 is not a valid signal number
1877
    my_sigset(sig, SIG_IGN);                    /* purify inspected */
unknown's avatar
unknown committed
1878
  if (sig == MYSQL_KILL_SIGNAL || sig == 0)
1879
    sql_print_information(ER_DEFAULT(ER_NORMAL_SHUTDOWN),my_progname);
unknown's avatar
unknown committed
1880
  else
1881
    sql_print_error(ER_DEFAULT(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */
unknown's avatar
unknown committed
1882

Sergei Golubchik's avatar
Sergei Golubchik committed
1883
#ifdef HAVE_SMEM
1884
  /*
Sergei Golubchik's avatar
Sergei Golubchik committed
1885 1886
    Send event to smem_event_connect_request for aborting
  */
1887
  if (opt_enable_shared_memory)
1888
  {
1889 1890 1891 1892 1893 1894
    if (!SetEvent(smem_event_connect_request))
    {
      DBUG_PRINT("error",
                 ("Got error: %ld from SetEvent of smem_event_connect_request",
                  GetLastError()));
    }
1895 1896 1897
  }
#endif

1898 1899 1900
  if (WSREP_ON)
    wsrep_stop_replication(NULL);

unknown's avatar
unknown committed
1901
  close_connections();
1902 1903 1904 1905

  if (wsrep_inited == 1)
    wsrep_deinit(true);

1906 1907
  if (sig != MYSQL_KILL_SIGNAL &&
      sig != 0)
unknown's avatar
unknown committed
1908 1909
    unireg_abort(1);				/* purecov: inspected */
  else
1910
    unireg_end();
unknown's avatar
Merge  
unknown committed
1911

1912
  /* purecov: begin deadcode */
1913
  DBUG_LEAVE;                                   // Must match DBUG_ENTER()
1914
  my_thread_end();
1915 1916
  pthread_exit(0);
  /* purecov: end */
unknown's avatar
unknown committed
1917

1918 1919 1920 1921 1922
  RETURN_FROM_KILL_SERVER;                      // Avoid compiler warnings

#else /* EMBEDDED_LIBRARY*/

  DBUG_LEAVE;
unknown's avatar
unknown committed
1923
  RETURN_FROM_KILL_SERVER;
1924 1925

#endif /* EMBEDDED_LIBRARY */
unknown's avatar
unknown committed
1926 1927 1928
}


1929
#if defined(USE_ONE_SIGNAL_HAND)
1930
pthread_handler_t kill_server_thread(void *arg __attribute__((unused)))
unknown's avatar
unknown committed
1931 1932 1933
{
  my_thread_init();				// Initialize new thread
  kill_server(0);
1934 1935 1936
  /* purecov: begin deadcode */
  my_thread_end();
  pthread_exit(0);
unknown's avatar
unknown committed
1937
  return 0;
1938
  /* purecov: end */
unknown's avatar
unknown committed
1939 1940 1941
}
#endif

1942

1943
extern "C" sig_handler print_signal_warning(int sig)
unknown's avatar
unknown committed
1944
{
unknown's avatar
unknown committed
1945
  if (global_system_variables.log_warnings)
1946
    sql_print_warning("Got signal %d from thread %ld", sig,my_thread_id());
1947
#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY
1948
  my_sigset(sig,print_signal_warning);		/* int. thread system calls */
unknown's avatar
unknown committed
1949
#endif
1950
#if !defined(__WIN__)
unknown's avatar
unknown committed
1951 1952 1953 1954 1955
  if (sig == SIGALRM)
    alarm(2);					/* reschedule alarm */
#endif
}

unknown's avatar
unknown committed
1956
#ifndef EMBEDDED_LIBRARY
1957

1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969
static void init_error_log_mutex()
{
  mysql_mutex_init(key_LOCK_error_log, &LOCK_error_log, MY_MUTEX_INIT_FAST);
}


static void clean_up_error_log_mutex()
{
  mysql_mutex_destroy(&LOCK_error_log);
}


unknown's avatar
unknown committed
1970 1971
/**
  cleanup all memory and end program nicely.
unknown's avatar
unknown committed
1972

1973 1974 1975
    If SIGNALS_DONT_BREAK_READ is defined, this function is called
    by the main thread. To get MySQL to shut down nicely in this case
    (Mac OS X) we have to call exit() instead if pthread_exit().
unknown's avatar
unknown committed
1976

unknown's avatar
unknown committed
1977 1978 1979
  @note
    This function never returns.
*/
1980
void unireg_end(void)
unknown's avatar
unknown committed
1981
{
unknown's avatar
unknown committed
1982
  clean_up(1);
unknown's avatar
unknown committed
1983
  my_thread_end();
1984
#if defined(SIGNALS_DONT_BREAK_READ)
1985 1986
  exit(0);
#else
unknown's avatar
unknown committed
1987
  pthread_exit(0);				// Exit is in main thread
1988
#endif
unknown's avatar
unknown committed
1989 1990
}

1991

1992
extern "C" void unireg_abort(int exit_code)
unknown's avatar
unknown committed
1993
{
1994
  DBUG_ENTER("unireg_abort");
1995

1996 1997
  if (opt_help)
    usage();
unknown's avatar
unknown committed
1998 1999
  if (exit_code)
    sql_print_error("Aborting\n");
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012

#ifdef WITH_WSREP
  /* Check if wsrep class is used. If yes, then cleanup wsrep */
  if (wsrep)
  {
    /*
      This is an abort situation, we cannot expect to gracefully close all
      wsrep threads here, we can only diconnect from service
    */
    wsrep_close_client_connections(FALSE);
    shutdown_in_progress= 1;
    wsrep->disconnect(wsrep);
    WSREP_INFO("Service disconnected.");
2013
    wsrep_close_threads(NULL); /* this won't close all threads */
2014 2015 2016 2017 2018 2019 2020 2021 2022
    sleep(1); /* so give some time to exit for those which can */
    WSREP_INFO("Some threads may fail to exit.");

    /* In bootstrap mode we deinitialize wsrep here. */
    if (opt_bootstrap && wsrep_inited)
      wsrep_deinit(true);
  }
#endif // WITH_WSREP

2023
  clean_up(!opt_abort && (exit_code || !opt_bootstrap)); /* purecov: inspected */
2024
  DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
2025 2026 2027 2028 2029
  mysqld_exit(exit_code);
}

static void mysqld_exit(int exit_code)
{
2030
  DBUG_ENTER("mysqld_exit");
2031 2032 2033 2034 2035
  /*
    Important note: we wait for the signal thread to end,
    but if a kill -15 signal was sent, the signal thread did
    spawn the kill_server_thread thread, which is running concurrently.
  */
2036
  rpl_deinit_gtid_waiting();
2037
  rpl_deinit_gtid_slave_state();
2038
  wait_for_signal_thread_to_end();
2039
  mysql_audit_finalize();
unknown's avatar
unknown committed
2040
  clean_up_mutexes();
Marc Alff's avatar
Marc Alff committed
2041
  clean_up_error_log_mutex();
2042
  my_end((opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0));
2043
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
2044
  shutdown_performance_schema();        // we do it as late as possible
2045
#endif
2046
  DBUG_LEAVE;
unknown's avatar
unknown committed
2047 2048
  exit(exit_code); /* purecov: inspected */
}
2049

2050
#endif /* !EMBEDDED_LIBRARY */
unknown's avatar
unknown committed
2051

2052
void clean_up(bool print_message)
unknown's avatar
unknown committed
2053 2054 2055 2056
{
  DBUG_PRINT("exit",("clean_up"));
  if (cleanup_done++)
    return; /* purecov: inspected */
unknown's avatar
unknown committed
2057

2058 2059 2060 2061
#ifdef HAVE_REPLICATION
  // We must call end_slave() as clean_up may have been called during startup
  end_slave();
  if (use_slave_mask)
2062
    my_bitmap_free(&slave_error_mask);
2063
#endif
2064
  stop_handle_manager();
2065 2066
  release_ddl_log();

unknown's avatar
unknown committed
2067 2068
  logger.cleanup_base();

2069
  injector::free_instance();
unknown's avatar
unknown committed
2070 2071
  mysql_bin_log.cleanup();

2072
  my_tz_free();
2073
  my_dboptions_cache_free();
2074
  ignore_db_dirs_free();
unknown's avatar
unknown committed
2075
  servers_free(1);
2076
#ifndef NO_EMBEDDED_ACCESS_CHECKS
unknown's avatar
unknown committed
2077 2078
  acl_free(1);
  grant_free();
unknown's avatar
unknown committed
2079
#endif
unknown's avatar
unknown committed
2080
  query_cache_destroy();
unknown's avatar
unknown committed
2081
  hostname_cache_free();
2082
  item_func_sleep_free();
unknown's avatar
unknown committed
2083
  lex_free();				/* Free some memory */
2084
  item_create_cleanup();
unknown's avatar
unknown committed
2085
  if (!opt_noacl)
2086
  {
2087
#ifdef HAVE_DLOPEN
unknown's avatar
unknown committed
2088
    udf_free();
2089
#endif
2090
  }
2091
  tdc_start_shutdown();
2092
  plugin_shutdown();
2093
  ha_end();
unknown's avatar
Merge  
unknown committed
2094 2095
  if (tc_log)
    tc_log->close();
He Zhenxing's avatar
He Zhenxing committed
2096
  delegates_destroy();
2097
  xid_cache_free();
2098
  tdc_deinit();
Konstantin Osipov's avatar
Konstantin Osipov committed
2099
  mdl_destroy();
2100
  key_caches.delete_elements((void (*)(const char*, uchar*)) free_key_cache);
2101
  wt_end();
2102
  multi_keycache_free();
2103
  sp_cache_end();
2104
  free_status_vars();
2105
  end_thr_alarm(1);			/* Free allocated memory */
Monty's avatar
Monty committed
2106 2107 2108
#ifndef EMBEDDED_LIBRARY
  end_thr_timer();
#endif
2109
  my_free_open_file_info();
unknown's avatar
unknown committed
2110 2111
  if (defaults_argv)
    free_defaults(defaults_argv);
unknown's avatar
unknown committed
2112
  free_tmpdir(&mysql_tmpdir_list);
2113
  my_bitmap_free(&temp_pool);
unknown's avatar
unknown committed
2114
  free_max_user_conn();
2115 2116 2117 2118
  free_global_user_stats();
  free_global_client_stats();
  free_global_table_stats();
  free_global_index_stats();
2119
  delete_dynamic(&all_options);
2120
  free_all_rpl_filters();
unknown's avatar
SCRUM  
unknown committed
2121
#ifdef HAVE_REPLICATION
2122
  end_slave_list();
2123
#endif
2124
  my_uuid_end();
unknown's avatar
unknown committed
2125
  delete binlog_filter;
2126
  delete global_rpl_filter;
2127
  end_ssl();
2128
#ifndef EMBEDDED_LIBRARY
2129
  vio_end();
2130
#endif /*!EMBEDDED_LIBRARY*/
2131 2132 2133 2134
#if defined(ENABLED_DEBUG_SYNC)
  /* End the debug sync facility. See debug_sync.cc. */
  debug_sync_end();
#endif /* defined(ENABLED_DEBUG_SYNC) */
unknown's avatar
unknown committed
2135

2136
  delete_pid_file(MYF(0));
2137

2138
  if (print_message && my_default_lc_messages && server_start_time)
2139 2140
    sql_print_information(ER_DEFAULT(ER_SHUTDOWN_COMPLETE),my_progname);
  cleanup_errmsgs();
Sergei Golubchik's avatar
Sergei Golubchik committed
2141
  MYSQL_CALLBACK(thread_scheduler, end, ());
2142
  mysql_library_end();
unknown's avatar
Merge  
unknown committed
2143
  finish_client_errs();
2144
  (void) my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST); // finish server errs
2145
  DBUG_PRINT("quit", ("Error messages freed"));
unknown's avatar
unknown committed
2146
  /* Tell main we are ready */
unknown's avatar
unknown committed
2147
  logger.cleanup_end();
2148
  sys_var_end();
2149
  free_charsets();
Marc Alff's avatar
Marc Alff committed
2150
  mysql_mutex_lock(&LOCK_thread_count);
2151
  DBUG_PRINT("quit", ("got thread count lock"));
unknown's avatar
unknown committed
2152
  ready_to_exit=1;
unknown's avatar
unknown committed
2153
  /* do the broadcast inside the lock to ensure that my_end() is not called */
Marc Alff's avatar
Marc Alff committed
2154 2155
  mysql_cond_broadcast(&COND_thread_count);
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
2156

2157
  free_list(opt_plugin_load_list_ptr);
2158 2159 2160 2161 2162 2163 2164

  if (THR_THD)
    (void) pthread_key_delete(THR_THD);

  if (THR_MALLOC)
    (void) pthread_key_delete(THR_MALLOC);

unknown's avatar
unknown committed
2165 2166 2167 2168
  /*
    The following lines may never be executed as the main thread may have
    killed us
  */
2169
  DBUG_PRINT("quit", ("done with cleanup"));
unknown's avatar
unknown committed
2170 2171 2172
} /* clean_up */


2173 2174
#ifndef EMBEDDED_LIBRARY

unknown's avatar
unknown committed
2175
/**
2176
  This is mainly needed when running with purify, but it's still nice to
unknown's avatar
unknown committed
2177
  know that all child threads have died when mysqld exits.
2178 2179 2180 2181 2182 2183 2184 2185 2186 2187
*/
static void wait_for_signal_thread_to_end()
{
  uint i;
  /*
    Wait up to 10 seconds for signal thread to die. We use this mainly to
    avoid getting warnings that my_thread_end has not been called
  */
  for (i= 0 ; i < 100 && signal_thread_in_use; i++)
  {
2188
    if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL) == ESRCH)
2189 2190 2191 2192
      break;
    my_sleep(100);				// Give it time to die
  }
}
2193
#endif /*EMBEDDED_LIBRARY*/
2194

unknown's avatar
unknown committed
2195 2196
static void clean_up_mutexes()
{
2197
  DBUG_ENTER("clean_up_mutexes");
Marc Alff's avatar
Marc Alff committed
2198
  mysql_rwlock_destroy(&LOCK_grant);
Marc Alff's avatar
Marc Alff committed
2199
  mysql_mutex_destroy(&LOCK_thread_count);
Michael Widenius's avatar
Michael Widenius committed
2200
  mysql_mutex_destroy(&LOCK_thread_cache);
Marc Alff's avatar
Marc Alff committed
2201
  mysql_mutex_destroy(&LOCK_status);
2202
  mysql_mutex_destroy(&LOCK_show_status);
Marc Alff's avatar
Marc Alff committed
2203 2204 2205
  mysql_mutex_destroy(&LOCK_delayed_insert);
  mysql_mutex_destroy(&LOCK_delayed_status);
  mysql_mutex_destroy(&LOCK_delayed_create);
Marc Alff's avatar
Marc Alff committed
2206 2207 2208
  mysql_mutex_destroy(&LOCK_crypt);
  mysql_mutex_destroy(&LOCK_user_conn);
  mysql_mutex_destroy(&LOCK_connection_count);
Sergei Golubchik's avatar
Sergei Golubchik committed
2209 2210 2211 2212
  mysql_mutex_destroy(&LOCK_stats);
  mysql_mutex_destroy(&LOCK_global_user_client_stats);
  mysql_mutex_destroy(&LOCK_global_table_stats);
  mysql_mutex_destroy(&LOCK_global_index_stats);
2213
#ifdef HAVE_OPENSSL
Marc Alff's avatar
Marc Alff committed
2214
  mysql_mutex_destroy(&LOCK_des_key_file);
unknown's avatar
unknown committed
2215
#ifndef HAVE_YASSL
2216
  for (int i= 0; i < CRYPTO_num_locks(); ++i)
2217
    mysql_rwlock_destroy(&openssl_stdlocks[i].lock);
2218
  OPENSSL_free(openssl_stdlocks);
Michael Widenius's avatar
Michael Widenius committed
2219 2220
#endif /* HAVE_YASSL */
#endif /* HAVE_OPENSSL */
2221
#ifdef HAVE_REPLICATION
Marc Alff's avatar
Marc Alff committed
2222
  mysql_mutex_destroy(&LOCK_rpl_status);
Michael Widenius's avatar
Michael Widenius committed
2223
#endif /* HAVE_REPLICATION */
Marc Alff's avatar
Marc Alff committed
2224 2225 2226 2227 2228
  mysql_mutex_destroy(&LOCK_active_mi);
  mysql_rwlock_destroy(&LOCK_sys_init_connect);
  mysql_rwlock_destroy(&LOCK_sys_init_slave);
  mysql_mutex_destroy(&LOCK_global_system_variables);
  mysql_rwlock_destroy(&LOCK_system_variables_hash);
Sergei Golubchik's avatar
Sergei Golubchik committed
2229
  mysql_mutex_destroy(&LOCK_short_uuid_generator);
Marc Alff's avatar
Marc Alff committed
2230 2231
  mysql_mutex_destroy(&LOCK_prepared_stmt_count);
  mysql_mutex_destroy(&LOCK_error_messages);
Marc Alff's avatar
Marc Alff committed
2232 2233 2234
  mysql_cond_destroy(&COND_thread_count);
  mysql_cond_destroy(&COND_thread_cache);
  mysql_cond_destroy(&COND_flush_thread_cache);
Sergei Golubchik's avatar
Sergei Golubchik committed
2235 2236
  mysql_mutex_destroy(&LOCK_server_started);
  mysql_cond_destroy(&COND_server_started);
Sergei Golubchik's avatar
Sergei Golubchik committed
2237
  mysql_mutex_destroy(&LOCK_prepare_ordered);
2238
  mysql_cond_destroy(&COND_prepare_ordered);
2239
  mysql_mutex_destroy(&LOCK_after_binlog_sync);
Sergei Golubchik's avatar
Sergei Golubchik committed
2240
  mysql_mutex_destroy(&LOCK_commit_ordered);
2241 2242
  mysql_mutex_destroy(&LOCK_slave_init);
  mysql_cond_destroy(&COND_slave_init);
2243
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
2244
}
2245 2246


unknown's avatar
unknown committed
2247 2248 2249 2250
/****************************************************************************
** Init IP and UNIX socket
****************************************************************************/

2251 2252 2253 2254 2255 2256
#ifdef EMBEDDED_LIBRARY
static void set_ports()
{
}

#else
unknown's avatar
unknown committed
2257 2258 2259
static void set_ports()
{
  char	*env;
2260
  if (!mysqld_port && !opt_disable_networking)
unknown's avatar
unknown committed
2261
  {					// Get port if not from commandline
2262
    mysqld_port= MYSQL_PORT;
2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274

    /*
      if builder specifically requested a default port, use that
      (even if it coincides with our factory default).
      only if they didn't do we check /etc/services (and, failing
      on that, fall back to the factory default of 3306).
      either default can be overridden by the environment variable
      MYSQL_TCP_PORT, which in turn can be overridden with command
      line options.
    */

#if MYSQL_PORT_DEFAULT == 0
unknown's avatar
unknown committed
2275
    struct  servent *serv_ptr;
2276
    if ((serv_ptr= getservbyname("mysql", "tcp")))
Sergei Golubchik's avatar
Sergei Golubchik committed
2277
      SYSVAR_AUTOSIZE(mysqld_port, ntohs((u_short) serv_ptr->s_port));
2278
#endif
unknown's avatar
unknown committed
2279
    if ((env = getenv("MYSQL_TCP_PORT")))
Sergei Golubchik's avatar
Sergei Golubchik committed
2280 2281 2282 2283
    {
      mysqld_port= (uint) atoi(env);
      mark_sys_var_value_origin(&mysqld_port, sys_var::ENV);
    }
unknown's avatar
unknown committed
2284
  }
2285
  if (!mysqld_unix_port)
unknown's avatar
unknown committed
2286 2287
  {
#ifdef __WIN__
2288
    mysqld_unix_port= (char*) MYSQL_NAMEDPIPE;
unknown's avatar
unknown committed
2289
#else
2290
    mysqld_unix_port= (char*) MYSQL_UNIX_ADDR;
unknown's avatar
unknown committed
2291 2292
#endif
    if ((env = getenv("MYSQL_UNIX_PORT")))
Sergei Golubchik's avatar
Sergei Golubchik committed
2293 2294 2295 2296
    {
      mysqld_unix_port= env;
      mark_sys_var_value_origin(&mysqld_unix_port, sys_var::ENV);
    }
unknown's avatar
unknown committed
2297 2298 2299 2300 2301
  }
}

/* Change to run as another user if started with --user */

2302
static struct passwd *check_user(const char *user)
unknown's avatar
unknown committed
2303
{
2304
#if !defined(__WIN__)
2305
  struct passwd *tmp_user_info;
2306
  uid_t user_id= geteuid();
unknown's avatar
unknown committed
2307

2308
  // Don't bother if we aren't superuser
2309
  if (user_id)
unknown's avatar
unknown committed
2310 2311
  {
    if (user)
2312
    {
2313 2314 2315 2316
      /* Don't give a warning, if real user is same as given with --user */
      /* purecov: begin tested */
      tmp_user_info= getpwnam(user);
      if ((!tmp_user_info || user_id != tmp_user_info->pw_uid) &&
2317
	  global_system_variables.log_warnings)
2318 2319
        sql_print_warning(
                    "One can only use the --user switch if running as root\n");
unknown's avatar
unknown committed
2320
      /* purecov: end */
2321
    }
2322
    return NULL;
unknown's avatar
unknown committed
2323
  }
2324
  if (!user)
unknown's avatar
unknown committed
2325
  {
2326
    if (!opt_bootstrap && !opt_help)
unknown's avatar
unknown committed
2327
    {
unknown's avatar
unknown committed
2328
      sql_print_error("Fatal error: Please read \"Security\" section of the manual to find out how to run mysqld as root!\n");
unknown's avatar
unknown committed
2329 2330
      unireg_abort(1);
    }
2331
    return NULL;
unknown's avatar
unknown committed
2332
  }
2333
  /* purecov: begin tested */
unknown's avatar
unknown committed
2334
  if (!strcmp(user,"root"))
unknown's avatar
unknown committed
2335
    return NULL;                        // Avoid problem with dynamic libraries
unknown's avatar
unknown committed
2336

2337
  if (!(tmp_user_info= getpwnam(user)))
unknown's avatar
unknown committed
2338
  {
2339
    // Allow a numeric uid to be used
unknown's avatar
unknown committed
2340
    const char *pos;
unknown's avatar
unknown committed
2341 2342
    for (pos= user; my_isdigit(mysqld_charset,*pos); pos++) ;
    if (*pos)                                   // Not numeric id
2343
      goto err;
2344
    if (!(tmp_user_info= getpwuid(atoi(user))))
2345
      goto err;
unknown's avatar
unknown committed
2346
  }
2347

unknown's avatar
unknown committed
2348 2349
  return tmp_user_info;
  /* purecov: end */
2350 2351

err:
unknown's avatar
unknown committed
2352
  sql_print_error("Fatal error: Can't change to run as user '%s' ;  Please check that the user exists!\n",user);
2353
  unireg_abort(1);
2354 2355 2356
#endif
  return NULL;
}
2357

2358 2359
static inline void allow_coredumps()
{
2360 2361 2362 2363 2364 2365 2366
#ifdef PR_SET_DUMPABLE
  if (test_flags & TEST_CORE_ON_SIGNAL)
  {
    /* inform kernel that process is dumpable */
    (void) prctl(PR_SET_DUMPABLE, 1);
  }
#endif
2367 2368
}

2369

2370
static void set_user(const char *user, struct passwd *user_info_arg)
2371
{
2372
  /* purecov: begin tested */
2373
#if !defined(__WIN__)
2374
  DBUG_ASSERT(user_info_arg != 0);
unknown's avatar
unknown committed
2375
#ifdef HAVE_INITGROUPS
2376 2377 2378 2379 2380 2381
  /*
    We can get a SIGSEGV when calling initgroups() on some systems when NSS
    is configured to use LDAP and the server is statically linked.  We set
    calling_initgroups as a flag to the SIGSEGV handler that is then used to
    output a specific message to help the user resolve this problem.
  */
2382
  calling_initgroups= 1;
2383
  initgroups((char*) user, user_info_arg->pw_gid);
2384
  calling_initgroups= 0;
unknown's avatar
unknown committed
2385
#endif
2386
  if (setgid(user_info_arg->pw_gid) == -1)
2387 2388 2389
  {
    sql_perror("setgid");
    unireg_abort(1);
unknown's avatar
unknown committed
2390
  }
2391
  if (setuid(user_info_arg->pw_uid) == -1)
unknown's avatar
unknown committed
2392 2393 2394 2395
  {
    sql_perror("setuid");
    unireg_abort(1);
  }
2396
  allow_coredumps();
unknown's avatar
unknown committed
2397
#endif
unknown's avatar
unknown committed
2398
  /* purecov: end */
unknown's avatar
unknown committed
2399 2400
}

unknown's avatar
unknown committed
2401

2402
static void set_effective_user(struct passwd *user_info_arg)
2403
{
2404
#if !defined(__WIN__)
2405 2406
  DBUG_ASSERT(user_info_arg != 0);
  if (setregid((gid_t)-1, user_info_arg->pw_gid) == -1)
2407
  {
2408
    sql_perror("setregid");
2409
    unireg_abort(1);
unknown's avatar
unknown committed
2410
  }
2411
  if (setreuid((uid_t)-1, user_info_arg->pw_uid) == -1)
2412
  {
2413
    sql_perror("setreuid");
2414 2415
    unireg_abort(1);
  }
2416
  allow_coredumps();
2417 2418 2419 2420
#endif
}


unknown's avatar
unknown committed
2421
/** Change root user if started with @c --chroot . */
unknown's avatar
unknown committed
2422 2423
static void set_root(const char *path)
{
2424
#if !defined(__WIN__)
unknown's avatar
unknown committed
2425 2426 2427 2428 2429
  if (chroot(path) == -1)
  {
    sql_perror("chroot");
    unireg_abort(1);
  }
2430
  my_setwd("/", MYF(0));
unknown's avatar
unknown committed
2431 2432 2433
#endif
}

2434 2435 2436
/**
   Activate usage of a tcp port
*/
2437

2438
static MYSQL_SOCKET activate_tcp_port(uint port)
unknown's avatar
unknown committed
2439
{
Sergei Golubchik's avatar
Sergei Golubchik committed
2440 2441 2442
  struct addrinfo *ai, *a;
  struct addrinfo hints;
  int error;
2443 2444
  int	arg;
  char port_buf[NI_MAXSERV];
2445
  const char *real_bind_addr_str;
2446
  MYSQL_SOCKET ip_sock= MYSQL_INVALID_SOCKET;
2447 2448
  DBUG_ENTER("activate_tcp_port");
  DBUG_PRINT("general",("IP Socket is %d",port));
unknown's avatar
unknown committed
2449

Sergei Golubchik's avatar
Sergei Golubchik committed
2450 2451 2452 2453
  bzero(&hints, sizeof (hints));
  hints.ai_flags= AI_PASSIVE;
  hints.ai_socktype= SOCK_STREAM;
  hints.ai_family= AF_UNSPEC;
2454 2455 2456 2457 2458
  
  if (my_bind_addr_str && strcmp(my_bind_addr_str, "*") == 0)
    real_bind_addr_str= NULL; // windows doesn't seem to support * here
  else
    real_bind_addr_str= my_bind_addr_str;
unknown's avatar
unknown committed
2459

2460
  my_snprintf(port_buf, NI_MAXSERV, "%d", port);
2461
  error= getaddrinfo(real_bind_addr_str, port_buf, &hints, &ai);
Sergei Golubchik's avatar
Sergei Golubchik committed
2462
  if (error != 0)
unknown's avatar
unknown committed
2463
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
2464
    DBUG_PRINT("error",("Got error: %d from getaddrinfo()", error));
2465 2466

    sql_print_error("%s: %s", ER_DEFAULT(ER_IPSOCK_ERROR), gai_strerror(error));
Sergei Golubchik's avatar
Sergei Golubchik committed
2467 2468
    unireg_abort(1);				/* purecov: tested */
  }
2469

2470 2471 2472 2473 2474
  /*
    special case: for wildcard addresses prefer ipv6 over ipv4,
    because we later switch off IPV6_V6ONLY, so ipv6 wildcard
    addresses will work for ipv4 too
  */
2475
  if (!real_bind_addr_str && ai->ai_family == AF_INET && ai->ai_next
2476 2477 2478 2479 2480 2481 2482 2483
      && ai->ai_next->ai_family == AF_INET6)
  {
    a= ai;
    ai= ai->ai_next;
    a->ai_next= ai->ai_next;
    ai->ai_next= a;
  }

Sergei Golubchik's avatar
Sergei Golubchik committed
2484 2485
  for (a= ai; a != NULL; a= a->ai_next)
  {
2486 2487
    ip_sock= mysql_socket_socket(key_socket_tcpip, a->ai_family,
                                 a->ai_socktype, a->ai_protocol);
2488

Sergei Golubchik's avatar
Sergei Golubchik committed
2489
    char ip_addr[INET6_ADDRSTRLEN];
2490 2491 2492 2493 2494 2495
    if (vio_get_normalized_ip_string(a->ai_addr, a->ai_addrlen,
                                     ip_addr, sizeof (ip_addr)))
    {
      ip_addr[0]= 0;
    }

Sergei Golubchik's avatar
Sergei Golubchik committed
2496
    if (mysql_socket_getfd(ip_sock) == INVALID_SOCKET)
2497 2498 2499 2500 2501 2502 2503 2504 2505 2506
    {
      sql_print_error("Failed to create a socket for %s '%s': errno: %d.",
                      (a->ai_family == AF_INET) ? "IPv4" : "IPv6",
                      (const char *) ip_addr,
                      (int) socket_errno);
    }
    else 
    {
      sql_print_information("Server socket created on IP: '%s'.",
                          (const char *) ip_addr);
Sergei Golubchik's avatar
Sergei Golubchik committed
2507
      break;
2508
    }
Sergei Golubchik's avatar
Sergei Golubchik committed
2509
  }
2510

2511
  if (mysql_socket_getfd(ip_sock) == INVALID_SOCKET)
2512 2513
  {
    DBUG_PRINT("error",("Got error: %d from socket()",socket_errno));
Sergei Golubchik's avatar
Sergei Golubchik committed
2514
    sql_perror(ER_DEFAULT(ER_IPSOCK_ERROR));  /* purecov: tested */
2515 2516
    unireg_abort(1);				/* purecov: tested */
  }
2517

2518 2519
  mysql_socket_set_thread_owner(ip_sock);

2520
#ifndef __WIN__
2521 2522 2523 2524
  /*
    We should not use SO_REUSEADDR on windows as this would enable a
    user to open two mysqld servers with the same TCP/IP port.
  */
Sergei Golubchik's avatar
Sergei Golubchik committed
2525
  arg= 1;
2526 2527
  (void) mysql_socket_setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,
                                 sizeof(arg));
unknown's avatar
unknown committed
2528
#endif /* __WIN__ */
2529 2530

#ifdef IPV6_V6ONLY
Sergei Golubchik's avatar
Sergei Golubchik committed
2531 2532 2533 2534
   /*
     For interoperability with older clients, IPv6 socket should
     listen on both IPv6 and IPv4 wildcard addresses.
     Turn off IPV6_V6ONLY option.
2535

Sergei Golubchik's avatar
Sergei Golubchik committed
2536 2537 2538 2539 2540 2541 2542
     NOTE: this will work starting from Windows Vista only.
     On Windows XP dual stack is not available, so it will not
     listen on the corresponding IPv4-address.
   */
  if (a->ai_family == AF_INET6)
  {
    arg= 0;
2543 2544
    (void) mysql_socket_setsockopt(ip_sock, IPPROTO_IPV6, IPV6_V6ONLY,
                                   (char*)&arg, sizeof(arg));
Sergei Golubchik's avatar
Sergei Golubchik committed
2545
  }
2546
#endif
2547 2548 2549 2550 2551 2552 2553 2554
  /*
    Sometimes the port is not released fast enough when stopping and
    restarting the server. This happens quite often with the test suite
    on busy Linux systems. Retry to bind the address at these intervals:
    Sleep intervals: 1, 2, 4,  6,  9, 13, 17, 22, ...
    Retry at second: 1, 3, 7, 13, 22, 35, 52, 74, ...
    Limit the sequence by mysqld_port_timeout (set --port-open-timeout=#).
  */
2555 2556
  int ret;
  uint waited, retry, this_wait;
2557 2558
  for (waited= 0, retry= 1; ; retry++, waited+= this_wait)
  {
2559
    if (((ret= mysql_socket_bind(ip_sock, a->ai_addr, a->ai_addrlen)) >= 0 ) ||
2560 2561 2562
        (socket_errno != SOCKET_EADDRINUSE) ||
        (waited >= mysqld_port_timeout))
      break;
2563
    sql_print_information("Retrying bind on TCP/IP port %u", port);
2564 2565
    this_wait= retry * retry / 3 + 1;
    sleep(this_wait);
unknown's avatar
unknown committed
2566
  }
Sergei Golubchik's avatar
Sergei Golubchik committed
2567
  freeaddrinfo(ai);
2568 2569
  if (ret < 0)
  {
2570 2571 2572 2573
    char buff[100];
    sprintf(buff, "Can't start server: Bind on TCP/IP port. Got error: %d",
            (int) socket_errno);
    sql_perror(buff);
2574 2575 2576 2577
    sql_print_error("Do you already have another mysqld server running on "
                    "port: %u ?", port);
    unireg_abort(1);
  }
2578
  if (mysql_socket_listen(ip_sock,(int) back_log) < 0)
2579 2580 2581 2582 2583 2584
  {
    sql_perror("Can't start server: listen() on TCP/IP port");
    sql_print_error("listen() on TCP/IP failed with error %d",
                    socket_errno);
    unireg_abort(1);
  }
2585 2586 2587 2588

#ifdef FD_CLOEXEC
  (void) fcntl(mysql_socket_getfd(ip_sock), F_SETFD, FD_CLOEXEC);
#endif
2589

2590 2591
  DBUG_RETURN(ip_sock);
}
2592

2593 2594 2595 2596
static void network_init(void)
{
#ifdef HAVE_SYS_UN_H
  struct sockaddr_un	UNIXaddr;
2597
  int	arg;
2598
#endif
unknown's avatar
unknown committed
2599
  DBUG_ENTER("network_init");
unknown's avatar
unknown committed
2600

Sergei Golubchik's avatar
Sergei Golubchik committed
2601
  if (MYSQL_CALLBACK_ELSE(thread_scheduler, init, (), 0))
unknown's avatar
unknown committed
2602 2603
    unireg_abort(1);			/* purecov: inspected */

unknown's avatar
unknown committed
2604 2605
  set_ports();

Sergei Golubchik's avatar
Sergei Golubchik committed
2606
  if (report_port == 0)
unknown's avatar
unknown committed
2607
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
2608
    SYSVAR_AUTOSIZE(report_port, mysqld_port);
unknown's avatar
unknown committed
2609
  }
Sergei Golubchik's avatar
c  
Sergei Golubchik committed
2610 2611 2612
#ifndef DBUG_OFF
  if (!opt_disable_networking)
    DBUG_ASSERT(report_port != 0);
2613
#endif
2614
  if (!opt_disable_networking && !opt_bootstrap)
unknown's avatar
unknown committed
2615
  {
2616 2617 2618 2619
    if (mysqld_port)
      base_ip_sock= activate_tcp_port(mysqld_port);
    if (mysqld_extra_port)
      extra_ip_sock= activate_tcp_port(mysqld_extra_port);
unknown's avatar
unknown committed
2620
  }
2621

2622
#ifdef _WIN32
unknown's avatar
unknown committed
2623
  /* create named pipe */
2624
  if (Service.IsNT() && mysqld_unix_port[0] && !opt_bootstrap &&
unknown's avatar
unknown committed
2625
      opt_enable_named_pipe)
unknown's avatar
unknown committed
2626
  {
2627

2628
    strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\.\\pipe\\",
2629
	     mysqld_unix_port, NullS);
2630 2631
    bzero((char*) &saPipeSecurity, sizeof(saPipeSecurity));
    bzero((char*) &sdPipeDescriptor, sizeof(sdPipeDescriptor));
2632
    if (!InitializeSecurityDescriptor(&sdPipeDescriptor,
2633
				      SECURITY_DESCRIPTOR_REVISION))
unknown's avatar
unknown committed
2634 2635 2636 2637 2638 2639 2640 2641 2642
    {
      sql_perror("Can't start server : Initialize security descriptor");
      unireg_abort(1);
    }
    if (!SetSecurityDescriptorDacl(&sdPipeDescriptor, TRUE, NULL, FALSE))
    {
      sql_perror("Can't start server : Set security descriptor");
      unireg_abort(1);
    }
unknown's avatar
Merge  
unknown committed
2643
    saPipeSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
unknown's avatar
unknown committed
2644 2645
    saPipeSecurity.lpSecurityDescriptor = &sdPipeDescriptor;
    saPipeSecurity.bInheritHandle = FALSE;
2646
    if ((hPipe= CreateNamedPipe(pipe_name,
2647
				PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
2648 2649 2650 2651 2652 2653 2654 2655
				PIPE_TYPE_BYTE |
				PIPE_READMODE_BYTE |
				PIPE_WAIT,
				PIPE_UNLIMITED_INSTANCES,
				(int) global_system_variables.net_buffer_length,
				(int) global_system_variables.net_buffer_length,
				NMPWAIT_USE_DEFAULT_WAIT,
				&saPipeSecurity)) == INVALID_HANDLE_VALUE)
unknown's avatar
unknown committed
2656 2657 2658 2659 2660 2661 2662
      {
	LPVOID lpMsgBuf;
	int error=GetLastError();
	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
		      FORMAT_MESSAGE_FROM_SYSTEM,
		      NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
		      (LPTSTR) &lpMsgBuf, 0, NULL );
2663
	sql_perror((char *)lpMsgBuf);
unknown's avatar
Merge  
unknown committed
2664
	LocalFree(lpMsgBuf);
unknown's avatar
unknown committed
2665 2666 2667 2668 2669
	unireg_abort(1);
      }
  }
#endif

2670
#if defined(HAVE_SYS_UN_H)
unknown's avatar
unknown committed
2671 2672 2673
  /*
  ** Create the UNIX socket
  */
2674
  if (mysqld_unix_port[0] && !opt_bootstrap)
unknown's avatar
unknown committed
2675
  {
2676
    DBUG_PRINT("general",("UNIX Socket is %s",mysqld_unix_port));
unknown's avatar
unknown committed
2677

unknown's avatar
unknown committed
2678 2679
    if (strlen(mysqld_unix_port) > (sizeof(UNIXaddr.sun_path) - 1))
    {
2680
      sql_print_error("The socket file path is too long (> %u): %s",
unknown's avatar
unknown committed
2681
                      (uint) sizeof(UNIXaddr.sun_path) - 1, mysqld_unix_port);
unknown's avatar
unknown committed
2682 2683
      unireg_abort(1);
    }
2684 2685
    unix_sock= mysql_socket_socket(key_socket_unix, AF_UNIX, SOCK_STREAM, 0);
    if (mysql_socket_getfd(unix_sock) < 0)
unknown's avatar
unknown committed
2686 2687 2688 2689
    {
      sql_perror("Can't start server : UNIX Socket "); /* purecov: inspected */
      unireg_abort(1);				/* purecov: inspected */
    }
Sergei Golubchik's avatar
Sergei Golubchik committed
2690 2691 2692

    mysql_socket_set_thread_owner(unix_sock);

unknown's avatar
unknown committed
2693 2694
    bzero((char*) &UNIXaddr, sizeof(UNIXaddr));
    UNIXaddr.sun_family = AF_UNIX;
2695 2696
    strmov(UNIXaddr.sun_path, mysqld_unix_port);
    (void) unlink(mysqld_unix_port);
2697
    arg= 1;
2698 2699
    (void) mysql_socket_setsockopt(unix_sock,SOL_SOCKET,SO_REUSEADDR,
                                   (char*)&arg, sizeof(arg));
unknown's avatar
unknown committed
2700
    umask(0);
2701 2702 2703
    if (mysql_socket_bind(unix_sock,
                          reinterpret_cast<struct sockaddr *>(&UNIXaddr),
                          sizeof(UNIXaddr)) < 0)
unknown's avatar
unknown committed
2704 2705
    {
      sql_perror("Can't start server : Bind on unix socket"); /* purecov: tested */
2706
      sql_print_error("Do you already have another mysqld server running on socket: %s ?",mysqld_unix_port);
unknown's avatar
unknown committed
2707 2708 2709 2710
      unireg_abort(1);					/* purecov: tested */
    }
    umask(((~my_umask) & 0666));
#if defined(S_IFSOCK) && defined(SECURE_SOCKETS)
2711
    (void) chmod(mysqld_unix_port,S_IFSOCK);	/* Fix solaris 2.6 bug */
unknown's avatar
unknown committed
2712
#endif
2713
    if (mysql_socket_listen(unix_sock,(int) back_log) < 0)
2714
      sql_print_warning("listen() on Unix socket failed with error %d",
unknown's avatar
unknown committed
2715
		      socket_errno);
2716 2717 2718
#ifdef FD_CLOEXEC
    (void) fcntl(mysql_socket_getfd(unix_sock), F_SETFD, FD_CLOEXEC);
#endif
unknown's avatar
unknown committed
2719 2720 2721 2722 2723 2724
  }
#endif
  DBUG_PRINT("info",("server started"));
  DBUG_VOID_RETURN;
}

Sergei Golubchik's avatar
Sergei Golubchik committed
2725

unknown's avatar
unknown committed
2726 2727
/**
  Close a connection.
2728

2729 2730
  @param thd        Thread handle.
  @param sql_errno  The error code to send before disconnect.
2731

unknown's avatar
unknown committed
2732
  @note
2733 2734
    For the connection that is doing shutdown, this is called twice
*/
2735
void close_connection(THD *thd, uint sql_errno)
unknown's avatar
unknown committed
2736 2737
{
  DBUG_ENTER("close_connection");
2738 2739 2740 2741

  if (sql_errno)
    net_send_error(thd, sql_errno, ER_DEFAULT(sql_errno), NULL);

Sergei Golubchik's avatar
Sergei Golubchik committed
2742 2743
  thd->print_aborted_warning(3, sql_errno ? ER_DEFAULT(sql_errno)
                                          : "CLOSE_CONNECTION");
2744

2745 2746 2747 2748
  thd->disconnect();

  MYSQL_CONNECTION_DONE((int) sql_errno, thd->thread_id);

2749 2750 2751 2752
  if (MYSQL_CONNECTION_DONE_ENABLED())
  {
    sleep(0); /* Workaround to avoid tailcall optimisation */
  }
2753
  mysql_audit_notify_connection_disconnect(thd, sql_errno);
unknown's avatar
unknown committed
2754 2755
  DBUG_VOID_RETURN;
}
2756 2757
#endif /* EMBEDDED_LIBRARY */

unknown's avatar
unknown committed
2758

2759
/** Called when mysqld is aborted with ^C */
unknown's avatar
unknown committed
2760
/* ARGSUSED */
2761
extern "C" sig_handler end_mysqld_signal(int sig __attribute__((unused)))
unknown's avatar
unknown committed
2762
{
2763
  DBUG_ENTER("end_mysqld_signal");
2764 2765
  /* Don't call kill_mysql() if signal thread is not running */
  if (signal_thread_in_use)
Sergei Golubchik's avatar
Sergei Golubchik committed
2766
    kill_mysql();                          // Take down mysqld nicely
unknown's avatar
unknown committed
2767 2768 2769 2770
  DBUG_VOID_RETURN;				/* purecov: deadcode */
}


2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783
/*
  Cleanup THD object

  SYNOPSIS
    thd_cleanup()
    thd		 Thread handler
*/

void thd_cleanup(THD *thd)
{
  thd->cleanup();
}

2784 2785 2786 2787 2788 2789 2790
/*
  Decrease number of connections

  SYNOPSIS
    dec_connection_count()
*/

Sergei Golubchik's avatar
Sergei Golubchik committed
2791
void dec_connection_count(THD *thd)
2792
{
2793 2794 2795 2796 2797 2798 2799 2800 2801 2802
#ifdef WITH_WSREP
  /*
    Do not decrement when its wsrep system thread. wsrep_applier is set for
    applier as well as rollbacker threads.
  */
  if (thd->wsrep_applier)
    return;
#endif /* WITH_WSREP */

  DBUG_ASSERT(*thd->scheduler->connection_count > 0);
2803
  mysql_mutex_lock(&LOCK_connection_count);
Sergei Golubchik's avatar
Sergei Golubchik committed
2804
  (*thd->scheduler->connection_count)--;
2805 2806 2807 2808
  mysql_mutex_unlock(&LOCK_connection_count);
}


Michael Widenius's avatar
Michael Widenius committed
2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820
/*
  Delete THD and decrement thread counters, including thread_running
*/

void delete_running_thd(THD *thd)
{
  mysql_mutex_lock(&LOCK_thread_count);
  thd->unlink();
  mysql_mutex_unlock(&LOCK_thread_count);

  delete thd;
  dec_thread_running();
2821
  thread_safe_decrement32(&thread_count);
Michael Widenius's avatar
Michael Widenius committed
2822 2823 2824 2825 2826 2827 2828 2829 2830
  if (!thread_count)
  {
    mysql_mutex_lock(&LOCK_thread_count);
    mysql_cond_broadcast(&COND_thread_count);
    mysql_mutex_unlock(&LOCK_thread_count);
  }
}


unknown's avatar
unknown committed
2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842
/*
  Unlink thd from global list of available connections and free thd

  SYNOPSIS
    unlink_thd()
    thd		 Thread handler

  NOTES
    LOCK_thread_count is locked and left locked
*/

void unlink_thd(THD *thd)
unknown's avatar
unknown committed
2843
{
unknown's avatar
unknown committed
2844 2845
  DBUG_ENTER("unlink_thd");
  DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd));
2846

2847
  thd_cleanup(thd);
Sergei Golubchik's avatar
Sergei Golubchik committed
2848
  dec_connection_count(thd);
2849

2850
  thd->add_status_to_global();
2851

Marc Alff's avatar
Marc Alff committed
2852
  mysql_mutex_lock(&LOCK_thread_count);
2853
  thd->unlink();
2854 2855 2856 2857 2858 2859
  /*
    Used by binlog_reset_master.  It would be cleaner to use
    DEBUG_SYNC here, but that's not possible because the THD's debug
    sync feature has been shut down at this point.
  */
  DBUG_EXECUTE_IF("sleep_after_lock_thread_count_before_delete_thd", sleep(5););
2860 2861
  mysql_mutex_unlock(&LOCK_thread_count);

Michael Widenius's avatar
Michael Widenius committed
2862
  delete thd;
2863
  thread_safe_decrement32(&thread_count);
Michael Widenius's avatar
Michael Widenius committed
2864

unknown's avatar
unknown committed
2865 2866 2867
  DBUG_VOID_RETURN;
}

2868

unknown's avatar
unknown committed
2869 2870 2871 2872 2873 2874 2875
/*
  Store thread in cache for reuse by new connections

  SYNOPSIS
    cache_thread()

  NOTES
Michael Widenius's avatar
Michael Widenius committed
2876
    LOCK_thread_cache is used to protect the cache variables
unknown's avatar
unknown committed
2877 2878 2879 2880 2881 2882 2883 2884 2885 2886

  RETURN
    0  Thread was not put in cache
    1  Thread is to be reused by new connection.
       (ie, caller should return, not abort with pthread_exit())
*/


static bool cache_thread()
{
Michael Widenius's avatar
Michael Widenius committed
2887 2888
  DBUG_ENTER("cache_thread");

Michael Widenius's avatar
Michael Widenius committed
2889
  mysql_mutex_lock(&LOCK_thread_cache);
unknown's avatar
unknown committed
2890
  if (cached_thread_count < thread_cache_size &&
2891
      ! abort_loop && !kill_cached_threads)
unknown's avatar
unknown committed
2892 2893
  {
    /* Don't kill the thread, just put it in cache for reuse */
unknown's avatar
unknown committed
2894
    DBUG_PRINT("info", ("Adding thread to cache"));
unknown's avatar
unknown committed
2895
    cached_thread_count++;
2896

2897
#ifdef HAVE_PSI_THREAD_INTERFACE
2898 2899 2900 2901
    /*
      Delete the instrumentation for the job that just completed,
      before parking this pthread in the cache (blocked on COND_thread_cache).
    */
2902
    PSI_THREAD_CALL(delete_current_thread)();
2903 2904
#endif

unknown's avatar
unknown committed
2905
    while (!abort_loop && ! wake_thread && ! kill_cached_threads)
Michael Widenius's avatar
Michael Widenius committed
2906
      mysql_cond_wait(&COND_thread_cache, &LOCK_thread_cache);
unknown's avatar
unknown committed
2907 2908
    cached_thread_count--;
    if (kill_cached_threads)
Marc Alff's avatar
Marc Alff committed
2909
      mysql_cond_signal(&COND_flush_thread_cache);
unknown's avatar
unknown committed
2910 2911
    if (wake_thread)
    {
unknown's avatar
unknown committed
2912
      THD *thd;
unknown's avatar
unknown committed
2913
      wake_thread--;
unknown's avatar
unknown committed
2914
      thd= thread_cache.get();
Michael Widenius's avatar
Michael Widenius committed
2915 2916
      mysql_mutex_unlock(&LOCK_thread_cache);

2917
      thd->thread_stack= (char*) &thd;          // For store_globals
unknown's avatar
unknown committed
2918
      (void) thd->store_globals();
2919

2920
#ifdef HAVE_PSI_THREAD_INTERFACE
2921 2922 2923 2924
      /*
        Create new instrumentation for the new THD job,
        and attach it to this running pthread.
      */
2925 2926 2927
      PSI_thread *psi= PSI_THREAD_CALL(new_thread)(key_thread_one_connection,
                                                   thd, thd->thread_id);
      PSI_THREAD_CALL(set_thread)(psi);
2928 2929
#endif

2930 2931 2932 2933 2934 2935
      /*
        THD::mysys_var::abort is associated with physical thread rather
        than with THD object. So we need to reset this flag before using
        this thread for handling of new THD object/connection.
      */
      thd->mysys_var->abort= 0;
2936
      thd->thr_create_utime= microsecond_interval_timer();
2937
      thd->start_utime= thd->thr_create_utime;
Michael Widenius's avatar
Michael Widenius committed
2938 2939 2940

      /* Link thd into list of all active threads (THD's) */
      mysql_mutex_lock(&LOCK_thread_count);
2941
      threads.append(thd);
Michael Widenius's avatar
Michael Widenius committed
2942
      mysql_mutex_unlock(&LOCK_thread_count);
Michael Widenius's avatar
Michael Widenius committed
2943
      DBUG_RETURN(1);
unknown's avatar
unknown committed
2944 2945
    }
  }
Michael Widenius's avatar
Michael Widenius committed
2946
  mysql_mutex_unlock(&LOCK_thread_cache);
Michael Widenius's avatar
Michael Widenius committed
2947
  DBUG_RETURN(0);
unknown's avatar
unknown committed
2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972
}


/*
  End thread for the current connection

  SYNOPSIS
    one_thread_per_connection_end()
    thd		  Thread handler
    put_in_cache  Store thread in cache, if there is room in it
                  Normally this is true in all cases except when we got
                  out of resources initializing the current thread

  NOTES
    If thread is cached, we will wait until thread is scheduled to be
    reused and then we will return.
    If thread is not cached, we end the thread.

  RETURN
    0    Signal to handle_one_connection to reuse connection
*/

bool one_thread_per_connection_end(THD *thd, bool put_in_cache)
{
  DBUG_ENTER("one_thread_per_connection_end");
2973
  const bool wsrep_applier= IF_WSREP(thd->wsrep_applier, false);
2974

unknown's avatar
unknown committed
2975
  unlink_thd(thd);
2976

2977
  if (put_in_cache && cache_thread() && !wsrep_applier)
Michael Widenius's avatar
Michael Widenius committed
2978
    DBUG_RETURN(0);                             // Thread is reused
unknown's avatar
unknown committed
2979

Michael Widenius's avatar
Michael Widenius committed
2980 2981 2982 2983 2984 2985 2986
  /*
    It's safe to check for thread_count outside of the mutex
    as we are only interested to see if it was counted to 0 by the
    above unlink_thd() call. We should only signal COND_thread_count if
    thread_count is likely to be 0. (false positives are ok)
  */
  if (!thread_count)
2987 2988
  {
    mysql_mutex_lock(&LOCK_thread_count);
Michael Widenius's avatar
Michael Widenius committed
2989 2990
    DBUG_PRINT("signal", ("Broadcasting COND_thread_count"));
    mysql_cond_broadcast(&COND_thread_count);
2991 2992
    mysql_mutex_unlock(&LOCK_thread_count);
  }
2993
  DBUG_LEAVE;                                   // Must match DBUG_ENTER()
2994
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
2995 2996
  ERR_remove_state(0);
#endif
2997
  my_thread_end();
unknown's avatar
unknown committed
2998 2999

  pthread_exit(0);
3000
  return 0;                                     // Avoid compiler warnings
unknown's avatar
unknown committed
3001 3002 3003 3004 3005
}


void flush_thread_cache()
{
Michael Widenius's avatar
Michael Widenius committed
3006 3007
  DBUG_ENTER("flush_thread_cache");
  mysql_mutex_lock(&LOCK_thread_cache);
unknown's avatar
unknown committed
3008 3009 3010
  kill_cached_threads++;
  while (cached_thread_count)
  {
Marc Alff's avatar
Marc Alff committed
3011
    mysql_cond_broadcast(&COND_thread_cache);
Michael Widenius's avatar
Michael Widenius committed
3012
    mysql_cond_wait(&COND_flush_thread_cache, &LOCK_thread_cache);
unknown's avatar
unknown committed
3013 3014
  }
  kill_cached_threads--;
Michael Widenius's avatar
Michael Widenius committed
3015 3016
  mysql_mutex_unlock(&LOCK_thread_cache);
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
3017 3018 3019 3020
}


/******************************************************************************
3021 3022 3023
  Setup a signal thread with handles all signals.
  Because Linux doesn't support schemas use a mutex to check that
  the signal thread is ready before continuing
unknown's avatar
unknown committed
3024 3025
******************************************************************************/

3026
#if defined(__WIN__)
3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040


/*
  On Windows, we use native SetConsoleCtrlHandler for handle events like Ctrl-C
  with graceful shutdown.
  Also, we do not use signal(), but SetUnhandledExceptionFilter instead - as it
  provides possibility to pass the exception to just-in-time debugger, collect
  dumps and potentially also the exception and thread context used to output
  callstack.
*/

static BOOL WINAPI console_event_handler( DWORD type ) 
{
  DBUG_ENTER("console_event_handler");
unknown's avatar
unknown committed
3041
#ifndef EMBEDDED_LIBRARY
3042 3043 3044 3045 3046 3047 3048 3049
  if(type == CTRL_C_EVENT)
  {
     /*
       Do not shutdown before startup is finished and shutdown
       thread is initialized. Otherwise there is a race condition 
       between main thread doing initialization and CTRL-C thread doing
       cleanup, which can result into crash.
     */
3050
#ifndef EMBEDDED_LIBRARY
3051 3052 3053
     if(hEventShutdown)
       kill_mysql();
     else
3054
#endif
3055 3056 3057
       sql_print_warning("CTRL-C ignored during startup");
     DBUG_RETURN(TRUE);
  }
unknown's avatar
unknown committed
3058
#endif
3059 3060 3061 3062 3063 3064 3065 3066 3067
  DBUG_RETURN(FALSE);
}




#ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER
#define DEBUGGER_ATTACH_TIMEOUT 120
/*
3068 3069
  Wait for debugger to attach and break into debugger. If debugger is
  not attached, resume after timeout.
3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119
*/
static void wait_for_debugger(int timeout_sec)
{
   if(!IsDebuggerPresent())
   {
     int i;
     printf("Waiting for debugger to attach, pid=%u\n",GetCurrentProcessId());
     fflush(stdout);
     for(i= 0; i < timeout_sec; i++)
     {
       Sleep(1000);
       if(IsDebuggerPresent())
       {
         /* Break into debugger */
         __debugbreak();
         return;
       }
     }
     printf("pid=%u, debugger not attached after %d seconds, resuming\n",GetCurrentProcessId(),
       timeout_sec);
     fflush(stdout);
   }
}
#endif /* DEBUG_UNHANDLED_EXCEPTION_FILTER */

LONG WINAPI my_unhandler_exception_filter(EXCEPTION_POINTERS *ex_pointers)
{
   static BOOL first_time= TRUE;
   if(!first_time)
   {
     /*
       This routine can be called twice, typically
       when detaching in JIT debugger.
       Return EXCEPTION_EXECUTE_HANDLER to terminate process.
     */
     return EXCEPTION_EXECUTE_HANDLER;
   }
   first_time= FALSE;
#ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER
   /*
    Unfortunately there is no clean way to debug unhandled exception filters,
    as debugger does not stop there(also documented in MSDN) 
    To overcome, one could put a MessageBox, but this will not work in service.
    Better solution is to print error message and sleep some minutes 
    until debugger is attached
  */
  wait_for_debugger(DEBUGGER_ATTACH_TIMEOUT);
#endif /* DEBUG_UNHANDLED_EXCEPTION_FILTER */
  __try
  {
3120
    my_set_exception_pointers(ex_pointers);
3121
    handle_fatal_signal(ex_pointers->ExceptionRecord->ExceptionCode);
3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139
  }
  __except(EXCEPTION_EXECUTE_HANDLER)
  {
    DWORD written;
    const char msg[] = "Got exception in exception handler!\n";
    WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),msg, sizeof(msg)-1, 
      &written,NULL);
  }
  /*
    Return EXCEPTION_CONTINUE_SEARCH to give JIT debugger
    (drwtsn32 or vsjitdebugger) possibility to attach,
    if JIT debugger is configured.
    Windows Error reporting might generate a dump here.
  */
  return EXCEPTION_CONTINUE_SEARCH;
}


unknown's avatar
unknown committed
3140 3141
static void init_signals(void)
{
3142 3143
  if(opt_console)
    SetConsoleCtrlHandler(console_event_handler,TRUE);
3144

3145
    /* Avoid MessageBox()es*/
3146 3147 3148 3149 3150 3151
  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
  _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
  _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
  _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
  _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
  _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
3152 3153 3154 3155 3156 3157 3158 3159

   /*
     Do not use SEM_NOGPFAULTERRORBOX in the following SetErrorMode (),
     because it would prevent JIT debugger and Windows error reporting
     from working. We need WER or JIT-debugging, since our own unhandled
     exception filter is not guaranteed to work in all situation
     (like heap corruption or stack overflow)
   */
3160 3161
  SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS
                               | SEM_NOOPENFILEERRORBOX);
3162
  SetUnhandledExceptionFilter(my_unhandler_exception_filter);
unknown's avatar
unknown committed
3163 3164
}

unknown's avatar
unknown committed
3165

3166
static void start_signal_handler(void)
3167
{
3168
#ifndef EMBEDDED_LIBRARY
3169 3170 3171
  // Save vm id of this process
  if (!opt_bootstrap)
    create_pid_file();
3172
#endif /* EMBEDDED_LIBRARY */
3173
}
unknown's avatar
unknown committed
3174

unknown's avatar
unknown committed
3175

unknown's avatar
unknown committed
3176 3177
static void check_data_home(const char *path)
{}
3178

3179
#endif /* __WIN__ */
unknown's avatar
unknown committed
3180

unknown's avatar
unknown committed
3181 3182 3183 3184 3185 3186 3187 3188 3189

#if BACKTRACE_DEMANGLE
#include <cxxabi.h>
extern "C" char *my_demangle(const char *mangled_name, int *status)
{
  return abi::__cxa_demangle(mangled_name, NULL, NULL, status);
}
#endif

3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260

/*
  pthread_attr_setstacksize() without so much platform-dependency

  Return: The actual stack size if possible.
*/

#ifndef EMBEDDED_LIBRARY
static size_t my_setstacksize(pthread_attr_t *attr, size_t stacksize)
{
  size_t guard_size __attribute__((unused))= 0;

#if defined(__ia64__) || defined(__ia64)
  /*
    On IA64, half of the requested stack size is used for "normal stack"
    and half for "register stack".  The space measured by check_stack_overrun
    is the "normal stack", so double the request to make sure we have the
    caller-expected amount of normal stack.

    NOTE: there is no guarantee that the register stack can't grow faster
    than normal stack, so it's very unclear that we won't dump core due to
    stack overrun despite check_stack_overrun's efforts.  Experimentation
    shows that in the execution_constants test, the register stack grows
    less than half as fast as normal stack, but perhaps other scenarios are
    less forgiving.  If it turns out that more space is needed for the
    register stack, that could be forced (rather inefficiently) by using a
    multiplier higher than 2 here.
  */
  stacksize *= 2;
#endif

  /*
    On many machines, the "guard space" is subtracted from the requested
    stack size, and that space is quite large on some platforms.  So add
    it to our request, if we can find out what it is.
  */
#ifdef HAVE_PTHREAD_ATTR_GETGUARDSIZE
  if (pthread_attr_getguardsize(attr, &guard_size))
    guard_size = 0;		/* if can't find it out, treat as 0 */
#endif

  pthread_attr_setstacksize(attr, stacksize + guard_size);

  /* Retrieve actual stack size if possible */
#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
  {
    size_t real_stack_size= 0;
    /* We must ignore real_stack_size = 0 as Solaris 2.9 can return 0 here */
    if (pthread_attr_getstacksize(attr, &real_stack_size) == 0 &&
	real_stack_size > guard_size)
    {
      real_stack_size -= guard_size;
      if (real_stack_size < stacksize)
      {
	if (global_system_variables.log_warnings)
          sql_print_warning("Asked for %zu thread stack, but got %zu",
                            stacksize, real_stack_size);
	stacksize= real_stack_size;
      }
    }
  }
#endif /* !EMBEDDED_LIBRARY */

#if defined(__ia64__) || defined(__ia64)
  stacksize /= 2;
#endif
  return stacksize;
}
#endif


3261
#if !defined(__WIN__)
unknown's avatar
unknown committed
3262 3263
#ifndef SA_RESETHAND
#define SA_RESETHAND 0
3264
#endif /* SA_RESETHAND */
unknown's avatar
unknown committed
3265 3266
#ifndef SA_NODEFER
#define SA_NODEFER 0
3267
#endif /* SA_NODEFER */
3268

3269 3270
#ifndef EMBEDDED_LIBRARY

unknown's avatar
unknown committed
3271 3272 3273
static void init_signals(void)
{
  sigset_t set;
3274
  struct sigaction sa;
unknown's avatar
unknown committed
3275 3276
  DBUG_ENTER("init_signals");

3277
  my_sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called!
unknown's avatar
unknown committed
3278

Michael Widenius's avatar
Michael Widenius committed
3279
  if (opt_stack_trace || (test_flags & TEST_CORE_ON_SIGNAL))
unknown's avatar
unknown committed
3280
  {
unknown's avatar
unknown committed
3281 3282 3283 3284
    sa.sa_flags = SA_RESETHAND | SA_NODEFER;
    sigemptyset(&sa.sa_mask);
    sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);

3285
    my_init_stacktrace();
unknown's avatar
unknown committed
3286
#if defined(__amiga__)
3287
    sa.sa_handler=(void(*)())handle_fatal_signal;
unknown's avatar
unknown committed
3288
#else
3289
    sa.sa_handler=handle_fatal_signal;
unknown's avatar
unknown committed
3290
#endif
unknown's avatar
unknown committed
3291
    sigaction(SIGSEGV, &sa, NULL);
3292
    sigaction(SIGABRT, &sa, NULL);
unknown's avatar
unknown committed
3293
#ifdef SIGBUS
unknown's avatar
unknown committed
3294
    sigaction(SIGBUS, &sa, NULL);
unknown's avatar
unknown committed
3295
#endif
unknown's avatar
unknown committed
3296
    sigaction(SIGILL, &sa, NULL);
3297
    sigaction(SIGFPE, &sa, NULL);
unknown's avatar
unknown committed
3298
  }
3299 3300 3301 3302 3303

#ifdef HAVE_GETRLIMIT
  if (test_flags & TEST_CORE_ON_SIGNAL)
  {
    /* Change limits so that we will get a core file */
3304
    STRUCT_RLIMIT rl;
3305
    rl.rlim_cur = rl.rlim_max = (rlim_t) RLIM_INFINITY;
unknown's avatar
unknown committed
3306
    if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
3307
      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");
3308 3309
  }
#endif
unknown's avatar
unknown committed
3310
  (void) sigemptyset(&set);
3311
  my_sigset(SIGPIPE,SIG_IGN);
unknown's avatar
unknown committed
3312
  sigaddset(&set,SIGPIPE);
3313
#ifndef IGNORE_SIGHUP_SIGQUIT
unknown's avatar
unknown committed
3314 3315
  sigaddset(&set,SIGQUIT);
  sigaddset(&set,SIGHUP);
3316 3317
#endif
  sigaddset(&set,SIGTERM);
3318 3319

  /* Fix signals if blocked by parents (can happen on Mac OS X) */
unknown's avatar
unknown committed
3320
  sigemptyset(&sa.sa_mask);
3321 3322 3323 3324 3325 3326
  sa.sa_flags = 0;
  sa.sa_handler = print_signal_warning;
  sigaction(SIGTERM, &sa, (struct sigaction*) 0);
  sa.sa_flags = 0;
  sa.sa_handler = print_signal_warning;
  sigaction(SIGHUP, &sa, (struct sigaction*) 0);
3327 3328
  if (thd_lib_detected != THD_LIB_LT)
    sigaddset(&set,THR_SERVER_ALARM);
3329
  if (test_flags & TEST_SIGINT)
3330
  {
3331 3332
    /* Allow SIGINT to break mysqld. This is for debugging with --gdb */
    my_sigset(SIGINT, end_mysqld_signal);
unknown's avatar
unknown committed
3333
    sigdelset(&set, SIGINT);
3334
  }
3335
  else
3336
  {
3337
    sigaddset(&set,SIGINT);
3338 3339 3340 3341
#ifdef SIGTSTP
    sigaddset(&set,SIGTSTP);
#endif
  }
unknown's avatar
unknown committed
3342

3343 3344
  sigprocmask(SIG_SETMASK,&set,NULL);
  pthread_sigmask(SIG_SETMASK,&set,NULL);
3345 3346 3347 3348 3349 3350 3351 3352 3353
  DBUG_VOID_RETURN;
}


static void start_signal_handler(void)
{
  int error;
  pthread_attr_t thr_attr;
  DBUG_ENTER("start_signal_handler");
unknown's avatar
unknown committed
3354 3355 3356 3357

  (void) pthread_attr_init(&thr_attr);
  pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_SYSTEM);
  (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
3358
  (void) my_setstacksize(&thr_attr,my_thread_stack_size);
unknown's avatar
unknown committed
3359

Marc Alff's avatar
Marc Alff committed
3360
  mysql_mutex_lock(&LOCK_thread_count);
Marc Alff's avatar
Marc Alff committed
3361 3362
  if ((error= mysql_thread_create(key_thread_signal_hand,
                                  &signal_thread, &thr_attr, signal_hand, 0)))
unknown's avatar
unknown committed
3363 3364 3365 3366 3367
  {
    sql_print_error("Can't create interrupt-thread (error %d, errno: %d)",
		    error,errno);
    exit(1);
  }
Marc Alff's avatar
Marc Alff committed
3368 3369
  mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
3370 3371 3372 3373 3374 3375

  (void) pthread_attr_destroy(&thr_attr);
  DBUG_VOID_RETURN;
}


unknown's avatar
unknown committed
3376
/** This threads handles all signals and alarms. */
unknown's avatar
unknown committed
3377
/* ARGSUSED */
3378
pthread_handler_t signal_hand(void *arg __attribute__((unused)))
unknown's avatar
unknown committed
3379 3380 3381 3382 3383
{
  sigset_t set;
  int sig;
  my_thread_init();				// Init new thread
  DBUG_ENTER("signal_hand");
unknown's avatar
unknown committed
3384 3385
  signal_thread_in_use= 1;

unknown's avatar
unknown committed
3386 3387
  /*
    Setup alarm handler
3388 3389
    This should actually be '+ max_number_of_slaves' instead of +10,
    but the +10 should be quite safe.
unknown's avatar
unknown committed
3390
  */
Sergei Golubchik's avatar
Sergei Golubchik committed
3391
  init_thr_alarm(thread_scheduler->max_threads + extra_max_connections +
3392
		 global_system_variables.max_insert_delayed_threads + 10);
3393
  if (test_flags & TEST_SIGINT)
3394
  {
3395 3396 3397
    /* Allow SIGINT to break mysqld. This is for debugging with --gdb */
    (void) sigemptyset(&set);
    (void) sigaddset(&set,SIGINT);
3398 3399
    (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL);
  }
unknown's avatar
unknown committed
3400 3401 3402 3403
  (void) sigemptyset(&set);			// Setup up SIGINT for debug
#ifdef USE_ONE_SIGNAL_HAND
  (void) sigaddset(&set,THR_SERVER_ALARM);	// For alarms
#endif
3404
#ifndef IGNORE_SIGHUP_SIGQUIT
unknown's avatar
unknown committed
3405 3406
  (void) sigaddset(&set,SIGQUIT);
  (void) sigaddset(&set,SIGHUP);
3407 3408
#endif
  (void) sigaddset(&set,SIGTERM);
unknown's avatar
unknown committed
3409 3410 3411
  (void) sigaddset(&set,SIGTSTP);

  /* Save pid to this process (or thread on Linux) */
3412
  if (!opt_bootstrap)
3413 3414
    create_pid_file();

3415 3416 3417 3418 3419
  /*
    signal to start_signal_handler that we are ready
    This works by waiting for start_signal_handler to free mutex,
    after which we signal it that we are ready.
    At this pointer there is no other threads running, so there
Marc Alff's avatar
Marc Alff committed
3420
    should not be any other mysql_cond_signal() calls.
3421
  */
Marc Alff's avatar
Marc Alff committed
3422 3423 3424
  mysql_mutex_lock(&LOCK_thread_count);
  mysql_mutex_unlock(&LOCK_thread_count);
  mysql_cond_broadcast(&COND_thread_count);
unknown's avatar
unknown committed
3425

3426
  (void) pthread_sigmask(SIG_BLOCK,&set,NULL);
unknown's avatar
unknown committed
3427 3428 3429 3430 3431
  for (;;)
  {
    int error;					// Used when debugging
    if (shutdown_in_progress && !abort_loop)
    {
3432
      sig= SIGTERM;
unknown's avatar
unknown committed
3433 3434 3435 3436 3437
      error=0;
    }
    else
      while ((error=my_sigwait(&set,&sig)) == EINTR) ;
    if (cleanup_done)
3438
    {
3439
      DBUG_PRINT("quit",("signal_handler: calling my_thread_end()"));
3440
      my_thread_end();
3441
      DBUG_LEAVE;                               // Must match DBUG_ENTER()
Sergei Golubchik's avatar
Sergei Golubchik committed
3442
      signal_thread_in_use= 0;
unknown's avatar
unknown committed
3443
      pthread_exit(0);				// Safety
3444
      return 0;                                 // Avoid compiler warnings
3445
    }
unknown's avatar
unknown committed
3446 3447 3448 3449 3450
    switch (sig) {
    case SIGTERM:
    case SIGQUIT:
    case SIGKILL:
#ifdef EXTRA_DEBUG
3451
      sql_print_information("Got signal %d to shutdown mysqld",sig);
unknown's avatar
unknown committed
3452
#endif
3453
      /* switch to the old log message processing */
Monty's avatar
Monty committed
3454
      logger.set_handlers(LOG_FILE, global_system_variables.sql_log_slow ? LOG_FILE:LOG_NONE,
3455
                          opt_log ? LOG_FILE:LOG_NONE);
unknown's avatar
unknown committed
3456 3457 3458 3459
      DBUG_PRINT("info",("Got signal: %d  abort_loop: %d",sig,abort_loop));
      if (!abort_loop)
      {
	abort_loop=1;				// mark abort for threads
3460
#ifdef HAVE_PSI_THREAD_INTERFACE
3461
        /* Delete the instrumentation for the signal thread */
3462
        PSI_THREAD_CALL(delete_current_thread)();
3463
#endif
unknown's avatar
unknown committed
3464 3465
#ifdef USE_ONE_SIGNAL_HAND
	pthread_t tmp;
3466 3467 3468 3469 3470 3471
        if ((error= mysql_thread_create(0, /* Not instrumented */
                                        &tmp, &connection_attrib,
                                        kill_server_thread,
                                        (void*) &sig)))
          sql_print_error("Can't create thread to kill server (errno= %d)",
                          error);
unknown's avatar
unknown committed
3472
#else
unknown's avatar
unknown committed
3473
	kill_server((void*) sig);	// MIT THREAD has a alarm thread
unknown's avatar
unknown committed
3474 3475 3476 3477
#endif
      }
      break;
    case SIGHUP:
unknown's avatar
unknown committed
3478 3479
      if (!abort_loop)
      {
3480
        int not_used;
unknown's avatar
Merge  
unknown committed
3481
	mysql_print_status();		// Print some debug info
unknown's avatar
unknown committed
3482 3483
	reload_acl_and_cache((THD*) 0,
			     (REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |
unknown's avatar
Merge  
unknown committed
3484
			      REFRESH_GRANT |
unknown's avatar
unknown committed
3485
			      REFRESH_THREADS | REFRESH_HOSTS),
unknown's avatar
unknown committed
3486
			     (TABLE_LIST*) 0, &not_used); // Flush logs
unknown's avatar
unknown committed
3487
      }
3488
      /* reenable logs after the options were reloaded */
3489 3490 3491
      if (log_output_options & LOG_NONE)
      {
        logger.set_handlers(LOG_FILE,
Monty's avatar
Monty committed
3492 3493
                            global_system_variables.sql_log_slow ?
                            LOG_TABLE : LOG_NONE,
3494 3495 3496 3497 3498
                            opt_log ? LOG_TABLE : LOG_NONE);
      }
      else
      {
        logger.set_handlers(LOG_FILE,
Monty's avatar
Monty committed
3499 3500
                            global_system_variables.sql_log_slow ?
                            log_output_options : LOG_NONE,
3501 3502
                            opt_log ? log_output_options : LOG_NONE);
      }
unknown's avatar
unknown committed
3503 3504 3505 3506 3507 3508 3509 3510
      break;
#ifdef USE_ONE_SIGNAL_HAND
    case THR_SERVER_ALARM:
      process_alarm(sig);			// Trigger alarms.
      break;
#endif
    default:
#ifdef EXTRA_DEBUG
3511
      sql_print_warning("Got signal: %d  error: %d",sig,error); /* purecov: tested */
unknown's avatar
unknown committed
3512 3513 3514 3515 3516 3517 3518
#endif
      break;					/* purecov: tested */
    }
  }
  return(0);					/* purecov: deadcode */
}

unknown's avatar
unknown committed
3519
static void check_data_home(const char *path)
unknown's avatar
unknown committed
3520
{}
unknown's avatar
unknown committed
3521

3522
#endif /*!EMBEDDED_LIBRARY*/
unknown's avatar
unknown committed
3523 3524 3525
#endif	/* __WIN__*/


unknown's avatar
unknown committed
3526
/**
unknown's avatar
Merge  
unknown committed
3527
  All global error messages are sent here where the first one is stored
unknown's avatar
unknown committed
3528
  for the client.
unknown's avatar
unknown committed
3529 3530
*/
/* ARGSUSED */
Marc Alff's avatar
Marc Alff committed
3531
extern "C" void my_message_sql(uint error, const char *str, myf MyFlags);
3532

Marc Alff's avatar
Marc Alff committed
3533
void my_message_sql(uint error, const char *str, myf MyFlags)
unknown's avatar
unknown committed
3534
{
Marc Alff's avatar
Marc Alff committed
3535
  THD *thd= current_thd;
3536
  Sql_condition::enum_warning_level level;
3537
  sql_print_message_func func;
unknown's avatar
unknown committed
3538
  DBUG_ENTER("my_message_sql");
3539 3540
  DBUG_PRINT("error", ("error: %u  message: '%s'  Flag: %lu", error, str,
                       MyFlags));
3541 3542

  DBUG_ASSERT(str != NULL);
3543
  DBUG_ASSERT(error != 0);
3544

3545 3546
  if (MyFlags & ME_JUST_INFO)
  {
3547
    level= Sql_condition::WARN_LEVEL_NOTE;
3548 3549 3550 3551
    func= sql_print_information;
  }
  else if (MyFlags & ME_JUST_WARNING)
  {
3552
    level= Sql_condition::WARN_LEVEL_WARN;
3553 3554 3555 3556
    func= sql_print_warning;
  }
  else
  {
3557
    level= Sql_condition::WARN_LEVEL_ERROR;
3558 3559
    func= sql_print_error;
  }
3560

Marc Alff's avatar
Marc Alff committed
3561
  if (thd)
unknown's avatar
unknown committed
3562
  {
Marc Alff's avatar
Marc Alff committed
3563 3564
    if (MyFlags & ME_FATALERROR)
      thd->is_fatal_error= 1;
Sergei Golubchik's avatar
Sergei Golubchik committed
3565
    (void) thd->raise_condition(error, NULL, level, str);
unknown's avatar
unknown committed
3566
  }
3567 3568
  else
    mysql_audit_general(0, MYSQL_AUDIT_GENERAL_ERROR, error, str);
3569 3570

  /* When simulating OOM, skip writing to error log to avoid mtr errors */
3571
  DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_VOID_RETURN;);
3572

3573
  if (!thd || thd->log_all_errors || (MyFlags & ME_NOREFRESH))
3574
    (*func)("%s: %s", my_progname_short, str); /* purecov: inspected */
Marc Alff's avatar
Marc Alff committed
3575
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
3576 3577
}

3578

3579 3580
extern "C" void *my_str_malloc_mysqld(size_t size);
extern "C" void my_str_free_mysqld(void *ptr);
3581
extern "C" void *my_str_realloc_mysqld(void *ptr, size_t size);
3582 3583

void *my_str_malloc_mysqld(size_t size)
3584 3585 3586 3587 3588
{
  return my_malloc(size, MYF(MY_FAE));
}


3589
void my_str_free_mysqld(void *ptr)
3590
{
3591
  my_free(ptr);
3592
}
3593 3594 3595 3596 3597

void *my_str_realloc_mysqld(void *ptr, size_t size)
{
  return my_realloc(ptr, size, MYF(MY_FAE));
}
3598 3599


unknown's avatar
unknown committed
3600 3601
#ifdef __WIN__

3602
pthread_handler_t handle_shutdown(void *arg)
unknown's avatar
unknown committed
3603 3604 3605 3606 3607 3608
{
  MSG msg;
  my_thread_init();

  /* this call should create the message queue for this thread */
  PeekMessage(&msg, NULL, 1, 65534,PM_NOREMOVE);
unknown's avatar
unknown committed
3609
#if !defined(EMBEDDED_LIBRARY)
unknown's avatar
unknown committed
3610
  if (WaitForSingleObject(hEventShutdown,INFINITE)==WAIT_OBJECT_0)
3611
#endif /* EMBEDDED_LIBRARY */
unknown's avatar
unknown committed
3612 3613 3614 3615 3616
     kill_server(MYSQL_KILL_SIGNAL);
  return 0;
}
#endif

3617
#include <mysqld_default_groups.h>
unknown's avatar
Merge  
unknown committed
3618

3619
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
3620 3621
static const int load_default_groups_sz=
sizeof(load_default_groups)/sizeof(load_default_groups[0]);
unknown's avatar
Merge  
unknown committed
3622
#endif
unknown's avatar
unknown committed
3623

unknown's avatar
unknown committed
3624

3625
#ifndef EMBEDDED_LIBRARY
3626 3627 3628
/**
  This function is used to check for stack overrun for pathological
  cases of  regular expressions and 'like' expressions.
3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643
*/
extern "C" int
check_enough_stack_size_slow()
{
  uchar stack_top;
  THD *my_thd= current_thd;
  if (my_thd != NULL)
    return check_stack_overrun(my_thd, STACK_MIN_SIZE * 2, &stack_top);
  return 0;
}


/*
  The call to current_thd in check_enough_stack_size_slow is quite expensive,
  so we try to avoid it for the normal cases.
3644 3645 3646 3647 3648
  The size of  each stack frame for the wildcmp() routines is ~128 bytes,
  so checking  *every* recursive call is not necessary.
 */
extern "C" int
check_enough_stack_size(int recurse_level)
3649
{
3650 3651
  if (recurse_level % 16 != 0)
    return 0;
3652
  return check_enough_stack_size_slow();
3653 3654 3655 3656
}
#endif


3657 3658 3659 3660 3661 3662 3663 3664

/*
   Initialize my_str_malloc() and my_str_free()
*/
static void init_libstrings()
{
  my_str_malloc= &my_str_malloc_mysqld;
  my_str_free= &my_str_free_mysqld;
Alexander Barkov's avatar
Alexander Barkov committed
3665
  my_str_realloc= &my_str_realloc_mysqld;
3666 3667 3668
#ifndef EMBEDDED_LIBRARY
  my_string_stack_guard= check_enough_stack_size;
#endif
3669
}
3670 3671 3672 3673 3674 3675 3676 3677


static void init_pcre()
{
  pcre_malloc= pcre_stack_malloc= my_str_malloc_mysqld;
  pcre_free= pcre_stack_free= my_str_free_mysqld;
#ifndef EMBEDDED_LIBRARY
  pcre_stack_guard= check_enough_stack_size_slow;
3678
#endif
3679
}
3680 3681


unknown's avatar
unknown committed
3682 3683
/**
  Initialize one of the global date/time format variables.
3684

unknown's avatar
unknown committed
3685 3686
  @param format_type		What kind of format should be supported
  @param var_ptr		Pointer to variable that should be updated
unknown's avatar
Merge  
unknown committed
3687

unknown's avatar
unknown committed
3688
  @retval
3689
    0 ok
unknown's avatar
unknown committed
3690
  @retval
3691 3692 3693
    1 error
*/

unknown's avatar
unknown committed
3694
static bool init_global_datetime_format(timestamp_type format_type,
3695
                                        DATE_TIME_FORMAT *format)
3696
{
3697 3698 3699 3700 3701
  /*
    Get command line option
    format->format.str is already set by my_getopt
  */
  format->format.length= strlen(format->format.str);
3702

3703
  if (parse_date_time_format(format_type, format))
3704
  {
3705 3706 3707
    fprintf(stderr, "Wrong date/time format specifier: %s\n",
            format->format.str);
    return true;
3708
  }
3709
  return false;
3710 3711
}

unknown's avatar
unknown committed
3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722
SHOW_VAR com_status_vars[]= {
  {"admin_commands",       (char*) offsetof(STATUS_VAR, com_other), SHOW_LONG_STATUS},
  {"alter_db",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_DB]), SHOW_LONG_STATUS},
  {"alter_db_upgrade",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_DB_UPGRADE]), SHOW_LONG_STATUS},
  {"alter_event",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_EVENT]), SHOW_LONG_STATUS},
  {"alter_function",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_FUNCTION]), SHOW_LONG_STATUS},
  {"alter_procedure",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_PROCEDURE]), SHOW_LONG_STATUS},
  {"alter_server",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_SERVER]), SHOW_LONG_STATUS},
  {"alter_table",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_TABLE]), SHOW_LONG_STATUS},
  {"alter_tablespace",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_TABLESPACE]), SHOW_LONG_STATUS},
  {"analyze",              (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ANALYZE]), SHOW_LONG_STATUS},
3723
  {"assign_to_keycache",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ASSIGN_TO_KEYCACHE]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3724 3725 3726 3727 3728 3729 3730 3731
  {"begin",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BEGIN]), SHOW_LONG_STATUS},
  {"binlog",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BINLOG_BASE64_EVENT]), SHOW_LONG_STATUS},
  {"call_procedure",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CALL]), SHOW_LONG_STATUS},
  {"change_db",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHANGE_DB]), SHOW_LONG_STATUS},
  {"change_master",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHANGE_MASTER]), SHOW_LONG_STATUS},
  {"check",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHECK]), SHOW_LONG_STATUS},
  {"checksum",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHECKSUM]), SHOW_LONG_STATUS},
  {"commit",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_COMMIT]), SHOW_LONG_STATUS},
3732
  {"compound_sql",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_COMPOUND]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3733 3734 3735 3736 3737
  {"create_db",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_DB]), SHOW_LONG_STATUS},
  {"create_event",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_EVENT]), SHOW_LONG_STATUS},
  {"create_function",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_SPFUNCTION]), SHOW_LONG_STATUS},
  {"create_index",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_INDEX]), SHOW_LONG_STATUS},
  {"create_procedure",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_PROCEDURE]), SHOW_LONG_STATUS},
3738
  {"create_role",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_ROLE]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753
  {"create_server",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_SERVER]), SHOW_LONG_STATUS},
  {"create_table",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_TABLE]), SHOW_LONG_STATUS},
  {"create_trigger",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_TRIGGER]), SHOW_LONG_STATUS},
  {"create_udf",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_FUNCTION]), SHOW_LONG_STATUS},
  {"create_user",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_USER]), SHOW_LONG_STATUS},
  {"create_view",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_VIEW]), SHOW_LONG_STATUS},
  {"dealloc_sql",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DEALLOCATE_PREPARE]), SHOW_LONG_STATUS},
  {"delete",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DELETE]), SHOW_LONG_STATUS},
  {"delete_multi",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DELETE_MULTI]), SHOW_LONG_STATUS},
  {"do",                   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DO]), SHOW_LONG_STATUS},
  {"drop_db",              (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_DB]), SHOW_LONG_STATUS},
  {"drop_event",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_EVENT]), SHOW_LONG_STATUS},
  {"drop_function",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_FUNCTION]), SHOW_LONG_STATUS},
  {"drop_index",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_INDEX]), SHOW_LONG_STATUS},
  {"drop_procedure",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_PROCEDURE]), SHOW_LONG_STATUS},
3754
  {"drop_role",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_ROLE]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3755 3756 3757 3758 3759 3760 3761 3762
  {"drop_server",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_SERVER]), SHOW_LONG_STATUS},
  {"drop_table",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_TABLE]), SHOW_LONG_STATUS},
  {"drop_trigger",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_TRIGGER]), SHOW_LONG_STATUS},
  {"drop_user",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_USER]), SHOW_LONG_STATUS},
  {"drop_view",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_VIEW]), SHOW_LONG_STATUS},
  {"empty_query",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EMPTY_QUERY]), SHOW_LONG_STATUS},
  {"execute_sql",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EXECUTE]), SHOW_LONG_STATUS},
  {"flush",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_FLUSH]), SHOW_LONG_STATUS},
3763
  {"get_diagnostics",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_GET_DIAGNOSTICS]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3764
  {"grant",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_GRANT]), SHOW_LONG_STATUS},
3765
  {"grant_role",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_GRANT_ROLE]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787
  {"ha_close",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_CLOSE]), SHOW_LONG_STATUS},
  {"ha_open",              (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_OPEN]), SHOW_LONG_STATUS},
  {"ha_read",              (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_READ]), SHOW_LONG_STATUS},
  {"help",                 (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HELP]), SHOW_LONG_STATUS},
  {"insert",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_INSERT]), SHOW_LONG_STATUS},
  {"insert_select",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_INSERT_SELECT]), SHOW_LONG_STATUS},
  {"install_plugin",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_INSTALL_PLUGIN]), SHOW_LONG_STATUS},
  {"kill",                 (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_KILL]), SHOW_LONG_STATUS},
  {"load",                 (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOAD]), SHOW_LONG_STATUS},
  {"lock_tables",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOCK_TABLES]), SHOW_LONG_STATUS},
  {"optimize",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_OPTIMIZE]), SHOW_LONG_STATUS},
  {"preload_keys",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PRELOAD_KEYS]), SHOW_LONG_STATUS},
  {"prepare_sql",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PREPARE]), SHOW_LONG_STATUS},
  {"purge",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PURGE]), SHOW_LONG_STATUS},
  {"purge_before_date",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PURGE_BEFORE]), SHOW_LONG_STATUS},
  {"release_savepoint",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RELEASE_SAVEPOINT]), SHOW_LONG_STATUS},
  {"rename_table",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RENAME_TABLE]), SHOW_LONG_STATUS},
  {"rename_user",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RENAME_USER]), SHOW_LONG_STATUS},
  {"repair",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPAIR]), SHOW_LONG_STATUS},
  {"replace",              (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPLACE]), SHOW_LONG_STATUS},
  {"replace_select",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPLACE_SELECT]), SHOW_LONG_STATUS},
  {"reset",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RESET]), SHOW_LONG_STATUS},
Marc Alff's avatar
Marc Alff committed
3788
  {"resignal",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RESIGNAL]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3789 3790
  {"revoke",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REVOKE]), SHOW_LONG_STATUS},
  {"revoke_all",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REVOKE_ALL]), SHOW_LONG_STATUS},
3791
  {"revoke_role",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REVOKE_ROLE]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813
  {"rollback",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ROLLBACK]), SHOW_LONG_STATUS},
  {"rollback_to_savepoint",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ROLLBACK_TO_SAVEPOINT]), SHOW_LONG_STATUS},
  {"savepoint",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SAVEPOINT]), SHOW_LONG_STATUS},
  {"select",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SELECT]), SHOW_LONG_STATUS},
  {"set_option",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SET_OPTION]), SHOW_LONG_STATUS},
  {"show_authors",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_AUTHORS]), SHOW_LONG_STATUS},
  {"show_binlog_events",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOG_EVENTS]), SHOW_LONG_STATUS},
  {"show_binlogs",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOGS]), SHOW_LONG_STATUS},
  {"show_charsets",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CHARSETS]), SHOW_LONG_STATUS},
  {"show_collations",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLLATIONS]), SHOW_LONG_STATUS},
  {"show_contributors",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CONTRIBUTORS]), SHOW_LONG_STATUS},
  {"show_create_db",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_DB]), SHOW_LONG_STATUS},
  {"show_create_event",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_EVENT]), SHOW_LONG_STATUS},
  {"show_create_func",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_FUNC]), SHOW_LONG_STATUS},
  {"show_create_proc",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_PROC]), SHOW_LONG_STATUS},
  {"show_create_table",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE]), SHOW_LONG_STATUS},
  {"show_create_trigger",  (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_TRIGGER]), SHOW_LONG_STATUS},
  {"show_databases",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_DATABASES]), SHOW_LONG_STATUS},
  {"show_engine_logs",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_LOGS]), SHOW_LONG_STATUS},
  {"show_engine_mutex",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_MUTEX]), SHOW_LONG_STATUS},
  {"show_engine_status",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_STATUS]), SHOW_LONG_STATUS},
  {"show_errors",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ERRORS]), SHOW_LONG_STATUS},
3814
  {"show_events",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_EVENTS]), SHOW_LONG_STATUS},
3815
  {"show_explain",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_EXPLAIN]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3816 3817 3818 3819 3820
  {"show_fields",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_FIELDS]), SHOW_LONG_STATUS},
#ifndef DBUG_OFF
  {"show_function_code",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_FUNC_CODE]), SHOW_LONG_STATUS},
#endif
  {"show_function_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS_FUNC]), SHOW_LONG_STATUS},
3821
  {"show_generic",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_GENERIC]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3822
  {"show_grants",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_GRANTS]), SHOW_LONG_STATUS},
3823
  {"show_keys",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_KEYS]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3824 3825 3826 3827 3828 3829 3830 3831 3832
  {"show_master_status",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_MASTER_STAT]), SHOW_LONG_STATUS},
  {"show_open_tables",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_OPEN_TABLES]), SHOW_LONG_STATUS},
  {"show_plugins",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PLUGINS]), SHOW_LONG_STATUS},
  {"show_privileges",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PRIVILEGES]), SHOW_LONG_STATUS},
#ifndef DBUG_OFF
  {"show_procedure_code",  (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROC_CODE]), SHOW_LONG_STATUS},
#endif
  {"show_procedure_status",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS_PROC]), SHOW_LONG_STATUS},
  {"show_processlist",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROCESSLIST]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3833 3834
  {"show_profile",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROFILE]), SHOW_LONG_STATUS},
  {"show_profiles",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROFILES]), SHOW_LONG_STATUS},
3835
  {"show_relaylog_events", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_RELAYLOG_EVENTS]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3836 3837 3838 3839 3840 3841 3842 3843 3844
  {"show_slave_hosts",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_HOSTS]), SHOW_LONG_STATUS},
  {"show_slave_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_STAT]), SHOW_LONG_STATUS},
  {"show_status",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS},
  {"show_storage_engines", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STORAGE_ENGINES]), SHOW_LONG_STATUS},
  {"show_table_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS},
  {"show_tables",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLES]), SHOW_LONG_STATUS},
  {"show_triggers",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TRIGGERS]), SHOW_LONG_STATUS},
  {"show_variables",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS},
  {"show_warnings",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
3845
  {"shutdown",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHUTDOWN]), SHOW_LONG_STATUS},
3846
  {"signal",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SIGNAL]), SHOW_LONG_STATUS},
3847 3848
  {"start_all_slaves",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_ALL_START]), SHOW_LONG_STATUS},
  {"start_slave",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_START]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3849 3850 3851 3852
  {"stmt_close",           (char*) offsetof(STATUS_VAR, com_stmt_close), SHOW_LONG_STATUS},
  {"stmt_execute",         (char*) offsetof(STATUS_VAR, com_stmt_execute), SHOW_LONG_STATUS},
  {"stmt_fetch",           (char*) offsetof(STATUS_VAR, com_stmt_fetch), SHOW_LONG_STATUS},
  {"stmt_prepare",         (char*) offsetof(STATUS_VAR, com_stmt_prepare), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3853
  {"stmt_reprepare",       (char*) offsetof(STATUS_VAR, com_stmt_reprepare), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3854 3855
  {"stmt_reset",           (char*) offsetof(STATUS_VAR, com_stmt_reset), SHOW_LONG_STATUS},
  {"stmt_send_long_data",  (char*) offsetof(STATUS_VAR, com_stmt_send_long_data), SHOW_LONG_STATUS},
3856 3857
  {"stop_all_slaves",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_ALL_STOP]), SHOW_LONG_STATUS},
  {"stop_slave",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_STOP]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868
  {"truncate",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_TRUNCATE]), SHOW_LONG_STATUS},
  {"uninstall_plugin",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNINSTALL_PLUGIN]), SHOW_LONG_STATUS},
  {"unlock_tables",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNLOCK_TABLES]), SHOW_LONG_STATUS},
  {"update",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UPDATE]), SHOW_LONG_STATUS},
  {"update_multi",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UPDATE_MULTI]), SHOW_LONG_STATUS},
  {"xa_commit",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_COMMIT]),SHOW_LONG_STATUS},
  {"xa_end",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_END]),SHOW_LONG_STATUS},
  {"xa_prepare",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_PREPARE]),SHOW_LONG_STATUS},
  {"xa_recover",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_RECOVER]),SHOW_LONG_STATUS},
  {"xa_rollback",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_ROLLBACK]),SHOW_LONG_STATUS},
  {"xa_start",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_START]),SHOW_LONG_STATUS},
3869
  {NullS, NullS, SHOW_LONG}
unknown's avatar
unknown committed
3870
};
3871

Sergei Golubchik's avatar
Sergei Golubchik committed
3872

3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928
#ifdef HAVE_PSI_STATEMENT_INTERFACE
PSI_statement_info sql_statement_info[(uint) SQLCOM_END + 1];
PSI_statement_info com_statement_info[(uint) COM_END + 1];

/**
  Initialize the command names array.
  Since we do not want to maintain a separate array,
  this is populated from data mined in com_status_vars,
  which already has one name for each command.
*/
void init_sql_statement_info()
{
  char *first_com= (char*) offsetof(STATUS_VAR, com_stat[0]);
  char *last_com= (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_END]);
  int record_size= (char*) offsetof(STATUS_VAR, com_stat[1])
                   - (char*) offsetof(STATUS_VAR, com_stat[0]);
  char *ptr;
  uint i;
  uint com_index;

  static const char* dummy= "";
  for (i= 0; i < ((uint) SQLCOM_END + 1); i++)
  {
    sql_statement_info[i].m_name= dummy;
    sql_statement_info[i].m_flags= 0;
  }

  SHOW_VAR *var= &com_status_vars[0];
  while (var->name != NULL)
  {
    ptr= var->value;
    if ((first_com <= ptr) && (ptr <= last_com))
    {
      com_index= ((int)(ptr - first_com))/record_size;
      DBUG_ASSERT(com_index < (uint) SQLCOM_END);
      sql_statement_info[com_index].m_name= var->name;
    }
    var++;
  }

  DBUG_ASSERT(strcmp(sql_statement_info[(uint) SQLCOM_SELECT].m_name, "select") == 0);
  DBUG_ASSERT(strcmp(sql_statement_info[(uint) SQLCOM_SIGNAL].m_name, "signal") == 0);

  sql_statement_info[(uint) SQLCOM_END].m_name= "error";
}

void init_com_statement_info()
{
  uint index;

  for (index= 0; index < (uint) COM_END + 1; index++)
  {
    com_statement_info[index].m_name= command_name[index].str;
    com_statement_info[index].m_flags= 0;
  }

Sergei Golubchik's avatar
Sergei Golubchik committed
3929
  /* "statement/abstract/query" can mutate into "statement/sql/..." */
3930 3931 3932 3933 3934
  com_statement_info[(uint) COM_QUERY].m_flags= PSI_FLAG_MUTABLE;
}
#endif


3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951
#ifdef SAFEMALLOC
/*
  Return the id for the current THD, to allow safemalloc to associate
  the memory with the right id.
*/

extern "C" my_thread_id mariadb_dbug_id()
{
  THD *thd;
  if ((thd= current_thd))
  {
    return thd->thread_id;
  }
  return my_thread_dbug_id();
}
#endif /* SAFEMALLOC */

Sergei Golubchik's avatar
Sergei Golubchik committed
3952 3953 3954 3955
/* Thread Mem Usage By P.Linux */
extern "C" {
static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific)
{
3956
  THD *thd= current_thd;
Sergei Golubchik's avatar
Sergei Golubchik committed
3957
  /* If thread specific memory */
3958
  if (likely(is_thread_specific))
Sergei Golubchik's avatar
Sergei Golubchik committed
3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971
  {
    if (mysqld_server_initialized || thd)
    {
      /*
        THD may not be set if we are called from my_net_init() before THD
        thread has started.
        However, this should never happen, so better to assert and
        fix this.
      */
      DBUG_ASSERT(thd);
      if (thd)
      {
        DBUG_PRINT("info", ("memory_used: %lld  size: %lld",
3972 3973 3974 3975
                            (longlong) thd->status_var.local_memory_used,
                            size));
        thd->status_var.local_memory_used+= size;
        DBUG_ASSERT((longlong) thd->status_var.local_memory_used >= 0);
Sergei Golubchik's avatar
Sergei Golubchik committed
3976 3977 3978
      }
    }
  }
3979 3980 3981 3982 3983 3984 3985 3986
  else if (likely(thd))
    thd->status_var.global_memory_used+= size;
  else
  {
    // workaround for gcc 4.2.4-1ubuntu4 -fPIE (from DEB_BUILD_HARDENING=1)
    int64 volatile * volatile ptr=&global_status_var.global_memory_used;
    my_atomic_add64_explicit(ptr, size, MY_MEMORY_ORDER_RELAXED);
  }
Sergei Golubchik's avatar
Sergei Golubchik committed
3987 3988 3989
}
}

Marc Alff's avatar
Marc Alff committed
3990
static int init_common_variables()
unknown's avatar
unknown committed
3991
{
unknown's avatar
unknown committed
3992
  umask(((~my_umask) & 0666));
unknown's avatar
unknown committed
3993 3994 3995 3996 3997 3998
  connection_errors_select= 0;
  connection_errors_accept= 0;
  connection_errors_tcpwrap= 0;
  connection_errors_internal= 0;
  connection_errors_max_connection= 0;
  connection_errors_peer_addr= 0;
unknown's avatar
Merge  
unknown committed
3999
  my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
Sergei Golubchik's avatar
Sergei Golubchik committed
4000

4001 4002 4003 4004 4005 4006 4007 4008
  if (pthread_key_create(&THR_THD,NULL) ||
      pthread_key_create(&THR_MALLOC,NULL))
  {
    sql_print_error("Can't create thread-keys");
    return 1;
  }

  set_current_thd(0);
Sergei Golubchik's avatar
Sergei Golubchik committed
4009 4010
  set_malloc_size_cb(my_malloc_size_cb_func);

4011
  init_libstrings();
unknown's avatar
unknown committed
4012 4013
  tzset();			// Set tzname

4014
  sf_leaking_memory= 0; // no memory leaks from now on
4015 4016 4017
#ifdef SAFEMALLOC
  sf_malloc_dbug_id= mariadb_dbug_id;
#endif
4018

unknown's avatar
SCRUM  
unknown committed
4019
  max_system_variables.pseudo_thread_id= (ulong)~0;
4020
  server_start_time= flush_status_time= my_time(0);
4021

4022
  global_rpl_filter= new Rpl_filter;
4023
  binlog_filter= new Rpl_filter;
4024
  if (!global_rpl_filter || !binlog_filter)
4025 4026
  {
    sql_perror("Could not allocate replication and binlog filters");
4027
    return 1;
4028 4029
  }

Sergei Golubchik's avatar
Sergei Golubchik committed
4030 4031 4032 4033
#if defined(HAVE_POOL_OF_THREADS) && !defined(_WIN32)
  SYSVAR_AUTOSIZE(threadpool_size, my_getncpus());
#endif

4034 4035
  if (init_thread_environment() ||
      mysql_init_variables())
unknown's avatar
unknown committed
4036
    return 1;
unknown's avatar
unknown committed
4037

4038 4039 4040
  if (ignore_db_dirs_init())
    return 1;

unknown's avatar
unknown committed
4041
#ifdef HAVE_TZNAME
4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054
  struct tm tm_tmp;
  localtime_r(&server_start_time,&tm_tmp);
  const char *tz_name=  tzname[tm_tmp.tm_isdst != 0 ? 1 : 0];
#ifdef _WIN32
  /*
    Time zone name may be localized and contain non-ASCII characters,
    Convert from ANSI encoding to UTF8.
  */
  wchar_t wtz_name[sizeof(system_time_zone)];
  mbstowcs(wtz_name, tz_name, sizeof(system_time_zone)-1);
  WideCharToMultiByte(CP_UTF8,0, wtz_name, -1, system_time_zone, 
    sizeof(system_time_zone) - 1, NULL, NULL);
#else
4055
  strmake_buf(system_time_zone, tz_name);
4056 4057
#endif /* _WIN32 */
#endif /* HAVE_TZNAME */
4058

4059
  /*
unknown's avatar
unknown committed
4060
    We set SYSTEM time zone as reasonable default and
4061 4062 4063 4064 4065
    also for failure of my_tz_init() and bootstrap mode.
    If user explicitly set time zone with --default-time-zone
    option we will change this value in my_tz_init().
  */
  global_system_variables.time_zone= my_tz_SYSTEM;
unknown's avatar
unknown committed
4066

4067 4068 4069
#ifdef HAVE_PSI_INTERFACE
  /*
    Complete the mysql_bin_log initialization.
4070 4071 4072
    Instrumentation keys are known only after the performance schema
    initialization, and can not be set in the MYSQL_BIN_LOG
    constructor (called before main()).
4073 4074 4075 4076
  */
  mysql_bin_log.set_psi_keys(key_BINLOG_LOCK_index,
                             key_BINLOG_update_cond,
                             key_file_binlog,
4077 4078
                             key_file_binlog_index,
                             key_BINLOG_COND_queue_busy);
4079 4080
#endif

unknown's avatar
unknown committed
4081
  /*
4082
    Init mutexes for the global MYSQL_BIN_LOG objects.
unknown's avatar
unknown committed
4083
    As safe_mutex depends on what MY_INIT() does, we can't init the mutexes of
4084 4085
    global MYSQL_BIN_LOGs in their constructors, because then they would be
    inited before MY_INIT(). So we do it here.
unknown's avatar
unknown committed
4086 4087
  */
  mysql_bin_log.init_pthread_objects();
4088

4089 4090 4091 4092 4093 4094 4095
  /* TODO: remove this when my_time_t is 64 bit compatible */
  if (!IS_TIME_T_VALID_FOR_TIMESTAMP(server_start_time))
  {
    sql_print_error("This MySQL server doesn't support dates later then 2038");
    return 1;
  }

4096 4097
  if (gethostname(glob_hostname,sizeof(glob_hostname)) < 0)
  {
4098 4099 4100 4101
    /*
      Get hostname of computer (used by 'show variables') and as default
      basename for the pid file if --log-basename is not given.
    */
4102 4103
    strmake(glob_hostname, STRING_WITH_LEN("localhost"));
    sql_print_warning("gethostname failed, using '%s' as hostname",
4104
                        glob_hostname);
Sergei Golubchik's avatar
Sergei Golubchik committed
4105
    opt_log_basename= const_cast<char *>("mysql");
4106 4107
  }
  else
Sergei Golubchik's avatar
Sergei Golubchik committed
4108
    opt_log_basename= glob_hostname;
4109

4110
#ifdef WITH_WSREP
4111
  if (wsrep_node_name == 0 || wsrep_node_name[0] == 0)
4112 4113 4114 4115 4116 4117
  {
    my_free((void *)wsrep_node_name);
    wsrep_node_name= my_strdup(glob_hostname, MYF(MY_WME));
  }
#endif /* WITH_WSREP */

Sergei Golubchik's avatar
Sergei Golubchik committed
4118 4119 4120
  strmake(pidfile_name, opt_log_basename, sizeof(pidfile_name)-5);
  strmov(fn_ext(pidfile_name),".pid");		// Add proper extension
  SYSVAR_AUTOSIZE(pidfile_name_ptr, pidfile_name);
4121
  mark_sys_var_value_origin(&opt_tc_log_size, sys_var::AUTO);
unknown's avatar
unknown committed
4122

4123 4124 4125 4126 4127 4128 4129
  /*
    The default-storage-engine entry in my_long_options should have a
    non-null default value. It was earlier intialized as
    (longlong)"MyISAM" in my_long_options but this triggered a
    compiler error in the Sun Studio 12 compiler. As a work-around we
    set the def_value member to 0 in my_long_options and initialize it
    to the correct value here.
4130 4131 4132 4133

    From MySQL 5.5 onwards, the default storage engine is InnoDB
    (except in the embedded server, where the default continues to
    be MyISAM)
4134
  */
4135
#if defined(WITH_INNOBASE_STORAGE_ENGINE) || defined(WITH_XTRADB_STORAGE_ENGINE)
4136
  default_storage_engine= const_cast<char *>("InnoDB");
4137 4138
#else
  default_storage_engine= const_cast<char *>("MyISAM");
4139
#endif
4140
  default_tmp_storage_engine= NULL;
4141

4142 4143 4144
  /*
    Add server status variables to the dynamic list of
    status variables that is shown by SHOW STATUS.
4145
    Later, in plugin_init, and mysql_install_plugin
4146 4147 4148 4149 4150
    new entries could be added to that list.
  */
  if (add_status_vars(status_vars))
    return 1; // an error was already reported

unknown's avatar
unknown committed
4151 4152 4153 4154 4155
#ifndef DBUG_OFF
  /*
    We have few debug-only commands in com_status_vars, only visible in debug
    builds. for simplicity we enable the assert only in debug builds

unknown's avatar
unknown committed
4156
    There are 8 Com_ variables which don't have corresponding SQLCOM_ values:
unknown's avatar
unknown committed
4157 4158 4159 4160 4161 4162 4163 4164
    (TODO strictly speaking they shouldn't be here, should not have Com_ prefix
    that is. Perhaps Stmt_ ? Comstmt_ ? Prepstmt_ ?)

      Com_admin_commands       => com_other
      Com_stmt_close           => com_stmt_close
      Com_stmt_execute         => com_stmt_execute
      Com_stmt_fetch           => com_stmt_fetch
      Com_stmt_prepare         => com_stmt_prepare
unknown's avatar
unknown committed
4165
      Com_stmt_reprepare       => com_stmt_reprepare
unknown's avatar
unknown committed
4166 4167 4168
      Com_stmt_reset           => com_stmt_reset
      Com_stmt_send_long_data  => com_stmt_send_long_data

4169 4170 4171
    With this correction the number of Com_ variables (number of elements in
    the array, excluding the last element - terminator) must match the number
    of SQLCOM_ constants.
unknown's avatar
unknown committed
4172
  */
4173
  compile_time_assert(sizeof(com_status_vars)/sizeof(com_status_vars[0]) - 1 ==
unknown's avatar
unknown committed
4174
                     SQLCOM_END + 8);
unknown's avatar
unknown committed
4175 4176
#endif

Marc Alff's avatar
Marc Alff committed
4177
  if (get_options(&remaining_argc, &remaining_argv))
4178
    return 1;
4179 4180
  set_server_version();

4181
#ifndef EMBEDDED_LIBRARY
4182
  if (opt_abort && !opt_verbose)
4183 4184 4185
    unireg_abort(0);
#endif /*!EMBEDDED_LIBRARY*/

unknown's avatar
unknown committed
4186 4187 4188
  DBUG_PRINT("info",("%s  Ver %s for %s on %s\n",my_progname,
		     server_version, SYSTEM_TYPE,MACHINE_TYPE));

unknown's avatar
Merge  
unknown committed
4189 4190
#ifdef HAVE_LARGE_PAGES
  /* Initialize large page size */
Sergei Golubchik's avatar
Sergei Golubchik committed
4191
  if (opt_large_pages)
unknown's avatar
Merge  
unknown committed
4192
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
4193 4194 4195
    SYSVAR_AUTOSIZE(opt_large_page_size, my_get_large_page_size());
    if (opt_large_page_size)
    {
4196 4197
      DBUG_PRINT("info", ("Large page set, large_page_size = %d",
                 opt_large_page_size));
unknown's avatar
Merge  
unknown committed
4198 4199
      my_use_large_pages= 1;
      my_large_page_size= opt_large_page_size;
Sergei Golubchik's avatar
Sergei Golubchik committed
4200 4201 4202
    }
    else
      SYSVAR_AUTOSIZE(opt_large_pages, 0);
4203
  }
unknown's avatar
Merge  
unknown committed
4204
#endif /* HAVE_LARGE_PAGES */
4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220
#ifdef HAVE_SOLARIS_LARGE_PAGES
#define LARGE_PAGESIZE (4*1024*1024)  /* 4MB */
#define SUPER_LARGE_PAGESIZE (256*1024*1024)  /* 256MB */
  if (opt_large_pages)
  {
  /*
    tell the kernel that we want to use 4/256MB page for heap storage
    and also for the stack. We use 4 MByte as default and if the
    super-large-page is set we increase it to 256 MByte. 256 MByte
    is for server installations with GBytes of RAM memory where
    the MySQL Server will have page caches and other memory regions
    measured in a number of GBytes.
    We use as big pages as possible which isn't bigger than the above
    desired page sizes.
  */
   int nelem;
4221
   size_t max_desired_page_size;
4222
   if (opt_super_large_pages)
4223
     max_desired_page_size= SUPER_LARGE_PAGESIZE;
4224
   else
4225
     max_desired_page_size= LARGE_PAGESIZE;
4226 4227 4228 4229 4230 4231
   nelem = getpagesizes(NULL, 0);
   if (nelem > 0)
   {
     size_t *pagesize = (size_t *) malloc(sizeof(size_t) * nelem);
     if (pagesize != NULL && getpagesizes(pagesize, nelem) > 0)
     {
4232 4233
       size_t max_page_size= 0;
       for (int i= 0; i < nelem; i++)
4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254
       {
         if (pagesize[i] > max_page_size &&
             pagesize[i] <= max_desired_page_size)
            max_page_size= pagesize[i];
       }
       free(pagesize);
       if (max_page_size > 0)
       {
         struct memcntl_mha mpss;

         mpss.mha_cmd= MHA_MAPSIZE_BSSBRK;
         mpss.mha_pagesize= max_page_size;
         mpss.mha_flags= 0;
         memcntl(NULL, 0, MC_HAT_ADVISE, (caddr_t)&mpss, 0, 0);
         mpss.mha_cmd= MHA_MAPSIZE_STACK;
         memcntl(NULL, 0, MC_HAT_ADVISE, (caddr_t)&mpss, 0, 0);
       }
     }
   }
  }
#endif /* HAVE_SOLARIS_LARGE_PAGES */
unknown's avatar
Merge  
unknown committed
4255

unknown's avatar
unknown committed
4256 4257
  /* connections and databases needs lots of files */
  {
4258
    uint files, wanted_files, max_open_files;
4259

4260
    /* MyISAM requires two file handles per table. */
4261
    wanted_files= (10 + max_connections + extra_max_connections +
4262
                   tc_size * 2);
4263 4264 4265 4266 4267 4268 4269 4270 4271 4272
    /*
      We are trying to allocate no less than max_connections*5 file
      handles (i.e. we are trying to set the limit so that they will
      be available).  In addition, we allocate no less than how much
      was already allocated.  However below we report a warning and
      recompute values only if we got less file handles than were
      explicitly requested.  No warning and re-computation occur if we
      can't get max_connections*5 but still got no less than was
      requested (value of wanted_files).
    */
4273
    max_open_files= MY_MAX(MY_MAX(wanted_files,
4274
                            (max_connections + extra_max_connections)*5),
4275 4276
                        open_files_limit);
    files= my_set_max_open_files(max_open_files);
4277 4278

    if (files < wanted_files)
unknown's avatar
unknown committed
4279
    {
4280 4281
      if (!open_files_limit)
      {
4282 4283 4284 4285
        /*
          If we have requested too much file handles than we bring
          max_connections in supported bounds.
        */
Sergei Golubchik's avatar
Sergei Golubchik committed
4286 4287
        SYSVAR_AUTOSIZE(max_connections,
           (ulong) MY_MIN(files-10-TABLE_OPEN_CACHE_MIN*2, max_connections));
4288
        /*
4289
          Decrease tc_size according to max_connections, but
4290
          not below TABLE_OPEN_CACHE_MIN.  Outer MY_MIN() ensures that we
4291
          never increase tc_size automatically (that could
4292 4293
          happen if max_connections is decreased above).
        */
Sergei Golubchik's avatar
Sergei Golubchik committed
4294 4295 4296
        SYSVAR_AUTOSIZE(tc_size, 
                        (ulong) MY_MIN(MY_MAX((files - 10 - max_connections) / 2,
                                              TABLE_OPEN_CACHE_MIN), tc_size));
4297 4298
	DBUG_PRINT("warning",
		   ("Changed limits: max_open_files: %u  max_connections: %ld  table_cache: %ld",
4299
		    files, max_connections, tc_size));
unknown's avatar
unknown committed
4300
	if (global_system_variables.log_warnings)
4301
	  sql_print_warning("Changed limits: max_open_files: %u  max_connections: %ld  table_cache: %ld",
4302
			files, max_connections, tc_size);
4303
      }
unknown's avatar
unknown committed
4304
      else if (global_system_variables.log_warnings)
4305
	sql_print_warning("Could not increase number of max_open_files to more than %u (request: %u)", files, wanted_files);
unknown's avatar
unknown committed
4306
    }
Sergei Golubchik's avatar
Sergei Golubchik committed
4307
    SYSVAR_AUTOSIZE(open_files_limit, files);
unknown's avatar
unknown committed
4308 4309
  }
  unireg_init(opt_specialflag); /* Set up extern variabels */
4310 4311 4312 4313 4314 4315 4316
  if (!(my_default_lc_messages=
        my_locale_by_name(lc_messages)))
  {
    sql_print_error("Unknown locale: '%s'", lc_messages);
    return 1;
  }
  global_system_variables.lc_messages= my_default_lc_messages;
4317 4318
  if (init_errmessage())	/* Read error messages from file */
    return 1;
4319
  init_client_errs();
Sergei Golubchik's avatar
Sergei Golubchik committed
4320
  mysql_library_init(unused,unused,unused); /* for replication */
unknown's avatar
unknown committed
4321
  lex_init();
4322 4323
  if (item_create_init())
    return 1;
unknown's avatar
unknown committed
4324
  item_init();
4325
  init_pcre();
4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352
  /*
    Process a comma-separated character set list and choose
    the first available character set. This is mostly for
    test purposes, to be able to start "mysqld" even if
    the requested character set is not available (see bug#18743).
  */
  for (;;)
  {
    char *next_character_set_name= strchr(default_character_set_name, ',');
    if (next_character_set_name)
      *next_character_set_name++= '\0';
    if (!(default_charset_info=
          get_charset_by_csname(default_character_set_name,
                                MY_CS_PRIMARY, MYF(MY_WME))))
    {
      if (next_character_set_name)
      {
        default_character_set_name= next_character_set_name;
        default_collation_name= 0;          // Ignore collation
      }
      else
        return 1;                           // Eof of the list
    }
    else
      break;
  }

4353 4354
  if (default_collation_name)
  {
unknown's avatar
unknown committed
4355 4356
    CHARSET_INFO *default_collation;
    default_collation= get_charset_by_name(default_collation_name, MYF(0));
unknown's avatar
unknown committed
4357 4358
    if (!default_collation)
    {
4359 4360 4361 4362
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
      buffered_logs.print();
      buffered_logs.cleanup();
#endif
4363
      sql_print_error(ER_DEFAULT(ER_UNKNOWN_COLLATION), default_collation_name);
unknown's avatar
unknown committed
4364 4365 4366
      return 1;
    }
    if (!my_charset_same(default_charset_info, default_collation))
4367
    {
4368
      sql_print_error(ER_DEFAULT(ER_COLLATION_CHARSET_MISMATCH),
4369 4370 4371 4372 4373 4374
		      default_collation_name,
		      default_charset_info->csname);
      return 1;
    }
    default_charset_info= default_collation;
  }
4375 4376 4377 4378
  /* Set collactions that depends on the default collation */
  global_system_variables.collation_server=	 default_charset_info;
  global_system_variables.collation_database=	 default_charset_info;
  global_system_variables.collation_connection=  default_charset_info;
4379
  global_system_variables.character_set_results= default_charset_info;
4380 4381 4382 4383 4384 4385 4386 4387 4388
  if (default_charset_info->mbminlen > 1)
  {
    global_system_variables.character_set_client=  &my_charset_latin1;
    sql_print_warning("Cannot use %s as character_set_client, %s will be used instead",
                      default_charset_info->csname,
                      global_system_variables.character_set_client->csname);
  }
  else
    global_system_variables.character_set_client=  default_charset_info;
4389

4390
  if (!(character_set_filesystem=
unknown's avatar
unknown committed
4391 4392 4393 4394 4395
        get_charset_by_csname(character_set_filesystem_name,
                              MY_CS_PRIMARY, MYF(MY_WME))))
    return 1;
  global_system_variables.character_set_filesystem= character_set_filesystem;

4396 4397 4398
  if (!(my_default_lc_time_names=
        my_locale_by_name(lc_time_names_name)))
  {
unknown's avatar
unknown committed
4399
    sql_print_error("Unknown locale: '%s'", lc_time_names_name);
4400 4401 4402
    return 1;
  }
  global_system_variables.lc_time_names= my_default_lc_time_names;
4403

4404
  /* check log options and issue warnings if needed */
4405 4406
  if (opt_log && opt_logname && *opt_logname &&
      !(log_output_options & (LOG_FILE | LOG_NONE)))
4407 4408
    sql_print_warning("Although a path was specified for the "
                      "--log option, log tables are used. "
4409
                      "To enable logging to files use the --log-output option.");
4410

Monty's avatar
Monty committed
4411 4412
  if (global_system_variables.sql_log_slow && opt_slow_logname &&
      *opt_slow_logname &&
4413
      !(log_output_options & (LOG_FILE | LOG_NONE)))
4414
    sql_print_warning("Although a path was specified for the "
Konstantin Osipov's avatar
Konstantin Osipov committed
4415
                      "--log-slow-queries option, log tables are used. "
4416
                      "To enable logging to files use the --log-output=file option.");
4417

Sergei Golubchik's avatar
Sergei Golubchik committed
4418 4419 4420 4421
  if (!opt_logname || !*opt_logname)
    make_default_log_name(&opt_logname, ".log", false);
  if (!opt_slow_logname || !*opt_slow_logname)
    make_default_log_name(&opt_slow_logname, "-slow.log", false);
4422

4423 4424 4425 4426 4427 4428
#if defined(ENABLED_DEBUG_SYNC)
  /* Initialize the debug sync facility. See debug_sync.cc. */
  if (debug_sync_init())
    return 1; /* purecov: tested */
#endif /* defined(ENABLED_DEBUG_SYNC) */

4429
#if (ENABLE_TEMP_POOL)
4430
  if (use_temp_pool && my_bitmap_init(&temp_pool,0,1024,1))
4431
    return 1;
4432 4433 4434 4435
#else
  use_temp_pool= 0;
#endif

4436
  if (my_dboptions_cache_init())
unknown's avatar
unknown committed
4437 4438
    return 1;

4439 4440 4441 4442 4443 4444
  /*
    Ensure that lower_case_table_names is set on system where we have case
    insensitive names.  If this is not done the users MyISAM tables will
    get corrupted if accesses with names of different case.
  */
  DBUG_PRINT("info", ("lower_case_table_names: %d", lower_case_table_names));
Sergei Golubchik's avatar
Sergei Golubchik committed
4445 4446
  SYSVAR_AUTOSIZE(lower_case_file_system,
                  test_if_case_insensitive(mysql_real_data_home));
4447
  if (!lower_case_table_names && lower_case_file_system == 1)
4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461
  {
    if (lower_case_table_names_used)
    {
      if (global_system_variables.log_warnings)
	sql_print_warning("\
You have forced lower_case_table_names to 0 through a command-line \
option, even though your file system '%s' is case insensitive.  This means \
that you can corrupt a MyISAM table by accessing it with different cases. \
You should consider changing lower_case_table_names to 1 or 2",
			mysql_real_data_home);
    }
    else
    {
      if (global_system_variables.log_warnings)
Sergei Golubchik's avatar
Sergei Golubchik committed
4462 4463 4464
	sql_print_warning("Setting lower_case_table_names=2 because file "
                  "system for %s is case insensitive", mysql_real_data_home);
      SYSVAR_AUTOSIZE(lower_case_table_names, 2);
4465 4466 4467
    }
  }
  else if (lower_case_table_names == 2 &&
4468
           !(lower_case_file_system= (lower_case_file_system == 1)))
4469 4470 4471 4472 4473 4474
  {
    if (global_system_variables.log_warnings)
      sql_print_warning("lower_case_table_names was set to 2, even though your "
                        "the file system '%s' is case sensitive.  Now setting "
                        "lower_case_table_names to 0 to avoid future problems.",
			mysql_real_data_home);
Sergei Golubchik's avatar
Sergei Golubchik committed
4475
    SYSVAR_AUTOSIZE(lower_case_table_names, 0);
4476
  }
4477 4478
  else
  {
4479
    lower_case_file_system= (lower_case_file_system == 1);
4480
  }
4481 4482 4483 4484 4485 4486

  /* Reset table_alias_charset, now that lower_case_table_names is set. */
  table_alias_charset= (lower_case_table_names ?
			files_charset_info :
			&my_charset_bin);

4487 4488 4489 4490 4491 4492
  if (ignore_db_dirs_process_additions())
  {
    sql_print_error("An error occurred while storing ignore_db_dirs to a hash.");
    return 1;
  }

unknown's avatar
unknown committed
4493 4494
  return 0;
}
unknown's avatar
unknown committed
4495

4496 4497

static int init_thread_environment()
unknown's avatar
unknown committed
4498
{
4499
  DBUG_ENTER("init_thread_environment");
Marc Alff's avatar
Marc Alff committed
4500
  mysql_mutex_init(key_LOCK_thread_count, &LOCK_thread_count, MY_MUTEX_INIT_FAST);
Michael Widenius's avatar
Michael Widenius committed
4501
  mysql_mutex_init(key_LOCK_thread_cache, &LOCK_thread_cache, MY_MUTEX_INIT_FAST);
Marc Alff's avatar
Marc Alff committed
4502
  mysql_mutex_init(key_LOCK_status, &LOCK_status, MY_MUTEX_INIT_FAST);
4503
  mysql_mutex_init(key_LOCK_show_status, &LOCK_show_status, MY_MUTEX_INIT_SLOW);
Marc Alff's avatar
Marc Alff committed
4504
  mysql_mutex_init(key_LOCK_delayed_insert,
Marc Alff's avatar
Marc Alff committed
4505 4506 4507 4508 4509
                   &LOCK_delayed_insert, MY_MUTEX_INIT_FAST);
  mysql_mutex_init(key_LOCK_delayed_status,
                   &LOCK_delayed_status, MY_MUTEX_INIT_FAST);
  mysql_mutex_init(key_LOCK_delayed_create,
                   &LOCK_delayed_create, MY_MUTEX_INIT_SLOW);
Marc Alff's avatar
Marc Alff committed
4510 4511 4512 4513 4514
  mysql_mutex_init(key_LOCK_crypt, &LOCK_crypt, MY_MUTEX_INIT_FAST);
  mysql_mutex_init(key_LOCK_user_conn, &LOCK_user_conn, MY_MUTEX_INIT_FAST);
  mysql_mutex_init(key_LOCK_active_mi, &LOCK_active_mi, MY_MUTEX_INIT_FAST);
  mysql_mutex_init(key_LOCK_global_system_variables,
                   &LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
unknown's avatar
unknown committed
4515
  mysql_mutex_record_order(&LOCK_active_mi, &LOCK_global_system_variables);
Marc Alff's avatar
Marc Alff committed
4516 4517 4518 4519 4520 4521
  mysql_rwlock_init(key_rwlock_LOCK_system_variables_hash,
                    &LOCK_system_variables_hash);
  mysql_mutex_init(key_LOCK_prepared_stmt_count,
                   &LOCK_prepared_stmt_count, MY_MUTEX_INIT_FAST);
  mysql_mutex_init(key_LOCK_error_messages,
                   &LOCK_error_messages, MY_MUTEX_INIT_FAST);
4522
  mysql_mutex_init(key_LOCK_uuid_short_generator,
Sergei Golubchik's avatar
Sergei Golubchik committed
4523
                   &LOCK_short_uuid_generator, MY_MUTEX_INIT_FAST);
Marc Alff's avatar
Marc Alff committed
4524 4525
  mysql_mutex_init(key_LOCK_connection_count,
                   &LOCK_connection_count, MY_MUTEX_INIT_FAST);
4526 4527 4528 4529 4530 4531 4532
  mysql_mutex_init(key_LOCK_stats, &LOCK_stats, MY_MUTEX_INIT_FAST);
  mysql_mutex_init(key_LOCK_global_user_client_stats,
                   &LOCK_global_user_client_stats, MY_MUTEX_INIT_FAST);
  mysql_mutex_init(key_LOCK_global_table_stats,
                   &LOCK_global_table_stats, MY_MUTEX_INIT_FAST);
  mysql_mutex_init(key_LOCK_global_index_stats,
                   &LOCK_global_index_stats, MY_MUTEX_INIT_FAST);
Sergei Golubchik's avatar
Sergei Golubchik committed
4533 4534
  mysql_mutex_init(key_LOCK_prepare_ordered, &LOCK_prepare_ordered,
                   MY_MUTEX_INIT_SLOW);
4535
  mysql_cond_init(key_COND_prepare_ordered, &COND_prepare_ordered, NULL);
4536 4537
  mysql_mutex_init(key_LOCK_after_binlog_sync, &LOCK_after_binlog_sync,
                   MY_MUTEX_INIT_SLOW);
Sergei Golubchik's avatar
Sergei Golubchik committed
4538 4539
  mysql_mutex_init(key_LOCK_commit_ordered, &LOCK_commit_ordered,
                   MY_MUTEX_INIT_SLOW);
4540
  mysql_mutex_init(key_LOCK_slave_init, &LOCK_slave_init,
4541
                   MY_MUTEX_INIT_SLOW);
4542
  mysql_cond_init(key_COND_slave_init, &COND_slave_init, NULL);
4543

4544
#ifdef HAVE_OPENSSL
Marc Alff's avatar
Marc Alff committed
4545 4546
  mysql_mutex_init(key_LOCK_des_key_file,
                   &LOCK_des_key_file, MY_MUTEX_INIT_FAST);
unknown's avatar
unknown committed
4547 4548 4549 4550
#ifndef HAVE_YASSL
  openssl_stdlocks= (openssl_lock_t*) OPENSSL_malloc(CRYPTO_num_locks() *
                                                     sizeof(openssl_lock_t));
  for (int i= 0; i < CRYPTO_num_locks(); ++i)
4551
    mysql_rwlock_init(key_rwlock_openssl, &openssl_stdlocks[i].lock);
unknown's avatar
unknown committed
4552 4553 4554 4555 4556 4557
  CRYPTO_set_dynlock_create_callback(openssl_dynlock_create);
  CRYPTO_set_dynlock_destroy_callback(openssl_dynlock_destroy);
  CRYPTO_set_dynlock_lock_callback(openssl_lock);
  CRYPTO_set_locking_callback(openssl_lock_function);
  CRYPTO_set_id_callback(openssl_id_function);
#endif
4558
#endif
Marc Alff's avatar
Marc Alff committed
4559 4560 4561
  mysql_rwlock_init(key_rwlock_LOCK_sys_init_connect, &LOCK_sys_init_connect);
  mysql_rwlock_init(key_rwlock_LOCK_sys_init_slave, &LOCK_sys_init_slave);
  mysql_rwlock_init(key_rwlock_LOCK_grant, &LOCK_grant);
Marc Alff's avatar
Marc Alff committed
4562 4563 4564
  mysql_cond_init(key_COND_thread_count, &COND_thread_count, NULL);
  mysql_cond_init(key_COND_thread_cache, &COND_thread_cache, NULL);
  mysql_cond_init(key_COND_flush_thread_cache, &COND_flush_thread_cache, NULL);
unknown's avatar
SCRUM  
unknown committed
4565
#ifdef HAVE_REPLICATION
Marc Alff's avatar
Marc Alff committed
4566
  mysql_mutex_init(key_LOCK_rpl_status, &LOCK_rpl_status, MY_MUTEX_INIT_FAST);
4567
#endif
Marc Alff's avatar
Marc Alff committed
4568 4569 4570
  mysql_mutex_init(key_LOCK_server_started,
                   &LOCK_server_started, MY_MUTEX_INIT_FAST);
  mysql_cond_init(key_COND_server_started, &COND_server_started, NULL);
unknown's avatar
Merge  
unknown committed
4571
  sp_cache_init();
4572
#ifdef HAVE_EVENT_SCHEDULER
4573
  Events::init_mutexes();
4574
#endif
4575
  init_show_explain_psi_keys();
unknown's avatar
unknown committed
4576 4577 4578 4579 4580
  /* Parameter for threads created for connections */
  (void) pthread_attr_init(&connection_attrib);
  (void) pthread_attr_setdetachstate(&connection_attrib,
				     PTHREAD_CREATE_DETACHED);
  pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM);
unknown's avatar
unknown committed
4581

4582 4583
#ifdef HAVE_REPLICATION
  rpl_init_gtid_slave_state();
4584
  rpl_init_gtid_waiting();
4585 4586
#endif

4587
  DBUG_RETURN(0);
unknown's avatar
unknown committed
4588 4589
}

4590

unknown's avatar
unknown committed
4591
#if defined(HAVE_OPENSSL) && !defined(HAVE_YASSL)
4592
static unsigned long openssl_id_function()
4593
{
4594
  return (unsigned long) pthread_self();
4595
}
4596 4597 4598


static openssl_lock_t *openssl_dynlock_create(const char *file, int line)
4599
{
4600
  openssl_lock_t *lock= new openssl_lock_t;
4601
  mysql_rwlock_init(key_rwlock_openssl, &lock->lock);
4602 4603 4604 4605
  return lock;
}


4606
static void openssl_dynlock_destroy(openssl_lock_t *lock, const char *file,
4607 4608
				    int line)
{
4609
  mysql_rwlock_destroy(&lock->lock);
4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625
  delete lock;
}


static void openssl_lock_function(int mode, int n, const char *file, int line)
{
  if (n < 0 || n > CRYPTO_num_locks())
  {
    /* Lock number out of bounds. */
    sql_print_error("Fatal: OpenSSL interface problem (n = %d)", n);
    abort();
  }
  openssl_lock(mode, &openssl_stdlocks[n], file, line);
}


4626
static void openssl_lock(int mode, openssl_lock_t *lock, const char *file,
4627 4628 4629 4630 4631 4632 4633 4634
			 int line)
{
  int err;
  char const *what;

  switch (mode) {
  case CRYPTO_LOCK|CRYPTO_READ:
    what = "read lock";
4635
    err= mysql_rwlock_rdlock(&lock->lock);
4636 4637 4638
    break;
  case CRYPTO_LOCK|CRYPTO_WRITE:
    what = "write lock";
4639
    err= mysql_rwlock_wrlock(&lock->lock);
4640 4641 4642 4643
    break;
  case CRYPTO_UNLOCK|CRYPTO_READ:
  case CRYPTO_UNLOCK|CRYPTO_WRITE:
    what = "unlock";
4644
    err= mysql_rwlock_unlock(&lock->lock);
4645 4646 4647 4648 4649 4650
    break;
  default:
    /* Unknown locking mode. */
    sql_print_error("Fatal: OpenSSL interface problem (mode=0x%x)", mode);
    abort();
  }
4651
  if (err)
4652
  {
4653
    sql_print_error("Fatal: can't %s OpenSSL lock", what);
4654 4655 4656 4657 4658 4659
    abort();
  }
}
#endif /* HAVE_OPENSSL */


unknown's avatar
unknown committed
4660 4661
static void init_ssl()
{
unknown's avatar
unknown committed
4662
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
unknown's avatar
unknown committed
4663 4664
  if (opt_use_ssl)
  {
4665 4666
    enum enum_ssl_init_error error= SSL_INITERR_NOERROR;

4667 4668 4669
    /* having ssl_acceptor_fd != 0 signals the use of SSL */
    ssl_acceptor_fd= new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert,
					  opt_ssl_ca, opt_ssl_capath,
4670 4671
					  opt_ssl_cipher, &error,
                                          opt_ssl_crl, opt_ssl_crlpath);
unknown's avatar
Merge  
unknown committed
4672
    DBUG_PRINT("info",("ssl_acceptor_fd: 0x%lx", (long) ssl_acceptor_fd));
4673
    ERR_remove_state(0);
unknown's avatar
unknown committed
4674
    if (!ssl_acceptor_fd)
4675
    {
4676
      sql_print_warning("Failed to setup SSL");
4677
      sql_print_warning("SSL error: %s", sslGetErrString(error));
unknown's avatar
unknown committed
4678
      opt_use_ssl = 0;
4679
      have_ssl= SHOW_OPTION_DISABLED;
4680 4681 4682 4683
    }
  }
  else
  {
4684
    have_ssl= SHOW_OPTION_DISABLED;
unknown's avatar
unknown committed
4685
  }
unknown's avatar
unknown committed
4686 4687
  if (des_key_file)
    load_des_key_file(des_key_file);
unknown's avatar
unknown committed
4688
#endif /* HAVE_OPENSSL && ! EMBEDDED_LIBRARY */
unknown's avatar
unknown committed
4689
}
unknown's avatar
unknown committed
4690

4691

4692 4693 4694
static void end_ssl()
{
#ifdef HAVE_OPENSSL
Konstantin Osipov's avatar
Konstantin Osipov committed
4695
#ifndef EMBEDDED_LIBRARY
4696 4697 4698 4699 4700
  if (ssl_acceptor_fd)
  {
    free_vio_ssl_acceptor_fd(ssl_acceptor_fd);
    ssl_acceptor_fd= 0;
  }
Konstantin Osipov's avatar
Konstantin Osipov committed
4701
#endif /* ! EMBEDDED_LIBRARY */
4702 4703 4704
#endif /* HAVE_OPENSSL */
}

4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730
#ifdef _WIN32
/**
  Registers a file to be collected when Windows Error Reporting creates a crash 
  report.

  @note only works on Vista and later, since WerRegisterFile() is not available
  on earlier Windows.
*/
#include <werapi.h>
static void add_file_to_crash_report(char *file)
{
  /* Load WerRegisterFile function dynamically.*/
  HRESULT (WINAPI *pWerRegisterFile)(PCWSTR, WER_REGISTER_FILE_TYPE, DWORD)
    =(HRESULT (WINAPI *) (PCWSTR, WER_REGISTER_FILE_TYPE, DWORD))
    GetProcAddress(GetModuleHandle("kernel32"),"WerRegisterFile");

  if (pWerRegisterFile)
  {
    wchar_t wfile[MAX_PATH+1]= {0};
    if (mbstowcs(wfile, file, MAX_PATH) != (size_t)-1)
    {
      pWerRegisterFile(wfile, WerRegFileTypeOther, WER_FILE_ANONYMOUS_DATA);
    }
  }
}
#endif
4731

4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777
#define init_default_storage_engine(X,Y) \
  init_default_storage_engine_impl(#X, X, &global_system_variables.Y)

static int init_default_storage_engine_impl(const char *opt_name,
                                            char *engine_name, plugin_ref *res)
{
  if (!engine_name)
  {
    *res= 0;
    return 0;
  }

  LEX_STRING name= { engine_name, strlen(engine_name) };
  plugin_ref plugin;
  handlerton *hton;
  if ((plugin= ha_resolve_by_name(0, &name, false)))
    hton= plugin_hton(plugin);
  else
  {
    sql_print_error("Unknown/unsupported storage engine: %s", engine_name);
    return 1;
  }
  if (!ha_storage_engine_is_enabled(hton))
  {
    if (!opt_bootstrap)
    {
      sql_print_error("%s (%s) is not available", opt_name, engine_name);
      return 1;
    }
    DBUG_ASSERT(*res);
  }
  else
  {
    /*
      Need to unlock as global_system_variables.table_plugin
      was acquired during plugin_init()
    */
    mysql_mutex_lock(&LOCK_global_system_variables);
    if (*res)
      plugin_unlock(0, *res);
    *res= plugin;
    mysql_mutex_unlock(&LOCK_global_system_variables);
  }
  return 0;
}

unknown's avatar
unknown committed
4778 4779
static int init_server_components()
{
4780
  DBUG_ENTER("init_server_components");
unknown's avatar
unknown committed
4781 4782 4783 4784
  /*
    We need to call each of these following functions to ensure that
    all things are initialized so that unireg_abort() doesn't fail
  */
4785
  mdl_init();
4786 4787
  tdc_init();
  if (hostname_cache_init())
4788
    unireg_abort(1);
unknown's avatar
unknown committed
4789

4790
  query_cache_set_min_res_unit(query_cache_min_res_unit);
unknown's avatar
unknown committed
4791
  query_cache_init();
unknown's avatar
unknown committed
4792
  query_cache_resize(query_cache_size);
4793
  query_cache_result_size_limit(query_cache_limit);
4794
  my_rnd_init(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2);
4795
  setup_fpu();
unknown's avatar
unknown committed
4796
  init_thr_lock();
Monty's avatar
Monty committed
4797 4798 4799 4800 4801 4802 4803 4804
#ifndef EMBEDDED_LIBRARY
  if (init_thr_timer(thread_scheduler->max_threads + extra_max_connections))
  {
    fprintf(stderr, "Can't initialize timers\n");
    unireg_abort(1);
  }
#endif

4805
  my_uuid_init((ulong) (my_rnd(&sql_rand))*12345,12345);
unknown's avatar
SCRUM  
unknown committed
4806
#ifdef HAVE_REPLICATION
4807
  init_slave_list();
4808
#endif
Sergei Golubchik's avatar
Sergei Golubchik committed
4809
  wt_init();
unknown's avatar
unknown committed
4810

4811 4812
  /* Setup logs */

4813 4814 4815 4816 4817
  /*
    Enable old-fashioned error log, except when the user has requested
    help information. Since the implementation of plugin server
    variables the help output is now written much later.
  */
4818
  if (opt_error_log && !opt_abort)
4819 4820
  {
    if (!log_error_file_ptr[0])
Sergei Golubchik's avatar
Sergei Golubchik committed
4821
    {
4822
      fn_format(log_error_file, pidfile_name, mysql_data_home, ".err",
4823
                MY_REPLACE_EXT); /* replace '.<domain>' by '.err', bug#4997 */
Sergei Golubchik's avatar
Sergei Golubchik committed
4824 4825
      SYSVAR_AUTOSIZE(log_error_file_ptr, log_error_file);
    }
4826
    else
Sergei Golubchik's avatar
Sergei Golubchik committed
4827
    {
4828 4829
      fn_format(log_error_file, log_error_file_ptr, mysql_data_home, ".err",
                MY_UNPACK_FILENAME | MY_SAFE_PATH);
Sergei Golubchik's avatar
Sergei Golubchik committed
4830 4831
      log_error_file_ptr= log_error_file;
    }
4832
    if (!log_error_file[0])
4833
      opt_error_log= 0;                         // Too long file name
4834 4835
    else
    {
4836
      my_bool res;
4837
#ifndef EMBEDDED_LIBRARY
4838 4839 4840
      res= reopen_fstreams(log_error_file, stdout, stderr);
#else
      res= reopen_fstreams(log_error_file, NULL, stderr);
4841
#endif
4842 4843 4844

      if (!res)
        setbuf(stderr, NULL);
4845 4846 4847 4848 4849

#ifdef _WIN32
      /* Add error log to windows crash reporting. */
      add_file_to_crash_report(log_error_file);
#endif
4850 4851 4852
    }
  }

4853 4854
  /* set up the hook before initializing plugins which may use it */
  error_handler_hook= my_message_sql;
Sergei Golubchik's avatar
Sergei Golubchik committed
4855
  proc_info_hook= set_thd_stage_info;
4856

Marc Alff's avatar
Marc Alff committed
4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
  /*
    Parsing the performance schema command line option may have reported
    warnings/information messages.
    Now that the logger is finally available, and redirected
    to the proper file when the --log--error option is used,
    print the buffered messages to the log.
  */
  buffered_logs.print();
  buffered_logs.cleanup();
#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */

4869 4870 4871 4872 4873 4874 4875 4876 4877
#ifndef EMBEDDED_LIBRARY
  /*
    Now that the logger is available, redirect character set
    errors directly to the logger
    (instead of the buffered_logs used at the server startup time).
  */
  my_charset_error_reporter= charset_error_reporter;
#endif

unknown's avatar
unknown committed
4878 4879 4880 4881 4882 4883
  if (xid_cache_init())
  {
    sql_print_error("Out of memory");
    unireg_abort(1);
  }

4884 4885 4886 4887
  /*
    initialize delegates for extension observers, errors have already
    been reported in the function
  */
He Zhenxing's avatar
He Zhenxing committed
4888 4889 4890
  if (delegates_init())
    unireg_abort(1);

unknown's avatar
unknown committed
4891
  /* need to configure logging before initializing storage engines */
Sergei Golubchik's avatar
Sergei Golubchik committed
4892
  if (!opt_bin_log_used && !WSREP_ON)
unknown's avatar
unknown committed
4893
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
4894
    if (opt_log_slave_updates)
4895 4896
      sql_print_warning("You need to use --log-bin to make "
                        "--log-slave-updates work.");
Sergei Golubchik's avatar
Sergei Golubchik committed
4897
    if (binlog_format_used)
4898 4899
      sql_print_warning("You need to use --log-bin to make "
                        "--binlog-format work.");
4900
  }
4901

4902
  /* Check that we have not let the format to unspecified at this point */
4903
  DBUG_ASSERT((uint)global_system_variables.binlog_format <=
4904
              array_elements(binlog_format_names)-1);
4905

unknown's avatar
unknown committed
4906
#ifdef HAVE_REPLICATION
unknown's avatar
unknown committed
4907 4908
  if (opt_log_slave_updates && replicate_same_server_id)
  {
4909 4910 4911
    if (opt_bin_log)
    {
      sql_print_error("using --replicate-same-server-id in conjunction with \
unknown's avatar
unknown committed
4912 4913
--log-slave-updates is impossible, it would lead to infinite loops in this \
server.");
4914 4915 4916 4917 4918 4919
      unireg_abort(1);
    }
    else
      sql_print_warning("using --replicate-same-server-id in conjunction with \
--log-slave-updates would lead to infinite loops in this server. However this \
will be ignored as the --log-bin option is not defined.");
unknown's avatar
unknown committed
4920
  }
unknown's avatar
unknown committed
4921
#endif
4922

4923 4924
  DBUG_ASSERT(!opt_bin_log || opt_bin_logname);

unknown's avatar
Merge  
unknown committed
4925
  if (opt_bin_log)
4926
  {
4927 4928
    /* Reports an error and aborts, if the --log-bin's path 
       is a directory.*/
4929
    if (opt_bin_logname[0] && 
4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947
        opt_bin_logname[strlen(opt_bin_logname) - 1] == FN_LIBCHAR)
    {
      sql_print_error("Path '%s' is a directory name, please specify \
a file name for --log-bin option", opt_bin_logname);
      unireg_abort(1);
    }

    /* Reports an error and aborts, if the --log-bin-index's path 
       is a directory.*/
    if (opt_binlog_index_name && 
        opt_binlog_index_name[strlen(opt_binlog_index_name) - 1] 
        == FN_LIBCHAR)
    {
      sql_print_error("Path '%s' is a directory name, please specify \
a file name for --log-bin-index option", opt_binlog_index_name);
      unireg_abort(1);
    }

unknown's avatar
Merge  
unknown committed
4948 4949 4950
    char buf[FN_REFLEN];
    const char *ln;
    ln= mysql_bin_log.generate_name(opt_bin_logname, "-bin", 1, buf);
4951
    if (!opt_bin_logname[0] && !opt_binlog_index_name)
4952 4953
    {
      /*
unknown's avatar
Merge  
unknown committed
4954 4955 4956 4957 4958
        User didn't give us info to name the binlog index file.
        Picking `hostname`-bin.index like did in 4.x, causes replication to
        fail if the hostname is changed later. So, we would like to instead
        require a name. But as we don't want to break many existing setups, we
        only give warning, not error.
4959
      */
4960 4961 4962 4963
      sql_print_warning("No argument was provided to --log-bin and "
                        "neither --log-basename or --log-bin-index where "
                        "used;  This may cause repliction to break when this "
                        "server acts as a master and has its hostname "
Sergei Golubchik's avatar
Sergei Golubchik committed
4964
                        "changed! Please use '--log-basename=%s' or "
4965
                        "'--log-bin=%s' to avoid this problem.",
Sergei Golubchik's avatar
Sergei Golubchik committed
4966
                        opt_log_basename, ln);
4967
    }
unknown's avatar
Merge  
unknown committed
4968
    if (ln == buf)
4969
      opt_bin_logname= my_once_strdup(buf, MYF(MY_WME));
4970 4971
  }

4972 4973 4974 4975 4976 4977 4978
    /*
      Wsrep initialization must happen at this point, because:
      - opt_bin_logname must be known when starting replication
        since SST may need it
      - SST may modify binlog index file, so it must be opened
        after SST has happened
     */
4979
  if (WSREP_ON && !wsrep_recovery && !opt_abort) /* WSREP BEFORE SE */
4980 4981 4982 4983
  {
    if (opt_bootstrap) // bootsrap option given - disable wsrep functionality
    {
      wsrep_provider_init(WSREP_NONE);
4984 4985
      if (wsrep_init())
        unireg_abort(1);
4986 4987 4988 4989
    }
    else // full wsrep initialization
    {
      // add basedir/bin to PATH to resolve wsrep script names
4990 4991
      char* const tmp_path= (char*)my_alloca(strlen(mysql_home) +
                                             strlen("/bin") + 1);
4992 4993 4994 4995 4996 4997 4998 4999 5000 5001
      if (tmp_path)
      {
        strcpy(tmp_path, mysql_home);
        strcat(tmp_path, "/bin");
        wsrep_prepend_PATH(tmp_path);
      }
      else
      {
        WSREP_ERROR("Could not append %s/bin to PATH", mysql_home);
      }
5002
      my_afree(tmp_path);
5003 5004 5005 5006 5007 5008 5009 5010 5011

      if (wsrep_before_SE())
      {
        set_ports(); // this is also called in network_init() later but we need
                     // to know mysqld_port now - lp:1071882
        wsrep_init_startup(true);
      }
    }
  }
5012

5013 5014 5015 5016 5017 5018 5019
  if (opt_bin_log)
  {
    if (mysql_bin_log.open_index_file(opt_binlog_index_name, opt_bin_logname,
                                      TRUE))
    {
      unireg_abort(1);
    }
5020 5021
  }

5022
  /* call ha_init_key_cache() on all key caches to init them */
5023
  process_key_caches(&ha_init_key_cache, 0);
5024

5025 5026 5027
  init_global_table_stats();
  init_global_index_stats();

5028 5029 5030 5031
  /* Allow storage engine to give real error messages */
  if (ha_init_errors())
    DBUG_RETURN(1);

5032 5033
  tc_log= 0; // ha_initialize_handlerton() needs that

Marc Alff's avatar
Marc Alff committed
5034
  if (plugin_init(&remaining_argc, remaining_argv,
5035
                  (opt_noacl ? PLUGIN_INIT_SKIP_PLUGIN_TABLE : 0) |
5036
                  (opt_abort ? PLUGIN_INIT_SKIP_INITIALIZATION : 0)))
5037 5038 5039
  {
    sql_print_error("Failed to initialize plugins.");
    unireg_abort(1);
unknown's avatar
unknown committed
5040
  }
5041
  plugins_are_initialized= TRUE;  /* Don't separate from init function */
unknown's avatar
unknown committed
5042

unknown's avatar
unknown committed
5043
  /* we do want to exit if there are any other unknown options */
Marc Alff's avatar
Marc Alff committed
5044
  if (remaining_argc > 1)
unknown's avatar
unknown committed
5045 5046
  {
    int ho_error;
unknown's avatar
unknown committed
5047
    struct my_option no_opts[]=
unknown's avatar
unknown committed
5048 5049 5050 5051 5052
    {
      {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
    };
    /*
      We need to eat any 'loose' arguments first before we conclude
unknown's avatar
unknown committed
5053
      that there are unprocessed options.
unknown's avatar
unknown committed
5054 5055
    */
    my_getopt_skip_unknown= 0;
unknown's avatar
unknown committed
5056

Marc Alff's avatar
Marc Alff committed
5057
    if ((ho_error= handle_options(&remaining_argc, &remaining_argv, no_opts,
5058
                                  mysqld_get_one_option)))
unknown's avatar
unknown committed
5059
      unireg_abort(ho_error);
Marc Alff's avatar
Marc Alff committed
5060 5061 5062
    /* Add back the program name handle_options removes */
    remaining_argc++;
    remaining_argv--;
5063
    my_getopt_skip_unknown= TRUE;
unknown's avatar
unknown committed
5064

Marc Alff's avatar
Marc Alff committed
5065
    if (remaining_argc > 1)
unknown's avatar
unknown committed
5066
    {
5067
      fprintf(stderr, "%s: Too many arguments (first extra is '%s').\n",
Marc Alff's avatar
Marc Alff committed
5068
              my_progname, remaining_argv[1]);
unknown's avatar
unknown committed
5069 5070
      unireg_abort(1);
    }
unknown's avatar
unknown committed
5071 5072
  }

5073
  if (opt_abort)
5074 5075
    unireg_abort(0);

unknown's avatar
unknown committed
5076
  /* if the errmsg.sys is not loaded, terminate to maintain behaviour */
5077 5078
  if (!DEFAULT_ERRMSGS[0][0])
    unireg_abort(1);  
unknown's avatar
unknown committed
5079

unknown's avatar
unknown committed
5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106
  /* We have to initialize the storage engines before CSV logging */
  if (ha_init())
  {
    sql_print_error("Can't init databases");
    unireg_abort(1);
  }

  if (opt_bootstrap)
    log_output_options= LOG_FILE;
  else
    logger.init_log_tables();

  if (log_output_options & LOG_NONE)
  {
    /*
      Issue a warining if there were specified additional options to the
      log-output along with NONE. Probably this wasn't what user wanted.
    */
    if ((log_output_options & LOG_NONE) && (log_output_options & ~LOG_NONE))
      sql_print_warning("There were other values specified to "
                        "log-output besides NONE. Disabling slow "
                        "and general logs anyway.");
    logger.set_handlers(LOG_FILE, LOG_NONE, LOG_NONE);
  }
  else
  {
    /* fall back to the log files if tables are not present */
unknown's avatar
unknown committed
5107 5108
    LEX_STRING csv_name={C_STRING_WITH_LEN("csv")};
    if (!plugin_is_ready(&csv_name, MYSQL_STORAGE_ENGINE_PLUGIN))
unknown's avatar
unknown committed
5109
    {
5110
      /* purecov: begin inspected */
unknown's avatar
unknown committed
5111 5112
      sql_print_error("CSV engine is not present, falling back to the "
                      "log files");
Sergei Golubchik's avatar
Sergei Golubchik committed
5113 5114
      SYSVAR_AUTOSIZE(log_output_options, 
                      (log_output_options & ~LOG_TABLE) | LOG_FILE);
5115
      /* purecov: end */
unknown's avatar
unknown committed
5116 5117
    }

Monty's avatar
Monty committed
5118 5119 5120
    logger.set_handlers(LOG_FILE,
                        global_system_variables.sql_log_slow ?
                        log_output_options:LOG_NONE,
unknown's avatar
unknown committed
5121 5122 5123
                        opt_log ? log_output_options:LOG_NONE);
  }

5124
  if (init_default_storage_engine(default_storage_engine, table_plugin))
5125
    unireg_abort(1);
5126 5127 5128 5129 5130 5131 5132

  if (default_tmp_storage_engine && !*default_tmp_storage_engine)
    default_tmp_storage_engine= NULL;

  if (init_default_storage_engine(default_tmp_storage_engine, tmp_table_plugin))
    unireg_abort(1);

Sergei Golubchik's avatar
Sergei Golubchik committed
5133
#ifdef USE_ARIA_FOR_TMP_TABLES
5134
  if (!ha_storage_engine_is_enabled(maria_hton) && !opt_bootstrap)
5135
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
5136
    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");
5137 5138
    unireg_abort(1);
  }
5139 5140 5141 5142 5143
  internal_tmp_table_max_key_length=   maria_max_key_length();
  internal_tmp_table_max_key_segments= maria_max_key_segments();
#else
  internal_tmp_table_max_key_length=   myisam_max_key_length();
  internal_tmp_table_max_key_segments= myisam_max_key_segments();
5144
#endif
5145

5146 5147 5148 5149 5150 5151 5152
#ifdef WITH_WSREP
  if (WSREP_ON && !opt_bin_log)
  {
    wsrep_emulate_bin_log= 1;
  }
#endif

5153
  tc_log= get_tc_log_implementation();
5154

unknown's avatar
unknown committed
5155
  if (tc_log->open(opt_bin_log ? opt_bin_logname : opt_tc_log_file))
unknown's avatar
Merge  
unknown committed
5156 5157 5158 5159 5160
  {
    sql_print_error("Can't init tc log");
    unireg_abort(1);
  }

unknown's avatar
unknown committed
5161 5162 5163 5164 5165
  if (ha_recover(0))
  {
    unireg_abort(1);
  }

5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177
  if (opt_bin_log)
  {
    /**
     * mutex lock is not needed here.
     * but to be able to have mysql_mutex_assert_owner() in code,
     * we do it anyway */
    mysql_mutex_lock(mysql_bin_log.get_log_lock());
    if (mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0,
                           WRITE_CACHE, max_binlog_size, 0, TRUE))
      unireg_abort(1);
    mysql_mutex_unlock(mysql_bin_log.get_log_lock());
  }
unknown's avatar
Merge  
unknown committed
5178 5179 5180

#ifdef HAVE_REPLICATION
  if (opt_bin_log && expire_logs_days)
5181
  {
5182
    time_t purge_time= server_start_time - expire_logs_days*24*60*60;
unknown's avatar
Merge  
unknown committed
5183 5184
    if (purge_time >= 0)
      mysql_bin_log.purge_logs_before_date(purge_time);
5185
  }
unknown's avatar
Merge  
unknown committed
5186 5187 5188 5189
#endif

  if (opt_myisam_log)
    (void) mi_log(1);
unknown's avatar
unknown committed
5190

unknown's avatar
unknown committed
5191
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && !defined(EMBEDDED_LIBRARY)
5192
  if (locked_in_memory && !getuid())
5193
  {
5194
    if (setreuid((uid_t)-1, 0) == -1)
5195
    {                        // this should never happen
5196
      sql_perror("setreuid");
5197 5198
      unireg_abort(1);
    }
5199 5200
    if (mlockall(MCL_CURRENT))
    {
5201
      if (global_system_variables.log_warnings)
5202
	sql_print_warning("Failed to lock memory. Errno: %d\n",errno);
unknown's avatar
unknown committed
5203
      locked_in_memory= 0;
5204
    }
5205 5206
    if (user_info)
      set_user(mysqld_user, user_info);
5207
  }
unknown's avatar
unknown committed
5208
  else
5209
#endif
unknown's avatar
unknown committed
5210
    locked_in_memory=0;
5211

5212
  ft_init_stopwords();
unknown's avatar
unknown committed
5213

unknown's avatar
unknown committed
5214
  init_max_user_conn();
5215
  init_update_queries();
5216 5217
  init_global_user_stats();
  init_global_client_stats();
5218 5219
  if (!opt_bootstrap)
    servers_init(0);
5220
  DBUG_RETURN(0);
unknown's avatar
unknown committed
5221
}
unknown's avatar
unknown committed
5222

5223

5224
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
5225

unknown's avatar
unknown committed
5226 5227 5228
static void create_shutdown_thread()
{
#ifdef __WIN__
5229 5230
  hEventShutdown=CreateEvent(0, FALSE, FALSE, shutdown_event_name);
  pthread_t hThread;
5231 5232 5233 5234 5235 5236
  int error;
  if ((error= mysql_thread_create(key_thread_handle_shutdown,
                                  &hThread, &connection_attrib,
                                  handle_shutdown, 0)))
    sql_print_warning("Can't create thread to handle shutdown requests"
                      " (errno= %d)", error);
unknown's avatar
unknown committed
5237

5238 5239
  // On "Stop Service" we have to do regular shutdown
  Service.SetShutdownEvent(hEventShutdown);
unknown's avatar
unknown committed
5240
#endif /* __WIN__ */
unknown's avatar
unknown committed
5241
}
unknown's avatar
unknown committed
5242

5243
#endif /* EMBEDDED_LIBRARY */
5244 5245


Vladislav Vaintroub's avatar
Vladislav Vaintroub committed
5246
#if (defined(_WIN32) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY)
5247
static void handle_connections_methods()
unknown's avatar
unknown committed
5248
{
5249
  pthread_t hThread;
5250
  int error;
5251
  DBUG_ENTER("handle_connections_methods");
unknown's avatar
unknown committed
5252
  if (hPipe == INVALID_HANDLE_VALUE &&
5253 5254
      (!have_tcpip || opt_disable_networking) &&
      !opt_enable_shared_memory)
unknown's avatar
unknown committed
5255
  {
unknown's avatar
unknown committed
5256
    sql_print_error("TCP/IP, --shared-memory, or --named-pipe should be configured on NT OS");
5257
    unireg_abort(1);				// Will not return
unknown's avatar
unknown committed
5258
  }
5259

Marc Alff's avatar
Marc Alff committed
5260 5261
  mysql_mutex_lock(&LOCK_thread_count);
  mysql_cond_init(key_COND_handler_count, &COND_handler_count, NULL);
5262 5263
  handler_count=0;
  if (hPipe != INVALID_HANDLE_VALUE)
unknown's avatar
unknown committed
5264
  {
5265
    handler_count++;
5266 5267 5268
    if ((error= mysql_thread_create(key_thread_handle_con_namedpipes,
                                    &hThread, &connection_attrib,
                                    handle_connections_namedpipes, 0)))
unknown's avatar
unknown committed
5269
    {
5270 5271
      sql_print_warning("Can't create thread to handle named pipes"
                        " (errno= %d)", error);
5272 5273 5274 5275 5276 5277
      handler_count--;
    }
  }
  if (have_tcpip && !opt_disable_networking)
  {
    handler_count++;
5278 5279 5280
    if ((error= mysql_thread_create(key_thread_handle_con_sockets,
                                    &hThread, &connection_attrib,
                                    handle_connections_sockets_thread, 0)))
5281
    {
5282 5283
      sql_print_warning("Can't create thread to handle TCP/IP",
                        " (errno= %d)", error);
5284 5285 5286 5287 5288 5289 5290
      handler_count--;
    }
  }
#ifdef HAVE_SMEM
  if (opt_enable_shared_memory)
  {
    handler_count++;
5291 5292 5293
    if ((error= mysql_thread_create(key_thread_handle_con_sharedmem,
                                    &hThread, &connection_attrib,
                                    handle_connections_shared_memory, 0)))
5294
    {
Sergei Golubchik's avatar
Sergei Golubchik committed
5295 5296
      sql_print_warning("Can't create thread to handle shared memory",
                        " (errno= %d)", error);
5297
      handler_count--;
unknown's avatar
unknown committed
5298 5299
    }
  }
5300
#endif
unknown's avatar
unknown committed
5301

5302
  while (handler_count > 0)
Marc Alff's avatar
Marc Alff committed
5303 5304
    mysql_cond_wait(&COND_handler_count, &LOCK_thread_count);
  mysql_mutex_unlock(&LOCK_thread_count);
5305 5306
  DBUG_VOID_RETURN;
}
5307 5308 5309

void decrement_handler_count()
{
Marc Alff's avatar
Marc Alff committed
5310
  mysql_mutex_lock(&LOCK_thread_count);
5311
  handler_count--;
Marc Alff's avatar
Marc Alff committed
5312 5313
  mysql_cond_signal(&COND_handler_count);
  mysql_mutex_unlock(&LOCK_thread_count);
5314
  my_thread_end();
5315 5316 5317
}
#else
#define decrement_handler_count()
Vladislav Vaintroub's avatar
Vladislav Vaintroub committed
5318
#endif /* defined(_WIN32) || defined(HAVE_SMEM) */
5319 5320


5321
#ifndef EMBEDDED_LIBRARY
Sergei Golubchik's avatar
Sergei Golubchik committed
5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347

LEX_STRING sql_statement_names[(uint) SQLCOM_END + 1];

static void init_sql_statement_names()
{
  char *first_com= (char*) offsetof(STATUS_VAR, com_stat[0]);
  char *last_com= (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_END]);
  int record_size= (char*) offsetof(STATUS_VAR, com_stat[1])
                   - (char*) offsetof(STATUS_VAR, com_stat[0]);
  char *ptr;
  uint i;
  uint com_index;

  for (i= 0; i < ((uint) SQLCOM_END + 1); i++)
    sql_statement_names[i]= empty_lex_str;

  SHOW_VAR *var= &com_status_vars[0];
  while (var->name != NULL)
  {
    ptr= var->value;
    if ((first_com <= ptr) && (ptr <= last_com))
    {
      com_index= ((int)(ptr - first_com))/record_size;
      DBUG_ASSERT(com_index < (uint) SQLCOM_END);
      sql_statement_names[com_index].str= const_cast<char *>(var->name);
      sql_statement_names[com_index].length= strlen(var->name);
unknown's avatar
unknown committed
5348
    }
Sergei Golubchik's avatar
Sergei Golubchik committed
5349
    var++;
unknown's avatar
unknown committed
5350
  }
unknown's avatar
unknown committed
5351

Sergei Golubchik's avatar
Sergei Golubchik committed
5352 5353
  DBUG_ASSERT(strcmp(sql_statement_names[(uint) SQLCOM_SELECT].str, "select") == 0);
  DBUG_ASSERT(strcmp(sql_statement_names[(uint) SQLCOM_SIGNAL].str, "signal") == 0);
5354

Sergei Golubchik's avatar
Sergei Golubchik committed
5355
  sql_statement_names[(uint) SQLCOM_END].str= const_cast<char*>("error");
5356
}
5357

5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394
#ifndef DBUG_OFF
/*
  Debugging helper function to keep the locale database
  (see sql_locale.cc) and max_month_name_length and
  max_day_name_length variable values in consistent state.
*/
static void test_lc_time_sz()
{
  DBUG_ENTER("test_lc_time_sz");
  for (MY_LOCALE **loc= my_locales; *loc; loc++)
  {
    uint max_month_len= 0;
    uint max_day_len = 0;
    for (const char **month= (*loc)->month_names->type_names; *month; month++)
    {
      set_if_bigger(max_month_len,
                    my_numchars_mb(&my_charset_utf8_general_ci,
                                   *month, *month + strlen(*month)));
    }
    for (const char **day= (*loc)->day_names->type_names; *day; day++)
    {
      set_if_bigger(max_day_len,
                    my_numchars_mb(&my_charset_utf8_general_ci,
                                   *day, *day + strlen(*day)));
    }
    if ((*loc)->max_month_name_length != max_month_len ||
        (*loc)->max_day_name_length != max_day_len)
    {
      DBUG_PRINT("Wrong max day name(or month name) length for locale:",
                 ("%s", (*loc)->name));
      DBUG_ASSERT(0);
    }
  }
  DBUG_VOID_RETURN;
}
#endif//DBUG_OFF

5395

unknown's avatar
unknown committed
5396 5397 5398
#ifdef __WIN__
int win_main(int argc, char **argv)
#else
5399
int mysqld_main(int argc, char **argv)
unknown's avatar
unknown committed
5400 5401
#endif
{
Marc Alff's avatar
Marc Alff committed
5402 5403 5404 5405 5406
  /*
    Perform basic thread library and malloc initialization,
    to be able to read defaults files and parse options.
  */
  my_progname= argv[0];
5407
  sf_leaking_memory= 1; // no safemalloc memory leak reports if we exit early
5408 5409
  mysqld_server_started= mysqld_server_initialized= 0;

5410 5411 5412
#ifdef HAVE_NPTL
  ld_assume_kernel_is_set= (getenv("LD_ASSUME_KERNEL") != 0);
#endif
5413 5414 5415
#ifndef _WIN32
  // For windows, my_init() is called from the win specific mysqld_main
  if (my_init())                 // init my_sys library & pthreads
Marc Alff's avatar
Marc Alff committed
5416
  {
5417
    fprintf(stderr, "my_init() failed.");
Marc Alff's avatar
Marc Alff committed
5418 5419
    return 1;
  }
5420
#endif
5421

Marc Alff's avatar
Marc Alff committed
5422 5423
  orig_argc= argc;
  orig_argv= argv;
5424
  my_getopt_use_args_separator= TRUE;
Marc Alff's avatar
Marc Alff committed
5425 5426
  if (load_defaults(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv))
    return 1;
5427
  my_getopt_use_args_separator= FALSE;
Marc Alff's avatar
Marc Alff committed
5428 5429 5430 5431 5432 5433 5434 5435
  defaults_argc= argc;
  defaults_argv= argv;
  remaining_argc= argc;
  remaining_argv= argv;

  /* Must be initialized early for comparison of options name */
  system_charset_info= &my_charset_utf8_general_ci;

5436
  init_sql_statement_names();
Marc Alff's avatar
Marc Alff committed
5437 5438
  sys_var_init();

5439
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
Marc Alff's avatar
Marc Alff committed
5440
  /*
5441
    Initialize the array of performance schema instrument configurations.
Marc Alff's avatar
Marc Alff committed
5442
  */
5443 5444
  init_pfs_instrument_array();
#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
Marc Alff's avatar
Marc Alff committed
5445 5446 5447 5448 5449 5450
  /*
    Logs generated while parsing the command line
    options are buffered and printed later.
  */
  buffered_logs.init();
  my_getopt_error_reporter= buffered_option_error_reporter;
5451
  my_charset_error_reporter= buffered_option_error_reporter;
5452
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
5453
  pfs_param.m_pfs_instrument= const_cast<char*>("");
5454
#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
5455

5456
  int ho_error __attribute__((unused))= handle_early_options();
Marc Alff's avatar
Marc Alff committed
5457

5458
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
Marc Alff's avatar
Marc Alff committed
5459 5460
  if (ho_error == 0)
  {
5461
    if (pfs_param.m_enabled  && !opt_help && !opt_bootstrap)
Marc Alff's avatar
Marc Alff committed
5462
    {
5463
      /* Add sizing hints from the server sizing parameters. */
5464 5465
      pfs_param.m_hints.m_table_definition_cache= tdc_size;
      pfs_param.m_hints.m_table_open_cache= tc_size;
5466 5467
      pfs_param.m_hints.m_max_connections= max_connections;
      pfs_param.m_hints.m_open_files_limit= open_files_limit;
Marc Alff's avatar
Marc Alff committed
5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495
      PSI_hook= initialize_performance_schema(&pfs_param);
      if (PSI_hook == NULL)
      {
        pfs_param.m_enabled= false;
        buffered_logs.buffer(WARNING_LEVEL,
                             "Performance schema disabled (reason: init failed).");
      }
    }
  }
#else
  /*
    Other provider of the instrumentation interface should
    initialize PSI_hook here:
    - HAVE_PSI_INTERFACE is for the instrumentation interface
    - WITH_PERFSCHEMA_STORAGE_ENGINE is for one implementation
      of the interface,
    but there could be alternate implementations, which is why
    these two defines are kept separate.
  */
#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */

#ifdef HAVE_PSI_INTERFACE
  /*
    Obtain the current performance schema instrumentation interface,
    if available.
  */
  if (PSI_hook)
  {
5496 5497 5498 5499
    PSI *psi_server= (PSI*) PSI_hook->get_interface(PSI_CURRENT_VERSION);
    if (likely(psi_server != NULL))
    {
      set_psi_server(psi_server);
Marc Alff's avatar
Marc Alff committed
5500

5501 5502 5503 5504 5505 5506 5507
      /*
        Now that we have parsed the command line arguments, and have
        initialized the performance schema itself, the next step is to
        register all the server instruments.
      */
      init_server_psi_keys();
      /* Instrument the main thread */
5508 5509
      PSI_thread *psi= PSI_THREAD_CALL(new_thread)(key_thread_main, NULL, 0);
      PSI_THREAD_CALL(set_thread)(psi);
5510 5511 5512 5513 5514 5515 5516 5517

      /*
        Now that some instrumentation is in place,
        recreate objects which were initialised early,
        so that they are instrumented as well.
      */
      my_thread_global_reinit();
    }
Marc Alff's avatar
Marc Alff committed
5518 5519 5520 5521
  }
#endif /* HAVE_PSI_INTERFACE */

  init_error_log_mutex();
5522

5523 5524 5525
  /* Initialize audit interface globals. Audit plugins are inited later. */
  mysql_audit_initialize();

5526 5527 5528 5529 5530 5531
  /*
    Perform basic logger initialization logger. Should be called after
    MY_INIT, as it initializes mutexes. Log tables are inited later.
  */
  logger.init_base();

Marc Alff's avatar
Marc Alff committed
5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
  if (ho_error)
  {
    /*
      Parsing command line option failed,
      Since we don't have a workable remaining_argc/remaining_argv
      to continue the server initialization, this is as far as this
      code can go.
      This is the best effort to log meaningful messages:
      - messages will be printed to stderr, which is not redirected yet,
      - messages will be printed in the NT event log, for windows.
    */
    buffered_logs.print();
    buffered_logs.cleanup();
    /*
      Not enough initializations for unireg_abort()
      Using exit() for windows.
    */
    exit (ho_error);
  }
#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */

unknown's avatar
unknown committed
5554
#ifdef _CUSTOMSTARTUPCONFIG_
unknown's avatar
unknown committed
5555 5556 5557
  if (_cust_check_startup())
  {
    / * _cust_check_startup will report startup failure error * /
unknown's avatar
Merge  
unknown committed
5558
    exit(1);
unknown's avatar
unknown committed
5559 5560
  }
#endif
unknown's avatar
unknown committed
5561

Marc Alff's avatar
Marc Alff committed
5562
  if (init_common_variables())
5563
    unireg_abort(1);				// Will do exit
unknown's avatar
unknown committed
5564 5565

  init_signals();
5566

Sergei Golubchik's avatar
Sergei Golubchik committed
5567 5568 5569 5570 5571
  ulonglong new_thread_stack_size;
  new_thread_stack_size= my_setstacksize(&connection_attrib,
                                         my_thread_stack_size);
  if (new_thread_stack_size != my_thread_stack_size)
    SYSVAR_AUTOSIZE(my_thread_stack_size, new_thread_stack_size);
unknown's avatar
unknown committed
5572

5573
  (void) thr_setconcurrency(concurrency);	// 10 by default
unknown's avatar
unknown committed
5574

5575 5576
  select_thread=pthread_self();
  select_thread_in_use=1;
unknown's avatar
unknown committed
5577 5578 5579 5580 5581 5582

#ifdef HAVE_LIBWRAP
  libwrapName= my_progname+dirname_length(my_progname);
  openlog(libwrapName, LOG_PID, LOG_AUTH);
#endif

5583 5584
#ifndef DBUG_OFF
  test_lc_time_sz();
5585
  srand((uint) time(NULL)); 
5586 5587
#endif

unknown's avatar
unknown committed
5588 5589 5590
  /*
    We have enough space for fiddling with the argv, continue
  */
unknown's avatar
unknown committed
5591
  check_data_home(mysql_real_data_home);
5592
  if (my_setwd(mysql_real_data_home, opt_abort ? 0 : MYF(MY_WME)) && !opt_abort)
unknown's avatar
unknown committed
5593
    unireg_abort(1);				/* purecov: inspected */
unknown's avatar
unknown committed
5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604

  if ((user_info= check_user(mysqld_user)))
  {
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
    if (locked_in_memory) // getuid() == 0 here
      set_effective_user(user_info);
    else
#endif
      set_user(mysqld_user, user_info);
  }

5605 5606 5607
  if (WSREP_ON && wsrep_check_opts())
    global_system_variables.wsrep_on= 0;

5608
  if (opt_bin_log && !global_system_variables.server_id)
unknown's avatar
unknown committed
5609
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
5610
    SYSVAR_AUTOSIZE(global_system_variables.server_id, ::server_id= 1);
unknown's avatar
unknown committed
5611
#ifdef EXTRA_DEBUG
5612 5613 5614 5615
    sql_print_warning("You have enabled the binary log, but you haven't set "
                      "server-id to a non-zero value: we force server id to 1; "
                      "updates will be logged to the binary log, but "
                      "connections from slaves will not be accepted.");
5616
#endif
unknown's avatar
unknown committed
5617 5618
  }

5619 5620 5621 5622 5623 5624 5625 5626
  /* 
   The subsequent calls may take a long time : e.g. innodb log read.
   Thus set the long running service control manager timeout
  */
#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
  Service.SetSlowStarting(slow_start_timeout);
#endif

unknown's avatar
unknown committed
5627
  if (init_server_components())
unknown's avatar
unknown committed
5628
    unireg_abort(1);
unknown's avatar
unknown committed
5629

5630
  init_ssl();
unknown's avatar
unknown committed
5631 5632
  network_init();

unknown's avatar
unknown committed
5633 5634 5635
#ifdef __WIN__
  if (!opt_console)
  {
5636 5637
    if (reopen_fstreams(log_error_file, stdout, stderr))
      unireg_abort(1);
5638
    setbuf(stderr, NULL);
unknown's avatar
unknown committed
5639
    FreeConsole();				// Remove window
5640
  }
unknown's avatar
unknown committed
5641 5642
#endif

5643 5644
  // Recover and exit.
  if (wsrep_recovery)
5645 5646
  {
    select_thread_in_use= 0;
5647 5648 5649 5650
    if (WSREP_ON)
      wsrep_recover();
    else
      sql_print_information("WSREP: disabled, skipping position recovery");
5651 5652 5653
    unireg_abort(0);
  }

unknown's avatar
unknown committed
5654 5655 5656 5657 5658
  /*
    init signals & alarm
    After this we can't quit by a simple unireg_abort
  */
  start_signal_handler();				// Creates pidfile
5659

5660
  if (mysql_rm_tmp_tables() || acl_init(opt_noacl) ||
5661
      my_tz_init((THD *)0, default_tz_name, opt_bootstrap))
unknown's avatar
unknown committed
5662 5663 5664
  {
    abort_loop=1;
    select_thread_in_use=0;
5665

unknown's avatar
unknown committed
5666
    (void) pthread_kill(signal_thread, MYSQL_KILL_SIGNAL);
5667

5668
    delete_pid_file(MYF(MY_WME));
5669

5670
    if (mysql_socket_getfd(unix_sock) != INVALID_SOCKET)
5671
      unlink(mysqld_unix_port);
unknown's avatar
unknown committed
5672 5673
    exit(1);
  }
5674

unknown's avatar
unknown committed
5675
  if (!opt_noacl)
5676
    (void) grant_init();
unknown's avatar
unknown committed
5677 5678

  if (!opt_noacl)
5679 5680
  {
#ifdef HAVE_DLOPEN
unknown's avatar
unknown committed
5681 5682
    udf_init();
#endif
5683
  }
5684

5685
  init_status_vars();
unknown's avatar
unknown committed
5686 5687
  if (opt_bootstrap) /* If running with bootstrap, do not start replication. */
    opt_skip_slave_start= 1;
5688 5689

  binlog_unsafe_map_init();
5690

Marc Alff's avatar
Marc Alff committed
5691 5692 5693 5694 5695 5696
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
  initialize_performance_schema_acl(opt_bootstrap);
#endif

  initialize_information_schema_acl();

5697 5698 5699 5700 5701
  execute_ddl_log_recovery();

  if (Events::init(opt_noacl || opt_bootstrap))
    unireg_abort(1);

5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727
  if (WSREP_ON)
  {
    if (opt_bootstrap)
    {
      /*! bootstrap wsrep init was taken care of above */
    }
    else
    {
      wsrep_SE_initialized();

      if (wsrep_before_SE())
      {
        /*! in case of no SST wsrep waits in view handler callback */
        wsrep_SE_init_grab();
        wsrep_SE_init_done();
        /*! in case of SST wsrep waits for wsrep->sst_received */
        wsrep_sst_continue();
      }
      else
      {
        wsrep_init_startup (false);
      }

      wsrep_create_appliers(wsrep_slave_threads - 1);
    }
  }
Sergei Golubchik's avatar
Sergei Golubchik committed
5728 5729
  else
    wsrep_init_startup (false);
5730

5731
 if (opt_bootstrap)
unknown's avatar
unknown committed
5732
  {
5733
    select_thread_in_use= 0;                    // Allow 'kill' to work
Marc Alff's avatar
Marc Alff committed
5734
    bootstrap(mysql_stdin);
5735 5736 5737 5738 5739 5740 5741
    if (!kill_in_progress)
      unireg_abort(bootstrap_error ? 1 : 0);
    else
    {
      sleep(2);                                 // Wait for kill
      exit(0);
    }
unknown's avatar
unknown committed
5742
  }
5743

5744 5745 5746
  /* It's now safe to use thread specific memory */
  mysqld_server_initialized= 1;

5747 5748 5749
  create_shutdown_thread();
  start_handle_manager();

5750 5751 5752
  /* Copy default global rpl_filter to global_rpl_filter */
  copy_filter_setting(global_rpl_filter, get_or_create_rpl_filter("", 0));

5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763
  /*
    init_slave() must be called after the thread keys are created.
    Some parts of the code (e.g. SHOW STATUS LIKE 'slave_running' and other
    places) assume that active_mi != 0, so let's fail if it's 0 (out of
    memory); a message has already been printed.
  */
  if (init_slave() && !active_mi)
  {
    unireg_abort(1);
  }

5764
  if (opt_init_file && *opt_init_file)
unknown's avatar
unknown committed
5765 5766 5767 5768
  {
    if (read_init_file(opt_init_file))
      unireg_abort(1);
  }
unknown's avatar
unknown committed
5769

5770
  sql_print_information(ER_DEFAULT(ER_STARTUP),my_progname,server_version,
5771 5772
                        ((mysql_socket_getfd(unix_sock) == INVALID_SOCKET) ?
                         (char*) "" : mysqld_unix_port),
unknown's avatar
unknown committed
5773
                         mysqld_port,
unknown's avatar
Merge  
unknown committed
5774
                         MYSQL_COMPILATION_COMMENT);
5775
  fclose(stdin);
5776 5777 5778
#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
  Service.SetRunning();
#endif
unknown's avatar
unknown committed
5779

unknown's avatar
unknown committed
5780
  /* Signal threads waiting for server to be started */
Marc Alff's avatar
Marc Alff committed
5781
  mysql_mutex_lock(&LOCK_server_started);
unknown's avatar
unknown committed
5782
  mysqld_server_started= 1;
Marc Alff's avatar
Marc Alff committed
5783 5784
  mysql_cond_signal(&COND_server_started);
  mysql_mutex_unlock(&LOCK_server_started);
unknown's avatar
unknown committed
5785

5786
#if defined(_WIN32) || defined(HAVE_SMEM)
5787
  handle_connections_methods();
unknown's avatar
unknown committed
5788
#else
5789 5790
  handle_connections_sockets();
#endif /* _WIN32 || HAVE_SMEM */
unknown's avatar
unknown committed
5791 5792

  /* (void) pthread_attr_destroy(&connection_attrib); */
5793

unknown's avatar
unknown committed
5794 5795 5796
  DBUG_PRINT("quit",("Exiting main thread"));

#ifndef __WIN__
unknown's avatar
unknown committed
5797
#ifdef EXTRA_DEBUG2
unknown's avatar
unknown committed
5798 5799
  sql_print_error("Before Lock_thread_count");
#endif
5800
  WSREP_DEBUG("Before Lock_thread_count");
Marc Alff's avatar
Marc Alff committed
5801
  mysql_mutex_lock(&LOCK_thread_count);
unknown's avatar
unknown committed
5802
  DBUG_PRINT("quit", ("Got thread_count mutex"));
unknown's avatar
unknown committed
5803
  select_thread_in_use=0;			// For close_connections
Marc Alff's avatar
Marc Alff committed
5804 5805
  mysql_mutex_unlock(&LOCK_thread_count);
  mysql_cond_broadcast(&COND_thread_count);
unknown's avatar
unknown committed
5806
#ifdef EXTRA_DEBUG2
unknown's avatar
unknown committed
5807 5808
  sql_print_error("After lock_thread_count");
#endif
unknown's avatar
merge  
unknown committed
5809
#endif /* __WIN__ */
5810

5811
#ifdef HAVE_PSI_THREAD_INTERFACE
5812 5813 5814 5815
  /*
    Disable the main thread instrumentation,
    to avoid recording events during the shutdown.
  */
5816
  PSI_THREAD_CALL(delete_current_thread)();
5817 5818
#endif

unknown's avatar
unknown committed
5819
  /* Wait until cleanup is done */
Marc Alff's avatar
Marc Alff committed
5820
  mysql_mutex_lock(&LOCK_thread_count);
unknown's avatar
unknown committed
5821
  while (!ready_to_exit)
Marc Alff's avatar
Marc Alff committed
5822 5823
    mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
merge  
unknown committed
5824 5825

#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
unknown's avatar
merge  
unknown committed
5826 5827 5828 5829
  if (Service.IsNT() && start_mode)
    Service.Stop();
  else
  {
unknown's avatar
unknown committed
5830
    Service.SetShutdownEvent(0);
unknown's avatar
merge  
unknown committed
5831 5832 5833
    if (hEventShutdown)
      CloseHandle(hEventShutdown);
  }
unknown's avatar
unknown committed
5834
#endif
5835
  mysqld_exit(0);
5836
  return 0;
unknown's avatar
unknown committed
5837 5838
}

5839
#endif /* !EMBEDDED_LIBRARY */
unknown's avatar
unknown committed
5840

unknown's avatar
SCRUM  
unknown committed
5841

5842 5843 5844 5845 5846
/****************************************************************************
  Main and thread entry function for Win32
  (all this is needed only to run mysqld as a service on WinNT)
****************************************************************************/

unknown's avatar
unknown committed
5847
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
unknown's avatar
unknown committed
5848 5849
int mysql_service(void *p)
{
5850 5851 5852
  if (my_thread_init())
    return 1;
  
5853 5854 5855 5856
  if (use_opt_args)
    win_main(opt_argc, opt_argv);
  else
    win_main(Service.my_argc, Service.my_argv);
5857 5858

  my_thread_end();
unknown's avatar
unknown committed
5859 5860 5861
  return 0;
}

5862 5863 5864 5865 5866 5867 5868 5869

/* Quote string if it contains space, else copy */

static char *add_quoted_string(char *to, const char *from, char *to_end)
{
  uint length= (uint) (to_end-to);

  if (!strchr(from, ' '))
unknown's avatar
unknown committed
5870 5871
    return strmake(to, from, length-1);
  return strxnmov(to, length-1, "\"", from, "\"", NullS);
5872 5873 5874
}


unknown's avatar
unknown committed
5875 5876
/**
  Handle basic handling of services, like installation and removal.
5877

unknown's avatar
unknown committed
5878 5879 5880 5881 5882 5883
  @param argv	   	        Pointer to argument list
  @param servicename		Internal name of service
  @param displayname		Display name of service (in taskbar ?)
  @param file_path		Path to this program
  @param startup_option	Startup option to mysqld

5884 5885
  @retval 0	option handled
  @retval 1	Could not handle option
unknown's avatar
unknown committed
5886
*/
5887

5888 5889 5890 5891 5892
static bool
default_service_handling(char **argv,
			 const char *servicename,
			 const char *displayname,
			 const char *file_path,
unknown's avatar
Merge  
unknown committed
5893 5894
			 const char *extra_opt,
			 const char *account_name)
5895
{
5896
  char path_and_service[FN_REFLEN+FN_REFLEN+32], *pos, *end;
5897
  const char *opt_delim;
5898
  end= path_and_service + sizeof(path_and_service)-3;
5899 5900 5901

  /* We have to quote filename if it contains spaces */
  pos= add_quoted_string(path_and_service, file_path, end);
5902
  if (extra_opt && *extra_opt)
5903
  {
5904 5905 5906 5907 5908
    /* 
     Add option after file_path. There will be zero or one extra option.  It's 
     assumed to be --defaults-file=file but isn't checked.  The variable (not
     the option name) should be quoted if it contains a string.  
    */
5909
    *pos++= ' ';
5910 5911 5912
    if (opt_delim= strchr(extra_opt, '='))
    {
      size_t length= ++opt_delim - extra_opt;
5913
      pos= strnmov(pos, extra_opt, length);
5914 5915 5916 5917 5918
    }
    else
      opt_delim= extra_opt;
    
    pos= add_quoted_string(pos, opt_delim, end);
5919
  }
5920 5921
  /* We must have servicename last */
  *pos++= ' ';
unknown's avatar
unknown committed
5922
  (void) add_quoted_string(pos, servicename, end);
5923

5924 5925
  if (Service.got_service_option(argv, "install"))
  {
unknown's avatar
Merge  
unknown committed
5926 5927
    Service.Install(1, servicename, displayname, path_and_service,
                    account_name);
5928 5929 5930 5931
    return 0;
  }
  if (Service.got_service_option(argv, "install-manual"))
  {
unknown's avatar
Merge  
unknown committed
5932 5933
    Service.Install(0, servicename, displayname, path_and_service,
                    account_name);
5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944
    return 0;
  }
  if (Service.got_service_option(argv, "remove"))
  {
    Service.Remove(servicename);
    return 0;
  }
  return 1;
}


5945
int mysqld_main(int argc, char **argv)
unknown's avatar
unknown committed
5946
{
5947 5948
  my_progname= argv[0];

unknown's avatar
unknown committed
5949 5950 5951 5952
  /*
    When several instances are running on the same machine, we
    need to have an  unique  named  hEventShudown  through the
    application PID e.g.: MySQLShutdown1890; MySQLShutdown2342
unknown's avatar
Merge  
unknown committed
5953
  */
5954
  int10_to_str((int) GetCurrentProcessId(),strmov(shutdown_event_name,
unknown's avatar
Merge  
unknown committed
5955 5956
                                                  "MySQLShutdown"), 10);

5957 5958 5959
  /* Must be initialized early for comparison of service name */
  system_charset_info= &my_charset_utf8_general_ci;

5960 5961 5962 5963 5964 5965
  if (my_init())
  {
    fprintf(stderr, "my_init() failed.");
    return 1;
  }

unknown's avatar
unknown committed
5966
  if (Service.GetOS())	/* true NT family */
unknown's avatar
unknown committed
5967
  {
unknown's avatar
unknown committed
5968
    char file_path[FN_REFLEN];
5969
    my_path(file_path, argv[0], "");		      /* Find name in path */
unknown's avatar
unknown committed
5970 5971
    fn_format(file_path,argv[0],file_path,"",
	      MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_RESOLVE_SYMLINKS);
unknown's avatar
unknown committed
5972

unknown's avatar
unknown committed
5973
    if (argc == 2)
5974
    {
5975
      if (!default_service_handling(argv, MYSQL_SERVICENAME, MYSQL_SERVICENAME,
unknown's avatar
Merge  
unknown committed
5976
				   file_path, "", NULL))
5977
	return 0;
unknown's avatar
unknown committed
5978
      if (Service.IsService(argv[1]))        /* Start an optional service */
unknown's avatar
unknown committed
5979
      {
unknown's avatar
unknown committed
5980 5981 5982 5983 5984 5985
	/*
	  Only add the service name to the groups read from the config file
	  if it's not "MySQL". (The default service name should be 'mysqld'
	  but we started a bad tradition by calling it MySQL from the start
	  and we are now stuck with it.
	*/
5986
	if (my_strcasecmp(system_charset_info, argv[1],"mysql"))
5987
	  load_default_groups[load_default_groups_sz-2]= argv[1];
unknown's avatar
unknown committed
5988
        start_mode= 1;
5989
        Service.Init(argv[1], mysql_service);
unknown's avatar
unknown committed
5990 5991 5992 5993
        return 0;
      }
    }
    else if (argc == 3) /* install or remove any optional service */
unknown's avatar
unknown committed
5994
    {
unknown's avatar
Merge  
unknown committed
5995 5996
      if (!default_service_handling(argv, argv[2], argv[2], file_path, "",
                                    NULL))
5997 5998
	return 0;
      if (Service.IsService(argv[2]))
unknown's avatar
unknown committed
5999
      {
6000 6001 6002 6003
	/*
	  mysqld was started as
	  mysqld --defaults-file=my_path\my.ini service-name
	*/
6004
	use_opt_args=1;
6005
	opt_argc= 2;				// Skip service-name
6006 6007
	opt_argv=argv;
	start_mode= 1;
6008
	if (my_strcasecmp(system_charset_info, argv[2],"mysql"))
6009
	  load_default_groups[load_default_groups_sz-2]= argv[2];
6010
	Service.Init(argv[2], mysql_service);
6011
	return 0;
unknown's avatar
unknown committed
6012 6013
      }
    }
unknown's avatar
Merge  
unknown committed
6014
    else if (argc == 4 || argc == 5)
6015 6016
    {
      /*
unknown's avatar
Merge  
unknown committed
6017 6018 6019 6020 6021
        This may seem strange, because we handle --local-service while
        preserving 4.1's behavior of allowing any one other argument that is
        passed to the service on startup. (The assumption is that this is
        --defaults-file=file, but that was not enforced in 4.1, so we don't
        enforce it here.)
6022
      */
unknown's avatar
Merge  
unknown committed
6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037
      const char *extra_opt= NullS;
      const char *account_name = NullS;
      int index;
      for (index = 3; index < argc; index++)
      {
        if (!strcmp(argv[index], "--local-service"))
          account_name= "NT AUTHORITY\\LocalService";
        else
          extra_opt= argv[index];
      }

      if (argc == 4 || account_name)
        if (!default_service_handling(argv, argv[2], argv[2], file_path,
                                      extra_opt, account_name))
          return 0;
6038
    }
unknown's avatar
unknown committed
6039
    else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME))
unknown's avatar
unknown committed
6040
    {
unknown's avatar
unknown committed
6041 6042 6043
      /* start the default service */
      start_mode= 1;
      Service.Init(MYSQL_SERVICENAME, mysql_service);
unknown's avatar
unknown committed
6044 6045 6046
      return 0;
    }
  }
unknown's avatar
unknown committed
6047
  /* Start as standalone server */
unknown's avatar
unknown committed
6048 6049 6050 6051 6052 6053 6054 6055
  Service.my_argc=argc;
  Service.my_argv=argv;
  mysql_service(NULL);
  return 0;
}
#endif


unknown's avatar
unknown committed
6056
/**
6057 6058 6059
  Execute all commands from a file. Used by the mysql_install_db script to
  create MySQL privilege tables without having to start a full MySQL server.
*/
6060

Marc Alff's avatar
Marc Alff committed
6061
static void bootstrap(MYSQL_FILE *file)
unknown's avatar
unknown committed
6062
{
6063
  DBUG_ENTER("bootstrap");
6064

6065
  THD *thd= new THD;
6066 6067 6068
#ifdef WITH_WSREP
  thd->variables.wsrep_on= 0;
#endif
unknown's avatar
unknown committed
6069
  thd->bootstrap=1;
6070
  my_net_init(&thd->net,(st_vio*) 0, MYF(0));
unknown's avatar
unknown committed
6071
  thd->max_client_packet_length= thd->net.max_packet;
6072
  thd->security_ctx->master_access= ~(ulong)0;
unknown's avatar
unknown committed
6073
  thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
Michael Widenius's avatar
Michael Widenius committed
6074
  thread_count++;                        // Safe as only one thread running
6075
  in_bootstrap= TRUE;
6076 6077

  bootstrap_file=file;
unknown's avatar
unknown committed
6078
#ifndef EMBEDDED_LIBRARY			// TODO:  Enable this
6079 6080 6081 6082 6083
  int error;
  if ((error= mysql_thread_create(key_thread_bootstrap,
                                  &thd->real_id, &connection_attrib,
                                  handle_bootstrap,
                                  (void*) thd)))
6084
  {
6085 6086
    sql_print_warning("Can't create thread to handle bootstrap (errno= %d)",
                      error);
unknown's avatar
Merge  
unknown committed
6087 6088
    bootstrap_error=-1;
    DBUG_VOID_RETURN;
6089 6090
  }
  /* Wait for thread to die */
Marc Alff's avatar
Marc Alff committed
6091
  mysql_mutex_lock(&LOCK_thread_count);
6092
  while (in_bootstrap)
6093
  {
Marc Alff's avatar
Marc Alff committed
6094
    mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
6095 6096
    DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
  }
Marc Alff's avatar
Marc Alff committed
6097
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
6098 6099
#else
  thd->mysql= 0;
Marc Alff's avatar
Marc Alff committed
6100
  do_handle_bootstrap(thd);
unknown's avatar
unknown committed
6101 6102
#endif

unknown's avatar
Merge  
unknown committed
6103
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
6104 6105
}

6106

unknown's avatar
unknown committed
6107 6108
static bool read_init_file(char *file_name)
{
Marc Alff's avatar
Marc Alff committed
6109
  MYSQL_FILE *file;
unknown's avatar
unknown committed
6110 6111
  DBUG_ENTER("read_init_file");
  DBUG_PRINT("enter",("name: %s",file_name));
Marc Alff's avatar
Marc Alff committed
6112 6113
  if (!(file= mysql_file_fopen(key_file_init, file_name,
                               O_RDONLY, MYF(MY_WME))))
6114
    DBUG_RETURN(TRUE);
unknown's avatar
Merge  
unknown committed
6115
  bootstrap(file);
Marc Alff's avatar
Marc Alff committed
6116
  mysql_file_fclose(file, MYF(MY_WME));
6117
  DBUG_RETURN(FALSE);
unknown's avatar
unknown committed
6118 6119 6120
}


Mikael Ronström's avatar
Mikael Ronström committed
6121 6122 6123 6124 6125 6126 6127 6128
/**
  Increment number of created threads
*/
void inc_thread_created(void)
{
  thread_created++;
}

6129
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
6130 6131 6132 6133 6134 6135 6136 6137 6138 6139

/*
   Simple scheduler that use the main thread to handle the request

   NOTES
     This is only used for debugging, when starting mysqld with
     --thread-handling=no-threads or --one-thread

     When we enter this function, LOCK_thread_count is hold!
*/
6140

unknown's avatar
unknown committed
6141 6142
void handle_connection_in_main_thread(THD *thd)
{
Marc Alff's avatar
Marc Alff committed
6143
  mysql_mutex_assert_owner(&LOCK_thread_count);
unknown's avatar
unknown committed
6144 6145
  thread_cache_size=0;			// Safety
  threads.append(thd);
Marc Alff's avatar
Marc Alff committed
6146
  mysql_mutex_unlock(&LOCK_thread_count);
6147
  thd->start_utime= microsecond_interval_timer();
Marc Alff's avatar
Marc Alff committed
6148
  do_handle_one_connection(thd);
unknown's avatar
unknown committed
6149 6150 6151 6152 6153 6154 6155 6156 6157
}


/*
  Scheduler that uses one thread per connection
*/

void create_thread_to_handle_connection(THD *thd)
{
Michael Widenius's avatar
Michael Widenius committed
6158 6159 6160 6161
  DBUG_ENTER("create_thread_to_handle_connection");
  mysql_mutex_assert_owner(&LOCK_thread_count);

  /* Check if we can get thread from the cache */
unknown's avatar
unknown committed
6162 6163
  if (cached_thread_count > wake_thread)
  {
Michael Widenius's avatar
Michael Widenius committed
6164 6165 6166
    mysql_mutex_lock(&LOCK_thread_cache);
    /* Recheck condition when we have the lock */
    if (cached_thread_count > wake_thread)
unknown's avatar
unknown committed
6167
    {
Marc Alff's avatar
Marc Alff committed
6168
      mysql_mutex_unlock(&LOCK_thread_count);
Michael Widenius's avatar
Michael Widenius committed
6169 6170 6171 6172 6173 6174 6175 6176 6177 6178
      /* Get thread from cache */
      thread_cache.push_back(thd);
      wake_thread++;
      mysql_cond_signal(&COND_thread_cache);
      mysql_mutex_unlock(&LOCK_thread_cache);
      DBUG_PRINT("info",("Thread created"));
      DBUG_VOID_RETURN;
    }
    mysql_mutex_unlock(&LOCK_thread_cache);
  }
6179

Michael Widenius's avatar
Michael Widenius committed
6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197
  char error_message_buff[MYSQL_ERRMSG_SIZE];
  /* Create new thread to handle connection */
  int error;
  thread_created++;
  threads.append(thd);
  DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id));
  thd->prior_thr_create_utime= microsecond_interval_timer();
  if ((error= mysql_thread_create(key_thread_one_connection,
                                  &thd->real_id, &connection_attrib,
                                  handle_one_connection,
                                  (void*) thd)))
  {
    /* purecov: begin inspected */
    DBUG_PRINT("error",
               ("Can't create thread to handle request (error %d)",
                error));
    thd->killed= KILL_CONNECTION;             // Safety
    mysql_mutex_unlock(&LOCK_thread_count);
6198

Michael Widenius's avatar
Michael Widenius committed
6199 6200 6201
    mysql_mutex_lock(&LOCK_connection_count);
    (*thd->scheduler->connection_count)--;
    mysql_mutex_unlock(&LOCK_connection_count);
6202

Michael Widenius's avatar
Michael Widenius committed
6203
    statistic_increment(aborted_connects,&LOCK_status);
Sergei Golubchik's avatar
Sergei Golubchik committed
6204
    statistic_increment(connection_errors_internal, &LOCK_status);
Michael Widenius's avatar
Michael Widenius committed
6205 6206 6207 6208 6209 6210 6211 6212 6213 6214
    /* Can't use my_error() since store_globals has not been called. */
    my_snprintf(error_message_buff, sizeof(error_message_buff),
                ER_THD(thd, ER_CANT_CREATE_THREAD), error);
    net_send_error(thd, ER_CANT_CREATE_THREAD, error_message_buff, NULL);
    close_connection(thd, ER_OUT_OF_RESOURCES);

    mysql_mutex_lock(&LOCK_thread_count);
    thd->unlink();
    mysql_mutex_unlock(&LOCK_thread_count);
    delete thd;
6215
    thread_safe_decrement32(&thread_count);
Michael Widenius's avatar
Michael Widenius committed
6216 6217
    return;
    /* purecov: end */
unknown's avatar
unknown committed
6218
  }
Marc Alff's avatar
Marc Alff committed
6219
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
6220
  DBUG_PRINT("info",("Thread created"));
Michael Widenius's avatar
Michael Widenius committed
6221
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
6222 6223 6224
}


unknown's avatar
unknown committed
6225
/**
6226 6227 6228 6229 6230 6231
  Create new thread to handle incoming connection.

    This function will create new thread to handle the incoming
    connection.  If there are idle cached threads one will be used.
    'thd' will be pushed into 'threads'.

unknown's avatar
unknown committed
6232
    In single-threaded mode (\#define ONE_THREAD) connection will be
6233 6234
    handled inside this function.

unknown's avatar
unknown committed
6235
  @param[in,out] thd    Thread handle of future thread.
6236 6237
*/

unknown's avatar
unknown committed
6238 6239 6240 6241
static void create_new_thread(THD *thd)
{
  DBUG_ENTER("create_new_thread");

6242 6243 6244 6245 6246
  /*
    Don't allow too many connections. We roughly check here that we allow
    only (max_connections + 1) connections.
  */

Marc Alff's avatar
Marc Alff committed
6247
  mysql_mutex_lock(&LOCK_connection_count);
6248

6249 6250
  if (*thd->scheduler->connection_count >=
      *thd->scheduler->max_connections + 1|| abort_loop)
unknown's avatar
unknown committed
6251
  {
Marc Alff's avatar
Marc Alff committed
6252
    mysql_mutex_unlock(&LOCK_connection_count);
6253

unknown's avatar
unknown committed
6254
    DBUG_PRINT("error",("Too many connections"));
6255
    close_connection(thd, ER_CON_COUNT_ERROR);
6256
    statistic_increment(denied_connections, &LOCK_status);
unknown's avatar
unknown committed
6257
    delete thd;
unknown's avatar
unknown committed
6258
    statistic_increment(connection_errors_max_connection, &LOCK_status);
unknown's avatar
unknown committed
6259 6260
    DBUG_VOID_RETURN;
  }
6261

6262
  ++*thd->scheduler->connection_count;
6263

6264 6265
  if (connection_count + extra_connection_count > max_used_connections)
    max_used_connections= connection_count + extra_connection_count;
6266

Marc Alff's avatar
Marc Alff committed
6267
  mysql_mutex_unlock(&LOCK_connection_count);
6268

6269
  thread_safe_increment32(&thread_count);
6270

Michael Widenius's avatar
Michael Widenius committed
6271
  /* Start a new thread to handle connection. */
Marc Alff's avatar
Marc Alff committed
6272
  mysql_mutex_lock(&LOCK_thread_count);
6273 6274 6275 6276 6277
  /*
    The initialization of thread_id is done in create_embedded_thd() for
    the embedded library.
    TODO: refactor this to avoid code duplication there
  */
unknown's avatar
unknown committed
6278
  thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
unknown's avatar
unknown committed
6279

Sergei Golubchik's avatar
Sergei Golubchik committed
6280
  MYSQL_CALLBACK(thd->scheduler, add_connection, (thd));
6281

unknown's avatar
unknown committed
6282 6283
  DBUG_VOID_RETURN;
}
6284 6285
#endif /* EMBEDDED_LIBRARY */

unknown's avatar
unknown committed
6286

unknown's avatar
unknown committed
6287 6288 6289 6290
#ifdef SIGNALS_DONT_BREAK_READ
inline void kill_broken_server()
{
  /* hack to get around signals ignored in syscalls for problem OS's */
6291 6292 6293
  if (mysql_socket_getfd(unix_sock) == INVALID_SOCKET ||
      (!opt_disable_networking &&
       mysql_socket_getfd(base_ip_sock) == INVALID_SOCKET))
unknown's avatar
unknown committed
6294 6295
  {
    select_thread_in_use = 0;
unknown's avatar
unknown committed
6296
    /* The following call will never return */
6297
    DBUG_PRINT("general", ("killing server because socket is closed"));
6298
    kill_server((void*) MYSQL_KILL_SIGNAL);
unknown's avatar
unknown committed
6299 6300 6301 6302 6303 6304
  }
}
#define MAYBE_BROKEN_SYSCALL kill_broken_server();
#else
#define MAYBE_BROKEN_SYSCALL
#endif
unknown's avatar
unknown committed
6305 6306 6307

	/* Handle new connections and spawn new process to handle them */

6308
#ifndef EMBEDDED_LIBRARY
6309

6310
void handle_connections_sockets()
unknown's avatar
unknown committed
6311
{
6312 6313
  MYSQL_SOCKET sock= mysql_socket_invalid();
  MYSQL_SOCKET new_sock= mysql_socket_invalid();
unknown's avatar
unknown committed
6314 6315
  uint error_count=0;
  THD *thd;
6316
  struct sockaddr_storage cAddr;
Michael Widenius's avatar
Michael Widenius committed
6317 6318 6319 6320
  int ip_flags __attribute__((unused))=0;
  int socket_flags __attribute__((unused))= 0;
  int extra_ip_flags __attribute__((unused))=0;
  int flags=0,retval;
unknown's avatar
unknown committed
6321
  st_vio *vio_tmp;
6322
  bool is_unix_sock;
6323 6324
#ifdef HAVE_POLL
  int socket_count= 0;
Sergei Golubchik's avatar
Sergei Golubchik committed
6325
  struct pollfd fds[3]; // for ip_sock, unix_sock and extra_ip_sock
6326
  MYSQL_SOCKET  pfs_fds[3]; // for performance schema
Sergei Golubchik's avatar
Sergei Golubchik committed
6327
#define setup_fds(X)                    \
Sergei Golubchik's avatar
Sergei Golubchik committed
6328
    mysql_socket_set_thread_owner(X);             \
6329 6330
    pfs_fds[socket_count]= (X);                   \
    fds[socket_count].fd= mysql_socket_getfd(X);  \
Sergei Golubchik's avatar
Sergei Golubchik committed
6331 6332
    fds[socket_count].events= POLLIN;   \
    socket_count++
6333
#else
6334
#define setup_fds(X)    FD_SET(mysql_socket_getfd(X),&clientFDs)
6335
  fd_set readFDs,clientFDs;
Sergei Golubchik's avatar
Sergei Golubchik committed
6336
  FD_ZERO(&clientFDs);
6337 6338
#endif

unknown's avatar
unknown committed
6339 6340
  DBUG_ENTER("handle_connections_sockets");

6341
  if (mysql_socket_getfd(base_ip_sock) != INVALID_SOCKET)
unknown's avatar
unknown committed
6342
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
6343
    setup_fds(base_ip_sock);
6344
    ip_flags = fcntl(mysql_socket_getfd(base_ip_sock), F_GETFL, 0);
unknown's avatar
unknown committed
6345
  }
6346
  if (mysql_socket_getfd(extra_ip_sock) != INVALID_SOCKET)
6347
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
6348
    setup_fds(extra_ip_sock);
6349
    extra_ip_flags = fcntl(mysql_socket_getfd(extra_ip_sock), F_GETFL, 0);
unknown's avatar
unknown committed
6350 6351
  }
#ifdef HAVE_SYS_UN_H
Sergei Golubchik's avatar
Sergei Golubchik committed
6352
  setup_fds(unix_sock);
6353
  socket_flags=fcntl(mysql_socket_getfd(unix_sock), F_GETFL, 0);
unknown's avatar
unknown committed
6354 6355 6356
#endif

  DBUG_PRINT("general",("Waiting for connections."));
unknown's avatar
unknown committed
6357
  MAYBE_BROKEN_SYSCALL;
unknown's avatar
unknown committed
6358 6359
  while (!abort_loop)
  {
6360 6361
#ifdef HAVE_POLL
    retval= poll(fds, socket_count, -1);
unknown's avatar
unknown committed
6362
#else
6363
    readFDs=clientFDs;
6364
    retval= select((int) 0,&readFDs,0,0,0);
6365 6366 6367
#endif

    if (retval < 0)
unknown's avatar
unknown committed
6368
    {
unknown's avatar
unknown committed
6369
      if (socket_errno != SOCKET_EINTR)
unknown's avatar
unknown committed
6370
      {
unknown's avatar
unknown committed
6371 6372 6373 6374 6375 6376
        /*
          select(2)/poll(2) failed on the listening port.
          There is not much details to report about the client,
          increment the server global status variable.
        */
        statistic_increment(connection_errors_accept, &LOCK_status);
unknown's avatar
unknown committed
6377
	if (!select_errors++ && !abort_loop)	/* purecov: inspected */
unknown's avatar
unknown committed
6378
	  sql_print_error("mysqld: Got error %d from select",socket_errno); /* purecov: inspected */
unknown's avatar
unknown committed
6379
      }
unknown's avatar
unknown committed
6380
      MAYBE_BROKEN_SYSCALL
unknown's avatar
unknown committed
6381 6382
      continue;
    }
6383

unknown's avatar
unknown committed
6384
    if (abort_loop)
unknown's avatar
unknown committed
6385 6386
    {
      MAYBE_BROKEN_SYSCALL;
unknown's avatar
unknown committed
6387
      break;
unknown's avatar
unknown committed
6388
    }
unknown's avatar
unknown committed
6389

6390
    /* Is this a new connection request ? */
6391 6392 6393 6394 6395
#ifdef HAVE_POLL
    for (int i= 0; i < socket_count; ++i) 
    {
      if (fds[i].revents & POLLIN)
      {
6396 6397
        sock= pfs_fds[i];
        flags= fcntl(mysql_socket_getfd(sock), F_GETFL, 0);
6398 6399 6400 6401
        break;
      }
    }
#else  // HAVE_POLL
6402
    if (FD_ISSET(mysql_socket_getfd(base_ip_sock),&readFDs))
unknown's avatar
unknown committed
6403
    {
Sergei Golubchik's avatar
Sergei Golubchik committed
6404 6405
      sock=  base_ip_sock;
      flags= ip_flags;
unknown's avatar
unknown committed
6406 6407
    }
    else
6408
    if (FD_ISSET(mysql_socket_getfd(extra_ip_sock),&readFDs))
unknown's avatar
unknown committed
6409
    {
Sergei Golubchik's avatar
Sergei Golubchik committed
6410 6411 6412 6413 6414 6415 6416
      sock=  extra_ip_sock;
      flags= extra_ip_flags;
    }
    else
    {
      sock = unix_sock;
      flags= socket_flags;
unknown's avatar
unknown committed
6417
    }
6418
#endif // HAVE_POLL
unknown's avatar
unknown committed
6419 6420 6421 6422 6423

#if !defined(NO_FCNTL_NONBLOCK)
    if (!(test_flags & TEST_BLOCKING))
    {
#if defined(O_NONBLOCK)
6424
      fcntl(mysql_socket_getfd(sock), F_SETFL, flags | O_NONBLOCK);
unknown's avatar
unknown committed
6425
#elif defined(O_NDELAY)
6426
      fcntl(mysql_socket_getfd(sock), F_SETFL, flags | O_NDELAY);
unknown's avatar
unknown committed
6427 6428 6429 6430 6431
#endif
    }
#endif /* NO_FCNTL_NONBLOCK */
    for (uint retry=0; retry < MAX_ACCEPT_RETRY; retry++)
    {
6432
      size_socket length= sizeof(struct sockaddr_storage);
6433 6434 6435 6436
      new_sock= mysql_socket_accept(key_socket_client_connection, sock,
                                    (struct sockaddr *)(&cAddr),
                                    &length);
      if (mysql_socket_getfd(new_sock) != INVALID_SOCKET ||
unknown's avatar
unknown committed
6437
	  (socket_errno != SOCKET_EINTR && socket_errno != SOCKET_EAGAIN))
unknown's avatar
unknown committed
6438
	break;
unknown's avatar
unknown committed
6439
      MAYBE_BROKEN_SYSCALL;
unknown's avatar
unknown committed
6440 6441 6442 6443
#if !defined(NO_FCNTL_NONBLOCK)
      if (!(test_flags & TEST_BLOCKING))
      {
	if (retry == MAX_ACCEPT_RETRY - 1)
6444 6445 6446 6447
        {
          // Try without O_NONBLOCK
	  fcntl(mysql_socket_getfd(sock), F_SETFL, flags);
        }
unknown's avatar
unknown committed
6448 6449 6450 6451 6452
      }
#endif
    }
#if !defined(NO_FCNTL_NONBLOCK)
    if (!(test_flags & TEST_BLOCKING))
6453
      fcntl(mysql_socket_getfd(sock), F_SETFL, flags);
unknown's avatar
unknown committed
6454
#endif
6455
    if (mysql_socket_getfd(new_sock) == INVALID_SOCKET)
unknown's avatar
unknown committed
6456
    {
unknown's avatar
unknown committed
6457 6458 6459 6460 6461 6462
      /*
        accept(2) failed on the listening port, after many retries.
        There is not much details to report about the client,
        increment the server global status variable.
      */
      statistic_increment(connection_errors_accept, &LOCK_status);
unknown's avatar
unknown committed
6463 6464
      if ((error_count++ & 255) == 0)		// This can happen often
	sql_perror("Error in accept");
unknown's avatar
unknown committed
6465
      MAYBE_BROKEN_SYSCALL;
unknown's avatar
unknown committed
6466
      if (socket_errno == SOCKET_ENFILE || socket_errno == SOCKET_EMFILE)
unknown's avatar
unknown committed
6467 6468 6469
	sleep(1);				// Give other threads some time
      continue;
    }
6470
#ifdef FD_CLOEXEC
6471
    (void) fcntl(mysql_socket_getfd(new_sock), F_SETFD, FD_CLOEXEC);
6472
#endif
unknown's avatar
unknown committed
6473 6474 6475

#ifdef HAVE_LIBWRAP
    {
6476 6477
      if (mysql_socket_getfd(sock) == mysql_socket_getfd(base_ip_sock) ||
          mysql_socket_getfd(sock) == mysql_socket_getfd(extra_ip_sock))
unknown's avatar
unknown committed
6478 6479 6480
      {
	struct request_info req;
	signal(SIGCHLD, SIG_DFL);
6481 6482
	request_init(&req, RQ_DAEMON, libwrapName, RQ_FILE,
                     mysql_socket_getfd(new_sock), NULL);
6483 6484
	my_fromhost(&req);
	if (!my_hosts_access(&req))
unknown's avatar
unknown committed
6485
	{
unknown's avatar
unknown committed
6486 6487 6488 6489 6490
	  /*
	    This may be stupid but refuse() includes an exit(0)
	    which we surely don't want...
	    clean_exit() - same stupid thing ...
	  */
6491
	  syslog(deny_severity, "refused connect from %s",
6492
		 my_eval_client(&req));
unknown's avatar
unknown committed
6493

unknown's avatar
unknown committed
6494 6495 6496 6497 6498 6499
	  /*
	    C++ sucks (the gibberish in front just translates the supplied
	    sink function pointer in the req structure from a void (*sink)();
	    to a void(*sink)(int) if you omit the cast, the C++ compiler
	    will cry...
	  */
unknown's avatar
unknown committed
6500 6501 6502
	  if (req.sink)
	    ((void (*)(int))req.sink)(req.fd);

6503
	  (void) mysql_socket_shutdown(new_sock, SHUT_RDWR);
6504
	  (void) mysql_socket_close(new_sock);
unknown's avatar
unknown committed
6505 6506
          /*
            The connection was refused by TCP wrappers.
6507 6508
            There are no details (by client IP) available to update the
            host_cache.
unknown's avatar
unknown committed
6509
          */
6510
          statistic_increment(connection_errors_tcpwrap, &LOCK_status);
unknown's avatar
unknown committed
6511 6512 6513 6514 6515 6516 6517 6518 6519 6520
	  continue;
	}
      }
    }
#endif /* HAVE_LIBWRAP */

    /*
    ** Don't allow too many connections
    */

6521
    DBUG_PRINT("info", ("Creating THD for new connection"));
unknown's avatar
unknown committed
6522 6523
    if (!(thd= new THD))
    {
6524
      (void) mysql_socket_shutdown(new_sock, SHUT_RDWR);
6525
      (void) mysql_socket_close(new_sock);
unknown's avatar
unknown committed
6526
      statistic_increment(connection_errors_internal, &LOCK_status);
unknown's avatar
unknown committed
6527 6528
      continue;
    }
6529 6530
    /* Set to get io buffers to be part of THD */
    set_current_thd(thd);
Sergei Golubchik's avatar
Sergei Golubchik committed
6531

6532 6533 6534 6535 6536 6537 6538
    is_unix_sock= (mysql_socket_getfd(sock) ==
                   mysql_socket_getfd(unix_sock));

    if (!(vio_tmp=
          mysql_socket_vio_new(new_sock,
                               is_unix_sock ? VIO_TYPE_SOCKET : VIO_TYPE_TCPIP,
                               is_unix_sock ? VIO_LOCALHOST: 0)) ||
6539
	my_net_init(&thd->net, vio_tmp, MYF(MY_THREAD_SPECIFIC)))
unknown's avatar
unknown committed
6540
    {
6541 6542 6543 6544 6545 6546 6547
      /*
        Only delete the temporary vio if we didn't already attach it to the
        NET object. The destructor in THD will delete any initialized net
        structure.
      */
      if (vio_tmp && thd->net.vio != vio_tmp)
        vio_delete(vio_tmp);
unknown's avatar
unknown committed
6548 6549
      else
      {
6550
	(void) mysql_socket_shutdown(new_sock, SHUT_RDWR);
6551
	(void) mysql_socket_close(new_sock);
unknown's avatar
unknown committed
6552 6553
      }
      delete thd;
unknown's avatar
unknown committed
6554
      statistic_increment(connection_errors_internal, &LOCK_status);
unknown's avatar
unknown committed
6555 6556
      continue;
    }
Sergei Golubchik's avatar
Sergei Golubchik committed
6557 6558

    init_net_server_extension(thd);
6559
    if (is_unix_sock)
6560
      thd->security_ctx->host=(char*) my_localhost;
6561

6562
    if (mysql_socket_getfd(sock) == mysql_socket_getfd(extra_ip_sock))
6563 6564
    {
      thd->extra_port= 1;
Sergei Golubchik's avatar
Sergei Golubchik committed
6565
      thd->scheduler= extra_thread_scheduler;
6566
    }
unknown's avatar
unknown committed
6567
    create_new_thread(thd);
6568
    set_current_thd(0);
unknown's avatar
unknown committed
6569
  }
6570 6571 6572
  DBUG_VOID_RETURN;
}

unknown's avatar
unknown committed
6573

6574 6575 6576 6577 6578
#ifdef _WIN32
pthread_handler_t handle_connections_sockets_thread(void *arg)
{
  my_thread_init();
  handle_connections_sockets();
6579
  decrement_handler_count();
6580
  return 0;
unknown's avatar
unknown committed
6581 6582
}

6583
pthread_handler_t handle_connections_namedpipes(void *arg)
unknown's avatar
unknown committed
6584 6585
{
  HANDLE hConnectedPipe;
6586
  OVERLAPPED connectOverlapped= {0};
unknown's avatar
unknown committed
6587 6588 6589
  THD *thd;
  my_thread_init();
  DBUG_ENTER("handle_connections_namedpipes");
6590 6591 6592 6593 6594 6595
  connectOverlapped.hEvent= CreateEvent(NULL, TRUE, FALSE, NULL);
  if (!connectOverlapped.hEvent)
  {
    sql_print_error("Can't create event, last error=%u", GetLastError());
    unireg_abort(1);
  }
unknown's avatar
unknown committed
6596 6597 6598 6599
  DBUG_PRINT("general",("Waiting for named pipe connections."));
  while (!abort_loop)
  {
    /* wait for named pipe connection */
6600 6601 6602 6603 6604 6605 6606 6607 6608 6609
    BOOL fConnected= ConnectNamedPipe(hPipe, &connectOverlapped);
    if (!fConnected && (GetLastError() == ERROR_IO_PENDING))
    {
        /*
          ERROR_IO_PENDING says async IO has started but not yet finished.
          GetOverlappedResult will wait for completion.
        */
        DWORD bytes;
        fConnected= GetOverlappedResult(hPipe, &connectOverlapped,&bytes, TRUE);
    }
unknown's avatar
unknown committed
6610 6611
    if (abort_loop)
      break;
unknown's avatar
unknown committed
6612
    if (!fConnected)
unknown's avatar
unknown committed
6613
      fConnected = GetLastError() == ERROR_PIPE_CONNECTED;
unknown's avatar
unknown committed
6614
    if (!fConnected)
unknown's avatar
unknown committed
6615
    {
unknown's avatar
Merge  
unknown committed
6616 6617
      CloseHandle(hPipe);
      if ((hPipe= CreateNamedPipe(pipe_name,
6618 6619
                                  PIPE_ACCESS_DUPLEX |
                                  FILE_FLAG_OVERLAPPED,
unknown's avatar
Merge  
unknown committed
6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630
                                  PIPE_TYPE_BYTE |
                                  PIPE_READMODE_BYTE |
                                  PIPE_WAIT,
                                  PIPE_UNLIMITED_INSTANCES,
                                  (int) global_system_variables.
                                  net_buffer_length,
                                  (int) global_system_variables.
                                  net_buffer_length,
                                  NMPWAIT_USE_DEFAULT_WAIT,
                                  &saPipeSecurity)) ==
	  INVALID_HANDLE_VALUE)
unknown's avatar
unknown committed
6631 6632 6633 6634 6635 6636 6637
      {
	sql_perror("Can't create new named pipe!");
	break;					// Abort
      }
    }
    hConnectedPipe = hPipe;
    /* create new pipe for new connection */
6638
    if ((hPipe = CreateNamedPipe(pipe_name,
6639 6640
                 PIPE_ACCESS_DUPLEX |
                 FILE_FLAG_OVERLAPPED,
unknown's avatar
unknown committed
6641 6642 6643 6644
				 PIPE_TYPE_BYTE |
				 PIPE_READMODE_BYTE |
				 PIPE_WAIT,
				 PIPE_UNLIMITED_INSTANCES,
6645 6646
				 (int) global_system_variables.net_buffer_length,
				 (int) global_system_variables.net_buffer_length,
unknown's avatar
unknown committed
6647 6648 6649 6650 6651 6652 6653 6654 6655
				 NMPWAIT_USE_DEFAULT_WAIT,
				 &saPipeSecurity)) ==
	INVALID_HANDLE_VALUE)
    {
      sql_perror("Can't create new named pipe!");
      hPipe=hConnectedPipe;
      continue;					// We have to try again
    }

unknown's avatar
unknown committed
6656
    if (!(thd = new THD))
unknown's avatar
unknown committed
6657
    {
unknown's avatar
Merge  
unknown committed
6658 6659
      DisconnectNamedPipe(hConnectedPipe);
      CloseHandle(hConnectedPipe);
unknown's avatar
unknown committed
6660 6661
      continue;
    }
6662
    set_current_thd(thd);
6663
    if (!(thd->net.vio= vio_new_win32pipe(hConnectedPipe)) ||
6664
	my_net_init(&thd->net, thd->net.vio, MYF(MY_THREAD_SPECIFIC)))
unknown's avatar
unknown committed
6665
    {
6666
      close_connection(thd, ER_OUT_OF_RESOURCES);
unknown's avatar
unknown committed
6667 6668 6669
      delete thd;
      continue;
    }
6670 6671
    /* Host is unknown */
    thd->security_ctx->host= my_strdup(my_localhost, MYF(0));
unknown's avatar
unknown committed
6672
    create_new_thread(thd);
6673
    set_current_thd(0);
unknown's avatar
unknown committed
6674
  }
6675
  CloseHandle(connectOverlapped.hEvent);
6676
  DBUG_LEAVE;
6677
  decrement_handler_count();
6678
  return 0;
unknown's avatar
unknown committed
6679
}
Vladislav Vaintroub's avatar
Vladislav Vaintroub committed
6680
#endif /* _WIN32 */
unknown's avatar
unknown committed
6681

6682

unknown's avatar
unknown committed
6683
#ifdef HAVE_SMEM
6684

unknown's avatar
unknown committed
6685 6686
/**
  Thread of shared memory's service.
6687

unknown's avatar
unknown committed
6688 6689
  @param arg                              Arguments of thread
*/
6690
pthread_handler_t handle_connections_shared_memory(void *arg)
6691
{
6692 6693
  /* file-mapping object, use for create shared memory */
  HANDLE handle_connect_file_map= 0;
6694
  char  *handle_connect_map= 0;                 // pointer on shared memory
6695 6696 6697
  HANDLE event_connect_answer= 0;
  ulong smem_buffer_length= shared_memory_buffer_length + 4;
  ulong connect_number= 1;
6698
  char *tmp= NULL;
6699 6700
  char *suffix_pos;
  char connect_number_char[22], *p;
6701
  const char *errmsg= 0;
6702
  SECURITY_ATTRIBUTES *sa_event= 0, *sa_mapping= 0;
6703 6704 6705 6706
  my_thread_init();
  DBUG_ENTER("handle_connections_shared_memorys");
  DBUG_PRINT("general",("Waiting for allocated shared memory."));

6707 6708 6709 6710 6711 6712
  /*
     get enough space base-name + '_' + longest suffix we might ever send
   */
  if (!(tmp= (char *)my_malloc(strlen(shared_memory_base_name) + 32L, MYF(MY_FAE))))
    goto error;

6713 6714 6715 6716 6717 6718 6719 6720
  if (my_security_attr_create(&sa_event, &errmsg,
                              GENERIC_ALL, SYNCHRONIZE | EVENT_MODIFY_STATE))
    goto error;

  if (my_security_attr_create(&sa_mapping, &errmsg,
                             GENERIC_ALL, FILE_MAP_READ | FILE_MAP_WRITE))
    goto error;

6721 6722 6723 6724 6725 6726 6727
  /*
    The name of event and file-mapping events create agree next rule:
      shared_memory_base_name+unique_part
    Where:
      shared_memory_base_name is unique value for each server
      unique_part is unique value for each object (events and file-mapping)
  */
6728
  suffix_pos= strxmov(tmp,shared_memory_base_name,"_",NullS);
6729
  strmov(suffix_pos, "CONNECT_REQUEST");
6730 6731
  if ((smem_event_connect_request= CreateEvent(sa_event,
                                               FALSE, FALSE, tmp)) == 0)
6732
  {
6733
    errmsg= "Could not create request event";
6734 6735
    goto error;
  }
6736
  strmov(suffix_pos, "CONNECT_ANSWER");
6737
  if ((event_connect_answer= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
6738
  {
6739
    errmsg="Could not create answer event";
6740 6741
    goto error;
  }
6742
  strmov(suffix_pos, "CONNECT_DATA");
6743 6744 6745
  if ((handle_connect_file_map=
       CreateFileMapping(INVALID_HANDLE_VALUE, sa_mapping,
                         PAGE_READWRITE, 0, sizeof(connect_number), tmp)) == 0)
6746
  {
6747
    errmsg= "Could not create file mapping";
6748 6749
    goto error;
  }
6750 6751 6752
  if ((handle_connect_map= (char *)MapViewOfFile(handle_connect_file_map,
						  FILE_MAP_WRITE,0,0,
						  sizeof(DWORD))) == 0)
6753
  {
6754
    errmsg= "Could not create shared memory service";
6755 6756 6757 6758 6759
    goto error;
  }

  while (!abort_loop)
  {
6760
    /* Wait a request from client */
6761
    WaitForSingleObject(smem_event_connect_request,INFINITE);
6762

unknown's avatar
unknown committed
6763 6764 6765
    /*
       it can be after shutdown command
    */
unknown's avatar
Merge  
unknown committed
6766
    if (abort_loop)
unknown's avatar
unknown committed
6767
      goto error;
6768

6769 6770 6771 6772 6773 6774
    HANDLE handle_client_file_map= 0;
    char  *handle_client_map= 0;
    HANDLE event_client_wrote= 0;
    HANDLE event_client_read= 0;    // for transfer data server <-> client
    HANDLE event_server_wrote= 0;
    HANDLE event_server_read= 0;
unknown's avatar
unknown committed
6775
    HANDLE event_conn_closed= 0;
6776
    THD *thd= 0;
6777

6778
    p= int10_to_str(connect_number, connect_number_char, 10);
6779 6780 6781 6782 6783 6784 6785 6786 6787 6788
    /*
      The name of event and file-mapping events create agree next rule:
        shared_memory_base_name+unique_part+number_of_connection
        Where:
	  shared_memory_base_name is uniquel value for each server
	  unique_part is unique value for each object (events and file-mapping)
	  number_of_connection is connection-number between server and client
    */
    suffix_pos= strxmov(tmp,shared_memory_base_name,"_",connect_number_char,
			 "_",NullS);
6789
    strmov(suffix_pos, "DATA");
6790 6791 6792
    if ((handle_client_file_map=
         CreateFileMapping(INVALID_HANDLE_VALUE, sa_mapping,
                           PAGE_READWRITE, 0, smem_buffer_length, tmp)) == 0)
6793
    {
6794
      errmsg= "Could not create file mapping";
6795 6796
      goto errorconn;
    }
6797 6798 6799
    if ((handle_client_map= (char*)MapViewOfFile(handle_client_file_map,
						  FILE_MAP_WRITE,0,0,
						  smem_buffer_length)) == 0)
6800
    {
6801
      errmsg= "Could not create memory map";
6802 6803 6804
      goto errorconn;
    }
    strmov(suffix_pos, "CLIENT_WROTE");
6805
    if ((event_client_wrote= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
6806
    {
6807
      errmsg= "Could not create client write event";
6808 6809 6810
      goto errorconn;
    }
    strmov(suffix_pos, "CLIENT_READ");
6811
    if ((event_client_read= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
6812
    {
6813
      errmsg= "Could not create client read event";
6814 6815 6816
      goto errorconn;
    }
    strmov(suffix_pos, "SERVER_READ");
6817
    if ((event_server_read= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
6818
    {
6819
      errmsg= "Could not create server read event";
6820 6821 6822
      goto errorconn;
    }
    strmov(suffix_pos, "SERVER_WROTE");
6823 6824
    if ((event_server_wrote= CreateEvent(sa_event,
                                         FALSE, FALSE, tmp)) == 0)
6825
    {
6826
      errmsg= "Could not create server write event";
6827 6828
      goto errorconn;
    }
unknown's avatar
unknown committed
6829
    strmov(suffix_pos, "CONNECTION_CLOSED");
6830 6831
    if ((event_conn_closed= CreateEvent(sa_event,
                                        TRUE, FALSE, tmp)) == 0)
unknown's avatar
unknown committed
6832 6833 6834 6835
    {
      errmsg= "Could not create closed connection event";
      goto errorconn;
    }
6836
    if (abort_loop)
6837
      goto errorconn;
6838 6839 6840
    if (!(thd= new THD))
      goto errorconn;
    /* Send number of connection to client */
6841
    int4store(handle_connect_map, connect_number);
6842
    if (!SetEvent(event_connect_answer))
6843
    {
6844
      errmsg= "Could not send answer event";
6845 6846
      goto errorconn;
    }
6847
    /* Set event that client should receive data */
6848 6849
    if (!SetEvent(event_client_read))
    {
6850
      errmsg= "Could not set client to read mode";
6851 6852
      goto errorconn;
    }
6853
    set_current_thd(thd);
6854
    if (!(thd->net.vio= vio_new_win32shared_memory(handle_client_file_map,
unknown's avatar
unknown committed
6855 6856 6857 6858 6859
                                                   handle_client_map,
                                                   event_client_wrote,
                                                   event_client_read,
                                                   event_server_wrote,
                                                   event_server_read,
unknown's avatar
unknown committed
6860
                                                   event_conn_closed)) ||
6861
        my_net_init(&thd->net, thd->net.vio, MYF(MY_THREAD_SPECIFIC)))
6862
    {
6863
      close_connection(thd, ER_OUT_OF_RESOURCES);
6864 6865
      errmsg= 0;
      goto errorconn;
6866
    }
6867
    thd->security_ctx->host= my_strdup(my_localhost, MYF(0)); /* Host is unknown */
6868
    create_new_thread(thd);
6869
    connect_number++;
6870
    set_current_thd(thd);
6871 6872 6873 6874 6875 6876 6877 6878 6879 6880 6881
    continue;

errorconn:
    /* Could not form connection;  Free used handlers/memort and retry */
    if (errmsg)
    {
      char buff[180];
      strxmov(buff, "Can't create shared memory connection: ", errmsg, ".",
	      NullS);
      sql_perror(buff);
    }
6882
    if (handle_client_file_map)
unknown's avatar
unknown committed
6883 6884 6885 6886 6887 6888 6889 6890 6891 6892 6893 6894 6895
      CloseHandle(handle_client_file_map);
    if (handle_client_map)
      UnmapViewOfFile(handle_client_map);
    if (event_server_wrote)
      CloseHandle(event_server_wrote);
    if (event_server_read)
      CloseHandle(event_server_read);
    if (event_client_wrote)
      CloseHandle(event_client_wrote);
    if (event_client_read)
      CloseHandle(event_client_read);
    if (event_conn_closed)
      CloseHandle(event_conn_closed);
6896
    delete thd;
6897
  }
6898
  set_current_thd(0);
6899 6900

  /* End shared memory handling */
6901
error:
6902
  if (tmp)
6903
    my_free(tmp);
6904

6905 6906 6907 6908 6909 6910
  if (errmsg)
  {
    char buff[180];
    strxmov(buff, "Can't create shared memory service: ", errmsg, ".", NullS);
    sql_perror(buff);
  }
6911 6912
  my_security_attr_free(sa_event);
  my_security_attr_free(sa_mapping);
6913 6914 6915
  if (handle_connect_map)	UnmapViewOfFile(handle_connect_map);
  if (handle_connect_file_map)	CloseHandle(handle_connect_file_map);
  if (event_connect_answer)	CloseHandle(event_connect_answer);
6916
  if (smem_event_connect_request) CloseHandle(smem_event_connect_request);
6917
  DBUG_LEAVE;
6918
  decrement_handler_count();
6919
  return 0;
6920 6921
}
#endif /* HAVE_SMEM */
6922
#endif /* EMBEDDED_LIBRARY */
unknown's avatar
unknown committed
6923

6924 6925 6926

/****************************************************************************
  Handle start options
unknown's avatar
unknown committed
6927 6928
******************************************************************************/

6929 6930 6931 6932 6933 6934 6935 6936 6937 6938 6939 6940 6941 6942 6943 6944 6945 6946 6947 6948 6949 6950 6951 6952 6953 6954 6955 6956 6957 6958 6959 6960 6961 6962 6963 6964 6965 6966 6967 6968 6969 6970 6971 6972 6973

/**
  Process command line options flagged as 'early'.
  Some components needs to be initialized as early as possible,
  because the rest of the server initialization depends on them.
  Options that needs to be parsed early includes:
  - the performance schema, when compiled in,
  - options related to the help,
  - options related to the bootstrap
  The performance schema needs to be initialized as early as possible,
  before to-be-instrumented objects of the server are initialized.
*/

int handle_early_options()
{
  int ho_error;
  DYNAMIC_ARRAY all_early_options;

  my_getopt_register_get_addr(NULL);
  /* Skip unknown options so that they may be processed later */
  my_getopt_skip_unknown= TRUE;

  /* prepare all_early_options array */
  my_init_dynamic_array(&all_early_options, sizeof(my_option), 100, 25, MYF(0));
  add_many_options(&all_early_options, pfs_early_options,
                  array_elements(pfs_early_options));
  sys_var_add_options(&all_early_options, sys_var::PARSE_EARLY);
  add_terminator(&all_early_options);

  ho_error= handle_options(&remaining_argc, &remaining_argv,
                           (my_option*)(all_early_options.buffer),
                           mysqld_get_one_option);
  if (ho_error == 0)
  {
    /* Add back the program name handle_options removes */
    remaining_argc++;
    remaining_argv--;
  }

  delete_dynamic(&all_early_options);

  return ho_error;
}


6974 6975 6976 6977 6978 6979 6980 6981 6982 6983 6984 6985 6986
#define MYSQL_COMPATIBILITY_OPTION(option) \
  { option, OPT_MYSQL_COMPATIBILITY, \
   0, 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0 }

#define MYSQL_TO_BE_IMPLEMENTED_OPTION(option) \
  { option, OPT_MYSQL_TO_BE_IMPLEMENTED, \
   0, 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0 }

#define MYSQL_SUGGEST_ANALOG_OPTION(option, str) \
  { option, OPT_MYSQL_COMPATIBILITY, \
   0, 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0 }


6987 6988 6989 6990 6991
/**
  System variables are automatically command-line options (few
  exceptions are documented in sys_var.h), so don't need
  to be listed here.
*/
6992

Marc Alff's avatar
Marc Alff committed
6993
struct my_option my_long_options[]=
6994
{
unknown's avatar
unknown committed
6995
  {"help", '?', "Display this help and exit.", 
6996
   &opt_help, &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
unknown's avatar
unknown committed
6997
   0, 0},
6998
  {"allow-suspicious-udfs", 0,
unknown's avatar
unknown committed
6999 7000
   "Allows use of UDFs consisting of only one symbol xxx() "
   "without corresponding xxx_init() or xxx_deinit(). That also means "
7001 7002
   "that one can load any function from any library, for example exit() "
   "from libc.so",
7003
   &opt_allow_suspicious_udfs, &opt_allow_suspicious_udfs,
7004
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7005 7006
  {"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax. This mode "
   "will also set transaction isolation level 'serializable'.", 0, 0, 0,
unknown's avatar
unknown committed
7007
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
7008 7009 7010 7011
  /*
    Because Sys_var_bit does not support command-line options, we need to
    explicitely add one for --autocommit
  */
7012 7013 7014
  {"autocommit", 0, "Set default value for autocommit (0 or 1)",
   &opt_autocommit, &opt_autocommit, 0,
   GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, NULL},
7015
  {"bind-address", 0, "IP address to bind to.",
7016
   &my_bind_addr_str, &my_bind_addr_str, 0, GET_STR,
unknown's avatar
unknown committed
7017
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7018
  {"binlog-do-db", OPT_BINLOG_DO_DB,
7019 7020
   "Tells the master it should log updates for the specified database, "
   "and exclude all others not explicitly mentioned.",
7021
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
7022
  {"binlog-ignore-db", OPT_BINLOG_IGNORE_DB,
Staale Smedseng's avatar
Staale Smedseng committed
7023
   "Tells the master that updates to the given database should not be logged to the binary log.",
7024
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7025
  {"binlog-row-event-max-size", 0,
7026 7027 7028
   "The maximum size of a row-based binary log event in bytes. Rows will be "
   "grouped into events smaller than this size if possible. "
   "The value has to be a multiple of 256.",
7029 7030
   &opt_binlog_rows_event_max_size, &opt_binlog_rows_event_max_size,
   0, GET_ULONG, REQUIRED_ARG,
7031 7032 7033 7034
   /* def_value */ 1024, /* min_value */  256, /* max_value */ ULONG_MAX, 
   /* sub_size */     0, /* block_size */ 256, 
   /* app_type */ 0
  },
7035
#ifndef DISABLE_GRANT_OPTIONS
7036
  {"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts.", 0, 0, 0,
7037
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
7038
#endif
7039
  {"character-set-client-handshake", 0,
unknown's avatar
unknown committed
7040
   "Don't ignore client side character set value sent during handshake.",
7041 7042
   &opt_character_set_client_handshake,
   &opt_character_set_client_handshake,
7043
    0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
7044
  {"character-set-filesystem", 0,
unknown's avatar
unknown committed
7045
   "Set the filesystem character set.",
7046 7047
   &character_set_filesystem_name,
   &character_set_filesystem_name,
unknown's avatar
unknown committed
7048
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
unknown's avatar
unknown committed
7049
  {"character-set-server", 'C', "Set the default character set.",
7050
   &default_character_set_name, &default_character_set_name,
unknown's avatar
unknown committed
7051
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
unknown's avatar
unknown committed
7052
  {"chroot", 'r', "Chroot mysqld daemon during startup.",
7053
   &mysqld_chroot, &mysqld_chroot, 0, GET_STR, REQUIRED_ARG,
unknown's avatar
unknown committed
7054
   0, 0, 0, 0, 0, 0},
7055
  {"collation-server", 0, "Set the default collation.",
7056
   &default_collation_name, &default_collation_name,
unknown's avatar
unknown committed
7057
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
Staale Smedseng's avatar
Staale Smedseng committed
7058
  {"console", OPT_CONSOLE, "Write error output on screen; don't remove the console window on windows.",
7059
   &opt_console, &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0,
7060
   0, 0, 0},
7061
  {"core-file", OPT_WANT_CORE, "Write core on errors.", 0, 0, 0, GET_NO_ARG,
7062
   NO_ARG, 0, 0, 0, 0, 0, 0},
Michael Widenius's avatar
Michael Widenius committed
7063 7064 7065 7066 7067 7068 7069 7070 7071 7072 7073 7074 7075 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088 7089 7090 7091 7092 7093 7094 7095 7096 7097 7098 7099 7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 7110
#ifdef DBUG_OFF
  {"debug", '#', "Built in DBUG debugger. Disabled in this build.",
   &current_dbug_option, &current_dbug_option, 0, GET_STR, OPT_ARG,
   0, 0, 0, 0, 0, 0},
#endif
#ifdef HAVE_REPLICATION
  {"debug-abort-slave-event-count", 0,
   "Option used by mysql-test for debugging and testing of replication.",
   &abort_slave_event_count,  &abort_slave_event_count,
   0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif /* HAVE_REPLICATION */
#ifndef DBUG_OFF
  {"debug-assert-on-error", 0,
   "Do an assert in various functions if we get a fatal error",
   &my_assert_on_error, &my_assert_on_error,
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
  {"debug-assert-if-crashed-table", 0,
   "Do an assert in handler::print_error() if we get a crashed table",
   &debug_assert_if_crashed_table, &debug_assert_if_crashed_table,
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
#ifdef HAVE_REPLICATION
  {"debug-disconnect-slave-event-count", 0,
   "Option used by mysql-test for debugging and testing of replication.",
   &disconnect_slave_event_count, &disconnect_slave_event_count,
   0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif /* HAVE_REPLICATION */
  {"debug-exit-info", 'T', "Used for debugging. Use at your own risk.",
   0, 0, 0, GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
  {"debug-gdb", 0,
   "Set up signals usable for debugging.",
   &opt_debugging, &opt_debugging,
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_REPLICATION
  {"debug-max-binlog-dump-events", 0,
   "Option used by mysql-test for debugging and testing of replication.",
   &max_binlog_dump_events, &max_binlog_dump_events, 0,
   GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif /* HAVE_REPLICATION */
#ifdef SAFE_MUTEX
  {"debug-mutex-deadlock-detector", 0,
   "Enable checking of wrong mutex usage.",
   &safe_mutex_deadlock_detector,
   &safe_mutex_deadlock_detector,
   0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
#endif
  {"debug-no-sync", 0,
   "Disables system sync calls. Only for running tests or debugging!",
7111
   &my_disable_sync, &my_disable_sync, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
Michael Widenius's avatar
Michael Widenius committed
7112 7113 7114 7115 7116 7117 7118
#ifdef HAVE_REPLICATION
  {"debug-sporadic-binlog-dump-fail", 0,
   "Option used by mysql-test for debugging and testing of replication.",
   &opt_sporadic_binlog_dump_fail,
   &opt_sporadic_binlog_dump_fail, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
   0},
#endif /* HAVE_REPLICATION */
7119 7120 7121
  /* default-storage-engine should have "MyISAM" as def_value. Instead
     of initializing it here it is done in init_common_variables() due
     to a compiler bug in Sun Studio compiler. */
7122
  {"default-storage-engine", 0, "The default storage engine for new tables",
7123
   &default_storage_engine, 0, 0, GET_STR, REQUIRED_ARG,
7124
   0, 0, 0, 0, 0, 0 },
7125 7126 7127 7128
  {"default-tmp-storage-engine", 0,
    "The default storage engine for user-created temporary tables",
   &default_tmp_storage_engine, 0, 0, GET_STR, REQUIRED_ARG,
   0, 0, 0, 0, 0, 0 },
7129
  {"default-time-zone", 0, "Set the default time zone.",
7130
   &default_tz_name, &default_tz_name,
7131
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
Michael Widenius's avatar
Michael Widenius committed
7132 7133 7134 7135 7136 7137 7138 7139
#if defined(ENABLED_DEBUG_SYNC)
  {"debug-sync-timeout", OPT_DEBUG_SYNC_TIMEOUT,
   "Enable the debug sync facility "
   "and optionally specify a default wait timeout in seconds. "
   "A zero value keeps the facility disabled.",
   &opt_debug_sync_timeout, 0,
   0, GET_UINT, OPT_ARG, 0, 0, UINT_MAX, 0, 0, 0},
#endif /* defined(ENABLED_DEBUG_SYNC) */
unknown's avatar
unknown committed
7140
#ifdef HAVE_OPENSSL
7141
  {"des-key-file", 0,
unknown's avatar
unknown committed
7142
   "Load keys for des_encrypt() and des_encrypt from given file.",
7143
   &des_key_file, &des_key_file, 0, GET_STR, REQUIRED_ARG,
unknown's avatar
unknown committed
7144 7145
   0, 0, 0, 0, 0, 0},
#endif /* HAVE_OPENSSL */
Michael Widenius's avatar
Michael Widenius committed
7146
#ifdef HAVE_STACKTRACE
Sergei Golubchik's avatar
Sergei Golubchik committed
7147
  {"stack-trace", 0 , "Print a symbolic stack trace on failure",
Michael Widenius's avatar
Michael Widenius committed
7148 7149
   &opt_stack_trace, &opt_stack_trace, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
#endif /* HAVE_STACKTRACE */
7150 7151 7152 7153
  {"external-locking", 0, "Use system (external) locking (disabled by "
   "default).  With this option enabled you can run myisamchk to test "
   "(not repair) tables while the MySQL server is running. Disable with "
   "--skip-external-locking.", &opt_external_locking, &opt_external_locking,
unknown's avatar
unknown committed
7154
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7155 7156
  /* We must always support the next option to make scripts like mysqltest
     easier to do */
7157
  {"gdb", 0,
Sergei Golubchik's avatar
Sergei Golubchik committed
7158 7159 7160
   "Set up signals usable for debugging. Deprecated, use --debug-gdb instead.",
   &opt_debugging, &opt_debugging,
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7161
#ifdef HAVE_LARGE_PAGE_OPTION
7162
  {"super-large-pages", 0, "Enable support for super large pages.",
7163
   &opt_super_large_pages, &opt_super_large_pages, 0,
7164
   GET_BOOL, OPT_ARG, 0, 0, 1, 0, 1, 0},
unknown's avatar
Merge  
unknown committed
7165
#endif
7166
  {"language", 'L',
7167 7168
   "Client error messages in given language. May be given as a full path. "
   "Deprecated. Use --lc-messages-dir instead.",
7169
   0, 0, 0,
7170
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7171
  {"lc-messages", 0,
7172
   "Set the language used for the error messages.",
7173
   &lc_messages, &lc_messages, 0, GET_STR, REQUIRED_ARG,
7174
   0, 0, 0, 0, 0, 0 },
7175
  {"lc-time-names", 0,
7176
   "Set the language used for the month names and the days of the week.",
7177
   &lc_time_names_name, &lc_time_names_name,
7178
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
7179 7180 7181
  {"log-basename", OPT_LOG_BASENAME,
   "Basename for all log files and the .pid file. This sets all log file "
   "names at once (in 'datadir') and is normally the only option you need "
Sergei Golubchik's avatar
Sergei Golubchik committed
7182
   "for specifying log files. Sets names for --log-bin, --log-bin-index, "
7183
   "--relay-log, --relay-log-index, --general-log-file, "
Sergei Golubchik's avatar
Sergei Golubchik committed
7184
   "--log-slow-query-log-file, --log-error-file, and --pid-file",
7185 7186
   &opt_log_basename, &opt_log_basename, 0, GET_STR, REQUIRED_ARG,
   0, 0, 0, 0, 0, 0},
7187
  {"log-bin", OPT_BIN_LOG,
7188 7189
   "Log update queries in binary format. Optional argument should be name for "
   "binary log. If not given "
7190
   "'datadir'/'log-basename'-bin or 'datadir'/mysql-bin will be used (the later if "
Sergei Golubchik's avatar
Sergei Golubchik committed
7191
   "--log-basename is not specified). We strongly recommend to use either "
7192
   "--log-basename or specify a filename to ensure that replication doesn't "
7193
   "stop if the real hostname of the computer changes.",
7194
   &opt_bin_logname, &opt_bin_logname, 0, GET_STR,
unknown's avatar
unknown committed
7195
   OPT_ARG, 0, 0, 0, 0, 0, 0},
7196
  {"log-bin-index", 0,
7197
   "File that holds the names for last binary log files.",
7198
   &opt_binlog_index_name, &opt_binlog_index_name, 0, GET_STR,
7199
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7200
  {"log-isam", OPT_ISAM_LOG, "Log all MyISAM changes to file.",
7201
   &myisam_log_filename, &myisam_log_filename, 0, GET_STR,
7202
   OPT_ARG, 0, 0, 0, 0, 0, 0},
7203
  {"log-short-format", 0,
unknown's avatar
unknown committed
7204
   "Don't log extra information to update and slow-query logs.",
7205
   &opt_short_log_format, &opt_short_log_format,
unknown's avatar
unknown committed
7206
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7207
  {"log-slow-admin-statements", 0,
7208 7209
   "Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements to "
   "the slow log if it is open.", &opt_log_slow_admin_statements,
7210
   &opt_log_slow_admin_statements, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7211
 {"log-slow-slave-statements", 0,
7212
  "Log slow statements executed by slave thread to the slow log if it is open.",
7213
  &opt_log_slow_slave_statements, &opt_log_slow_slave_statements,
7214
  0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7215
  {"log-tc", 0,
unknown's avatar
Merge  
unknown committed
7216
   "Path to transaction coordinator log (used for transactions that affect "
Staale Smedseng's avatar
Staale Smedseng committed
7217
   "more than one storage engine, when binary log is disabled).",
7218
   &opt_tc_log_file, &opt_tc_log_file, 0, GET_STR,
unknown's avatar
Merge  
unknown committed
7219
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7220
  {"master-info-file", 0,
7221
   "The location and name of the file that remembers the master and where "
7222
   "the I/O replication thread is in the master's binlogs. Defaults to "
Sergei Golubchik's avatar
Sergei Golubchik committed
7223
   "master.info",
7224
   &master_info_file, &master_info_file, 0, GET_STR,
unknown's avatar
unknown committed
7225
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7226
  {"master-retry-count", 0,
7227
   "The number of tries the slave will make to connect to the master before giving up.",
7228
   &master_retry_count, &master_retry_count, 0, GET_ULONG,
7229
   REQUIRED_ARG, 3600*24, 0, 0, 0, 0, 0},
unknown's avatar
SCRUM  
unknown committed
7230
#ifdef HAVE_REPLICATION
7231
  {"init-rpl-role", 0, "Set the replication role",
7232
   &rpl_status, &rpl_status, &rpl_role_typelib,
7233
   GET_ENUM, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
SCRUM  
unknown committed
7234
#endif /* HAVE_REPLICATION */
7235
  {"memlock", 0, "Lock mysqld in memory.", &locked_in_memory,
7236
   &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7237
  {"old-style-user-limits", 0,
Staale Smedseng's avatar
Staale Smedseng committed
7238 7239
   "Enable old-style user limits (before 5.0.3, user resources were counted "
   "per each user+host vs. per account).",
7240
   &opt_old_style_user_limits, &opt_old_style_user_limits,
unknown's avatar
Merge  
unknown committed
7241
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7242
  {"port-open-timeout", 0,
7243
   "Maximum time in seconds to wait for the port to become free. "
7244 7245
   "(Default: No wait).", &mysqld_port_timeout, &mysqld_port_timeout, 0,
   GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7246
  {"replicate-do-db", OPT_REPLICATE_DO_DB,
7247 7248 7249 7250 7251 7252 7253
   "Tells the slave thread to restrict replication to the specified database. "
   "To specify more than one database, use the directive multiple times, "
   "once for each database. Note that this will only work if you do not use "
   "cross-database queries such as UPDATE some_db.some_table SET foo='bar' "
   "while having selected a different or no database. If you need cross "
   "database updates to work, make sure you have 3.23.28 or later, and use "
   "replicate-wild-do-table=db_name.%.",
7254
   0, 0, 0, GET_STR | GET_ASK_ADDR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7255
  {"replicate-do-table", OPT_REPLICATE_DO_TABLE,
7256 7257 7258
   "Tells the slave thread to restrict replication to the specified table. "
   "To specify more than one table, use the directive multiple times, once "
   "for each table. This will work for cross-database updates, in contrast "
7259
   "to replicate-do-db.", 0, 0, 0, GET_STR | GET_ASK_ADDR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7260
  {"replicate-ignore-db", OPT_REPLICATE_IGNORE_DB,
7261 7262 7263 7264 7265
   "Tells the slave thread to not replicate to the specified database. To "
   "specify more than one database to ignore, use the directive multiple "
   "times, once for each database. This option will not work if you use "
   "cross database updates. If you need cross database updates to work, "
   "make sure you have 3.23.28 or later, and use replicate-wild-ignore-"
7266
   "table=db_name.%. ", 0, 0, 0, GET_STR | GET_ASK_ADDR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7267
  {"replicate-ignore-table", OPT_REPLICATE_IGNORE_TABLE,
7268 7269 7270
   "Tells the slave thread to not replicate to the specified table. To specify "
   "more than one table to ignore, use the directive multiple times, once for "
   "each table. This will work for cross-database updates, in contrast to "
7271
   "replicate-ignore-db.", 0, 0, 0, GET_STR | GET_ASK_ADDR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7272
  {"replicate-rewrite-db", OPT_REPLICATE_REWRITE_DB,
7273 7274
   "Updates to a database with a different name than the original. Example: "
   "replicate-rewrite-db=master_db_name->slave_db_name.",
7275
   0, 0, 0, GET_STR | GET_ASK_ADDR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
7276
#ifdef HAVE_REPLICATION
7277
  {"replicate-same-server-id", 0,
7278 7279 7280 7281
   "In replication, if set to 1, do not skip events having our server id. "
   "Default value is 0 (to break infinite loops in circular replication). "
   "Can't be set to 1 if --log-slave-updates is used.",
   &replicate_same_server_id, &replicate_same_server_id,
7282
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
7283
#endif
unknown's avatar
unknown committed
7284
  {"replicate-wild-do-table", OPT_REPLICATE_WILD_DO_TABLE,
7285 7286 7287 7288 7289 7290
   "Tells the slave thread to restrict replication to the tables that match "
   "the specified wildcard pattern. To specify more than one table, use the "
   "directive multiple times, once for each table. This will work for cross-"
   "database updates. Example: replicate-wild-do-table=foo%.bar% will "
   "replicate only updates to tables in all databases that start with foo "
   "and whose table names start with bar.",
7291
   0, 0, 0, GET_STR | GET_ASK_ADDR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
7292
  {"replicate-wild-ignore-table", OPT_REPLICATE_WILD_IGNORE_TABLE,
7293 7294 7295 7296 7297 7298
   "Tells the slave thread to not replicate to the tables that match the "
   "given wildcard pattern. To specify more than one table to ignore, use "
   "the directive multiple times, once for each table. This will work for "
   "cross-database updates. Example: replicate-wild-ignore-table=foo%.bar% "
   "will not do updates to tables in databases that start with foo and whose "
   "table names start with bar.",
7299
   0, 0, 0, GET_STR | GET_ASK_ADDR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7300
  {"safe-mode", OPT_SAFE, "Skip some optimize stages (for testing). Deprecated.",
7301
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
7302
  {"safe-user-create", 0,
7303
   "Don't allow new user creation by the user who has no write privileges to the mysql.user table.",
7304
   &opt_safe_user_create, &opt_safe_user_create, 0, GET_BOOL,
7305
   NO_ARG, 0, 0, 0, 0, 0, 0},
7306
  {"show-slave-auth-info", 0,
Staale Smedseng's avatar
Staale Smedseng committed
7307
   "Show user and password in SHOW SLAVE HOSTS on this master.",
7308
   &opt_show_slave_auth_info, &opt_show_slave_auth_info, 0,
7309
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7310 7311 7312
  {"skip-bdb", OPT_DEPRECATED_OPTION,
   "Deprecated option; Exist only for compatiblity with old my.cnf files",
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
7313
#ifndef DISABLE_GRANT_OPTIONS
7314
  {"skip-grant-tables", 0,
Staale Smedseng's avatar
Staale Smedseng committed
7315
   "Start without grant tables. This gives all users FULL ACCESS to all tables.",
7316
   &opt_noacl, &opt_noacl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
7317
   0},
7318
#endif
unknown's avatar
unknown committed
7319 7320
  {"skip-host-cache", OPT_SKIP_HOST_CACHE, "Don't cache host names.", 0, 0, 0,
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
7321
  {"skip-slave-start", 0,
7322 7323
   "If set, slave is not autostarted.", &opt_skip_slave_start,
   &opt_skip_slave_start, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7324 7325 7326 7327 7328 7329 7330 7331 7332 7333 7334 7335 7336 7337
#ifdef HAVE_REPLICATION
  {"slave-parallel-mode", OPT_SLAVE_PARALLEL_MODE,
   "Controls what transactions are applied in parallel when using "
   "--slave-parallel-threads. Syntax: slave_parallel_mode=value[,value...], "
   "where \"value\" could be one or more of: \"domain\", to apply different "
   "replication domains in parallel; \"follow_master_commit\", to apply "
   "in parallel transactions that group-committed together on the master; "
   "\"transactional\", to optimistically try to apply all transactional "
   "DML in parallel; and \"waiting\" to extend \"transactional\" to "
   "even transactions that had to wait on the master.",
   &opt_slave_parallel_mode, &opt_slave_parallel_mode,
   &slave_parallel_mode_typelib, GET_SET | GET_ASK_ADDR, REQUIRED_ARG,
   SLAVE_PARALLEL_DOMAIN | SLAVE_PARALLEL_FOLLOW_MASTER_COMMIT, 0, 0, 0, 0, 0},
#endif
7338 7339 7340 7341 7342 7343 7344
#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
  {"slow-start-timeout", 0,
   "Maximum number of milliseconds that the service control manager should wait "
   "before trying to kill the windows service during startup"
   "(Default: 15000).", &slow_start_timeout, &slow_start_timeout, 0,
   GET_ULONG, REQUIRED_ARG, 15000, 0, 0, 0, 0, 0},
#endif
7345
#ifdef HAVE_OPENSSL
7346
  {"ssl", 0,
7347
   "Enable SSL for connection (automatically enabled if an ssl option is used).",
7348
   &opt_use_ssl, &opt_use_ssl, 0, GET_BOOL, OPT_ARG, 0, 0, 0,
7349
   0, 0, 0},
7350
#endif
unknown's avatar
unknown committed
7351
#ifdef __WIN__
7352
  {"standalone", 0,
unknown's avatar
unknown committed
7353 7354 7355 7356
  "Dummy option to start as a standalone program (NT).", 0, 0, 0, GET_NO_ARG,
   NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
  {"symbolic-links", 's', "Enable symbolic link support.",
7357
   &my_use_symdir, &my_use_symdir, 0, GET_BOOL, NO_ARG,
7358 7359 7360 7361
   /*
     The system call realpath() produces warnings under valgrind and
     purify. These are not suppressed: instead we disable symlinks
     option if compiled with valgrind support.
7362 7363
     Also disable by default on Windows, due to high overhead for checking .sym 
     files.
7364
   */
7365
   IF_VALGRIND(0,IF_WIN(0,1)), 0, 0, 0, 0, 0},
7366
  {"sysdate-is-now", 0,
7367 7368 7369 7370
   "Non-default option to alias SYSDATE() to NOW() to make it safe-replicable. "
   "Since 5.0, SYSDATE() returns a `dynamic' value different for different "
   "invocations, even within the same statement.",
   &global_system_variables.sysdate_is_now,
unknown's avatar
unknown committed
7371
   0, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
7372
  {"tc-heuristic-recover", 0,
7373 7374
   "Decision to use in heuristic recover process",
   &tc_heuristic_recover, &tc_heuristic_recover,
7375 7376
   &tc_heuristic_recover_typelib, GET_ENUM, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
  {"temp-pool", 0,
7377
#if (ENABLE_TEMP_POOL)
7378 7379
   "Using this option will cause most temporary files created to use a small "
   "set of names, rather than a unique name for each new file.",
7380 7381 7382
#else
   "This option is ignored on this OS.",
#endif
7383
   &use_temp_pool, &use_temp_pool, 0, GET_BOOL, NO_ARG, 1,
unknown's avatar
unknown committed
7384
   0, 0, 0, 0, 0},
7385
  {"transaction-isolation", 0,
7386
   "Default transaction isolation level",
7387 7388
   &global_system_variables.tx_isolation,
   &global_system_variables.tx_isolation, &tx_isolation_typelib,
7389
   GET_ENUM, REQUIRED_ARG, ISO_REPEATABLE_READ, 0, 0, 0, 0, 0},
7390 7391 7392 7393 7394 7395
  {"transaction-read-only", 0,
   "Default transaction access mode. "
   "True if transactions are read-only.",
   &global_system_variables.tx_read_only,
   &global_system_variables.tx_read_only, 0,
   GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
7396
  {"user", 'u', "Run mysqld daemon as user.", 0, 0, 0, GET_STR, REQUIRED_ARG,
unknown's avatar
unknown committed
7397
   0, 0, 0, 0, 0, 0},
Staale Smedseng's avatar
Staale Smedseng committed
7398
  {"verbose", 'v', "Used with --help option for detailed help.",
7399
   &opt_verbose, &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
7400
  {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
7401
   NO_ARG, 0, 0, 0, 0, 0, 0},
7402
  {"plugin-load", OPT_PLUGIN_LOAD,
7403 7404 7405
   "Semicolon-separated list of plugins to load, where each plugin is "
   "specified as ether a plugin_name=library_file pair or only a library_file. "
   "If the latter case, all plugins from a given library_file will be loaded.",
7406
   0, 0, 0,
unknown's avatar
unknown committed
7407
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7408 7409
  {"plugin-load-add", OPT_PLUGIN_LOAD_ADD,
   "Optional semicolon-separated list of plugins to load. This option adds "
7410
   "to the list specified by --plugin-load in an incremental way. "
7411 7412 7413
   "It can be specified many times, adding more plugins every time.",
   0, 0, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
7414
  {"table_cache", 0, "Deprecated; use --table-open-cache instead.",
7415
   &tc_size, &tc_size, 0, GET_ULONG,
7416
   REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
Monty's avatar
Monty committed
7417 7418 7419 7420 7421 7422 7423
#ifdef WITH_WSREP
  {"wsrep-new-cluster", 0, "Bootstrap a cluster. It works by overriding the "
   "current value of wsrep_cluster_address. It is recommended not to add this "
   "option to the config file as this will trigger bootstrap on every server "
   "start.", &wsrep_new_cluster, &wsrep_new_cluster, 0, GET_BOOL, NO_ARG,
   0, 0, 0, 0, 0, 0},
#endif
7424 7425 7426 7427

  /* The following options exist in 5.6 but not in 10.0 */
  MYSQL_TO_BE_IMPLEMENTED_OPTION("default-tmp-storage-engine"),
  MYSQL_COMPATIBILITY_OPTION("log-raw"),
7428
  MYSQL_COMPATIBILITY_OPTION("log-bin-use-v1-row-events"),
7429 7430 7431 7432 7433 7434 7435 7436 7437 7438 7439 7440 7441 7442 7443 7444 7445 7446 7447 7448 7449 7450 7451 7452 7453 7454 7455 7456 7457 7458 7459 7460 7461 7462 7463 7464 7465 7466 7467
  MYSQL_TO_BE_IMPLEMENTED_OPTION("default-authentication-plugin"),
  MYSQL_COMPATIBILITY_OPTION("binlog-max-flush-queue-time"),
  MYSQL_TO_BE_IMPLEMENTED_OPTION("binlog-row-image"),
  MYSQL_TO_BE_IMPLEMENTED_OPTION("explicit-defaults-for-timestamp"),
  MYSQL_COMPATIBILITY_OPTION("master-info-repository"),
  MYSQL_COMPATIBILITY_OPTION("relay-log-info-repository"),
  MYSQL_SUGGEST_ANALOG_OPTION("binlog-rows-query-log-events", "--binlog-annotate-row-events"),
  MYSQL_COMPATIBILITY_OPTION("binlog-order-commits"),
  MYSQL_TO_BE_IMPLEMENTED_OPTION("log-throttle-queries-not-using-indexes"),
  MYSQL_TO_BE_IMPLEMENTED_OPTION("end-markers-in-json"),
  MYSQL_TO_BE_IMPLEMENTED_OPTION("optimizer-trace"),              // OPTIMIZER_TRACE
  MYSQL_TO_BE_IMPLEMENTED_OPTION("optimizer-trace-features"),     // OPTIMIZER_TRACE
  MYSQL_TO_BE_IMPLEMENTED_OPTION("optimizer-trace-offset"),       // OPTIMIZER_TRACE
  MYSQL_TO_BE_IMPLEMENTED_OPTION("optimizer-trace-limit"),        // OPTIMIZER_TRACE
  MYSQL_TO_BE_IMPLEMENTED_OPTION("optimizer-trace-max-mem-size"), // OPTIMIZER_TRACE
  MYSQL_TO_BE_IMPLEMENTED_OPTION("eq-range-index-dive-limit"),
  MYSQL_COMPATIBILITY_OPTION("server-id-bits"),
  MYSQL_TO_BE_IMPLEMENTED_OPTION("slave-rows-search-algorithms"), // HAVE_REPLICATION
  MYSQL_COMPATIBILITY_OPTION("table-open-cache-instances"),
  MYSQL_TO_BE_IMPLEMENTED_OPTION("slave-allow-batching"),         // HAVE_REPLICATION
  MYSQL_COMPATIBILITY_OPTION("slave-checkpoint-period"),      // HAVE_REPLICATION
  MYSQL_COMPATIBILITY_OPTION("slave-checkpoint-group"),       // HAVE_REPLICATION
  MYSQL_SUGGEST_ANALOG_OPTION("slave-parallel-workers", "--slave-parallel-threads"),       // HAVE_REPLICATION
  MYSQL_SUGGEST_ANALOG_OPTION("slave-pending-jobs-size-max", "--slave-parallel-max-queued"),  // HAVE_REPLICATION
  MYSQL_TO_BE_IMPLEMENTED_OPTION("disconnect-on-expired-password"),
  MYSQL_TO_BE_IMPLEMENTED_OPTION("sha256-password-private-key-path"), // HAVE_OPENSSL && !HAVE_YASSL
  MYSQL_TO_BE_IMPLEMENTED_OPTION("sha256-password-public-key-path"),  // HAVE_OPENSSL && !HAVE_YASSL

  /* The following options exist in 5.5 and 5.6 but not in 10.0 */
  MYSQL_SUGGEST_ANALOG_OPTION("abort-slave-event-count", "--debug-abort-slave-event-count"),
  MYSQL_SUGGEST_ANALOG_OPTION("disconnect-slave-event-count", "--debug-disconnect-slave-event-count"),
  MYSQL_SUGGEST_ANALOG_OPTION("exit-info", "--debug-exit-info"),
  MYSQL_SUGGEST_ANALOG_OPTION("max-binlog-dump-events", "--debug-max-binlog-dump-events"),
  MYSQL_SUGGEST_ANALOG_OPTION("sporadic-binlog-dump-fail", "--debug-sporadic-binlog-dump-fail"),
  MYSQL_COMPATIBILITY_OPTION("new"),

  /* The following options were added after 5.6.10 */
  MYSQL_TO_BE_IMPLEMENTED_OPTION("rpl-stop-slave-timeout"),
  MYSQL_TO_BE_IMPLEMENTED_OPTION("validate-user-plugins") // NO_EMBEDDED_ACCESS_CHECKS
7468
};
unknown's avatar
unknown committed
7469

7470 7471
static int show_queries(THD *thd, SHOW_VAR *var, char *buff,
                        enum enum_var_type scope)
7472
{
7473
  var->type= SHOW_LONGLONG;
7474 7475 7476 7477
  var->value= (char *)&thd->query_id;
  return 0;
}

7478

7479 7480
static int show_net_compression(THD *thd, SHOW_VAR *var, char *buff,
                                enum enum_var_type scope)
7481
{
7482
  var->type= SHOW_MY_BOOL;
7483 7484 7485 7486
  var->value= (char *)&thd->net.compress;
  return 0;
}

7487 7488
static int show_starttime(THD *thd, SHOW_VAR *var, char *buff,
                          enum enum_var_type scope)
7489
{
7490
  var->type= SHOW_LONG;
7491
  var->value= buff;
unknown's avatar
unknown committed
7492
  *((long *)buff)= (long) (thd->query_start() - server_start_time);
7493 7494 7495
  return 0;
}

7496
#ifdef ENABLED_PROFILING
7497 7498
static int show_flushstatustime(THD *thd, SHOW_VAR *var, char *buff,
                                enum enum_var_type scope)
7499 7500 7501 7502 7503 7504
{
  var->type= SHOW_LONG;
  var->value= buff;
  *((long *)buff)= (long) (thd->query_start() - flush_status_time);
  return 0;
}
7505
#endif
7506

7507
#ifdef HAVE_REPLICATION
7508 7509
static int show_rpl_status(THD *thd, SHOW_VAR *var, char *buff,
                           enum enum_var_type scope)
7510
{
7511
  var->type= SHOW_CHAR;
7512 7513 7514 7515
  var->value= const_cast<char*>(rpl_status_type[(int)rpl_status]);
  return 0;
}

7516 7517
static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff,
                              enum enum_var_type scope)
7518
{
7519
  Master_info *mi= NULL;
unknown's avatar
unknown committed
7520
  bool tmp;
unknown's avatar
unknown committed
7521
  LINT_INIT(tmp);
unknown's avatar
unknown committed
7522

7523 7524
  var->type= SHOW_MY_BOOL;
  var->value= buff;
Marc Alff's avatar
Marc Alff committed
7525
  mysql_mutex_lock(&LOCK_active_mi);
7526 7527 7528 7529 7530 7531 7532 7533 7534
  if (master_info_index) 
  {
    mi= master_info_index->
      get_master_info(&thd->variables.default_master_connection,
                      Sql_condition::WARN_LEVEL_NOTE);
    if (mi)
      tmp= (my_bool) (mi->slave_running == MYSQL_SLAVE_RUN_CONNECT &&
                      mi->rli.slave_running);
  }
unknown's avatar
unknown committed
7535 7536 7537
  mysql_mutex_unlock(&LOCK_active_mi);
  if (mi)
    *((my_bool *)buff)= tmp;
7538
  else
7539
    var->type= SHOW_UNDEF;
7540 7541
  return 0;
}
Andrei Elkin's avatar
Andrei Elkin committed
7542

7543

7544 7545
static int show_slave_received_heartbeats(THD *thd, SHOW_VAR *var, char *buff,
                                          enum enum_var_type scope)
Andrei Elkin's avatar
Andrei Elkin committed
7546
{
7547
  Master_info *mi= NULL;
unknown's avatar
unknown committed
7548
  longlong tmp;
unknown's avatar
unknown committed
7549
  LINT_INIT(tmp);
unknown's avatar
unknown committed
7550

7551 7552
  var->type= SHOW_LONGLONG;
  var->value= buff;
Marc Alff's avatar
Marc Alff committed
7553
  mysql_mutex_lock(&LOCK_active_mi);
7554 7555 7556 7557 7558 7559 7560 7561
  if (master_info_index) 
  {
    mi= master_info_index->
      get_master_info(&thd->variables.default_master_connection,
                      Sql_condition::WARN_LEVEL_NOTE);
    if (mi)
      tmp= mi->received_heartbeats;
  }
unknown's avatar
unknown committed
7562 7563 7564
  mysql_mutex_unlock(&LOCK_active_mi);
  if (mi)
    *((longlong *)buff)= tmp;
Andrei Elkin's avatar
Andrei Elkin committed
7565 7566 7567 7568 7569
  else
    var->type= SHOW_UNDEF;
  return 0;
}

7570

7571 7572
static int show_heartbeat_period(THD *thd, SHOW_VAR *var, char *buff,
                                 enum enum_var_type scope)
Andrei Elkin's avatar
Andrei Elkin committed
7573
{
7574
  Master_info *mi= NULL;
unknown's avatar
unknown committed
7575 7576
  float tmp;
  LINT_INIT(tmp);
unknown's avatar
unknown committed
7577

7578 7579
  var->type= SHOW_CHAR;
  var->value= buff;
Marc Alff's avatar
Marc Alff committed
7580
  mysql_mutex_lock(&LOCK_active_mi);
7581 7582 7583 7584
  if (master_info_index) 
  {
    mi= master_info_index->
      get_master_info(&thd->variables.default_master_connection,
7585
                    Sql_condition::WARN_LEVEL_NOTE);
7586 7587 7588
    if (mi)
      tmp= mi->heartbeat_period;
  }
unknown's avatar
unknown committed
7589 7590
  mysql_mutex_unlock(&LOCK_active_mi);
  if (mi)
unknown's avatar
unknown committed
7591
    sprintf(buff, "%.3f", tmp);
Andrei Elkin's avatar
Andrei Elkin committed
7592 7593 7594 7595 7596 7597
  else
    var->type= SHOW_UNDEF;
  return 0;
}


7598 7599
#endif /* HAVE_REPLICATION */

7600 7601
static int show_open_tables(THD *thd, SHOW_VAR *var, char *buff,
                            enum enum_var_type scope)
7602
{
7603
  var->type= SHOW_LONG;
7604
  var->value= buff;
7605
  *((long *) buff)= (long) tc_records();
7606 7607 7608
  return 0;
}

7609 7610
static int show_prepared_stmt_count(THD *thd, SHOW_VAR *var, char *buff,
                                    enum enum_var_type scope)
unknown's avatar
unknown committed
7611 7612 7613
{
  var->type= SHOW_LONG;
  var->value= buff;
Marc Alff's avatar
Marc Alff committed
7614
  mysql_mutex_lock(&LOCK_prepared_stmt_count);
unknown's avatar
unknown committed
7615
  *((long *)buff)= (long)prepared_stmt_count;
Marc Alff's avatar
Marc Alff committed
7616
  mysql_mutex_unlock(&LOCK_prepared_stmt_count);
unknown's avatar
unknown committed
7617 7618 7619
  return 0;
}

7620 7621
static int show_table_definitions(THD *thd, SHOW_VAR *var, char *buff,
                                  enum enum_var_type scope)
7622
{
7623
  var->type= SHOW_LONG;
7624
  var->value= buff;
7625
  *((long *) buff)= (long) tdc_records();
7626 7627 7628
  return 0;
}

7629

7630 7631
static int show_flush_commands(THD *thd, SHOW_VAR *var, char *buff,
                               enum enum_var_type scope)
7632 7633 7634 7635 7636 7637 7638 7639
{
  var->type= SHOW_LONG;
  var->value= buff;
  *((long *) buff)= (long) tdc_refresh_version();
  return 0;
}


Konstantin Osipov's avatar
Konstantin Osipov committed
7640
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
7641
/* Functions relying on CTX */
7642 7643
static int show_ssl_ctx_sess_accept(THD *thd, SHOW_VAR *var, char *buff,
                                    enum enum_var_type scope)
7644
{
7645
  var->type= SHOW_LONG;
7646 7647 7648 7649 7650 7651
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_accept(ssl_acceptor_fd->ssl_context));
  return 0;
}

7652 7653
static int show_ssl_ctx_sess_accept_good(THD *thd, SHOW_VAR *var, char *buff,
                                         enum enum_var_type scope)
7654
{
7655
  var->type= SHOW_LONG;
7656 7657 7658 7659 7660 7661
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_accept_good(ssl_acceptor_fd->ssl_context));
  return 0;
}

7662 7663
static int show_ssl_ctx_sess_connect_good(THD *thd, SHOW_VAR *var, char *buff,
                                          enum enum_var_type scope)
7664
{
7665
  var->type= SHOW_LONG;
7666 7667 7668 7669 7670 7671
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_connect_good(ssl_acceptor_fd->ssl_context));
  return 0;
}

7672 7673 7674
static int show_ssl_ctx_sess_accept_renegotiate(THD *thd, SHOW_VAR *var,
                                                char *buff,
                                                enum enum_var_type scope)
7675
{
7676
  var->type= SHOW_LONG;
7677 7678 7679 7680 7681 7682
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context));
  return 0;
}

7683 7684 7685
static int show_ssl_ctx_sess_connect_renegotiate(THD *thd, SHOW_VAR *var,
                                                 char *buff,
                                                 enum enum_var_type scope)
7686
{
7687
  var->type= SHOW_LONG;
7688 7689 7690 7691 7692 7693
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_connect_renegotiate(ssl_acceptor_fd->ssl_context));
  return 0;
}

7694 7695
static int show_ssl_ctx_sess_cb_hits(THD *thd, SHOW_VAR *var, char *buff,
                                     enum enum_var_type scope)
7696
{
7697
  var->type= SHOW_LONG;
7698 7699 7700 7701 7702 7703
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_cb_hits(ssl_acceptor_fd->ssl_context));
  return 0;
}

7704 7705
static int show_ssl_ctx_sess_hits(THD *thd, SHOW_VAR *var, char *buff,
                                  enum enum_var_type scope)
7706
{
7707
  var->type= SHOW_LONG;
7708 7709 7710 7711 7712 7713
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_hits(ssl_acceptor_fd->ssl_context));
  return 0;
}

7714 7715
static int show_ssl_ctx_sess_cache_full(THD *thd, SHOW_VAR *var, char *buff,
                                        enum enum_var_type scope)
7716
{
7717
  var->type= SHOW_LONG;
7718 7719 7720 7721 7722 7723
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_cache_full(ssl_acceptor_fd->ssl_context));
  return 0;
}

7724 7725
static int show_ssl_ctx_sess_misses(THD *thd, SHOW_VAR *var, char *buff,
                                    enum enum_var_type scope)
7726
{
7727
  var->type= SHOW_LONG;
7728 7729 7730 7731 7732 7733
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_misses(ssl_acceptor_fd->ssl_context));
  return 0;
}

7734 7735
static int show_ssl_ctx_sess_timeouts(THD *thd, SHOW_VAR *var, char *buff,
                                      enum enum_var_type scope)
7736
{
7737
  var->type= SHOW_LONG;
7738 7739 7740 7741 7742 7743
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_timeouts(ssl_acceptor_fd->ssl_context));
  return 0;
}

7744 7745
static int show_ssl_ctx_sess_number(THD *thd, SHOW_VAR *var, char *buff,
                                    enum enum_var_type scope)
7746
{
7747
  var->type= SHOW_LONG;
7748 7749 7750 7751 7752 7753
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context));
  return 0;
}

7754 7755
static int show_ssl_ctx_sess_connect(THD *thd, SHOW_VAR *var, char *buff,
                                     enum enum_var_type scope)
7756
{
7757
  var->type= SHOW_LONG;
7758 7759 7760 7761 7762 7763
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_connect(ssl_acceptor_fd->ssl_context));
  return 0;
}

7764 7765 7766
static int show_ssl_ctx_sess_get_cache_size(THD *thd, SHOW_VAR *var,
                                            char *buff,
                                            enum enum_var_type scope)
7767
{
7768
  var->type= SHOW_LONG;
7769 7770 7771 7772 7773 7774
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context));
  return 0;
}

7775 7776
static int show_ssl_ctx_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff,
                                        enum enum_var_type scope)
7777
{
7778
  var->type= SHOW_LONG;
7779 7780 7781 7782 7783 7784
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_get_verify_mode(ssl_acceptor_fd->ssl_context));
  return 0;
}

7785 7786
static int show_ssl_ctx_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff,
                                         enum enum_var_type scope)
7787
{
7788
  var->type= SHOW_LONG;
7789 7790 7791 7792 7793 7794
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_get_verify_depth(ssl_acceptor_fd->ssl_context));
  return 0;
}

7795 7796 7797
static int show_ssl_ctx_get_session_cache_mode(THD *thd, SHOW_VAR *var,
                                               char *buff,
                                               enum enum_var_type scope)
7798
{
7799
  var->type= SHOW_CHAR;
7800
  if (!ssl_acceptor_fd)
unknown's avatar
unknown committed
7801
    var->value= const_cast<char*>("NONE");
7802 7803 7804 7805
  else
    switch (SSL_CTX_get_session_cache_mode(ssl_acceptor_fd->ssl_context))
    {
    case SSL_SESS_CACHE_OFF:
unknown's avatar
unknown committed
7806
      var->value= const_cast<char*>("OFF"); break;
7807
    case SSL_SESS_CACHE_CLIENT:
unknown's avatar
unknown committed
7808
      var->value= const_cast<char*>("CLIENT"); break;
7809
    case SSL_SESS_CACHE_SERVER:
unknown's avatar
unknown committed
7810
      var->value= const_cast<char*>("SERVER"); break;
7811
    case SSL_SESS_CACHE_BOTH:
unknown's avatar
unknown committed
7812
      var->value= const_cast<char*>("BOTH"); break;
7813
    case SSL_SESS_CACHE_NO_AUTO_CLEAR:
unknown's avatar
unknown committed
7814
      var->value= const_cast<char*>("NO_AUTO_CLEAR"); break;
7815
    case SSL_SESS_CACHE_NO_INTERNAL_LOOKUP:
unknown's avatar
unknown committed
7816
      var->value= const_cast<char*>("NO_INTERNAL_LOOKUP"); break;
7817
    default:
unknown's avatar
unknown committed
7818
      var->value= const_cast<char*>("Unknown"); break;
7819 7820 7821 7822
    }
  return 0;
}

7823
/*
7824
   Functions relying on SSL
7825 7826 7827 7828 7829
   Note: In the show_ssl_* functions, we need to check if we have a
         valid vio-object since this isn't always true, specifically
         when session_status or global_status is requested from
         inside an Event.
 */
7830 7831 7832

static int show_ssl_get_version(THD *thd, SHOW_VAR *var, char *buff,
                                enum enum_var_type scope)
7833
{
7834
  var->type= SHOW_CHAR;
7835 7836 7837
  if( thd->vio_ok() && thd->net.vio->ssl_arg )
    var->value= const_cast<char*>(SSL_get_version((SSL*) thd->net.vio->ssl_arg));
  else
7838
    var->value= (char *)"";
7839 7840 7841
  return 0;
}

7842 7843
static int show_ssl_session_reused(THD *thd, SHOW_VAR *var, char *buff,
                                   enum enum_var_type scope)
7844
{
7845
  var->type= SHOW_LONG;
7846
  var->value= buff;
7847 7848 7849 7850
  if( thd->vio_ok() && thd->net.vio->ssl_arg )
    *((long *)buff)= (long)SSL_session_reused((SSL*) thd->net.vio->ssl_arg);
  else
    *((long *)buff)= 0;
unknown's avatar
unknown committed
7851
  return 0;
7852 7853
}

7854 7855
static int show_ssl_get_default_timeout(THD *thd, SHOW_VAR *var, char *buff,
                                        enum enum_var_type scope)
7856
{
7857
  var->type= SHOW_LONG;
7858
  var->value= buff;
7859 7860 7861 7862
  if( thd->vio_ok() && thd->net.vio->ssl_arg )
    *((long *)buff)= (long)SSL_get_default_timeout((SSL*)thd->net.vio->ssl_arg);
  else
    *((long *)buff)= 0;
7863 7864 7865
  return 0;
}

7866 7867
static int show_ssl_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff,
                                    enum enum_var_type scope)
7868
{
7869
  var->type= SHOW_LONG;
7870
  var->value= buff;
7871 7872 7873 7874
  if( thd->net.vio && thd->net.vio->ssl_arg )
    *((long *)buff)= (long)SSL_get_verify_mode((SSL*)thd->net.vio->ssl_arg);
  else
    *((long *)buff)= 0;
7875 7876 7877
  return 0;
}

7878 7879
static int show_ssl_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff,
                                     enum enum_var_type scope)
7880
{
7881
  var->type= SHOW_LONG;
7882
  var->value= buff;
7883 7884 7885 7886
  if( thd->vio_ok() && thd->net.vio->ssl_arg )
    *((long *)buff)= (long)SSL_get_verify_depth((SSL*)thd->net.vio->ssl_arg);
  else
    *((long *)buff)= 0;
7887 7888 7889
  return 0;
}

7890 7891
static int show_ssl_get_cipher(THD *thd, SHOW_VAR *var, char *buff,
                               enum enum_var_type scope)
7892
{
7893
  var->type= SHOW_CHAR;
7894 7895 7896
  if( thd->vio_ok() && thd->net.vio->ssl_arg )
    var->value= const_cast<char*>(SSL_get_cipher((SSL*) thd->net.vio->ssl_arg));
  else
7897
    var->value= (char *)"";
7898 7899 7900
  return 0;
}

7901 7902
static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff,
                                    enum enum_var_type scope)
7903
{
7904
  var->type= SHOW_CHAR;
7905
  var->value= buff;
7906
  if (thd->vio_ok() && thd->net.vio->ssl_arg)
7907 7908 7909
  {
    int i;
    const char *p;
7910 7911 7912
    char *end= buff + SHOW_VAR_FUNC_BUFF_SIZE;
    for (i=0; (p= SSL_get_cipher_list((SSL*) thd->net.vio->ssl_arg,i)) &&
               buff < end; i++)
7913
    {
7914
      buff= strnmov(buff, p, end-buff-1);
7915 7916 7917 7918 7919 7920 7921 7922 7923
      *buff++= ':';
    }
    if (i)
      buff--;
  }
  *buff=0;
  return 0;
}

7924 7925 7926 7927 7928 7929 7930 7931 7932 7933 7934 7935 7936 7937 7938 7939 7940 7941 7942 7943 7944 7945 7946 7947 7948 7949 7950 7951 7952 7953 7954 7955 7956 7957 7958 7959 7960 7961 7962 7963 7964 7965 7966 7967 7968 7969 7970 7971 7972 7973 7974 7975

#ifdef HAVE_YASSL

static char *
my_asn1_time_to_string(ASN1_TIME *time, char *buf, size_t len)
{
  return yaSSL_ASN1_TIME_to_string(time, buf, len);
}

#else /* openssl */

static char *
my_asn1_time_to_string(ASN1_TIME *time, char *buf, size_t len)
{
  int n_read;
  char *res= NULL;
  BIO *bio= BIO_new(BIO_s_mem());

  if (bio == NULL)
    return NULL;

  if (!ASN1_TIME_print(bio, time))
    goto end;

  n_read= BIO_read(bio, buf, (int) (len - 1));

  if (n_read > 0)
  {
    buf[n_read]= 0;
    res= buf;
  }

end:
  BIO_free(bio);
  return res;
}

#endif


/**
  Handler function for the 'ssl_get_server_not_before' variable

  @param      thd  the mysql thread structure
  @param      var  the data for the variable
  @param[out] buf  the string to put the value of the variable into

  @return          status
  @retval     0    success
*/

static int
7976 7977
show_ssl_get_server_not_before(THD *thd, SHOW_VAR *var, char *buff,
                               enum enum_var_type scope)
7978 7979 7980 7981 7982 7983 7984 7985 7986 7987 7988 7989 7990 7991 7992 7993 7994 7995 7996 7997 7998 7999 8000 8001 8002 8003 8004 8005 8006 8007 8008 8009
{
  var->type= SHOW_CHAR;
  if(thd->vio_ok() && thd->net.vio->ssl_arg)
  {
    SSL *ssl= (SSL*) thd->net.vio->ssl_arg;
    X509 *cert= SSL_get_certificate(ssl);
    ASN1_TIME *not_before= X509_get_notBefore(cert);

    var->value= my_asn1_time_to_string(not_before, buff,
                                       SHOW_VAR_FUNC_BUFF_SIZE);
    if (!var->value)
      return 1;
    var->value= buff;
  }
  else
    var->value= empty_c_string;
  return 0;
}


/**
  Handler function for the 'ssl_get_server_not_after' variable

  @param      thd  the mysql thread structure
  @param      var  the data for the variable
  @param[out] buf  the string to put the value of the variable into

  @return          status
  @retval     0    success
*/

static int
8010 8011
show_ssl_get_server_not_after(THD *thd, SHOW_VAR *var, char *buff,
                              enum enum_var_type scope)
8012 8013 8014 8015 8016 8017 8018 8019 8020 8021 8022 8023 8024 8025 8026 8027 8028 8029
{
  var->type= SHOW_CHAR;
  if(thd->vio_ok() && thd->net.vio->ssl_arg)
  {
    SSL *ssl= (SSL*) thd->net.vio->ssl_arg;
    X509 *cert= SSL_get_certificate(ssl);
    ASN1_TIME *not_after= X509_get_notAfter(cert);

    var->value= my_asn1_time_to_string(not_after, buff,
                                       SHOW_VAR_FUNC_BUFF_SIZE);
    if (!var->value)
      return 1;
  }
  else
    var->value= empty_c_string;
  return 0;
}

Konstantin Osipov's avatar
Konstantin Osipov committed
8030
#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
8031

8032 8033
static int show_default_keycache(THD *thd, SHOW_VAR *var, char *buff,
                                 enum enum_var_type scope)
8034 8035 8036 8037 8038 8039 8040 8041 8042 8043 8044 8045 8046 8047 8048 8049 8050 8051 8052 8053 8054 8055 8056 8057
{
  struct st_data {
    KEY_CACHE_STATISTICS stats;
    SHOW_VAR var[8];
  } *data;
  SHOW_VAR *v;

  data=(st_data *)buff;
  v= data->var;

  var->type= SHOW_ARRAY;
  var->value= (char*)v;

  get_key_cache_statistics(dflt_key_cache, 0, &data->stats);

#define set_one_keycache_var(X,Y)       \
  v->name= X;                           \
  v->type= SHOW_LONGLONG;               \
  v->value= (char*)&data->stats.Y;      \
  v++;

  set_one_keycache_var("blocks_not_flushed", blocks_changed);
  set_one_keycache_var("blocks_unused",      blocks_unused);
  set_one_keycache_var("blocks_used",        blocks_used);
Sergei Golubchik's avatar
Sergei Golubchik committed
8058
  set_one_keycache_var("blocks_warm",        blocks_warm);
8059 8060 8061 8062 8063 8064 8065 8066 8067 8068 8069 8070 8071 8072
  set_one_keycache_var("read_requests",      read_requests);
  set_one_keycache_var("reads",              reads);
  set_one_keycache_var("write_requests",     write_requests);
  set_one_keycache_var("writes",             writes);

  v->name= 0;

  DBUG_ASSERT((char*)(v+1) <= buff + SHOW_VAR_FUNC_BUFF_SIZE);

#undef set_one_keycache_var

  return 0;
}

8073 8074 8075 8076 8077 8078 8079 8080 8081 8082 8083 8084 8085 8086 8087

static int show_memory_used(THD *thd, SHOW_VAR *var, char *buff,
                            enum enum_var_type scope)
{
  var->type= SHOW_LONGLONG;
  var->value= buff;
  if (scope == OPT_GLOBAL)
    *(longlong*) buff= (global_status_var.local_memory_used +
                        global_status_var.global_memory_used);
  else
    *(longlong*) buff= thd->status_var.local_memory_used;
  return 0;
}


8088
#ifndef DBUG_OFF
8089 8090
static int debug_status_func(THD *thd, SHOW_VAR *var, char *buff,
                             enum enum_var_type scope)
8091 8092 8093 8094 8095 8096 8097 8098 8099 8100 8101 8102 8103 8104 8105 8106 8107 8108 8109 8110 8111 8112 8113 8114 8115 8116 8117 8118 8119 8120 8121 8122 8123 8124
{
#define add_var(X,Y,Z)                  \
  v->name= X;                           \
  v->value= (char*)Y;                   \
  v->type= Z;                           \
  v++;

  var->type= SHOW_ARRAY;
  var->value= buff;

  SHOW_VAR *v= (SHOW_VAR *)buff;

  if (_db_keyword_(0, "role_merge_stats", 1))
  {
    static SHOW_VAR roles[]= {
      {"global",  (char*) &role_global_merges,  SHOW_ULONG},
      {"db",      (char*) &role_db_merges,      SHOW_ULONG},
      {"table",   (char*) &role_table_merges,   SHOW_ULONG},
      {"column",  (char*) &role_column_merges,  SHOW_ULONG},
      {"routine", (char*) &role_routine_merges, SHOW_ULONG},
      {NullS, NullS, SHOW_LONG}
    };

    add_var("role_merges", roles, SHOW_ARRAY);
  }

  v->name= 0;

#undef add_var

  return 0;
}
#endif

8125
#ifdef HAVE_POOL_OF_THREADS
8126 8127
int show_threadpool_idle_threads(THD *thd, SHOW_VAR *var, char *buff,
                                 enum enum_var_type scope)
8128 8129 8130 8131 8132 8133 8134
{
  var->type= SHOW_INT;
  var->value= buff;
  *(int *)buff= tp_get_idle_thread_count(); 
  return 0;
}
#endif
8135

8136 8137 8138 8139
/*
  Variables shown by SHOW STATUS in alphabetical order
*/

8140
SHOW_VAR status_vars[]= {
8141 8142
  {"Aborted_clients",          (char*) &aborted_threads,        SHOW_LONG},
  {"Aborted_connects",         (char*) &aborted_connects,       SHOW_LONG},
8143
  {"Access_denied_errors",     (char*) offsetof(STATUS_VAR, access_denied_errors), SHOW_LONG_STATUS},
Sergei Golubchik's avatar
Sergei Golubchik committed
8144
  {"Binlog_bytes_written",     (char*) offsetof(STATUS_VAR, binlog_bytes_written), SHOW_LONGLONG_STATUS},
8145 8146
  {"Binlog_cache_disk_use",    (char*) &binlog_cache_disk_use,  SHOW_LONG},
  {"Binlog_cache_use",         (char*) &binlog_cache_use,       SHOW_LONG},
8147 8148
  {"Binlog_stmt_cache_disk_use",(char*) &binlog_stmt_cache_disk_use,  SHOW_LONG},
  {"Binlog_stmt_cache_use",    (char*) &binlog_stmt_cache_use,       SHOW_LONG},
8149
  {"Busy_time",                (char*) offsetof(STATUS_VAR, busy_time), SHOW_DOUBLE_STATUS},
8150 8151
  {"Bytes_received",           (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONGLONG_STATUS},
  {"Bytes_sent",               (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS},
unknown's avatar
unknown committed
8152
  {"Com",                      (char*) com_status_vars, SHOW_ARRAY},
8153
  {"Compression",              (char*) &show_net_compression, SHOW_SIMPLE_FUNC},
8154
  {"Connections",              (char*) &thread_id,              SHOW_LONG_NOFLUSH},
unknown's avatar
unknown committed
8155 8156 8157 8158 8159 8160
  {"Connection_errors_accept", (char*) &connection_errors_accept, SHOW_LONG},
  {"Connection_errors_internal", (char*) &connection_errors_internal, SHOW_LONG},
  {"Connection_errors_max_connections", (char*) &connection_errors_max_connection, SHOW_LONG},
  {"Connection_errors_peer_address", (char*) &connection_errors_peer_addr, SHOW_LONG},
  {"Connection_errors_select", (char*) &connection_errors_select, SHOW_LONG},
  {"Connection_errors_tcpwrap", (char*) &connection_errors_tcpwrap, SHOW_LONG},
8161
  {"Cpu_time",                 (char*) offsetof(STATUS_VAR, cpu_time), SHOW_DOUBLE_STATUS},
Sergei Golubchik's avatar
Sergei Golubchik committed
8162
  {"Created_tmp_disk_tables",  (char*) offsetof(STATUS_VAR, created_tmp_disk_tables_), SHOW_LONG_STATUS},
8163
  {"Created_tmp_files",	       (char*) &my_tmp_file_created,	SHOW_LONG},
Sergei Golubchik's avatar
Sergei Golubchik committed
8164
  {"Created_tmp_tables",       (char*) offsetof(STATUS_VAR, created_tmp_tables_), SHOW_LONG_STATUS},
8165 8166 8167
#ifndef DBUG_OFF
  {"Debug",                    (char*) &debug_status_func,  SHOW_FUNC},
#endif
8168
  {"Delayed_errors",           (char*) &delayed_insert_errors,  SHOW_LONG},
8169
  {"Delayed_insert_threads",   (char*) &delayed_insert_threads, SHOW_LONG_NOFLUSH},
8170
  {"Delayed_writes",           (char*) &delayed_insert_writes,  SHOW_LONG},
8171
  {"Empty_queries",            (char*) offsetof(STATUS_VAR, empty_queries), SHOW_LONG_STATUS},
8172 8173
  {"Executed_events",          (char*) &executed_events, SHOW_LONG_NOFLUSH },
  {"Executed_triggers",        (char*) offsetof(STATUS_VAR, executed_triggers), SHOW_LONG_STATUS},
8174
  {"Feature_delay_key_write",  (char*) &feature_files_opened_with_delayed_keys, SHOW_LONG },
8175 8176 8177 8178 8179 8180
  {"Feature_dynamic_columns",  (char*) offsetof(STATUS_VAR, feature_dynamic_columns), SHOW_LONG_STATUS},
  {"Feature_fulltext",         (char*) offsetof(STATUS_VAR, feature_fulltext), SHOW_LONG_STATUS},
  {"Feature_gis",              (char*) offsetof(STATUS_VAR, feature_gis), SHOW_LONG_STATUS},
  {"Feature_locale",           (char*) offsetof(STATUS_VAR, feature_locale), SHOW_LONG_STATUS},
  {"Feature_subquery",         (char*) offsetof(STATUS_VAR, feature_subquery), SHOW_LONG_STATUS},
  {"Feature_timezone",         (char*) offsetof(STATUS_VAR, feature_timezone), SHOW_LONG_STATUS},
8181 8182
  {"Feature_trigger",          (char*) offsetof(STATUS_VAR, feature_trigger), SHOW_LONG_STATUS},
  {"Feature_xml",              (char*) offsetof(STATUS_VAR, feature_xml), SHOW_LONG_STATUS},
8183
  {"Flush_commands",           (char*) &show_flush_commands, SHOW_SIMPLE_FUNC},
unknown's avatar
Merge  
unknown committed
8184 8185 8186
  {"Handler_commit",           (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
  {"Handler_delete",           (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS},
  {"Handler_discover",         (char*) offsetof(STATUS_VAR, ha_discover_count), SHOW_LONG_STATUS},
8187
  {"Handler_external_lock",    (char*) offsetof(STATUS_VAR, ha_external_lock_count), SHOW_LONGLONG_STATUS},
8188
  {"Handler_icp_attempts",     (char*) offsetof(STATUS_VAR, ha_icp_attempts), SHOW_LONG_STATUS},
8189 8190
  {"Handler_icp_match",        (char*) offsetof(STATUS_VAR, ha_icp_match), SHOW_LONG_STATUS},
  {"Handler_mrr_init",         (char*) offsetof(STATUS_VAR, ha_mrr_init_count),  SHOW_LONG_STATUS},
8191 8192
  {"Handler_mrr_key_refills",  (char*) offsetof(STATUS_VAR, ha_mrr_key_refills_count), SHOW_LONG_STATUS},
  {"Handler_mrr_rowid_refills",(char*) offsetof(STATUS_VAR, ha_mrr_rowid_refills_count), SHOW_LONG_STATUS},
unknown's avatar
Merge  
unknown committed
8193 8194 8195
  {"Handler_prepare",          (char*) offsetof(STATUS_VAR, ha_prepare_count),  SHOW_LONG_STATUS},
  {"Handler_read_first",       (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS},
  {"Handler_read_key",         (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS},
8196
  {"Handler_read_last",        (char*) offsetof(STATUS_VAR, ha_read_last_count), SHOW_LONG_STATUS},
unknown's avatar
Merge  
unknown committed
8197 8198 8199
  {"Handler_read_next",        (char*) offsetof(STATUS_VAR, ha_read_next_count), SHOW_LONG_STATUS},
  {"Handler_read_prev",        (char*) offsetof(STATUS_VAR, ha_read_prev_count), SHOW_LONG_STATUS},
  {"Handler_read_rnd",         (char*) offsetof(STATUS_VAR, ha_read_rnd_count), SHOW_LONG_STATUS},
8200
  {"Handler_read_rnd_deleted", (char*) offsetof(STATUS_VAR, ha_read_rnd_deleted_count), SHOW_LONG_STATUS},
unknown's avatar
Merge  
unknown committed
8201 8202 8203 8204
  {"Handler_read_rnd_next",    (char*) offsetof(STATUS_VAR, ha_read_rnd_next_count), SHOW_LONG_STATUS},
  {"Handler_rollback",         (char*) offsetof(STATUS_VAR, ha_rollback_count), SHOW_LONG_STATUS},
  {"Handler_savepoint",        (char*) offsetof(STATUS_VAR, ha_savepoint_count), SHOW_LONG_STATUS},
  {"Handler_savepoint_rollback",(char*) offsetof(STATUS_VAR, ha_savepoint_rollback_count), SHOW_LONG_STATUS},
8205 8206
  {"Handler_tmp_update",       (char*) offsetof(STATUS_VAR, ha_tmp_update_count), SHOW_LONG_STATUS},
  {"Handler_tmp_write",        (char*) offsetof(STATUS_VAR, ha_tmp_write_count), SHOW_LONG_STATUS},
8207 8208
  {"Handler_update",           (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS},
  {"Handler_write",            (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS},
8209
  {"Key",                      (char*) &show_default_keycache, SHOW_FUNC},
8210
  {"Last_query_cost",          (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS},
8211
  {"Max_statement_time_exceeded", (char*) offsetof(STATUS_VAR, max_statement_time_exceeded), SHOW_LONG_STATUS},
8212
  {"Max_used_connections",     (char*) &max_used_connections,  SHOW_LONG},
8213
  {"Memory_used",              (char*) &show_memory_used, SHOW_SIMPLE_FUNC},
8214 8215 8216
  {"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use,    SHOW_LONG_NOFLUSH},
  {"Open_files",               (char*) &my_file_opened,         SHOW_LONG_NOFLUSH},
  {"Open_streams",             (char*) &my_stream_opened,       SHOW_LONG_NOFLUSH},
8217 8218
  {"Open_table_definitions",   (char*) &show_table_definitions, SHOW_SIMPLE_FUNC},
  {"Open_tables",              (char*) &show_open_tables,       SHOW_SIMPLE_FUNC},
8219
  {"Opened_files",             (char*) &my_file_total_opened, SHOW_LONG_NOFLUSH},
8220
  {"Opened_plugin_libraries",  (char*) &dlopen_count, SHOW_LONG},
8221
  {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS},
Sergei Golubchik's avatar
Sergei Golubchik committed
8222
  {"Opened_tables",            (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS},
8223
  {"Opened_views",             (char*) offsetof(STATUS_VAR, opened_views), SHOW_LONG_STATUS},
8224
  {"Prepared_stmt_count",      (char*) &show_prepared_stmt_count, SHOW_SIMPLE_FUNC},
Sergei Golubchik's avatar
Sergei Golubchik committed
8225
  {"Rows_sent",                (char*) offsetof(STATUS_VAR, rows_sent), SHOW_LONGLONG_STATUS},
8226
  {"Rows_read",                (char*) offsetof(STATUS_VAR, rows_read), SHOW_LONGLONG_STATUS},
8227
  {"Rows_tmp_read",            (char*) offsetof(STATUS_VAR, rows_tmp_read), SHOW_LONGLONG_STATUS},
unknown's avatar
unknown committed
8228
#ifdef HAVE_QUERY_CACHE
8229 8230
  {"Qcache_free_blocks",       (char*) &query_cache.free_memory_blocks, SHOW_LONG_NOFLUSH},
  {"Qcache_free_memory",       (char*) &query_cache.free_memory, SHOW_LONG_NOFLUSH},
unknown's avatar
unknown committed
8231
  {"Qcache_hits",              (char*) &query_cache.hits,       SHOW_LONG},
8232
  {"Qcache_inserts",           (char*) &query_cache.inserts,    SHOW_LONG},
8233
  {"Qcache_lowmem_prunes",     (char*) &query_cache.lowmem_prunes, SHOW_LONG},
unknown's avatar
unknown committed
8234
  {"Qcache_not_cached",        (char*) &query_cache.refused,    SHOW_LONG},
8235 8236
  {"Qcache_queries_in_cache",  (char*) &query_cache.queries_in_cache, SHOW_LONG_NOFLUSH},
  {"Qcache_total_blocks",      (char*) &query_cache.total_blocks, SHOW_LONG_NOFLUSH},
unknown's avatar
unknown committed
8237
#endif /*HAVE_QUERY_CACHE*/
8238
  {"Queries",                  (char*) &show_queries,            SHOW_SIMPLE_FUNC},
8239
  {"Questions",                (char*) offsetof(STATUS_VAR, questions), SHOW_LONG_STATUS},
8240
#ifdef HAVE_REPLICATION
8241
  {"Rpl_status",               (char*) &show_rpl_status,          SHOW_SIMPLE_FUNC},
8242
#endif
Sergei Golubchik's avatar
Sergei Golubchik committed
8243 8244 8245 8246 8247
  {"Select_full_join",         (char*) offsetof(STATUS_VAR, select_full_join_count_), SHOW_LONG_STATUS},
  {"Select_full_range_join",   (char*) offsetof(STATUS_VAR, select_full_range_join_count_), SHOW_LONG_STATUS},
  {"Select_range",             (char*) offsetof(STATUS_VAR, select_range_count_), SHOW_LONG_STATUS},
  {"Select_range_check",       (char*) offsetof(STATUS_VAR, select_range_check_count_), SHOW_LONG_STATUS},
  {"Select_scan",	       (char*) offsetof(STATUS_VAR, select_scan_count_), SHOW_LONG_STATUS},
Michael Widenius's avatar
Michael Widenius committed
8248
  {"Slave_open_temp_tables",   (char*) &slave_open_temp_tables, SHOW_INT},
8249
#ifdef HAVE_REPLICATION
8250 8251
  {"Slave_heartbeat_period",   (char*) &show_heartbeat_period, SHOW_SIMPLE_FUNC},
  {"Slave_received_heartbeats",(char*) &show_slave_received_heartbeats, SHOW_SIMPLE_FUNC},
Sergei Golubchik's avatar
Sergei Golubchik committed
8252
  {"Slave_retried_transactions",(char*)&slave_retried_transactions, SHOW_LONG},
8253
  {"Slave_running",            (char*) &show_slave_running,     SHOW_SIMPLE_FUNC},
8254
#endif
8255
  {"Slow_launch_threads",      (char*) &slow_launch_threads,    SHOW_LONG},
unknown's avatar
Merge  
unknown committed
8256
  {"Slow_queries",             (char*) offsetof(STATUS_VAR, long_query_count), SHOW_LONG_STATUS},
Sergei Golubchik's avatar
Sergei Golubchik committed
8257
  {"Sort_merge_passes",	       (char*) offsetof(STATUS_VAR, filesort_merge_passes_), SHOW_LONG_STATUS},
8258
  {"Sort_priority_queue_sorts",(char*) offsetof(STATUS_VAR, filesort_pq_sorts_), SHOW_LONG_STATUS}, 
Sergei Golubchik's avatar
Sergei Golubchik committed
8259 8260 8261
  {"Sort_range",	       (char*) offsetof(STATUS_VAR, filesort_range_count_), SHOW_LONG_STATUS},
  {"Sort_rows",		       (char*) offsetof(STATUS_VAR, filesort_rows_), SHOW_LONG_STATUS},
  {"Sort_scan",		       (char*) offsetof(STATUS_VAR, filesort_scan_count_), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
8262
#ifdef HAVE_OPENSSL
Konstantin Osipov's avatar
Konstantin Osipov committed
8263
#ifndef EMBEDDED_LIBRARY
8264 8265 8266 8267 8268 8269 8270 8271 8272 8273 8274 8275
  {"Ssl_accept_renegotiates",  (char*) &show_ssl_ctx_sess_accept_renegotiate, SHOW_SIMPLE_FUNC},
  {"Ssl_accepts",              (char*) &show_ssl_ctx_sess_accept, SHOW_SIMPLE_FUNC},
  {"Ssl_callback_cache_hits",  (char*) &show_ssl_ctx_sess_cb_hits, SHOW_SIMPLE_FUNC},
  {"Ssl_cipher",               (char*) &show_ssl_get_cipher, SHOW_SIMPLE_FUNC},
  {"Ssl_cipher_list",          (char*) &show_ssl_get_cipher_list, SHOW_SIMPLE_FUNC},
  {"Ssl_client_connects",      (char*) &show_ssl_ctx_sess_connect, SHOW_SIMPLE_FUNC},
  {"Ssl_connect_renegotiates", (char*) &show_ssl_ctx_sess_connect_renegotiate, SHOW_SIMPLE_FUNC},
  {"Ssl_ctx_verify_depth",     (char*) &show_ssl_ctx_get_verify_depth, SHOW_SIMPLE_FUNC},
  {"Ssl_ctx_verify_mode",      (char*) &show_ssl_ctx_get_verify_mode, SHOW_SIMPLE_FUNC},
  {"Ssl_default_timeout",      (char*) &show_ssl_get_default_timeout, SHOW_SIMPLE_FUNC},
  {"Ssl_finished_accepts",     (char*) &show_ssl_ctx_sess_accept_good, SHOW_SIMPLE_FUNC},
  {"Ssl_finished_connects",    (char*) &show_ssl_ctx_sess_connect_good, SHOW_SIMPLE_FUNC},
Sergei Golubchik's avatar
Sergei Golubchik committed
8276 8277
  {"Ssl_server_not_after",     (char*) &show_ssl_get_server_not_after, SHOW_SIMPLE_FUNC},
  {"Ssl_server_not_before",    (char*) &show_ssl_get_server_not_before, SHOW_SIMPLE_FUNC},
8278 8279 8280 8281 8282 8283 8284 8285 8286 8287 8288
  {"Ssl_session_cache_hits",   (char*) &show_ssl_ctx_sess_hits, SHOW_SIMPLE_FUNC},
  {"Ssl_session_cache_misses", (char*) &show_ssl_ctx_sess_misses, SHOW_SIMPLE_FUNC},
  {"Ssl_session_cache_mode",   (char*) &show_ssl_ctx_get_session_cache_mode, SHOW_SIMPLE_FUNC},
  {"Ssl_session_cache_overflows", (char*) &show_ssl_ctx_sess_cache_full, SHOW_SIMPLE_FUNC},
  {"Ssl_session_cache_size",   (char*) &show_ssl_ctx_sess_get_cache_size, SHOW_SIMPLE_FUNC},
  {"Ssl_session_cache_timeouts", (char*) &show_ssl_ctx_sess_timeouts, SHOW_SIMPLE_FUNC},
  {"Ssl_sessions_reused",      (char*) &show_ssl_session_reused, SHOW_SIMPLE_FUNC},
  {"Ssl_used_session_cache_entries",(char*) &show_ssl_ctx_sess_number, SHOW_SIMPLE_FUNC},
  {"Ssl_verify_depth",         (char*) &show_ssl_get_verify_depth, SHOW_SIMPLE_FUNC},
  {"Ssl_verify_mode",          (char*) &show_ssl_get_verify_mode, SHOW_SIMPLE_FUNC},
  {"Ssl_version",              (char*) &show_ssl_get_version, SHOW_SIMPLE_FUNC},
Konstantin Osipov's avatar
Konstantin Osipov committed
8289
#endif
unknown's avatar
unknown committed
8290
#endif /* HAVE_OPENSSL */
8291
  {"Syncs",                    (char*) &my_sync_count,          SHOW_LONG_NOFLUSH},
unknown's avatar
unknown committed
8292 8293 8294 8295
  /*
    Expression cache used only for caching subqueries now, so its statistic
    variables we call subquery_cache*.
  */
8296 8297
  {"Subquery_cache_hit",       (char*) &subquery_cache_hit,     SHOW_LONG},
  {"Subquery_cache_miss",      (char*) &subquery_cache_miss,    SHOW_LONG},
unknown's avatar
unknown committed
8298 8299
  {"Table_locks_immediate",    (char*) &locks_immediate,        SHOW_LONG},
  {"Table_locks_waited",       (char*) &locks_waited,           SHOW_LONG},
8300
#ifdef HAVE_MMAP
unknown's avatar
Merge  
unknown committed
8301
  {"Tc_log_max_pages_used",    (char*) &tc_log_max_pages_used,  SHOW_LONG},
8302
  {"Tc_log_page_size",         (char*) &tc_log_page_size,       SHOW_LONG_NOFLUSH},
unknown's avatar
Merge  
unknown committed
8303
  {"Tc_log_page_waits",        (char*) &tc_log_page_waits,      SHOW_LONG},
8304
#endif
8305
#ifdef HAVE_POOL_OF_THREADS
8306
  {"Threadpool_idle_threads",  (char *) &show_threadpool_idle_threads, SHOW_SIMPLE_FUNC},
8307
  {"Threadpool_threads",       (char *) &tp_stats.num_worker_threads, SHOW_INT},
8308
#endif
8309
  {"Threads_cached",           (char*) &cached_thread_count,    SHOW_LONG_NOFLUSH},
Konstantin Osipov's avatar
Konstantin Osipov committed
8310
  {"Threads_connected",        (char*) &connection_count,       SHOW_INT},
8311 8312
  {"Threads_created",	       (char*) &thread_created,		SHOW_LONG_NOFLUSH},
  {"Threads_running",          (char*) &thread_running,         SHOW_INT},
8313
  {"Uptime",                   (char*) &show_starttime,         SHOW_SIMPLE_FUNC},
8314
#ifdef ENABLED_PROFILING
8315
  {"Uptime_since_flush_status",(char*) &show_flushstatustime,   SHOW_SIMPLE_FUNC},
8316 8317 8318
#endif
#ifdef WITH_WSREP
  {"wsrep",                    (char*) &wsrep_show_status,       SHOW_FUNC},
8319
#endif
8320
  {NullS, NullS, SHOW_LONG}
unknown's avatar
unknown committed
8321 8322
};

8323
static bool add_terminator(DYNAMIC_ARRAY *options)
8324 8325
{
  my_option empty_element= {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0};
Marc Alff's avatar
Marc Alff committed
8326
  return insert_dynamic(options, (uchar *)&empty_element);
8327 8328
}

8329 8330 8331 8332 8333 8334 8335 8336 8337
static bool add_many_options(DYNAMIC_ARRAY *options, my_option *list,
                            size_t elements)
{
  for (my_option *opt= list; opt < list + elements; opt++)
    if (insert_dynamic(options, opt))
      return 1;
  return 0;
}

8338
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
8339 8340
static void print_version(void)
{
8341
  set_server_version();
8342

8343 8344
  printf("%s  Ver %s for %s on %s (%s)\n",my_progname,
	 server_version,SYSTEM_TYPE,MACHINE_TYPE, MYSQL_COMPILATION_COMMENT);
unknown's avatar
unknown committed
8345 8346
}

8347 8348 8349 8350 8351 8352 8353 8354 8355 8356 8357 8358 8359 8360 8361 8362 8363 8364 8365 8366 8367 8368 8369 8370 8371 8372 8373 8374
/** Compares two options' names, treats - and _ the same */
static int option_cmp(my_option *a, my_option *b)
{
  const char *sa= a->name;
  const char *sb= b->name;
  for (; *sa || *sb; sa++, sb++)
  {
    if (*sa < *sb)
    {
      if (*sa == '-' && *sb == '_')
        continue;
      else
        return -1;
    }
    if (*sa > *sb)
    {
      if (*sa == '_' && *sb == '-')
        continue;
      else
        return 1;
    }
  }
  return 0;
}

static void print_help()
{
  MEM_ROOT mem_root;
8375
  init_alloc_root(&mem_root, 4096, 4096, MYF(0));
8376 8377

  pop_dynamic(&all_options);
8378 8379
  add_many_options(&all_options, pfs_early_options,
                  array_elements(pfs_early_options));
Marc Alff's avatar
Marc Alff committed
8380
  sys_var_add_options(&all_options, sys_var::PARSE_EARLY);
8381 8382
  add_plugin_options(&all_options, &mem_root);
  sort_dynamic(&all_options, (qsort_cmp) option_cmp);
8383
  sort_dynamic(&all_options, (qsort_cmp) option_cmp);
Marc Alff's avatar
Marc Alff committed
8384
  add_terminator(&all_options);
8385 8386

  my_print_help((my_option*) all_options.buffer);
8387

8388
  /* Add variables that must be shown but not changed, like version numbers */
8389
  pop_dynamic(&all_options);
8390
  sys_var_add_options(&all_options, sys_var::GETOPT_ONLY_HELP);
8391 8392
  sort_dynamic(&all_options, (qsort_cmp) option_cmp);
  add_terminator(&all_options);
8393 8394 8395 8396 8397
  my_print_variables((my_option*) all_options.buffer);

  free_root(&mem_root, MYF(0));
}

unknown's avatar
unknown committed
8398 8399
static void usage(void)
{
8400
  DBUG_ENTER("usage");
8401
  if (!(default_charset_info= get_charset_by_csname(default_character_set_name,
unknown's avatar
unknown committed
8402 8403 8404 8405 8406
					           MY_CS_PRIMARY,
						   MYF(MY_WME))))
    exit(1);
  if (!default_collation_name)
    default_collation_name= (char*) default_charset_info->name;
unknown's avatar
unknown committed
8407
  print_version();
8408
  puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000"));
Sergei Golubchik's avatar
Sergei Golubchik committed
8409
  puts("Starts the MariaDB database server.\n");
unknown's avatar
unknown committed
8410
  printf("Usage: %s [OPTIONS]\n", my_progname);
8411
  if (!opt_verbose)
Staale Smedseng's avatar
Staale Smedseng committed
8412
    puts("\nFor more help options (several pages), use mysqld --verbose --help.");
8413 8414
  else
  {
unknown's avatar
unknown committed
8415 8416
#ifdef __WIN__
  puts("NT and Win32 specific options:\n\
Staale Smedseng's avatar
Staale Smedseng committed
8417 8418 8419 8420 8421 8422 8423 8424
  --install                     Install the default service (NT).\n\
  --install-manual              Install the default service started manually (NT).\n\
  --install service_name        Install an optional service (NT).\n\
  --install-manual service_name Install an optional service started manually (NT).\n\
  --remove                      Remove the default service from the service list (NT).\n\
  --remove service_name         Remove the service_name from the service list (NT).\n\
  --enable-named-pipe           Only to be used for the default server (NT).\n\
  --standalone                  Dummy option to start as a standalone server (NT).\
unknown's avatar
unknown committed
8425
");
8426
  puts("");
unknown's avatar
unknown committed
8427
#endif
8428
  print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
unknown's avatar
unknown committed
8429 8430
  puts("");
  set_ports();
8431

unknown's avatar
unknown committed
8432
  /* Print out all the options including plugin supplied options */
8433
  print_help();
8434

8435 8436 8437 8438 8439 8440 8441
  if (! plugins_are_initialized)
  {
    puts("\n\
Plugins have parameters that are not reflected in this list\n\
because execution stopped before plugins were initialized.");
  }

unknown's avatar
unknown committed
8442
  puts("\n\
unknown's avatar
unknown committed
8443
To see what values a running MySQL server is using, type\n\
8444
'mysqladmin variables' instead of 'mysqld --verbose --help'.");
8445
  }
8446
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
8447
}
8448
#endif /*!EMBEDDED_LIBRARY*/
unknown's avatar
unknown committed
8449

unknown's avatar
unknown committed
8450
/**
8451
  Initialize MySQL global variables to default values.
unknown's avatar
unknown committed
8452

unknown's avatar
unknown committed
8453
  @note
unknown's avatar
unknown committed
8454 8455 8456 8457
    The reason to set a lot of global variables to zero is to allow one to
    restart the embedded server with a clean environment
    It's also needed on some exotic platforms where global variables are
    not set to 0 when a program starts.
unknown's avatar
unknown committed
8458

8459
    We don't need to set variables refered to in my_long_options
unknown's avatar
unknown committed
8460 8461
    as these are initialized by my_getopt.
*/
unknown's avatar
unknown committed
8462

8463
static int mysql_init_variables(void)
unknown's avatar
unknown committed
8464 8465 8466 8467
{
  /* Things reset to zero */
  opt_skip_slave_start= opt_reckless_slave = 0;
  mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0;
8468
#if defined(HAVE_REALPATH) && !defined(HAVE_valgrind) && !defined(HAVE_BROKEN_REALPATH)
8469
  /*  We can only test for sub paths if my_symlink.c is using realpath */
8470
  myisam_test_invalid_symlink= test_if_data_home_dir;
8471
#endif
Monty's avatar
Monty committed
8472
  opt_log= 0;
8473
  opt_bin_log= opt_bin_log_used= 0;
unknown's avatar
unknown committed
8474
  opt_disable_networking= opt_skip_show_db=0;
8475
  opt_skip_name_resolve= 0;
8476
  opt_ignore_builtin_innodb= 0;
Sergei Golubchik's avatar
Sergei Golubchik committed
8477
  opt_logname= opt_binlog_index_name= opt_slow_logname= 0;
8478
  opt_log_basename= 0;
unknown's avatar
Merge  
unknown committed
8479
  opt_tc_log_file= (char *)"tc.log";      // no hostname in tc_log file name !
8480 8481
  opt_secure_auth= 0;
  opt_bootstrap= opt_myisam_log= 0;
unknown's avatar
unknown committed
8482
  mqh_used= 0;
8483
  kill_in_progress= 0;
unknown's avatar
unknown committed
8484 8485 8486 8487 8488 8489 8490
  cleanup_done= 0;
  server_id_supplied= 0;
  test_flags= select_errors= dropping_tables= ha_open_options=0;
  thread_count= thread_running= kill_cached_threads= wake_thread=0;
  slave_open_temp_tables= 0;
  cached_thread_count= 0;
  opt_endinfo= using_udf_functions= 0;
8491
  opt_using_transactions= 0;
unknown's avatar
unknown committed
8492 8493
  abort_loop= select_thread_in_use= signal_thread_in_use= 0;
  ready_to_exit= shutdown_in_progress= grant_option= 0;
unknown's avatar
Merge  
unknown committed
8494
  aborted_threads= aborted_connects= 0;
unknown's avatar
unknown committed
8495
  subquery_cache_miss= subquery_cache_hit= 0;
unknown's avatar
unknown committed
8496 8497
  delayed_insert_threads= delayed_insert_writes= delayed_rows_in_use= 0;
  delayed_insert_errors= thread_created= 0;
unknown's avatar
Merge  
unknown committed
8498
  specialflag= 0;
8499
  binlog_cache_use=  binlog_cache_disk_use= 0;
unknown's avatar
unknown committed
8500 8501
  max_used_connections= slow_launch_threads = 0;
  mysqld_user= mysqld_chroot= opt_init_file= opt_bin_logname = 0;
8502
  prepared_stmt_count= 0;
8503
  mysqld_unix_port= opt_mysql_tmpdir= my_bind_addr_str= NullS;
8504
  bzero((uchar*) &mysql_tmpdir_list, sizeof(mysql_tmpdir_list));
unknown's avatar
Merge  
unknown committed
8505
  bzero((char *) &global_status_var, sizeof(global_status_var));
8506
  opt_large_pages= 0;
8507
  opt_super_large_pages= 0;
8508 8509 8510
#if defined(ENABLED_DEBUG_SYNC)
  opt_debug_sync_timeout= 0;
#endif /* defined(ENABLED_DEBUG_SYNC) */
8511
  key_map_full.set_all();
unknown's avatar
unknown committed
8512

8513 8514 8515 8516 8517
  /* Character sets */
  system_charset_info= &my_charset_utf8_general_ci;
  files_charset_info= &my_charset_utf8_general_ci;
  national_charset_info= &my_charset_utf8_general_ci;
  table_alias_charset= &my_charset_bin;
unknown's avatar
unknown committed
8518
  character_set_filesystem= &my_charset_bin;
8519

unknown's avatar
unknown committed
8520
  opt_specialflag= SPECIAL_ENGLISH;
8521
  unix_sock= base_ip_sock= extra_ip_sock= MYSQL_INVALID_SOCKET;
unknown's avatar
unknown committed
8522 8523 8524 8525
  mysql_home_ptr= mysql_home;
  log_error_file_ptr= log_error_file;
  protocol_version= PROTOCOL_VERSION;
  what_to_log= ~ (1L << (uint) COM_TIME);
8526
  denied_connections= 0;
8527
  executed_events= 0;
8528
  global_query_id= thread_id= 1L;
unknown's avatar
unknown committed
8529 8530 8531
  strmov(server_version, MYSQL_SERVER_VERSION);
  threads.empty();
  thread_cache.empty();
8532
  key_caches.empty();
unknown's avatar
unknown committed
8533
  if (!(dflt_key_cache= get_or_create_key_cache(default_key_cache_base.str,
8534
                                                default_key_cache_base.length)))
8535 8536 8537 8538
  {
    sql_print_error("Cannot allocate the keycache");
    return 1;
  }
8539

8540 8541
  /* set key_cache_hash.default_value = dflt_key_cache */
  multi_keycache_init();
unknown's avatar
unknown committed
8542 8543

  /* Set directory paths */
8544
  mysql_real_data_home_len=
8545 8546
    strmake_buf(mysql_real_data_home,
                get_relative_path(MYSQL_DATADIR)) - mysql_real_data_home;
unknown's avatar
unknown committed
8547 8548
  /* Replication parameters */
  master_info_file= (char*) "master.info",
unknown's avatar
unknown committed
8549
    relay_log_info_file= (char*) "relay-log.info";
unknown's avatar
unknown committed
8550 8551
  report_user= report_password = report_host= 0;	/* TO BE DELETED */
  opt_relay_logname= opt_relaylog_index_name= 0;
8552
  slave_retried_transactions= 0;
unknown's avatar
unknown committed
8553 8554 8555

  /* Variables in libraries */
  charsets_dir= 0;
8556
  default_character_set_name= (char*) MYSQL_DEFAULT_CHARSET_NAME;
8557
  default_collation_name= compiled_default_collation_name;
unknown's avatar
unknown committed
8558
  character_set_filesystem_name= (char*) "binary";
8559
  lc_messages= (char*) "en_US";
8560
  lc_time_names_name= (char*) "en_US";
8561
  
unknown's avatar
unknown committed
8562 8563 8564 8565
  /* Variables that depends on compile options */
#ifndef DBUG_OFF
  default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace",
			     "d:t:i:o,/tmp/mysqld.trace");
8566
  current_dbug_option= default_dbug_option;
unknown's avatar
unknown committed
8567 8568
#endif
  opt_error_log= IF_WIN(1,0);
8569 8570
#ifdef ENABLED_PROFILING
    have_profiling = SHOW_OPTION_YES;
8571
#else
8572
    have_profiling = SHOW_OPTION_NO;
8573
#endif
8574

unknown's avatar
unknown committed
8575
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
8576
  have_ssl=SHOW_OPTION_YES;
8577 8578
#if HAVE_YASSL
  have_openssl= SHOW_OPTION_NO;
unknown's avatar
unknown committed
8579
#else
8580 8581 8582 8583
  have_openssl= SHOW_OPTION_YES;
#endif
#else
  have_openssl= have_ssl= SHOW_OPTION_NO;
unknown's avatar
unknown committed
8584
#endif
unknown's avatar
unknown committed
8585
#ifdef HAVE_BROKEN_REALPATH
unknown's avatar
unknown committed
8586 8587 8588 8589
  have_symlink=SHOW_OPTION_NO;
#else
  have_symlink=SHOW_OPTION_YES;
#endif
8590 8591 8592 8593 8594
#ifdef HAVE_DLOPEN
  have_dlopen=SHOW_OPTION_YES;
#else
  have_dlopen=SHOW_OPTION_NO;
#endif
unknown's avatar
unknown committed
8595 8596 8597 8598 8599
#ifdef HAVE_QUERY_CACHE
  have_query_cache=SHOW_OPTION_YES;
#else
  have_query_cache=SHOW_OPTION_NO;
#endif
8600 8601 8602 8603 8604 8605 8606 8607 8608 8609
#ifdef HAVE_SPATIAL
  have_geometry=SHOW_OPTION_YES;
#else
  have_geometry=SHOW_OPTION_NO;
#endif
#ifdef HAVE_RTREE_KEYS
  have_rtree_keys=SHOW_OPTION_YES;
#else
  have_rtree_keys=SHOW_OPTION_NO;
#endif
unknown's avatar
unknown committed
8610 8611 8612 8613 8614 8615
#ifdef HAVE_CRYPT
  have_crypt=SHOW_OPTION_YES;
#else
  have_crypt=SHOW_OPTION_NO;
#endif
#ifdef HAVE_COMPRESS
8616
  have_compress= SHOW_OPTION_YES;
unknown's avatar
unknown committed
8617
#else
8618
  have_compress= SHOW_OPTION_NO;
unknown's avatar
unknown committed
8619 8620 8621 8622 8623 8624
#endif
#ifdef HAVE_LIBWRAP
  libwrapName= NullS;
#endif
#ifdef HAVE_OPENSSL
  des_key_file = 0;
Konstantin Osipov's avatar
Konstantin Osipov committed
8625
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
8626
  ssl_acceptor_fd= 0;
Konstantin Osipov's avatar
Konstantin Osipov committed
8627 8628
#endif /* ! EMBEDDED_LIBRARY */
#endif /* HAVE_OPENSSL */
unknown's avatar
unknown committed
8629 8630 8631 8632
#ifdef HAVE_SMEM
  shared_memory_base_name= default_shared_memory_base_name;
#endif

8633 8634
#if defined(__WIN__)
  /* Allow Win32 users to move MySQL anywhere */
unknown's avatar
unknown committed
8635 8636
  {
    char prg_dev[LIBLEN];
8637 8638 8639 8640 8641 8642 8643 8644 8645 8646 8647
    char executing_path_name[LIBLEN];
    if (!test_if_hard_path(my_progname))
    {
      // we don't want to use GetModuleFileName inside of my_path since
      // my_path is a generic path dereferencing function and here we care
      // only about the executing binary.
      GetModuleFileName(NULL, executing_path_name, sizeof(executing_path_name));
      my_path(prg_dev, executing_path_name, NULL);
    }
    else
      my_path(prg_dev, my_progname, "mysql/bin");
unknown's avatar
unknown committed
8648 8649 8650 8651 8652
    strcat(prg_dev,"/../");			// Remove 'bin' to get base dir
    cleanup_dirname(mysql_home,prg_dev);
  }
#else
  const char *tmpenv;
unknown's avatar
unknown committed
8653
  if (!(tmpenv = getenv("MY_BASEDIR_VERSION")))
unknown's avatar
unknown committed
8654
    tmpenv = DEFAULT_MYSQL_HOME;
8655
  strmake_buf(mysql_home, tmpenv);
Sergei Golubchik's avatar
Sergei Golubchik committed
8656
  mark_sys_var_value_origin(&mysql_home_ptr, sys_var::ENV);
8657
#endif
8658

Sergei Golubchik's avatar
Sergei Golubchik committed
8659
  if (wsrep_init_vars())
8660
    return 1;
8661

8662
  return 0;
unknown's avatar
unknown committed
8663 8664
}

8665
my_bool
8666
mysqld_get_one_option(int optid, const struct my_option *opt, char *argument)
unknown's avatar
unknown committed
8667
{
8668 8669 8670 8671 8672 8673
  if (opt->app_type)
  {
    sys_var *var= (sys_var*) opt->app_type;
    var->value_origin= sys_var::CONFIG;
  }

8674 8675
  switch(optid) {
  case '#':
8676
#ifndef DBUG_OFF
8677 8678 8679
    if (!argument)
      argument= (char*) default_dbug_option;
    if (argument[0] == '0' && !argument[1])
unknown's avatar
unknown committed
8680 8681 8682 8683
    {
      DEBUGGER_OFF;
      break;
    }
8684
    DEBUGGER_ON;
8685
    if (argument[0] == '1' && !argument[1])
unknown's avatar
unknown committed
8686
      break;
8687
    DBUG_SET_INITIAL(argument);
8688
    current_dbug_option= argument;
8689
    opt_endinfo=1;				/* unireg: memory allocation */
8690 8691
#else
    sql_print_warning("'%s' is disabled in this build", opt->name);
8692
#endif
8693
    break;
8694
  case OPT_DEPRECATED_OPTION:
Sergei Golubchik's avatar
Sergei Golubchik committed
8695 8696
    sql_print_warning("'%s' is deprecated. It does nothing and exists only "
                      "for compatiblity with old my.cnf files.",
8697 8698
                      opt->name);
    break;
8699 8700 8701 8702 8703 8704 8705 8706
  case OPT_MYSQL_COMPATIBILITY:
    sql_print_warning("'%s' is MySQL 5.6 compatible option. Not used or needed "
                      "in MariaDB.", opt->name);
    break;
  case OPT_MYSQL_TO_BE_IMPLEMENTED:
    sql_print_warning("'%s' is MySQL 5.6 compatible option. To be implemented "
                      "in later versions.", opt->name);
    break;
8707
  case 'a':
Sergei Golubchik's avatar
Sergei Golubchik committed
8708 8709
    SYSVAR_AUTOSIZE(global_system_variables.sql_mode, MODE_ANSI);
    SYSVAR_AUTOSIZE(global_system_variables.tx_isolation, ISO_SERIALIZABLE);
8710 8711
    break;
  case 'b':
8712
    strmake_buf(mysql_home, argument);
8713
    break;
8714
  case 'C':
8715 8716
    if (default_collation_name == compiled_default_collation_name)
      default_collation_name= 0;
8717
    break;
8718
  case 'h':
8719
    strmake_buf(mysql_real_data_home, argument);
8720
    /* Correct pointer set by my_getopt (for embedded library) */
8721
    mysql_real_data_home_ptr= mysql_real_data_home;
8722
    break;
8723
  case 'u':
8724
    if (!mysqld_user || !strcmp(mysqld_user, argument))
unknown's avatar
unknown committed
8725
      mysqld_user= argument;
8726
    else
8727
      sql_print_warning("Ignoring user change to '%s' because the user was set to '%s' earlier on the command line\n", argument, mysqld_user);
8728
    break;
8729
  case 'L':
8730
    strmake_buf(lc_messages_dir, argument);
8731
    break;
8732 8733
  case OPT_BINLOG_FORMAT:
    binlog_format_used= true;
8734
    break;
8735
#include <sslopt-case.h>
8736
#ifndef EMBEDDED_LIBRARY
8737 8738
  case 'V':
    print_version();
8739 8740
    opt_abort= 1;                    // Abort after parsing all options
    break;
8741
#endif /*EMBEDDED_LIBRARY*/
8742 8743 8744 8745 8746 8747 8748 8749
  case 'W':
    if (!argument)
      global_system_variables.log_warnings++;
    else if (argument == disabled_my_option)
      global_system_variables.log_warnings= 0L;
    else
      global_system_variables.log_warnings= atoi(argument);
    break;
8750 8751 8752 8753
  case 'T':
    test_flags= argument ? (uint) atoi(argument) : 0;
    opt_endinfo=1;
    break;
8754 8755 8756
  case OPT_THREAD_CONCURRENCY:
    WARN_DEPRECATED_NO_REPLACEMENT(NULL, "THREAD_CONCURRENCY");
    break;
8757 8758 8759 8760
  case (int) OPT_ISAM_LOG:
    opt_myisam_log=1;
    break;
  case (int) OPT_BIN_LOG:
8761
    opt_bin_log= MY_TEST(argument != disabled_my_option);
8762
    opt_bin_log_used= 1;
8763
    break;
8764 8765 8766 8767 8768 8769 8770 8771
  case (int) OPT_LOG_BASENAME:
  {
    if (opt_log_basename[0] == 0 || strchr(opt_log_basename, FN_EXTCHAR) ||
        strchr(opt_log_basename,FN_LIBCHAR))
    {
      sql_print_error("Wrong argument for --log-basename. It can't be empty or contain '.' or '" FN_DIRSEP "'");
      return 1;
    }
Sergei Golubchik's avatar
Sergei Golubchik committed
8772
    if (log_error_file_ptr != disabled_my_option)
Sergei Golubchik's avatar
Sergei Golubchik committed
8773
      SYSVAR_AUTOSIZE(log_error_file_ptr, opt_log_basename);
8774

Sergei Golubchik's avatar
Sergei Golubchik committed
8775 8776 8777 8778
    make_default_log_name(&opt_logname, ".log", false);
    make_default_log_name(&opt_slow_logname, "-slow.log", false);
    make_default_log_name(&opt_bin_logname, "-bin", true);
    make_default_log_name(&opt_binlog_index_name, "-bin.index", true);
Sergei Golubchik's avatar
Sergei Golubchik committed
8779 8780 8781 8782 8783 8784 8785
    mark_sys_var_value_origin(&opt_logname, sys_var::AUTO);
    mark_sys_var_value_origin(&opt_slow_logname, sys_var::AUTO);
    if (!opt_logname || !opt_slow_logname || !opt_bin_logname ||
        !opt_binlog_index_name)
      return 1;

#ifdef HAVE_REPLICATION
Sergei Golubchik's avatar
Sergei Golubchik committed
8786 8787
    make_default_log_name(&opt_relay_logname, "-relay-bin", true);
    make_default_log_name(&opt_relaylog_index_name, "-relay-bin.index", true);
Sergei Golubchik's avatar
Sergei Golubchik committed
8788 8789 8790 8791 8792
    mark_sys_var_value_origin(&opt_relay_logname, sys_var::AUTO);
    mark_sys_var_value_origin(&opt_relaylog_index_name, sys_var::AUTO);
    if (!opt_relay_logname || !opt_relaylog_index_name)
      return 1;
#endif
8793

Sergei Golubchik's avatar
Sergei Golubchik committed
8794
    SYSVAR_AUTOSIZE(pidfile_name_ptr, pidfile_name);
8795 8796 8797 8798
    strmake(pidfile_name, argument, sizeof(pidfile_name)-5);
    strmov(fn_ext(pidfile_name),".pid");

    /* check for errors */
Sergei Golubchik's avatar
Sergei Golubchik committed
8799
    if (!pidfile_name_ptr)
8800 8801 8802
      return 1;                                 // out of memory error
    break;
  }
unknown's avatar
SCRUM  
unknown committed
8803
#ifdef HAVE_REPLICATION
8804
  case (int)OPT_REPLICATE_IGNORE_DB:
8805
  {
8806
    cur_rpl_filter->add_ignore_db(argument);
8807 8808 8809 8810
    break;
  }
  case (int)OPT_REPLICATE_DO_DB:
  {
8811
    cur_rpl_filter->add_do_db(argument);
8812 8813 8814 8815
    break;
  }
  case (int)OPT_REPLICATE_REWRITE_DB:
  {
8816
    /* See also OPT_REWRITE_DB handling in client/mysqlbinlog.cc */
8817
    char* key = argument,*p, *val;
8818

8819
    if (!(p= strstr(argument, "->")))
8820
    {
8821 8822
      sql_print_error("Bad syntax in replicate-rewrite-db - missing '->'!\n");
      return 1;
8823
    }
8824
    val= p--;
unknown's avatar
unknown committed
8825
    while (my_isspace(mysqld_charset, *p) && p > argument)
8826 8827
      *p-- = 0;
    if (p == argument)
8828
    {
8829 8830
      sql_print_error("Bad syntax in replicate-rewrite-db - empty FROM db!\n");
      return 1;
8831
    }
8832 8833
    *val= 0;
    val+= 2;
unknown's avatar
unknown committed
8834
    while (*val && my_isspace(mysqld_charset, *val))
8835
      val++;
8836
    if (!*val)
8837
    {
8838 8839
      sql_print_error("Bad syntax in replicate-rewrite-db - empty TO db!\n");
      return 1;
8840 8841
    }

8842
    cur_rpl_filter->add_db_rewrite(key, val);
8843 8844
    break;
  }
8845 8846 8847 8848 8849 8850
  case (int)OPT_SLAVE_PARALLEL_MODE:
  {
    /* Store latest mode for Master::Info */
    cur_rpl_filter->set_parallel_mode(opt_slave_parallel_mode);
    break;
  }
8851

8852
  case (int)OPT_BINLOG_IGNORE_DB:
8853
  {
8854
    binlog_filter->add_ignore_db(argument);
8855 8856
    break;
  }
8857
  case (int)OPT_BINLOG_DO_DB:
8858
  {
8859
    binlog_filter->add_do_db(argument);
8860 8861
    break;
  }
8862
  case (int)OPT_REPLICATE_DO_TABLE:
8863
  {
8864
    if (cur_rpl_filter->add_do_table(argument))
8865
    {
8866 8867
      sql_print_error("Could not add do table rule '%s'!\n", argument);
      return 1;
8868
    }
8869 8870
    break;
  }
8871
  case (int)OPT_REPLICATE_WILD_DO_TABLE:
8872
  {
8873
    if (cur_rpl_filter->add_wild_do_table(argument))
8874
    {
8875 8876
      sql_print_error("Could not add do table rule '%s'!\n", argument);
      return 1;
8877
    }
8878 8879
    break;
  }
8880
  case (int)OPT_REPLICATE_WILD_IGNORE_TABLE:
8881
  {
8882
    if (cur_rpl_filter->add_wild_ignore_table(argument))
8883
    {
8884 8885
      sql_print_error("Could not add ignore table rule '%s'!\n", argument);
      return 1;
8886
    }
8887 8888
    break;
  }
8889
  case (int)OPT_REPLICATE_IGNORE_TABLE:
8890
  {
8891
    if (cur_rpl_filter->add_ignore_table(argument))
8892
    {
8893 8894
      sql_print_error("Could not add ignore table rule '%s'!\n", argument);
      return 1;
8895
    }
8896 8897
    break;
  }
unknown's avatar
SCRUM  
unknown committed
8898
#endif /* HAVE_REPLICATION */
8899
  case (int) OPT_SAFE:
8900
    opt_specialflag|= SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC;
Sergei Golubchik's avatar
Sergei Golubchik committed
8901 8902
    SYSVAR_AUTOSIZE(delay_key_write_options, (uint) DELAY_KEY_WRITE_NONE);
    SYSVAR_AUTOSIZE(myisam_recover_options, HA_RECOVER_DEFAULT);
8903
    ha_open_options&= ~(HA_OPEN_DELAY_KEY_WRITE);
unknown's avatar
unknown committed
8904
#ifdef HAVE_QUERY_CACHE
Sergei Golubchik's avatar
Sergei Golubchik committed
8905
    SYSVAR_AUTOSIZE(query_cache_size, 0);
8906
#endif
8907 8908
    sql_print_warning("The syntax '--safe-mode' is deprecated and will be "
                      "removed in a future release.");
8909 8910 8911 8912 8913
    break;
  case (int) OPT_SKIP_HOST_CACHE:
    opt_specialflag|= SPECIAL_NO_HOST_CACHE;
    break;
  case (int) OPT_SKIP_RESOLVE:
8914
    opt_skip_name_resolve= 1;
8915 8916 8917 8918 8919
    opt_specialflag|=SPECIAL_NO_RESOLVE;
    break;
  case (int) OPT_WANT_CORE:
    test_flags |= TEST_CORE_ON_SIGNAL;
    break;
8920 8921 8922 8923
  case OPT_CONSOLE:
    if (opt_console)
      opt_error_log= 0;			// Force logs to stdout
    break;
8924 8925 8926 8927 8928
  case OPT_BOOTSTRAP:
    opt_noacl=opt_bootstrap=1;
    break;
  case OPT_SERVER_ID:
    server_id_supplied = 1;
8929
    ::server_id= global_system_variables.server_id;
8930
    break;
unknown's avatar
unknown committed
8931
  case OPT_LOWER_CASE_TABLE_NAMES:
8932
    lower_case_table_names_used= 1;
unknown's avatar
unknown committed
8933
    break;
8934 8935 8936 8937 8938 8939 8940 8941 8942 8943 8944 8945 8946 8947 8948 8949
#if defined(ENABLED_DEBUG_SYNC)
  case OPT_DEBUG_SYNC_TIMEOUT:
    /*
      Debug Sync Facility. See debug_sync.cc.
      Default timeout for WAIT_FOR action.
      Default value is zero (facility disabled).
      If option is given without an argument, supply a non-zero value.
    */
    if (!argument)
    {
      /* purecov: begin tested */
      opt_debug_sync_timeout= DEBUG_SYNC_DEFAULT_WAIT_TIMEOUT;
      /* purecov: end */
    }
    break;
#endif /* defined(ENABLED_DEBUG_SYNC) */
8950 8951 8952 8953 8954 8955 8956 8957
  case OPT_LOG_ERROR:
    /*
      "No --log-error" == "write errors to stderr",
      "--log-error without argument" == "write errors to a file".
    */
    if (argument == NULL) /* no argument */
      log_error_file_ptr= const_cast<char*>("");
    break;
8958 8959 8960 8961 8962 8963 8964 8965 8966 8967 8968 8969 8970 8971
  case OPT_IGNORE_DB_DIRECTORY:
    if (*argument == 0)
      ignore_db_dirs_reset();
    else
    {
      if (push_ignored_db_dir(argument))
      {
        sql_print_error("Can't start server: "
                        "cannot process --ignore-db-dir=%.*s", 
                        FN_REFLEN, argument);
        return 1;
      }
    }
    break;
8972 8973 8974 8975 8976 8977 8978

  case OPT_PLUGIN_LOAD:
    free_list(opt_plugin_load_list_ptr);
    /* fall through */
  case OPT_PLUGIN_LOAD_ADD:
    opt_plugin_load_list_ptr->push_back(new i_string(argument));
    break;
8979 8980 8981
  case OPT_MAX_LONG_DATA_SIZE:
    max_long_data_size_used= true;
    break;
8982 8983
  case OPT_PFS_INSTRUMENT:
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
8984
#ifndef EMBEDDED_LIBRARY
8985 8986 8987 8988 8989 8990 8991 8992 8993 8994 8995 8996 8997 8998 8999 9000 9001 9002 9003 9004 9005 9006 9007 9008 9009 9010 9011 9012 9013 9014 9015 9016 9017 9018 9019 9020 9021 9022 9023 9024 9025 9026 9027 9028 9029 9030 9031 9032 9033 9034 9035 9036 9037 9038 9039 9040 9041 9042 9043 9044 9045 9046 9047
    /* Parse instrument name and value from argument string */
    char* name = argument,*p, *val;

    /* Assignment required */
    if (!(p= strchr(argument, '=')))
    {
       my_getopt_error_reporter(WARNING_LEVEL,
                             "Missing value for performance_schema_instrument "
                             "'%s'", argument);
      return 0;
    }

    /* Option value */
    val= p + 1;
    if (!*val)
    {
       my_getopt_error_reporter(WARNING_LEVEL,
                             "Missing value for performance_schema_instrument "
                             "'%s'", argument);
      return 0;
    }

    /* Trim leading spaces from instrument name */
    while (*name && my_isspace(mysqld_charset, *name))
      name++;

    /* Trim trailing spaces and slashes from instrument name */
    while (p > argument && (my_isspace(mysqld_charset, p[-1]) || p[-1] == '/'))
      p--;
    *p= 0;

    if (!*name)
    {
       my_getopt_error_reporter(WARNING_LEVEL,
                             "Invalid instrument name for "
                             "performance_schema_instrument '%s'", argument);
      return 0;
    }

    /* Trim leading spaces from option value */
    while (*val && my_isspace(mysqld_charset, *val))
      val++;

    /* Trim trailing spaces from option value */
    if ((p= my_strchr(mysqld_charset, val, val+strlen(val), ' ')) != NULL)
      *p= 0;

    if (!*val)
    {
       my_getopt_error_reporter(WARNING_LEVEL,
                             "Invalid value for performance_schema_instrument "
                             "'%s'", argument);
      return 0;
    }

    /* Add instrument name and value to array of configuration options */
    if (add_pfs_instr_to_array(name, val))
    {
       my_getopt_error_reporter(WARNING_LEVEL,
                             "Invalid value for performance_schema_instrument "
                             "'%s'", argument);
      return 0;
    }
9048
#endif /* EMBEDDED_LIBRARY */
9049 9050
#endif
    break;
unknown's avatar
unknown committed
9051
  }
9052 9053
  return 0;
}
9054

9055

unknown's avatar
unknown committed
9056
/** Handle arguments for multiple key caches. */
9057

9058
C_MODE_START
9059

9060
static void*
9061
mysql_getopt_value(const char *name, uint length,
9062
		   const struct my_option *option, int *error)
9063
{
9064 9065
  if (error)
    *error= 0;
9066 9067
  switch (option->id) {
  case OPT_KEY_BUFFER_SIZE:
unknown's avatar
unknown committed
9068
  case OPT_KEY_CACHE_BLOCK_SIZE:
9069 9070
  case OPT_KEY_CACHE_DIVISION_LIMIT:
  case OPT_KEY_CACHE_AGE_THRESHOLD:
9071
  case OPT_KEY_CACHE_PARTITIONS:
9072
  case OPT_KEY_CACHE_CHANGED_BLOCKS_HASH_SIZE:
9073
  {
unknown's avatar
unknown committed
9074
    KEY_CACHE *key_cache;
9075
    if (!(key_cache= get_or_create_key_cache(name, length)))
9076 9077 9078 9079 9080
    {
      if (error)
        *error= EXIT_OUT_OF_MEMORY;
      return 0;
    }
9081 9082
    switch (option->id) {
    case OPT_KEY_BUFFER_SIZE:
9083
      return &key_cache->param_buff_size;
9084
    case OPT_KEY_CACHE_BLOCK_SIZE:
9085
      return &key_cache->param_block_size;
9086
    case OPT_KEY_CACHE_DIVISION_LIMIT:
9087
      return &key_cache->param_division_limit;
9088
    case OPT_KEY_CACHE_AGE_THRESHOLD:
9089
      return &key_cache->param_age_threshold;
9090 9091
    case OPT_KEY_CACHE_PARTITIONS:
      return (uchar**) &key_cache->param_partitions;
9092 9093
    case OPT_KEY_CACHE_CHANGED_BLOCKS_HASH_SIZE:
      return (uchar**) &key_cache->changed_blocks_hash_size;
9094
    }
9095
  }
9096
#ifdef HAVE_REPLICATION
9097 9098 9099 9100 9101 9102 9103
  case OPT_REPLICATE_DO_DB:
  case OPT_REPLICATE_DO_TABLE:
  case OPT_REPLICATE_IGNORE_DB:
  case OPT_REPLICATE_IGNORE_TABLE:
  case OPT_REPLICATE_WILD_DO_TABLE:
  case OPT_REPLICATE_WILD_IGNORE_TABLE:
  case OPT_REPLICATE_REWRITE_DB:
9104
  case OPT_SLAVE_PARALLEL_MODE:
9105 9106 9107 9108 9109 9110 9111
  {
    /* Store current filter for mysqld_get_one_option() */
    if (!(cur_rpl_filter= get_or_create_rpl_filter(name, length)))
    {
      if (error)
        *error= EXIT_OUT_OF_MEMORY;
    }
9112
    if (option->id == OPT_SLAVE_PARALLEL_MODE)
9113
    {
9114 9115 9116 9117 9118
      /*
        Ensure parallel_mode variable is shown in --help. The other
        variables are not easily printable here.
       */
      return (char**) &opt_slave_parallel_mode;
9119
    }
9120
    return 0;
9121 9122
  }
#endif
9123
  }
9124
  return option->value;
9125 9126
}

9127
static void option_error_reporter(enum loglevel level, const char *format, ...)
unknown's avatar
unknown committed
9128
{
9129
  va_list args;
unknown's avatar
unknown committed
9130
  va_start(args, format);
9131 9132 9133 9134 9135 9136 9137

  /* Don't print warnings for --loose options during bootstrap */
  if (level == ERROR_LEVEL || !opt_bootstrap ||
      global_system_variables.log_warnings)
  {
    vprint_msg_to_log(level, format, args);
  }
unknown's avatar
unknown committed
9138
  va_end(args);
unknown's avatar
unknown committed
9139
}
9140

9141
C_MODE_END
unknown's avatar
unknown committed
9142

unknown's avatar
unknown committed
9143
/**
Marc Alff's avatar
Marc Alff committed
9144 9145 9146 9147 9148 9149
  Get server options from the command line,
  and perform related server initializations.
  @param [in, out] argc_ptr       command line options (count)
  @param [in, out] argv_ptr       command line options (values)
  @return 0 on success

unknown's avatar
unknown committed
9150 9151 9152
  @todo
  - FIXME add EXIT_TOO_MANY_ARGUMENTS to "mysys_err.h" and return that code?
*/
Marc Alff's avatar
Marc Alff committed
9153
static int get_options(int *argc_ptr, char ***argv_ptr)
9154 9155 9156
{
  int ho_error;

9157
  my_getopt_register_get_addr(mysql_getopt_value);
9158
  my_getopt_error_reporter= option_error_reporter;
unknown's avatar
unknown committed
9159

Marc Alff's avatar
Marc Alff committed
9160 9161 9162
  /* prepare all_options array */
  my_init_dynamic_array(&all_options, sizeof(my_option),
                        array_elements(my_long_options),
9163
                        array_elements(my_long_options)/4, MYF(0));
9164
  add_many_options(&all_options, my_long_options, array_elements(my_long_options));
9165
  sys_var_add_options(&all_options, 0);
Marc Alff's avatar
Marc Alff committed
9166
  add_terminator(&all_options);
9167

unknown's avatar
unknown committed
9168 9169 9170
  /* Skip unknown options so that they may be processed later by plugins */
  my_getopt_skip_unknown= TRUE;

Marc Alff's avatar
Marc Alff committed
9171
  if ((ho_error= handle_options(argc_ptr, argv_ptr, (my_option*)(all_options.buffer),
9172
                                mysqld_get_one_option)))
9173
    return ho_error;
9174 9175 9176

  if (!opt_help)
    delete_dynamic(&all_options);
9177 9178
  else
    opt_abort= 1;
9179

Marc Alff's avatar
Marc Alff committed
9180 9181 9182
  /* Add back the program name handle_options removes */
  (*argc_ptr)++;
  (*argv_ptr)--;
9183

9184 9185 9186 9187 9188 9189
  /*
    Options have been parsed. Now some of them need additional special
    handling, like custom value checking, checking of incompatibilites
    between options, setting of multiple variables, etc.
    Do them here.
  */
9190

9191 9192
  if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes ||
       opt_log_slow_slave_statements) &&
Monty's avatar
Monty committed
9193
      !global_system_variables.sql_log_slow)
9194
    sql_print_warning("options --log-slow-admin-statements, --log-queries-not-using-indexes and --log-slow-slave-statements have no effect if --log_slow_queries is not set");
9195 9196 9197 9198 9199 9200 9201 9202
  if (global_system_variables.net_buffer_length > 
      global_system_variables.max_allowed_packet)
  {
    sql_print_warning("net_buffer_length (%lu) is set to be larger "
                      "than max_allowed_packet (%lu). Please rectify.",
                      global_system_variables.net_buffer_length, 
                      global_system_variables.max_allowed_packet);
  }
9203

9204 9205 9206 9207 9208 9209 9210 9211 9212 9213 9214 9215 9216 9217 9218 9219 9220 9221 9222
  if (log_error_file_ptr != disabled_my_option)
    opt_error_log= 1;
  else
    log_error_file_ptr= const_cast<char*>("");

  opt_init_connect.length=strlen(opt_init_connect.str);
  opt_init_slave.length=strlen(opt_init_slave.str);

  if (global_system_variables.low_priority_updates)
    thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY;

  if (ft_boolean_check_syntax_string((uchar*) ft_boolean_syntax))
  {
    sql_print_error("Invalid ft-boolean-syntax string: %s\n",
                    ft_boolean_syntax);
    return 1;
  }

  if (opt_disable_networking)
Sergei Golubchik's avatar
Sergei Golubchik committed
9223
    mysqld_port= mysqld_extra_port= 0;
9224

9225 9226 9227 9228 9229 9230 9231 9232 9233 9234 9235 9236 9237 9238 9239 9240
  if (opt_skip_show_db)
    opt_specialflag|= SPECIAL_SKIP_SHOW_DB;

  if (myisam_flush)
    flush_time= 0;

#ifdef HAVE_REPLICATION
  if (opt_slave_skip_errors)
    init_slave_skip_errors(opt_slave_skip_errors);
#endif

  if (global_system_variables.max_join_size == HA_POS_ERROR)
    global_system_variables.option_bits|= OPTION_BIG_SELECTS;
  else
    global_system_variables.option_bits&= ~OPTION_BIG_SELECTS;

9241
  if (!opt_bootstrap && WSREP_PROVIDER_EXISTS &&
9242 9243
      global_system_variables.binlog_format != BINLOG_FORMAT_ROW)
  {
9244 9245 9246 9247 9248 9249 9250

    WSREP_ERROR ("Only binlog_format = 'ROW' is currently supported. "
                 "Configured value: '%s'. Please adjust your configuration.",
                 binlog_format_names[global_system_variables.binlog_format]);
    return 1;
  }

9251 9252 9253 9254 9255 9256
  // Synchronize @@global.autocommit on --autocommit
  const ulonglong turn_bit_on= opt_autocommit ?
    OPTION_AUTOCOMMIT : OPTION_NOT_AUTOCOMMIT;
  global_system_variables.option_bits=
    (global_system_variables.option_bits &
     ~(OPTION_NOT_AUTOCOMMIT | OPTION_AUTOCOMMIT)) | turn_bit_on;
9257 9258 9259

  global_system_variables.sql_mode=
    expand_sql_mode(global_system_variables.sql_mode);
Sergei Golubchik's avatar
Sergei Golubchik committed
9260
#if !defined(HAVE_REALPATH) || defined(HAVE_BROKEN_REALPATH)
9261 9262 9263 9264 9265 9266 9267 9268 9269 9270
  my_use_symdir=0;
  my_disable_symlinks=1;
  have_symlink=SHOW_OPTION_NO;
#else
  if (!my_use_symdir)
  {
    my_disable_symlinks=1;
    have_symlink=SHOW_OPTION_DISABLED;
  }
#endif
9271 9272 9273
  if (opt_debugging)
  {
    /* Allow break with SIGINT, no core or stack trace */
Michael Widenius's avatar
Michael Widenius committed
9274 9275
    test_flags|= TEST_SIGINT;
    opt_stack_trace= 1;
9276 9277
    test_flags&= ~TEST_CORE_ON_SIGNAL;
  }
9278
  /* Set global MyISAM variables from delay_key_write_options */
9279
  fix_delay_key_write(0, 0, OPT_GLOBAL);
9280

9281
#ifndef EMBEDDED_LIBRARY
9282 9283
  if (mysqld_chroot)
    set_root(mysqld_chroot);
9284
#else
Sergei Golubchik's avatar
Sergei Golubchik committed
9285
  SYSVAR_AUTOSIZE(thread_handling, SCHEDULER_NO_THREADS);
9286 9287
  max_allowed_packet= global_system_variables.max_allowed_packet;
  net_buffer_length= global_system_variables.net_buffer_length;
9288
#endif
9289 9290
  if (fix_paths())
    return 1;
unknown's avatar
unknown committed
9291

unknown's avatar
unknown committed
9292 9293 9294 9295
  /*
    Set some global variables from the global_system_variables
    In most cases the global variables will not be used
  */
9296
  my_disable_locking= myisam_single_user= MY_TEST(opt_external_locking == 0);
unknown's avatar
unknown committed
9297
  my_default_record_cache_size=global_system_variables.read_buff_size;
unknown's avatar
unknown committed
9298

9299
  /*
9300 9301 9302
    Log mysys errors when we don't have a thd or thd->log_all_errors is set
    (recovery) to the log.  This is mainly useful for debugging strange system
    errors.
9303 9304 9305 9306 9307 9308
  */
  if (global_system_variables.log_warnings >= 10)
    my_global_flags= MY_WME | ME_JUST_INFO;
  /* Log all errors not handled by thd->handle_error() to my_message_sql() */
  if (global_system_variables.log_warnings >= 11)
    my_global_flags|= ME_NOREFRESH;
9309 9310
  if (my_assert_on_error)
    debug_assert_if_crashed_table= 1;
9311

9312
  global_system_variables.long_query_time= (ulonglong)
Monty's avatar
Monty committed
9313 9314 9315
    (global_system_variables.long_query_time_double * 1e6 + 0.1);
  global_system_variables.max_statement_time= (ulonglong)
    (global_system_variables.max_statement_time_double * 1e6 + 0.1);
9316

9317 9318
  if (opt_short_log_format)
    opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT;
9319

9320
  if (init_global_datetime_format(MYSQL_TIMESTAMP_DATE,
9321
                                  &global_date_format) ||
9322
      init_global_datetime_format(MYSQL_TIMESTAMP_TIME,
9323
                                  &global_time_format) ||
9324
      init_global_datetime_format(MYSQL_TIMESTAMP_DATETIME,
9325
                                  &global_datetime_format))
9326
    return 1;
9327

unknown's avatar
unknown committed
9328
#ifdef EMBEDDED_LIBRARY
Sergei Golubchik's avatar
Sergei Golubchik committed
9329 9330
  one_thread_scheduler(thread_scheduler);
  one_thread_scheduler(extra_thread_scheduler);
unknown's avatar
unknown committed
9331
#else
9332 9333 9334 9335 9336

#ifdef _WIN32
  /* workaround: disable thread pool on XP */
  if (GetProcAddress(GetModuleHandle("kernel32"),"CreateThreadpool") == 0 &&
      thread_handling > SCHEDULER_NO_THREADS)
Sergei Golubchik's avatar
Sergei Golubchik committed
9337
    SYSVAR_AUTOSIZE(thread_handling, SCHEDULER_ONE_THREAD_PER_CONNECTION);
9338 9339
#endif

9340
  if (thread_handling <= SCHEDULER_ONE_THREAD_PER_CONNECTION)
Sergei Golubchik's avatar
Sergei Golubchik committed
9341
    one_thread_per_connection_scheduler(thread_scheduler, &max_connections,
9342
                                        &connection_count);
9343
  else if (thread_handling == SCHEDULER_NO_THREADS)
Sergei Golubchik's avatar
Sergei Golubchik committed
9344
    one_thread_scheduler(thread_scheduler);
unknown's avatar
unknown committed
9345
  else
9346 9347 9348
    pool_of_threads_scheduler(thread_scheduler,  &max_connections,
                                        &connection_count); 

Sergei Golubchik's avatar
Sergei Golubchik committed
9349
  one_thread_per_connection_scheduler(extra_thread_scheduler,
9350 9351
                                      &extra_max_connections,
                                      &extra_connection_count);
unknown's avatar
unknown committed
9352
#endif
9353

9354 9355
  opt_readonly= read_only;

9356 9357 9358 9359 9360
  /*
    If max_long_data_size is not specified explicitly use
    value of max_allowed_packet.
  */
  if (!max_long_data_size_used)
Sergei Golubchik's avatar
Sergei Golubchik committed
9361 9362
    SYSVAR_AUTOSIZE(max_long_data_size,
                    global_system_variables.max_allowed_packet);
9363

9364
  /* Remember if max_user_connections was 0 at startup */
Sergei Golubchik's avatar
Sergei Golubchik committed
9365
  max_user_connections_checking= global_system_variables.max_user_connections != 0;
9366

Sergei Golubchik's avatar
Sergei Golubchik committed
9367
#ifdef HAVE_REPLICATION
9368 9369 9370 9371
  {
    sys_var *max_relay_log_size_var, *max_binlog_size_var;
    /* If max_relay_log_size is 0, then set it to max_binlog_size */
    if (!global_system_variables.max_relay_log_size)
Sergei Golubchik's avatar
Sergei Golubchik committed
9372 9373
      SYSVAR_AUTOSIZE(global_system_variables.max_relay_log_size,
                      max_binlog_size);
9374 9375 9376 9377 9378 9379

    /*
      Fix so that DEFAULT and limit checking works with max_relay_log_size
      (Yes, this is a hack, but it's required as the definition of
      max_relay_log_size allows it to be set to 0).
    */
Sergei Golubchik's avatar
Sergei Golubchik committed
9380 9381
    max_relay_log_size_var= intern_find_sys_var(STRING_WITH_LEN("max_relay_log_size"));
    max_binlog_size_var= intern_find_sys_var(STRING_WITH_LEN("max_binlog_size"));
Sergei Golubchik's avatar
Sergei Golubchik committed
9382 9383 9384 9385 9386 9387 9388
    if (max_binlog_size_var && max_relay_log_size_var)
    {
      max_relay_log_size_var->option.min_value=
        max_binlog_size_var->option.min_value; 
      max_relay_log_size_var->option.def_value=
        max_binlog_size_var->option.def_value;
    }
9389
  }
Sergei Golubchik's avatar
Sergei Golubchik committed
9390
#endif
9391 9392 9393

  /* Ensure that some variables are not set higher than needed */
  if (back_log > max_connections)
Sergei Golubchik's avatar
Sergei Golubchik committed
9394
    SYSVAR_AUTOSIZE(back_log, max_connections);
9395
  if (thread_cache_size > max_connections)
Sergei Golubchik's avatar
Sergei Golubchik committed
9396
    SYSVAR_AUTOSIZE(thread_cache_size, max_connections);
9397
  
9398
  return 0;
unknown's avatar
unknown committed
9399 9400 9401
}


9402 9403 9404 9405 9406 9407 9408
/*
  Create version name for running mysqld version
  We automaticly add suffixes -debug, -embedded and -log to the version
  name to make the version more descriptive.
  (MYSQL_SERVER_SUFFIX is set by the compilation environment)
*/

Michael Widenius's avatar
Michael Widenius committed
9409
void set_server_version(void)
9410 9411
{
  char *end= strxmov(server_version, MYSQL_SERVER_VERSION,
9412
                     MYSQL_SERVER_SUFFIX_STR, NullS);
9413 9414 9415
#ifdef EMBEDDED_LIBRARY
  end= strmov(end, "-embedded");
#endif
9416 9417 9418
#ifdef WITH_WSREP
  end= strmov(end, "-wsrep");
#endif
9419
#ifndef DBUG_OFF
9420
  if (!strstr(MYSQL_SERVER_SUFFIX_STR, "-debug"))
9421 9422
    end= strmov(end, "-debug");
#endif
Monty's avatar
Monty committed
9423
  if (opt_log || global_system_variables.sql_log_slow || opt_bin_log)
9424 9425 9426 9427
    strmov(end, "-log");                        // This may slow down system
}


unknown's avatar
unknown committed
9428 9429 9430
static char *get_relative_path(const char *path)
{
  if (test_if_hard_path(path) &&
9431
      is_prefix(path,DEFAULT_MYSQL_HOME) &&
unknown's avatar
unknown committed
9432 9433
      strcmp(DEFAULT_MYSQL_HOME,FN_ROOTDIR))
  {
unknown's avatar
unknown committed
9434
    path+=(uint) strlen(DEFAULT_MYSQL_HOME);
9435
    while (*path == FN_LIBCHAR || *path == FN_LIBCHAR2)
unknown's avatar
unknown committed
9436 9437 9438 9439 9440 9441
      path++;
  }
  return (char*) path;
}


unknown's avatar
unknown committed
9442
/**
9443 9444
  Fix filename and replace extension where 'dir' is relative to
  mysql_real_data_home.
unknown's avatar
unknown committed
9445 9446
  @return
    1 if len(path) > FN_REFLEN
9447 9448 9449
*/

bool
9450
fn_format_relative_to_data_home(char * to, const char *name,
9451 9452 9453 9454 9455 9456 9457 9458 9459 9460
				const char *dir, const char *extension)
{
  char tmp_path[FN_REFLEN];
  if (!test_if_hard_path(dir))
  {
    strxnmov(tmp_path,sizeof(tmp_path)-1, mysql_real_data_home,
	     dir, NullS);
    dir=tmp_path;
  }
  return !fn_format(to, name, dir, extension,
9461
		    MY_APPEND_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH);
9462 9463 9464
}


9465 9466 9467 9468 9469 9470 9471 9472 9473 9474 9475 9476 9477 9478
/**
  Test a file path to determine if the path is compatible with the secure file
  path restriction.
 
  @param path null terminated character string

  @return
    @retval TRUE The path is secure
    @retval FALSE The path isn't secure
*/

bool is_secure_file_path(char *path)
{
  char buff1[FN_REFLEN], buff2[FN_REFLEN];
9479
  size_t opt_secure_file_priv_len;
9480 9481 9482 9483 9484 9485
  /*
    All paths are secure if opt_secure_file_path is 0
  */
  if (!opt_secure_file_priv)
    return TRUE;

9486 9487
  opt_secure_file_priv_len= strlen(opt_secure_file_priv);

Georgi Kodinov's avatar
Georgi Kodinov committed
9488 9489 9490
  if (strlen(path) >= FN_REFLEN)
    return FALSE;

9491 9492 9493 9494 9495
  if (my_realpath(buff1, path, 0))
  {
    /*
      The supplied file path might have been a file and not a directory.
    */
Michael Widenius's avatar
Michael Widenius committed
9496
    size_t length= dirname_length(path);        // Guaranteed to be < FN_REFLEN
9497 9498 9499 9500 9501 9502
    memcpy(buff2, path, length);
    buff2[length]= '\0';
    if (length == 0 || my_realpath(buff1, buff2, 0))
      return FALSE;
  }
  convert_dirname(buff2, buff1, NullS);
9503 9504 9505 9506 9507 9508 9509 9510 9511 9512 9513 9514 9515 9516
  if (!lower_case_file_system)
  {
    if (strncmp(opt_secure_file_priv, buff2, opt_secure_file_priv_len))
      return FALSE;
  }
  else
  {
    if (files_charset_info->coll->strnncoll(files_charset_info,
                                            (uchar *) buff2, strlen(buff2),
                                            (uchar *) opt_secure_file_priv,
                                            opt_secure_file_priv_len,
                                            TRUE))
      return FALSE;
  }
9517 9518 9519
  return TRUE;
}

Michael Widenius's avatar
Michael Widenius committed
9520

9521
static int fix_paths(void)
unknown's avatar
unknown committed
9522
{
9523
  char buff[FN_REFLEN],*pos;
9524 9525
  DBUG_ENTER("fix_paths");

9526
  convert_dirname(mysql_home,mysql_home,NullS);
9527
  /* Resolve symlinks to allow 'mysql_home' to be a relative symlink */
9528
  my_realpath(mysql_home,mysql_home,MYF(0));
9529 9530 9531 9532 9533 9534 9535
  /* Ensure that mysql_home ends in FN_LIBCHAR */
  pos=strend(mysql_home);
  if (pos[-1] != FN_LIBCHAR)
  {
    pos[0]= FN_LIBCHAR;
    pos[1]= 0;
  }
9536
  convert_dirname(lc_messages_dir, lc_messages_dir, NullS);
9537
  convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
unknown's avatar
unknown committed
9538 9539
  (void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir
  (void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home);
9540
  (void) my_load_path(pidfile_name, pidfile_name_ptr, mysql_real_data_home);
Marc Alff's avatar
Marc Alff committed
9541

Sergei Golubchik's avatar
Sergei Golubchik committed
9542 9543 9544
  convert_dirname(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr : 
                                  get_relative_path(PLUGINDIR), NullS);
  (void) my_load_path(opt_plugin_dir, opt_plugin_dir, mysql_home);
9545
  opt_plugin_dir_ptr= opt_plugin_dir;
Sergei Golubchik's avatar
Sergei Golubchik committed
9546
  pidfile_name_ptr= pidfile_name;
unknown's avatar
unknown committed
9547

9548 9549 9550 9551 9552 9553
  my_realpath(mysql_unpacked_real_data_home, mysql_real_data_home, MYF(0));
  mysql_unpacked_real_data_home_len= 
    (int) strlen(mysql_unpacked_real_data_home);
  if (mysql_unpacked_real_data_home[mysql_unpacked_real_data_home_len-1] == FN_LIBCHAR)
    --mysql_unpacked_real_data_home_len;

unknown's avatar
unknown committed
9554
  char *sharedir=get_relative_path(SHAREDIR);
unknown's avatar
unknown committed
9555
  if (test_if_hard_path(sharedir))
9556
    strmake_buf(buff, sharedir);		/* purecov: tested */
unknown's avatar
unknown committed
9557
  else
unknown's avatar
unknown committed
9558
    strxnmov(buff,sizeof(buff)-1,mysql_home,sharedir,NullS);
9559
  convert_dirname(buff,buff,NullS);
9560
  (void) my_load_path(lc_messages_dir, lc_messages_dir, buff);
unknown's avatar
unknown committed
9561 9562

  /* If --character-sets-dir isn't given, use shared library dir */
9563
  if (charsets_dir)
Sergei Golubchik's avatar
Sergei Golubchik committed
9564
  {
9565
    strmake_buf(mysql_charsets_dir, charsets_dir);
Sergei Golubchik's avatar
Sergei Golubchik committed
9566 9567
    charsets_dir= mysql_charsets_dir;
  }
9568
  else
Sergei Golubchik's avatar
Sergei Golubchik committed
9569
  {
unknown's avatar
unknown committed
9570 9571
    strxnmov(mysql_charsets_dir, sizeof(mysql_charsets_dir)-1, buff,
	     CHARSET_DIR, NullS);
Sergei Golubchik's avatar
Sergei Golubchik committed
9572 9573
    SYSVAR_AUTOSIZE(charsets_dir, mysql_charsets_dir);
  }
unknown's avatar
unknown committed
9574
  (void) my_load_path(mysql_charsets_dir, mysql_charsets_dir, buff);
9575
  convert_dirname(mysql_charsets_dir, mysql_charsets_dir, NullS);
unknown's avatar
unknown committed
9576

unknown's avatar
unknown committed
9577
  if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir))
9578
    DBUG_RETURN(1);
9579 9580
  if (!opt_mysql_tmpdir)
    opt_mysql_tmpdir= mysql_tmpdir;
unknown's avatar
SCRUM  
unknown committed
9581
#ifdef HAVE_REPLICATION
9582
  if (!slave_load_tmpdir)
Sergei Golubchik's avatar
Sergei Golubchik committed
9583
    SYSVAR_AUTOSIZE(slave_load_tmpdir, mysql_tmpdir);
9584
#endif /* HAVE_REPLICATION */
9585 9586 9587
  /*
    Convert the secure-file-priv option to system format, allowing
    a quick strcmp to check if read or write is in an allowed dir
Michael Widenius's avatar
Michael Widenius committed
9588
  */
9589 9590
  if (opt_secure_file_priv)
  {
9591 9592
    if (*opt_secure_file_priv == 0)
    {
9593
      my_free(opt_secure_file_priv);
9594 9595 9596 9597
      opt_secure_file_priv= 0;
    }
    else
    {
9598 9599
      if (strlen(opt_secure_file_priv) >= FN_REFLEN)
        opt_secure_file_priv[FN_REFLEN-1]= '\0';
9600
      if (my_realpath(buff, opt_secure_file_priv, 0))
9601 9602
      {
        sql_print_warning("Failed to normalize the argument for --secure-file-priv.");
9603
        DBUG_RETURN(1);
9604
      }
9605
      char *secure_file_real_path= (char *)my_malloc(FN_REFLEN, MYF(MY_FAE));
9606
      convert_dirname(secure_file_real_path, buff, NullS);
9607
      my_free(opt_secure_file_priv);
9608 9609
      opt_secure_file_priv= secure_file_real_path;
    }
9610
  }
9611
  DBUG_RETURN(0);
unknown's avatar
unknown committed
9612 9613
}

unknown's avatar
unknown committed
9614 9615
/**
  Check if file system used for databases is case insensitive.
9616

unknown's avatar
unknown committed
9617
  @param dir_name			Directory to test
9618

9619 9620 9621
  @retval -1  Don't know (Test failed)
  @retval  0   File system is case sensitive
  @retval  1   File system is case insensitive
9622 9623 9624 9625 9626 9627 9628 9629
*/

static int test_if_case_insensitive(const char *dir_name)
{
  int result= 0;
  File file;
  char buff[FN_REFLEN], buff2[FN_REFLEN];
  MY_STAT stat_info;
9630
  DBUG_ENTER("test_if_case_insensitive");
9631 9632 9633 9634 9635

  fn_format(buff, glob_hostname, dir_name, ".lower-test",
	    MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_REPLACE_DIR);
  fn_format(buff2, glob_hostname, dir_name, ".LOWER-TEST",
	    MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_REPLACE_DIR);
Marc Alff's avatar
Marc Alff committed
9636 9637 9638
  mysql_file_delete(key_file_casetest, buff2, MYF(0));
  if ((file= mysql_file_create(key_file_casetest,
                               buff, 0666, O_RDWR, MYF(0))) < 0)
9639
  {
9640
    if (!opt_abort)
9641
      sql_print_warning("Can't create test file %s", buff);
9642
    DBUG_RETURN(-1);
9643
  }
Marc Alff's avatar
Marc Alff committed
9644 9645
  mysql_file_close(file, MYF(0));
  if (mysql_file_stat(key_file_casetest, buff2, &stat_info, MYF(0)))
9646
    result= 1;					// Can access file
Marc Alff's avatar
Marc Alff committed
9647
  mysql_file_delete(key_file_casetest, buff, MYF(MY_WME));
9648 9649
  DBUG_PRINT("exit", ("result: %d", result));
  DBUG_RETURN(result);
9650 9651 9652
}


9653 9654
#ifndef EMBEDDED_LIBRARY

unknown's avatar
unknown committed
9655 9656 9657
/**
  Create file to store pid number.
*/
9658 9659 9660
static void create_pid_file()
{
  File file;
Marc Alff's avatar
Marc Alff committed
9661 9662
  if ((file= mysql_file_create(key_file_pid, pidfile_name, 0664,
                               O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0)
9663
  {
9664
    char buff[MAX_BIGINT_WIDTH + 1], *end;
9665
    end= int10_to_str((long) getpid(), buff, 10);
unknown's avatar
unknown committed
9666
    *end++= '\n';
Marc Alff's avatar
Marc Alff committed
9667 9668
    if (!mysql_file_write(file, (uchar*) buff, (uint) (end-buff),
                          MYF(MY_WME | MY_NABP)))
9669
    {
Marc Alff's avatar
Marc Alff committed
9670
      mysql_file_close(file, MYF(0));
9671
      pid_file_created= true;
9672 9673
      return;
    }
Marc Alff's avatar
Marc Alff committed
9674
    mysql_file_close(file, MYF(0));
9675
  }
9676
  sql_perror("Can't start server: can't create PID file");
unknown's avatar
foo1  
unknown committed
9677
  exit(1);
9678
}
9679
#endif /* EMBEDDED_LIBRARY */
9680

Marc Alff's avatar
Marc Alff committed
9681

9682 9683 9684 9685 9686
/**
  Remove the process' pid file.
  
  @param  flags  file operation flags
*/
Marc Alff's avatar
Marc Alff committed
9687

9688 9689 9690 9691 9692 9693 9694 9695 9696 9697 9698
static void delete_pid_file(myf flags)
{
#ifndef EMBEDDED_LIBRARY
  if (pid_file_created)
  {
    mysql_file_delete(key_file_pid, pidfile_name, flags);
    pid_file_created= false;
  }
#endif /* EMBEDDED_LIBRARY */
  return;
}
Marc Alff's avatar
Marc Alff committed
9699 9700


unknown's avatar
unknown committed
9701
/** Clear most status variables. */
9702 9703
void refresh_status(THD *thd)
{
Marc Alff's avatar
Marc Alff committed
9704
  mysql_mutex_lock(&LOCK_status);
9705

9706
  /* Add thread's status variabes to global status */
9707
  add_to_status(&global_status_var, &thd->status_var);
9708 9709

  /* Reset thread's status variables */
9710
  thd->set_status_var_init();
9711 9712
  bzero((uchar*) &thd->org_status_var, sizeof(thd->org_status_var)); 
  thd->start_bytes_received= 0;
9713

9714
  /* Reset some global variables */
unknown's avatar
unknown committed
9715
  reset_status_vars();
9716 9717 9718 9719
#ifdef WITH_WSREP
  if (WSREP_ON)
    wsrep->stats_reset(wsrep);
#endif /* WITH_WSREP */
9720

9721
  /* Reset the counters of all key caches (default and named). */
9722
  process_key_caches(reset_key_cache_counters, 0);
9723
  flush_status_time= time((time_t*) 0);
Marc Alff's avatar
Marc Alff committed
9724
  mysql_mutex_unlock(&LOCK_status);
9725 9726 9727

  /*
    Set max_used_connections to the number of currently open
Michael Widenius's avatar
Michael Widenius committed
9728
    connections.  This is not perfect, but status data is not exact anyway.
9729 9730
  */
  max_used_connections= thread_count-delayed_insert_threads;
9731 9732
}

Sergei Golubchik's avatar
Sergei Golubchik committed
9733 9734 9735 9736 9737 9738 9739 9740 9741 9742 9743 9744 9745 9746 9747 9748 9749 9750 9751 9752 9753 9754 9755 9756 9757 9758 9759 9760 9761 9762 9763 9764 9765
#ifdef HAVE_PSI_INTERFACE
static PSI_file_info all_server_files[]=
{
#ifdef HAVE_MMAP
  { &key_file_map, "map", 0},
#endif /* HAVE_MMAP */
  { &key_file_binlog, "binlog", 0},
  { &key_file_binlog_index, "binlog_index", 0},
  { &key_file_relaylog, "relaylog", 0},
  { &key_file_relaylog_index, "relaylog_index", 0},
  { &key_file_casetest, "casetest", 0},
  { &key_file_dbopt, "dbopt", 0},
  { &key_file_des_key_file, "des_key_file", 0},
  { &key_file_ERRMSG, "ERRMSG", 0},
  { &key_select_to_file, "select_to_file", 0},
  { &key_file_fileparser, "file_parser", 0},
  { &key_file_frm, "FRM", 0},
  { &key_file_global_ddl_log, "global_ddl_log", 0},
  { &key_file_load, "load", 0},
  { &key_file_loadfile, "LOAD_FILE", 0},
  { &key_file_log_event_data, "log_event_data", 0},
  { &key_file_log_event_info, "log_event_info", 0},
  { &key_file_master_info, "master_info", 0},
  { &key_file_misc, "misc", 0},
  { &key_file_partition, "partition", 0},
  { &key_file_pid, "pid", 0},
  { &key_file_query_log, "query_log", 0},
  { &key_file_relay_log_info, "relay_log_info", 0},
  { &key_file_send_file, "send_file", 0},
  { &key_file_slow_log, "slow_log", 0},
  { &key_file_tclog, "tclog", 0},
  { &key_file_trg, "trigger_name", 0},
  { &key_file_trn, "trigger", 0},
unknown's avatar
unknown committed
9766 9767
  { &key_file_init, "init", 0},
  { &key_file_binlog_state, "binlog_state", 0}
Sergei Golubchik's avatar
Sergei Golubchik committed
9768 9769 9770
};
#endif /* HAVE_PSI_INTERFACE */

9771
PSI_stage_info stage_after_apply_event= { 0, "after apply log event", 0};
9772
PSI_stage_info stage_after_create= { 0, "After create", 0};
Sergei Golubchik's avatar
Sergei Golubchik committed
9773 9774
PSI_stage_info stage_after_opening_tables= { 0, "After opening tables", 0};
PSI_stage_info stage_after_table_lock= { 0, "After table lock", 0};
9775
PSI_stage_info stage_allocating_local_table= { 0, "allocating local table", 0};
9776 9777 9778
PSI_stage_info stage_alter_inplace_prepare= { 0, "preparing for alter table", 0};
PSI_stage_info stage_alter_inplace= { 0, "altering table", 0};
PSI_stage_info stage_alter_inplace_commit= { 0, "committing alter table to storage engine", 0};
9779
PSI_stage_info stage_apply_event= { 0, "apply log event", 0};
9780 9781 9782 9783 9784 9785 9786 9787
PSI_stage_info stage_changing_master= { 0, "Changing master", 0};
PSI_stage_info stage_checking_master_version= { 0, "Checking master version", 0};
PSI_stage_info stage_checking_permissions= { 0, "checking permissions", 0};
PSI_stage_info stage_checking_privileges_on_cached_query= { 0, "checking privileges on cached query", 0};
PSI_stage_info stage_checking_query_cache_for_query= { 0, "checking query cache for query", 0};
PSI_stage_info stage_cleaning_up= { 0, "cleaning up", 0};
PSI_stage_info stage_closing_tables= { 0, "closing tables", 0};
PSI_stage_info stage_connecting_to_master= { 0, "Connecting to master", 0};
Sergei Golubchik's avatar
Sergei Golubchik committed
9788
PSI_stage_info stage_converting_heap_to_myisam= { 0, "converting HEAP to " TMP_ENGINE_NAME, 0};
9789 9790 9791 9792 9793 9794 9795 9796 9797 9798
PSI_stage_info stage_copying_to_group_table= { 0, "Copying to group table", 0};
PSI_stage_info stage_copying_to_tmp_table= { 0, "Copying to tmp table", 0};
PSI_stage_info stage_copy_to_tmp_table= { 0, "copy to tmp table", 0};
PSI_stage_info stage_creating_delayed_handler= { 0, "Creating delayed handler", 0};
PSI_stage_info stage_creating_sort_index= { 0, "Creating sort index", 0};
PSI_stage_info stage_creating_table= { 0, "creating table", 0};
PSI_stage_info stage_creating_tmp_table= { 0, "Creating tmp table", 0};
PSI_stage_info stage_deleting_from_main_table= { 0, "deleting from main table", 0};
PSI_stage_info stage_deleting_from_reference_tables= { 0, "deleting from reference tables", 0};
PSI_stage_info stage_discard_or_import_tablespace= { 0, "discard_or_import_tablespace", 0};
Sergei Golubchik's avatar
Sergei Golubchik committed
9799
PSI_stage_info stage_enabling_keys= { 0, "enabling keys", 0};
9800 9801 9802 9803
PSI_stage_info stage_end= { 0, "end", 0};
PSI_stage_info stage_executing= { 0, "executing", 0};
PSI_stage_info stage_execution_of_init_command= { 0, "Execution of init_command", 0};
PSI_stage_info stage_explaining= { 0, "explaining", 0};
Sergei Golubchik's avatar
Sergei Golubchik committed
9804
PSI_stage_info stage_finding_key_cache= { 0, "Finding key cache", 0};
9805 9806 9807 9808 9809 9810 9811 9812 9813 9814 9815 9816 9817 9818 9819 9820 9821 9822 9823 9824 9825 9826 9827 9828
PSI_stage_info stage_finished_reading_one_binlog_switching_to_next_binlog= { 0, "Finished reading one binlog; switching to next binlog", 0};
PSI_stage_info stage_flushing_relay_log_and_master_info_repository= { 0, "Flushing relay log and master info repository.", 0};
PSI_stage_info stage_flushing_relay_log_info_file= { 0, "Flushing relay-log info file.", 0};
PSI_stage_info stage_freeing_items= { 0, "freeing items", 0};
PSI_stage_info stage_fulltext_initialization= { 0, "FULLTEXT initialization", 0};
PSI_stage_info stage_got_handler_lock= { 0, "got handler lock", 0};
PSI_stage_info stage_got_old_table= { 0, "got old table", 0};
PSI_stage_info stage_init= { 0, "init", 0};
PSI_stage_info stage_insert= { 0, "insert", 0};
PSI_stage_info stage_invalidating_query_cache_entries_table= { 0, "invalidating query cache entries (table)", 0};
PSI_stage_info stage_invalidating_query_cache_entries_table_list= { 0, "invalidating query cache entries (table list)", 0};
PSI_stage_info stage_killing_slave= { 0, "Killing slave", 0};
PSI_stage_info stage_logging_slow_query= { 0, "logging slow query", 0};
PSI_stage_info stage_making_temp_file_append_before_load_data= { 0, "Making temporary file (append) before replaying LOAD DATA INFILE.", 0};
PSI_stage_info stage_making_temp_file_create_before_load_data= { 0, "Making temporary file (create) before replaying LOAD DATA INFILE.", 0};
PSI_stage_info stage_manage_keys= { 0, "manage keys", 0};
PSI_stage_info stage_master_has_sent_all_binlog_to_slave= { 0, "Master has sent all binlog to slave; waiting for binlog to be updated", 0};
PSI_stage_info stage_opening_tables= { 0, "Opening tables", 0};
PSI_stage_info stage_optimizing= { 0, "optimizing", 0};
PSI_stage_info stage_preparing= { 0, "preparing", 0};
PSI_stage_info stage_purging_old_relay_logs= { 0, "Purging old relay logs", 0};
PSI_stage_info stage_query_end= { 0, "query end", 0};
PSI_stage_info stage_queueing_master_event_to_the_relay_log= { 0, "Queueing master event to the relay log", 0};
PSI_stage_info stage_reading_event_from_the_relay_log= { 0, "Reading event from the relay log", 0};
Sergei Golubchik's avatar
Sergei Golubchik committed
9829
PSI_stage_info stage_recreating_table= { 0, "recreating table", 0};
9830 9831 9832 9833 9834 9835 9836 9837 9838 9839 9840 9841
PSI_stage_info stage_registering_slave_on_master= { 0, "Registering slave on master", 0};
PSI_stage_info stage_removing_duplicates= { 0, "Removing duplicates", 0};
PSI_stage_info stage_removing_tmp_table= { 0, "removing tmp table", 0};
PSI_stage_info stage_rename= { 0, "rename", 0};
PSI_stage_info stage_rename_result_table= { 0, "rename result table", 0};
PSI_stage_info stage_requesting_binlog_dump= { 0, "Requesting binlog dump", 0};
PSI_stage_info stage_reschedule= { 0, "reschedule", 0};
PSI_stage_info stage_searching_rows_for_update= { 0, "Searching rows for update", 0};
PSI_stage_info stage_sending_binlog_event_to_slave= { 0, "Sending binlog event to slave", 0};
PSI_stage_info stage_sending_cached_result_to_client= { 0, "sending cached result to client", 0};
PSI_stage_info stage_sending_data= { 0, "Sending data", 0};
PSI_stage_info stage_setup= { 0, "setup", 0};
Sergei Golubchik's avatar
Sergei Golubchik committed
9842
PSI_stage_info stage_show_explain= { 0, "show explain", 0};
9843
PSI_stage_info stage_slave_has_read_all_relay_log= { 0, "Slave has read all relay log; waiting for the slave I/O thread to update it", 0};
Sergei Golubchik's avatar
Sergei Golubchik committed
9844
PSI_stage_info stage_sorting= { 0, "Sorting", 0};
9845 9846 9847 9848 9849 9850 9851 9852
PSI_stage_info stage_sorting_for_group= { 0, "Sorting for group", 0};
PSI_stage_info stage_sorting_for_order= { 0, "Sorting for order", 0};
PSI_stage_info stage_sorting_result= { 0, "Sorting result", 0};
PSI_stage_info stage_statistics= { 0, "statistics", 0};
PSI_stage_info stage_sql_thd_waiting_until_delay= { 0, "Waiting until MASTER_DELAY seconds after master executed event", 0 };
PSI_stage_info stage_storing_result_in_query_cache= { 0, "storing result in query cache", 0};
PSI_stage_info stage_storing_row_into_queue= { 0, "storing row into queue", 0};
PSI_stage_info stage_system_lock= { 0, "System lock", 0};
9853
PSI_stage_info stage_unlocking_tables= { 0, "Unlocking tables", 0};
9854 9855
PSI_stage_info stage_table_lock= { 0, "Table lock", 0};
PSI_stage_info stage_filling_schema_table= { 0, "Filling schema table", 0};
9856 9857 9858 9859 9860 9861 9862 9863 9864 9865 9866 9867 9868 9869 9870 9871 9872 9873 9874 9875 9876 9877 9878 9879 9880 9881 9882 9883 9884 9885
PSI_stage_info stage_update= { 0, "update", 0};
PSI_stage_info stage_updating= { 0, "updating", 0};
PSI_stage_info stage_updating_main_table= { 0, "updating main table", 0};
PSI_stage_info stage_updating_reference_tables= { 0, "updating reference tables", 0};
PSI_stage_info stage_upgrading_lock= { 0, "upgrading lock", 0};
PSI_stage_info stage_user_lock= { 0, "User lock", 0};
PSI_stage_info stage_user_sleep= { 0, "User sleep", 0};
PSI_stage_info stage_verifying_table= { 0, "verifying table", 0};
PSI_stage_info stage_waiting_for_delay_list= { 0, "waiting for delay_list", 0};
PSI_stage_info stage_waiting_for_gtid_to_be_written_to_binary_log= { 0, "waiting for GTID to be written to binary log", 0};
PSI_stage_info stage_waiting_for_handler_insert= { 0, "waiting for handler insert", 0};
PSI_stage_info stage_waiting_for_handler_lock= { 0, "waiting for handler lock", 0};
PSI_stage_info stage_waiting_for_handler_open= { 0, "waiting for handler open", 0};
PSI_stage_info stage_waiting_for_insert= { 0, "Waiting for INSERT", 0};
PSI_stage_info stage_waiting_for_master_to_send_event= { 0, "Waiting for master to send event", 0};
PSI_stage_info stage_waiting_for_master_update= { 0, "Waiting for master update", 0};
PSI_stage_info stage_waiting_for_relay_log_space= { 0, "Waiting for the slave SQL thread to free enough relay log space", 0};
PSI_stage_info stage_waiting_for_slave_mutex_on_exit= { 0, "Waiting for slave mutex on exit", 0};
PSI_stage_info stage_waiting_for_slave_thread_to_start= { 0, "Waiting for slave thread to start", 0};
PSI_stage_info stage_waiting_for_table_flush= { 0, "Waiting for table flush", 0};
PSI_stage_info stage_waiting_for_query_cache_lock= { 0, "Waiting for query cache lock", 0};
PSI_stage_info stage_waiting_for_the_next_event_in_relay_log= { 0, "Waiting for the next event in relay log", 0};
PSI_stage_info stage_waiting_for_the_slave_thread_to_advance_position= { 0, "Waiting for the slave SQL thread to advance position", 0};
PSI_stage_info stage_waiting_to_finalize_termination= { 0, "Waiting to finalize termination", 0};
PSI_stage_info stage_waiting_to_get_readlock= { 0, "Waiting to get readlock", 0};
PSI_stage_info stage_slave_waiting_workers_to_exit= { 0, "Waiting for workers to exit", 0};
PSI_stage_info stage_slave_waiting_worker_to_release_partition= { 0, "Waiting for Slave Worker to release partition", 0};
PSI_stage_info stage_slave_waiting_worker_to_free_events= { 0, "Waiting for Slave Workers to free pending events", 0};
PSI_stage_info stage_slave_waiting_worker_queue= { 0, "Waiting for Slave Worker queue", 0};
PSI_stage_info stage_slave_waiting_event_from_coordinator= { 0, "Waiting for an event from Coordinator", 0};
9886 9887 9888
PSI_stage_info stage_binlog_waiting_background_tasks= { 0, "Waiting for background binlog tasks", 0};
PSI_stage_info stage_binlog_processing_checkpoint_notify= { 0, "Processing binlog checkpoint notification", 0};
PSI_stage_info stage_binlog_stopping_background_thread= { 0, "Stopping binlog background thread", 0};
9889
PSI_stage_info stage_waiting_for_work_from_sql_thread= { 0, "Waiting for work from SQL thread", 0};
9890 9891
PSI_stage_info stage_waiting_for_prior_transaction_to_commit= { 0, "Waiting for prior transaction to commit", 0};
PSI_stage_info stage_waiting_for_prior_transaction_to_start_commit= { 0, "Waiting for prior transaction to start commit before starting next transaction", 0};
Sergei Golubchik's avatar
Sergei Golubchik committed
9892
PSI_stage_info stage_waiting_for_room_in_worker_thread= { 0, "Waiting for room in worker thread event queue", 0};
unknown's avatar
unknown committed
9893 9894
PSI_stage_info stage_master_gtid_wait_primary= { 0, "Waiting in MASTER_GTID_WAIT() (primary waiter)", 0};
PSI_stage_info stage_master_gtid_wait= { 0, "Waiting in MASTER_GTID_WAIT()", 0};
9895
PSI_stage_info stage_gtid_wait_other_connection= { 0, "Waiting for other master connection to process GTID received on multiple master connections", 0};
9896

9897
#ifdef HAVE_PSI_INTERFACE
9898

9899 9900
PSI_stage_info *all_server_stages[]=
{
9901
  & stage_after_apply_event,
9902
  & stage_after_create,
Sergei Golubchik's avatar
Sergei Golubchik committed
9903 9904
  & stage_after_opening_tables,
  & stage_after_table_lock,
9905
  & stage_allocating_local_table,
Sergei Golubchik's avatar
Sergei Golubchik committed
9906 9907 9908
  & stage_alter_inplace,
  & stage_alter_inplace_commit,
  & stage_alter_inplace_prepare,
9909
  & stage_apply_event,
Sergei Golubchik's avatar
Sergei Golubchik committed
9910 9911 9912
  & stage_binlog_processing_checkpoint_notify,
  & stage_binlog_stopping_background_thread,
  & stage_binlog_waiting_background_tasks,
9913 9914 9915 9916 9917 9918 9919 9920 9921
  & stage_changing_master,
  & stage_checking_master_version,
  & stage_checking_permissions,
  & stage_checking_privileges_on_cached_query,
  & stage_checking_query_cache_for_query,
  & stage_cleaning_up,
  & stage_closing_tables,
  & stage_connecting_to_master,
  & stage_converting_heap_to_myisam,
Sergei Golubchik's avatar
Sergei Golubchik committed
9922
  & stage_copy_to_tmp_table,
9923 9924 9925 9926 9927 9928 9929 9930 9931
  & stage_copying_to_group_table,
  & stage_copying_to_tmp_table,
  & stage_creating_delayed_handler,
  & stage_creating_sort_index,
  & stage_creating_table,
  & stage_creating_tmp_table,
  & stage_deleting_from_main_table,
  & stage_deleting_from_reference_tables,
  & stage_discard_or_import_tablespace,
Sergei Golubchik's avatar
Sergei Golubchik committed
9932
  & stage_enabling_keys,
9933 9934 9935 9936
  & stage_end,
  & stage_executing,
  & stage_execution_of_init_command,
  & stage_explaining,
Sergei Golubchik's avatar
Sergei Golubchik committed
9937
  & stage_finding_key_cache,
9938 9939 9940 9941 9942 9943 9944 9945 9946 9947 9948 9949 9950 9951 9952 9953 9954 9955 9956 9957 9958 9959 9960 9961
  & stage_finished_reading_one_binlog_switching_to_next_binlog,
  & stage_flushing_relay_log_and_master_info_repository,
  & stage_flushing_relay_log_info_file,
  & stage_freeing_items,
  & stage_fulltext_initialization,
  & stage_got_handler_lock,
  & stage_got_old_table,
  & stage_init,
  & stage_insert,
  & stage_invalidating_query_cache_entries_table,
  & stage_invalidating_query_cache_entries_table_list,
  & stage_killing_slave,
  & stage_logging_slow_query,
  & stage_making_temp_file_append_before_load_data,
  & stage_making_temp_file_create_before_load_data,
  & stage_manage_keys,
  & stage_master_has_sent_all_binlog_to_slave,
  & stage_opening_tables,
  & stage_optimizing,
  & stage_preparing,
  & stage_purging_old_relay_logs,
  & stage_query_end,
  & stage_queueing_master_event_to_the_relay_log,
  & stage_reading_event_from_the_relay_log,
Sergei Golubchik's avatar
Sergei Golubchik committed
9962
  & stage_recreating_table,
9963 9964 9965 9966 9967 9968 9969 9970 9971 9972 9973 9974
  & stage_registering_slave_on_master,
  & stage_removing_duplicates,
  & stage_removing_tmp_table,
  & stage_rename,
  & stage_rename_result_table,
  & stage_requesting_binlog_dump,
  & stage_reschedule,
  & stage_searching_rows_for_update,
  & stage_sending_binlog_event_to_slave,
  & stage_sending_cached_result_to_client,
  & stage_sending_data,
  & stage_setup,
Sergei Golubchik's avatar
Sergei Golubchik committed
9975
  & stage_show_explain,
Sergei Golubchik's avatar
Sergei Golubchik committed
9976 9977 9978 9979 9980 9981
  & stage_slave_has_read_all_relay_log,
  & stage_slave_waiting_event_from_coordinator,
  & stage_slave_waiting_worker_queue,
  & stage_slave_waiting_worker_to_free_events,
  & stage_slave_waiting_worker_to_release_partition,
  & stage_slave_waiting_workers_to_exit,
Sergei Golubchik's avatar
Sergei Golubchik committed
9982
  & stage_sorting,
9983 9984 9985 9986 9987 9988 9989 9990
  & stage_sorting_for_group,
  & stage_sorting_for_order,
  & stage_sorting_result,
  & stage_sql_thd_waiting_until_delay,
  & stage_statistics,
  & stage_storing_result_in_query_cache,
  & stage_storing_row_into_queue,
  & stage_system_lock,
9991
  & stage_unlocking_tables,
9992 9993
  & stage_table_lock,
  & stage_filling_schema_table,
9994 9995 9996 9997 9998 9999 10000 10001 10002
  & stage_update,
  & stage_updating,
  & stage_updating_main_table,
  & stage_updating_reference_tables,
  & stage_upgrading_lock,
  & stage_user_lock,
  & stage_user_sleep,
  & stage_verifying_table,
  & stage_waiting_for_delay_list,
Sergei Golubchik's avatar
Sergei Golubchik committed
10003
  & stage_waiting_for_gtid_to_be_written_to_binary_log,
10004 10005 10006 10007 10008 10009
  & stage_waiting_for_handler_insert,
  & stage_waiting_for_handler_lock,
  & stage_waiting_for_handler_open,
  & stage_waiting_for_insert,
  & stage_waiting_for_master_to_send_event,
  & stage_waiting_for_master_update,
Sergei Golubchik's avatar
Sergei Golubchik committed
10010
  & stage_waiting_for_prior_transaction_to_commit,
10011
  & stage_waiting_for_prior_transaction_to_start_commit,
Sergei Golubchik's avatar
Sergei Golubchik committed
10012 10013 10014
  & stage_waiting_for_query_cache_lock,
  & stage_waiting_for_relay_log_space,
  & stage_waiting_for_room_in_worker_thread,
10015 10016 10017 10018 10019
  & stage_waiting_for_slave_mutex_on_exit,
  & stage_waiting_for_slave_thread_to_start,
  & stage_waiting_for_table_flush,
  & stage_waiting_for_the_next_event_in_relay_log,
  & stage_waiting_for_the_slave_thread_to_advance_position,
Sergei Golubchik's avatar
Sergei Golubchik committed
10020
  & stage_waiting_for_work_from_sql_thread,
10021
  & stage_waiting_to_finalize_termination,
unknown's avatar
unknown committed
10022 10023
  & stage_waiting_to_get_readlock,
  & stage_master_gtid_wait_primary,
10024 10025
  & stage_master_gtid_wait,
  & stage_gtid_wait_other_connection
10026 10027 10028 10029 10030 10031 10032 10033 10034 10035 10036 10037 10038 10039 10040 10041 10042 10043 10044
};

PSI_socket_key key_socket_tcpip, key_socket_unix, key_socket_client_connection;

static PSI_socket_info all_server_sockets[]=
{
  { &key_socket_tcpip, "server_tcpip_socket", PSI_FLAG_GLOBAL},
  { &key_socket_unix, "server_unix_socket", PSI_FLAG_GLOBAL},
  { &key_socket_client_connection, "client_connection", 0}
};

/**
  Initialise all the performance schema instrumentation points
  used by the server.
*/
void init_server_psi_keys(void)
{
  const char* category= "sql";
  int count;
unknown's avatar
unknown committed
10045

10046 10047 10048 10049 10050 10051 10052 10053 10054 10055 10056 10057 10058 10059 10060 10061 10062 10063 10064 10065 10066 10067 10068 10069 10070 10071 10072 10073
  count= array_elements(all_server_mutexes);
  mysql_mutex_register(category, all_server_mutexes, count);

  count= array_elements(all_server_rwlocks);
  mysql_rwlock_register(category, all_server_rwlocks, count);

  count= array_elements(all_server_conds);
  mysql_cond_register(category, all_server_conds, count);

  count= array_elements(all_server_threads);
  mysql_thread_register(category, all_server_threads, count);

  count= array_elements(all_server_files);
  mysql_file_register(category, all_server_files, count);

  count= array_elements(all_server_stages);
  mysql_stage_register(category, all_server_stages, count);

  count= array_elements(all_server_sockets);
  mysql_socket_register(category, all_server_sockets, count);

#ifdef HAVE_PSI_STATEMENT_INTERFACE
  init_sql_statement_info();
  count= array_elements(sql_statement_info);
  mysql_statement_register(category, sql_statement_info, count);

  category= "com";
  init_com_statement_info();
Sergei Golubchik's avatar
Sergei Golubchik committed
10074 10075 10076 10077 10078

  /*
    Register [0 .. COM_QUERY - 1] as "statement/com/..."
  */
  count= (int) COM_QUERY;
10079 10080
  mysql_statement_register(category, com_statement_info, count);

Sergei Golubchik's avatar
Sergei Golubchik committed
10081 10082 10083 10084 10085 10086 10087 10088 10089 10090 10091 10092
  /*
    Register [COM_QUERY + 1 .. COM_END] as "statement/com/..."
  */
  count= (int) COM_END - (int) COM_QUERY;
  mysql_statement_register(category, & com_statement_info[(int) COM_QUERY + 1], count);

  category= "abstract";
  /*
    Register [COM_QUERY] as "statement/abstract/com_query"
  */
  mysql_statement_register(category, & com_statement_info[(int) COM_QUERY], 1);

10093 10094
  /*
    When a new packet is received,
Sergei Golubchik's avatar
Sergei Golubchik committed
10095
    it is instrumented as "statement/abstract/new_packet".
10096 10097
    Based on the packet type found, it later mutates to the
    proper narrow type, for example
Sergei Golubchik's avatar
Sergei Golubchik committed
10098 10099
    "statement/abstract/query" or "statement/com/ping".
    In cases of "statement/abstract/query", SQL queries are given to
10100 10101 10102 10103
    the parser, which mutates the statement type to an even more
    narrow classification, for example "statement/sql/select".
  */
  stmt_info_new_packet.m_key= 0;
Sergei Golubchik's avatar
Sergei Golubchik committed
10104
  stmt_info_new_packet.m_name= "new_packet";
10105
  stmt_info_new_packet.m_flags= PSI_FLAG_MUTABLE;
Sergei Golubchik's avatar
Sergei Golubchik committed
10106 10107 10108 10109 10110 10111 10112 10113 10114 10115 10116
  mysql_statement_register(category, &stmt_info_new_packet, 1);

  /*
    Statements processed from the relay log are initially instrumented as
    "statement/abstract/relay_log". The parser will mutate the statement type to
    a more specific classification, for example "statement/sql/insert".
  */
  stmt_info_rpl.m_key= 0;
  stmt_info_rpl.m_name= "relay_log";
  stmt_info_rpl.m_flags= PSI_FLAG_MUTABLE;
  mysql_statement_register(category, &stmt_info_rpl, 1);
unknown's avatar
unknown committed
10117
#endif
10118
}
Marc Alff's avatar
Marc Alff committed
10119

10120
#endif /* HAVE_PSI_INTERFACE */