mysqld.cc 276 KB
Newer Older
Sergei Golubchik's avatar
Sergei Golubchik committed
1 2
/* Copyright (c) 2000, 2012, Oracle and/or its affiliates.
   Copyright (c) 2008, 2012, Monty Program 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 15 16
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

17
#include "my_global.h"                          /* NO_EMBEDDED_ACCESS_CHECKS */
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 43 44 45 46 47 48 49 50 51 52 53
#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
#include "sql_base.h"     // table_def_free, table_def_init,
                          // cached_open_tables,
                          // cached_table_definitions
#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
54
#include "sql_expression_cache.h" // subquery_cache_miss, subquery_cache_hit
Sergei Golubchik's avatar
Sergei Golubchik committed
55

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

Marc Alff's avatar
Marc Alff committed
78 79 80 81
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
#include "../storage/perfschema/pfs_server.h"
#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */

82
#include "keycaches.h"
83
#include "../storage/myisam/ha_myisam.h"
84
#include "set_var.h"
85

86 87
#include "rpl_injector.h"

He Zhenxing's avatar
He Zhenxing committed
88 89
#include "rpl_handler.h"

90 91
#ifdef HAVE_SYS_PRCTL_H
#include <sys/prctl.h>
92 93
#endif

unknown's avatar
unknown committed
94 95
#include <thr_alarm.h>
#include <ft_global.h>
96
#include <errmsg.h>
unknown's avatar
Merge  
unknown committed
97 98
#include "sp_rcontext.h"
#include "sp_cache.h"
99
#include "sql_reload.h"  // reload_acl_and_cache
unknown's avatar
unknown committed
100

101 102
#ifdef HAVE_POLL_H
#include <poll.h>
103 104
#endif

unknown's avatar
unknown committed
105
#define mysqld_charset &my_charset_latin1
106

107
/* We have HAVE_valgrind below as this speeds up the shutdown of MySQL */
108

109
#if defined(SIGNALS_DONT_BREAK_READ) || defined(HAVE_valgrind) && defined(__linux__)
unknown's avatar
unknown committed
110
#define HAVE_CLOSE_SERVER_SOCK 1
111
#endif
unknown's avatar
unknown committed
112

unknown's avatar
unknown committed
113 114 115 116
extern "C" {					// Because of SCO 3.2V4.2
#include <errno.h>
#include <sys/stat.h>
#ifndef __GNU_LIBRARY__
117
#define __GNU_LIBRARY__				// Skip warnings in getopt.h
unknown's avatar
unknown committed
118
#endif
119
#include <my_getopt.h>
unknown's avatar
unknown committed
120 121 122 123 124 125 126 127 128
#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
129
#include <my_net.h>
unknown's avatar
unknown committed
130

131
#if !defined(__WIN__)
unknown's avatar
unknown committed
132 133
#include <sys/resource.h>
#ifdef HAVE_SYS_UN_H
134
#include <sys/un.h>
unknown's avatar
unknown committed
135 136
#endif
#ifdef HAVE_SELECT_H
137
#include <select.h>
unknown's avatar
unknown committed
138 139 140 141 142
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#include <sys/utsname.h>
unknown's avatar
unknown committed
143
#endif /* __WIN__ */
unknown's avatar
unknown committed
144

145
#include <my_libwrap.h>
unknown's avatar
unknown committed
146

147 148 149 150
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif

151 152 153 154
#ifdef __WIN__ 
#include <crtdbg.h>
#endif

155 156 157 158 159 160 161 162 163 164
#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
165
#ifdef _AIX41
unknown's avatar
unknown committed
166
int initgroups(const char *,unsigned int);
unknown's avatar
unknown committed
167 168
#endif

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

Sergei Golubchik's avatar
Sergei Golubchik committed
195 196 197 198
#ifndef HAVE_FCNTL
#define fcntl(X,Y,Z) 0
#endif

199 200 201
extern "C" my_bool reopen_fstreams(const char *filename,
                                   FILE *outstream, FILE *errstream);

202
inline void setup_fpu()
unknown's avatar
unknown committed
203
{
204
#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H) && !defined(HAVE_FEDISABLEEXCEPT)
unknown's avatar
unknown committed
205
  /* We can't handle floating point exceptions with threads, so disable
unknown's avatar
unknown committed
206
     this on freebsd
207 208
     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
209
  */
210
#if defined(FP_X_DNML)
unknown's avatar
unknown committed
211 212
  fpsetmask(~(FP_X_INV | FP_X_DNML | FP_X_OFL | FP_X_UFL | FP_X_DZ |
	      FP_X_IMP));
unknown's avatar
unknown committed
213
#else
214 215
  fpsetmask(~(FP_X_INV |             FP_X_OFL | FP_X_UFL | FP_X_DZ |
              FP_X_IMP));
216 217 218 219 220 221
#endif /* FP_X_DNML */
#endif /* __FreeBSD__ && HAVE_IEEEFP_H && !HAVE_FEDISABLEEXCEPT */

#ifdef HAVE_FEDISABLEEXCEPT
  fedisableexcept(FE_ALL_EXCEPT);
#endif
222

223 224 225 226
#ifdef HAVE_FESETROUND
    /* Set FPU rounding mode to "round-to-nearest" */
  fesetround(FE_TONEAREST);
#endif /* HAVE_FESETROUND */
227 228

  /*
229 230 231 232
    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.
233
  */
234
#if defined(__i386__) && !defined(__SSE2_MATH__)
235 236 237 238 239 240 241 242 243 244 245 246
#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__ */

247
#if defined(__sgi) && defined(HAVE_SYS_FPU_H)
248
  /* Enable denormalized DOUBLE values support for IRIX */
249 250 251 252 253
  union fpc_csr n;
  n.fc_word = get_fpc_csr();
  n.fc_struct.flush = 0;
  set_fpc_csr(n.fc_word);
#endif
254
}
unknown's avatar
unknown committed
255

unknown's avatar
unknown committed
256 257
} /* cplusplus */

unknown's avatar
unknown committed
258
#define MYSQL_KILL_SIGNAL SIGTERM
unknown's avatar
unknown committed
259 260 261 262 263 264 265

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

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

266
extern "C" sig_handler handle_fatal_signal(int sig);
267

268 269 270
#if defined(__linux__)
#define ENABLE_TEMP_POOL 1
#else
Vladislav Vaintroub's avatar
Vladislav Vaintroub committed
271
#define ENABLE_TEMP_POOL 0
272 273
#endif

unknown's avatar
unknown committed
274
/* Constants */
275

276 277
#include <welcome_copyright_notice.h> // ORACLE_WELCOME_COPYRIGHT_NOTICE

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

unknown's avatar
unknown committed
280 281 282 283 284 285 286 287 288
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
289

unknown's avatar
unknown committed
290
const char *first_keyword= "first", *binary_keyword= "BINARY";
unknown's avatar
unknown committed
291
const char *my_localhost= "localhost", *delayed_user= "DELAYED";
292

unknown's avatar
unknown committed
293
bool opt_large_files= sizeof(my_off_t) > 4;
294
static my_bool opt_autocommit; ///< for --autocommit command-line option
295 296 297 298

/*
  Used with --help for detailed option
*/
299
static my_bool opt_verbose= 0;
300

301
arg_cmp_func Arg_comparator::comparator_matrix[6][2] =
302 303 304
{{&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
305
 {&Arg_comparator::compare_row,        &Arg_comparator::compare_e_row},
306 307
 {&Arg_comparator::compare_decimal,    &Arg_comparator::compare_e_decimal},
 {&Arg_comparator::compare_datetime,   &Arg_comparator::compare_e_datetime}};
unknown's avatar
unknown committed
308

unknown's avatar
unknown committed
309 310
/* static variables */

Marc Alff's avatar
Marc Alff committed
311 312 313
#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
314
static PSI_cond_key key_COND_handler_count;
Marc Alff's avatar
Marc Alff committed
315 316 317 318 319 320 321 322 323 324 325 326 327
#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__ */
328 329 330 331

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

334 335 336 337
#ifdef HAVE_NPTL
volatile sig_atomic_t ld_assume_kernel_is_set= 0;
#endif

338
/* the default log output is log tables */
unknown's avatar
unknown committed
339
static bool lower_case_table_names_used= 0;
340
static bool max_long_data_size_used= false;
unknown's avatar
unknown committed
341
static bool volatile select_thread_in_use, signal_thread_in_use;
342
static volatile bool ready_to_exit;
unknown's avatar
unknown committed
343 344 345
static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0;
static my_bool opt_short_log_format= 0;
static uint kill_cached_threads, wake_thread;
Michael Widenius's avatar
Michael Widenius committed
346
ulong max_used_connections;
unknown's avatar
unknown committed
347
static volatile ulong cached_thread_count= 0;
348
static char *mysqld_user, *mysqld_chroot;
unknown's avatar
unknown committed
349
static char *default_character_set_name;
unknown's avatar
unknown committed
350
static char *character_set_filesystem_name;
351
static char *lc_messages;
352
static char *lc_time_names_name;
unknown's avatar
unknown committed
353
static char *my_bind_addr_str;
354 355
static char *default_collation_name;
char *default_storage_engine;
356
static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME;
unknown's avatar
unknown committed
357
static I_List<THD> thread_cache;
358 359
static bool binlog_format_used= false;
LEX_STRING opt_init_connect, opt_init_slave;
Marc Alff's avatar
Marc Alff committed
360
static mysql_cond_t COND_thread_cache, COND_flush_thread_cache;
361
static DYNAMIC_ARRAY all_options;
unknown's avatar
unknown committed
362

unknown's avatar
unknown committed
363
/* Global variables */
unknown's avatar
unknown committed
364

365
bool opt_bin_log, opt_bin_log_used=0, opt_ignore_builtin_innodb= 0;
366
my_bool opt_log, opt_slow_log, debug_assert_if_crashed_table= 0, opt_help= 0, opt_abort;
367
ulonglong log_output_options;
Sergei Golubchik's avatar
Sergei Golubchik committed
368
my_bool opt_userstat_running;
369
my_bool opt_log_queries_not_using_indexes= 0;
370
bool opt_error_log= IF_WIN(1,0);
unknown's avatar
unknown committed
371
bool opt_disable_networking=0, opt_skip_show_db=0;
372
bool opt_skip_name_resolve=0;
373
my_bool opt_character_set_client_handshake= 1;
unknown's avatar
unknown committed
374
bool server_id_supplied = 0;
375
bool opt_endinfo, using_udf_functions;
376
my_bool locked_in_memory;
377
bool opt_using_transactions;
unknown's avatar
unknown committed
378
bool volatile abort_loop;
379
bool volatile shutdown_in_progress;
Sergei Golubchik's avatar
Sergei Golubchik committed
380
uint volatile global_disable_checkpoint;
381 382 383
#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
ulong slow_start_timeout;
#endif
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398
/*
  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;
399 400 401 402
/**
   @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.
403
   @note This flag is dropped in 5.1
404 405 406
   @see grant_init()
 */
bool volatile grant_option;
unknown's avatar
unknown committed
407

unknown's avatar
unknown committed
408
my_bool opt_skip_slave_start = 0; ///< If set, slave is not autostarted
unknown's avatar
unknown committed
409
my_bool opt_reckless_slave = 0;
unknown's avatar
unknown committed
410 411
my_bool opt_enable_named_pipe= 0;
my_bool opt_local_infile, opt_slave_compressed_protocol;
412 413
my_bool opt_safe_user_create = 0;
my_bool opt_show_slave_auth_info;
414
my_bool opt_log_slave_updates= 0;
415
my_bool opt_replicate_annotate_row_events= 0;
416 417
char *opt_slave_skip_errors;

418 419 420 421 422
/*
  Legacy global handlerton. These will be removed (please do not add more).
*/
handlerton *heap_hton;
handlerton *myisam_hton;
423
handlerton *partition_hton;
424

425 426
my_bool read_only= 0, opt_readonly= 0;
my_bool use_temp_pool, relay_log_purge;
427
my_bool relay_log_recovery;
unknown's avatar
unknown committed
428
my_bool opt_sync_frm, opt_allow_suspicious_udfs;
429
my_bool opt_secure_auth= 0;
430
char* opt_secure_file_priv;
431
my_bool opt_log_slow_admin_statements= 0;
432
my_bool opt_log_slow_slave_statements= 0;
unknown's avatar
unknown committed
433
my_bool lower_case_file_system= 0;
434
my_bool opt_large_pages= 0;
435
my_bool opt_super_large_pages= 0;
unknown's avatar
unknown committed
436
my_bool opt_myisam_use_mmap= 0;
437
uint   opt_large_page_size= 0;
438
#if defined(ENABLED_DEBUG_SYNC)
439
MYSQL_PLUGIN_IMPORT uint    opt_debug_sync_timeout= 0;
440
#endif /* defined(ENABLED_DEBUG_SYNC) */
441
my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
442
ulong opt_replicate_events_marked_for_skip;
443

unknown's avatar
Merge  
unknown committed
444 445 446 447 448
/*
  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
449
volatile bool mqh_used = 0;
450
my_bool opt_noacl;
unknown's avatar
Merge  
unknown committed
451
my_bool sp_automatic_privileges= 1;
452

453
ulong opt_binlog_rows_event_max_size;
454 455
my_bool opt_master_verify_checksum= 0;
my_bool opt_slave_sql_verify_checksum= 1;
unknown's avatar
unknown committed
456
const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS};
457
#ifdef HAVE_INITGROUPS
458
volatile sig_atomic_t calling_initgroups= 0; /**< Used in SIGSEGV handler. */
459
#endif
460
uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
461
uint mysqld_extra_port;
462
uint mysqld_port_timeout;
Georgi Kodinov's avatar
merge  
Georgi Kodinov committed
463
ulong delay_key_write_options;
464
uint protocol_version;
unknown's avatar
unknown committed
465
uint lower_case_table_names;
Georgi Kodinov's avatar
merge  
Georgi Kodinov committed
466
ulong tc_heuristic_recover= 0;
467
uint volatile thread_count;
468
int32 thread_running;
469
ulong thread_created;
470
ulong back_log, connect_timeout, concurrency, server_id;
unknown's avatar
unknown committed
471
ulong table_cache_size, table_def_size;
472
ulong what_to_log;
473
ulong slow_launch_time, slave_open_temp_tables;
unknown's avatar
unknown committed
474
ulong open_files_limit, max_binlog_size, max_relay_log_size;
475 476
ulong slave_trans_retries;
uint  slave_net_timeout;
477
ulong slave_exec_mode_options;
unknown's avatar
unknown committed
478
ulonglong slave_type_conversions_options;
479
ulong thread_cache_size=0;
480 481
ulonglong binlog_cache_size=0;
ulonglong max_binlog_cache_size=0;
482
ulong slave_max_allowed_packet= 0;
483 484 485
ulonglong binlog_stmt_cache_size=0;
ulonglong  max_binlog_stmt_cache_size=0;
ulonglong query_cache_size=0;
486
ulong refresh_version;  /* Increments on each reload */
487
ulong executed_events=0;
488
query_id_t global_query_id;
489
my_atomic_rwlock_t global_query_id_lock;
490
my_atomic_rwlock_t thread_running_lock;
unknown's avatar
unknown committed
491
ulong aborted_threads, aborted_connects;
unknown's avatar
unknown committed
492 493
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
494
ulong delayed_insert_errors,flush_time;
unknown's avatar
Merge  
unknown committed
495
ulong specialflag=0;
496
ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
497
ulong binlog_stmt_cache_use= 0, binlog_stmt_cache_disk_use= 0;
unknown's avatar
unknown committed
498
ulong max_connections, max_connect_errors;
499
ulong extra_max_connections;
500
ulonglong denied_connections;
Sergei Golubchik's avatar
Sergei Golubchik committed
501
my_decimal decimal_zero;
Sergei Golubchik's avatar
Sergei Golubchik committed
502

503 504 505 506 507
/*
  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
508

509 510 511 512
/* Limits for internal temporary tables (MyISAM or Aria) */
uint internal_tmp_table_max_key_length;
uint internal_tmp_table_max_key_segments;

513
bool max_user_connections_checking=0;
unknown's avatar
unknown committed
514
/**
515 516 517 518
  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
519
/**
520 521 522 523 524 525 526 527 528 529
  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
530
ulong thread_id=1L,current_pid;
531
ulong slow_launch_threads = 0;
532 533
uint sync_binlog_period= 0, sync_relaylog_period= 0,
     sync_relayloginfo_period= 0, sync_masterinfo_period= 0;
unknown's avatar
unknown committed
534
ulong expire_logs_days = 0;
unknown's avatar
unknown committed
535
ulong rpl_recovery_rank=0;
536 537 538 539 540
/**
  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
541

542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574
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
575

576
time_t server_start_time, flush_status_time;
577

578 579
char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
char *default_tz_name;
580
char log_error_file[FN_REFLEN], glob_hostname[FN_REFLEN], *opt_log_basename;
unknown's avatar
unknown committed
581
char mysql_real_data_home[FN_REFLEN],
582 583
     lc_messages_dir[FN_REFLEN], reg_ext[FN_EXTLEN],
     mysql_charsets_dir[FN_REFLEN],
584
     *opt_init_file, *opt_tc_log_file;
585
char *lc_messages_dir_ptr= lc_messages_dir, *log_error_file_ptr;
586
char mysql_unpacked_real_data_home[FN_REFLEN];
587
int mysql_unpacked_real_data_home_len;
588
uint mysql_real_data_home_len, mysql_data_home_len= 1;
589
uint reg_ext_length;
590 591 592
const key_map key_map_empty(0);
key_map key_map_full(0);                        // Will be initialized later

593 594
DATE_TIME_FORMAT global_date_format, global_datetime_format, global_time_format;
Time_zone *default_tz;
595

596 597
char *mysql_data_home= const_cast<char*>(".");
const char *mysql_real_data_home_ptr= mysql_real_data_home;
598
char server_version[SERVER_VERSION_LENGTH];
599
char *mysqld_unix_port, *opt_mysql_tmpdir;
Georgi Kodinov's avatar
merge  
Georgi Kodinov committed
600
ulong thread_handling;
601

602
/** name of reference on left expression in rewritten IN subquery */
603
const char *in_left_expr_name= "<left expr>";
unknown's avatar
unknown committed
604
/** name of additional condition */
605
const char *in_additional_cond= "<IN COND>";
606 607
const char *in_having_cond= "<IN HAVING>";

unknown's avatar
unknown committed
608 609 610 611 612 613 614 615
/* 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
616
MYSQL_FILE *bootstrap_file;
unknown's avatar
Merge  
unknown committed
617
int bootstrap_error;
unknown's avatar
unknown committed
618

unknown's avatar
unknown committed
619
I_List<THD> threads;
unknown's avatar
unknown committed
620 621
Rpl_filter* rpl_filter;
Rpl_filter* binlog_filter;
unknown's avatar
unknown committed
622

623 624 625 626 627 628 629 630 631 632 633 634 635 636 637
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
638 639
struct system_variables global_system_variables;
struct system_variables max_system_variables;
unknown's avatar
Merge  
unknown committed
640
struct system_status_var global_status_var;
unknown's avatar
unknown committed
641

unknown's avatar
unknown committed
642
MY_TMPDIR mysql_tmpdir_list;
643
MY_BITMAP temp_pool;
unknown's avatar
unknown committed
644

645 646
CHARSET_INFO *system_charset_info, *files_charset_info ;
CHARSET_INFO *national_charset_info, *table_alias_charset;
unknown's avatar
unknown committed
647
CHARSET_INFO *character_set_filesystem;
Marc Alff's avatar
Marc Alff committed
648
CHARSET_INFO *error_message_charset_info;
649

650
MY_LOCALE *my_default_lc_messages;
651 652
MY_LOCALE *my_default_lc_time_names;

653
SHOW_COMP_OPTION have_ssl, have_symlink, have_dlopen, have_query_cache;
654
SHOW_COMP_OPTION have_geometry, have_rtree_keys;
unknown's avatar
unknown committed
655
SHOW_COMP_OPTION have_crypt, have_compress;
656
SHOW_COMP_OPTION have_profiling;
unknown's avatar
unknown committed
657 658

/* Thread specific variables */
659

unknown's avatar
unknown committed
660
pthread_key(MEM_ROOT**,THR_MALLOC);
unknown's avatar
unknown committed
661
pthread_key(THD*, THR_THD);
Marc Alff's avatar
Marc Alff committed
662
mysql_mutex_t LOCK_thread_count;
663
mysql_mutex_t
Sergei Golubchik's avatar
Sergei Golubchik committed
664
  LOCK_status, LOCK_error_log, LOCK_short_uuid_generator,
Marc Alff's avatar
Marc Alff committed
665 666 667 668 669
  LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
  LOCK_crypt,
  LOCK_global_system_variables,
  LOCK_user_conn, LOCK_slave_list, LOCK_active_mi,
  LOCK_connection_count, LOCK_error_messages;
Sergei Golubchik's avatar
Sergei Golubchik committed
670 671 672

mysql_mutex_t LOCK_stats, LOCK_global_user_client_stats,
              LOCK_global_table_stats, LOCK_global_index_stats;
673

unknown's avatar
unknown committed
674
/**
675 676 677 678 679 680
  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
681
mysql_mutex_t LOCK_prepared_stmt_count;
682
#ifdef HAVE_OPENSSL
Marc Alff's avatar
Marc Alff committed
683
mysql_mutex_t LOCK_des_key_file;
684
#endif
Marc Alff's avatar
Marc Alff committed
685 686
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
687
mysql_cond_t COND_thread_count;
unknown's avatar
unknown committed
688 689
pthread_t signal_thread;
pthread_attr_t connection_attrib;
Marc Alff's avatar
Marc Alff committed
690 691
mysql_mutex_t LOCK_server_started;
mysql_cond_t COND_server_started;
unknown's avatar
unknown committed
692 693

int mysqld_server_started= 0;
unknown's avatar
unknown committed
694

695 696
File_parser_dummy_hook file_parser_dummy_hook;

unknown's avatar
unknown committed
697
/* replication parameters, if master_host is not NULL, we are a slave */
698
uint report_port= 0;
unknown's avatar
unknown committed
699
ulong master_retry_count=0;
700
char *master_info_file;
unknown's avatar
unknown committed
701
char *relay_log_info_file, *report_user, *report_password, *report_host;
unknown's avatar
unknown committed
702
char *opt_relay_logname = 0, *opt_relaylog_index_name=0;
703
char *opt_logname, *opt_slow_logname, *opt_bin_logname;
unknown's avatar
unknown committed
704 705 706

/* Static variables */

707
static volatile sig_atomic_t kill_in_progress;
Michael Widenius's avatar
Michael Widenius committed
708
my_bool opt_stack_trace;
709 710
my_bool opt_expect_abort= 0, opt_bootstrap= 0;
static my_bool opt_myisam_log;
unknown's avatar
unknown committed
711
static int cleanup_done;
712
static ulong opt_specialflag;
Sergei Golubchik's avatar
Sergei Golubchik committed
713
static char *opt_binlog_index_name;
714
char *mysql_home_ptr, *pidfile_name_ptr;
Marc Alff's avatar
Marc Alff committed
715
/** Initial command line arguments (count), after load_defaults().*/
unknown's avatar
unknown committed
716
static int defaults_argc;
Marc Alff's avatar
Marc Alff committed
717 718 719 720 721 722 723 724
/**
  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
725
static char **defaults_argv;
Marc Alff's avatar
Marc Alff committed
726 727 728 729
/** 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
730

731 732 733
int orig_argc;
char **orig_argv;

734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753
#ifdef HAVE_PSI_INTERFACE
#ifdef HAVE_MMAP
PSI_mutex_key key_PAGE_lock, key_LOCK_sync, key_LOCK_active, key_LOCK_pool;
#endif /* HAVE_MMAP */

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

PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_prep_xids,
  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,
  key_LOCK_rpl_status, key_LOCK_server_started, key_LOCK_status,
  key_LOCK_system_variables_hash, key_LOCK_table_share, key_LOCK_thd_data,
  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
754
  key_master_info_sleep_lock,
755 756
  key_mutex_slave_reporting_capability_err_lock, key_relay_log_info_data_lock,
  key_relay_log_info_log_space_lock, key_relay_log_info_run_lock,
Sergei Golubchik's avatar
Sergei Golubchik committed
757
  key_relay_log_info_sleep_lock,
758 759 760 761 762 763 764
  key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data,
  key_LOCK_error_messages, key_LOG_INFO_lock, key_LOCK_thread_count,
  key_PARTITION_LOCK_auto_inc;
PSI_mutex_key key_RELAYLOG_LOCK_index;

PSI_mutex_key key_LOCK_stats,
  key_LOCK_global_user_client_stats, key_LOCK_global_table_stats,
Sergei Golubchik's avatar
Sergei Golubchik committed
765 766 767 768
  key_LOCK_global_index_stats,
  key_LOCK_wakeup_ready;

PSI_mutex_key key_LOCK_prepare_ordered, key_LOCK_commit_ordered;
769 770 771 772 773 774 775 776 777 778 779 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

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},
#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},
  { &key_BINLOG_LOCK_prep_xids, "MYSQL_BIN_LOG::LOCK_prep_xids", 0},
  { &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},
  { &key_LOCK_system_variables_hash, "LOCK_system_variables_hash", PSI_FLAG_GLOBAL},
  { &key_LOCK_table_share, "LOCK_table_share", 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
808
  { &key_LOCK_wakeup_ready, "THD::LOCK_wakeup_ready", 0},
809 810
  { &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
811
  { &key_LOCK_uuid_short_generator, "LOCK_uuid_short_generator", PSI_FLAG_GLOBAL},
812 813 814
  { &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
815
  { &key_master_info_sleep_lock, "Master_info::sleep_lock", 0},
816 817 818 819
  { &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},
Sergei Golubchik's avatar
Sergei Golubchik committed
820
  { &key_relay_log_info_sleep_lock, "Relay_log_info::sleep_lock", 0},
821 822 823
  { &key_structure_guard_mutex, "Query_cache::structure_guard_mutex", 0},
  { &key_TABLE_SHARE_LOCK_ha_data, "TABLE_SHARE::LOCK_ha_data", 0},
  { &key_LOCK_error_messages, "LOCK_error_messages", PSI_FLAG_GLOBAL},
Sergei Golubchik's avatar
Sergei Golubchik committed
824 825
  { &key_LOCK_prepare_ordered, "LOCK_prepare_ordered", PSI_FLAG_GLOBAL},
  { &key_LOCK_commit_ordered, "LOCK_commit_ordered", PSI_FLAG_GLOBAL},
826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848
  { &key_LOG_INFO_lock, "LOG_INFO::lock", 0},
  { &key_LOCK_thread_count, "LOCK_thread_count", PSI_FLAG_GLOBAL},
  { &key_PARTITION_LOCK_auto_inc, "HA_DATA_PARTITION::LOCK_auto_inc", 0}
};

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
849
PSI_cond_key key_PAGE_cond, key_COND_active, key_COND_pool;
850 851 852 853 854 855 856 857
#endif /* HAVE_MMAP */

PSI_cond_key key_BINLOG_COND_prep_xids, key_BINLOG_update_cond,
  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
858
  key_master_info_sleep_cond,
859 860
  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,
Sergei Golubchik's avatar
Sergei Golubchik committed
861
  key_relay_log_info_sleep_cond,
862
  key_TABLE_SHARE_cond, key_user_level_lock_cond,
863 864
  key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache,
  key_BINLOG_COND_queue_busy;
Sergei Golubchik's avatar
Sergei Golubchik committed
865
PSI_cond_key key_RELAYLOG_update_cond, key_COND_wakeup_ready;
866 867
PSI_cond_key key_RELAYLOG_COND_queue_busy;
PSI_cond_key key_TC_LOG_MMAP_COND_queue_busy;
868 869 870 871 872 873 874 875 876 877

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},
878
  { &key_TC_LOG_MMAP_COND_queue_busy, "TC_LOG_MMAP::COND_queue_busy", 0},
879 880 881
#endif /* HAVE_MMAP */
  { &key_BINLOG_COND_prep_xids, "MYSQL_BIN_LOG::COND_prep_xids", 0},
  { &key_BINLOG_update_cond, "MYSQL_BIN_LOG::update_cond", 0},
882
  { &key_BINLOG_COND_queue_busy, "MYSQL_BIN_LOG::COND_queue_busy", 0},
883
  { &key_RELAYLOG_update_cond, "MYSQL_RELAY_LOG::update_cond", 0},
884
  { &key_RELAYLOG_COND_queue_busy, "MYSQL_RELAY_LOG::COND_queue_busy", 0},
Sergei Golubchik's avatar
Sergei Golubchik committed
885
  { &key_COND_wakeup_ready, "THD::COND_wakeup_ready", 0},
886 887 888 889 890 891 892 893 894 895
  { &key_COND_cache_status_changed, "Query_cache::COND_cache_status_changed", 0},
  { &key_COND_manager, "COND_manager", PSI_FLAG_GLOBAL},
  { &key_COND_rpl_status, "COND_rpl_status", 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
896
  { &key_master_info_sleep_cond, "Master_info::sleep_cond", 0},
897 898 899 900
  { &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},
Sergei Golubchik's avatar
Sergei Golubchik committed
901
  { &key_relay_log_info_sleep_cond, "Relay_log_info::sleep_cond", 0},
902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
  { &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},
  { &key_COND_flush_thread_cache, "COND_flush_thread_cache", PSI_FLAG_GLOBAL}
};

PSI_thread_key key_thread_bootstrap, key_thread_delayed_insert,
  key_thread_handle_manager, key_thread_main,
  key_thread_one_connection, key_thread_signal_hand;

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},
  { &key_thread_signal_hand, "signal_handler", PSI_FLAG_GLOBAL}
};

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;

static PSI_file_info all_server_files[]=
{
  { &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},
  { &key_file_init, "init", 0}
};

/**
  Initialise all the performance schema instrumentation points
  used by the server.
*/
void init_server_psi_keys(void)
{
  const char* category= "sql";
  int count;

  if (PSI_server == NULL)
    return;

  count= array_elements(all_server_mutexes);
  PSI_server->register_mutex(category, all_server_mutexes, count);

  count= array_elements(all_server_rwlocks);
  PSI_server->register_rwlock(category, all_server_rwlocks, count);

  count= array_elements(all_server_conds);
  PSI_server->register_cond(category, all_server_conds, count);

  count= array_elements(all_server_threads);
  PSI_server->register_thread(category, all_server_threads, count);

  count= array_elements(all_server_files);
  PSI_server->register_file(category, all_server_files, count);
}

#endif /* HAVE_PSI_INTERFACE */

Marc Alff's avatar
Marc Alff committed
1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068
/*
  Since buffered_option_error_reporter is only used currently
  for parsing performance schema options, this code is not needed
  when the performance schema is not compiled in.
*/
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
/**
  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:
1069 1070 1071 1072 1073 1074 1075 1076 1077
    /*
      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
1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151
    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()
{
  init_alloc_root(&m_root, 1024, 0);
}

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;

1152
#ifndef EMBEDDED_LIBRARY
Marc Alff's avatar
Marc Alff committed
1153 1154 1155 1156 1157
/**
  Error reporter that buffer log messages.
  @param level          log message level
  @param format         log message format string
*/
1158 1159 1160
C_MODE_START
static void buffered_option_error_reporter(enum loglevel level,
                                           const char *format, ...)
Marc Alff's avatar
Marc Alff committed
1161 1162 1163 1164 1165 1166 1167 1168 1169
{
  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);
}
1170 1171
C_MODE_END
#endif /* !EMBEDDED_LIBRARY */
Marc Alff's avatar
Marc Alff committed
1172 1173
#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */

1174
static my_socket unix_sock, base_ip_sock, extra_ip_sock;
1175
struct my_rnd_struct sql_rand; ///< used by sql_class.cc:THD::THD()
unknown's avatar
unknown committed
1176

unknown's avatar
unknown committed
1177 1178 1179 1180 1181
#ifndef EMBEDDED_LIBRARY
struct passwd *user_info;
static pthread_t select_thread;
#endif

unknown's avatar
unknown committed
1182 1183
/* OS specific variables */

unknown's avatar
unknown committed
1184 1185 1186
#ifdef __WIN__
#undef	 getpid
#include <process.h>
unknown's avatar
unknown committed
1187

Marc Alff's avatar
Marc Alff committed
1188
static mysql_cond_t COND_handler_count;
unknown's avatar
unknown committed
1189 1190 1191 1192 1193
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
1194
#if !defined(EMBEDDED_LIBRARY)
unknown's avatar
unknown committed
1195
static HANDLE hEventShutdown;
1196
static char shutdown_event_name[40];
unknown's avatar
unknown committed
1197
#include "nt_servc.h"
unknown's avatar
unknown committed
1198
static	 NTService  Service;	      ///< Service object for WinNT
unknown's avatar
unknown committed
1199 1200 1201
#endif /* EMBEDDED_LIBRARY */
#endif /* __WIN__ */

Vladislav Vaintroub's avatar
Vladislav Vaintroub committed
1202
#ifdef _WIN32
1203
static char pipe_name[512];
unknown's avatar
unknown committed
1204 1205 1206
static SECURITY_ATTRIBUTES saPipeSecurity;
static SECURITY_DESCRIPTOR sdPipeDescriptor;
static HANDLE hPipe = INVALID_HANDLE_VALUE;
unknown's avatar
unknown committed
1207
#endif
unknown's avatar
unknown committed
1208

unknown's avatar
unknown committed
1209
#ifndef EMBEDDED_LIBRARY
1210
bool mysqld_embedded=0;
unknown's avatar
unknown committed
1211
#else
1212
bool mysqld_embedded=1;
unknown's avatar
unknown committed
1213 1214
#endif

1215 1216
static my_bool plugins_are_initialized= FALSE;

unknown's avatar
unknown committed
1217
#ifndef DBUG_OFF
1218
static const char* default_dbug_option;
unknown's avatar
unknown committed
1219
#endif
1220
static const char *current_dbug_option="disabled";
unknown's avatar
unknown committed
1221
#ifdef HAVE_LIBWRAP
1222
const char *libwrapName= NULL;
1223 1224
int allow_severity = LOG_INFO;
int deny_severity = LOG_WARNING;
unknown's avatar
unknown committed
1225 1226 1227 1228 1229 1230 1231
#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;
1232
my_bool opt_enable_shared_memory;
1233
HANDLE smem_event_connect_request= 0;
unknown's avatar
unknown committed
1234 1235
#endif

1236 1237 1238 1239
my_bool opt_use_ssl  = 0;
char *opt_ssl_ca= NULL, *opt_ssl_capath= NULL, *opt_ssl_cert= NULL,
     *opt_ssl_cipher= NULL, *opt_ssl_key= NULL;

Sergei Golubchik's avatar
Sergei Golubchik committed
1240 1241 1242
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
1243

unknown's avatar
unknown committed
1244
#ifdef HAVE_OPENSSL
1245
#include <openssl/crypto.h>
unknown's avatar
unknown committed
1246
#ifndef HAVE_YASSL
1247 1248
typedef struct CRYPTO_dynlock_value
{
Marc Alff's avatar
Marc Alff committed
1249
  mysql_rwlock_t lock;
1250 1251 1252 1253 1254 1255 1256 1257
} 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
1258
#endif
unknown's avatar
unknown committed
1259
char *des_key_file;
Konstantin Osipov's avatar
Konstantin Osipov committed
1260
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
1261
struct st_VioSSLFd *ssl_acceptor_fd;
Konstantin Osipov's avatar
Konstantin Osipov committed
1262
#endif
unknown's avatar
unknown committed
1263 1264
#endif /* HAVE_OPENSSL */

1265 1266 1267 1268
/**
  Number of currently active user connections. The variable is protected by
  LOCK_connection_count.
*/
1269
uint connection_count= 0, extra_connection_count= 0;
unknown's avatar
unknown committed
1270 1271 1272

/* Function declarations */

1273
pthread_handler_t signal_hand(void *arg);
1274
static int mysql_init_variables(void);
Marc Alff's avatar
Marc Alff committed
1275 1276
static int get_options(int *argc_ptr, char ***argv_ptr);
static bool add_terminator(DYNAMIC_ARRAY *options);
1277
extern "C" my_bool mysqld_get_one_option(int, const struct my_option *, char *);
1278
static int init_thread_environment();
unknown's avatar
unknown committed
1279
static char *get_relative_path(const char *path);
1280
static int fix_paths(void);
1281 1282 1283 1284
void handle_connections_sockets();
#ifdef _WIN32
pthread_handler_t handle_connections_sockets_thread(void *arg);
#endif
1285
pthread_handler_t kill_server_thread(void *arg);
Marc Alff's avatar
Marc Alff committed
1286
static void bootstrap(MYSQL_FILE *file);
unknown's avatar
unknown committed
1287
static bool read_init_file(char *file_name);
Vladislav Vaintroub's avatar
Vladislav Vaintroub committed
1288
#ifdef _WIN32
1289
pthread_handler_t handle_connections_namedpipes(void *arg);
unknown's avatar
unknown committed
1290
#endif
1291
#ifdef HAVE_SMEM
1292
pthread_handler_t handle_connections_shared_memory(void *arg);
1293
#endif
1294
pthread_handler_t handle_slave(void *arg);
unknown's avatar
unknown committed
1295
static void clean_up(bool print_message);
1296 1297 1298
static int test_if_case_insensitive(const char *dir_name);

#ifndef EMBEDDED_LIBRARY
1299
static bool pid_file_created= false;
1300
static void usage(void);
1301 1302
static void start_signal_handler(void);
static void close_server_sock();
unknown's avatar
unknown committed
1303
static void clean_up_mutexes(void);
1304
static void wait_for_signal_thread_to_end(void);
1305
static void create_pid_file();
1306
static void mysqld_exit(int exit_code) __attribute__((noreturn));
1307
#endif
1308
static void delete_pid_file(myf flags);
Konstantin Osipov's avatar
Konstantin Osipov committed
1309
static void end_ssl();
1310

1311 1312

#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328
/****************************************************************************
** 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 */
1329
#if !defined(__WIN__)
unknown's avatar
unknown committed
1330 1331
  DBUG_PRINT("quit", ("waiting for select thread: 0x%lx",
                      (ulong) select_thread));
Marc Alff's avatar
Marc Alff committed
1332
  mysql_mutex_lock(&LOCK_thread_count);
unknown's avatar
unknown committed
1333 1334 1335 1336 1337 1338

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

unknown's avatar
unknown committed
1341
#ifndef DONT_USE_THR_ALARM
1342
    if (pthread_kill(select_thread, thr_client_alarm))
unknown's avatar
unknown committed
1343 1344
      break;					// allready dead
#endif
1345
    set_timespec(abstime, 2);
1346
    for (uint tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
unknown's avatar
unknown committed
1347
    {
Marc Alff's avatar
Marc Alff committed
1348 1349
      error= mysql_cond_timedwait(&COND_thread_count, &LOCK_thread_count,
                                  &abstime);
unknown's avatar
unknown committed
1350 1351 1352 1353
      if (error != EINTR)
	break;
    }
#ifdef EXTRA_DEBUG
1354
    if (error != 0 && error != ETIMEDOUT && !count++)
Marc Alff's avatar
Marc Alff committed
1355
      sql_print_error("Got error %d from mysql_cond_timedwait", error);
unknown's avatar
unknown committed
1356
#endif
unknown's avatar
unknown committed
1357
    close_server_sock();
unknown's avatar
unknown committed
1358
  }
Marc Alff's avatar
Marc Alff committed
1359
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
1360 1361 1362 1363 1364
#endif /* __WIN__ */


  /* Abort listening to new connections */
  DBUG_PRINT("quit",("Closing sockets"));
unknown's avatar
Merge  
unknown committed
1365
  if (!opt_disable_networking )
unknown's avatar
unknown committed
1366
  {
1367
    if (base_ip_sock != INVALID_SOCKET)
unknown's avatar
unknown committed
1368
    {
Sergei Golubchik's avatar
c  
Sergei Golubchik committed
1369
      (void) mysql_socket_shutdown(base_ip_sock, SHUT_RDWR);
1370 1371 1372 1373
      (void) closesocket(base_ip_sock);
      base_ip_sock= INVALID_SOCKET;
    }
    if (extra_ip_sock != INVALID_SOCKET)
unknown's avatar
unknown committed
1374
    {
Sergei Golubchik's avatar
c  
Sergei Golubchik committed
1375
      (void) mysql_socket_shutdown(extra_ip_sock, SHUT_RDWR);
1376 1377
      (void) closesocket(extra_ip_sock);
      extra_ip_sock= INVALID_SOCKET;
unknown's avatar
unknown committed
1378 1379
    }
  }
Vladislav Vaintroub's avatar
Vladislav Vaintroub committed
1380
#ifdef _WIN32
unknown's avatar
unknown committed
1381
  if (hPipe != INVALID_HANDLE_VALUE && opt_enable_named_pipe)
unknown's avatar
unknown committed
1382
  {
unknown's avatar
merge  
unknown committed
1383
    HANDLE temp;
unknown's avatar
Merge  
unknown committed
1384
    DBUG_PRINT("quit", ("Closing named pipes") );
1385

unknown's avatar
merge  
unknown committed
1386
    /* Create connection to the handle named pipe handler to break the loop */
1387
    if ((temp = CreateFile(pipe_name,
unknown's avatar
merge  
unknown committed
1388 1389 1390 1391 1392 1393 1394
			   GENERIC_READ | GENERIC_WRITE,
			   0,
			   NULL,
			   OPEN_EXISTING,
			   0,
			   NULL )) != INVALID_HANDLE_VALUE)
    {
1395
      WaitNamedPipe(pipe_name, 1000);
unknown's avatar
merge  
unknown committed
1396 1397 1398 1399 1400 1401
      DWORD dwMode = PIPE_READMODE_BYTE | PIPE_WAIT;
      SetNamedPipeHandleState(temp, &dwMode, NULL, NULL);
      CancelIo(temp);
      DisconnectNamedPipe(temp);
      CloseHandle(temp);
    }
unknown's avatar
unknown committed
1402 1403 1404 1405 1406
  }
#endif
#ifdef HAVE_SYS_UN_H
  if (unix_sock != INVALID_SOCKET)
  {
Sergei Golubchik's avatar
c  
Sergei Golubchik committed
1407
    (void) mysql_socket_shutdown(unix_sock, SHUT_RDWR);
unknown's avatar
unknown committed
1408
    (void) closesocket(unix_sock);
1409
    (void) unlink(mysqld_unix_port);
unknown's avatar
unknown committed
1410 1411 1412
    unix_sock= INVALID_SOCKET;
  }
#endif
1413
  end_thr_alarm(0);			 // Abort old alarms.
unknown's avatar
unknown committed
1414

1415 1416 1417 1418 1419
  /*
    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
1420 1421

  THD *tmp;
Marc Alff's avatar
Marc Alff committed
1422
  mysql_mutex_lock(&LOCK_thread_count); // For unlink from list
unknown's avatar
unknown committed
1423 1424 1425 1426 1427 1428

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

1433
    tmp->killed= KILL_SERVER_HARD;
Sergei Golubchik's avatar
Sergei Golubchik committed
1434
    MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (tmp));
1435
    mysql_mutex_lock(&tmp->LOCK_thd_data);
unknown's avatar
unknown committed
1436 1437 1438
    if (tmp->mysys_var)
    {
      tmp->mysys_var->abort=1;
Marc Alff's avatar
Marc Alff committed
1439
      mysql_mutex_lock(&tmp->mysys_var->mutex);
unknown's avatar
unknown committed
1440
      if (tmp->mysys_var->current_cond)
unknown's avatar
unknown committed
1441
      {
1442 1443 1444
        uint i;
        for (i=0; i < 2; i++)
        {
Sergei Golubchik's avatar
Sergei Golubchik committed
1445 1446
          int ret= mysql_mutex_trylock(tmp->mysys_var->current_mutex);
          mysql_cond_broadcast(tmp->mysys_var->current_cond);
1447 1448 1449
          if (!ret)
          {
            /* Thread has surely got the signal, unlock and abort */
Sergei Golubchik's avatar
Sergei Golubchik committed
1450
            mysql_mutex_unlock(tmp->mysys_var->current_mutex);
1451 1452 1453 1454
            break;
          }
          sleep(1);
        }
unknown's avatar
unknown committed
1455
      }
Marc Alff's avatar
Marc Alff committed
1456
      mysql_mutex_unlock(&tmp->mysys_var->mutex);
unknown's avatar
unknown committed
1457
    }
1458
    mysql_mutex_unlock(&tmp->LOCK_thd_data);
unknown's avatar
unknown committed
1459
  }
Marc Alff's avatar
Marc Alff committed
1460
  mysql_mutex_unlock(&LOCK_thread_count); // For unlink from list
unknown's avatar
unknown committed
1461

1462
  Events::deinit();
1463 1464
  end_slave();

1465 1466 1467
  /* Give threads time to die. */
  for (int i= 0; thread_count && i < 100; i++)
    my_sleep(20000);
unknown's avatar
unknown committed
1468

1469 1470 1471 1472 1473
  /*
    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
1474 1475 1476 1477

  for (;;)
  {
    DBUG_PRINT("quit",("Locking LOCK_thread_count"));
Marc Alff's avatar
Marc Alff committed
1478
    mysql_mutex_lock(&LOCK_thread_count); // For unlink from list
unknown's avatar
unknown committed
1479 1480 1481
    if (!(tmp=threads.get()))
    {
      DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
Marc Alff's avatar
Marc Alff committed
1482
      mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
1483 1484 1485
      break;
    }
#ifndef __bsdi__				// Bug in BSDI kernel
1486
    if (tmp->vio_ok())
unknown's avatar
unknown committed
1487
    {
1488
      if (global_system_variables.log_warnings)
1489
        sql_print_warning(ER_DEFAULT(ER_FORCING_CLOSE),my_progname,
1490
                          tmp->thread_id,
1491 1492
                          (tmp->main_security_ctx.user ?
                           tmp->main_security_ctx.user : ""));
Sergei Golubchik's avatar
Sergei Golubchik committed
1493
      close_connection(tmp,ER_SERVER_SHUTDOWN);
unknown's avatar
unknown committed
1494 1495 1496
    }
#endif
    DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
Marc Alff's avatar
Marc Alff committed
1497
    mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
1498 1499 1500
  }
  /* 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
1501
  mysql_mutex_lock(&LOCK_thread_count);
unknown's avatar
unknown committed
1502 1503
  while (thread_count)
  {
Marc Alff's avatar
Marc Alff committed
1504
    mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
unknown's avatar
unknown committed
1505 1506
    DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
  }
Marc Alff's avatar
Marc Alff committed
1507
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
1508 1509 1510 1511 1512

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

1513

1514
#ifdef HAVE_CLOSE_SERVER_SOCK
1515
static void close_socket(my_socket sock, const char *info)
unknown's avatar
unknown committed
1516
{
1517 1518 1519
  DBUG_ENTER("close_socket");

  if (sock != INVALID_SOCKET)
unknown's avatar
unknown committed
1520
  {
1521
    DBUG_PRINT("info", ("calling shutdown on %s socket", info));
Sergei Golubchik's avatar
c  
Sergei Golubchik committed
1522
    (void) mysql_socket_shutdown(sock, SHUT_RDWR);
unknown's avatar
unknown committed
1523
#if defined(__NETWARE__)
1524
    /*
unknown's avatar
unknown committed
1525 1526
      The following code is disabled for normal systems as it causes MySQL
      to hang on AIX 4.3 during shutdown
1527
    */
1528 1529
    DBUG_PRINT("info", ("calling closesocket on %s socket", info));
    (void) closesocket(tmp_sock);
1530
#endif
unknown's avatar
unknown committed
1531
  }
1532 1533
  DBUG_VOID_RETURN;
}
1534
#endif
1535 1536


1537
static void close_server_sock()
unknown's avatar
unknown committed
1538
{
1539
#ifdef HAVE_CLOSE_SERVER_SOCK
unknown's avatar
unknown committed
1540
  DBUG_ENTER("close_server_sock");
1541 1542 1543 1544 1545 1546

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

  if (unix_sock != INVALID_SOCKET)
Konstantin Osipov's avatar
Konstantin Osipov committed
1547
    (void) unlink(mysqld_unix_port);
1548
  base_ip_sock= extra_ip_sock= unix_sock= INVALID_SOCKET;
Sergei Golubchik's avatar
Sergei Golubchik committed
1549

unknown's avatar
unknown committed
1550 1551
  DBUG_VOID_RETURN;
#endif
1552
}
unknown's avatar
unknown committed
1553

1554 1555
#endif /*EMBEDDED_LIBRARY*/

1556

unknown's avatar
unknown committed
1557 1558 1559 1560
void kill_mysql(void)
{
  DBUG_ENTER("kill_mysql");

1561
#if defined(SIGNALS_DONT_BREAK_READ) && !defined(EMBEDDED_LIBRARY)
1562 1563
  abort_loop=1;					// Break connection loops
  close_server_sock();				// Force accept to wake up
1564
#endif
unknown's avatar
unknown committed
1565

unknown's avatar
unknown committed
1566
#if defined(__WIN__)
unknown's avatar
unknown committed
1567
#if !defined(EMBEDDED_LIBRARY)
unknown's avatar
unknown committed
1568 1569 1570 1571 1572
  {
    if (!SetEvent(hEventShutdown))
    {
      DBUG_PRINT("error",("Got error: %ld from SetEvent",GetLastError()));
    }
1573 1574 1575 1576 1577 1578
    /*
      or:
      HANDLE hEvent=OpenEvent(0, FALSE, "MySqlShutdown");
      SetEvent(hEventShutdown);
      CloseHandle(hEvent);
    */
unknown's avatar
unknown committed
1579
  }
unknown's avatar
unknown committed
1580
#endif
unknown's avatar
unknown committed
1581
#elif defined(HAVE_PTHREAD_KILL)
1582
  if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL))
unknown's avatar
unknown committed
1583 1584 1585 1586
  {
    DBUG_PRINT("error",("Got error %d from pthread_kill",errno)); /* purecov: inspected */
  }
#elif !defined(SIGNALS_DONT_BREAK_READ)
1587
  kill(current_pid, MYSQL_KILL_SIGNAL);
unknown's avatar
unknown committed
1588
#endif
unknown's avatar
unknown committed
1589 1590 1591
  DBUG_PRINT("quit",("After pthread_kill"));
  shutdown_in_progress=1;			// Safety if kill didn't work
#ifdef SIGNALS_DONT_BREAK_READ
1592
  if (!kill_in_progress)
unknown's avatar
unknown committed
1593 1594
  {
    pthread_t tmp;
unknown's avatar
unknown committed
1595
    abort_loop=1;
Marc Alff's avatar
Marc Alff committed
1596 1597 1598
    if (mysql_thread_create(0, /* Not instrumented */
                            &tmp, &connection_attrib, kill_server_thread,
                            (void*) 0))
1599
      sql_print_error("Can't create thread to kill server");
unknown's avatar
unknown committed
1600
  }
1601
#endif
unknown's avatar
unknown committed
1602
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
1603 1604
}

unknown's avatar
unknown committed
1605 1606
/**
  Force server down. Kill all connections and threads and exit.
1607

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

unknown's avatar
unknown committed
1610
  @note
1611 1612 1613 1614
    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
1615

1616
#if !defined(__WIN__)
unknown's avatar
unknown committed
1617
static void *kill_server(void *sig_ptr)
1618
#define RETURN_FROM_KILL_SERVER return 0
unknown's avatar
unknown committed
1619 1620
#else
static void __cdecl kill_server(int sig_ptr)
1621
#define RETURN_FROM_KILL_SERVER return
unknown's avatar
unknown committed
1622 1623 1624
#endif
{
  DBUG_ENTER("kill_server");
1625
#ifndef EMBEDDED_LIBRARY
unknown's avatar
Merge  
unknown committed
1626
  int sig=(int) (long) sig_ptr;			// This is passed a int
1627
  // if there is a signal during the kill in progress, ignore the other
unknown's avatar
unknown committed
1628
  if (kill_in_progress)				// Safety
1629 1630
  {
    DBUG_LEAVE;
unknown's avatar
unknown committed
1631
    RETURN_FROM_KILL_SERVER;
1632
  }
unknown's avatar
unknown committed
1633 1634
  kill_in_progress=TRUE;
  abort_loop=1;					// This should be set
1635
  if (sig != 0) // 0 is not a valid signal number
1636
    my_sigset(sig, SIG_IGN);                    /* purify inspected */
unknown's avatar
unknown committed
1637
  if (sig == MYSQL_KILL_SIGNAL || sig == 0)
1638
    sql_print_information(ER_DEFAULT(ER_NORMAL_SHUTDOWN),my_progname);
unknown's avatar
unknown committed
1639
  else
1640
    sql_print_error(ER_DEFAULT(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */
unknown's avatar
unknown committed
1641

Sergei Golubchik's avatar
Sergei Golubchik committed
1642
#ifdef HAVE_SMEM
1643
  /*
Sergei Golubchik's avatar
Sergei Golubchik committed
1644 1645
    Send event to smem_event_connect_request for aborting
  */
1646
  if (opt_enable_shared_memory)
1647
  {
1648 1649 1650 1651 1652 1653
    if (!SetEvent(smem_event_connect_request))
    {
      DBUG_PRINT("error",
                 ("Got error: %ld from SetEvent of smem_event_connect_request",
                  GetLastError()));
    }
1654 1655 1656
  }
#endif

unknown's avatar
unknown committed
1657
  close_connections();
1658 1659
  if (sig != MYSQL_KILL_SIGNAL &&
      sig != 0)
unknown's avatar
unknown committed
1660 1661
    unireg_abort(1);				/* purecov: inspected */
  else
1662
    unireg_end();
unknown's avatar
Merge  
unknown committed
1663

1664
  /* purecov: begin deadcode */
1665
  DBUG_LEAVE;                                   // Must match DBUG_ENTER()
1666
  my_thread_end();
1667 1668
  pthread_exit(0);
  /* purecov: end */
unknown's avatar
unknown committed
1669

1670 1671 1672 1673 1674
  RETURN_FROM_KILL_SERVER;                      // Avoid compiler warnings

#else /* EMBEDDED_LIBRARY*/

  DBUG_LEAVE;
unknown's avatar
unknown committed
1675
  RETURN_FROM_KILL_SERVER;
1676 1677

#endif /* EMBEDDED_LIBRARY */
unknown's avatar
unknown committed
1678 1679 1680
}


1681
#if defined(USE_ONE_SIGNAL_HAND)
1682
pthread_handler_t kill_server_thread(void *arg __attribute__((unused)))
unknown's avatar
unknown committed
1683 1684 1685
{
  my_thread_init();				// Initialize new thread
  kill_server(0);
1686 1687 1688
  /* purecov: begin deadcode */
  my_thread_end();
  pthread_exit(0);
unknown's avatar
unknown committed
1689
  return 0;
1690
  /* purecov: end */
unknown's avatar
unknown committed
1691 1692 1693
}
#endif

1694

1695
extern "C" sig_handler print_signal_warning(int sig)
unknown's avatar
unknown committed
1696
{
unknown's avatar
unknown committed
1697
  if (global_system_variables.log_warnings)
1698
    sql_print_warning("Got signal %d from thread %ld", sig,my_thread_id());
1699
#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY
1700
  my_sigset(sig,print_signal_warning);		/* int. thread system calls */
unknown's avatar
unknown committed
1701
#endif
1702
#if !defined(__WIN__)
unknown's avatar
unknown committed
1703 1704 1705 1706 1707
  if (sig == SIGALRM)
    alarm(2);					/* reschedule alarm */
#endif
}

unknown's avatar
unknown committed
1708
#ifndef EMBEDDED_LIBRARY
1709

1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721
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
1722 1723
/**
  cleanup all memory and end program nicely.
unknown's avatar
unknown committed
1724

1725 1726 1727
    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
1728

unknown's avatar
unknown committed
1729 1730 1731
  @note
    This function never returns.
*/
1732
void unireg_end(void)
unknown's avatar
unknown committed
1733
{
unknown's avatar
unknown committed
1734
  clean_up(1);
unknown's avatar
unknown committed
1735
  my_thread_end();
1736
#if defined(SIGNALS_DONT_BREAK_READ)
1737 1738
  exit(0);
#else
unknown's avatar
unknown committed
1739
  pthread_exit(0);				// Exit is in main thread
1740
#endif
unknown's avatar
unknown committed
1741 1742
}

1743

1744
extern "C" void unireg_abort(int exit_code)
unknown's avatar
unknown committed
1745
{
1746
  DBUG_ENTER("unireg_abort");
1747

1748 1749
  if (opt_help)
    usage();
unknown's avatar
unknown committed
1750 1751
  if (exit_code)
    sql_print_error("Aborting\n");
1752
  clean_up(!opt_abort && (exit_code || !opt_bootstrap)); /* purecov: inspected */
1753
  DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
1754 1755 1756 1757 1758
  mysqld_exit(exit_code);
}

static void mysqld_exit(int exit_code)
{
1759 1760 1761 1762 1763
  /*
    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.
  */
1764
  wait_for_signal_thread_to_end();
1765
  mysql_audit_finalize();
unknown's avatar
unknown committed
1766
  clean_up_mutexes();
Marc Alff's avatar
Marc Alff committed
1767
  clean_up_error_log_mutex();
1768
  my_end((opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0));
1769
  shutdown_performance_schema();        // we do it as late as possible
unknown's avatar
unknown committed
1770 1771
  exit(exit_code); /* purecov: inspected */
}
1772

1773
#endif /* !EMBEDDED_LIBRARY */
unknown's avatar
unknown committed
1774

1775
void clean_up(bool print_message)
unknown's avatar
unknown committed
1776 1777 1778 1779
{
  DBUG_PRINT("exit",("clean_up"));
  if (cleanup_done++)
    return; /* purecov: inspected */
unknown's avatar
unknown committed
1780

1781
  close_active_mi();
1782
  stop_handle_manager();
1783 1784
  release_ddl_log();

unknown's avatar
unknown committed
1785 1786 1787 1788 1789
  /*
    make sure that handlers finish up
    what they have that is dependent on the binlog
  */
  ha_binlog_end(current_thd);
unknown's avatar
unknown committed
1790 1791 1792

  logger.cleanup_base();

1793
  injector::free_instance();
unknown's avatar
unknown committed
1794 1795
  mysql_bin_log.cleanup();

unknown's avatar
SCRUM  
unknown committed
1796
#ifdef HAVE_REPLICATION
unknown's avatar
unknown committed
1797 1798
  if (use_slave_mask)
    bitmap_free(&slave_error_mask);
1799
#endif
1800
  my_tz_free();
1801
  my_dboptions_cache_free();
1802
  ignore_db_dirs_free();
unknown's avatar
unknown committed
1803
#ifndef NO_EMBEDDED_ACCESS_CHECKS
unknown's avatar
unknown committed
1804
  servers_free(1);
unknown's avatar
unknown committed
1805 1806
  acl_free(1);
  grant_free();
unknown's avatar
unknown committed
1807
#endif
unknown's avatar
unknown committed
1808
  query_cache_destroy();
unknown's avatar
unknown committed
1809 1810 1811
  hostname_cache_free();
  item_user_lock_free();
  lex_free();				/* Free some memory */
1812
  item_create_cleanup();
unknown's avatar
unknown committed
1813
  if (!opt_noacl)
1814
  {
1815
#ifdef HAVE_DLOPEN
unknown's avatar
unknown committed
1816
    udf_free();
1817
#endif
1818
  }
Konstantin Osipov's avatar
Konstantin Osipov committed
1819
  table_def_start_shutdown();
1820
  plugin_shutdown();
1821
  ha_end();
unknown's avatar
Merge  
unknown committed
1822 1823
  if (tc_log)
    tc_log->close();
He Zhenxing's avatar
He Zhenxing committed
1824
  delegates_destroy();
1825
  xid_cache_free();
Konstantin Osipov's avatar
Konstantin Osipov committed
1826 1827
  table_def_free();
  mdl_destroy();
1828
  key_caches.delete_elements((void (*)(const char*, uchar*)) free_key_cache);
1829
  wt_end();
1830
  multi_keycache_free();
1831
  sp_cache_end();
1832
  free_status_vars();
1833
  end_thr_alarm(1);			/* Free allocated memory */
1834
  my_free_open_file_info();
unknown's avatar
unknown committed
1835 1836
  if (defaults_argv)
    free_defaults(defaults_argv);
unknown's avatar
unknown committed
1837
  free_tmpdir(&mysql_tmpdir_list);
unknown's avatar
unknown committed
1838
  bitmap_free(&temp_pool);
unknown's avatar
unknown committed
1839
  free_max_user_conn();
1840 1841 1842 1843
  free_global_user_stats();
  free_global_client_stats();
  free_global_table_stats();
  free_global_index_stats();
1844
  delete_dynamic(&all_options);
unknown's avatar
SCRUM  
unknown committed
1845
#ifdef HAVE_REPLICATION
1846
  end_slave_list();
1847
#endif
1848
  my_uuid_end();
unknown's avatar
unknown committed
1849 1850
  delete binlog_filter;
  delete rpl_filter;
1851
  end_ssl();
1852
  vio_end();
unknown's avatar
unknown committed
1853
  my_regex_end();
1854 1855 1856 1857
#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
1858

1859
  delete_pid_file(MYF(0));
1860

1861
  if (print_message && my_default_lc_messages && server_start_time)
1862 1863
    sql_print_information(ER_DEFAULT(ER_SHUTDOWN_COMPLETE),my_progname);
  cleanup_errmsgs();
Sergei Golubchik's avatar
Sergei Golubchik committed
1864
  MYSQL_CALLBACK(thread_scheduler, end, ());
1865
  mysql_library_end();
unknown's avatar
Merge  
unknown committed
1866
  finish_client_errs();
1867
  (void) my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST); // finish server errs
1868
  DBUG_PRINT("quit", ("Error messages freed"));
unknown's avatar
unknown committed
1869
  /* Tell main we are ready */
unknown's avatar
unknown committed
1870
  logger.cleanup_end();
1871
  sys_var_end();
1872
  my_atomic_rwlock_destroy(&global_query_id_lock);
1873
  my_atomic_rwlock_destroy(&thread_running_lock);
1874
  free_charsets();
Marc Alff's avatar
Marc Alff committed
1875
  mysql_mutex_lock(&LOCK_thread_count);
1876
  DBUG_PRINT("quit", ("got thread count lock"));
unknown's avatar
unknown committed
1877
  ready_to_exit=1;
unknown's avatar
unknown committed
1878
  /* do the broadcast inside the lock to ensure that my_end() is not called */
Marc Alff's avatar
Marc Alff committed
1879 1880
  mysql_cond_broadcast(&COND_thread_count);
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
1881

unknown's avatar
unknown committed
1882 1883 1884 1885
  /*
    The following lines may never be executed as the main thread may have
    killed us
  */
1886
  DBUG_PRINT("quit", ("done with cleanup"));
unknown's avatar
unknown committed
1887 1888 1889
} /* clean_up */


1890 1891
#ifndef EMBEDDED_LIBRARY

unknown's avatar
unknown committed
1892
/**
1893
  This is mainly needed when running with purify, but it's still nice to
unknown's avatar
unknown committed
1894
  know that all child threads have died when mysqld exits.
1895 1896 1897 1898 1899 1900 1901 1902 1903 1904
*/
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++)
  {
1905
    if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL) == ESRCH)
1906 1907 1908 1909
      break;
    my_sleep(100);				// Give it time to die
  }
}
1910
#endif /*EMBEDDED_LIBRARY*/
1911

unknown's avatar
unknown committed
1912 1913
static void clean_up_mutexes()
{
1914
  DBUG_ENTER("clean_up_mutexes");
Marc Alff's avatar
Marc Alff committed
1915
  mysql_rwlock_destroy(&LOCK_grant);
Marc Alff's avatar
Marc Alff committed
1916
  mysql_mutex_destroy(&LOCK_thread_count);
Marc Alff's avatar
Marc Alff committed
1917 1918 1919 1920
  mysql_mutex_destroy(&LOCK_status);
  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
1921 1922 1923
  mysql_mutex_destroy(&LOCK_crypt);
  mysql_mutex_destroy(&LOCK_user_conn);
  mysql_mutex_destroy(&LOCK_connection_count);
Sergei Golubchik's avatar
Sergei Golubchik committed
1924 1925 1926 1927
  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);
1928
#ifdef HAVE_OPENSSL
Marc Alff's avatar
Marc Alff committed
1929
  mysql_mutex_destroy(&LOCK_des_key_file);
unknown's avatar
unknown committed
1930
#ifndef HAVE_YASSL
1931
  for (int i= 0; i < CRYPTO_num_locks(); ++i)
1932
    mysql_rwlock_destroy(&openssl_stdlocks[i].lock);
1933
  OPENSSL_free(openssl_stdlocks);
Michael Widenius's avatar
Michael Widenius committed
1934 1935
#endif /* HAVE_YASSL */
#endif /* HAVE_OPENSSL */
1936
#ifdef HAVE_REPLICATION
Marc Alff's avatar
Marc Alff committed
1937 1938
  mysql_mutex_destroy(&LOCK_rpl_status);
  mysql_cond_destroy(&COND_rpl_status);
Michael Widenius's avatar
Michael Widenius committed
1939
#endif /* HAVE_REPLICATION */
Marc Alff's avatar
Marc Alff committed
1940 1941 1942 1943 1944
  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
1945
  mysql_mutex_destroy(&LOCK_short_uuid_generator);
Marc Alff's avatar
Marc Alff committed
1946 1947
  mysql_mutex_destroy(&LOCK_prepared_stmt_count);
  mysql_mutex_destroy(&LOCK_error_messages);
Marc Alff's avatar
Marc Alff committed
1948 1949 1950
  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
1951 1952
  mysql_mutex_destroy(&LOCK_server_started);
  mysql_cond_destroy(&COND_server_started);
Sergei Golubchik's avatar
Sergei Golubchik committed
1953 1954
  mysql_mutex_destroy(&LOCK_prepare_ordered);
  mysql_mutex_destroy(&LOCK_commit_ordered);
1955
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
1956
}
1957 1958


unknown's avatar
unknown committed
1959 1960 1961 1962
/****************************************************************************
** Init IP and UNIX socket
****************************************************************************/

unknown's avatar
unknown committed
1963
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
1964 1965 1966
static void set_ports()
{
  char	*env;
1967
  if (!mysqld_port && !opt_disable_networking)
unknown's avatar
unknown committed
1968
  {					// Get port if not from commandline
1969
    mysqld_port= MYSQL_PORT;
1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981

    /*
      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
1982
    struct  servent *serv_ptr;
1983 1984
    if ((serv_ptr= getservbyname("mysql", "tcp")))
      mysqld_port= ntohs((u_short) serv_ptr->s_port); /* purecov: inspected */
1985
#endif
unknown's avatar
unknown committed
1986
    if ((env = getenv("MYSQL_TCP_PORT")))
1987
      mysqld_port= (uint) atoi(env);		/* purecov: inspected */
unknown's avatar
unknown committed
1988
  }
1989
  if (!mysqld_unix_port)
unknown's avatar
unknown committed
1990 1991
  {
#ifdef __WIN__
1992
    mysqld_unix_port= (char*) MYSQL_NAMEDPIPE;
unknown's avatar
unknown committed
1993
#else
1994
    mysqld_unix_port= (char*) MYSQL_UNIX_ADDR;
unknown's avatar
unknown committed
1995 1996
#endif
    if ((env = getenv("MYSQL_UNIX_PORT")))
1997
      mysqld_unix_port= env;			/* purecov: inspected */
unknown's avatar
unknown committed
1998 1999 2000 2001 2002
  }
}

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

2003
static struct passwd *check_user(const char *user)
unknown's avatar
unknown committed
2004
{
2005
#if !defined(__WIN__)
2006
  struct passwd *tmp_user_info;
2007
  uid_t user_id= geteuid();
unknown's avatar
unknown committed
2008

2009
  // Don't bother if we aren't superuser
2010
  if (user_id)
unknown's avatar
unknown committed
2011 2012
  {
    if (user)
2013
    {
2014 2015 2016 2017
      /* 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) &&
2018
	  global_system_variables.log_warnings)
2019 2020
        sql_print_warning(
                    "One can only use the --user switch if running as root\n");
unknown's avatar
unknown committed
2021
      /* purecov: end */
2022
    }
2023
    return NULL;
unknown's avatar
unknown committed
2024
  }
2025
  if (!user)
unknown's avatar
unknown committed
2026 2027 2028
  {
    if (!opt_bootstrap)
    {
unknown's avatar
unknown committed
2029
      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
2030 2031
      unireg_abort(1);
    }
2032
    return NULL;
unknown's avatar
unknown committed
2033
  }
2034
  /* purecov: begin tested */
unknown's avatar
unknown committed
2035
  if (!strcmp(user,"root"))
unknown's avatar
unknown committed
2036
    return NULL;                        // Avoid problem with dynamic libraries
unknown's avatar
unknown committed
2037

2038
  if (!(tmp_user_info= getpwnam(user)))
unknown's avatar
unknown committed
2039
  {
2040
    // Allow a numeric uid to be used
unknown's avatar
unknown committed
2041
    const char *pos;
unknown's avatar
unknown committed
2042 2043
    for (pos= user; my_isdigit(mysqld_charset,*pos); pos++) ;
    if (*pos)                                   // Not numeric id
2044
      goto err;
2045
    if (!(tmp_user_info= getpwuid(atoi(user))))
2046
      goto err;
unknown's avatar
unknown committed
2047
  }
2048

unknown's avatar
unknown committed
2049 2050
  return tmp_user_info;
  /* purecov: end */
2051 2052

err:
unknown's avatar
unknown committed
2053
  sql_print_error("Fatal error: Can't change to run as user '%s' ;  Please check that the user exists!\n",user);
2054
  unireg_abort(1);
2055 2056 2057
#endif
  return NULL;
}
2058

2059 2060
static inline void allow_coredumps()
{
2061 2062 2063 2064 2065 2066 2067
#ifdef PR_SET_DUMPABLE
  if (test_flags & TEST_CORE_ON_SIGNAL)
  {
    /* inform kernel that process is dumpable */
    (void) prctl(PR_SET_DUMPABLE, 1);
  }
#endif
2068 2069
}

2070

2071
static void set_user(const char *user, struct passwd *user_info_arg)
2072
{
2073
  /* purecov: begin tested */
2074
#if !defined(__WIN__)
2075
  DBUG_ASSERT(user_info_arg != 0);
unknown's avatar
unknown committed
2076
#ifdef HAVE_INITGROUPS
2077 2078 2079 2080 2081 2082
  /*
    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.
  */
2083
  calling_initgroups= 1;
2084
  initgroups((char*) user, user_info_arg->pw_gid);
2085
  calling_initgroups= 0;
unknown's avatar
unknown committed
2086
#endif
2087
  if (setgid(user_info_arg->pw_gid) == -1)
2088 2089 2090
  {
    sql_perror("setgid");
    unireg_abort(1);
unknown's avatar
unknown committed
2091
  }
2092
  if (setuid(user_info_arg->pw_uid) == -1)
unknown's avatar
unknown committed
2093 2094 2095 2096
  {
    sql_perror("setuid");
    unireg_abort(1);
  }
2097
  allow_coredumps();
unknown's avatar
unknown committed
2098
#endif
unknown's avatar
unknown committed
2099
  /* purecov: end */
unknown's avatar
unknown committed
2100 2101
}

unknown's avatar
unknown committed
2102

2103
static void set_effective_user(struct passwd *user_info_arg)
2104
{
2105
#if !defined(__WIN__)
2106 2107
  DBUG_ASSERT(user_info_arg != 0);
  if (setregid((gid_t)-1, user_info_arg->pw_gid) == -1)
2108
  {
2109
    sql_perror("setregid");
2110
    unireg_abort(1);
unknown's avatar
unknown committed
2111
  }
2112
  if (setreuid((uid_t)-1, user_info_arg->pw_uid) == -1)
2113
  {
2114
    sql_perror("setreuid");
2115 2116
    unireg_abort(1);
  }
2117
  allow_coredumps();
2118 2119 2120 2121
#endif
}


unknown's avatar
unknown committed
2122
/** Change root user if started with @c --chroot . */
unknown's avatar
unknown committed
2123 2124
static void set_root(const char *path)
{
2125
#if !defined(__WIN__)
unknown's avatar
unknown committed
2126 2127 2128 2129 2130
  if (chroot(path) == -1)
  {
    sql_perror("chroot");
    unireg_abort(1);
  }
2131
  my_setwd("/", MYF(0));
unknown's avatar
unknown committed
2132 2133 2134
#endif
}

2135 2136 2137
/**
   Activate usage of a tcp port
*/
2138

2139
static my_socket activate_tcp_port(uint port)
unknown's avatar
unknown committed
2140
{
Sergei Golubchik's avatar
Sergei Golubchik committed
2141 2142 2143
  struct addrinfo *ai, *a;
  struct addrinfo hints;
  int error;
2144 2145
  int	arg;
  char port_buf[NI_MAXSERV];
2146
  my_socket ip_sock= INVALID_SOCKET;
2147 2148
  DBUG_ENTER("activate_tcp_port");
  DBUG_PRINT("general",("IP Socket is %d",port));
unknown's avatar
unknown committed
2149

Sergei Golubchik's avatar
Sergei Golubchik committed
2150 2151 2152 2153
  bzero(&hints, sizeof (hints));
  hints.ai_flags= AI_PASSIVE;
  hints.ai_socktype= SOCK_STREAM;
  hints.ai_family= AF_UNSPEC;
unknown's avatar
unknown committed
2154

2155
  my_snprintf(port_buf, NI_MAXSERV, "%d", port);
Sergei Golubchik's avatar
Sergei Golubchik committed
2156 2157
  error= getaddrinfo(my_bind_addr_str, port_buf, &hints, &ai);
  if (error != 0)
unknown's avatar
unknown committed
2158
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
2159 2160 2161 2162
    DBUG_PRINT("error",("Got error: %d from getaddrinfo()", error));
    sql_perror(ER_DEFAULT(ER_IPSOCK_ERROR));  /* purecov: tested */
    unireg_abort(1);				/* purecov: tested */
  }
2163

Sergei Golubchik's avatar
Sergei Golubchik committed
2164 2165
  for (a= ai; a != NULL; a= a->ai_next)
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
2166
    ip_sock= socket(a->ai_family, a->ai_socktype, a->ai_protocol);
Sergei Golubchik's avatar
Sergei Golubchik committed
2167 2168 2169
    if (ip_sock != INVALID_SOCKET)
      break;
  }
2170

2171 2172 2173
  if (ip_sock == INVALID_SOCKET)
  {
    DBUG_PRINT("error",("Got error: %d from socket()",socket_errno));
Sergei Golubchik's avatar
Sergei Golubchik committed
2174
    sql_perror(ER_DEFAULT(ER_IPSOCK_ERROR));  /* purecov: tested */
2175 2176
    unireg_abort(1);				/* purecov: tested */
  }
2177 2178

#ifndef __WIN__
2179 2180 2181 2182
  /*
    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
2183
  arg= 1;
2184
  (void) setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,sizeof(arg));
unknown's avatar
unknown committed
2185
#endif /* __WIN__ */
2186 2187

#ifdef IPV6_V6ONLY
Sergei Golubchik's avatar
Sergei Golubchik committed
2188 2189 2190 2191
   /*
     For interoperability with older clients, IPv6 socket should
     listen on both IPv6 and IPv4 wildcard addresses.
     Turn off IPV6_V6ONLY option.
2192

Sergei Golubchik's avatar
Sergei Golubchik committed
2193 2194 2195 2196 2197 2198 2199 2200 2201 2202
     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;
    (void) setsockopt(ip_sock, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
              sizeof(arg));
  }
2203
#endif
2204 2205 2206 2207 2208 2209 2210 2211
  /*
    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=#).
  */
2212 2213
  int ret;
  uint waited, retry, this_wait;
2214 2215
  for (waited= 0, retry= 1; ; retry++, waited+= this_wait)
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
2216
    if (((ret= bind(ip_sock, a->ai_addr, a->ai_addrlen)) >= 0 ) ||
2217 2218 2219
        (socket_errno != SOCKET_EADDRINUSE) ||
        (waited >= mysqld_port_timeout))
      break;
2220
    sql_print_information("Retrying bind on TCP/IP port %u", port);
2221 2222
    this_wait= retry * retry / 3 + 1;
    sleep(this_wait);
unknown's avatar
unknown committed
2223
  }
Sergei Golubchik's avatar
Sergei Golubchik committed
2224
  freeaddrinfo(ai);
2225 2226
  if (ret < 0)
  {
2227 2228 2229 2230
    char buff[100];
    sprintf(buff, "Can't start server: Bind on TCP/IP port. Got error: %d",
            (int) socket_errno);
    sql_perror(buff);
2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243
    sql_print_error("Do you already have another mysqld server running on "
                    "port: %u ?", port);
    unireg_abort(1);
  }
  if (listen(ip_sock,(int) back_log) < 0)
  {
    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);
  }
  DBUG_RETURN(ip_sock);
}
2244

2245 2246 2247 2248
static void network_init(void)
{
#ifdef HAVE_SYS_UN_H
  struct sockaddr_un	UNIXaddr;
2249
  int	arg;
2250
#endif
unknown's avatar
unknown committed
2251
  DBUG_ENTER("network_init");
unknown's avatar
unknown committed
2252

Sergei Golubchik's avatar
Sergei Golubchik committed
2253
  if (MYSQL_CALLBACK_ELSE(thread_scheduler, init, (), 0))
unknown's avatar
unknown committed
2254 2255
    unireg_abort(1);			/* purecov: inspected */

unknown's avatar
unknown committed
2256 2257
  set_ports();

Sergei Golubchik's avatar
Sergei Golubchik committed
2258
  if (report_port == 0)
unknown's avatar
unknown committed
2259
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
2260
    report_port= mysqld_port;
unknown's avatar
unknown committed
2261
  }
Sergei Golubchik's avatar
c  
Sergei Golubchik committed
2262 2263 2264
#ifndef DBUG_OFF
  if (!opt_disable_networking)
    DBUG_ASSERT(report_port != 0);
2265
#endif
2266
  if (!opt_disable_networking && !opt_bootstrap)
unknown's avatar
unknown committed
2267
  {
2268 2269 2270 2271
    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
2272
  }
2273

2274
#ifdef _WIN32
unknown's avatar
unknown committed
2275
  /* create named pipe */
2276
  if (Service.IsNT() && mysqld_unix_port[0] && !opt_bootstrap &&
unknown's avatar
unknown committed
2277
      opt_enable_named_pipe)
unknown's avatar
unknown committed
2278
  {
2279

2280
    strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\.\\pipe\\",
2281
	     mysqld_unix_port, NullS);
2282 2283
    bzero((char*) &saPipeSecurity, sizeof(saPipeSecurity));
    bzero((char*) &sdPipeDescriptor, sizeof(sdPipeDescriptor));
2284
    if (!InitializeSecurityDescriptor(&sdPipeDescriptor,
2285
				      SECURITY_DESCRIPTOR_REVISION))
unknown's avatar
unknown committed
2286 2287 2288 2289 2290 2291 2292 2293 2294
    {
      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
2295
    saPipeSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
unknown's avatar
unknown committed
2296 2297
    saPipeSecurity.lpSecurityDescriptor = &sdPipeDescriptor;
    saPipeSecurity.bInheritHandle = FALSE;
2298
    if ((hPipe= CreateNamedPipe(pipe_name,
2299
				PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
2300 2301 2302 2303 2304 2305 2306 2307
				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
2308 2309 2310 2311 2312 2313 2314
      {
	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 );
2315
	sql_perror((char *)lpMsgBuf);
unknown's avatar
Merge  
unknown committed
2316
	LocalFree(lpMsgBuf);
unknown's avatar
unknown committed
2317 2318 2319 2320 2321
	unireg_abort(1);
      }
  }
#endif

2322
#if defined(HAVE_SYS_UN_H)
unknown's avatar
unknown committed
2323 2324 2325
  /*
  ** Create the UNIX socket
  */
2326
  if (mysqld_unix_port[0] && !opt_bootstrap)
unknown's avatar
unknown committed
2327
  {
2328
    DBUG_PRINT("general",("UNIX Socket is %s",mysqld_unix_port));
unknown's avatar
unknown committed
2329

unknown's avatar
unknown committed
2330 2331
    if (strlen(mysqld_unix_port) > (sizeof(UNIXaddr.sun_path) - 1))
    {
2332
      sql_print_error("The socket file path is too long (> %u): %s",
unknown's avatar
unknown committed
2333
                      (uint) sizeof(UNIXaddr.sun_path) - 1, mysqld_unix_port);
unknown's avatar
unknown committed
2334 2335
      unireg_abort(1);
    }
2336
    if ((unix_sock= socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
unknown's avatar
unknown committed
2337 2338 2339 2340 2341 2342
    {
      sql_perror("Can't start server : UNIX Socket "); /* purecov: inspected */
      unireg_abort(1);				/* purecov: inspected */
    }
    bzero((char*) &UNIXaddr, sizeof(UNIXaddr));
    UNIXaddr.sun_family = AF_UNIX;
2343 2344
    strmov(UNIXaddr.sun_path, mysqld_unix_port);
    (void) unlink(mysqld_unix_port);
2345
    arg= 1;
unknown's avatar
unknown committed
2346 2347 2348
    (void) setsockopt(unix_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,
		      sizeof(arg));
    umask(0);
2349
    if (bind(unix_sock, reinterpret_cast<struct sockaddr *>(&UNIXaddr),
unknown's avatar
unknown committed
2350 2351 2352
	     sizeof(UNIXaddr)) < 0)
    {
      sql_perror("Can't start server : Bind on unix socket"); /* purecov: tested */
2353
      sql_print_error("Do you already have another mysqld server running on socket: %s ?",mysqld_unix_port);
unknown's avatar
unknown committed
2354 2355 2356 2357
      unireg_abort(1);					/* purecov: tested */
    }
    umask(((~my_umask) & 0666));
#if defined(S_IFSOCK) && defined(SECURE_SOCKETS)
2358
    (void) chmod(mysqld_unix_port,S_IFSOCK);	/* Fix solaris 2.6 bug */
unknown's avatar
unknown committed
2359
#endif
2360
    if (listen(unix_sock,(int) back_log) < 0)
2361
      sql_print_warning("listen() on Unix socket failed with error %d",
unknown's avatar
unknown committed
2362
		      socket_errno);
unknown's avatar
unknown committed
2363 2364 2365 2366 2367 2368
  }
#endif
  DBUG_PRINT("info",("server started"));
  DBUG_VOID_RETURN;
}

Sergei Golubchik's avatar
Sergei Golubchik committed
2369

unknown's avatar
unknown committed
2370 2371
/**
  Close a connection.
2372

2373 2374
  @param thd        Thread handle.
  @param sql_errno  The error code to send before disconnect.
2375

unknown's avatar
unknown committed
2376
  @note
2377 2378
    For the connection that is doing shutdown, this is called twice
*/
2379
void close_connection(THD *thd, uint sql_errno)
unknown's avatar
unknown committed
2380 2381
{
  DBUG_ENTER("close_connection");
2382 2383 2384 2385

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

Sergei Golubchik's avatar
Sergei Golubchik committed
2386 2387
  thd->print_aborted_warning(3, sql_errno ? ER_DEFAULT(sql_errno)
                                          : "CLOSE_CONNECTION");
2388

2389 2390 2391 2392
  thd->disconnect();

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

2393 2394 2395 2396
  if (MYSQL_CONNECTION_DONE_ENABLED())
  {
    sleep(0); /* Workaround to avoid tailcall optimisation */
  }
2397
  MYSQL_AUDIT_NOTIFY_CONNECTION_DISCONNECT(thd, sql_errno);
unknown's avatar
unknown committed
2398 2399
  DBUG_VOID_RETURN;
}
2400 2401
#endif /* EMBEDDED_LIBRARY */

unknown's avatar
unknown committed
2402

2403
/** Called when mysqld is aborted with ^C */
unknown's avatar
unknown committed
2404
/* ARGSUSED */
2405
extern "C" sig_handler end_mysqld_signal(int sig __attribute__((unused)))
unknown's avatar
unknown committed
2406
{
2407
  DBUG_ENTER("end_mysqld_signal");
2408 2409
  /* Don't call kill_mysql() if signal thread is not running */
  if (signal_thread_in_use)
Sergei Golubchik's avatar
Sergei Golubchik committed
2410
    kill_mysql();                          // Take down mysqld nicely
unknown's avatar
unknown committed
2411 2412 2413 2414
  DBUG_VOID_RETURN;				/* purecov: deadcode */
}


2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427
/*
  Cleanup THD object

  SYNOPSIS
    thd_cleanup()
    thd		 Thread handler
*/

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

2428 2429 2430 2431 2432 2433 2434
/*
  Decrease number of connections

  SYNOPSIS
    dec_connection_count()
*/

Sergei Golubchik's avatar
Sergei Golubchik committed
2435
void dec_connection_count(THD *thd)
2436 2437
{
  mysql_mutex_lock(&LOCK_connection_count);
Sergei Golubchik's avatar
Sergei Golubchik committed
2438
  (*thd->scheduler->connection_count)--;
2439 2440 2441 2442
  mysql_mutex_unlock(&LOCK_connection_count);
}


unknown's avatar
unknown committed
2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454
/*
  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
2455
{
unknown's avatar
unknown committed
2456 2457
  DBUG_ENTER("unlink_thd");
  DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd));
2458

2459
  thd_cleanup(thd);
Sergei Golubchik's avatar
Sergei Golubchik committed
2460
  dec_connection_count(thd);
2461 2462 2463 2464 2465

  mysql_mutex_lock(&LOCK_status);
  add_to_status(&global_status_var, &thd->status_var);
  mysql_mutex_unlock(&LOCK_status);

Marc Alff's avatar
Marc Alff committed
2466
  mysql_mutex_lock(&LOCK_thread_count);
2467 2468
  thread_count--;
  thd->unlink();
2469 2470 2471 2472 2473 2474
  /*
    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););
2475 2476 2477
  mysql_mutex_unlock(&LOCK_thread_count);

  delete thd;
unknown's avatar
unknown committed
2478 2479 2480
  DBUG_VOID_RETURN;
}

2481

unknown's avatar
unknown committed
2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499
/*
  Store thread in cache for reuse by new connections

  SYNOPSIS
    cache_thread()

  NOTES
    LOCK_thread_count has to be locked

  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()
{
Marc Alff's avatar
Marc Alff committed
2500
  mysql_mutex_assert_owner(&LOCK_thread_count);
unknown's avatar
unknown committed
2501
  if (cached_thread_count < thread_cache_size &&
2502
      ! abort_loop && !kill_cached_threads)
unknown's avatar
unknown committed
2503 2504
  {
    /* Don't kill the thread, just put it in cache for reuse */
unknown's avatar
unknown committed
2505
    DBUG_PRINT("info", ("Adding thread to cache"));
unknown's avatar
unknown committed
2506
    cached_thread_count++;
2507 2508 2509 2510 2511 2512 2513 2514 2515 2516

#ifdef HAVE_PSI_INTERFACE
    /*
      Delete the instrumentation for the job that just completed,
      before parking this pthread in the cache (blocked on COND_thread_cache).
    */
    if (likely(PSI_server != NULL))
      PSI_server->delete_current_thread();
#endif

unknown's avatar
unknown committed
2517
    while (!abort_loop && ! wake_thread && ! kill_cached_threads)
Marc Alff's avatar
Marc Alff committed
2518
      mysql_cond_wait(&COND_thread_cache, &LOCK_thread_count);
unknown's avatar
unknown committed
2519 2520
    cached_thread_count--;
    if (kill_cached_threads)
Marc Alff's avatar
Marc Alff committed
2521
      mysql_cond_signal(&COND_flush_thread_cache);
unknown's avatar
unknown committed
2522 2523
    if (wake_thread)
    {
unknown's avatar
unknown committed
2524
      THD *thd;
unknown's avatar
unknown committed
2525
      wake_thread--;
unknown's avatar
unknown committed
2526
      thd= thread_cache.get();
2527
      thd->thread_stack= (char*) &thd;          // For store_globals
unknown's avatar
unknown committed
2528
      (void) thd->store_globals();
2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543

#ifdef HAVE_PSI_INTERFACE
      /*
        Create new instrumentation for the new THD job,
        and attach it to this running pthread.
      */
      if (likely(PSI_server != NULL))
      {
        PSI_thread *psi= PSI_server->new_thread(key_thread_one_connection,
                                                thd, thd->thread_id);
        if (likely(psi != NULL))
          PSI_server->set_thread(psi);
      }
#endif

2544 2545 2546 2547 2548 2549
      /*
        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;
2550
      thd->thr_create_utime= microsecond_interval_timer();
2551
      thd->start_utime= thd->thr_create_utime;
2552
      threads.append(thd);
unknown's avatar
unknown committed
2553
      return(1);
unknown's avatar
unknown committed
2554 2555
    }
  }
unknown's avatar
unknown committed
2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582
  return(0);
}


/*
  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");
  unlink_thd(thd);
2583 2584
  /* Mark that current_thd is not valid anymore */
  my_pthread_setspecific_ptr(THR_THD,  0);
unknown's avatar
unknown committed
2585
  if (put_in_cache)
2586 2587
  {
    mysql_mutex_lock(&LOCK_thread_count);
unknown's avatar
unknown committed
2588
    put_in_cache= cache_thread();
2589 2590 2591 2592
    mysql_mutex_unlock(&LOCK_thread_count);
    if (put_in_cache)
      DBUG_RETURN(0);                             // Thread is reused
  }
unknown's avatar
unknown committed
2593

2594
  /* It's safe to broadcast outside a lock (COND... is not deleted here) */
unknown's avatar
unknown committed
2595
  DBUG_PRINT("signal", ("Broadcasting COND_thread_count"));
2596
  DBUG_LEAVE;                                   // Must match DBUG_ENTER()
2597
  my_thread_end();
Marc Alff's avatar
Marc Alff committed
2598
  mysql_cond_broadcast(&COND_thread_count);
unknown's avatar
unknown committed
2599 2600

  pthread_exit(0);
2601
  return 0;                                     // Avoid compiler warnings
unknown's avatar
unknown committed
2602 2603 2604 2605 2606
}


void flush_thread_cache()
{
Marc Alff's avatar
Marc Alff committed
2607
  mysql_mutex_lock(&LOCK_thread_count);
unknown's avatar
unknown committed
2608 2609 2610
  kill_cached_threads++;
  while (cached_thread_count)
  {
Marc Alff's avatar
Marc Alff committed
2611 2612
    mysql_cond_broadcast(&COND_thread_cache);
    mysql_cond_wait(&COND_flush_thread_cache, &LOCK_thread_count);
unknown's avatar
unknown committed
2613 2614
  }
  kill_cached_threads--;
Marc Alff's avatar
Marc Alff committed
2615
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
2616 2617 2618 2619
}


/******************************************************************************
2620 2621 2622
  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
2623 2624
******************************************************************************/

2625
#if defined(__WIN__)
2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639


/*
  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
2640
#ifndef EMBEDDED_LIBRARY
2641 2642 2643 2644 2645 2646 2647 2648
  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.
     */
2649
#ifndef EMBEDDED_LIBRARY
2650 2651 2652
     if(hEventShutdown)
       kill_mysql();
     else
2653
#endif
2654 2655 2656
       sql_print_warning("CTRL-C ignored during startup");
     DBUG_RETURN(TRUE);
  }
unknown's avatar
unknown committed
2657
#endif
2658 2659 2660 2661 2662 2663 2664 2665 2666
  DBUG_RETURN(FALSE);
}




#ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER
#define DEBUGGER_ATTACH_TIMEOUT 120
/*
2667 2668
  Wait for debugger to attach and break into debugger. If debugger is
  not attached, resume after timeout.
2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718
*/
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
  {
2719
    my_set_exception_pointers(ex_pointers);
2720
    handle_fatal_signal(ex_pointers->ExceptionRecord->ExceptionCode);
2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738
  }
  __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
2739 2740
static void init_signals(void)
{
2741 2742
  if(opt_console)
    SetConsoleCtrlHandler(console_event_handler,TRUE);
2743

2744
    /* Avoid MessageBox()es*/
2745 2746 2747 2748 2749 2750
  _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);
2751 2752 2753 2754 2755 2756 2757 2758

   /*
     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)
   */
2759 2760
  SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS
                               | SEM_NOOPENFILEERRORBOX);
2761
  SetUnhandledExceptionFilter(my_unhandler_exception_filter);
unknown's avatar
unknown committed
2762 2763
}

unknown's avatar
unknown committed
2764

2765
static void start_signal_handler(void)
2766
{
2767
#ifndef EMBEDDED_LIBRARY
2768 2769 2770
  // Save vm id of this process
  if (!opt_bootstrap)
    create_pid_file();
2771
#endif /* EMBEDDED_LIBRARY */
2772
}
unknown's avatar
unknown committed
2773

unknown's avatar
unknown committed
2774

unknown's avatar
unknown committed
2775 2776
static void check_data_home(const char *path)
{}
2777

2778
#endif /* __WIN__ */
unknown's avatar
unknown committed
2779

unknown's avatar
unknown committed
2780 2781 2782 2783 2784 2785 2786 2787 2788

#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

2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859

/*
  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


2860
#if !defined(__WIN__)
unknown's avatar
unknown committed
2861 2862
#ifndef SA_RESETHAND
#define SA_RESETHAND 0
2863
#endif /* SA_RESETHAND */
unknown's avatar
unknown committed
2864 2865
#ifndef SA_NODEFER
#define SA_NODEFER 0
2866
#endif /* SA_NODEFER */
2867

2868 2869
#ifndef EMBEDDED_LIBRARY

unknown's avatar
unknown committed
2870 2871 2872
static void init_signals(void)
{
  sigset_t set;
2873
  struct sigaction sa;
unknown's avatar
unknown committed
2874 2875
  DBUG_ENTER("init_signals");

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

Michael Widenius's avatar
Michael Widenius committed
2878
  if (opt_stack_trace || (test_flags & TEST_CORE_ON_SIGNAL))
unknown's avatar
unknown committed
2879
  {
unknown's avatar
unknown committed
2880 2881 2882 2883
    sa.sa_flags = SA_RESETHAND | SA_NODEFER;
    sigemptyset(&sa.sa_mask);
    sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);

2884
    my_init_stacktrace();
unknown's avatar
unknown committed
2885
#if defined(__amiga__)
2886
    sa.sa_handler=(void(*)())handle_fatal_signal;
unknown's avatar
unknown committed
2887
#else
2888
    sa.sa_handler=handle_fatal_signal;
unknown's avatar
unknown committed
2889
#endif
unknown's avatar
unknown committed
2890
    sigaction(SIGSEGV, &sa, NULL);
2891
    sigaction(SIGABRT, &sa, NULL);
unknown's avatar
unknown committed
2892
#ifdef SIGBUS
unknown's avatar
unknown committed
2893
    sigaction(SIGBUS, &sa, NULL);
unknown's avatar
unknown committed
2894
#endif
unknown's avatar
unknown committed
2895
    sigaction(SIGILL, &sa, NULL);
2896
    sigaction(SIGFPE, &sa, NULL);
unknown's avatar
unknown committed
2897
  }
2898 2899 2900 2901 2902

#ifdef HAVE_GETRLIMIT
  if (test_flags & TEST_CORE_ON_SIGNAL)
  {
    /* Change limits so that we will get a core file */
2903
    STRUCT_RLIMIT rl;
2904
    rl.rlim_cur = rl.rlim_max = (rlim_t) RLIM_INFINITY;
unknown's avatar
unknown committed
2905
    if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
2906
      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");
2907 2908
  }
#endif
unknown's avatar
unknown committed
2909
  (void) sigemptyset(&set);
2910
  my_sigset(SIGPIPE,SIG_IGN);
unknown's avatar
unknown committed
2911
  sigaddset(&set,SIGPIPE);
2912
#ifndef IGNORE_SIGHUP_SIGQUIT
unknown's avatar
unknown committed
2913 2914
  sigaddset(&set,SIGQUIT);
  sigaddset(&set,SIGHUP);
2915 2916
#endif
  sigaddset(&set,SIGTERM);
2917 2918

  /* Fix signals if blocked by parents (can happen on Mac OS X) */
unknown's avatar
unknown committed
2919
  sigemptyset(&sa.sa_mask);
2920 2921 2922 2923 2924 2925
  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);
unknown's avatar
unknown committed
2926 2927 2928
#ifdef SIGTSTP
  sigaddset(&set,SIGTSTP);
#endif
2929 2930
  if (thd_lib_detected != THD_LIB_LT)
    sigaddset(&set,THR_SERVER_ALARM);
2931
  if (test_flags & TEST_SIGINT)
2932
  {
2933 2934
    /* Allow SIGINT to break mysqld. This is for debugging with --gdb */
    my_sigset(SIGINT, end_mysqld_signal);
unknown's avatar
unknown committed
2935
    sigdelset(&set, SIGINT);
2936
  }
2937 2938
  else
    sigaddset(&set,SIGINT);
unknown's avatar
unknown committed
2939

2940 2941
  sigprocmask(SIG_SETMASK,&set,NULL);
  pthread_sigmask(SIG_SETMASK,&set,NULL);
2942 2943 2944 2945 2946 2947 2948 2949 2950
  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
2951 2952 2953 2954

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

Marc Alff's avatar
Marc Alff committed
2957
  mysql_mutex_lock(&LOCK_thread_count);
Marc Alff's avatar
Marc Alff committed
2958 2959
  if ((error= mysql_thread_create(key_thread_signal_hand,
                                  &signal_thread, &thr_attr, signal_hand, 0)))
unknown's avatar
unknown committed
2960 2961 2962 2963 2964
  {
    sql_print_error("Can't create interrupt-thread (error %d, errno: %d)",
		    error,errno);
    exit(1);
  }
Marc Alff's avatar
Marc Alff committed
2965 2966
  mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
2967 2968 2969 2970 2971 2972

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


unknown's avatar
unknown committed
2973
/** This threads handles all signals and alarms. */
unknown's avatar
unknown committed
2974
/* ARGSUSED */
2975
pthread_handler_t signal_hand(void *arg __attribute__((unused)))
unknown's avatar
unknown committed
2976 2977 2978 2979 2980
{
  sigset_t set;
  int sig;
  my_thread_init();				// Init new thread
  DBUG_ENTER("signal_hand");
unknown's avatar
unknown committed
2981 2982
  signal_thread_in_use= 1;

unknown's avatar
unknown committed
2983 2984
  /*
    Setup alarm handler
2985 2986
    This should actually be '+ max_number_of_slaves' instead of +10,
    but the +10 should be quite safe.
unknown's avatar
unknown committed
2987
  */
Sergei Golubchik's avatar
Sergei Golubchik committed
2988
  init_thr_alarm(thread_scheduler->max_threads + extra_max_connections +
2989
		 global_system_variables.max_insert_delayed_threads + 10);
2990
  if (test_flags & TEST_SIGINT)
2991
  {
2992 2993 2994
    /* Allow SIGINT to break mysqld. This is for debugging with --gdb */
    (void) sigemptyset(&set);
    (void) sigaddset(&set,SIGINT);
2995 2996
    (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL);
  }
unknown's avatar
unknown committed
2997 2998 2999 3000
  (void) sigemptyset(&set);			// Setup up SIGINT for debug
#ifdef USE_ONE_SIGNAL_HAND
  (void) sigaddset(&set,THR_SERVER_ALARM);	// For alarms
#endif
3001
#ifndef IGNORE_SIGHUP_SIGQUIT
unknown's avatar
unknown committed
3002 3003
  (void) sigaddset(&set,SIGQUIT);
  (void) sigaddset(&set,SIGHUP);
3004 3005
#endif
  (void) sigaddset(&set,SIGTERM);
unknown's avatar
unknown committed
3006 3007 3008
  (void) sigaddset(&set,SIGTSTP);

  /* Save pid to this process (or thread on Linux) */
3009
  if (!opt_bootstrap)
3010 3011
    create_pid_file();

3012 3013 3014 3015 3016
  /*
    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
3017
    should not be any other mysql_cond_signal() calls.
3018
  */
Marc Alff's avatar
Marc Alff committed
3019 3020 3021
  mysql_mutex_lock(&LOCK_thread_count);
  mysql_mutex_unlock(&LOCK_thread_count);
  mysql_cond_broadcast(&COND_thread_count);
unknown's avatar
unknown committed
3022

3023
  (void) pthread_sigmask(SIG_BLOCK,&set,NULL);
unknown's avatar
unknown committed
3024 3025 3026 3027 3028
  for (;;)
  {
    int error;					// Used when debugging
    if (shutdown_in_progress && !abort_loop)
    {
3029
      sig= SIGTERM;
unknown's avatar
unknown committed
3030 3031 3032 3033 3034
      error=0;
    }
    else
      while ((error=my_sigwait(&set,&sig)) == EINTR) ;
    if (cleanup_done)
3035
    {
3036
      DBUG_PRINT("quit",("signal_handler: calling my_thread_end()"));
3037
      my_thread_end();
3038
      DBUG_LEAVE;                               // Must match DBUG_ENTER()
Sergei Golubchik's avatar
Sergei Golubchik committed
3039
      signal_thread_in_use= 0;
unknown's avatar
unknown committed
3040
      pthread_exit(0);				// Safety
3041
      return 0;                                 // Avoid compiler warnings
3042
    }
unknown's avatar
unknown committed
3043 3044 3045 3046 3047
    switch (sig) {
    case SIGTERM:
    case SIGQUIT:
    case SIGKILL:
#ifdef EXTRA_DEBUG
3048
      sql_print_information("Got signal %d to shutdown mysqld",sig);
unknown's avatar
unknown committed
3049
#endif
3050
      /* switch to the old log message processing */
3051 3052
      logger.set_handlers(LOG_FILE, opt_slow_log ? LOG_FILE:LOG_NONE,
                          opt_log ? LOG_FILE:LOG_NONE);
unknown's avatar
unknown committed
3053 3054 3055 3056
      DBUG_PRINT("info",("Got signal: %d  abort_loop: %d",sig,abort_loop));
      if (!abort_loop)
      {
	abort_loop=1;				// mark abort for threads
3057 3058 3059 3060 3061
#ifdef HAVE_PSI_INTERFACE
        /* Delete the instrumentation for the signal thread */
        if (likely(PSI_server != NULL))
          PSI_server->delete_current_thread();
#endif
unknown's avatar
unknown committed
3062 3063
#ifdef USE_ONE_SIGNAL_HAND
	pthread_t tmp;
Marc Alff's avatar
Marc Alff committed
3064 3065 3066
        if (mysql_thread_create(0, /* Not instrumented */
                                &tmp, &connection_attrib, kill_server_thread,
                                (void*) &sig))
3067
	  sql_print_error("Can't create thread to kill server");
unknown's avatar
unknown committed
3068
#else
unknown's avatar
unknown committed
3069
	kill_server((void*) sig);	// MIT THREAD has a alarm thread
unknown's avatar
unknown committed
3070 3071 3072 3073
#endif
      }
      break;
    case SIGHUP:
unknown's avatar
unknown committed
3074 3075
      if (!abort_loop)
      {
3076
        int not_used;
unknown's avatar
Merge  
unknown committed
3077
	mysql_print_status();		// Print some debug info
unknown's avatar
unknown committed
3078 3079
	reload_acl_and_cache((THD*) 0,
			     (REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |
unknown's avatar
Merge  
unknown committed
3080
			      REFRESH_GRANT |
unknown's avatar
unknown committed
3081
			      REFRESH_THREADS | REFRESH_HOSTS),
unknown's avatar
unknown committed
3082
			     (TABLE_LIST*) 0, &not_used); // Flush logs
unknown's avatar
unknown committed
3083
      }
3084
      /* reenable logs after the options were reloaded */
3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096
      if (log_output_options & LOG_NONE)
      {
        logger.set_handlers(LOG_FILE,
                            opt_slow_log ? LOG_TABLE : LOG_NONE,
                            opt_log ? LOG_TABLE : LOG_NONE);
      }
      else
      {
        logger.set_handlers(LOG_FILE,
                            opt_slow_log ? log_output_options : LOG_NONE,
                            opt_log ? log_output_options : LOG_NONE);
      }
unknown's avatar
unknown committed
3097 3098 3099 3100 3101 3102 3103 3104
      break;
#ifdef USE_ONE_SIGNAL_HAND
    case THR_SERVER_ALARM:
      process_alarm(sig);			// Trigger alarms.
      break;
#endif
    default:
#ifdef EXTRA_DEBUG
3105
      sql_print_warning("Got signal: %d  error: %d",sig,error); /* purecov: tested */
unknown's avatar
unknown committed
3106 3107 3108 3109 3110 3111 3112
#endif
      break;					/* purecov: tested */
    }
  }
  return(0);					/* purecov: deadcode */
}

unknown's avatar
unknown committed
3113
static void check_data_home(const char *path)
unknown's avatar
unknown committed
3114
{}
unknown's avatar
unknown committed
3115

3116
#endif /*!EMBEDDED_LIBRARY*/
unknown's avatar
unknown committed
3117 3118 3119
#endif	/* __WIN__*/


unknown's avatar
unknown committed
3120
/**
unknown's avatar
Merge  
unknown committed
3121
  All global error messages are sent here where the first one is stored
unknown's avatar
unknown committed
3122
  for the client.
unknown's avatar
unknown committed
3123 3124
*/
/* ARGSUSED */
Marc Alff's avatar
Marc Alff committed
3125
extern "C" void my_message_sql(uint error, const char *str, myf MyFlags);
3126

Marc Alff's avatar
Marc Alff committed
3127
void my_message_sql(uint error, const char *str, myf MyFlags)
unknown's avatar
unknown committed
3128
{
Marc Alff's avatar
Marc Alff committed
3129
  THD *thd= current_thd;
3130 3131
  MYSQL_ERROR::enum_warning_level level;
  sql_print_message_func func;
Sergei Golubchik's avatar
Sergei Golubchik committed
3132

unknown's avatar
unknown committed
3133
  DBUG_ENTER("my_message_sql");
3134
  DBUG_PRINT("error", ("error: %u  message: '%s'  Flag: %d", error, str, MyFlags));
3135 3136

  DBUG_ASSERT(str != NULL);
3137
  DBUG_ASSERT(error != 0);
3138

3139
  mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_ERROR, error, str);
3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154
  if (MyFlags & ME_JUST_INFO)
  {
    level= MYSQL_ERROR::WARN_LEVEL_NOTE;
    func= sql_print_information;
  }
  else if (MyFlags & ME_JUST_WARNING)
  {
    level= MYSQL_ERROR::WARN_LEVEL_WARN;
    func= sql_print_warning;
  }
  else
  {
    level= MYSQL_ERROR::WARN_LEVEL_ERROR;
    func= sql_print_error;
  }
3155

Marc Alff's avatar
Marc Alff committed
3156
  if (thd)
unknown's avatar
unknown committed
3157
  {
Marc Alff's avatar
Marc Alff committed
3158 3159
    if (MyFlags & ME_FATALERROR)
      thd->is_fatal_error= 1;
Sergei Golubchik's avatar
Sergei Golubchik committed
3160
    (void) thd->raise_condition(error, NULL, level, str);
unknown's avatar
unknown committed
3161
  }
3162 3163

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

3166
  if (!thd || thd->log_all_errors || (MyFlags & ME_NOREFRESH))
3167
    (*func)("%s: %s", my_progname_short, str); /* purecov: inspected */
Marc Alff's avatar
Marc Alff committed
3168
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
3169 3170
}

3171

3172
#ifndef EMBEDDED_LIBRARY
3173 3174 3175 3176
extern "C" void *my_str_malloc_mysqld(size_t size);
extern "C" void my_str_free_mysqld(void *ptr);

void *my_str_malloc_mysqld(size_t size)
3177 3178 3179 3180 3181
{
  return my_malloc(size, MYF(MY_FAE));
}


3182
void my_str_free_mysqld(void *ptr)
3183
{
3184
  my_free(ptr);
3185
}
3186
#endif /* EMBEDDED_LIBRARY */
3187 3188


unknown's avatar
unknown committed
3189 3190
#ifdef __WIN__

3191
pthread_handler_t handle_shutdown(void *arg)
unknown's avatar
unknown committed
3192 3193 3194 3195 3196 3197
{
  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
3198
#if !defined(EMBEDDED_LIBRARY)
unknown's avatar
unknown committed
3199
  if (WaitForSingleObject(hEventShutdown,INFINITE)==WAIT_OBJECT_0)
3200
#endif /* EMBEDDED_LIBRARY */
unknown's avatar
unknown committed
3201 3202 3203 3204 3205
     kill_server(MYSQL_KILL_SIGNAL);
  return 0;
}
#endif

3206
#include <mysqld_default_groups.h>
unknown's avatar
Merge  
unknown committed
3207

3208
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
3209 3210
static const int load_default_groups_sz=
sizeof(load_default_groups)/sizeof(load_default_groups[0]);
unknown's avatar
Merge  
unknown committed
3211
#endif
unknown's avatar
unknown committed
3212

unknown's avatar
unknown committed
3213

3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226
#ifndef EMBEDDED_LIBRARY
static
int
check_enough_stack_size()
{
  uchar stack_top;

  return check_stack_overrun(current_thd, STACK_MIN_SIZE,
                             &stack_top);
}
#endif


unknown's avatar
unknown committed
3227 3228
/**
  Initialize one of the global date/time format variables.
3229

unknown's avatar
unknown committed
3230 3231
  @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
3232

unknown's avatar
unknown committed
3233
  @retval
3234
    0 ok
unknown's avatar
unknown committed
3235
  @retval
3236 3237 3238
    1 error
*/

unknown's avatar
unknown committed
3239
static bool init_global_datetime_format(timestamp_type format_type,
3240
                                        DATE_TIME_FORMAT *format)
3241
{
3242 3243 3244 3245 3246
  /*
    Get command line option
    format->format.str is already set by my_getopt
  */
  format->format.length= strlen(format->format.str);
3247

3248
  if (parse_date_time_format(format_type, format))
3249
  {
3250 3251 3252
    fprintf(stderr, "Wrong date/time format specifier: %s\n",
            format->format.str);
    return true;
3253
  }
3254
  return false;
3255 3256
}

unknown's avatar
unknown committed
3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327
SHOW_VAR com_status_vars[]= {
  {"admin_commands",       (char*) offsetof(STATUS_VAR, com_other), SHOW_LONG_STATUS},
  {"assign_to_keycache",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ASSIGN_TO_KEYCACHE]), 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},
  {"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},
  {"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},
  {"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},
  {"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},
  {"grant",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_GRANT]), SHOW_LONG_STATUS},
  {"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
3328
  {"resignal",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RESIGNAL]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3329 3330 3331 3332 3333 3334 3335
  {"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},
  {"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},
Marc Alff's avatar
Marc Alff committed
3336
  {"signal",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SIGNAL]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3337 3338 3339 3340
  {"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},
3341
  {"show_client_statistics",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CLIENT_STATS]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362
  {"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_events",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_EVENTS]), SHOW_LONG_STATUS},
  {"show_errors",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ERRORS]), SHOW_LONG_STATUS},
  {"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},
  {"show_grants",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_GRANTS]), SHOW_LONG_STATUS},
  {"show_keys",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_KEYS]), SHOW_LONG_STATUS},
3363
  {"show_index_statistics",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_INDEX_STATS]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3364 3365 3366 3367 3368 3369 3370 3371 3372
  {"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
3373 3374
  {"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},
3375
  {"show_relaylog_events", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_RELAYLOG_EVENTS]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3376 3377 3378 3379
  {"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},
3380
  {"show_table_statistics",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATS]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3381 3382 3383
  {"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},
3384
  {"show_user_statistics",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_USER_STATS]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3385 3386 3387 3388 3389 3390 3391 3392
  {"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},
  {"slave_start",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_START]), SHOW_LONG_STATUS},
  {"slave_stop",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_STOP]), SHOW_LONG_STATUS},
  {"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
3393
  {"stmt_reprepare",       (char*) offsetof(STATUS_VAR, com_stmt_reprepare), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406
  {"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},
  {"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},
3407
  {NullS, NullS, SHOW_LONG}
unknown's avatar
unknown committed
3408
};
3409

Marc Alff's avatar
Marc Alff committed
3410
static int init_common_variables()
unknown's avatar
unknown committed
3411
{
unknown's avatar
unknown committed
3412
  umask(((~my_umask) & 0666));
unknown's avatar
Merge  
unknown committed
3413
  my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
Sergei Golubchik's avatar
Sergei Golubchik committed
3414

unknown's avatar
unknown committed
3415 3416
  tzset();			// Set tzname

3417 3418
  sf_leaking_memory= 0; // no memory leaks from now on

unknown's avatar
SCRUM  
unknown committed
3419
  max_system_variables.pseudo_thread_id= (ulong)~0;
3420
  server_start_time= flush_status_time= my_time(0);
3421

3422 3423
  rpl_filter= new Rpl_filter;
  binlog_filter= new Rpl_filter;
unknown's avatar
unknown committed
3424
  if (!rpl_filter || !binlog_filter)
3425 3426
  {
    sql_perror("Could not allocate replication and binlog filters");
3427
    return 1;
3428 3429
  }

3430 3431
  if (init_thread_environment() ||
      mysql_init_variables())
unknown's avatar
unknown committed
3432
    return 1;
unknown's avatar
unknown committed
3433

3434 3435 3436
  if (ignore_db_dirs_init())
    return 1;

unknown's avatar
unknown committed
3437
#ifdef HAVE_TZNAME
3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453
  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
  strmake(system_time_zone, tz_name,  sizeof(system_time_zone)-1);
#endif /* _WIN32 */
#endif /* HAVE_TZNAME */
3454

3455
  /*
unknown's avatar
unknown committed
3456
    We set SYSTEM time zone as reasonable default and
3457 3458 3459 3460 3461
    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
3462

3463 3464 3465 3466 3467 3468 3469 3470 3471
#ifdef HAVE_PSI_INTERFACE
  /*
    Complete the mysql_bin_log initialization.
    Instrumentation keys are known only after the performance schema initialization,
    and can not be set in the MYSQL_BIN_LOG constructor (called before main()).
  */
  mysql_bin_log.set_psi_keys(key_BINLOG_LOCK_index,
                             key_BINLOG_update_cond,
                             key_file_binlog,
3472 3473
                             key_file_binlog_index,
                             key_BINLOG_COND_queue_busy);
3474 3475
#endif

unknown's avatar
unknown committed
3476
  /*
3477
    Init mutexes for the global MYSQL_BIN_LOG objects.
unknown's avatar
unknown committed
3478
    As safe_mutex depends on what MY_INIT() does, we can't init the mutexes of
3479 3480
    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
3481 3482
  */
  mysql_bin_log.init_pthread_objects();
3483

3484 3485 3486 3487 3488 3489 3490
  /* 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;
  }

3491 3492
  if (gethostname(glob_hostname,sizeof(glob_hostname)) < 0)
  {
3493 3494 3495 3496
    /*
      Get hostname of computer (used by 'show variables') and as default
      basename for the pid file if --log-basename is not given.
    */
3497 3498
    strmake(glob_hostname, STRING_WITH_LEN("localhost"));
    sql_print_warning("gethostname failed, using '%s' as hostname",
3499
                        glob_hostname);
Sergei Golubchik's avatar
Sergei Golubchik committed
3500
    opt_log_basename= const_cast<char *>("mysql");
3501 3502
  }
  else
Sergei Golubchik's avatar
Sergei Golubchik committed
3503
    opt_log_basename= glob_hostname;
3504

Sergei Golubchik's avatar
Sergei Golubchik committed
3505
  if (!*pidfile_name)
3506
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
3507 3508
    strmake(pidfile_name, opt_log_basename, sizeof(pidfile_name)-5);
    strmov(fn_ext(pidfile_name),".pid");		// Add proper extension
3509
  }
unknown's avatar
unknown committed
3510

3511 3512 3513 3514 3515 3516 3517
  /*
    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.
3518 3519 3520 3521

    From MySQL 5.5 onwards, the default storage engine is InnoDB
    (except in the embedded server, where the default continues to
    be MyISAM)
3522
  */
3523
#if defined(WITH_INNOBASE_STORAGE_ENGINE) || defined(WITH_XTRADB_STORAGE_ENGINE)
3524
  default_storage_engine= const_cast<char *>("InnoDB");
3525 3526
#else
  default_storage_engine= const_cast<char *>("MyISAM");
3527
#endif
3528

3529 3530 3531
  /*
    Add server status variables to the dynamic list of
    status variables that is shown by SHOW STATUS.
3532
    Later, in plugin_init, and mysql_install_plugin
3533 3534 3535 3536 3537
    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
3538 3539 3540 3541 3542
#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
3543
    There are 8 Com_ variables which don't have corresponding SQLCOM_ values:
unknown's avatar
unknown committed
3544 3545 3546 3547 3548 3549 3550 3551
    (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
3552
      Com_stmt_reprepare       => com_stmt_reprepare
unknown's avatar
unknown committed
3553 3554 3555
      Com_stmt_reset           => com_stmt_reset
      Com_stmt_send_long_data  => com_stmt_send_long_data

3556 3557 3558
    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
3559
  */
3560
  compile_time_assert(sizeof(com_status_vars)/sizeof(com_status_vars[0]) - 1 ==
unknown's avatar
unknown committed
3561
                     SQLCOM_END + 8);
unknown's avatar
unknown committed
3562 3563
#endif

Marc Alff's avatar
Marc Alff committed
3564
  if (get_options(&remaining_argc, &remaining_argv))
3565
    return 1;
3566 3567
  set_server_version();

3568
#ifndef EMBEDDED_LIBRARY
3569
  if (opt_abort && !opt_verbose)
3570 3571 3572
    unireg_abort(0);
#endif /*!EMBEDDED_LIBRARY*/

unknown's avatar
unknown committed
3573 3574 3575
  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
3576 3577 3578 3579
#ifdef HAVE_LARGE_PAGES
  /* Initialize large page size */
  if (opt_large_pages && (opt_large_page_size= my_get_large_page_size()))
  {
3580 3581
      DBUG_PRINT("info", ("Large page set, large_page_size = %d",
                 opt_large_page_size));
unknown's avatar
Merge  
unknown committed
3582 3583 3584
      my_use_large_pages= 1;
      my_large_page_size= opt_large_page_size;
  }
3585 3586 3587 3588 3589 3590 3591 3592
  else
  {
    opt_large_pages= 0;
    /* 
       Either not configured to use large pages or Linux haven't
       been compiled with large page support
    */
  }
unknown's avatar
Merge  
unknown committed
3593
#endif /* HAVE_LARGE_PAGES */
3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609
#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;
3610
   size_t max_desired_page_size;
3611
   if (opt_super_large_pages)
3612
     max_desired_page_size= SUPER_LARGE_PAGESIZE;
3613
   else
3614
     max_desired_page_size= LARGE_PAGESIZE;
3615 3616 3617 3618 3619 3620
   nelem = getpagesizes(NULL, 0);
   if (nelem > 0)
   {
     size_t *pagesize = (size_t *) malloc(sizeof(size_t) * nelem);
     if (pagesize != NULL && getpagesizes(pagesize, nelem) > 0)
     {
3621 3622
       size_t max_page_size= 0;
       for (int i= 0; i < nelem; i++)
3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643
       {
         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
3644

unknown's avatar
unknown committed
3645 3646
  /* connections and databases needs lots of files */
  {
3647
    uint files, wanted_files, max_open_files;
3648

3649
    /* MyISAM requires two file handles per table. */
3650 3651
    wanted_files= (10 + max_connections + extra_max_connections +
                   table_cache_size*2);
3652 3653 3654 3655 3656 3657 3658 3659 3660 3661
    /*
      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).
    */
3662 3663
    max_open_files= max(max(wanted_files,
                            (max_connections + extra_max_connections)*5),
3664 3665
                        open_files_limit);
    files= my_set_max_open_files(max_open_files);
3666 3667

    if (files < wanted_files)
unknown's avatar
unknown committed
3668
    {
3669 3670
      if (!open_files_limit)
      {
3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684
        /*
          If we have requested too much file handles than we bring
          max_connections in supported bounds.
        */
        max_connections= (ulong) min(files-10-TABLE_OPEN_CACHE_MIN*2,
                                     max_connections);
        /*
          Decrease table_cache_size according to max_connections, but
          not below TABLE_OPEN_CACHE_MIN.  Outer min() ensures that we
          never increase table_cache_size automatically (that could
          happen if max_connections is decreased above).
        */
        table_cache_size= (ulong) min(max((files-10-max_connections)/2,
                                          TABLE_OPEN_CACHE_MIN),
unknown's avatar
unknown committed
3685
                                      table_cache_size);
3686 3687 3688
	DBUG_PRINT("warning",
		   ("Changed limits: max_open_files: %u  max_connections: %ld  table_cache: %ld",
		    files, max_connections, table_cache_size));
unknown's avatar
unknown committed
3689
	if (global_system_variables.log_warnings)
3690
	  sql_print_warning("Changed limits: max_open_files: %u  max_connections: %ld  table_cache: %ld",
3691 3692
			files, max_connections, table_cache_size);
      }
unknown's avatar
unknown committed
3693
      else if (global_system_variables.log_warnings)
3694
	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
3695
    }
unknown's avatar
unknown committed
3696
    open_files_limit= files;
unknown's avatar
unknown committed
3697 3698
  }
  unireg_init(opt_specialflag); /* Set up extern variabels */
3699 3700 3701 3702 3703 3704 3705
  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;
3706 3707
  if (init_errmessage())	/* Read error messages from file */
    return 1;
3708
  init_client_errs();
Sergei Golubchik's avatar
Sergei Golubchik committed
3709
  mysql_library_init(unused,unused,unused); /* for replication */
unknown's avatar
unknown committed
3710
  lex_init();
3711 3712
  if (item_create_init())
    return 1;
unknown's avatar
unknown committed
3713
  item_init();
3714 3715 3716 3717
#ifndef EMBEDDED_LIBRARY
  my_regex_init(&my_charset_latin1, check_enough_stack_size);
#else
  my_regex_init(&my_charset_latin1, NULL);
unknown's avatar
unknown committed
3718
#endif
3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745
  /*
    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;
  }

3746 3747
  if (default_collation_name)
  {
unknown's avatar
unknown committed
3748 3749
    CHARSET_INFO *default_collation;
    default_collation= get_charset_by_name(default_collation_name, MYF(0));
unknown's avatar
unknown committed
3750 3751
    if (!default_collation)
    {
3752
      sql_print_error(ER_DEFAULT(ER_UNKNOWN_COLLATION), default_collation_name);
unknown's avatar
unknown committed
3753 3754 3755
      return 1;
    }
    if (!my_charset_same(default_charset_info, default_collation))
3756
    {
3757
      sql_print_error(ER_DEFAULT(ER_COLLATION_CHARSET_MISMATCH),
3758 3759 3760 3761 3762 3763
		      default_collation_name,
		      default_charset_info->csname);
      return 1;
    }
    default_charset_info= default_collation;
  }
3764 3765 3766 3767
  /* 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;
3768
  global_system_variables.character_set_results= default_charset_info;
3769
  global_system_variables.character_set_client=  default_charset_info;
3770

3771
  if (!(character_set_filesystem=
unknown's avatar
unknown committed
3772 3773 3774 3775 3776
        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;

3777 3778 3779
  if (!(my_default_lc_time_names=
        my_locale_by_name(lc_time_names_name)))
  {
unknown's avatar
unknown committed
3780
    sql_print_error("Unknown locale: '%s'", lc_time_names_name);
3781 3782 3783
    return 1;
  }
  global_system_variables.lc_time_names= my_default_lc_time_names;
3784

3785
  /* check log options and issue warnings if needed */
3786 3787
  if (opt_log && opt_logname && *opt_logname &&
      !(log_output_options & (LOG_FILE | LOG_NONE)))
3788 3789
    sql_print_warning("Although a path was specified for the "
                      "--log option, log tables are used. "
3790
                      "To enable logging to files use the --log-output option.");
3791

3792 3793
  if (opt_slow_log && opt_slow_logname && *opt_slow_logname &&
      !(log_output_options & (LOG_FILE | LOG_NONE)))
3794
    sql_print_warning("Although a path was specified for the "
Konstantin Osipov's avatar
Konstantin Osipov committed
3795
                      "--log-slow-queries option, log tables are used. "
3796
                      "To enable logging to files use the --log-output=file option.");
3797

Sergei Golubchik's avatar
Sergei Golubchik committed
3798 3799 3800 3801
  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);
3802

3803 3804 3805 3806 3807 3808
#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) */

3809
#if (ENABLE_TEMP_POOL)
3810
  if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
3811
    return 1;
3812 3813 3814 3815
#else
  use_temp_pool= 0;
#endif

3816
  if (my_dboptions_cache_init())
unknown's avatar
unknown committed
3817 3818
    return 1;

3819 3820 3821 3822 3823 3824
  /*
    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));
3825 3826
  lower_case_file_system= test_if_case_insensitive(mysql_real_data_home);
  if (!lower_case_table_names && lower_case_file_system == 1)
3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845
  {
    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)
	sql_print_warning("Setting lower_case_table_names=2 because file system for %s is case insensitive", mysql_real_data_home);
      lower_case_table_names= 2;
    }
  }
  else if (lower_case_table_names == 2 &&
3846
           !(lower_case_file_system= (lower_case_file_system == 1)))
3847 3848 3849 3850 3851 3852 3853 3854
  {
    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);
    lower_case_table_names= 0;
  }
3855 3856
  else
  {
3857
    lower_case_file_system= (lower_case_file_system == 1);
3858
  }
3859 3860 3861 3862 3863 3864

  /* 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);

3865 3866 3867 3868 3869 3870
  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
3871 3872
  return 0;
}
unknown's avatar
unknown committed
3873

3874 3875

static int init_thread_environment()
unknown's avatar
unknown committed
3876
{
Marc Alff's avatar
Marc Alff committed
3877
  mysql_mutex_init(key_LOCK_thread_count, &LOCK_thread_count, MY_MUTEX_INIT_FAST);
Marc Alff's avatar
Marc Alff committed
3878
  mysql_mutex_init(key_LOCK_status, &LOCK_status, MY_MUTEX_INIT_FAST);
Marc Alff's avatar
Marc Alff committed
3879
  mysql_mutex_init(key_LOCK_delayed_insert,
Marc Alff's avatar
Marc Alff committed
3880 3881 3882 3883 3884
                   &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
3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895
  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);
  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);
3896
  mysql_mutex_init(key_LOCK_uuid_short_generator,
Sergei Golubchik's avatar
Sergei Golubchik committed
3897
                   &LOCK_short_uuid_generator, MY_MUTEX_INIT_FAST);
Marc Alff's avatar
Marc Alff committed
3898 3899
  mysql_mutex_init(key_LOCK_connection_count,
                   &LOCK_connection_count, MY_MUTEX_INIT_FAST);
3900 3901 3902 3903 3904 3905 3906
  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
3907 3908 3909 3910
  mysql_mutex_init(key_LOCK_prepare_ordered, &LOCK_prepare_ordered,
                   MY_MUTEX_INIT_SLOW);
  mysql_mutex_init(key_LOCK_commit_ordered, &LOCK_commit_ordered,
                   MY_MUTEX_INIT_SLOW);
3911

3912
#ifdef HAVE_OPENSSL
Marc Alff's avatar
Marc Alff committed
3913 3914
  mysql_mutex_init(key_LOCK_des_key_file,
                   &LOCK_des_key_file, MY_MUTEX_INIT_FAST);
unknown's avatar
unknown committed
3915 3916 3917 3918
#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)
3919
    mysql_rwlock_init(key_rwlock_openssl, &openssl_stdlocks[i].lock);
unknown's avatar
unknown committed
3920 3921 3922 3923 3924 3925
  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
3926
#endif
Marc Alff's avatar
Marc Alff committed
3927 3928 3929
  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
3930 3931 3932
  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
3933
#ifdef HAVE_REPLICATION
Marc Alff's avatar
Marc Alff committed
3934 3935
  mysql_mutex_init(key_LOCK_rpl_status, &LOCK_rpl_status, MY_MUTEX_INIT_FAST);
  mysql_cond_init(key_COND_rpl_status, &COND_rpl_status, NULL);
3936
#endif
Marc Alff's avatar
Marc Alff committed
3937 3938 3939
  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
3940
  sp_cache_init();
3941
#ifdef HAVE_EVENT_SCHEDULER
3942
  Events::init_mutexes();
3943
#endif
unknown's avatar
unknown committed
3944 3945 3946 3947 3948
  /* 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
3949

unknown's avatar
unknown committed
3950 3951 3952 3953 3954 3955 3956 3957 3958
  if (pthread_key_create(&THR_THD,NULL) ||
      pthread_key_create(&THR_MALLOC,NULL))
  {
    sql_print_error("Can't create thread-keys");
    return 1;
  }
  return 0;
}

3959

unknown's avatar
unknown committed
3960
#if defined(HAVE_OPENSSL) && !defined(HAVE_YASSL)
3961
static unsigned long openssl_id_function()
3962
{
3963
  return (unsigned long) pthread_self();
3964
}
3965 3966 3967


static openssl_lock_t *openssl_dynlock_create(const char *file, int line)
3968
{
3969
  openssl_lock_t *lock= new openssl_lock_t;
3970
  mysql_rwlock_init(key_rwlock_openssl, &lock->lock);
3971 3972 3973 3974
  return lock;
}


3975
static void openssl_dynlock_destroy(openssl_lock_t *lock, const char *file,
3976 3977
				    int line)
{
3978
  mysql_rwlock_destroy(&lock->lock);
3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994
  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);
}


3995
static void openssl_lock(int mode, openssl_lock_t *lock, const char *file,
3996 3997 3998 3999 4000 4001 4002 4003
			 int line)
{
  int err;
  char const *what;

  switch (mode) {
  case CRYPTO_LOCK|CRYPTO_READ:
    what = "read lock";
4004
    err= mysql_rwlock_rdlock(&lock->lock);
4005 4006 4007
    break;
  case CRYPTO_LOCK|CRYPTO_WRITE:
    what = "write lock";
4008
    err= mysql_rwlock_wrlock(&lock->lock);
4009 4010 4011 4012
    break;
  case CRYPTO_UNLOCK|CRYPTO_READ:
  case CRYPTO_UNLOCK|CRYPTO_WRITE:
    what = "unlock";
4013
    err= mysql_rwlock_unlock(&lock->lock);
4014 4015 4016 4017 4018 4019
    break;
  default:
    /* Unknown locking mode. */
    sql_print_error("Fatal: OpenSSL interface problem (mode=0x%x)", mode);
    abort();
  }
4020
  if (err)
4021
  {
4022
    sql_print_error("Fatal: can't %s OpenSSL lock", what);
4023 4024 4025 4026 4027 4028
    abort();
  }
}
#endif /* HAVE_OPENSSL */


unknown's avatar
unknown committed
4029 4030
static void init_ssl()
{
unknown's avatar
unknown committed
4031
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
unknown's avatar
unknown committed
4032 4033
  if (opt_use_ssl)
  {
4034 4035
    enum enum_ssl_init_error error= SSL_INITERR_NOERROR;

4036 4037 4038
    /* 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,
4039
					  opt_ssl_cipher, &error);
unknown's avatar
Merge  
unknown committed
4040
    DBUG_PRINT("info",("ssl_acceptor_fd: 0x%lx", (long) ssl_acceptor_fd));
unknown's avatar
unknown committed
4041
    if (!ssl_acceptor_fd)
4042
    {
4043
      sql_print_warning("Failed to setup SSL");
4044
      sql_print_warning("SSL error: %s", sslGetErrString(error));
unknown's avatar
unknown committed
4045
      opt_use_ssl = 0;
4046
      have_ssl= SHOW_OPTION_DISABLED;
4047 4048 4049 4050
    }
  }
  else
  {
4051
    have_ssl= SHOW_OPTION_DISABLED;
unknown's avatar
unknown committed
4052
  }
unknown's avatar
unknown committed
4053 4054
  if (des_key_file)
    load_des_key_file(des_key_file);
unknown's avatar
unknown committed
4055
#endif /* HAVE_OPENSSL && ! EMBEDDED_LIBRARY */
unknown's avatar
unknown committed
4056
}
unknown's avatar
unknown committed
4057

4058

4059 4060 4061
static void end_ssl()
{
#ifdef HAVE_OPENSSL
Konstantin Osipov's avatar
Konstantin Osipov committed
4062
#ifndef EMBEDDED_LIBRARY
4063 4064 4065 4066 4067
  if (ssl_acceptor_fd)
  {
    free_vio_ssl_acceptor_fd(ssl_acceptor_fd);
    ssl_acceptor_fd= 0;
  }
Konstantin Osipov's avatar
Konstantin Osipov committed
4068
#endif /* ! EMBEDDED_LIBRARY */
4069 4070 4071
#endif /* HAVE_OPENSSL */
}

4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097
#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
4098

unknown's avatar
unknown committed
4099 4100
static int init_server_components()
{
4101
  DBUG_ENTER("init_server_components");
unknown's avatar
unknown committed
4102 4103 4104 4105
  /*
    We need to call each of these following functions to ensure that
    all things are initialized so that unireg_abort() doesn't fail
  */
4106 4107
  mdl_init();
  if (table_def_init() | hostname_cache_init())
4108
    unireg_abort(1);
unknown's avatar
unknown committed
4109

4110
  query_cache_set_min_res_unit(query_cache_min_res_unit);
unknown's avatar
unknown committed
4111
  query_cache_init();
unknown's avatar
unknown committed
4112
  query_cache_resize(query_cache_size);
4113
  my_rnd_init(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2);
4114
  setup_fpu();
unknown's avatar
unknown committed
4115
  init_thr_lock();
4116
  my_uuid_init((ulong) (my_rnd(&sql_rand))*12345,12345);
unknown's avatar
SCRUM  
unknown committed
4117
#ifdef HAVE_REPLICATION
4118
  init_slave_list();
4119
#endif
Sergei Golubchik's avatar
Sergei Golubchik committed
4120
  wt_init();
unknown's avatar
unknown committed
4121

4122 4123
  /* Setup logs */

4124 4125 4126 4127 4128
  /*
    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.
  */
4129
  if (opt_error_log && !opt_abort)
4130 4131
  {
    if (!log_error_file_ptr[0])
4132
      fn_format(log_error_file, pidfile_name, mysql_data_home, ".err",
4133 4134 4135 4136
                MY_REPLACE_EXT); /* replace '.<domain>' by '.err', bug#4997 */
    else
      fn_format(log_error_file, log_error_file_ptr, mysql_data_home, ".err",
                MY_UNPACK_FILENAME | MY_SAFE_PATH);
4137 4138 4139 4140 4141
    /*
      _ptr may have been set to my_disabled_option or "" if no argument was
      passed, but we need to show the real name in SHOW VARIABLES:
    */
    log_error_file_ptr= log_error_file;
4142
    if (!log_error_file[0])
4143
      opt_error_log= 0;                         // Too long file name
4144 4145
    else
    {
4146
      my_bool res;
4147
#ifndef EMBEDDED_LIBRARY
4148 4149 4150
      res= reopen_fstreams(log_error_file, stdout, stderr);
#else
      res= reopen_fstreams(log_error_file, NULL, stderr);
4151
#endif
4152 4153 4154

      if (!res)
        setbuf(stderr, NULL);
4155 4156 4157 4158 4159

#ifdef _WIN32
      /* Add error log to windows crash reporting. */
      add_file_to_crash_report(log_error_file);
#endif
4160 4161 4162
    }
  }

4163 4164
  /* set up the hook before initializing plugins which may use it */
  error_handler_hook= my_message_sql;
4165 4166
  proc_info_hook= set_thd_proc_info;

Marc Alff's avatar
Marc Alff committed
4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178
#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 */

unknown's avatar
unknown committed
4179 4180 4181 4182 4183 4184
  if (xid_cache_init())
  {
    sql_print_error("Out of memory");
    unireg_abort(1);
  }

4185 4186 4187 4188
  /*
    initialize delegates for extension observers, errors have already
    been reported in the function
  */
He Zhenxing's avatar
He Zhenxing committed
4189 4190 4191
  if (delegates_init())
    unireg_abort(1);

unknown's avatar
unknown committed
4192
  /* need to configure logging before initializing storage engines */
4193
  if (!opt_bin_log_used)
unknown's avatar
unknown committed
4194
  {
4195 4196 4197 4198 4199 4200
    if (opt_log_slave_updates)
      sql_print_warning("You need to use --log-bin to make "
                        "--log-slave-updates work.");
    if (binlog_format_used)
      sql_print_warning("You need to use --log-bin to make "
                        "--binlog-format work.");
4201
  }
4202

4203
  /* Check that we have not let the format to unspecified at this point */
4204
  DBUG_ASSERT((uint)global_system_variables.binlog_format <=
4205
              array_elements(binlog_format_names)-1);
4206

unknown's avatar
unknown committed
4207
#ifdef HAVE_REPLICATION
unknown's avatar
unknown committed
4208 4209
  if (opt_log_slave_updates && replicate_same_server_id)
  {
4210 4211 4212
    if (opt_bin_log)
    {
      sql_print_error("using --replicate-same-server-id in conjunction with \
unknown's avatar
unknown committed
4213 4214
--log-slave-updates is impossible, it would lead to infinite loops in this \
server.");
4215 4216 4217 4218 4219 4220
      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
4221
  }
unknown's avatar
unknown committed
4222
#endif
4223

unknown's avatar
Merge  
unknown committed
4224
  if (opt_bin_log)
4225
  {
4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246
    /* Reports an error and aborts, if the --log-bin's path 
       is a directory.*/
    if (opt_bin_logname && 
        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
4247 4248 4249 4250
    char buf[FN_REFLEN];
    const char *ln;
    ln= mysql_bin_log.generate_name(opt_bin_logname, "-bin", 1, buf);
    if (!opt_bin_logname && !opt_binlog_index_name)
4251 4252
    {
      /*
unknown's avatar
Merge  
unknown committed
4253 4254 4255 4256 4257
        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.
4258
      */
4259 4260 4261 4262
      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
4263
                        "changed! Please use '--log-basename=%s' or "
4264
                        "'--log-bin=%s' to avoid this problem.",
Sergei Golubchik's avatar
Sergei Golubchik committed
4265
                        opt_log_basename, ln);
4266
    }
unknown's avatar
Merge  
unknown committed
4267
    if (ln == buf)
4268
    {
4269
      opt_bin_logname= my_once_strdup(buf, MYF(MY_WME));
4270
    }
4271
    if (mysql_bin_log.open_index_file(opt_binlog_index_name, ln, TRUE))
unknown's avatar
unknown committed
4272 4273 4274
    {
      unireg_abort(1);
    }
4275 4276
  }

4277
  /* call ha_init_key_cache() on all key caches to init them */
4278
  process_key_caches(&ha_init_key_cache, 0);
4279

4280 4281 4282
  init_global_table_stats();
  init_global_index_stats();

4283 4284 4285 4286
  /* Allow storage engine to give real error messages */
  if (ha_init_errors())
    DBUG_RETURN(1);

Marc Alff's avatar
Marc Alff committed
4287
  if (plugin_init(&remaining_argc, remaining_argv,
4288
                  (opt_noacl ? PLUGIN_INIT_SKIP_PLUGIN_TABLE : 0) |
4289
                  (opt_abort ? PLUGIN_INIT_SKIP_INITIALIZATION : 0)))
4290 4291 4292
  {
    sql_print_error("Failed to initialize plugins.");
    unireg_abort(1);
unknown's avatar
unknown committed
4293
  }
4294
  plugins_are_initialized= TRUE;  /* Don't separate from init function */
unknown's avatar
unknown committed
4295

4296 4297 4298 4299 4300 4301
  have_csv= plugin_status(STRING_WITH_LEN("csv"),
                          MYSQL_STORAGE_ENGINE_PLUGIN);
  have_ndbcluster= plugin_status(STRING_WITH_LEN("ndbcluster"),
                                 MYSQL_STORAGE_ENGINE_PLUGIN);
  have_partitioning= plugin_status(STRING_WITH_LEN("partition"),
                                   MYSQL_STORAGE_ENGINE_PLUGIN);
unknown's avatar
unknown committed
4302 4303

  /* we do want to exit if there are any other unknown options */
Marc Alff's avatar
Marc Alff committed
4304
  if (remaining_argc > 1)
unknown's avatar
unknown committed
4305 4306
  {
    int ho_error;
unknown's avatar
unknown committed
4307
    struct my_option no_opts[]=
unknown's avatar
unknown committed
4308 4309 4310 4311 4312
    {
      {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
4313
      that there are unprocessed options.
unknown's avatar
unknown committed
4314 4315
    */
    my_getopt_skip_unknown= 0;
unknown's avatar
unknown committed
4316

Marc Alff's avatar
Marc Alff committed
4317
    if ((ho_error= handle_options(&remaining_argc, &remaining_argv, no_opts,
4318
                                  mysqld_get_one_option)))
unknown's avatar
unknown committed
4319
      unireg_abort(ho_error);
Marc Alff's avatar
Marc Alff committed
4320 4321 4322
    /* Add back the program name handle_options removes */
    remaining_argc++;
    remaining_argv--;
4323
    my_getopt_skip_unknown= TRUE;
unknown's avatar
unknown committed
4324

Marc Alff's avatar
Marc Alff committed
4325
    if (remaining_argc > 1)
unknown's avatar
unknown committed
4326
    {
4327
      fprintf(stderr, "%s: Too many arguments (first extra is '%s').\n",
Marc Alff's avatar
Marc Alff committed
4328
              my_progname, remaining_argv[1]);
unknown's avatar
unknown committed
4329 4330
      unireg_abort(1);
    }
unknown's avatar
unknown committed
4331 4332
  }

4333
  if (opt_abort)
4334 4335
    unireg_abort(0);

unknown's avatar
unknown committed
4336
  /* if the errmsg.sys is not loaded, terminate to maintain behaviour */
4337 4338
  if (!DEFAULT_ERRMSGS[0][0])
    unireg_abort(1);  
unknown's avatar
unknown committed
4339

unknown's avatar
unknown committed
4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366
  /* 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
4367 4368
    LEX_STRING csv_name={C_STRING_WITH_LEN("csv")};
    if (!plugin_is_ready(&csv_name, MYSQL_STORAGE_ENGINE_PLUGIN))
unknown's avatar
unknown committed
4369
    {
4370
      /* purecov: begin inspected */
unknown's avatar
unknown committed
4371 4372
      sql_print_error("CSV engine is not present, falling back to the "
                      "log files");
unknown's avatar
unknown committed
4373
      log_output_options= (log_output_options & ~LOG_TABLE) | LOG_FILE;
4374
      /* purecov: end */
unknown's avatar
unknown committed
4375 4376 4377 4378 4379 4380
    }

    logger.set_handlers(LOG_FILE, opt_slow_log ? log_output_options:LOG_NONE,
                        opt_log ? log_output_options:LOG_NONE);
  }

4381
  /*
4382
    Set the default storage engine
4383
  */
4384 4385 4386 4387 4388 4389
  LEX_STRING name= { default_storage_engine, strlen(default_storage_engine) };
  plugin_ref plugin;
  handlerton *hton;
  if ((plugin= ha_resolve_by_name(0, &name)))
    hton= plugin_data(plugin, handlerton*);
  else
4390
  {
4391 4392 4393 4394 4395 4396 4397
    sql_print_error("Unknown/unsupported storage engine: %s",
                    default_storage_engine);
    unireg_abort(1);
  }
  if (!ha_storage_engine_is_enabled(hton))
  {
    if (!opt_bootstrap)
4398
    {
4399 4400
      sql_print_error("Default storage engine (%s) is not available",
                      default_storage_engine);
4401 4402
      unireg_abort(1);
    }
4403 4404 4405 4406 4407 4408 4409 4410
    DBUG_ASSERT(global_system_variables.table_plugin);
  }
  else
  {
    /*
      Need to unlock as global_system_variables.table_plugin
      was acquired during plugin_init()
    */
Sergei Golubchik's avatar
Sergei Golubchik committed
4411
    mysql_mutex_lock(&LOCK_global_system_variables);
4412 4413
    plugin_unlock(0, global_system_variables.table_plugin);
    global_system_variables.table_plugin= plugin;
Sergei Golubchik's avatar
Sergei Golubchik committed
4414
    mysql_mutex_unlock(&LOCK_global_system_variables);
4415
  }
4416
#if defined(WITH_ARIA_STORAGE_ENGINE) && defined(USE_ARIA_FOR_TMP_TABLES)
4417
  if (!ha_storage_engine_is_enabled(maria_hton) && !opt_bootstrap)
4418
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
4419
    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");
4420 4421
    unireg_abort(1);
  }
4422 4423 4424 4425 4426
  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();
4427
#endif
4428

unknown's avatar
unknown committed
4429 4430 4431 4432
  tc_log= (total_ha_2pc > 1 ? (opt_bin_log  ?
                               (TC_LOG *) &mysql_bin_log :
                               (TC_LOG *) &tc_log_mmap) :
           (TC_LOG *) &tc_log_dummy);
unknown's avatar
unknown committed
4433

unknown's avatar
unknown committed
4434
  if (tc_log->open(opt_bin_log ? opt_bin_logname : opt_tc_log_file))
unknown's avatar
Merge  
unknown committed
4435 4436 4437 4438 4439
  {
    sql_print_error("Can't init tc log");
    unireg_abort(1);
  }

unknown's avatar
unknown committed
4440 4441 4442 4443 4444
  if (ha_recover(0))
  {
    unireg_abort(1);
  }

unknown's avatar
Merge  
unknown committed
4445
  if (opt_bin_log && mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0,
4446
                                        WRITE_CACHE, 0, max_binlog_size, 0, TRUE))
unknown's avatar
unknown committed
4447
    unireg_abort(1);
unknown's avatar
Merge  
unknown committed
4448 4449 4450

#ifdef HAVE_REPLICATION
  if (opt_bin_log && expire_logs_days)
4451
  {
4452
    time_t purge_time= server_start_time - expire_logs_days*24*60*60;
unknown's avatar
Merge  
unknown committed
4453 4454
    if (purge_time >= 0)
      mysql_bin_log.purge_logs_before_date(purge_time);
4455
  }
unknown's avatar
Merge  
unknown committed
4456 4457 4458 4459
#endif

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

unknown's avatar
unknown committed
4461
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && !defined(EMBEDDED_LIBRARY)
4462
  if (locked_in_memory && !getuid())
4463
  {
4464
    if (setreuid((uid_t)-1, 0) == -1)
4465
    {                        // this should never happen
4466
      sql_perror("setreuid");
4467 4468
      unireg_abort(1);
    }
4469 4470
    if (mlockall(MCL_CURRENT))
    {
4471
      if (global_system_variables.log_warnings)
4472
	sql_print_warning("Failed to lock memory. Errno: %d\n",errno);
unknown's avatar
unknown committed
4473
      locked_in_memory= 0;
4474
    }
4475 4476
    if (user_info)
      set_user(mysqld_user, user_info);
4477
  }
unknown's avatar
unknown committed
4478
  else
4479
#endif
unknown's avatar
unknown committed
4480
    locked_in_memory=0;
4481

4482
  ft_init_stopwords();
unknown's avatar
unknown committed
4483

unknown's avatar
unknown committed
4484
  init_max_user_conn();
4485
  init_update_queries();
4486 4487
  init_global_user_stats();
  init_global_client_stats();
4488
  DBUG_RETURN(0);
unknown's avatar
unknown committed
4489
}
unknown's avatar
unknown committed
4490

4491

4492
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
4493

unknown's avatar
unknown committed
4494 4495 4496
static void create_shutdown_thread()
{
#ifdef __WIN__
4497 4498
  hEventShutdown=CreateEvent(0, FALSE, FALSE, shutdown_event_name);
  pthread_t hThread;
Marc Alff's avatar
Marc Alff committed
4499 4500
  if (mysql_thread_create(key_thread_handle_shutdown,
                          &hThread, &connection_attrib, handle_shutdown, 0))
4501
    sql_print_warning("Can't create thread to handle shutdown requests");
unknown's avatar
unknown committed
4502

4503 4504
  // On "Stop Service" we have to do regular shutdown
  Service.SetShutdownEvent(hEventShutdown);
unknown's avatar
unknown committed
4505
#endif /* __WIN__ */
unknown's avatar
unknown committed
4506
}
unknown's avatar
unknown committed
4507

4508
#endif /* EMBEDDED_LIBRARY */
4509 4510


Vladislav Vaintroub's avatar
Vladislav Vaintroub committed
4511
#if (defined(_WIN32) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY)
4512
static void handle_connections_methods()
unknown's avatar
unknown committed
4513
{
4514 4515
  pthread_t hThread;
  DBUG_ENTER("handle_connections_methods");
unknown's avatar
unknown committed
4516
  if (hPipe == INVALID_HANDLE_VALUE &&
4517 4518
      (!have_tcpip || opt_disable_networking) &&
      !opt_enable_shared_memory)
unknown's avatar
unknown committed
4519
  {
unknown's avatar
unknown committed
4520
    sql_print_error("TCP/IP, --shared-memory, or --named-pipe should be configured on NT OS");
4521
    unireg_abort(1);				// Will not return
unknown's avatar
unknown committed
4522
  }
4523

Marc Alff's avatar
Marc Alff committed
4524 4525
  mysql_mutex_lock(&LOCK_thread_count);
  mysql_cond_init(key_COND_handler_count, &COND_handler_count, NULL);
4526 4527
  handler_count=0;
  if (hPipe != INVALID_HANDLE_VALUE)
unknown's avatar
unknown committed
4528
  {
4529
    handler_count++;
Marc Alff's avatar
Marc Alff committed
4530 4531 4532
    if (mysql_thread_create(key_thread_handle_con_namedpipes,
                            &hThread, &connection_attrib,
                            handle_connections_namedpipes, 0))
unknown's avatar
unknown committed
4533
    {
4534
      sql_print_warning("Can't create thread to handle named pipes");
4535 4536 4537 4538 4539 4540
      handler_count--;
    }
  }
  if (have_tcpip && !opt_disable_networking)
  {
    handler_count++;
Marc Alff's avatar
Marc Alff committed
4541 4542 4543
    if (mysql_thread_create(key_thread_handle_con_sockets,
                            &hThread, &connection_attrib,
                            handle_connections_sockets_thread, 0))
4544
    {
4545
      sql_print_warning("Can't create thread to handle TCP/IP");
4546 4547 4548 4549 4550 4551 4552
      handler_count--;
    }
  }
#ifdef HAVE_SMEM
  if (opt_enable_shared_memory)
  {
    handler_count++;
Marc Alff's avatar
Marc Alff committed
4553 4554 4555
    if (mysql_thread_create(key_thread_handle_con_sharedmem,
                            &hThread, &connection_attrib,
                            handle_connections_shared_memory, 0))
4556
    {
4557
      sql_print_warning("Can't create thread to handle shared memory");
4558
      handler_count--;
unknown's avatar
unknown committed
4559 4560
    }
  }
4561
#endif
unknown's avatar
unknown committed
4562

4563
  while (handler_count > 0)
Marc Alff's avatar
Marc Alff committed
4564 4565
    mysql_cond_wait(&COND_handler_count, &LOCK_thread_count);
  mysql_mutex_unlock(&LOCK_thread_count);
4566 4567
  DBUG_VOID_RETURN;
}
4568 4569 4570

void decrement_handler_count()
{
Marc Alff's avatar
Marc Alff committed
4571
  mysql_mutex_lock(&LOCK_thread_count);
4572
  handler_count--;
Marc Alff's avatar
Marc Alff committed
4573 4574
  mysql_cond_signal(&COND_handler_count);
  mysql_mutex_unlock(&LOCK_thread_count);
4575
  my_thread_end();
4576 4577 4578
}
#else
#define decrement_handler_count()
Vladislav Vaintroub's avatar
Vladislav Vaintroub committed
4579
#endif /* defined(_WIN32) || defined(HAVE_SMEM) */
4580 4581


4582
#ifndef EMBEDDED_LIBRARY
4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619
#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

unknown's avatar
unknown committed
4620 4621 4622
#ifdef __WIN__
int win_main(int argc, char **argv)
#else
4623
int mysqld_main(int argc, char **argv)
unknown's avatar
unknown committed
4624 4625
#endif
{
Marc Alff's avatar
Marc Alff committed
4626 4627 4628 4629 4630
  /*
    Perform basic thread library and malloc initialization,
    to be able to read defaults files and parse options.
  */
  my_progname= argv[0];
4631
  sf_leaking_memory= 1; // no safemalloc memory leak reports if we exit early
4632 4633 4634
#ifdef HAVE_NPTL
  ld_assume_kernel_is_set= (getenv("LD_ASSUME_KERNEL") != 0);
#endif
4635 4636 4637
#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
4638
  {
4639
    fprintf(stderr, "my_init() failed.");
Marc Alff's avatar
Marc Alff committed
4640 4641
    return 1;
  }
4642
#endif
Marc Alff's avatar
Marc Alff committed
4643 4644 4645

  orig_argc= argc;
  orig_argv= argv;
4646
  my_getopt_use_args_separator= TRUE;
Marc Alff's avatar
Marc Alff committed
4647 4648
  if (load_defaults(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv))
    return 1;
4649
  my_getopt_use_args_separator= FALSE;
Marc Alff's avatar
Marc Alff committed
4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 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 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740
  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;

  sys_var_init();

#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
  /*
    The performance schema needs to be initialized as early as possible,
    before to-be-instrumented objects of the server are initialized.
  */
  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);
  sys_var_add_options(&all_early_options, sys_var::PARSE_EARLY);
  add_terminator(&all_early_options);

  /*
    Logs generated while parsing the command line
    options are buffered and printed later.
  */
  buffered_logs.init();
  my_getopt_error_reporter= buffered_option_error_reporter;

  ho_error= handle_options(&remaining_argc, &remaining_argv,
                           (my_option*)(all_early_options.buffer), NULL);
  delete_dynamic(&all_early_options);
  if (ho_error == 0)
  {
    /* Add back the program name handle_options removes */
    remaining_argc++;
    remaining_argv--;
    if (pfs_param.m_enabled)
    {
      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)
    PSI_server= (PSI*) PSI_hook->get_interface(PSI_CURRENT_VERSION);

  if (PSI_server)
  {
    /*
      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 */
    PSI_thread *psi= PSI_server->new_thread(key_thread_main, NULL, 0);
    if (psi)
      PSI_server->set_thread(psi);

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

  init_error_log_mutex();
4746

4747 4748 4749
  /* Initialize audit interface globals. Audit plugins are inited later. */
  mysql_audit_initialize();

4750 4751 4752 4753 4754 4755
  /*
    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
4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777
#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
4778
#ifdef _CUSTOMSTARTUPCONFIG_
unknown's avatar
unknown committed
4779 4780 4781
  if (_cust_check_startup())
  {
    / * _cust_check_startup will report startup failure error * /
unknown's avatar
Merge  
unknown committed
4782
    exit(1);
unknown's avatar
unknown committed
4783 4784
  }
#endif
unknown's avatar
unknown committed
4785

Marc Alff's avatar
Marc Alff committed
4786
  if (init_common_variables())
4787
    unireg_abort(1);				// Will do exit
unknown's avatar
unknown committed
4788 4789

  init_signals();
4790 4791 4792

  my_thread_stack_size= my_setstacksize(&connection_attrib,
                                        my_thread_stack_size);
unknown's avatar
unknown committed
4793

4794
  (void) thr_setconcurrency(concurrency);	// 10 by default
unknown's avatar
unknown committed
4795

4796 4797
  select_thread=pthread_self();
  select_thread_in_use=1;
unknown's avatar
unknown committed
4798 4799 4800 4801 4802 4803

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

4804 4805
#ifndef DBUG_OFF
  test_lc_time_sz();
4806
  srand((uint) time(NULL)); 
4807 4808
#endif

unknown's avatar
unknown committed
4809 4810 4811
  /*
    We have enough space for fiddling with the argv, continue
  */
unknown's avatar
unknown committed
4812
  check_data_home(mysql_real_data_home);
4813
  if (my_setwd(mysql_real_data_home, opt_abort ? 0 : MYF(MY_WME)) && !opt_abort)
unknown's avatar
unknown committed
4814
    unireg_abort(1);				/* purecov: inspected */
unknown's avatar
unknown committed
4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825

  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);
  }

unknown's avatar
unknown committed
4826 4827
  if (opt_bin_log && !server_id)
  {
4828
    server_id= 1;
unknown's avatar
unknown committed
4829
#ifdef EXTRA_DEBUG
4830 4831 4832 4833
    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.");
4834
#endif
unknown's avatar
unknown committed
4835 4836
  }

4837 4838 4839 4840 4841 4842 4843 4844
  /* 
   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
4845
  if (init_server_components())
unknown's avatar
unknown committed
4846
    unireg_abort(1);
unknown's avatar
unknown committed
4847

4848
  init_ssl();
unknown's avatar
unknown committed
4849 4850
  network_init();

unknown's avatar
unknown committed
4851 4852 4853
#ifdef __WIN__
  if (!opt_console)
  {
4854 4855
    if (reopen_fstreams(log_error_file, stdout, stderr))
      unireg_abort(1);
4856
    setbuf(stderr, NULL);
unknown's avatar
unknown committed
4857
    FreeConsole();				// Remove window
4858
  }
unknown's avatar
unknown committed
4859 4860
#endif

4861 4862 4863 4864 4865 4866
  /*
   Initialize my_str_malloc() and my_str_free()
  */
  my_str_malloc= &my_str_malloc_mysqld;
  my_str_free= &my_str_free_mysqld;

unknown's avatar
unknown committed
4867 4868 4869 4870 4871
  /*
    init signals & alarm
    After this we can't quit by a simple unireg_abort
  */
  start_signal_handler();				// Creates pidfile
4872

4873
  if (mysql_rm_tmp_tables() || acl_init(opt_noacl) ||
4874
      my_tz_init((THD *)0, default_tz_name, opt_bootstrap))
unknown's avatar
unknown committed
4875 4876 4877
  {
    abort_loop=1;
    select_thread_in_use=0;
4878

unknown's avatar
unknown committed
4879
    (void) pthread_kill(signal_thread, MYSQL_KILL_SIGNAL);
4880

4881
    delete_pid_file(MYF(MY_WME));
4882

4883
    if (unix_sock != INVALID_SOCKET)
4884
      unlink(mysqld_unix_port);
unknown's avatar
unknown committed
4885 4886
    exit(1);
  }
4887

unknown's avatar
unknown committed
4888
  if (!opt_noacl)
4889
    (void) grant_init();
unknown's avatar
unknown committed
4890

unknown's avatar
unknown committed
4891 4892 4893
  if (!opt_bootstrap)
    servers_init(0);

unknown's avatar
unknown committed
4894
  if (!opt_noacl)
4895 4896
  {
#ifdef HAVE_DLOPEN
unknown's avatar
unknown committed
4897 4898
    udf_init();
#endif
4899
  }
4900

4901
  init_status_vars();
unknown's avatar
unknown committed
4902 4903
  if (opt_bootstrap) /* If running with bootstrap, do not start replication. */
    opt_skip_slave_start= 1;
4904 4905

  binlog_unsafe_map_init();
4906 4907 4908 4909 4910 4911 4912 4913 4914 4915
  /*
    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);
  }
4916

Marc Alff's avatar
Marc Alff committed
4917 4918
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
  initialize_performance_schema_acl(opt_bootstrap);
4919 4920 4921 4922 4923 4924 4925 4926
  /*
    Do not check the structure of the performance schema tables
    during bootstrap:
    - the tables are not supposed to exist yet, bootstrap will create them
    - a check would print spurious error messages
  */
  if (! opt_bootstrap)
    check_performance_schema();
Marc Alff's avatar
Marc Alff committed
4927 4928 4929 4930
#endif

  initialize_information_schema_acl();

4931 4932 4933 4934 4935
  execute_ddl_log_recovery();

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

unknown's avatar
unknown committed
4936 4937
  if (opt_bootstrap)
  {
4938
    select_thread_in_use= 0;                    // Allow 'kill' to work
Marc Alff's avatar
Marc Alff committed
4939
    bootstrap(mysql_stdin);
4940 4941 4942 4943 4944 4945 4946
    if (!kill_in_progress)
      unireg_abort(bootstrap_error ? 1 : 0);
    else
    {
      sleep(2);                                 // Wait for kill
      exit(0);
    }
unknown's avatar
unknown committed
4947
  }
4948
  if (opt_init_file && *opt_init_file)
unknown's avatar
unknown committed
4949 4950 4951 4952
  {
    if (read_init_file(opt_init_file))
      unireg_abort(1);
  }
unknown's avatar
unknown committed
4953

Sergei Golubchik's avatar
Sergei Golubchik committed
4954 4955 4956 4957 4958
  /*
    We must have LOCK_open before LOCK_global_system_variables because
    LOCK_open is hold while sql_plugin.c::intern_sys_var_ptr() is called.
  */
  mysql_mutex_record_order(&LOCK_open, &LOCK_global_system_variables);
4959

unknown's avatar
unknown committed
4960
  create_shutdown_thread();
4961
  start_handle_manager();
unknown's avatar
unknown committed
4962

4963
  sql_print_information(ER_DEFAULT(ER_STARTUP),my_progname,server_version,
unknown's avatar
unknown committed
4964
                        ((unix_sock == INVALID_SOCKET) ? (char*) ""
unknown's avatar
Merge  
unknown committed
4965
                                                       : mysqld_unix_port),
unknown's avatar
unknown committed
4966
                         mysqld_port,
unknown's avatar
Merge  
unknown committed
4967
                         MYSQL_COMPILATION_COMMENT);
4968 4969 4970
#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
  Service.SetRunning();
#endif
unknown's avatar
unknown committed
4971

unknown's avatar
unknown committed
4972 4973

  /* Signal threads waiting for server to be started */
Marc Alff's avatar
Marc Alff committed
4974
  mysql_mutex_lock(&LOCK_server_started);
unknown's avatar
unknown committed
4975
  mysqld_server_started= 1;
Marc Alff's avatar
Marc Alff committed
4976 4977
  mysql_cond_signal(&COND_server_started);
  mysql_mutex_unlock(&LOCK_server_started);
unknown's avatar
unknown committed
4978

4979
#if defined(_WIN32) || defined(HAVE_SMEM)
4980
  handle_connections_methods();
unknown's avatar
unknown committed
4981
#else
4982 4983
  handle_connections_sockets();
#endif /* _WIN32 || HAVE_SMEM */
unknown's avatar
unknown committed
4984 4985

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

unknown's avatar
unknown committed
4987 4988 4989
  DBUG_PRINT("quit",("Exiting main thread"));

#ifndef __WIN__
unknown's avatar
unknown committed
4990
#ifdef EXTRA_DEBUG2
unknown's avatar
unknown committed
4991 4992
  sql_print_error("Before Lock_thread_count");
#endif
Marc Alff's avatar
Marc Alff committed
4993
  mysql_mutex_lock(&LOCK_thread_count);
unknown's avatar
unknown committed
4994
  DBUG_PRINT("quit", ("Got thread_count mutex"));
unknown's avatar
unknown committed
4995
  select_thread_in_use=0;			// For close_connections
Marc Alff's avatar
Marc Alff committed
4996 4997
  mysql_mutex_unlock(&LOCK_thread_count);
  mysql_cond_broadcast(&COND_thread_count);
unknown's avatar
unknown committed
4998
#ifdef EXTRA_DEBUG2
unknown's avatar
unknown committed
4999 5000
  sql_print_error("After lock_thread_count");
#endif
unknown's avatar
merge  
unknown committed
5001
#endif /* __WIN__ */
5002

5003 5004 5005 5006 5007 5008 5009 5010 5011
#ifdef HAVE_PSI_INTERFACE
  /*
    Disable the main thread instrumentation,
    to avoid recording events during the shutdown.
  */
  if (PSI_server)
    PSI_server->delete_current_thread();
#endif

unknown's avatar
unknown committed
5012
  /* Wait until cleanup is done */
Marc Alff's avatar
Marc Alff committed
5013
  mysql_mutex_lock(&LOCK_thread_count);
unknown's avatar
unknown committed
5014
  while (!ready_to_exit)
Marc Alff's avatar
Marc Alff committed
5015 5016
    mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
merge  
unknown committed
5017 5018

#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
unknown's avatar
merge  
unknown committed
5019 5020 5021 5022
  if (Service.IsNT() && start_mode)
    Service.Stop();
  else
  {
unknown's avatar
unknown committed
5023
    Service.SetShutdownEvent(0);
unknown's avatar
merge  
unknown committed
5024 5025 5026
    if (hEventShutdown)
      CloseHandle(hEventShutdown);
  }
unknown's avatar
unknown committed
5027
#endif
5028
  mysqld_exit(0);
5029
  return 0;
unknown's avatar
unknown committed
5030 5031
}

5032
#endif /* !EMBEDDED_LIBRARY */
unknown's avatar
unknown committed
5033

unknown's avatar
SCRUM  
unknown committed
5034

5035 5036 5037 5038 5039
/****************************************************************************
  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
5040
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
unknown's avatar
unknown committed
5041 5042
int mysql_service(void *p)
{
5043 5044 5045
  if (my_thread_init())
    return 1;
  
5046 5047 5048 5049
  if (use_opt_args)
    win_main(opt_argc, opt_argv);
  else
    win_main(Service.my_argc, Service.my_argv);
5050 5051

  my_thread_end();
unknown's avatar
unknown committed
5052 5053 5054
  return 0;
}

5055 5056 5057 5058 5059 5060 5061 5062

/* 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
5063 5064
    return strmake(to, from, length-1);
  return strxnmov(to, length-1, "\"", from, "\"", NullS);
5065 5066 5067
}


unknown's avatar
unknown committed
5068 5069
/**
  Handle basic handling of services, like installation and removal.
5070

unknown's avatar
unknown committed
5071 5072 5073 5074 5075 5076
  @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

5077 5078
  @retval 0	option handled
  @retval 1	Could not handle option
unknown's avatar
unknown committed
5079
*/
5080

5081 5082 5083 5084 5085
static bool
default_service_handling(char **argv,
			 const char *servicename,
			 const char *displayname,
			 const char *file_path,
unknown's avatar
Merge  
unknown committed
5086 5087
			 const char *extra_opt,
			 const char *account_name)
5088
{
5089
  char path_and_service[FN_REFLEN+FN_REFLEN+32], *pos, *end;
5090
  const char *opt_delim;
5091
  end= path_and_service + sizeof(path_and_service)-3;
5092 5093 5094 5095 5096

  /* We have to quote filename if it contains spaces */
  pos= add_quoted_string(path_and_service, file_path, end);
  if (*extra_opt)
  {
5097 5098 5099 5100 5101
    /* 
     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.  
    */
5102
    *pos++= ' ';
5103 5104 5105
    if (opt_delim= strchr(extra_opt, '='))
    {
      size_t length= ++opt_delim - extra_opt;
5106
      pos= strnmov(pos, extra_opt, length);
5107 5108 5109 5110 5111
    }
    else
      opt_delim= extra_opt;
    
    pos= add_quoted_string(pos, opt_delim, end);
5112
  }
5113 5114
  /* We must have servicename last */
  *pos++= ' ';
unknown's avatar
unknown committed
5115
  (void) add_quoted_string(pos, servicename, end);
5116

5117 5118
  if (Service.got_service_option(argv, "install"))
  {
unknown's avatar
Merge  
unknown committed
5119 5120
    Service.Install(1, servicename, displayname, path_and_service,
                    account_name);
5121 5122 5123 5124
    return 0;
  }
  if (Service.got_service_option(argv, "install-manual"))
  {
unknown's avatar
Merge  
unknown committed
5125 5126
    Service.Install(0, servicename, displayname, path_and_service,
                    account_name);
5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137
    return 0;
  }
  if (Service.got_service_option(argv, "remove"))
  {
    Service.Remove(servicename);
    return 0;
  }
  return 1;
}


5138
int mysqld_main(int argc, char **argv)
unknown's avatar
unknown committed
5139
{
5140 5141
  my_progname= argv[0];

unknown's avatar
unknown committed
5142 5143 5144 5145
  /*
    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
5146
  */
5147
  int10_to_str((int) GetCurrentProcessId(),strmov(shutdown_event_name,
unknown's avatar
Merge  
unknown committed
5148 5149
                                                  "MySQLShutdown"), 10);

5150 5151 5152
  /* Must be initialized early for comparison of service name */
  system_charset_info= &my_charset_utf8_general_ci;

5153 5154 5155 5156 5157 5158
  if (my_init())
  {
    fprintf(stderr, "my_init() failed.");
    return 1;
  }

unknown's avatar
unknown committed
5159
  if (Service.GetOS())	/* true NT family */
unknown's avatar
unknown committed
5160
  {
unknown's avatar
unknown committed
5161
    char file_path[FN_REFLEN];
5162
    my_path(file_path, argv[0], "");		      /* Find name in path */
unknown's avatar
unknown committed
5163 5164
    fn_format(file_path,argv[0],file_path,"",
	      MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_RESOLVE_SYMLINKS);
unknown's avatar
unknown committed
5165

unknown's avatar
unknown committed
5166
    if (argc == 2)
5167
    {
5168
      if (!default_service_handling(argv, MYSQL_SERVICENAME, MYSQL_SERVICENAME,
unknown's avatar
Merge  
unknown committed
5169
				   file_path, "", NULL))
5170
	return 0;
unknown's avatar
unknown committed
5171
      if (Service.IsService(argv[1]))        /* Start an optional service */
unknown's avatar
unknown committed
5172
      {
unknown's avatar
unknown committed
5173 5174 5175 5176 5177 5178
	/*
	  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.
	*/
5179
	if (my_strcasecmp(system_charset_info, argv[1],"mysql"))
5180
	  load_default_groups[load_default_groups_sz-2]= argv[1];
unknown's avatar
unknown committed
5181
        start_mode= 1;
5182
        Service.Init(argv[1], mysql_service);
unknown's avatar
unknown committed
5183 5184 5185 5186
        return 0;
      }
    }
    else if (argc == 3) /* install or remove any optional service */
unknown's avatar
unknown committed
5187
    {
unknown's avatar
Merge  
unknown committed
5188 5189
      if (!default_service_handling(argv, argv[2], argv[2], file_path, "",
                                    NULL))
5190 5191
	return 0;
      if (Service.IsService(argv[2]))
unknown's avatar
unknown committed
5192
      {
5193 5194 5195 5196
	/*
	  mysqld was started as
	  mysqld --defaults-file=my_path\my.ini service-name
	*/
5197
	use_opt_args=1;
5198
	opt_argc= 2;				// Skip service-name
5199 5200
	opt_argv=argv;
	start_mode= 1;
5201
	if (my_strcasecmp(system_charset_info, argv[2],"mysql"))
5202
	  load_default_groups[load_default_groups_sz-2]= argv[2];
5203
	Service.Init(argv[2], mysql_service);
5204
	return 0;
unknown's avatar
unknown committed
5205 5206
      }
    }
unknown's avatar
Merge  
unknown committed
5207
    else if (argc == 4 || argc == 5)
5208 5209
    {
      /*
unknown's avatar
Merge  
unknown committed
5210 5211 5212 5213 5214
        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.)
5215
      */
unknown's avatar
Merge  
unknown committed
5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230
      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;
5231
    }
unknown's avatar
unknown committed
5232
    else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME))
unknown's avatar
unknown committed
5233
    {
unknown's avatar
unknown committed
5234 5235 5236
      /* start the default service */
      start_mode= 1;
      Service.Init(MYSQL_SERVICENAME, mysql_service);
unknown's avatar
unknown committed
5237 5238 5239
      return 0;
    }
  }
unknown's avatar
unknown committed
5240
  /* Start as standalone server */
unknown's avatar
unknown committed
5241 5242 5243 5244 5245 5246 5247 5248
  Service.my_argc=argc;
  Service.my_argv=argv;
  mysql_service(NULL);
  return 0;
}
#endif


unknown's avatar
unknown committed
5249
/**
5250 5251 5252
  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.
*/
5253

Marc Alff's avatar
Marc Alff committed
5254
static void bootstrap(MYSQL_FILE *file)
unknown's avatar
unknown committed
5255
{
5256
  DBUG_ENTER("bootstrap");
5257

5258
  THD *thd= new THD;
unknown's avatar
unknown committed
5259
  thd->bootstrap=1;
unknown's avatar
unknown committed
5260
  my_net_init(&thd->net,(st_vio*) 0);
unknown's avatar
unknown committed
5261
  thd->max_client_packet_length= thd->net.max_packet;
5262
  thd->security_ctx->master_access= ~(ulong)0;
unknown's avatar
unknown committed
5263
  thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
unknown's avatar
unknown committed
5264
  thread_count++;
5265
  in_bootstrap= TRUE;
5266 5267

  bootstrap_file=file;
unknown's avatar
unknown committed
5268
#ifndef EMBEDDED_LIBRARY			// TODO:  Enable this
Marc Alff's avatar
Marc Alff committed
5269 5270 5271
  if (mysql_thread_create(key_thread_bootstrap,
                          &thd->real_id, &connection_attrib, handle_bootstrap,
                          (void*) thd))
5272
  {
5273
    sql_print_warning("Can't create thread to handle bootstrap");
unknown's avatar
Merge  
unknown committed
5274 5275
    bootstrap_error=-1;
    DBUG_VOID_RETURN;
5276 5277
  }
  /* Wait for thread to die */
Marc Alff's avatar
Marc Alff committed
5278
  mysql_mutex_lock(&LOCK_thread_count);
5279
  while (in_bootstrap)
5280
  {
Marc Alff's avatar
Marc Alff committed
5281
    mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
5282 5283
    DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
  }
Marc Alff's avatar
Marc Alff committed
5284
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
5285 5286
#else
  thd->mysql= 0;
Marc Alff's avatar
Marc Alff committed
5287
  do_handle_bootstrap(thd);
unknown's avatar
unknown committed
5288 5289
#endif

unknown's avatar
Merge  
unknown committed
5290
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
5291 5292
}

5293

unknown's avatar
unknown committed
5294 5295
static bool read_init_file(char *file_name)
{
Marc Alff's avatar
Marc Alff committed
5296
  MYSQL_FILE *file;
unknown's avatar
unknown committed
5297 5298
  DBUG_ENTER("read_init_file");
  DBUG_PRINT("enter",("name: %s",file_name));
Marc Alff's avatar
Marc Alff committed
5299 5300
  if (!(file= mysql_file_fopen(key_file_init, file_name,
                               O_RDONLY, MYF(MY_WME))))
5301
    DBUG_RETURN(TRUE);
unknown's avatar
Merge  
unknown committed
5302
  bootstrap(file);
Marc Alff's avatar
Marc Alff committed
5303
  mysql_file_fclose(file, MYF(MY_WME));
5304
  DBUG_RETURN(FALSE);
unknown's avatar
unknown committed
5305 5306 5307
}


Mikael Ronström's avatar
Mikael Ronström committed
5308 5309 5310 5311 5312 5313 5314 5315
/**
  Increment number of created threads
*/
void inc_thread_created(void)
{
  thread_created++;
}

5316
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
5317 5318 5319 5320 5321 5322 5323 5324 5325 5326

/*
   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!
*/
5327

unknown's avatar
unknown committed
5328 5329
void handle_connection_in_main_thread(THD *thd)
{
Marc Alff's avatar
Marc Alff committed
5330
  mysql_mutex_assert_owner(&LOCK_thread_count);
unknown's avatar
unknown committed
5331 5332
  thread_cache_size=0;			// Safety
  threads.append(thd);
Marc Alff's avatar
Marc Alff committed
5333
  mysql_mutex_unlock(&LOCK_thread_count);
5334
  thd->start_utime= microsecond_interval_timer();
Marc Alff's avatar
Marc Alff committed
5335
  do_handle_one_connection(thd);
unknown's avatar
unknown committed
5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347
}


/*
  Scheduler that uses one thread per connection
*/

void create_thread_to_handle_connection(THD *thd)
{
  if (cached_thread_count > wake_thread)
  {
    /* Get thread from cache */
5348
    thread_cache.push_back(thd);
unknown's avatar
unknown committed
5349
    wake_thread++;
Marc Alff's avatar
Marc Alff committed
5350
    mysql_cond_signal(&COND_thread_cache);
unknown's avatar
unknown committed
5351 5352 5353
  }
  else
  {
5354
    char error_message_buff[MYSQL_ERRMSG_SIZE];
unknown's avatar
unknown committed
5355 5356 5357 5358 5359
    /* Create new thread to handle connection */
    int error;
    thread_created++;
    threads.append(thd);
    DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id));
5360
    thd->prior_thr_create_utime= microsecond_interval_timer();
Marc Alff's avatar
Marc Alff committed
5361 5362 5363 5364
    if ((error= mysql_thread_create(key_thread_one_connection,
                                    &thd->real_id, &connection_attrib,
                                    handle_one_connection,
                                    (void*) thd)))
unknown's avatar
unknown committed
5365
    {
5366
      /* purecov: begin inspected */
unknown's avatar
unknown committed
5367 5368 5369 5370
      DBUG_PRINT("error",
                 ("Can't create thread to handle request (error %d)",
                  error));
      thread_count--;
5371
      thd->killed= KILL_CONNECTION;             // Safety
Marc Alff's avatar
Marc Alff committed
5372
      mysql_mutex_unlock(&LOCK_thread_count);
5373

Marc Alff's avatar
Marc Alff committed
5374
      mysql_mutex_lock(&LOCK_connection_count);
5375
      (*thd->scheduler->connection_count)--;
Marc Alff's avatar
Marc Alff committed
5376
      mysql_mutex_unlock(&LOCK_connection_count);
5377

unknown's avatar
unknown committed
5378
      statistic_increment(aborted_connects,&LOCK_status);
5379 5380
      /* Can't use my_error() since store_globals has not been called. */
      my_snprintf(error_message_buff, sizeof(error_message_buff),
5381
                  ER_THD(thd, ER_CANT_CREATE_THREAD), error);
Marc Alff's avatar
Marc Alff committed
5382
      net_send_error(thd, ER_CANT_CREATE_THREAD, error_message_buff, NULL);
Sergei Golubchik's avatar
Sergei Golubchik committed
5383
      close_connection(thd, ER_OUT_OF_RESOURCES);
Marc Alff's avatar
Marc Alff committed
5384
      mysql_mutex_lock(&LOCK_thread_count);
unknown's avatar
unknown committed
5385
      delete thd;
Marc Alff's avatar
Marc Alff committed
5386
      mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
5387 5388 5389 5390
      return;
      /* purecov: end */
    }
  }
Marc Alff's avatar
Marc Alff committed
5391
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
5392 5393 5394 5395
  DBUG_PRINT("info",("Thread created"));
}


unknown's avatar
unknown committed
5396
/**
5397 5398 5399 5400 5401 5402
  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
5403
    In single-threaded mode (\#define ONE_THREAD) connection will be
5404 5405
    handled inside this function.

unknown's avatar
unknown committed
5406
  @param[in,out] thd    Thread handle of future thread.
5407 5408
*/

unknown's avatar
unknown committed
5409 5410 5411 5412
static void create_new_thread(THD *thd)
{
  DBUG_ENTER("create_new_thread");

5413 5414 5415 5416 5417
  /*
    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
5418
  mysql_mutex_lock(&LOCK_connection_count);
5419

5420 5421
  if (*thd->scheduler->connection_count >=
      *thd->scheduler->max_connections + 1|| abort_loop)
unknown's avatar
unknown committed
5422
  {
Marc Alff's avatar
Marc Alff committed
5423
    mysql_mutex_unlock(&LOCK_connection_count);
5424

unknown's avatar
unknown committed
5425
    DBUG_PRINT("error",("Too many connections"));
5426
    close_connection(thd, ER_CON_COUNT_ERROR);
5427
    statistic_increment(denied_connections, &LOCK_status);
unknown's avatar
unknown committed
5428 5429 5430
    delete thd;
    DBUG_VOID_RETURN;
  }
5431

5432
  ++*thd->scheduler->connection_count;
5433

5434 5435
  if (connection_count + extra_connection_count > max_used_connections)
    max_used_connections= connection_count + extra_connection_count;
5436

Marc Alff's avatar
Marc Alff committed
5437
  mysql_mutex_unlock(&LOCK_connection_count);
5438 5439 5440

  /* Start a new thread to handle connection. */

Marc Alff's avatar
Marc Alff committed
5441
  mysql_mutex_lock(&LOCK_thread_count);
5442

5443 5444 5445 5446 5447
  /*
    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
5448
  thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
unknown's avatar
unknown committed
5449

5450 5451
  thread_count++;

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

unknown's avatar
unknown committed
5454 5455
  DBUG_VOID_RETURN;
}
5456 5457
#endif /* EMBEDDED_LIBRARY */

unknown's avatar
unknown committed
5458

unknown's avatar
unknown committed
5459 5460 5461 5462
#ifdef SIGNALS_DONT_BREAK_READ
inline void kill_broken_server()
{
  /* hack to get around signals ignored in syscalls for problem OS's */
5463
  if (unix_sock == INVALID_SOCKET ||
Michael Widenius's avatar
Michael Widenius committed
5464
      (!opt_disable_networking && base_ip_sock == INVALID_SOCKET))
unknown's avatar
unknown committed
5465 5466
  {
    select_thread_in_use = 0;
unknown's avatar
unknown committed
5467
    /* The following call will never return */
5468
    DBUG_PRINT("general", ("killing server because socket is closed"));
5469
    kill_server((void*) MYSQL_KILL_SIGNAL);
unknown's avatar
unknown committed
5470 5471 5472 5473 5474 5475
  }
}
#define MAYBE_BROKEN_SYSCALL kill_broken_server();
#else
#define MAYBE_BROKEN_SYSCALL
#endif
unknown's avatar
unknown committed
5476 5477 5478

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

5479
#ifndef EMBEDDED_LIBRARY
5480

5481
void handle_connections_sockets()
unknown's avatar
unknown committed
5482
{
5483
  my_socket UNINIT_VAR(sock), UNINIT_VAR(new_sock);
unknown's avatar
unknown committed
5484 5485
  uint error_count=0;
  THD *thd;
5486
  struct sockaddr_storage cAddr;
Michael Widenius's avatar
Michael Widenius committed
5487 5488 5489 5490
  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
5491
  st_vio *vio_tmp;
5492 5493
#ifdef HAVE_POLL
  int socket_count= 0;
Sergei Golubchik's avatar
Sergei Golubchik committed
5494 5495 5496 5497 5498
  struct pollfd fds[3]; // for ip_sock, unix_sock and extra_ip_sock
#define setup_fds(X)                    \
    fds[socket_count].fd= X;            \
    fds[socket_count].events= POLLIN;   \
    socket_count++
5499 5500
#else
  fd_set readFDs,clientFDs;
5501 5502
  uint max_used_connection= (uint)
    max(max(base_ip_sock, unix_sock), extra_ip_sock) + 1;
Sergei Golubchik's avatar
Sergei Golubchik committed
5503 5504
#define setup_fds(X)    FD_SET(X,&clientFDs)
  FD_ZERO(&clientFDs);
5505 5506
#endif

unknown's avatar
unknown committed
5507 5508
  DBUG_ENTER("handle_connections_sockets");

5509
  if (base_ip_sock != INVALID_SOCKET)
unknown's avatar
unknown committed
5510
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
5511 5512
    setup_fds(base_ip_sock);
    ip_flags = fcntl(base_ip_sock, F_GETFL, 0);
unknown's avatar
unknown committed
5513
  }
5514 5515
  if (extra_ip_sock != INVALID_SOCKET)
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
5516
    setup_fds(extra_ip_sock);
5517
    extra_ip_flags = fcntl(extra_ip_sock, F_GETFL, 0);
unknown's avatar
unknown committed
5518 5519
  }
#ifdef HAVE_SYS_UN_H
Sergei Golubchik's avatar
Sergei Golubchik committed
5520
  setup_fds(unix_sock);
unknown's avatar
unknown committed
5521 5522 5523 5524
  socket_flags=fcntl(unix_sock, F_GETFL, 0);
#endif

  DBUG_PRINT("general",("Waiting for connections."));
unknown's avatar
unknown committed
5525
  MAYBE_BROKEN_SYSCALL;
unknown's avatar
unknown committed
5526 5527
  while (!abort_loop)
  {
5528 5529
#ifdef HAVE_POLL
    retval= poll(fds, socket_count, -1);
unknown's avatar
unknown committed
5530
#else
5531 5532 5533 5534 5535 5536
    readFDs=clientFDs;

    retval= select((int) max_used_connection,&readFDs,0,0,0);
#endif

    if (retval < 0)
unknown's avatar
unknown committed
5537
    {
unknown's avatar
unknown committed
5538
      if (socket_errno != SOCKET_EINTR)
unknown's avatar
unknown committed
5539 5540
      {
	if (!select_errors++ && !abort_loop)	/* purecov: inspected */
unknown's avatar
unknown committed
5541
	  sql_print_error("mysqld: Got error %d from select",socket_errno); /* purecov: inspected */
unknown's avatar
unknown committed
5542
      }
unknown's avatar
unknown committed
5543
      MAYBE_BROKEN_SYSCALL
unknown's avatar
unknown committed
5544 5545
      continue;
    }
5546

unknown's avatar
unknown committed
5547
    if (abort_loop)
unknown's avatar
unknown committed
5548 5549
    {
      MAYBE_BROKEN_SYSCALL;
unknown's avatar
unknown committed
5550
      break;
unknown's avatar
unknown committed
5551
    }
unknown's avatar
unknown committed
5552

5553
    /* Is this a new connection request ? */
5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564
#ifdef HAVE_POLL
    for (int i= 0; i < socket_count; ++i) 
    {
      if (fds[i].revents & POLLIN)
      {
        sock= fds[i].fd;
        flags= fcntl(sock, F_GETFL, 0);
        break;
      }
    }
#else  // HAVE_POLL
Sergei Golubchik's avatar
Sergei Golubchik committed
5565
    if (FD_ISSET(base_ip_sock,&readFDs))
unknown's avatar
unknown committed
5566
    {
Sergei Golubchik's avatar
Sergei Golubchik committed
5567 5568
      sock=  base_ip_sock;
      flags= ip_flags;
unknown's avatar
unknown committed
5569 5570
    }
    else
Sergei Golubchik's avatar
Sergei Golubchik committed
5571
    if (FD_ISSET(extra_ip_sock,&readFDs))
unknown's avatar
unknown committed
5572
    {
Sergei Golubchik's avatar
Sergei Golubchik committed
5573 5574 5575 5576 5577 5578 5579
      sock=  extra_ip_sock;
      flags= extra_ip_flags;
    }
    else
    {
      sock = unix_sock;
      flags= socket_flags;
unknown's avatar
unknown committed
5580
    }
5581
#endif // HAVE_POLL
unknown's avatar
unknown committed
5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594

#if !defined(NO_FCNTL_NONBLOCK)
    if (!(test_flags & TEST_BLOCKING))
    {
#if defined(O_NONBLOCK)
      fcntl(sock, F_SETFL, flags | O_NONBLOCK);
#elif defined(O_NDELAY)
      fcntl(sock, F_SETFL, flags | O_NDELAY);
#endif
    }
#endif /* NO_FCNTL_NONBLOCK */
    for (uint retry=0; retry < MAX_ACCEPT_RETRY; retry++)
    {
5595 5596 5597
      size_socket length= sizeof(struct sockaddr_storage);
      new_sock= accept(sock, (struct sockaddr *)(&cAddr),
                       &length);
unknown's avatar
unknown committed
5598 5599
      if (new_sock != INVALID_SOCKET ||
	  (socket_errno != SOCKET_EINTR && socket_errno != SOCKET_EAGAIN))
unknown's avatar
unknown committed
5600
	break;
unknown's avatar
unknown committed
5601
      MAYBE_BROKEN_SYSCALL;
unknown's avatar
unknown committed
5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613
#if !defined(NO_FCNTL_NONBLOCK)
      if (!(test_flags & TEST_BLOCKING))
      {
	if (retry == MAX_ACCEPT_RETRY - 1)
	  fcntl(sock, F_SETFL, flags);		// Try without O_NONBLOCK
      }
#endif
    }
#if !defined(NO_FCNTL_NONBLOCK)
    if (!(test_flags & TEST_BLOCKING))
      fcntl(sock, F_SETFL, flags);
#endif
unknown's avatar
unknown committed
5614
    if (new_sock == INVALID_SOCKET)
unknown's avatar
unknown committed
5615 5616 5617
    {
      if ((error_count++ & 255) == 0)		// This can happen often
	sql_perror("Error in accept");
unknown's avatar
unknown committed
5618
      MAYBE_BROKEN_SYSCALL;
unknown's avatar
unknown committed
5619
      if (socket_errno == SOCKET_ENFILE || socket_errno == SOCKET_EMFILE)
unknown's avatar
unknown committed
5620 5621 5622 5623 5624 5625
	sleep(1);				// Give other threads some time
      continue;
    }

#ifdef HAVE_LIBWRAP
    {
5626
      if (sock == base_ip_sock || sock == extra_ip_sock)
unknown's avatar
unknown committed
5627 5628 5629 5630
      {
	struct request_info req;
	signal(SIGCHLD, SIG_DFL);
	request_init(&req, RQ_DAEMON, libwrapName, RQ_FILE, new_sock, NULL);
5631 5632
	my_fromhost(&req);
	if (!my_hosts_access(&req))
unknown's avatar
unknown committed
5633
	{
unknown's avatar
unknown committed
5634 5635 5636 5637 5638
	  /*
	    This may be stupid but refuse() includes an exit(0)
	    which we surely don't want...
	    clean_exit() - same stupid thing ...
	  */
5639
	  syslog(deny_severity, "refused connect from %s",
5640
		 my_eval_client(&req));
unknown's avatar
unknown committed
5641

unknown's avatar
unknown committed
5642 5643 5644 5645 5646 5647
	  /*
	    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
5648 5649 5650
	  if (req.sink)
	    ((void (*)(int))req.sink)(req.fd);

5651
	  (void) mysql_socket_shutdown(new_sock, SHUT_RDWR);
unknown's avatar
unknown committed
5652 5653 5654 5655 5656 5657 5658 5659 5660
	  (void) closesocket(new_sock);
	  continue;
	}
      }
    }
#endif /* HAVE_LIBWRAP */

    {
      size_socket dummyLen;
5661 5662 5663 5664
      struct sockaddr_storage dummy;
      dummyLen = sizeof(dummy);
      if (  getsockname(new_sock,(struct sockaddr *)&dummy, 
                  (SOCKET_SIZE_TYPE *)&dummyLen) < 0  )
unknown's avatar
unknown committed
5665 5666
      {
	sql_perror("Error on new connection socket");
5667
	(void) mysql_socket_shutdown(new_sock, SHUT_RDWR);
unknown's avatar
unknown committed
5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678
	(void) closesocket(new_sock);
	continue;
      }
    }

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

    if (!(thd= new THD))
    {
5679
      (void) mysql_socket_shutdown(new_sock, SHUT_RDWR);
Konstantin Osipov's avatar
Konstantin Osipov committed
5680
      (void) closesocket(new_sock);
unknown's avatar
unknown committed
5681 5682 5683
      continue;
    }
    if (!(vio_tmp=vio_new(new_sock,
5684
			  sock == unix_sock ? VIO_TYPE_SOCKET :
unknown's avatar
unknown committed
5685
			  VIO_TYPE_TCPIP,
5686
			  sock == unix_sock ? VIO_LOCALHOST: 0)) ||
unknown's avatar
unknown committed
5687 5688
	my_net_init(&thd->net,vio_tmp))
    {
5689 5690 5691 5692 5693 5694 5695
      /*
        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
5696 5697
      else
      {
5698
	(void) mysql_socket_shutdown(new_sock, SHUT_RDWR);
unknown's avatar
unknown committed
5699 5700 5701 5702 5703 5704
	(void) closesocket(new_sock);
      }
      delete thd;
      continue;
    }
    if (sock == unix_sock)
5705
      thd->security_ctx->host=(char*) my_localhost;
5706

5707 5708 5709
    if (sock == extra_ip_sock)
    {
      thd->extra_port= 1;
Sergei Golubchik's avatar
Sergei Golubchik committed
5710
      thd->scheduler= extra_thread_scheduler;
5711
    }
unknown's avatar
unknown committed
5712 5713
    create_new_thread(thd);
  }
5714 5715 5716
  DBUG_VOID_RETURN;
}

unknown's avatar
unknown committed
5717

5718 5719 5720 5721 5722
#ifdef _WIN32
pthread_handler_t handle_connections_sockets_thread(void *arg)
{
  my_thread_init();
  handle_connections_sockets();
5723
  decrement_handler_count();
5724
  return 0;
unknown's avatar
unknown committed
5725 5726
}

5727
pthread_handler_t handle_connections_namedpipes(void *arg)
unknown's avatar
unknown committed
5728 5729
{
  HANDLE hConnectedPipe;
5730
  OVERLAPPED connectOverlapped= {0};
unknown's avatar
unknown committed
5731 5732 5733
  THD *thd;
  my_thread_init();
  DBUG_ENTER("handle_connections_namedpipes");
5734 5735 5736 5737 5738 5739
  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
5740 5741 5742 5743
  DBUG_PRINT("general",("Waiting for named pipe connections."));
  while (!abort_loop)
  {
    /* wait for named pipe connection */
5744 5745 5746 5747 5748 5749 5750 5751 5752 5753
    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
5754 5755
    if (abort_loop)
      break;
unknown's avatar
unknown committed
5756
    if (!fConnected)
unknown's avatar
unknown committed
5757
      fConnected = GetLastError() == ERROR_PIPE_CONNECTED;
unknown's avatar
unknown committed
5758
    if (!fConnected)
unknown's avatar
unknown committed
5759
    {
unknown's avatar
Merge  
unknown committed
5760 5761
      CloseHandle(hPipe);
      if ((hPipe= CreateNamedPipe(pipe_name,
5762 5763
                                  PIPE_ACCESS_DUPLEX |
                                  FILE_FLAG_OVERLAPPED,
unknown's avatar
Merge  
unknown committed
5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774
                                  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
5775 5776 5777 5778 5779 5780 5781
      {
	sql_perror("Can't create new named pipe!");
	break;					// Abort
      }
    }
    hConnectedPipe = hPipe;
    /* create new pipe for new connection */
5782
    if ((hPipe = CreateNamedPipe(pipe_name,
5783 5784
                 PIPE_ACCESS_DUPLEX |
                 FILE_FLAG_OVERLAPPED,
unknown's avatar
unknown committed
5785 5786 5787 5788
				 PIPE_TYPE_BYTE |
				 PIPE_READMODE_BYTE |
				 PIPE_WAIT,
				 PIPE_UNLIMITED_INSTANCES,
5789 5790
				 (int) global_system_variables.net_buffer_length,
				 (int) global_system_variables.net_buffer_length,
unknown's avatar
unknown committed
5791 5792 5793 5794 5795 5796 5797 5798 5799
				 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
5800
    if (!(thd = new THD))
unknown's avatar
unknown committed
5801
    {
unknown's avatar
Merge  
unknown committed
5802 5803
      DisconnectNamedPipe(hConnectedPipe);
      CloseHandle(hConnectedPipe);
unknown's avatar
unknown committed
5804 5805
      continue;
    }
5806
    if (!(thd->net.vio= vio_new_win32pipe(hConnectedPipe)) ||
unknown's avatar
unknown committed
5807 5808
	my_net_init(&thd->net, thd->net.vio))
    {
5809
      close_connection(thd, ER_OUT_OF_RESOURCES);
unknown's avatar
unknown committed
5810 5811 5812
      delete thd;
      continue;
    }
5813 5814
    /* Host is unknown */
    thd->security_ctx->host= my_strdup(my_localhost, MYF(0));
unknown's avatar
unknown committed
5815 5816
    create_new_thread(thd);
  }
5817
  CloseHandle(connectOverlapped.hEvent);
5818
  DBUG_LEAVE;
5819
  decrement_handler_count();
5820
  return 0;
unknown's avatar
unknown committed
5821
}
Vladislav Vaintroub's avatar
Vladislav Vaintroub committed
5822
#endif /* _WIN32 */
unknown's avatar
unknown committed
5823

5824

unknown's avatar
unknown committed
5825
#ifdef HAVE_SMEM
5826

unknown's avatar
unknown committed
5827 5828
/**
  Thread of shared memory's service.
5829

unknown's avatar
unknown committed
5830 5831
  @param arg                              Arguments of thread
*/
5832
pthread_handler_t handle_connections_shared_memory(void *arg)
5833
{
5834 5835
  /* file-mapping object, use for create shared memory */
  HANDLE handle_connect_file_map= 0;
5836
  char  *handle_connect_map= 0;                 // pointer on shared memory
5837 5838 5839
  HANDLE event_connect_answer= 0;
  ulong smem_buffer_length= shared_memory_buffer_length + 4;
  ulong connect_number= 1;
5840
  char *tmp= NULL;
5841 5842
  char *suffix_pos;
  char connect_number_char[22], *p;
5843
  const char *errmsg= 0;
5844
  SECURITY_ATTRIBUTES *sa_event= 0, *sa_mapping= 0;
5845 5846 5847 5848
  my_thread_init();
  DBUG_ENTER("handle_connections_shared_memorys");
  DBUG_PRINT("general",("Waiting for allocated shared memory."));

5849 5850 5851 5852 5853 5854
  /*
     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;

5855 5856 5857 5858 5859 5860 5861 5862
  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;

5863 5864 5865 5866 5867 5868 5869
  /*
    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)
  */
5870
  suffix_pos= strxmov(tmp,shared_memory_base_name,"_",NullS);
5871
  strmov(suffix_pos, "CONNECT_REQUEST");
5872 5873
  if ((smem_event_connect_request= CreateEvent(sa_event,
                                               FALSE, FALSE, tmp)) == 0)
5874
  {
5875
    errmsg= "Could not create request event";
5876 5877
    goto error;
  }
5878
  strmov(suffix_pos, "CONNECT_ANSWER");
5879
  if ((event_connect_answer= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
5880
  {
5881
    errmsg="Could not create answer event";
5882 5883
    goto error;
  }
5884
  strmov(suffix_pos, "CONNECT_DATA");
5885 5886 5887
  if ((handle_connect_file_map=
       CreateFileMapping(INVALID_HANDLE_VALUE, sa_mapping,
                         PAGE_READWRITE, 0, sizeof(connect_number), tmp)) == 0)
5888
  {
5889
    errmsg= "Could not create file mapping";
5890 5891
    goto error;
  }
5892 5893 5894
  if ((handle_connect_map= (char *)MapViewOfFile(handle_connect_file_map,
						  FILE_MAP_WRITE,0,0,
						  sizeof(DWORD))) == 0)
5895
  {
5896
    errmsg= "Could not create shared memory service";
5897 5898 5899 5900 5901
    goto error;
  }

  while (!abort_loop)
  {
5902
    /* Wait a request from client */
5903
    WaitForSingleObject(smem_event_connect_request,INFINITE);
5904

unknown's avatar
unknown committed
5905 5906 5907
    /*
       it can be after shutdown command
    */
unknown's avatar
Merge  
unknown committed
5908
    if (abort_loop)
unknown's avatar
unknown committed
5909
      goto error;
5910

5911 5912 5913 5914 5915 5916
    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
5917
    HANDLE event_conn_closed= 0;
5918
    THD *thd= 0;
5919

5920
    p= int10_to_str(connect_number, connect_number_char, 10);
5921 5922 5923 5924 5925 5926 5927 5928 5929 5930
    /*
      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);
5931
    strmov(suffix_pos, "DATA");
5932 5933 5934
    if ((handle_client_file_map=
         CreateFileMapping(INVALID_HANDLE_VALUE, sa_mapping,
                           PAGE_READWRITE, 0, smem_buffer_length, tmp)) == 0)
5935
    {
5936
      errmsg= "Could not create file mapping";
5937 5938
      goto errorconn;
    }
5939 5940 5941
    if ((handle_client_map= (char*)MapViewOfFile(handle_client_file_map,
						  FILE_MAP_WRITE,0,0,
						  smem_buffer_length)) == 0)
5942
    {
5943
      errmsg= "Could not create memory map";
5944 5945 5946
      goto errorconn;
    }
    strmov(suffix_pos, "CLIENT_WROTE");
5947
    if ((event_client_wrote= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
5948
    {
5949
      errmsg= "Could not create client write event";
5950 5951 5952
      goto errorconn;
    }
    strmov(suffix_pos, "CLIENT_READ");
5953
    if ((event_client_read= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
5954
    {
5955
      errmsg= "Could not create client read event";
5956 5957 5958
      goto errorconn;
    }
    strmov(suffix_pos, "SERVER_READ");
5959
    if ((event_server_read= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
5960
    {
5961
      errmsg= "Could not create server read event";
5962 5963 5964
      goto errorconn;
    }
    strmov(suffix_pos, "SERVER_WROTE");
5965 5966
    if ((event_server_wrote= CreateEvent(sa_event,
                                         FALSE, FALSE, tmp)) == 0)
5967
    {
5968
      errmsg= "Could not create server write event";
5969 5970
      goto errorconn;
    }
unknown's avatar
unknown committed
5971
    strmov(suffix_pos, "CONNECTION_CLOSED");
5972 5973
    if ((event_conn_closed= CreateEvent(sa_event,
                                        TRUE, FALSE, tmp)) == 0)
unknown's avatar
unknown committed
5974 5975 5976 5977
    {
      errmsg= "Could not create closed connection event";
      goto errorconn;
    }
5978
    if (abort_loop)
5979
      goto errorconn;
5980 5981 5982
    if (!(thd= new THD))
      goto errorconn;
    /* Send number of connection to client */
5983
    int4store(handle_connect_map, connect_number);
5984
    if (!SetEvent(event_connect_answer))
5985
    {
5986
      errmsg= "Could not send answer event";
5987 5988
      goto errorconn;
    }
5989
    /* Set event that client should receive data */
5990 5991
    if (!SetEvent(event_client_read))
    {
5992
      errmsg= "Could not set client to read mode";
5993 5994
      goto errorconn;
    }
5995
    if (!(thd->net.vio= vio_new_win32shared_memory(handle_client_file_map,
unknown's avatar
unknown committed
5996 5997 5998 5999 6000
                                                   handle_client_map,
                                                   event_client_wrote,
                                                   event_client_read,
                                                   event_server_wrote,
                                                   event_server_read,
unknown's avatar
unknown committed
6001
                                                   event_conn_closed)) ||
unknown's avatar
unknown committed
6002
                        my_net_init(&thd->net, thd->net.vio))
6003
    {
6004
      close_connection(thd, ER_OUT_OF_RESOURCES);
6005 6006
      errmsg= 0;
      goto errorconn;
6007
    }
6008
    thd->security_ctx->host= my_strdup(my_localhost, MYF(0)); /* Host is unknown */
6009
    create_new_thread(thd);
6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021
    connect_number++;
    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);
    }
6022
    if (handle_client_file_map)
unknown's avatar
unknown committed
6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035
      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);
6036
    delete thd;
6037
  }
6038 6039

  /* End shared memory handling */
6040
error:
6041
  if (tmp)
6042
    my_free(tmp);
6043

6044 6045 6046 6047 6048 6049
  if (errmsg)
  {
    char buff[180];
    strxmov(buff, "Can't create shared memory service: ", errmsg, ".", NullS);
    sql_perror(buff);
  }
6050 6051
  my_security_attr_free(sa_event);
  my_security_attr_free(sa_mapping);
6052 6053 6054
  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);
6055
  if (smem_event_connect_request) CloseHandle(smem_event_connect_request);
6056
  DBUG_LEAVE;
6057
  decrement_handler_count();
6058
  return 0;
6059 6060
}
#endif /* HAVE_SMEM */
6061
#endif /* EMBEDDED_LIBRARY */
unknown's avatar
unknown committed
6062

6063 6064 6065

/****************************************************************************
  Handle start options
unknown's avatar
unknown committed
6066 6067
******************************************************************************/

6068 6069 6070 6071 6072
/**
  System variables are automatically command-line options (few
  exceptions are documented in sys_var.h), so don't need
  to be listed here.
*/
6073

Marc Alff's avatar
Marc Alff committed
6074
struct my_option my_long_options[]=
6075
{
unknown's avatar
unknown committed
6076
  {"help", '?', "Display this help and exit.", 
6077
   &opt_help, &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
unknown's avatar
unknown committed
6078
   0, 0},
6079
  {"allow-suspicious-udfs", 0,
unknown's avatar
unknown committed
6080 6081
   "Allows use of UDFs consisting of only one symbol xxx() "
   "without corresponding xxx_init() or xxx_deinit(). That also means "
6082 6083
   "that one can load any function from any library, for example exit() "
   "from libc.so",
6084
   &opt_allow_suspicious_udfs, &opt_allow_suspicious_udfs,
6085
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
6086 6087
  {"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
6088
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
6089 6090 6091 6092
  /*
    Because Sys_var_bit does not support command-line options, we need to
    explicitely add one for --autocommit
  */
6093 6094 6095
  {"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},
unknown's avatar
unknown committed
6096
  {"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
6097
   &my_bind_addr_str, &my_bind_addr_str, 0, GET_STR,
unknown's avatar
unknown committed
6098
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6099
  {"binlog-do-db", OPT_BINLOG_DO_DB,
6100 6101
   "Tells the master it should log updates for the specified database, "
   "and exclude all others not explicitly mentioned.",
6102
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
6103
  {"binlog-ignore-db", OPT_BINLOG_IGNORE_DB,
Staale Smedseng's avatar
Staale Smedseng committed
6104
   "Tells the master that updates to the given database should not be logged to the binary log.",
6105
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6106
  {"binlog-row-event-max-size", 0,
6107 6108 6109
   "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.",
6110 6111
   &opt_binlog_rows_event_max_size, &opt_binlog_rows_event_max_size,
   0, GET_ULONG, REQUIRED_ARG,
6112 6113 6114 6115
   /* def_value */ 1024, /* min_value */  256, /* max_value */ ULONG_MAX, 
   /* sub_size */     0, /* block_size */ 256, 
   /* app_type */ 0
  },
6116
#ifndef DISABLE_GRANT_OPTIONS
6117
  {"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts.", 0, 0, 0,
6118
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
6119
#endif
6120
  {"character-set-client-handshake", 0,
unknown's avatar
unknown committed
6121
   "Don't ignore client side character set value sent during handshake.",
6122 6123
   &opt_character_set_client_handshake,
   &opt_character_set_client_handshake,
6124
    0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
6125
  {"character-set-filesystem", 0,
unknown's avatar
unknown committed
6126
   "Set the filesystem character set.",
6127 6128
   &character_set_filesystem_name,
   &character_set_filesystem_name,
unknown's avatar
unknown committed
6129
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
unknown's avatar
unknown committed
6130
  {"character-set-server", 'C', "Set the default character set.",
6131
   &default_character_set_name, &default_character_set_name,
unknown's avatar
unknown committed
6132
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
unknown's avatar
unknown committed
6133
  {"chroot", 'r', "Chroot mysqld daemon during startup.",
6134
   &mysqld_chroot, &mysqld_chroot, 0, GET_STR, REQUIRED_ARG,
unknown's avatar
unknown committed
6135
   0, 0, 0, 0, 0, 0},
6136
  {"collation-server", 0, "Set the default collation.",
6137
   &default_collation_name, &default_collation_name,
unknown's avatar
unknown committed
6138
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
Staale Smedseng's avatar
Staale Smedseng committed
6139
  {"console", OPT_CONSOLE, "Write error output on screen; don't remove the console window on windows.",
6140
   &opt_console, &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0,
6141
   0, 0, 0},
6142
  {"core-file", OPT_WANT_CORE, "Write core on errors.", 0, 0, 0, GET_NO_ARG,
6143
   NO_ARG, 0, 0, 0, 0, 0, 0},
6144 6145 6146
  /* 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. */
Michael Widenius's avatar
Michael Widenius committed
6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194
#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!",
6195
   &my_disable_sync, &my_disable_sync, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
Michael Widenius's avatar
Michael Widenius committed
6196 6197 6198 6199 6200 6201 6202
#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 */
6203
  {"default-storage-engine", 0, "The default storage engine for new tables",
6204
   &default_storage_engine, 0, 0, GET_STR, REQUIRED_ARG,
6205
   0, 0, 0, 0, 0, 0 },
6206
  {"default-time-zone", 0, "Set the default time zone.",
6207
   &default_tz_name, &default_tz_name,
6208
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
Michael Widenius's avatar
Michael Widenius committed
6209 6210 6211 6212 6213 6214 6215 6216
#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
6217
#ifdef HAVE_OPENSSL
6218
  {"des-key-file", 0,
unknown's avatar
unknown committed
6219
   "Load keys for des_encrypt() and des_encrypt from given file.",
6220
   &des_key_file, &des_key_file, 0, GET_STR, REQUIRED_ARG,
unknown's avatar
unknown committed
6221 6222
   0, 0, 0, 0, 0, 0},
#endif /* HAVE_OPENSSL */
Michael Widenius's avatar
Michael Widenius committed
6223
#ifdef HAVE_STACKTRACE
Sergei Golubchik's avatar
Sergei Golubchik committed
6224
  {"stack-trace", 0 , "Print a symbolic stack trace on failure",
Michael Widenius's avatar
Michael Widenius committed
6225 6226
   &opt_stack_trace, &opt_stack_trace, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
#endif /* HAVE_STACKTRACE */
6227 6228 6229 6230
  {"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
6231
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
6232 6233
  /* We must always support the next option to make scripts like mysqltest
     easier to do */
6234
  {"gdb", 0,
Sergei Golubchik's avatar
Sergei Golubchik committed
6235 6236 6237
   "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},
6238
#ifdef HAVE_LARGE_PAGE_OPTION
6239
  {"super-large-pages", 0, "Enable support for super large pages.",
6240
   &opt_super_large_pages, &opt_super_large_pages, 0,
6241
   GET_BOOL, OPT_ARG, 0, 0, 1, 0, 1, 0},
unknown's avatar
Merge  
unknown committed
6242
#endif
6243
  {"language", 'L',
6244 6245
   "Client error messages in given language. May be given as a full path. "
   "Deprecated. Use --lc-messages-dir instead.",
6246
   0, 0, 0,
6247
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6248
  {"lc-messages", 0,
6249
   "Set the language used for the error messages.",
6250
   &lc_messages, &lc_messages, 0, GET_STR, REQUIRED_ARG,
6251
   0, 0, 0, 0, 0, 0 },
6252
  {"lc-time-names", 0,
6253
   "Set the language used for the month names and the days of the week.",
6254
   &lc_time_names_name, &lc_time_names_name,
6255
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
6256
  {"log", 'l', "Log connections and queries to file (deprecated option, use "
6257 6258
   "--general-log/--general-log-file instead).", &opt_logname, &opt_logname,
   0, GET_STR_ALLOC, OPT_ARG, 0, 0, 0, 0, 0, 0},
6259 6260 6261
  {"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
6262
   "for specifying log files. Sets names for --log-bin, --log-bin-index, "
6263
   "--relay-log, --relay-log-index, --general-log-file, "
Sergei Golubchik's avatar
Sergei Golubchik committed
6264
   "--log-slow-query-log-file, --log-error-file, and --pid-file",
6265 6266
   &opt_log_basename, &opt_log_basename, 0, GET_STR, REQUIRED_ARG,
   0, 0, 0, 0, 0, 0},
6267
  {"log-bin", OPT_BIN_LOG,
6268 6269
   "Log update queries in binary format. Optional argument should be name for "
   "binary log. If not given "
6270
   "'datadir'/'log-basename'-bin or 'datadir'/mysql-bin will be used (the later if "
Sergei Golubchik's avatar
Sergei Golubchik committed
6271
   "--log-basename is not specified). We strongly recommend to use either "
6272
   "--log-basename or specify a filename to ensure that replication doesn't "
6273
   "stop if the real hostname of the computer changes.",
6274
   &opt_bin_logname, &opt_bin_logname, 0, GET_STR,
unknown's avatar
unknown committed
6275
   OPT_ARG, 0, 0, 0, 0, 0, 0},
6276
  {"log-bin-index", 0,
6277
   "File that holds the names for last binary log files.",
6278
   &opt_binlog_index_name, &opt_binlog_index_name, 0, GET_STR,
6279
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6280
  {"log-isam", OPT_ISAM_LOG, "Log all MyISAM changes to file.",
6281
   &myisam_log_filename, &myisam_log_filename, 0, GET_STR,
6282
   OPT_ARG, 0, 0, 0, 0, 0, 0},
6283
  {"log-short-format", 0,
unknown's avatar
unknown committed
6284
   "Don't log extra information to update and slow-query logs.",
6285
   &opt_short_log_format, &opt_short_log_format,
unknown's avatar
unknown committed
6286
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
6287
  {"log-slow-admin-statements", 0,
6288 6289
   "Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements to "
   "the slow log if it is open.", &opt_log_slow_admin_statements,
6290
   &opt_log_slow_admin_statements, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
6291
 {"log-slow-slave-statements", 0,
6292
  "Log slow statements executed by slave thread to the slow log if it is open.",
6293
  &opt_log_slow_slave_statements, &opt_log_slow_slave_statements,
6294
  0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
Konstantin Osipov's avatar
Konstantin Osipov committed
6295
  {"log-slow-queries", OPT_SLOW_QUERY_LOG,
Sergei Golubchik's avatar
Sergei Golubchik committed
6296 6297
   "Enable logging of slow queries (longer than --long-query-time) to log file "
   "or table. Optional argument is a file name for the slow log. If not given, "
6298
   "'log-basename'-slow.log will be used. Use --log-output=TABLE if you want "
6299
   "to have the log in the table mysql.slow_log. "
Konstantin Osipov's avatar
Konstantin Osipov committed
6300
   "Deprecated option, use --slow-query-log/--slow-query-log-file instead.",
6301
   &opt_slow_logname, &opt_slow_logname, 0, GET_STR_ALLOC, OPT_ARG,
unknown's avatar
unknown committed
6302
   0, 0, 0, 0, 0, 0},
6303
  {"log-tc", 0,
unknown's avatar
Merge  
unknown committed
6304
   "Path to transaction coordinator log (used for transactions that affect "
Staale Smedseng's avatar
Staale Smedseng committed
6305
   "more than one storage engine, when binary log is disabled).",
6306
   &opt_tc_log_file, &opt_tc_log_file, 0, GET_STR,
unknown's avatar
Merge  
unknown committed
6307
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6308
#ifdef HAVE_MMAP
6309
  {"log-tc-size", 0, "Size of transaction coordinator log.",
6310
   &opt_tc_log_size, &opt_tc_log_size, 0, GET_ULONG,
unknown's avatar
unknown committed
6311
   REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, (ulonglong) ULONG_MAX, 0,
6312
   TC_LOG_PAGE_SIZE, 0},
6313
#endif
6314
  {"master-info-file", 0,
6315
   "The location and name of the file that remembers the master and where "
6316
   "the I/O replication thread is in the master's binlogs. Defaults to "
Sergei Golubchik's avatar
Sergei Golubchik committed
6317
   "master.info",
6318
   &master_info_file, &master_info_file, 0, GET_STR,
unknown's avatar
unknown committed
6319
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6320
  {"master-retry-count", 0,
6321
   "The number of tries the slave will make to connect to the master before giving up.",
6322
   &master_retry_count, &master_retry_count, 0, GET_ULONG,
6323
   REQUIRED_ARG, 3600*24, 0, 0, 0, 0, 0},
unknown's avatar
SCRUM  
unknown committed
6324
#ifdef HAVE_REPLICATION
6325
  {"init-rpl-role", 0, "Set the replication role.",
6326
   &rpl_status, &rpl_status, &rpl_role_typelib,
6327
   GET_ENUM, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
SCRUM  
unknown committed
6328
#endif /* HAVE_REPLICATION */
6329
  {"memlock", 0, "Lock mysqld in memory.", &locked_in_memory,
6330
   &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
6331
  {"one-thread", OPT_ONE_THREAD,
Staale Smedseng's avatar
Staale Smedseng committed
6332 6333
   "(Deprecated): Only use one thread (for debugging under Linux). Use "
   "thread-handling=no-threads instead.",
unknown's avatar
unknown committed
6334
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
6335
  {"old-style-user-limits", 0,
Staale Smedseng's avatar
Staale Smedseng committed
6336 6337
   "Enable old-style user limits (before 5.0.3, user resources were counted "
   "per each user+host vs. per account).",
6338
   &opt_old_style_user_limits, &opt_old_style_user_limits,
unknown's avatar
Merge  
unknown committed
6339
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
6340
  {"port-open-timeout", 0,
6341
   "Maximum time in seconds to wait for the port to become free. "
6342 6343
   "(Default: No wait).", &mysqld_port_timeout, &mysqld_port_timeout, 0,
   GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6344
  {"replicate-do-db", OPT_REPLICATE_DO_DB,
6345 6346 6347 6348 6349 6350 6351
   "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.%.",
6352 6353
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
  {"replicate-do-table", OPT_REPLICATE_DO_TABLE,
6354 6355 6356 6357
   "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 "
   "to replicate-do-db.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6358
  {"replicate-ignore-db", OPT_REPLICATE_IGNORE_DB,
6359 6360 6361 6362 6363 6364
   "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-"
   "table=db_name.%. ", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6365
  {"replicate-ignore-table", OPT_REPLICATE_IGNORE_TABLE,
6366 6367 6368
   "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 "
6369
   "replicate-ignore-db.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6370
  {"replicate-rewrite-db", OPT_REPLICATE_REWRITE_DB,
6371 6372
   "Updates to a database with a different name than the original. Example: "
   "replicate-rewrite-db=master_db_name->slave_db_name.",
6373
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
6374
#ifdef HAVE_REPLICATION
6375
  {"replicate-same-server-id", 0,
6376 6377 6378 6379
   "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,
6380
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
6381
#endif
unknown's avatar
unknown committed
6382
  {"replicate-wild-do-table", OPT_REPLICATE_WILD_DO_TABLE,
6383 6384 6385 6386 6387 6388
   "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.",
unknown's avatar
unknown committed
6389 6390
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
  {"replicate-wild-ignore-table", OPT_REPLICATE_WILD_IGNORE_TABLE,
6391 6392 6393 6394 6395 6396
   "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.",
unknown's avatar
unknown committed
6397
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6398
  {"safe-mode", OPT_SAFE, "Skip some optimize stages (for testing). Deprecated.",
6399
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
6400
  {"safe-user-create", 0,
6401
   "Don't allow new user creation by the user who has no write privileges to the mysql.user table.",
6402
   &opt_safe_user_create, &opt_safe_user_create, 0, GET_BOOL,
6403
   NO_ARG, 0, 0, 0, 0, 0, 0},
6404
  {"show-slave-auth-info", 0,
Staale Smedseng's avatar
Staale Smedseng committed
6405
   "Show user and password in SHOW SLAVE HOSTS on this master.",
6406
   &opt_show_slave_auth_info, &opt_show_slave_auth_info, 0,
6407
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
6408 6409 6410
  {"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},
6411
#ifndef DISABLE_GRANT_OPTIONS
6412
  {"skip-grant-tables", 0,
Staale Smedseng's avatar
Staale Smedseng committed
6413
   "Start without grant tables. This gives all users FULL ACCESS to all tables.",
6414
   &opt_noacl, &opt_noacl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
6415
   0},
6416
#endif
unknown's avatar
unknown committed
6417 6418
  {"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},
6419
  {"skip-slave-start", 0,
6420 6421
   "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},
6422
  {"skip-thread-priority", OPT_SKIP_PRIOR,
Konstantin Osipov's avatar
Konstantin Osipov committed
6423 6424 6425
   "Don't give threads different priorities. This option is deprecated "
   "because it has no effect; the implied behavior is already the default.",
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
6426 6427 6428 6429 6430 6431 6432
#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
6433
#ifdef HAVE_OPENSSL
6434 6435
  {"ssl", 0,
   "Enable SSL for connection (automatically enabled with other flags).",
6436
   &opt_use_ssl, &opt_use_ssl, 0, GET_BOOL, OPT_ARG, 0, 0, 0,
6437
   0, 0, 0},
6438
#endif
unknown's avatar
unknown committed
6439
#ifdef __WIN__
6440
  {"standalone", 0,
unknown's avatar
unknown committed
6441 6442 6443 6444
  "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.",
6445
   &my_use_symdir, &my_use_symdir, 0, GET_BOOL, NO_ARG,
6446 6447 6448 6449
   /*
     The system call realpath() produces warnings under valgrind and
     purify. These are not suppressed: instead we disable symlinks
     option if compiled with valgrind support.
6450 6451
     Also disable by default on Windows, due to high overhead for checking .sym 
     files.
6452
   */
6453
   IF_VALGRIND(0,IF_WIN(0,1)), 0, 0, 0, 0, 0},
6454
  {"sysdate-is-now", 0,
6455 6456 6457 6458
   "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
6459
   0, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
6460
  {"tc-heuristic-recover", 0,
6461
   "Decision to use in heuristic recover process. Possible values are COMMIT "
6462
   "or ROLLBACK.", &tc_heuristic_recover, &tc_heuristic_recover,
6463 6464
   &tc_heuristic_recover_typelib, GET_ENUM, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
  {"temp-pool", 0,
6465
#if (ENABLE_TEMP_POOL)
6466 6467
   "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.",
6468 6469 6470
#else
   "This option is ignored on this OS.",
#endif
6471
   &use_temp_pool, &use_temp_pool, 0, GET_BOOL, NO_ARG, 1,
unknown's avatar
unknown committed
6472
   0, 0, 0, 0, 0},
6473 6474
  {"transaction-isolation", 0,
   "Default transaction isolation level.",
6475 6476
   &global_system_variables.tx_isolation,
   &global_system_variables.tx_isolation, &tx_isolation_typelib,
6477
   GET_ENUM, REQUIRED_ARG, ISO_REPEATABLE_READ, 0, 0, 0, 0, 0},
6478
  {"user", 'u', "Run mysqld daemon as user.", 0, 0, 0, GET_STR, REQUIRED_ARG,
unknown's avatar
unknown committed
6479
   0, 0, 0, 0, 0, 0},
Staale Smedseng's avatar
Staale Smedseng committed
6480
  {"verbose", 'v', "Used with --help option for detailed help.",
6481
   &opt_verbose, &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
6482
  {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
6483
   NO_ARG, 0, 0, 0, 0, 0, 0},
6484
  {"plugin-load", 0,
6485 6486 6487
   "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.",
6488
   &opt_plugin_load, &opt_plugin_load, 0,
unknown's avatar
unknown committed
6489
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6490
  {"table_cache", 0, "Deprecated; use --table-open-cache instead.",
6491
   &table_cache_size, &table_cache_size, 0, GET_ULONG,
6492
   REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
6493
  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
6494
};
unknown's avatar
unknown committed
6495

6496

6497
static int show_queries(THD *thd, SHOW_VAR *var, char *buff)
6498
{
6499
  var->type= SHOW_LONGLONG;
6500 6501 6502 6503
  var->value= (char *)&thd->query_id;
  return 0;
}

6504

6505
static int show_net_compression(THD *thd, SHOW_VAR *var, char *buff)
6506
{
6507
  var->type= SHOW_MY_BOOL;
6508 6509 6510 6511
  var->value= (char *)&thd->net.compress;
  return 0;
}

6512
static int show_starttime(THD *thd, SHOW_VAR *var, char *buff)
6513
{
6514
  var->type= SHOW_LONG;
6515
  var->value= buff;
unknown's avatar
unknown committed
6516
  *((long *)buff)= (long) (thd->query_start() - server_start_time);
6517 6518 6519
  return 0;
}

6520
#ifdef ENABLED_PROFILING
6521 6522 6523 6524 6525 6526 6527
static int show_flushstatustime(THD *thd, SHOW_VAR *var, char *buff)
{
  var->type= SHOW_LONG;
  var->value= buff;
  *((long *)buff)= (long) (thd->query_start() - flush_status_time);
  return 0;
}
6528
#endif
6529

6530
#ifdef HAVE_REPLICATION
6531
static int show_rpl_status(THD *thd, SHOW_VAR *var, char *buff)
6532
{
6533
  var->type= SHOW_CHAR;
6534 6535 6536 6537
  var->value= const_cast<char*>(rpl_status_type[(int)rpl_status]);
  return 0;
}

6538
static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff)
6539
{
6540
  var->type= SHOW_MY_BOOL;
Marc Alff's avatar
Marc Alff committed
6541
  mysql_mutex_lock(&LOCK_active_mi);
6542
  var->value= buff;
6543 6544
  *((my_bool *)buff)= (my_bool) (active_mi && 
                                 active_mi->slave_running == MYSQL_SLAVE_RUN_CONNECT &&
6545
                                 active_mi->rli.slave_running);
Marc Alff's avatar
Marc Alff committed
6546
  mysql_mutex_unlock(&LOCK_active_mi);
6547 6548 6549
  return 0;
}

6550
static int show_slave_retried_trans(THD *thd, SHOW_VAR *var, char *buff)
6551 6552 6553 6554 6555
{
  /*
    TODO: with multimaster, have one such counter per line in
    SHOW SLAVE STATUS, and have the sum over all lines here.
  */
Marc Alff's avatar
Marc Alff committed
6556
  mysql_mutex_lock(&LOCK_active_mi);
6557 6558
  if (active_mi)
  {
6559
    var->type= SHOW_LONG;
6560
    var->value= buff;
Marc Alff's avatar
Marc Alff committed
6561
    mysql_mutex_lock(&active_mi->rli.data_lock);
6562
    *((long *)buff)= (long)active_mi->rli.retried_trans;
Marc Alff's avatar
Marc Alff committed
6563
    mysql_mutex_unlock(&active_mi->rli.data_lock);
6564 6565
  }
  else
6566
    var->type= SHOW_UNDEF;
Marc Alff's avatar
Marc Alff committed
6567
  mysql_mutex_unlock(&LOCK_active_mi);
6568 6569
  return 0;
}
Andrei Elkin's avatar
Andrei Elkin committed
6570 6571 6572

static int show_slave_received_heartbeats(THD *thd, SHOW_VAR *var, char *buff)
{
Marc Alff's avatar
Marc Alff committed
6573
  mysql_mutex_lock(&LOCK_active_mi);
Andrei Elkin's avatar
Andrei Elkin committed
6574 6575 6576 6577
  if (active_mi)
  {
    var->type= SHOW_LONGLONG;
    var->value= buff;
Marc Alff's avatar
Marc Alff committed
6578
    mysql_mutex_lock(&active_mi->rli.data_lock);
Andrei Elkin's avatar
Andrei Elkin committed
6579
    *((longlong *)buff)= active_mi->received_heartbeats;
Marc Alff's avatar
Marc Alff committed
6580
    mysql_mutex_unlock(&active_mi->rli.data_lock);
Andrei Elkin's avatar
Andrei Elkin committed
6581 6582 6583
  }
  else
    var->type= SHOW_UNDEF;
Marc Alff's avatar
Marc Alff committed
6584
  mysql_mutex_unlock(&LOCK_active_mi);
Andrei Elkin's avatar
Andrei Elkin committed
6585 6586 6587 6588 6589
  return 0;
}

static int show_heartbeat_period(THD *thd, SHOW_VAR *var, char *buff)
{
Marc Alff's avatar
Marc Alff committed
6590
  mysql_mutex_lock(&LOCK_active_mi);
Andrei Elkin's avatar
Andrei Elkin committed
6591 6592 6593 6594
  if (active_mi)
  {
    var->type= SHOW_CHAR;
    var->value= buff;
6595
    sprintf(buff, "%.3f", active_mi->heartbeat_period);
Andrei Elkin's avatar
Andrei Elkin committed
6596 6597 6598
  }
  else
    var->type= SHOW_UNDEF;
Marc Alff's avatar
Marc Alff committed
6599
  mysql_mutex_unlock(&LOCK_active_mi);
Andrei Elkin's avatar
Andrei Elkin committed
6600 6601 6602 6603
  return 0;
}


6604 6605
#endif /* HAVE_REPLICATION */

6606
static int show_open_tables(THD *thd, SHOW_VAR *var, char *buff)
6607
{
6608
  var->type= SHOW_LONG;
6609 6610 6611 6612 6613
  var->value= buff;
  *((long *)buff)= (long)cached_open_tables();
  return 0;
}

unknown's avatar
unknown committed
6614 6615 6616 6617
static int show_prepared_stmt_count(THD *thd, SHOW_VAR *var, char *buff)
{
  var->type= SHOW_LONG;
  var->value= buff;
Marc Alff's avatar
Marc Alff committed
6618
  mysql_mutex_lock(&LOCK_prepared_stmt_count);
unknown's avatar
unknown committed
6619
  *((long *)buff)= (long)prepared_stmt_count;
Marc Alff's avatar
Marc Alff committed
6620
  mysql_mutex_unlock(&LOCK_prepared_stmt_count);
unknown's avatar
unknown committed
6621 6622 6623
  return 0;
}

6624
static int show_table_definitions(THD *thd, SHOW_VAR *var, char *buff)
6625
{
6626
  var->type= SHOW_LONG;
6627 6628 6629 6630 6631
  var->value= buff;
  *((long *)buff)= (long)cached_table_definitions();
  return 0;
}

Konstantin Osipov's avatar
Konstantin Osipov committed
6632
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
6633
/* Functions relying on CTX */
6634
static int show_ssl_ctx_sess_accept(THD *thd, SHOW_VAR *var, char *buff)
6635
{
6636
  var->type= SHOW_LONG;
6637 6638 6639 6640 6641 6642
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_accept(ssl_acceptor_fd->ssl_context));
  return 0;
}

6643
static int show_ssl_ctx_sess_accept_good(THD *thd, SHOW_VAR *var, char *buff)
6644
{
6645
  var->type= SHOW_LONG;
6646 6647 6648 6649 6650 6651
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_accept_good(ssl_acceptor_fd->ssl_context));
  return 0;
}

6652
static int show_ssl_ctx_sess_connect_good(THD *thd, SHOW_VAR *var, char *buff)
6653
{
6654
  var->type= SHOW_LONG;
6655 6656 6657 6658 6659 6660
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_connect_good(ssl_acceptor_fd->ssl_context));
  return 0;
}

6661
static int show_ssl_ctx_sess_accept_renegotiate(THD *thd, SHOW_VAR *var, char *buff)
6662
{
6663
  var->type= SHOW_LONG;
6664 6665 6666 6667 6668 6669
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context));
  return 0;
}

6670
static int show_ssl_ctx_sess_connect_renegotiate(THD *thd, SHOW_VAR *var, char *buff)
6671
{
6672
  var->type= SHOW_LONG;
6673 6674 6675 6676 6677 6678
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_connect_renegotiate(ssl_acceptor_fd->ssl_context));
  return 0;
}

6679
static int show_ssl_ctx_sess_cb_hits(THD *thd, SHOW_VAR *var, char *buff)
6680
{
6681
  var->type= SHOW_LONG;
6682 6683 6684 6685 6686 6687
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_cb_hits(ssl_acceptor_fd->ssl_context));
  return 0;
}

6688
static int show_ssl_ctx_sess_hits(THD *thd, SHOW_VAR *var, char *buff)
6689
{
6690
  var->type= SHOW_LONG;
6691 6692 6693 6694 6695 6696
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_hits(ssl_acceptor_fd->ssl_context));
  return 0;
}

6697
static int show_ssl_ctx_sess_cache_full(THD *thd, SHOW_VAR *var, char *buff)
6698
{
6699
  var->type= SHOW_LONG;
6700 6701 6702 6703 6704 6705
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_cache_full(ssl_acceptor_fd->ssl_context));
  return 0;
}

6706
static int show_ssl_ctx_sess_misses(THD *thd, SHOW_VAR *var, char *buff)
6707
{
6708
  var->type= SHOW_LONG;
6709 6710 6711 6712 6713 6714
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_misses(ssl_acceptor_fd->ssl_context));
  return 0;
}

6715
static int show_ssl_ctx_sess_timeouts(THD *thd, SHOW_VAR *var, char *buff)
6716
{
6717
  var->type= SHOW_LONG;
6718 6719 6720 6721 6722 6723
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_timeouts(ssl_acceptor_fd->ssl_context));
  return 0;
}

6724
static int show_ssl_ctx_sess_number(THD *thd, SHOW_VAR *var, char *buff)
6725
{
6726
  var->type= SHOW_LONG;
6727 6728 6729 6730 6731 6732
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context));
  return 0;
}

6733
static int show_ssl_ctx_sess_connect(THD *thd, SHOW_VAR *var, char *buff)
6734
{
6735
  var->type= SHOW_LONG;
6736 6737 6738 6739 6740 6741
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_connect(ssl_acceptor_fd->ssl_context));
  return 0;
}

6742
static int show_ssl_ctx_sess_get_cache_size(THD *thd, SHOW_VAR *var, char *buff)
6743
{
6744
  var->type= SHOW_LONG;
6745 6746 6747 6748 6749 6750
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context));
  return 0;
}

6751
static int show_ssl_ctx_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff)
6752
{
6753
  var->type= SHOW_LONG;
6754 6755 6756 6757 6758 6759
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_get_verify_mode(ssl_acceptor_fd->ssl_context));
  return 0;
}

6760
static int show_ssl_ctx_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff)
6761
{
6762
  var->type= SHOW_LONG;
6763 6764 6765 6766 6767 6768
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_get_verify_depth(ssl_acceptor_fd->ssl_context));
  return 0;
}

6769
static int show_ssl_ctx_get_session_cache_mode(THD *thd, SHOW_VAR *var, char *buff)
6770
{
6771
  var->type= SHOW_CHAR;
6772
  if (!ssl_acceptor_fd)
unknown's avatar
unknown committed
6773
    var->value= const_cast<char*>("NONE");
6774 6775 6776 6777
  else
    switch (SSL_CTX_get_session_cache_mode(ssl_acceptor_fd->ssl_context))
    {
    case SSL_SESS_CACHE_OFF:
unknown's avatar
unknown committed
6778
      var->value= const_cast<char*>("OFF"); break;
6779
    case SSL_SESS_CACHE_CLIENT:
unknown's avatar
unknown committed
6780
      var->value= const_cast<char*>("CLIENT"); break;
6781
    case SSL_SESS_CACHE_SERVER:
unknown's avatar
unknown committed
6782
      var->value= const_cast<char*>("SERVER"); break;
6783
    case SSL_SESS_CACHE_BOTH:
unknown's avatar
unknown committed
6784
      var->value= const_cast<char*>("BOTH"); break;
6785
    case SSL_SESS_CACHE_NO_AUTO_CLEAR:
unknown's avatar
unknown committed
6786
      var->value= const_cast<char*>("NO_AUTO_CLEAR"); break;
6787
    case SSL_SESS_CACHE_NO_INTERNAL_LOOKUP:
unknown's avatar
unknown committed
6788
      var->value= const_cast<char*>("NO_INTERNAL_LOOKUP"); break;
6789
    default:
unknown's avatar
unknown committed
6790
      var->value= const_cast<char*>("Unknown"); break;
6791 6792 6793 6794
    }
  return 0;
}

6795
/*
6796
   Functions relying on SSL
6797 6798 6799 6800 6801
   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.
 */
6802
static int show_ssl_get_version(THD *thd, SHOW_VAR *var, char *buff)
6803
{
6804
  var->type= SHOW_CHAR;
6805 6806 6807
  if( thd->vio_ok() && thd->net.vio->ssl_arg )
    var->value= const_cast<char*>(SSL_get_version((SSL*) thd->net.vio->ssl_arg));
  else
6808
    var->value= (char *)"";
6809 6810 6811
  return 0;
}

6812
static int show_ssl_session_reused(THD *thd, SHOW_VAR *var, char *buff)
6813
{
6814
  var->type= SHOW_LONG;
6815
  var->value= buff;
6816 6817 6818 6819
  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
6820
  return 0;
6821 6822
}

6823
static int show_ssl_get_default_timeout(THD *thd, SHOW_VAR *var, char *buff)
6824
{
6825
  var->type= SHOW_LONG;
6826
  var->value= buff;
6827 6828 6829 6830
  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;
6831 6832 6833
  return 0;
}

6834
static int show_ssl_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff)
6835
{
6836
  var->type= SHOW_LONG;
6837
  var->value= buff;
6838 6839 6840 6841
  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;
6842 6843 6844
  return 0;
}

6845
static int show_ssl_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff)
6846
{
6847
  var->type= SHOW_LONG;
6848
  var->value= buff;
6849 6850 6851 6852
  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;
6853 6854 6855
  return 0;
}

6856
static int show_ssl_get_cipher(THD *thd, SHOW_VAR *var, char *buff)
6857
{
6858
  var->type= SHOW_CHAR;
6859 6860 6861
  if( thd->vio_ok() && thd->net.vio->ssl_arg )
    var->value= const_cast<char*>(SSL_get_cipher((SSL*) thd->net.vio->ssl_arg));
  else
6862
    var->value= (char *)"";
6863 6864 6865
  return 0;
}

6866
static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff)
6867
{
6868
  var->type= SHOW_CHAR;
6869
  var->value= buff;
6870
  if (thd->vio_ok() && thd->net.vio->ssl_arg)
6871 6872 6873
  {
    int i;
    const char *p;
6874 6875 6876
    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++)
6877
    {
6878
      buff= strnmov(buff, p, end-buff-1);
6879 6880 6881 6882 6883 6884 6885 6886 6887
      *buff++= ':';
    }
    if (i)
      buff--;
  }
  *buff=0;
  return 0;
}

Konstantin Osipov's avatar
Konstantin Osipov committed
6888
#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
6889

6890 6891 6892 6893 6894 6895 6896 6897 6898 6899 6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 6910 6911 6912 6913 6914
static int show_default_keycache(THD *thd, SHOW_VAR *var, char *buff)
{
  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
6915
  set_one_keycache_var("blocks_warm",        blocks_warm);
6916 6917 6918 6919 6920 6921 6922 6923 6924 6925 6926 6927 6928 6929
  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;
}

6930 6931 6932 6933 6934 6935 6936 6937 6938
#ifdef HAVE_POOL_OF_THREADS
int show_threadpool_idle_threads(THD *thd, SHOW_VAR *var, char *buff)
{
  var->type= SHOW_INT;
  var->value= buff;
  *(int *)buff= tp_get_idle_thread_count(); 
  return 0;
}
#endif
6939

6940 6941 6942 6943
/*
  Variables shown by SHOW STATUS in alphabetical order
*/

6944
SHOW_VAR status_vars[]= {
6945 6946
  {"Aborted_clients",          (char*) &aborted_threads,        SHOW_LONG},
  {"Aborted_connects",         (char*) &aborted_connects,       SHOW_LONG},
6947
  {"Access_denied_errors",     (char*) offsetof(STATUS_VAR, access_denied_errors), SHOW_LONG_STATUS},
Sergei Golubchik's avatar
Sergei Golubchik committed
6948
  {"Binlog_bytes_written",     (char*) offsetof(STATUS_VAR, binlog_bytes_written), SHOW_LONGLONG_STATUS},
6949 6950
  {"Binlog_cache_disk_use",    (char*) &binlog_cache_disk_use,  SHOW_LONG},
  {"Binlog_cache_use",         (char*) &binlog_cache_use,       SHOW_LONG},
6951 6952
  {"Binlog_stmt_cache_disk_use",(char*) &binlog_stmt_cache_disk_use,  SHOW_LONG},
  {"Binlog_stmt_cache_use",    (char*) &binlog_stmt_cache_use,       SHOW_LONG},
6953
  {"Busy_time",                (char*) offsetof(STATUS_VAR, busy_time), SHOW_DOUBLE_STATUS},
6954 6955
  {"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
6956
  {"Com",                      (char*) com_status_vars, SHOW_ARRAY},
6957
  {"Compression",              (char*) &show_net_compression, SHOW_FUNC},
6958
  {"Connections",              (char*) &thread_id,              SHOW_LONG_NOFLUSH},
6959
  {"Cpu_time",                 (char*) offsetof(STATUS_VAR, cpu_time), SHOW_DOUBLE_STATUS},
unknown's avatar
Merge  
unknown committed
6960
  {"Created_tmp_disk_tables",  (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS},
6961
  {"Created_tmp_files",	       (char*) &my_tmp_file_created,	SHOW_LONG},
unknown's avatar
Merge  
unknown committed
6962
  {"Created_tmp_tables",       (char*) offsetof(STATUS_VAR, created_tmp_tables), SHOW_LONG_STATUS},
6963
  {"Delayed_errors",           (char*) &delayed_insert_errors,  SHOW_LONG},
6964
  {"Delayed_insert_threads",   (char*) &delayed_insert_threads, SHOW_LONG_NOFLUSH},
6965
  {"Delayed_writes",           (char*) &delayed_insert_writes,  SHOW_LONG},
6966
  {"Empty_queries",            (char*) offsetof(STATUS_VAR, empty_queries), SHOW_LONG_STATUS},
6967 6968 6969 6970 6971 6972 6973 6974 6975 6976
  {"Executed_events",          (char*) &executed_events, SHOW_LONG_NOFLUSH },
  {"Executed_triggers",        (char*) offsetof(STATUS_VAR, executed_triggers), SHOW_LONG_STATUS},
  {"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},
  {"Feature_trigger",         (char*) offsetof(STATUS_VAR, feature_trigger), SHOW_LONG_STATUS},
  {"Feature_xml",             (char*) offsetof(STATUS_VAR, feature_xml), SHOW_LONG_STATUS},
6977
  {"Flush_commands",           (char*) &refresh_version,        SHOW_LONG_NOFLUSH},
unknown's avatar
Merge  
unknown committed
6978 6979 6980
  {"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},
6981
  {"Handler_icp_attempts",     (char*) offsetof(STATUS_VAR, ha_icp_attempts), SHOW_LONG_STATUS},
6982 6983
  {"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},
6984 6985
  {"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
6986 6987 6988
  {"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},
6989
  {"Handler_read_last",        (char*) offsetof(STATUS_VAR, ha_read_last_count), SHOW_LONG_STATUS},
unknown's avatar
Merge  
unknown committed
6990 6991 6992
  {"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},
6993
  {"Handler_read_rnd_deleted", (char*) offsetof(STATUS_VAR, ha_read_rnd_deleted_count), SHOW_LONG_STATUS},
unknown's avatar
Merge  
unknown committed
6994 6995 6996 6997
  {"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},
6998 6999
  {"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},
7000 7001
  {"Handler_update",           (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS},
  {"Handler_write",            (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS},
7002
  {"Key",                      (char*) &show_default_keycache, SHOW_FUNC},
7003
  {"Last_query_cost",          (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS},
7004
  {"Max_used_connections",     (char*) &max_used_connections,  SHOW_LONG},
7005 7006 7007
  {"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},
7008 7009
  {"Open_table_definitions",   (char*) &show_table_definitions, SHOW_FUNC},
  {"Open_tables",              (char*) &show_open_tables,       SHOW_FUNC},
7010
  {"Opened_files",             (char*) &my_file_total_opened, SHOW_LONG_NOFLUSH},
7011
  {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS},
Sergei Golubchik's avatar
Sergei Golubchik committed
7012
  {"Opened_tables",            (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS},
7013
  {"Opened_views",            (char*) offsetof(STATUS_VAR, opened_views), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
7014
  {"Prepared_stmt_count",      (char*) &show_prepared_stmt_count, SHOW_FUNC},
7015
  {"Rows_read",                (char*) offsetof(STATUS_VAR, rows_read), SHOW_LONGLONG_STATUS},
Sergei Golubchik's avatar
Sergei Golubchik committed
7016
  {"Rows_sent",                (char*) offsetof(STATUS_VAR, rows_sent), SHOW_LONGLONG_STATUS},
7017
  {"Rows_tmp_read",            (char*) offsetof(STATUS_VAR, rows_tmp_read), SHOW_LONGLONG_STATUS},
unknown's avatar
unknown committed
7018
#ifdef HAVE_QUERY_CACHE
7019 7020
  {"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
7021
  {"Qcache_hits",              (char*) &query_cache.hits,       SHOW_LONG},
7022
  {"Qcache_inserts",           (char*) &query_cache.inserts,    SHOW_LONG},
7023
  {"Qcache_lowmem_prunes",     (char*) &query_cache.lowmem_prunes, SHOW_LONG},
unknown's avatar
unknown committed
7024
  {"Qcache_not_cached",        (char*) &query_cache.refused,    SHOW_LONG},
7025 7026
  {"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
7027
#endif /*HAVE_QUERY_CACHE*/
7028
  {"Queries",                  (char*) &show_queries,            SHOW_FUNC},
7029
  {"Questions",                (char*) offsetof(STATUS_VAR, questions), SHOW_LONG_STATUS},
7030 7031 7032
#ifdef HAVE_REPLICATION
  {"Rpl_status",               (char*) &show_rpl_status,          SHOW_FUNC},
#endif
unknown's avatar
Merge  
unknown committed
7033 7034 7035 7036 7037
  {"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},
7038
  {"Slave_open_temp_tables",   (char*) &slave_open_temp_tables, SHOW_LONG},
7039
#ifdef HAVE_REPLICATION
Andrei Elkin's avatar
Andrei Elkin committed
7040 7041
  {"Slave_heartbeat_period",   (char*) &show_heartbeat_period, SHOW_FUNC},
  {"Slave_received_heartbeats",(char*) &show_slave_received_heartbeats, SHOW_FUNC},
Sergei Golubchik's avatar
Sergei Golubchik committed
7042
  {"Slave_retried_transactions",(char*) &show_slave_retried_trans, SHOW_FUNC},
7043 7044
  {"Slave_running",            (char*) &show_slave_running,     SHOW_FUNC},
#endif
7045
  {"Slow_launch_threads",      (char*) &slow_launch_threads,    SHOW_LONG},
unknown's avatar
Merge  
unknown committed
7046 7047 7048 7049 7050
  {"Slow_queries",             (char*) offsetof(STATUS_VAR, long_query_count), SHOW_LONG_STATUS},
  {"Sort_merge_passes",	       (char*) offsetof(STATUS_VAR, filesort_merge_passes), SHOW_LONG_STATUS},
  {"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
7051
#ifdef HAVE_OPENSSL
Konstantin Osipov's avatar
Konstantin Osipov committed
7052
#ifndef EMBEDDED_LIBRARY
7053 7054 7055 7056 7057 7058 7059 7060 7061 7062 7063 7064 7065 7066 7067 7068 7069 7070 7071 7072 7073 7074 7075
  {"Ssl_accept_renegotiates",  (char*) &show_ssl_ctx_sess_accept_renegotiate, SHOW_FUNC},
  {"Ssl_accepts",              (char*) &show_ssl_ctx_sess_accept, SHOW_FUNC},
  {"Ssl_callback_cache_hits",  (char*) &show_ssl_ctx_sess_cb_hits, SHOW_FUNC},
  {"Ssl_cipher",               (char*) &show_ssl_get_cipher, SHOW_FUNC},
  {"Ssl_cipher_list",          (char*) &show_ssl_get_cipher_list, SHOW_FUNC},
  {"Ssl_client_connects",      (char*) &show_ssl_ctx_sess_connect, SHOW_FUNC},
  {"Ssl_connect_renegotiates", (char*) &show_ssl_ctx_sess_connect_renegotiate, SHOW_FUNC},
  {"Ssl_ctx_verify_depth",     (char*) &show_ssl_ctx_get_verify_depth, SHOW_FUNC},
  {"Ssl_ctx_verify_mode",      (char*) &show_ssl_ctx_get_verify_mode, SHOW_FUNC},
  {"Ssl_default_timeout",      (char*) &show_ssl_get_default_timeout, SHOW_FUNC},
  {"Ssl_finished_accepts",     (char*) &show_ssl_ctx_sess_accept_good, SHOW_FUNC},
  {"Ssl_finished_connects",    (char*) &show_ssl_ctx_sess_connect_good, SHOW_FUNC},
  {"Ssl_session_cache_hits",   (char*) &show_ssl_ctx_sess_hits, SHOW_FUNC},
  {"Ssl_session_cache_misses", (char*) &show_ssl_ctx_sess_misses, SHOW_FUNC},
  {"Ssl_session_cache_mode",   (char*) &show_ssl_ctx_get_session_cache_mode, SHOW_FUNC},
  {"Ssl_session_cache_overflows", (char*) &show_ssl_ctx_sess_cache_full, SHOW_FUNC},
  {"Ssl_session_cache_size",   (char*) &show_ssl_ctx_sess_get_cache_size, SHOW_FUNC},
  {"Ssl_session_cache_timeouts", (char*) &show_ssl_ctx_sess_timeouts, SHOW_FUNC},
  {"Ssl_sessions_reused",      (char*) &show_ssl_session_reused, SHOW_FUNC},
  {"Ssl_used_session_cache_entries",(char*) &show_ssl_ctx_sess_number, SHOW_FUNC},
  {"Ssl_verify_depth",         (char*) &show_ssl_get_verify_depth, SHOW_FUNC},
  {"Ssl_verify_mode",          (char*) &show_ssl_get_verify_mode, SHOW_FUNC},
  {"Ssl_version",              (char*) &show_ssl_get_version, SHOW_FUNC},
Konstantin Osipov's avatar
Konstantin Osipov committed
7076
#endif
unknown's avatar
unknown committed
7077
#endif /* HAVE_OPENSSL */
7078
  {"Syncs",                    (char*) &my_sync_count,          SHOW_LONG_NOFLUSH},
unknown's avatar
unknown committed
7079 7080 7081 7082
  /*
    Expression cache used only for caching subqueries now, so its statistic
    variables we call subquery_cache*.
  */
7083 7084
  {"Subquery_cache_hit",       (char*) &subquery_cache_hit,     SHOW_LONG},
  {"Subquery_cache_miss",      (char*) &subquery_cache_miss,    SHOW_LONG},
unknown's avatar
unknown committed
7085 7086
  {"Table_locks_immediate",    (char*) &locks_immediate,        SHOW_LONG},
  {"Table_locks_waited",       (char*) &locks_waited,           SHOW_LONG},
7087
#ifdef HAVE_MMAP
unknown's avatar
Merge  
unknown committed
7088
  {"Tc_log_max_pages_used",    (char*) &tc_log_max_pages_used,  SHOW_LONG},
7089
  {"Tc_log_page_size",         (char*) &tc_log_page_size,       SHOW_LONG_NOFLUSH},
unknown's avatar
Merge  
unknown committed
7090
  {"Tc_log_page_waits",        (char*) &tc_log_page_waits,      SHOW_LONG},
7091
#endif
7092 7093
#ifdef HAVE_POOL_OF_THREADS
  {"Threadpool_idle_threads",  (char *) &show_threadpool_idle_threads, SHOW_FUNC},
7094
  {"Threadpool_threads",       (char *) &tp_stats.num_worker_threads, SHOW_INT},
7095
#endif
7096
  {"Threads_cached",           (char*) &cached_thread_count,    SHOW_LONG_NOFLUSH},
Konstantin Osipov's avatar
Konstantin Osipov committed
7097
  {"Threads_connected",        (char*) &connection_count,       SHOW_INT},
7098 7099
  {"Threads_created",	       (char*) &thread_created,		SHOW_LONG_NOFLUSH},
  {"Threads_running",          (char*) &thread_running,         SHOW_INT},
7100
  {"Uptime",                   (char*) &show_starttime,         SHOW_FUNC},
7101
#ifdef ENABLED_PROFILING
7102
  {"Uptime_since_flush_status",(char*) &show_flushstatustime,   SHOW_FUNC},
7103
#endif
7104
  {NullS, NullS, SHOW_LONG}
unknown's avatar
unknown committed
7105 7106
};

Marc Alff's avatar
Marc Alff committed
7107
bool add_terminator(DYNAMIC_ARRAY *options)
7108 7109
{
  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
7110
  return insert_dynamic(options, (uchar *)&empty_element);
7111 7112
}

7113
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
7114 7115
static void print_version(void)
{
7116
  set_server_version();
7117

7118 7119
  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
7120 7121
}

7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 7132 7133 7134 7135 7136 7137 7138 7139 7140 7141 7142 7143 7144 7145 7146 7147 7148 7149 7150 7151 7152 7153
/** 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;
    }
  }
  DBUG_ASSERT(a->name == b->name);
  return 0;
}

static void print_help()
{
  MEM_ROOT mem_root;
  init_alloc_root(&mem_root, 4096, 4096);

  pop_dynamic(&all_options);
Marc Alff's avatar
Marc Alff committed
7154
  sys_var_add_options(&all_options, sys_var::PARSE_EARLY);
7155 7156
  add_plugin_options(&all_options, &mem_root);
  sort_dynamic(&all_options, (qsort_cmp) option_cmp);
Marc Alff's avatar
Marc Alff committed
7157
  add_terminator(&all_options);
7158 7159 7160 7161 7162 7163 7164

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

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

unknown's avatar
unknown committed
7165 7166
static void usage(void)
{
7167
  DBUG_ENTER("usage");
7168
  if (!(default_charset_info= get_charset_by_csname(default_character_set_name,
unknown's avatar
unknown committed
7169 7170 7171 7172 7173
					           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
7174
  print_version();
7175
  puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000"));
Sergei Golubchik's avatar
Sergei Golubchik committed
7176
  puts("Starts the MariaDB database server.\n");
unknown's avatar
unknown committed
7177
  printf("Usage: %s [OPTIONS]\n", my_progname);
7178
  if (!opt_verbose)
Staale Smedseng's avatar
Staale Smedseng committed
7179
    puts("\nFor more help options (several pages), use mysqld --verbose --help.");
7180 7181
  else
  {
unknown's avatar
unknown committed
7182 7183
#ifdef __WIN__
  puts("NT and Win32 specific options:\n\
Staale Smedseng's avatar
Staale Smedseng committed
7184 7185 7186 7187 7188 7189 7190 7191
  --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
7192
");
7193
  puts("");
unknown's avatar
unknown committed
7194
#endif
7195
  print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
unknown's avatar
unknown committed
7196 7197
  puts("");
  set_ports();
7198

unknown's avatar
unknown committed
7199
  /* Print out all the options including plugin supplied options */
7200
  print_help();
7201

7202 7203 7204 7205 7206 7207 7208
  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
7209
  puts("\n\
unknown's avatar
unknown committed
7210
To see what values a running MySQL server is using, type\n\
7211
'mysqladmin variables' instead of 'mysqld --verbose --help'.");
7212
  }
7213
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
7214
}
7215
#endif /*!EMBEDDED_LIBRARY*/
unknown's avatar
unknown committed
7216

unknown's avatar
unknown committed
7217
/**
7218
  Initialize MySQL global variables to default values.
unknown's avatar
unknown committed
7219

unknown's avatar
unknown committed
7220
  @note
unknown's avatar
unknown committed
7221 7222 7223 7224
    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
7225

7226
    We don't need to set variables refered to in my_long_options
unknown's avatar
unknown committed
7227 7228
    as these are initialized by my_getopt.
*/
unknown's avatar
unknown committed
7229

7230
static int mysql_init_variables(void)
unknown's avatar
unknown committed
7231 7232 7233 7234
{
  /* Things reset to zero */
  opt_skip_slave_start= opt_reckless_slave = 0;
  mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0;
7235
#if defined(HAVE_REALPATH) && !defined(HAVE_valgrind) && !defined(HAVE_BROKEN_REALPATH)
7236
  /*  We can only test for sub paths if my_symlink.c is using realpath */
7237
  myisam_test_invalid_symlink= test_if_data_home_dir;
7238
#endif
unknown's avatar
unknown committed
7239
  opt_log= opt_slow_log= 0;
7240
  opt_bin_log= opt_bin_log_used= 0;
unknown's avatar
unknown committed
7241
  opt_disable_networking= opt_skip_show_db=0;
7242
  opt_skip_name_resolve= 0;
7243
  opt_ignore_builtin_innodb= 0;
Sergei Golubchik's avatar
Sergei Golubchik committed
7244
  opt_logname= opt_binlog_index_name= opt_slow_logname= 0;
7245
  opt_log_basename= 0;
unknown's avatar
Merge  
unknown committed
7246
  opt_tc_log_file= (char *)"tc.log";      // no hostname in tc_log file name !
7247 7248
  opt_secure_auth= 0;
  opt_bootstrap= opt_myisam_log= 0;
unknown's avatar
unknown committed
7249
  mqh_used= 0;
7250
  kill_in_progress= 0;
unknown's avatar
unknown committed
7251 7252 7253 7254 7255 7256 7257
  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;
7258
  opt_using_transactions= 0;
unknown's avatar
unknown committed
7259 7260
  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
7261
  aborted_threads= aborted_connects= 0;
unknown's avatar
unknown committed
7262
  subquery_cache_miss= subquery_cache_hit= 0;
unknown's avatar
unknown committed
7263 7264
  delayed_insert_threads= delayed_insert_writes= delayed_rows_in_use= 0;
  delayed_insert_errors= thread_created= 0;
unknown's avatar
Merge  
unknown committed
7265
  specialflag= 0;
7266
  binlog_cache_use=  binlog_cache_disk_use= 0;
unknown's avatar
unknown committed
7267 7268
  max_used_connections= slow_launch_threads = 0;
  mysqld_user= mysqld_chroot= opt_init_file= opt_bin_logname = 0;
7269
  prepared_stmt_count= 0;
7270
  mysqld_unix_port= opt_mysql_tmpdir= my_bind_addr_str= NullS;
7271
  bzero((uchar*) &mysql_tmpdir_list, sizeof(mysql_tmpdir_list));
unknown's avatar
Merge  
unknown committed
7272
  bzero((char *) &global_status_var, sizeof(global_status_var));
7273
  opt_large_pages= 0;
7274
  opt_super_large_pages= 0;
7275 7276 7277
#if defined(ENABLED_DEBUG_SYNC)
  opt_debug_sync_timeout= 0;
#endif /* defined(ENABLED_DEBUG_SYNC) */
7278
  key_map_full.set_all();
unknown's avatar
unknown committed
7279

7280 7281 7282 7283 7284
  /* 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
7285
  character_set_filesystem= &my_charset_bin;
7286

unknown's avatar
unknown committed
7287
  opt_specialflag= SPECIAL_ENGLISH;
7288
  unix_sock= base_ip_sock= extra_ip_sock= INVALID_SOCKET;
unknown's avatar
unknown committed
7289 7290 7291 7292 7293
  mysql_home_ptr= mysql_home;
  pidfile_name_ptr= pidfile_name;
  log_error_file_ptr= log_error_file;
  protocol_version= PROTOCOL_VERSION;
  what_to_log= ~ (1L << (uint) COM_TIME);
7294
  refresh_version= 2L;	/* Increments on each reload. 0 and 1 are reserved */
7295
  executed_events= 0;
7296
  global_query_id= thread_id= 1L;
7297
  my_atomic_rwlock_init(&global_query_id_lock);
7298
  my_atomic_rwlock_init(&thread_running_lock);
unknown's avatar
unknown committed
7299 7300 7301
  strmov(server_version, MYSQL_SERVER_VERSION);
  threads.empty();
  thread_cache.empty();
7302
  key_caches.empty();
unknown's avatar
unknown committed
7303
  if (!(dflt_key_cache= get_or_create_key_cache(default_key_cache_base.str,
7304
                                                default_key_cache_base.length)))
7305 7306 7307 7308
  {
    sql_print_error("Cannot allocate the keycache");
    return 1;
  }
7309

7310 7311
  /* set key_cache_hash.default_value = dflt_key_cache */
  multi_keycache_init();
unknown's avatar
unknown committed
7312 7313

  /* Set directory paths */
7314 7315 7316
  mysql_real_data_home_len=
    strmake(mysql_real_data_home, get_relative_path(MYSQL_DATADIR),
            sizeof(mysql_real_data_home)-1) - mysql_real_data_home;
unknown's avatar
unknown committed
7317 7318
  /* Replication parameters */
  master_info_file= (char*) "master.info",
unknown's avatar
unknown committed
7319
    relay_log_info_file= (char*) "relay-log.info";
unknown's avatar
unknown committed
7320 7321 7322 7323 7324
  report_user= report_password = report_host= 0;	/* TO BE DELETED */
  opt_relay_logname= opt_relaylog_index_name= 0;

  /* Variables in libraries */
  charsets_dir= 0;
7325
  default_character_set_name= (char*) MYSQL_DEFAULT_CHARSET_NAME;
7326
  default_collation_name= compiled_default_collation_name;
unknown's avatar
unknown committed
7327
  character_set_filesystem_name= (char*) "binary";
7328
  lc_messages= (char*) "en_US";
7329
  lc_time_names_name= (char*) "en_US";
7330
  
unknown's avatar
unknown committed
7331 7332 7333 7334
  /* 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");
7335
  current_dbug_option= default_dbug_option;
unknown's avatar
unknown committed
7336 7337
#endif
  opt_error_log= IF_WIN(1,0);
7338 7339
#ifdef ENABLED_PROFILING
    have_profiling = SHOW_OPTION_YES;
7340
#else
7341
    have_profiling = SHOW_OPTION_NO;
7342
#endif
7343

unknown's avatar
unknown committed
7344
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
7345
  have_ssl=SHOW_OPTION_YES;
unknown's avatar
unknown committed
7346
#else
7347
  have_ssl=SHOW_OPTION_NO;
unknown's avatar
unknown committed
7348
#endif
unknown's avatar
unknown committed
7349
#ifdef HAVE_BROKEN_REALPATH
unknown's avatar
unknown committed
7350 7351 7352 7353
  have_symlink=SHOW_OPTION_NO;
#else
  have_symlink=SHOW_OPTION_YES;
#endif
7354 7355 7356 7357 7358
#ifdef HAVE_DLOPEN
  have_dlopen=SHOW_OPTION_YES;
#else
  have_dlopen=SHOW_OPTION_NO;
#endif
unknown's avatar
unknown committed
7359 7360 7361 7362 7363
#ifdef HAVE_QUERY_CACHE
  have_query_cache=SHOW_OPTION_YES;
#else
  have_query_cache=SHOW_OPTION_NO;
#endif
7364 7365 7366 7367 7368 7369 7370 7371 7372 7373
#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
7374 7375 7376 7377 7378 7379
#ifdef HAVE_CRYPT
  have_crypt=SHOW_OPTION_YES;
#else
  have_crypt=SHOW_OPTION_NO;
#endif
#ifdef HAVE_COMPRESS
7380
  have_compress= SHOW_OPTION_YES;
unknown's avatar
unknown committed
7381
#else
7382
  have_compress= SHOW_OPTION_NO;
unknown's avatar
unknown committed
7383 7384 7385 7386 7387 7388
#endif
#ifdef HAVE_LIBWRAP
  libwrapName= NullS;
#endif
#ifdef HAVE_OPENSSL
  des_key_file = 0;
Konstantin Osipov's avatar
Konstantin Osipov committed
7389
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
7390
  ssl_acceptor_fd= 0;
Konstantin Osipov's avatar
Konstantin Osipov committed
7391 7392
#endif /* ! EMBEDDED_LIBRARY */
#endif /* HAVE_OPENSSL */
unknown's avatar
unknown committed
7393 7394 7395 7396
#ifdef HAVE_SMEM
  shared_memory_base_name= default_shared_memory_base_name;
#endif

7397 7398
#if defined(__WIN__)
  /* Allow Win32 users to move MySQL anywhere */
unknown's avatar
unknown committed
7399 7400
  {
    char prg_dev[LIBLEN];
7401 7402 7403 7404 7405 7406 7407 7408 7409 7410 7411
    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
7412 7413 7414 7415 7416
    strcat(prg_dev,"/../");			// Remove 'bin' to get base dir
    cleanup_dirname(mysql_home,prg_dev);
  }
#else
  const char *tmpenv;
unknown's avatar
unknown committed
7417
  if (!(tmpenv = getenv("MY_BASEDIR_VERSION")))
unknown's avatar
unknown committed
7418
    tmpenv = DEFAULT_MYSQL_HOME;
unknown's avatar
unknown committed
7419
  (void) strmake(mysql_home, tmpenv, sizeof(mysql_home)-1);
unknown's avatar
unknown committed
7420
#endif
7421
  return 0;
unknown's avatar
unknown committed
7422 7423
}

7424 7425 7426 7427
my_bool
mysqld_get_one_option(int optid,
                      const struct my_option *opt __attribute__((unused)),
                      char *argument)
unknown's avatar
unknown committed
7428
{
7429 7430
  switch(optid) {
  case '#':
7431
#ifndef DBUG_OFF
7432 7433 7434
    if (!argument)
      argument= (char*) default_dbug_option;
    if (argument[0] == '0' && !argument[1])
unknown's avatar
unknown committed
7435 7436 7437 7438
    {
      DEBUGGER_OFF;
      break;
    }
7439
    DEBUGGER_ON;
7440
    if (argument[0] == '1' && !argument[1])
unknown's avatar
unknown committed
7441
      break;
7442
    DBUG_SET_INITIAL(argument);
7443
    opt_endinfo=1;				/* unireg: memory allocation */
7444 7445
#else
    sql_print_warning("'%s' is disabled in this build", opt->name);
7446
#endif
7447
    break;
7448
  case OPT_DEPRECATED_OPTION:
Sergei Golubchik's avatar
Sergei Golubchik committed
7449 7450
    sql_print_warning("'%s' is deprecated. It does nothing and exists only "
                      "for compatiblity with old my.cnf files.",
7451 7452
                      opt->name);
    break;
7453
  case 'a':
7454
    global_system_variables.sql_mode= MODE_ANSI;
unknown's avatar
unknown committed
7455
    global_system_variables.tx_isolation= ISO_SERIALIZABLE;
7456 7457 7458 7459
    break;
  case 'b':
    strmake(mysql_home,argument,sizeof(mysql_home)-1);
    break;
7460
  case 'C':
7461 7462
    if (default_collation_name == compiled_default_collation_name)
      default_collation_name= 0;
7463
    break;
7464
  case 'l':
7465
    WARN_DEPRECATED(NULL, 7, 0, "--log", "'--general-log'/'--general-log-file'");
7466 7467 7468 7469
    opt_log=1;
    break;
  case 'h':
    strmake(mysql_real_data_home,argument, sizeof(mysql_real_data_home)-1);
7470
    /* Correct pointer set by my_getopt (for embedded library) */
7471
    mysql_real_data_home_ptr= mysql_real_data_home;
7472
    break;
7473
  case 'u':
7474
    if (!mysqld_user || !strcmp(mysqld_user, argument))
unknown's avatar
unknown committed
7475
      mysqld_user= argument;
7476
    else
7477
      sql_print_warning("Ignoring user change to '%s' because the user was set to '%s' earlier on the command line\n", argument, mysqld_user);
7478
    break;
7479
  case 'L':
7480
    strmake(lc_messages_dir, argument, sizeof(lc_messages_dir)-1);
7481
    break;
7482 7483
  case OPT_BINLOG_FORMAT:
    binlog_format_used= true;
7484
    break;
7485
#include <sslopt-case.h>
7486
#ifndef EMBEDDED_LIBRARY
7487 7488
  case 'V':
    print_version();
7489 7490
    opt_abort= 1;                    // Abort after parsing all options
    break;
7491
#endif /*EMBEDDED_LIBRARY*/
7492 7493 7494 7495 7496 7497 7498 7499
  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;
7500 7501 7502 7503 7504 7505 7506 7507
  case 'T':
    test_flags= argument ? (uint) atoi(argument) : 0;
    opt_endinfo=1;
    break;
  case (int) OPT_ISAM_LOG:
    opt_myisam_log=1;
    break;
  case (int) OPT_BIN_LOG:
7508
    opt_bin_log= test(argument != disabled_my_option);
7509
    opt_bin_log_used= 1;
7510
    break;
7511 7512 7513 7514 7515 7516 7517 7518
  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
7519 7520
    if (log_error_file_ptr != disabled_my_option)
      log_error_file_ptr= opt_log_basename;
7521

Sergei Golubchik's avatar
Sergei Golubchik committed
7522 7523 7524 7525 7526 7527
    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);
    make_default_log_name(&opt_relay_logname, "-relay-bin", true);
    make_default_log_name(&opt_relaylog_index_name, "-relay-bin.index", true);
7528 7529 7530 7531 7532 7533 7534

    pidfile_name_ptr= pidfile_name;
    strmake(pidfile_name, argument, sizeof(pidfile_name)-5);
    strmov(fn_ext(pidfile_name),".pid");

    /* check for errors */
    if (!opt_bin_logname || !opt_relaylog_index_name || ! opt_logname ||
Sergei Golubchik's avatar
Sergei Golubchik committed
7535
        ! opt_slow_logname || !pidfile_name_ptr)
7536 7537 7538
      return 1;                                 // out of memory error
    break;
  }
unknown's avatar
SCRUM  
unknown committed
7539
#ifdef HAVE_REPLICATION
7540
  case (int)OPT_REPLICATE_IGNORE_DB:
7541
  {
7542
    rpl_filter->add_ignore_db(argument);
7543 7544 7545 7546
    break;
  }
  case (int)OPT_REPLICATE_DO_DB:
  {
7547
    rpl_filter->add_do_db(argument);
7548 7549 7550 7551
    break;
  }
  case (int)OPT_REPLICATE_REWRITE_DB:
  {
7552
    /* See also OPT_REWRITE_DB handling in client/mysqlbinlog.cc */
7553
    char* key = argument,*p, *val;
7554

7555
    if (!(p= strstr(argument, "->")))
7556
    {
7557 7558
      sql_print_error("Bad syntax in replicate-rewrite-db - missing '->'!\n");
      return 1;
7559
    }
7560
    val= p--;
unknown's avatar
unknown committed
7561
    while (my_isspace(mysqld_charset, *p) && p > argument)
7562 7563
      *p-- = 0;
    if (p == argument)
7564
    {
7565 7566
      sql_print_error("Bad syntax in replicate-rewrite-db - empty FROM db!\n");
      return 1;
7567
    }
7568 7569
    *val= 0;
    val+= 2;
unknown's avatar
unknown committed
7570
    while (*val && my_isspace(mysqld_charset, *val))
7571
      val++;
7572
    if (!*val)
7573
    {
7574 7575
      sql_print_error("Bad syntax in replicate-rewrite-db - empty TO db!\n");
      return 1;
7576 7577
    }

7578
    rpl_filter->add_db_rewrite(key, val);
7579 7580 7581
    break;
  }

7582
  case (int)OPT_BINLOG_IGNORE_DB:
7583
  {
7584
    binlog_filter->add_ignore_db(argument);
7585 7586
    break;
  }
7587
  case (int)OPT_BINLOG_DO_DB:
7588
  {
7589
    binlog_filter->add_do_db(argument);
7590 7591
    break;
  }
7592
  case (int)OPT_REPLICATE_DO_TABLE:
7593
  {
7594
    if (rpl_filter->add_do_table(argument))
7595
    {
7596 7597
      sql_print_error("Could not add do table rule '%s'!\n", argument);
      return 1;
7598
    }
7599 7600
    break;
  }
7601
  case (int)OPT_REPLICATE_WILD_DO_TABLE:
7602
  {
7603
    if (rpl_filter->add_wild_do_table(argument))
7604
    {
7605 7606
      sql_print_error("Could not add do table rule '%s'!\n", argument);
      return 1;
7607
    }
7608 7609
    break;
  }
7610
  case (int)OPT_REPLICATE_WILD_IGNORE_TABLE:
7611
  {
7612
    if (rpl_filter->add_wild_ignore_table(argument))
7613
    {
7614 7615
      sql_print_error("Could not add ignore table rule '%s'!\n", argument);
      return 1;
7616
    }
7617 7618
    break;
  }
7619
  case (int)OPT_REPLICATE_IGNORE_TABLE:
7620
  {
7621
    if (rpl_filter->add_ignore_table(argument))
7622
    {
7623 7624
      sql_print_error("Could not add ignore table rule '%s'!\n", argument);
      return 1;
7625
    }
7626 7627
    break;
  }
unknown's avatar
SCRUM  
unknown committed
7628
#endif /* HAVE_REPLICATION */
7629
  case (int) OPT_SLOW_QUERY_LOG:
7630
    WARN_DEPRECATED(NULL, 7, 0, "--log-slow-queries", "'--slow-query-log'/'--slow-query-log-file'");
7631
    opt_slow_log= 1;
7632
    break;
7633
  case (int) OPT_SAFE:
7634
    opt_specialflag|= SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC;
7635
    delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
7636 7637
    myisam_recover_options= HA_RECOVER_DEFAULT;
    ha_open_options&= ~(HA_OPEN_DELAY_KEY_WRITE);
unknown's avatar
unknown committed
7638
#ifdef HAVE_QUERY_CACHE
7639 7640
    query_cache_size=0;
#endif
7641 7642
    sql_print_warning("The syntax '--safe-mode' is deprecated and will be "
                      "removed in a future release.");
7643 7644 7645
    break;
  case (int) OPT_SKIP_PRIOR:
    opt_specialflag|= SPECIAL_NO_PRIOR;
7646
    sql_print_warning("The --skip-thread-priority startup option is deprecated "
Konstantin Osipov's avatar
Konstantin Osipov committed
7647 7648
                      "and will be removed in MySQL 7.0. This option has no effect "
                      "as the implied behavior is already the default.");
7649
    break;
7650 7651 7652 7653
  case (int) OPT_SKIP_HOST_CACHE:
    opt_specialflag|= SPECIAL_NO_HOST_CACHE;
    break;
  case (int) OPT_SKIP_RESOLVE:
7654
    opt_skip_name_resolve= 1;
7655 7656 7657 7658 7659 7660 7661
    opt_specialflag|=SPECIAL_NO_RESOLVE;
    break;
  case (int) OPT_WANT_CORE:
    test_flags |= TEST_CORE_ON_SIGNAL;
    break;
  case (int) OPT_BIND_ADDRESS:
    {
7662 7663 7664 7665 7666 7667 7668
      struct addrinfo *res_lst, hints;    

      bzero(&hints, sizeof(struct addrinfo));
      hints.ai_socktype= SOCK_STREAM;
      hints.ai_protocol= IPPROTO_TCP;

      if (getaddrinfo(argument, NULL, &hints, &res_lst) != 0) 
unknown's avatar
unknown committed
7669
      {
7670 7671
        sql_print_error("Can't start server: cannot resolve hostname!");
        return 1;
unknown's avatar
unknown committed
7672
      }
7673 7674

      if (res_lst->ai_next)
7675
      {
7676
        sql_print_error("Can't start server: bind-address refers to multiple interfaces!");
7677
        return 1;
7678
      }
7679
      freeaddrinfo(res_lst);
7680 7681
    }
    break;
7682 7683 7684 7685
  case OPT_CONSOLE:
    if (opt_console)
      opt_error_log= 0;			// Force logs to stdout
    break;
7686 7687 7688 7689 7690 7691
  case OPT_BOOTSTRAP:
    opt_noacl=opt_bootstrap=1;
    break;
  case OPT_SERVER_ID:
    server_id_supplied = 1;
    break;
unknown's avatar
unknown committed
7692
  case OPT_ONE_THREAD:
7693
    thread_handling= SCHEDULER_NO_THREADS;
7694
    break;
unknown's avatar
unknown committed
7695
  case OPT_LOWER_CASE_TABLE_NAMES:
7696
    lower_case_table_names_used= 1;
unknown's avatar
unknown committed
7697
    break;
7698 7699 7700 7701 7702 7703 7704 7705 7706 7707 7708 7709 7710 7711 7712 7713
#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) */
7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725
  case OPT_ENGINE_CONDITION_PUSHDOWN:
    /*
      The last of --engine-condition-pushdown and --optimizer_switch on
      command line wins (see get_options().
    */
    if (global_system_variables.engine_condition_pushdown)
      global_system_variables.optimizer_switch|=
        OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN;
    else
      global_system_variables.optimizer_switch&=
        ~OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN;
    break;
7726 7727 7728 7729 7730 7731 7732 7733
  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;
7734 7735 7736
  case OPT_MAX_LONG_DATA_SIZE:
    max_long_data_size_used= true;
    break;
7737 7738 7739 7740 7741 7742 7743 7744 7745 7746 7747 7748 7749 7750 7751 7752


  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;
unknown's avatar
unknown committed
7753
  }
7754 7755
  return 0;
}
7756

7757

unknown's avatar
unknown committed
7758
/** Handle arguments for multiple key caches. */
7759

7760
C_MODE_START
7761

7762
static void*
7763
mysql_getopt_value(const char *keyname, uint key_length,
7764
		   const struct my_option *option, int *error)
7765
{
7766 7767
  if (error)
    *error= 0;
7768 7769
  switch (option->id) {
  case OPT_KEY_BUFFER_SIZE:
unknown's avatar
unknown committed
7770
  case OPT_KEY_CACHE_BLOCK_SIZE:
7771 7772
  case OPT_KEY_CACHE_DIVISION_LIMIT:
  case OPT_KEY_CACHE_AGE_THRESHOLD:
7773
  case OPT_KEY_CACHE_PARTITIONS:
7774
  {
unknown's avatar
unknown committed
7775
    KEY_CACHE *key_cache;
7776
    if (!(key_cache= get_or_create_key_cache(keyname, key_length)))
7777 7778 7779 7780 7781
    {
      if (error)
        *error= EXIT_OUT_OF_MEMORY;
      return 0;
    }
7782 7783
    switch (option->id) {
    case OPT_KEY_BUFFER_SIZE:
7784
      return &key_cache->param_buff_size;
7785
    case OPT_KEY_CACHE_BLOCK_SIZE:
7786
      return &key_cache->param_block_size;
7787
    case OPT_KEY_CACHE_DIVISION_LIMIT:
7788
      return &key_cache->param_division_limit;
7789
    case OPT_KEY_CACHE_AGE_THRESHOLD:
7790
      return &key_cache->param_age_threshold;
7791 7792
    case OPT_KEY_CACHE_PARTITIONS:
      return (uchar**) &key_cache->param_partitions;
7793
    }
7794 7795
  }
  }
7796
  return option->value;
7797 7798
}

7799
static void option_error_reporter(enum loglevel level, const char *format, ...)
unknown's avatar
unknown committed
7800
{
7801
  va_list args;
unknown's avatar
unknown committed
7802
  va_start(args, format);
7803 7804 7805 7806 7807 7808 7809

  /* 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
7810
  va_end(args);
unknown's avatar
unknown committed
7811
}
7812

7813
C_MODE_END
unknown's avatar
unknown committed
7814

unknown's avatar
unknown committed
7815
/**
Marc Alff's avatar
Marc Alff committed
7816 7817 7818 7819 7820 7821
  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
7822 7823 7824
  @todo
  - FIXME add EXIT_TOO_MANY_ARGUMENTS to "mysys_err.h" and return that code?
*/
Marc Alff's avatar
Marc Alff committed
7825
static int get_options(int *argc_ptr, char ***argv_ptr)
7826 7827 7828
{
  int ho_error;

7829
  my_getopt_register_get_addr(mysql_getopt_value);
7830
  my_getopt_error_reporter= option_error_reporter;
unknown's avatar
unknown committed
7831

Marc Alff's avatar
Marc Alff committed
7832 7833 7834 7835
  /* prepare all_options array */
  my_init_dynamic_array(&all_options, sizeof(my_option),
                        array_elements(my_long_options),
                        array_elements(my_long_options)/4);
7836 7837 7838
  for (my_option *opt= my_long_options;
       opt < my_long_options + array_elements(my_long_options) - 1;
       opt++)
Marc Alff's avatar
Marc Alff committed
7839
    insert_dynamic(&all_options, (uchar*) opt);
7840
  sys_var_add_options(&all_options, 0);
Marc Alff's avatar
Marc Alff committed
7841
  add_terminator(&all_options);
7842

unknown's avatar
unknown committed
7843 7844 7845
  /* Skip unknown options so that they may be processed later by plugins */
  my_getopt_skip_unknown= TRUE;

Marc Alff's avatar
Marc Alff committed
7846
  if ((ho_error= handle_options(argc_ptr, argv_ptr, (my_option*)(all_options.buffer),
7847
                                mysqld_get_one_option)))
7848
    return ho_error;
7849 7850 7851

  if (!opt_help)
    delete_dynamic(&all_options);
7852 7853
  else
    opt_abort= 1;
7854

Marc Alff's avatar
Marc Alff committed
7855 7856 7857
  /* Add back the program name handle_options removes */
  (*argc_ptr)++;
  (*argv_ptr)--;
7858

7859 7860 7861 7862 7863 7864
  /*
    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.
  */
7865

7866 7867
  if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes ||
       opt_log_slow_slave_statements) &&
7868
      !opt_slow_log)
7869
    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");
7870 7871 7872 7873 7874 7875 7876 7877
  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);
  }
7878

7879 7880 7881 7882 7883 7884 7885 7886 7887 7888 7889 7890 7891 7892 7893 7894 7895 7896 7897
  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
7898
    mysqld_port= mysqld_extra_port= 0;
7899

7900 7901 7902 7903 7904 7905 7906 7907 7908 7909 7910 7911 7912 7913 7914 7915
  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;

7916 7917 7918 7919 7920 7921
  // 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;
7922 7923 7924

  global_system_variables.sql_mode=
    expand_sql_mode(global_system_variables.sql_mode);
unknown's avatar
unknown committed
7925
#if defined(HAVE_BROKEN_REALPATH)
7926 7927 7928 7929 7930 7931 7932 7933 7934 7935
  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
7936 7937 7938
  if (opt_debugging)
  {
    /* Allow break with SIGINT, no core or stack trace */
Michael Widenius's avatar
Michael Widenius committed
7939 7940
    test_flags|= TEST_SIGINT;
    opt_stack_trace= 1;
7941 7942
    test_flags&= ~TEST_CORE_ON_SIGNAL;
  }
7943
  /* Set global MyISAM variables from delay_key_write_options */
7944
  fix_delay_key_write(0, 0, OPT_GLOBAL);
7945

7946
#ifndef EMBEDDED_LIBRARY
7947 7948
  if (mysqld_chroot)
    set_root(mysqld_chroot);
7949
#else
7950
  thread_handling = SCHEDULER_NO_THREADS;
7951 7952
  max_allowed_packet= global_system_variables.max_allowed_packet;
  net_buffer_length= global_system_variables.net_buffer_length;
7953
#endif
7954 7955
  if (fix_paths())
    return 1;
unknown's avatar
unknown committed
7956

unknown's avatar
unknown committed
7957 7958 7959 7960
  /*
    Set some global variables from the global_system_variables
    In most cases the global variables will not be used
  */
7961
  my_disable_locking= myisam_single_user= test(opt_external_locking == 0);
unknown's avatar
unknown committed
7962
  my_default_record_cache_size=global_system_variables.read_buff_size;
unknown's avatar
unknown committed
7963

7964
  /*
7965 7966 7967
    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.
7968 7969 7970 7971 7972 7973
  */
  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;
7974 7975
  if (my_assert_on_error)
    debug_assert_if_crashed_table= 1;
7976

7977 7978
  global_system_variables.long_query_time= (ulonglong)
    (global_system_variables.long_query_time_double * 1e6);
7979

7980 7981
  if (opt_short_log_format)
    opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT;
7982

7983
  if (init_global_datetime_format(MYSQL_TIMESTAMP_DATE,
7984
                                  &global_date_format) ||
7985
      init_global_datetime_format(MYSQL_TIMESTAMP_TIME,
7986
                                  &global_time_format) ||
7987
      init_global_datetime_format(MYSQL_TIMESTAMP_DATETIME,
7988
                                  &global_datetime_format))
7989
    return 1;
7990

unknown's avatar
unknown committed
7991
#ifdef EMBEDDED_LIBRARY
Sergei Golubchik's avatar
Sergei Golubchik committed
7992 7993
  one_thread_scheduler(thread_scheduler);
  one_thread_scheduler(extra_thread_scheduler);
unknown's avatar
unknown committed
7994
#else
7995 7996 7997 7998 7999 8000 8001 8002

#ifdef _WIN32
  /* workaround: disable thread pool on XP */
  if (GetProcAddress(GetModuleHandle("kernel32"),"CreateThreadpool") == 0 &&
      thread_handling > SCHEDULER_NO_THREADS)
    thread_handling = SCHEDULER_ONE_THREAD_PER_CONNECTION;
#endif

8003
  if (thread_handling <= SCHEDULER_ONE_THREAD_PER_CONNECTION)
Sergei Golubchik's avatar
Sergei Golubchik committed
8004
    one_thread_per_connection_scheduler(thread_scheduler, &max_connections,
8005
                                        &connection_count);
8006
  else if (thread_handling == SCHEDULER_NO_THREADS)
Sergei Golubchik's avatar
Sergei Golubchik committed
8007
    one_thread_scheduler(thread_scheduler);
unknown's avatar
unknown committed
8008
  else
8009 8010 8011
    pool_of_threads_scheduler(thread_scheduler,  &max_connections,
                                        &connection_count); 

Sergei Golubchik's avatar
Sergei Golubchik committed
8012
  one_thread_per_connection_scheduler(extra_thread_scheduler,
8013 8014
                                      &extra_max_connections,
                                      &extra_connection_count);
unknown's avatar
unknown committed
8015
#endif
8016 8017 8018 8019 8020

  global_system_variables.engine_condition_pushdown=
    test(global_system_variables.optimizer_switch &
         OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN);

8021 8022
  opt_readonly= read_only;

8023 8024 8025 8026 8027 8028 8029
  /*
    If max_long_data_size is not specified explicitly use
    value of max_allowed_packet.
  */
  if (!max_long_data_size_used)
    max_long_data_size= global_system_variables.max_allowed_packet;

8030
  /* Rember if max_user_connections was 0 at startup */
Sergei Golubchik's avatar
Sergei Golubchik committed
8031
  max_user_connections_checking= global_system_variables.max_user_connections != 0;
8032
  return 0;
unknown's avatar
unknown committed
8033 8034 8035
}


8036 8037 8038 8039 8040 8041 8042
/*
  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
8043
void set_server_version(void)
8044 8045
{
  char *end= strxmov(server_version, MYSQL_SERVER_VERSION,
8046
                     MYSQL_SERVER_SUFFIX_STR, NullS);
8047 8048 8049 8050
#ifdef EMBEDDED_LIBRARY
  end= strmov(end, "-embedded");
#endif
#ifndef DBUG_OFF
8051
  if (!strstr(MYSQL_SERVER_SUFFIX_STR, "-debug"))
8052 8053
    end= strmov(end, "-debug");
#endif
8054
  if (opt_log || opt_slow_log || opt_bin_log)
8055 8056 8057 8058
    strmov(end, "-log");                        // This may slow down system
}


unknown's avatar
unknown committed
8059 8060 8061
static char *get_relative_path(const char *path)
{
  if (test_if_hard_path(path) &&
8062
      is_prefix(path,DEFAULT_MYSQL_HOME) &&
unknown's avatar
unknown committed
8063 8064
      strcmp(DEFAULT_MYSQL_HOME,FN_ROOTDIR))
  {
unknown's avatar
unknown committed
8065
    path+=(uint) strlen(DEFAULT_MYSQL_HOME);
8066
    while (*path == FN_LIBCHAR || *path == FN_LIBCHAR2)
unknown's avatar
unknown committed
8067 8068 8069 8070 8071 8072
      path++;
  }
  return (char*) path;
}


unknown's avatar
unknown committed
8073
/**
8074 8075
  Fix filename and replace extension where 'dir' is relative to
  mysql_real_data_home.
unknown's avatar
unknown committed
8076 8077
  @return
    1 if len(path) > FN_REFLEN
8078 8079 8080
*/

bool
8081
fn_format_relative_to_data_home(char * to, const char *name,
8082 8083 8084 8085 8086 8087 8088 8089 8090 8091
				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,
8092
		    MY_APPEND_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH);
8093 8094 8095
}


8096 8097 8098 8099 8100 8101 8102 8103 8104 8105 8106 8107 8108 8109
/**
  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];
8110
  size_t opt_secure_file_priv_len;
8111 8112 8113 8114 8115 8116
  /*
    All paths are secure if opt_secure_file_path is 0
  */
  if (!opt_secure_file_priv)
    return TRUE;

8117 8118
  opt_secure_file_priv_len= strlen(opt_secure_file_priv);

Georgi Kodinov's avatar
Georgi Kodinov committed
8119 8120 8121
  if (strlen(path) >= FN_REFLEN)
    return FALSE;

8122 8123 8124 8125 8126
  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
8127
    size_t length= dirname_length(path);        // Guaranteed to be < FN_REFLEN
8128 8129 8130 8131 8132 8133
    memcpy(buff2, path, length);
    buff2[length]= '\0';
    if (length == 0 || my_realpath(buff1, buff2, 0))
      return FALSE;
  }
  convert_dirname(buff2, buff1, NullS);
8134 8135 8136 8137 8138 8139 8140 8141 8142 8143 8144 8145 8146 8147
  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;
  }
8148 8149 8150
  return TRUE;
}

Michael Widenius's avatar
Michael Widenius committed
8151

8152
static int fix_paths(void)
unknown's avatar
unknown committed
8153
{
8154
  char buff[FN_REFLEN],*pos;
8155 8156
  DBUG_ENTER("fix_paths");

8157
  convert_dirname(mysql_home,mysql_home,NullS);
8158
  /* Resolve symlinks to allow 'mysql_home' to be a relative symlink */
8159
  my_realpath(mysql_home,mysql_home,MYF(0));
8160 8161 8162 8163 8164 8165 8166
  /* Ensure that mysql_home ends in FN_LIBCHAR */
  pos=strend(mysql_home);
  if (pos[-1] != FN_LIBCHAR)
  {
    pos[0]= FN_LIBCHAR;
    pos[1]= 0;
  }
8167
  convert_dirname(lc_messages_dir, lc_messages_dir, NullS);
8168
  convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
unknown's avatar
unknown committed
8169 8170
  (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);
8171
  (void) my_load_path(pidfile_name, pidfile_name_ptr, mysql_real_data_home);
Marc Alff's avatar
Marc Alff committed
8172

Sergei Golubchik's avatar
Sergei Golubchik committed
8173 8174 8175
  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);
8176
  opt_plugin_dir_ptr= opt_plugin_dir;
Sergei Golubchik's avatar
Sergei Golubchik committed
8177
  pidfile_name_ptr= pidfile_name;
unknown's avatar
unknown committed
8178

8179 8180 8181 8182 8183 8184
  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
8185
  char *sharedir=get_relative_path(SHAREDIR);
unknown's avatar
unknown committed
8186
  if (test_if_hard_path(sharedir))
unknown's avatar
unknown committed
8187
    strmake(buff,sharedir,sizeof(buff)-1);		/* purecov: tested */
unknown's avatar
unknown committed
8188
  else
unknown's avatar
unknown committed
8189
    strxnmov(buff,sizeof(buff)-1,mysql_home,sharedir,NullS);
8190
  convert_dirname(buff,buff,NullS);
8191
  (void) my_load_path(lc_messages_dir, lc_messages_dir, buff);
unknown's avatar
unknown committed
8192 8193

  /* If --character-sets-dir isn't given, use shared library dir */
8194 8195 8196
  if (charsets_dir)
    strmake(mysql_charsets_dir, charsets_dir, sizeof(mysql_charsets_dir)-1);
  else
unknown's avatar
unknown committed
8197 8198
    strxnmov(mysql_charsets_dir, sizeof(mysql_charsets_dir)-1, buff,
	     CHARSET_DIR, NullS);
unknown's avatar
unknown committed
8199
  (void) my_load_path(mysql_charsets_dir, mysql_charsets_dir, buff);
8200
  convert_dirname(mysql_charsets_dir, mysql_charsets_dir, NullS);
unknown's avatar
unknown committed
8201
  charsets_dir=mysql_charsets_dir;
unknown's avatar
unknown committed
8202

unknown's avatar
unknown committed
8203
  if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir))
8204
    DBUG_RETURN(1);
8205 8206
  if (!opt_mysql_tmpdir)
    opt_mysql_tmpdir= mysql_tmpdir;
unknown's avatar
SCRUM  
unknown committed
8207
#ifdef HAVE_REPLICATION
8208
  if (!slave_load_tmpdir)
8209
    slave_load_tmpdir= mysql_tmpdir;
8210
#endif /* HAVE_REPLICATION */
8211 8212 8213
  /*
    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
8214
  */
8215 8216
  if (opt_secure_file_priv)
  {
8217 8218
    if (*opt_secure_file_priv == 0)
    {
8219
      my_free(opt_secure_file_priv);
8220 8221 8222 8223
      opt_secure_file_priv= 0;
    }
    else
    {
8224 8225
      if (strlen(opt_secure_file_priv) >= FN_REFLEN)
        opt_secure_file_priv[FN_REFLEN-1]= '\0';
8226
      if (my_realpath(buff, opt_secure_file_priv, 0))
8227 8228
      {
        sql_print_warning("Failed to normalize the argument for --secure-file-priv.");
8229
        DBUG_RETURN(1);
8230
      }
8231
      char *secure_file_real_path= (char *)my_malloc(FN_REFLEN, MYF(MY_FAE));
8232
      convert_dirname(secure_file_real_path, buff, NullS);
8233
      my_free(opt_secure_file_priv);
8234 8235
      opt_secure_file_priv= secure_file_real_path;
    }
8236
  }
8237
  DBUG_RETURN(0);
unknown's avatar
unknown committed
8238 8239
}

unknown's avatar
unknown committed
8240 8241
/**
  Check if file system used for databases is case insensitive.
8242

unknown's avatar
unknown committed
8243
  @param dir_name			Directory to test
8244

8245 8246 8247
  @retval -1  Don't know (Test failed)
  @retval  0   File system is case sensitive
  @retval  1   File system is case insensitive
8248 8249 8250 8251 8252 8253 8254 8255
*/

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;
8256
  DBUG_ENTER("test_if_case_insensitive");
8257 8258 8259 8260 8261

  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
8262 8263 8264
  mysql_file_delete(key_file_casetest, buff2, MYF(0));
  if ((file= mysql_file_create(key_file_casetest,
                               buff, 0666, O_RDWR, MYF(0))) < 0)
8265
  {
8266
    if (!opt_abort)
8267
      sql_print_warning("Can't create test file %s", buff);
8268
    DBUG_RETURN(-1);
8269
  }
Marc Alff's avatar
Marc Alff committed
8270 8271
  mysql_file_close(file, MYF(0));
  if (mysql_file_stat(key_file_casetest, buff2, &stat_info, MYF(0)))
8272
    result= 1;					// Can access file
Marc Alff's avatar
Marc Alff committed
8273
  mysql_file_delete(key_file_casetest, buff, MYF(MY_WME));
8274 8275
  DBUG_PRINT("exit", ("result: %d", result));
  DBUG_RETURN(result);
8276 8277 8278
}


8279 8280
#ifndef EMBEDDED_LIBRARY

unknown's avatar
unknown committed
8281 8282 8283
/**
  Create file to store pid number.
*/
8284 8285 8286
static void create_pid_file()
{
  File file;
Marc Alff's avatar
Marc Alff committed
8287 8288
  if ((file= mysql_file_create(key_file_pid, pidfile_name, 0664,
                               O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0)
8289
  {
8290
    char buff[MAX_BIGINT_WIDTH + 1], *end;
8291
    end= int10_to_str((long) getpid(), buff, 10);
unknown's avatar
unknown committed
8292
    *end++= '\n';
Marc Alff's avatar
Marc Alff committed
8293 8294
    if (!mysql_file_write(file, (uchar*) buff, (uint) (end-buff),
                          MYF(MY_WME | MY_NABP)))
8295
    {
Marc Alff's avatar
Marc Alff committed
8296
      mysql_file_close(file, MYF(0));
8297
      pid_file_created= true;
8298 8299
      return;
    }
Marc Alff's avatar
Marc Alff committed
8300
    mysql_file_close(file, MYF(0));
8301
  }
8302
  sql_perror("Can't start server: can't create PID file");
unknown's avatar
foo1  
unknown committed
8303
  exit(1);
8304
}
8305
#endif /* EMBEDDED_LIBRARY */
8306

Marc Alff's avatar
Marc Alff committed
8307

8308 8309 8310 8311 8312
/**
  Remove the process' pid file.
  
  @param  flags  file operation flags
*/
Marc Alff's avatar
Marc Alff committed
8313

8314 8315 8316 8317 8318 8319 8320 8321 8322 8323 8324
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
8325 8326


unknown's avatar
unknown committed
8327
/** Clear most status variables. */
8328 8329
void refresh_status(THD *thd)
{
Marc Alff's avatar
Marc Alff committed
8330
  mysql_mutex_lock(&LOCK_status);
8331

8332
  /* Add thread's status variabes to global status */
8333
  add_to_status(&global_status_var, &thd->status_var);
8334 8335

  /* Reset thread's status variables */
8336
  bzero((uchar*) &thd->status_var, sizeof(thd->status_var));
8337 8338
  bzero((uchar*) &thd->org_status_var, sizeof(thd->org_status_var)); 
  thd->start_bytes_received= 0;
8339

8340
  /* Reset some global variables */
unknown's avatar
unknown committed
8341
  reset_status_vars();
8342

8343
  /* Reset the counters of all key caches (default and named). */
8344
  process_key_caches(reset_key_cache_counters, 0);
8345
  flush_status_time= time((time_t*) 0);
Marc Alff's avatar
Marc Alff committed
8346
  mysql_mutex_unlock(&LOCK_status);
8347 8348 8349 8350 8351 8352 8353

  /*
    Set max_used_connections to the number of currently open
    connections.  Lock LOCK_thread_count out of LOCK_status to avoid
    deadlocks.  Status reset becomes not atomic, but status data is
    not exact anyway.
  */
Marc Alff's avatar
Marc Alff committed
8354
  mysql_mutex_lock(&LOCK_thread_count);
8355
  max_used_connections= thread_count-delayed_insert_threads;
Marc Alff's avatar
Marc Alff committed
8356
  mysql_mutex_unlock(&LOCK_thread_count);
8357 8358 8359
}


8360
/*****************************************************************************
unknown's avatar
unknown committed
8361 8362
  Instantiate variables for missing storage engines
  This section should go away soon
8363 8364
*****************************************************************************/

unknown's avatar
unknown committed
8365
/*****************************************************************************
8366
  Instantiate templates
unknown's avatar
unknown committed
8367 8368
*****************************************************************************/

8369
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
unknown's avatar
unknown committed
8370 8371 8372 8373
/* Used templates */
template class I_List<THD>;
template class I_List_iterator<THD>;
template class I_List<i_string>;
8374
template class I_List<i_string_pair>;
8375 8376
template class I_List<Statement>;
template class I_List_iterator<Statement>;
unknown's avatar
unknown committed
8377
#endif
Marc Alff's avatar
Marc Alff committed
8378