mysqld.cc 274 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

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

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

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

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

/*
  Used with --help for detailed option
*/
297
static my_bool opt_verbose= 0;
298

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

unknown's avatar
unknown committed
307 308
/* static variables */

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

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

332 333 334 335
#ifdef HAVE_NPTL
volatile sig_atomic_t ld_assume_kernel_is_set= 0;
#endif

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

unknown's avatar
unknown committed
361
/* Global variables */
unknown's avatar
unknown committed
362

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

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

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

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

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

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

500 501 502 503 504
/*
  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
505

506 507 508 509
/* Limits for internal temporary tables (MyISAM or Aria) */
uint internal_tmp_table_max_key_length;
uint internal_tmp_table_max_key_segments;

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

539 540 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
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
572

573
time_t server_start_time, flush_status_time;
574

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

590 591
DATE_TIME_FORMAT global_date_format, global_datetime_format, global_time_format;
Time_zone *default_tz;
592

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

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

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

unknown's avatar
unknown committed
616
I_List<THD> threads;
unknown's avatar
unknown committed
617 618
Rpl_filter* rpl_filter;
Rpl_filter* binlog_filter;
unknown's avatar
unknown committed
619

unknown's avatar
unknown committed
620 621
struct system_variables global_system_variables;
struct system_variables max_system_variables;
unknown's avatar
Merge  
unknown committed
622
struct system_status_var global_status_var;
unknown's avatar
unknown committed
623

unknown's avatar
unknown committed
624
MY_TMPDIR mysql_tmpdir_list;
625
MY_BITMAP temp_pool;
unknown's avatar
unknown committed
626

627 628
CHARSET_INFO *system_charset_info, *files_charset_info ;
CHARSET_INFO *national_charset_info, *table_alias_charset;
unknown's avatar
unknown committed
629
CHARSET_INFO *character_set_filesystem;
Marc Alff's avatar
Marc Alff committed
630
CHARSET_INFO *error_message_charset_info;
631

632
MY_LOCALE *my_default_lc_messages;
633 634
MY_LOCALE *my_default_lc_time_names;

635
SHOW_COMP_OPTION have_ssl, have_symlink, have_dlopen, have_query_cache;
636
SHOW_COMP_OPTION have_geometry, have_rtree_keys;
unknown's avatar
unknown committed
637
SHOW_COMP_OPTION have_crypt, have_compress;
638
SHOW_COMP_OPTION have_profiling;
unknown's avatar
unknown committed
639 640

/* Thread specific variables */
641

unknown's avatar
unknown committed
642
pthread_key(MEM_ROOT**,THR_MALLOC);
unknown's avatar
unknown committed
643
pthread_key(THD*, THR_THD);
Marc Alff's avatar
Marc Alff committed
644
mysql_mutex_t LOCK_thread_count;
645
mysql_mutex_t
Sergei Golubchik's avatar
Sergei Golubchik committed
646
  LOCK_status, LOCK_error_log, LOCK_short_uuid_generator,
Marc Alff's avatar
Marc Alff committed
647 648 649 650 651
  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
652 653 654

mysql_mutex_t LOCK_stats, LOCK_global_user_client_stats,
              LOCK_global_table_stats, LOCK_global_index_stats;
655

unknown's avatar
unknown committed
656
/**
657 658 659 660 661 662
  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
663
mysql_mutex_t LOCK_prepared_stmt_count;
664
#ifdef HAVE_OPENSSL
Marc Alff's avatar
Marc Alff committed
665
mysql_mutex_t LOCK_des_key_file;
666
#endif
Marc Alff's avatar
Marc Alff committed
667 668
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
669
mysql_cond_t COND_thread_count;
unknown's avatar
unknown committed
670 671
pthread_t signal_thread;
pthread_attr_t connection_attrib;
Marc Alff's avatar
Marc Alff committed
672 673
mysql_mutex_t LOCK_server_started;
mysql_cond_t COND_server_started;
unknown's avatar
unknown committed
674 675

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

677 678
File_parser_dummy_hook file_parser_dummy_hook;

unknown's avatar
unknown committed
679
/* replication parameters, if master_host is not NULL, we are a slave */
680
uint report_port= 0;
unknown's avatar
unknown committed
681
ulong master_retry_count=0;
682
char *master_info_file;
unknown's avatar
unknown committed
683
char *relay_log_info_file, *report_user, *report_password, *report_host;
unknown's avatar
unknown committed
684
char *opt_relay_logname = 0, *opt_relaylog_index_name=0;
685
char *opt_logname, *opt_slow_logname, *opt_bin_logname;
unknown's avatar
unknown committed
686 687 688

/* Static variables */

689
static volatile sig_atomic_t kill_in_progress;
Michael Widenius's avatar
Michael Widenius committed
690 691
my_bool opt_stack_trace;
my_bool opt_expect_abort= 0;
692
static my_bool opt_bootstrap, opt_myisam_log;
unknown's avatar
unknown committed
693
static int cleanup_done;
694
static ulong opt_specialflag;
Sergei Golubchik's avatar
Sergei Golubchik committed
695
static char *opt_binlog_index_name;
696
char *mysql_home_ptr, *pidfile_name_ptr;
Marc Alff's avatar
Marc Alff committed
697
/** Initial command line arguments (count), after load_defaults().*/
unknown's avatar
unknown committed
698
static int defaults_argc;
Marc Alff's avatar
Marc Alff committed
699 700 701 702 703 704 705 706
/**
  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
707
static char **defaults_argv;
Marc Alff's avatar
Marc Alff committed
708 709 710 711
/** 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
712

713 714 715
int orig_argc;
char **orig_argv;

716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735
#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
736
  key_master_info_sleep_lock,
737 738
  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
739
  key_relay_log_info_sleep_lock,
740 741 742 743 744 745 746
  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
747 748 749 750
  key_LOCK_global_index_stats,
  key_LOCK_wakeup_ready;

PSI_mutex_key key_LOCK_prepare_ordered, key_LOCK_commit_ordered;
751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789

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
790
  { &key_LOCK_wakeup_ready, "THD::LOCK_wakeup_ready", 0},
791 792
  { &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
793
  { &key_LOCK_uuid_short_generator, "LOCK_uuid_short_generator", PSI_FLAG_GLOBAL},
794 795 796
  { &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
797
  { &key_master_info_sleep_lock, "Master_info::sleep_lock", 0},
798 799 800 801
  { &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
802
  { &key_relay_log_info_sleep_lock, "Relay_log_info::sleep_lock", 0},
803 804 805
  { &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
806 807
  { &key_LOCK_prepare_ordered, "LOCK_prepare_ordered", PSI_FLAG_GLOBAL},
  { &key_LOCK_commit_ordered, "LOCK_commit_ordered", PSI_FLAG_GLOBAL},
808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830
  { &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
831
PSI_cond_key key_PAGE_cond, key_COND_active, key_COND_pool;
832 833 834 835 836 837 838 839
#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
840
  key_master_info_sleep_cond,
841 842
  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
843
  key_relay_log_info_sleep_cond,
844
  key_TABLE_SHARE_cond, key_user_level_lock_cond,
845 846
  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
847
PSI_cond_key key_RELAYLOG_update_cond, key_COND_wakeup_ready;
848 849
PSI_cond_key key_RELAYLOG_COND_queue_busy;
PSI_cond_key key_TC_LOG_MMAP_COND_queue_busy;
850 851 852 853 854 855 856 857 858 859

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},
860
  { &key_TC_LOG_MMAP_COND_queue_busy, "TC_LOG_MMAP::COND_queue_busy", 0},
861 862 863
#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},
864
  { &key_BINLOG_COND_queue_busy, "MYSQL_BIN_LOG::COND_queue_busy", 0},
865
  { &key_RELAYLOG_update_cond, "MYSQL_RELAY_LOG::update_cond", 0},
866
  { &key_RELAYLOG_COND_queue_busy, "MYSQL_RELAY_LOG::COND_queue_busy", 0},
Sergei Golubchik's avatar
Sergei Golubchik committed
867
  { &key_COND_wakeup_ready, "THD::COND_wakeup_ready", 0},
868 869 870 871 872 873 874 875 876 877
  { &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
878
  { &key_master_info_sleep_cond, "Master_info::sleep_cond", 0},
879 880 881 882
  { &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
883
  { &key_relay_log_info_sleep_cond, "Relay_log_info::sleep_cond", 0},
884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 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
  { &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
993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 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
/*
  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:
1051 1052 1053 1054 1055 1056 1057 1058 1059
    /*
      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
1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 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
    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;

1134
#ifndef EMBEDDED_LIBRARY
Marc Alff's avatar
Marc Alff committed
1135 1136 1137 1138 1139
/**
  Error reporter that buffer log messages.
  @param level          log message level
  @param format         log message format string
*/
1140 1141 1142
C_MODE_START
static void buffered_option_error_reporter(enum loglevel level,
                                           const char *format, ...)
Marc Alff's avatar
Marc Alff committed
1143 1144 1145 1146 1147 1148 1149 1150 1151
{
  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);
}
1152 1153
C_MODE_END
#endif /* !EMBEDDED_LIBRARY */
Marc Alff's avatar
Marc Alff committed
1154 1155
#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */

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

unknown's avatar
unknown committed
1159 1160 1161 1162 1163
#ifndef EMBEDDED_LIBRARY
struct passwd *user_info;
static pthread_t select_thread;
#endif

unknown's avatar
unknown committed
1164 1165
/* OS specific variables */

unknown's avatar
unknown committed
1166 1167 1168
#ifdef __WIN__
#undef	 getpid
#include <process.h>
unknown's avatar
unknown committed
1169

Marc Alff's avatar
Marc Alff committed
1170
static mysql_cond_t COND_handler_count;
unknown's avatar
unknown committed
1171 1172 1173 1174 1175
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
1176
#if !defined(EMBEDDED_LIBRARY)
unknown's avatar
unknown committed
1177
static HANDLE hEventShutdown;
1178
static char shutdown_event_name[40];
unknown's avatar
unknown committed
1179
#include "nt_servc.h"
unknown's avatar
unknown committed
1180
static	 NTService  Service;	      ///< Service object for WinNT
unknown's avatar
unknown committed
1181 1182 1183
#endif /* EMBEDDED_LIBRARY */
#endif /* __WIN__ */

Vladislav Vaintroub's avatar
Vladislav Vaintroub committed
1184
#ifdef _WIN32
1185
static char pipe_name[512];
unknown's avatar
unknown committed
1186 1187 1188
static SECURITY_ATTRIBUTES saPipeSecurity;
static SECURITY_DESCRIPTOR sdPipeDescriptor;
static HANDLE hPipe = INVALID_HANDLE_VALUE;
unknown's avatar
unknown committed
1189
#endif
unknown's avatar
unknown committed
1190

unknown's avatar
unknown committed
1191
#ifndef EMBEDDED_LIBRARY
1192
bool mysqld_embedded=0;
unknown's avatar
unknown committed
1193
#else
1194
bool mysqld_embedded=1;
unknown's avatar
unknown committed
1195 1196
#endif

1197 1198
static my_bool plugins_are_initialized= FALSE;

unknown's avatar
unknown committed
1199
#ifndef DBUG_OFF
1200
static const char* default_dbug_option;
unknown's avatar
unknown committed
1201
#endif
1202
static const char *current_dbug_option="disabled";
unknown's avatar
unknown committed
1203
#ifdef HAVE_LIBWRAP
1204
const char *libwrapName= NULL;
1205 1206
int allow_severity = LOG_INFO;
int deny_severity = LOG_WARNING;
unknown's avatar
unknown committed
1207 1208 1209 1210 1211 1212 1213
#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;
1214
my_bool opt_enable_shared_memory;
1215
HANDLE smem_event_connect_request= 0;
unknown's avatar
unknown committed
1216 1217
#endif

1218 1219 1220 1221
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
1222 1223 1224
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
1225

unknown's avatar
unknown committed
1226
#ifdef HAVE_OPENSSL
1227
#include <openssl/crypto.h>
unknown's avatar
unknown committed
1228
#ifndef HAVE_YASSL
1229 1230
typedef struct CRYPTO_dynlock_value
{
Marc Alff's avatar
Marc Alff committed
1231
  mysql_rwlock_t lock;
1232 1233 1234 1235 1236 1237 1238 1239
} 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
1240
#endif
unknown's avatar
unknown committed
1241
char *des_key_file;
Konstantin Osipov's avatar
Konstantin Osipov committed
1242
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
1243
struct st_VioSSLFd *ssl_acceptor_fd;
Konstantin Osipov's avatar
Konstantin Osipov committed
1244
#endif
unknown's avatar
unknown committed
1245 1246
#endif /* HAVE_OPENSSL */

1247 1248 1249 1250
/**
  Number of currently active user connections. The variable is protected by
  LOCK_connection_count.
*/
1251
uint connection_count= 0, extra_connection_count= 0;
unknown's avatar
unknown committed
1252 1253 1254

/* Function declarations */

1255
pthread_handler_t signal_hand(void *arg);
1256
static int mysql_init_variables(void);
Marc Alff's avatar
Marc Alff committed
1257 1258
static int get_options(int *argc_ptr, char ***argv_ptr);
static bool add_terminator(DYNAMIC_ARRAY *options);
1259
extern "C" my_bool mysqld_get_one_option(int, const struct my_option *, char *);
1260
static int init_thread_environment();
unknown's avatar
unknown committed
1261
static char *get_relative_path(const char *path);
1262
static int fix_paths(void);
1263 1264 1265 1266
void handle_connections_sockets();
#ifdef _WIN32
pthread_handler_t handle_connections_sockets_thread(void *arg);
#endif
1267
pthread_handler_t kill_server_thread(void *arg);
Marc Alff's avatar
Marc Alff committed
1268
static void bootstrap(MYSQL_FILE *file);
unknown's avatar
unknown committed
1269
static bool read_init_file(char *file_name);
Vladislav Vaintroub's avatar
Vladislav Vaintroub committed
1270
#ifdef _WIN32
1271
pthread_handler_t handle_connections_namedpipes(void *arg);
unknown's avatar
unknown committed
1272
#endif
1273
#ifdef HAVE_SMEM
1274
pthread_handler_t handle_connections_shared_memory(void *arg);
1275
#endif
1276
pthread_handler_t handle_slave(void *arg);
unknown's avatar
unknown committed
1277
static void clean_up(bool print_message);
1278 1279 1280
static int test_if_case_insensitive(const char *dir_name);

#ifndef EMBEDDED_LIBRARY
1281
static void usage(void);
1282 1283
static void start_signal_handler(void);
static void close_server_sock();
unknown's avatar
unknown committed
1284
static void clean_up_mutexes(void);
1285
static void wait_for_signal_thread_to_end(void);
1286
static void create_pid_file();
1287
static void mysqld_exit(int exit_code) __attribute__((noreturn));
1288
#endif
Konstantin Osipov's avatar
Konstantin Osipov committed
1289
static void end_ssl();
1290

1291 1292

#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308
/****************************************************************************
** 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 */
1309
#if !defined(__WIN__)
unknown's avatar
unknown committed
1310 1311
  DBUG_PRINT("quit", ("waiting for select thread: 0x%lx",
                      (ulong) select_thread));
Marc Alff's avatar
Marc Alff committed
1312
  mysql_mutex_lock(&LOCK_thread_count);
unknown's avatar
unknown committed
1313 1314 1315 1316 1317 1318

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

unknown's avatar
unknown committed
1321
#ifndef DONT_USE_THR_ALARM
1322
    if (pthread_kill(select_thread, thr_client_alarm))
unknown's avatar
unknown committed
1323 1324
      break;					// allready dead
#endif
1325
    set_timespec(abstime, 2);
1326
    for (uint tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
unknown's avatar
unknown committed
1327
    {
Marc Alff's avatar
Marc Alff committed
1328 1329
      error= mysql_cond_timedwait(&COND_thread_count, &LOCK_thread_count,
                                  &abstime);
unknown's avatar
unknown committed
1330 1331 1332 1333
      if (error != EINTR)
	break;
    }
#ifdef EXTRA_DEBUG
1334
    if (error != 0 && error != ETIMEDOUT && !count++)
Marc Alff's avatar
Marc Alff committed
1335
      sql_print_error("Got error %d from mysql_cond_timedwait", error);
unknown's avatar
unknown committed
1336
#endif
unknown's avatar
unknown committed
1337
    close_server_sock();
unknown's avatar
unknown committed
1338
  }
Marc Alff's avatar
Marc Alff committed
1339
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
1340 1341 1342 1343 1344
#endif /* __WIN__ */


  /* Abort listening to new connections */
  DBUG_PRINT("quit",("Closing sockets"));
unknown's avatar
Merge  
unknown committed
1345
  if (!opt_disable_networking )
unknown's avatar
unknown committed
1346
  {
1347
    if (base_ip_sock != INVALID_SOCKET)
unknown's avatar
unknown committed
1348
    {
Sergei Golubchik's avatar
c  
Sergei Golubchik committed
1349
      (void) mysql_socket_shutdown(base_ip_sock, SHUT_RDWR);
1350 1351 1352 1353
      (void) closesocket(base_ip_sock);
      base_ip_sock= INVALID_SOCKET;
    }
    if (extra_ip_sock != INVALID_SOCKET)
unknown's avatar
unknown committed
1354
    {
Sergei Golubchik's avatar
c  
Sergei Golubchik committed
1355
      (void) mysql_socket_shutdown(extra_ip_sock, SHUT_RDWR);
1356 1357
      (void) closesocket(extra_ip_sock);
      extra_ip_sock= INVALID_SOCKET;
unknown's avatar
unknown committed
1358 1359
    }
  }
Vladislav Vaintroub's avatar
Vladislav Vaintroub committed
1360
#ifdef _WIN32
unknown's avatar
unknown committed
1361
  if (hPipe != INVALID_HANDLE_VALUE && opt_enable_named_pipe)
unknown's avatar
unknown committed
1362
  {
unknown's avatar
merge  
unknown committed
1363
    HANDLE temp;
unknown's avatar
Merge  
unknown committed
1364
    DBUG_PRINT("quit", ("Closing named pipes") );
1365

unknown's avatar
merge  
unknown committed
1366
    /* Create connection to the handle named pipe handler to break the loop */
1367
    if ((temp = CreateFile(pipe_name,
unknown's avatar
merge  
unknown committed
1368 1369 1370 1371 1372 1373 1374
			   GENERIC_READ | GENERIC_WRITE,
			   0,
			   NULL,
			   OPEN_EXISTING,
			   0,
			   NULL )) != INVALID_HANDLE_VALUE)
    {
1375
      WaitNamedPipe(pipe_name, 1000);
unknown's avatar
merge  
unknown committed
1376 1377 1378 1379 1380 1381
      DWORD dwMode = PIPE_READMODE_BYTE | PIPE_WAIT;
      SetNamedPipeHandleState(temp, &dwMode, NULL, NULL);
      CancelIo(temp);
      DisconnectNamedPipe(temp);
      CloseHandle(temp);
    }
unknown's avatar
unknown committed
1382 1383 1384 1385 1386
  }
#endif
#ifdef HAVE_SYS_UN_H
  if (unix_sock != INVALID_SOCKET)
  {
Sergei Golubchik's avatar
c  
Sergei Golubchik committed
1387
    (void) mysql_socket_shutdown(unix_sock, SHUT_RDWR);
unknown's avatar
unknown committed
1388
    (void) closesocket(unix_sock);
1389
    (void) unlink(mysqld_unix_port);
unknown's avatar
unknown committed
1390 1391 1392
    unix_sock= INVALID_SOCKET;
  }
#endif
1393
  end_thr_alarm(0);			 // Abort old alarms.
unknown's avatar
unknown committed
1394

1395 1396 1397 1398 1399
  /*
    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
1400 1401

  THD *tmp;
Marc Alff's avatar
Marc Alff committed
1402
  mysql_mutex_lock(&LOCK_thread_count); // For unlink from list
unknown's avatar
unknown committed
1403 1404 1405 1406 1407 1408

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

1413
    tmp->killed= KILL_SERVER_HARD;
Sergei Golubchik's avatar
Sergei Golubchik committed
1414
    MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (tmp));
1415
    mysql_mutex_lock(&tmp->LOCK_thd_data);
unknown's avatar
unknown committed
1416 1417 1418
    if (tmp->mysys_var)
    {
      tmp->mysys_var->abort=1;
Marc Alff's avatar
Marc Alff committed
1419
      mysql_mutex_lock(&tmp->mysys_var->mutex);
unknown's avatar
unknown committed
1420
      if (tmp->mysys_var->current_cond)
unknown's avatar
unknown committed
1421
      {
1422 1423 1424
        uint i;
        for (i=0; i < 2; i++)
        {
Sergei Golubchik's avatar
Sergei Golubchik committed
1425 1426
          int ret= mysql_mutex_trylock(tmp->mysys_var->current_mutex);
          mysql_cond_broadcast(tmp->mysys_var->current_cond);
1427 1428 1429
          if (!ret)
          {
            /* Thread has surely got the signal, unlock and abort */
Sergei Golubchik's avatar
Sergei Golubchik committed
1430
            mysql_mutex_unlock(tmp->mysys_var->current_mutex);
1431 1432 1433 1434
            break;
          }
          sleep(1);
        }
unknown's avatar
unknown committed
1435
      }
Marc Alff's avatar
Marc Alff committed
1436
      mysql_mutex_unlock(&tmp->mysys_var->mutex);
unknown's avatar
unknown committed
1437
    }
1438
    mysql_mutex_unlock(&tmp->LOCK_thd_data);
unknown's avatar
unknown committed
1439
  }
Marc Alff's avatar
Marc Alff committed
1440
  mysql_mutex_unlock(&LOCK_thread_count); // For unlink from list
unknown's avatar
unknown committed
1441

1442
  Events::deinit();
1443 1444
  end_slave();

1445 1446 1447
  /* Give threads time to die. */
  for (int i= 0; thread_count && i < 100; i++)
    my_sleep(20000);
unknown's avatar
unknown committed
1448

1449 1450 1451 1452 1453
  /*
    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
1454 1455 1456 1457

  for (;;)
  {
    DBUG_PRINT("quit",("Locking LOCK_thread_count"));
Marc Alff's avatar
Marc Alff committed
1458
    mysql_mutex_lock(&LOCK_thread_count); // For unlink from list
unknown's avatar
unknown committed
1459 1460 1461
    if (!(tmp=threads.get()))
    {
      DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
Marc Alff's avatar
Marc Alff committed
1462
      mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
1463 1464 1465
      break;
    }
#ifndef __bsdi__				// Bug in BSDI kernel
1466
    if (tmp->vio_ok())
unknown's avatar
unknown committed
1467
    {
1468
      if (global_system_variables.log_warnings)
1469
        sql_print_warning(ER_DEFAULT(ER_FORCING_CLOSE),my_progname,
1470
                          tmp->thread_id,
1471 1472
                          (tmp->main_security_ctx.user ?
                           tmp->main_security_ctx.user : ""));
Sergei Golubchik's avatar
Sergei Golubchik committed
1473
      close_connection(tmp,ER_SERVER_SHUTDOWN);
unknown's avatar
unknown committed
1474 1475 1476
    }
#endif
    DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
Marc Alff's avatar
Marc Alff committed
1477
    mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
1478 1479 1480
  }
  /* 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
1481
  mysql_mutex_lock(&LOCK_thread_count);
unknown's avatar
unknown committed
1482 1483
  while (thread_count)
  {
Marc Alff's avatar
Marc Alff committed
1484
    mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
unknown's avatar
unknown committed
1485 1486
    DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
  }
Marc Alff's avatar
Marc Alff committed
1487
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
1488 1489 1490 1491 1492

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

1493

1494
#ifdef HAVE_CLOSE_SERVER_SOCK
1495
static void close_socket(my_socket sock, const char *info)
unknown's avatar
unknown committed
1496
{
1497 1498 1499
  DBUG_ENTER("close_socket");

  if (sock != INVALID_SOCKET)
unknown's avatar
unknown committed
1500
  {
1501
    DBUG_PRINT("info", ("calling shutdown on %s socket", info));
Sergei Golubchik's avatar
c  
Sergei Golubchik committed
1502
    (void) mysql_socket_shutdown(sock, SHUT_RDWR);
unknown's avatar
unknown committed
1503
#if defined(__NETWARE__)
1504
    /*
unknown's avatar
unknown committed
1505 1506
      The following code is disabled for normal systems as it causes MySQL
      to hang on AIX 4.3 during shutdown
1507
    */
1508 1509
    DBUG_PRINT("info", ("calling closesocket on %s socket", info));
    (void) closesocket(tmp_sock);
1510
#endif
unknown's avatar
unknown committed
1511
  }
1512 1513
  DBUG_VOID_RETURN;
}
1514
#endif
1515 1516


1517
static void close_server_sock()
unknown's avatar
unknown committed
1518
{
1519
#ifdef HAVE_CLOSE_SERVER_SOCK
unknown's avatar
unknown committed
1520
  DBUG_ENTER("close_server_sock");
1521 1522 1523 1524 1525 1526

  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
1527
    (void) unlink(mysqld_unix_port);
1528
  base_ip_sock= extra_ip_sock= unix_sock= INVALID_SOCKET;
Sergei Golubchik's avatar
Sergei Golubchik committed
1529

unknown's avatar
unknown committed
1530 1531
  DBUG_VOID_RETURN;
#endif
1532
}
unknown's avatar
unknown committed
1533

1534 1535
#endif /*EMBEDDED_LIBRARY*/

1536

unknown's avatar
unknown committed
1537 1538 1539 1540
void kill_mysql(void)
{
  DBUG_ENTER("kill_mysql");

1541
#if defined(SIGNALS_DONT_BREAK_READ) && !defined(EMBEDDED_LIBRARY)
1542 1543
  abort_loop=1;					// Break connection loops
  close_server_sock();				// Force accept to wake up
1544
#endif
unknown's avatar
unknown committed
1545

unknown's avatar
unknown committed
1546
#if defined(__WIN__)
unknown's avatar
unknown committed
1547
#if !defined(EMBEDDED_LIBRARY)
unknown's avatar
unknown committed
1548 1549 1550 1551 1552
  {
    if (!SetEvent(hEventShutdown))
    {
      DBUG_PRINT("error",("Got error: %ld from SetEvent",GetLastError()));
    }
1553 1554 1555 1556 1557 1558
    /*
      or:
      HANDLE hEvent=OpenEvent(0, FALSE, "MySqlShutdown");
      SetEvent(hEventShutdown);
      CloseHandle(hEvent);
    */
unknown's avatar
unknown committed
1559
  }
unknown's avatar
unknown committed
1560
#endif
unknown's avatar
unknown committed
1561
#elif defined(HAVE_PTHREAD_KILL)
1562
  if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL))
unknown's avatar
unknown committed
1563 1564 1565 1566
  {
    DBUG_PRINT("error",("Got error %d from pthread_kill",errno)); /* purecov: inspected */
  }
#elif !defined(SIGNALS_DONT_BREAK_READ)
1567
  kill(current_pid, MYSQL_KILL_SIGNAL);
unknown's avatar
unknown committed
1568
#endif
unknown's avatar
unknown committed
1569 1570 1571
  DBUG_PRINT("quit",("After pthread_kill"));
  shutdown_in_progress=1;			// Safety if kill didn't work
#ifdef SIGNALS_DONT_BREAK_READ
1572
  if (!kill_in_progress)
unknown's avatar
unknown committed
1573 1574
  {
    pthread_t tmp;
unknown's avatar
unknown committed
1575
    abort_loop=1;
Marc Alff's avatar
Marc Alff committed
1576 1577 1578
    if (mysql_thread_create(0, /* Not instrumented */
                            &tmp, &connection_attrib, kill_server_thread,
                            (void*) 0))
1579
      sql_print_error("Can't create thread to kill server");
unknown's avatar
unknown committed
1580
  }
1581
#endif
unknown's avatar
unknown committed
1582
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
1583 1584
}

unknown's avatar
unknown committed
1585 1586
/**
  Force server down. Kill all connections and threads and exit.
1587

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

unknown's avatar
unknown committed
1590
  @note
1591 1592 1593 1594
    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
1595

1596
#if !defined(__WIN__)
unknown's avatar
unknown committed
1597
static void *kill_server(void *sig_ptr)
1598
#define RETURN_FROM_KILL_SERVER return 0
unknown's avatar
unknown committed
1599 1600
#else
static void __cdecl kill_server(int sig_ptr)
1601
#define RETURN_FROM_KILL_SERVER return
unknown's avatar
unknown committed
1602 1603 1604
#endif
{
  DBUG_ENTER("kill_server");
1605
#ifndef EMBEDDED_LIBRARY
unknown's avatar
Merge  
unknown committed
1606
  int sig=(int) (long) sig_ptr;			// This is passed a int
1607
  // if there is a signal during the kill in progress, ignore the other
unknown's avatar
unknown committed
1608
  if (kill_in_progress)				// Safety
1609 1610
  {
    DBUG_LEAVE;
unknown's avatar
unknown committed
1611
    RETURN_FROM_KILL_SERVER;
1612
  }
unknown's avatar
unknown committed
1613 1614
  kill_in_progress=TRUE;
  abort_loop=1;					// This should be set
1615
  if (sig != 0) // 0 is not a valid signal number
1616
    my_sigset(sig, SIG_IGN);                    /* purify inspected */
unknown's avatar
unknown committed
1617
  if (sig == MYSQL_KILL_SIGNAL || sig == 0)
1618
    sql_print_information(ER_DEFAULT(ER_NORMAL_SHUTDOWN),my_progname);
unknown's avatar
unknown committed
1619
  else
1620
    sql_print_error(ER_DEFAULT(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */
unknown's avatar
unknown committed
1621

Sergei Golubchik's avatar
Sergei Golubchik committed
1622
#ifdef HAVE_SMEM
1623
  /*
Sergei Golubchik's avatar
Sergei Golubchik committed
1624 1625
    Send event to smem_event_connect_request for aborting
  */
1626
  if (opt_enable_shared_memory)
1627
  {
1628 1629 1630 1631 1632 1633
    if (!SetEvent(smem_event_connect_request))
    {
      DBUG_PRINT("error",
                 ("Got error: %ld from SetEvent of smem_event_connect_request",
                  GetLastError()));
    }
1634 1635 1636
  }
#endif

unknown's avatar
unknown committed
1637
  close_connections();
1638 1639
  if (sig != MYSQL_KILL_SIGNAL &&
      sig != 0)
unknown's avatar
unknown committed
1640 1641
    unireg_abort(1);				/* purecov: inspected */
  else
1642
    unireg_end();
unknown's avatar
Merge  
unknown committed
1643

1644
  /* purecov: begin deadcode */
1645
  DBUG_LEAVE;                                   // Must match DBUG_ENTER()
1646
  my_thread_end();
1647 1648
  pthread_exit(0);
  /* purecov: end */
unknown's avatar
unknown committed
1649

1650 1651 1652 1653 1654
  RETURN_FROM_KILL_SERVER;                      // Avoid compiler warnings

#else /* EMBEDDED_LIBRARY*/

  DBUG_LEAVE;
unknown's avatar
unknown committed
1655
  RETURN_FROM_KILL_SERVER;
1656 1657

#endif /* EMBEDDED_LIBRARY */
unknown's avatar
unknown committed
1658 1659 1660
}


1661
#if defined(USE_ONE_SIGNAL_HAND)
1662
pthread_handler_t kill_server_thread(void *arg __attribute__((unused)))
unknown's avatar
unknown committed
1663 1664 1665
{
  my_thread_init();				// Initialize new thread
  kill_server(0);
1666 1667 1668
  /* purecov: begin deadcode */
  my_thread_end();
  pthread_exit(0);
unknown's avatar
unknown committed
1669
  return 0;
1670
  /* purecov: end */
unknown's avatar
unknown committed
1671 1672 1673
}
#endif

1674

1675
extern "C" sig_handler print_signal_warning(int sig)
unknown's avatar
unknown committed
1676
{
unknown's avatar
unknown committed
1677
  if (global_system_variables.log_warnings)
1678
    sql_print_warning("Got signal %d from thread %ld", sig,my_thread_id());
1679
#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY
1680
  my_sigset(sig,print_signal_warning);		/* int. thread system calls */
unknown's avatar
unknown committed
1681
#endif
1682
#if !defined(__WIN__)
unknown's avatar
unknown committed
1683 1684 1685 1686 1687
  if (sig == SIGALRM)
    alarm(2);					/* reschedule alarm */
#endif
}

unknown's avatar
unknown committed
1688
#ifndef EMBEDDED_LIBRARY
1689

1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701
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
1702 1703
/**
  cleanup all memory and end program nicely.
unknown's avatar
unknown committed
1704

1705 1706 1707
    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
1708

unknown's avatar
unknown committed
1709 1710 1711
  @note
    This function never returns.
*/
1712
void unireg_end(void)
unknown's avatar
unknown committed
1713
{
unknown's avatar
unknown committed
1714
  clean_up(1);
unknown's avatar
unknown committed
1715
  my_thread_end();
1716
#if defined(SIGNALS_DONT_BREAK_READ)
1717 1718
  exit(0);
#else
unknown's avatar
unknown committed
1719
  pthread_exit(0);				// Exit is in main thread
1720
#endif
unknown's avatar
unknown committed
1721 1722
}

1723

1724
extern "C" void unireg_abort(int exit_code)
unknown's avatar
unknown committed
1725
{
1726
  DBUG_ENTER("unireg_abort");
1727

1728 1729
  if (opt_help)
    usage();
unknown's avatar
unknown committed
1730 1731
  if (exit_code)
    sql_print_error("Aborting\n");
1732
  clean_up(!opt_abort && (exit_code || !opt_bootstrap)); /* purecov: inspected */
1733
  DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
1734 1735 1736 1737 1738
  mysqld_exit(exit_code);
}

static void mysqld_exit(int exit_code)
{
1739 1740 1741 1742 1743
  /*
    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.
  */
1744
  wait_for_signal_thread_to_end();
1745
  mysql_audit_finalize();
unknown's avatar
unknown committed
1746
  clean_up_mutexes();
Marc Alff's avatar
Marc Alff committed
1747
  clean_up_error_log_mutex();
1748
  my_end((opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0));
1749
  shutdown_performance_schema();        // we do it as late as possible
unknown's avatar
unknown committed
1750 1751
  exit(exit_code); /* purecov: inspected */
}
1752

1753
#endif /* !EMBEDDED_LIBRARY */
unknown's avatar
unknown committed
1754

1755
void clean_up(bool print_message)
unknown's avatar
unknown committed
1756 1757 1758 1759
{
  DBUG_PRINT("exit",("clean_up"));
  if (cleanup_done++)
    return; /* purecov: inspected */
unknown's avatar
unknown committed
1760

1761
  close_active_mi();
1762
  stop_handle_manager();
1763 1764
  release_ddl_log();

unknown's avatar
unknown committed
1765 1766 1767 1768 1769
  /*
    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
1770 1771 1772

  logger.cleanup_base();

1773
  injector::free_instance();
unknown's avatar
unknown committed
1774 1775
  mysql_bin_log.cleanup();

unknown's avatar
SCRUM  
unknown committed
1776
#ifdef HAVE_REPLICATION
unknown's avatar
unknown committed
1777 1778
  if (use_slave_mask)
    bitmap_free(&slave_error_mask);
1779
#endif
1780
  my_tz_free();
1781
  my_dboptions_cache_free();
unknown's avatar
unknown committed
1782
#ifndef NO_EMBEDDED_ACCESS_CHECKS
unknown's avatar
unknown committed
1783
  servers_free(1);
unknown's avatar
unknown committed
1784 1785
  acl_free(1);
  grant_free();
unknown's avatar
unknown committed
1786
#endif
unknown's avatar
unknown committed
1787
  query_cache_destroy();
unknown's avatar
unknown committed
1788 1789 1790
  hostname_cache_free();
  item_user_lock_free();
  lex_free();				/* Free some memory */
1791
  item_create_cleanup();
1792
  free_charsets();
unknown's avatar
unknown committed
1793
  if (!opt_noacl)
1794
  {
1795
#ifdef HAVE_DLOPEN
unknown's avatar
unknown committed
1796
    udf_free();
1797
#endif
1798
  }
Konstantin Osipov's avatar
Konstantin Osipov committed
1799
  table_def_start_shutdown();
1800
  plugin_shutdown();
1801
  ha_end();
unknown's avatar
Merge  
unknown committed
1802 1803
  if (tc_log)
    tc_log->close();
He Zhenxing's avatar
He Zhenxing committed
1804
  delegates_destroy();
1805
  xid_cache_free();
Konstantin Osipov's avatar
Konstantin Osipov committed
1806 1807
  table_def_free();
  mdl_destroy();
1808
  key_caches.delete_elements((void (*)(const char*, uchar*)) free_key_cache);
1809
  wt_end();
1810
  multi_keycache_free();
1811
  sp_cache_end();
1812
  free_status_vars();
1813
  end_thr_alarm(1);			/* Free allocated memory */
1814
  my_free_open_file_info();
unknown's avatar
unknown committed
1815 1816
  if (defaults_argv)
    free_defaults(defaults_argv);
unknown's avatar
unknown committed
1817
  free_tmpdir(&mysql_tmpdir_list);
unknown's avatar
unknown committed
1818
  bitmap_free(&temp_pool);
unknown's avatar
unknown committed
1819
  free_max_user_conn();
1820 1821 1822 1823
  free_global_user_stats();
  free_global_client_stats();
  free_global_table_stats();
  free_global_index_stats();
1824
  delete_dynamic(&all_options);
unknown's avatar
SCRUM  
unknown committed
1825
#ifdef HAVE_REPLICATION
1826
  end_slave_list();
1827
#endif
1828
  my_uuid_end();
unknown's avatar
unknown committed
1829 1830
  delete binlog_filter;
  delete rpl_filter;
1831
  end_ssl();
1832
  vio_end();
unknown's avatar
unknown committed
1833
  my_regex_end();
1834 1835 1836 1837
#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
1838

1839
#if !defined(EMBEDDED_LIBRARY)
1840
  if (!opt_bootstrap)
Marc Alff's avatar
Marc Alff committed
1841
    mysql_file_delete(key_file_pid, pidfile_name, MYF(0)); // This may not always exist
unknown's avatar
unknown committed
1842
#endif
1843
  if (print_message && my_default_lc_messages && server_start_time)
1844 1845
    sql_print_information(ER_DEFAULT(ER_SHUTDOWN_COMPLETE),my_progname);
  cleanup_errmsgs();
Sergei Golubchik's avatar
Sergei Golubchik committed
1846
  MYSQL_CALLBACK(thread_scheduler, end, ());
1847
  mysql_library_end();
unknown's avatar
Merge  
unknown committed
1848
  finish_client_errs();
1849
  (void) my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST); // finish server errs
1850
  DBUG_PRINT("quit", ("Error messages freed"));
unknown's avatar
unknown committed
1851
  /* Tell main we are ready */
unknown's avatar
unknown committed
1852
  logger.cleanup_end();
1853
  sys_var_end();
1854
  my_atomic_rwlock_destroy(&global_query_id_lock);
1855
  my_atomic_rwlock_destroy(&thread_running_lock);
Marc Alff's avatar
Marc Alff committed
1856
  mysql_mutex_lock(&LOCK_thread_count);
1857
  DBUG_PRINT("quit", ("got thread count lock"));
unknown's avatar
unknown committed
1858
  ready_to_exit=1;
unknown's avatar
unknown committed
1859
  /* do the broadcast inside the lock to ensure that my_end() is not called */
Marc Alff's avatar
Marc Alff committed
1860 1861
  mysql_cond_broadcast(&COND_thread_count);
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
1862

unknown's avatar
unknown committed
1863 1864 1865 1866
  /*
    The following lines may never be executed as the main thread may have
    killed us
  */
1867
  DBUG_PRINT("quit", ("done with cleanup"));
unknown's avatar
unknown committed
1868 1869 1870
} /* clean_up */


1871 1872
#ifndef EMBEDDED_LIBRARY

unknown's avatar
unknown committed
1873
/**
1874
  This is mainly needed when running with purify, but it's still nice to
unknown's avatar
unknown committed
1875
  know that all child threads have died when mysqld exits.
1876 1877 1878 1879 1880 1881 1882 1883 1884 1885
*/
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++)
  {
1886
    if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL) == ESRCH)
1887 1888 1889 1890
      break;
    my_sleep(100);				// Give it time to die
  }
}
1891
#endif /*EMBEDDED_LIBRARY*/
1892

unknown's avatar
unknown committed
1893 1894
static void clean_up_mutexes()
{
1895
  DBUG_ENTER("clean_up_mutexes");
Marc Alff's avatar
Marc Alff committed
1896
  mysql_rwlock_destroy(&LOCK_grant);
Marc Alff's avatar
Marc Alff committed
1897
  mysql_mutex_destroy(&LOCK_thread_count);
Marc Alff's avatar
Marc Alff committed
1898 1899 1900 1901
  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
1902 1903 1904
  mysql_mutex_destroy(&LOCK_crypt);
  mysql_mutex_destroy(&LOCK_user_conn);
  mysql_mutex_destroy(&LOCK_connection_count);
Sergei Golubchik's avatar
Sergei Golubchik committed
1905 1906 1907 1908
  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);
1909
#ifdef HAVE_OPENSSL
Marc Alff's avatar
Marc Alff committed
1910
  mysql_mutex_destroy(&LOCK_des_key_file);
unknown's avatar
unknown committed
1911
#ifndef HAVE_YASSL
1912
  for (int i= 0; i < CRYPTO_num_locks(); ++i)
1913
    mysql_rwlock_destroy(&openssl_stdlocks[i].lock);
1914
  OPENSSL_free(openssl_stdlocks);
Michael Widenius's avatar
Michael Widenius committed
1915 1916
#endif /* HAVE_YASSL */
#endif /* HAVE_OPENSSL */
1917
#ifdef HAVE_REPLICATION
Marc Alff's avatar
Marc Alff committed
1918 1919
  mysql_mutex_destroy(&LOCK_rpl_status);
  mysql_cond_destroy(&COND_rpl_status);
Michael Widenius's avatar
Michael Widenius committed
1920
#endif /* HAVE_REPLICATION */
Marc Alff's avatar
Marc Alff committed
1921 1922 1923 1924 1925
  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
1926
  mysql_mutex_destroy(&LOCK_short_uuid_generator);
Marc Alff's avatar
Marc Alff committed
1927 1928
  mysql_mutex_destroy(&LOCK_prepared_stmt_count);
  mysql_mutex_destroy(&LOCK_error_messages);
Marc Alff's avatar
Marc Alff committed
1929 1930 1931
  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
1932 1933
  mysql_mutex_destroy(&LOCK_server_started);
  mysql_cond_destroy(&COND_server_started);
Sergei Golubchik's avatar
Sergei Golubchik committed
1934 1935
  mysql_mutex_destroy(&LOCK_prepare_ordered);
  mysql_mutex_destroy(&LOCK_commit_ordered);
1936
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
1937
}
1938 1939


unknown's avatar
unknown committed
1940 1941 1942 1943
/****************************************************************************
** Init IP and UNIX socket
****************************************************************************/

unknown's avatar
unknown committed
1944
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
1945 1946 1947
static void set_ports()
{
  char	*env;
1948
  if (!mysqld_port && !opt_disable_networking)
unknown's avatar
unknown committed
1949
  {					// Get port if not from commandline
1950
    mysqld_port= MYSQL_PORT;
1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962

    /*
      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
1963
    struct  servent *serv_ptr;
1964 1965
    if ((serv_ptr= getservbyname("mysql", "tcp")))
      mysqld_port= ntohs((u_short) serv_ptr->s_port); /* purecov: inspected */
1966
#endif
unknown's avatar
unknown committed
1967
    if ((env = getenv("MYSQL_TCP_PORT")))
1968
      mysqld_port= (uint) atoi(env);		/* purecov: inspected */
unknown's avatar
unknown committed
1969
  }
1970
  if (!mysqld_unix_port)
unknown's avatar
unknown committed
1971 1972
  {
#ifdef __WIN__
1973
    mysqld_unix_port= (char*) MYSQL_NAMEDPIPE;
unknown's avatar
unknown committed
1974
#else
1975
    mysqld_unix_port= (char*) MYSQL_UNIX_ADDR;
unknown's avatar
unknown committed
1976 1977
#endif
    if ((env = getenv("MYSQL_UNIX_PORT")))
1978
      mysqld_unix_port= env;			/* purecov: inspected */
unknown's avatar
unknown committed
1979 1980 1981 1982 1983
  }
}

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

1984
static struct passwd *check_user(const char *user)
unknown's avatar
unknown committed
1985
{
1986
#if !defined(__WIN__)
1987
  struct passwd *tmp_user_info;
1988
  uid_t user_id= geteuid();
unknown's avatar
unknown committed
1989

1990
  // Don't bother if we aren't superuser
1991
  if (user_id)
unknown's avatar
unknown committed
1992 1993
  {
    if (user)
1994
    {
1995 1996 1997 1998
      /* 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) &&
1999
	  global_system_variables.log_warnings)
2000 2001
        sql_print_warning(
                    "One can only use the --user switch if running as root\n");
unknown's avatar
unknown committed
2002
      /* purecov: end */
2003
    }
2004
    return NULL;
unknown's avatar
unknown committed
2005
  }
2006
  if (!user)
unknown's avatar
unknown committed
2007 2008 2009
  {
    if (!opt_bootstrap)
    {
unknown's avatar
unknown committed
2010
      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
2011 2012
      unireg_abort(1);
    }
2013
    return NULL;
unknown's avatar
unknown committed
2014
  }
2015
  /* purecov: begin tested */
unknown's avatar
unknown committed
2016
  if (!strcmp(user,"root"))
unknown's avatar
unknown committed
2017
    return NULL;                        // Avoid problem with dynamic libraries
unknown's avatar
unknown committed
2018

2019
  if (!(tmp_user_info= getpwnam(user)))
unknown's avatar
unknown committed
2020
  {
2021
    // Allow a numeric uid to be used
unknown's avatar
unknown committed
2022
    const char *pos;
unknown's avatar
unknown committed
2023 2024
    for (pos= user; my_isdigit(mysqld_charset,*pos); pos++) ;
    if (*pos)                                   // Not numeric id
2025
      goto err;
2026
    if (!(tmp_user_info= getpwuid(atoi(user))))
2027
      goto err;
unknown's avatar
unknown committed
2028
  }
unknown's avatar
unknown committed
2029 2030
  return tmp_user_info;
  /* purecov: end */
2031 2032

err:
unknown's avatar
unknown committed
2033
  sql_print_error("Fatal error: Can't change to run as user '%s' ;  Please check that the user exists!\n",user);
2034
  unireg_abort(1);
2035 2036 2037 2038 2039 2040 2041 2042 2043

#ifdef PR_SET_DUMPABLE
  if (test_flags & TEST_CORE_ON_SIGNAL)
  {
    /* inform kernel that process is dumpable */
    (void) prctl(PR_SET_DUMPABLE, 1);
  }
#endif

unknown's avatar
unknown committed
2044 2045
#endif
  return NULL;
2046 2047
}

2048
static void set_user(const char *user, struct passwd *user_info_arg)
2049
{
2050
  /* purecov: begin tested */
2051
#if !defined(__WIN__)
2052
  DBUG_ASSERT(user_info_arg != 0);
unknown's avatar
unknown committed
2053
#ifdef HAVE_INITGROUPS
2054 2055 2056 2057 2058 2059
  /*
    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.
  */
2060
  calling_initgroups= 1;
2061
  initgroups((char*) user, user_info_arg->pw_gid);
2062
  calling_initgroups= 0;
unknown's avatar
unknown committed
2063
#endif
2064
  if (setgid(user_info_arg->pw_gid) == -1)
2065 2066 2067
  {
    sql_perror("setgid");
    unireg_abort(1);
unknown's avatar
unknown committed
2068
  }
2069
  if (setuid(user_info_arg->pw_uid) == -1)
unknown's avatar
unknown committed
2070 2071 2072 2073 2074
  {
    sql_perror("setuid");
    unireg_abort(1);
  }
#endif
unknown's avatar
unknown committed
2075
  /* purecov: end */
unknown's avatar
unknown committed
2076 2077
}

unknown's avatar
unknown committed
2078

2079
static void set_effective_user(struct passwd *user_info_arg)
2080
{
2081
#if !defined(__WIN__)
2082 2083
  DBUG_ASSERT(user_info_arg != 0);
  if (setregid((gid_t)-1, user_info_arg->pw_gid) == -1)
2084
  {
2085
    sql_perror("setregid");
2086
    unireg_abort(1);
unknown's avatar
unknown committed
2087
  }
2088
  if (setreuid((uid_t)-1, user_info_arg->pw_uid) == -1)
2089
  {
2090
    sql_perror("setreuid");
2091 2092 2093 2094 2095 2096
    unireg_abort(1);
  }
#endif
}


unknown's avatar
unknown committed
2097
/** Change root user if started with @c --chroot . */
unknown's avatar
unknown committed
2098 2099
static void set_root(const char *path)
{
2100
#if !defined(__WIN__)
unknown's avatar
unknown committed
2101 2102 2103 2104 2105
  if (chroot(path) == -1)
  {
    sql_perror("chroot");
    unireg_abort(1);
  }
2106
  my_setwd("/", MYF(0));
unknown's avatar
unknown committed
2107 2108 2109
#endif
}

2110 2111 2112
/**
   Activate usage of a tcp port
*/
2113

2114
static my_socket activate_tcp_port(uint port)
unknown's avatar
unknown committed
2115
{
Sergei Golubchik's avatar
Sergei Golubchik committed
2116 2117 2118
  struct addrinfo *ai, *a;
  struct addrinfo hints;
  int error;
2119 2120
  int	arg;
  char port_buf[NI_MAXSERV];
2121
  my_socket ip_sock= INVALID_SOCKET;
2122 2123
  DBUG_ENTER("activate_tcp_port");
  DBUG_PRINT("general",("IP Socket is %d",port));
unknown's avatar
unknown committed
2124

Sergei Golubchik's avatar
Sergei Golubchik committed
2125 2126 2127 2128
  bzero(&hints, sizeof (hints));
  hints.ai_flags= AI_PASSIVE;
  hints.ai_socktype= SOCK_STREAM;
  hints.ai_family= AF_UNSPEC;
unknown's avatar
unknown committed
2129

2130
  my_snprintf(port_buf, NI_MAXSERV, "%d", port);
Sergei Golubchik's avatar
Sergei Golubchik committed
2131 2132
  error= getaddrinfo(my_bind_addr_str, port_buf, &hints, &ai);
  if (error != 0)
unknown's avatar
unknown committed
2133
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
2134 2135 2136 2137
    DBUG_PRINT("error",("Got error: %d from getaddrinfo()", error));
    sql_perror(ER_DEFAULT(ER_IPSOCK_ERROR));  /* purecov: tested */
    unireg_abort(1);				/* purecov: tested */
  }
2138

Sergei Golubchik's avatar
Sergei Golubchik committed
2139 2140
  for (a= ai; a != NULL; a= a->ai_next)
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
2141
    ip_sock= socket(a->ai_family, a->ai_socktype, a->ai_protocol);
Sergei Golubchik's avatar
Sergei Golubchik committed
2142 2143 2144
    if (ip_sock != INVALID_SOCKET)
      break;
  }
2145

2146 2147 2148
  if (ip_sock == INVALID_SOCKET)
  {
    DBUG_PRINT("error",("Got error: %d from socket()",socket_errno));
Sergei Golubchik's avatar
Sergei Golubchik committed
2149
    sql_perror(ER_DEFAULT(ER_IPSOCK_ERROR));  /* purecov: tested */
2150 2151
    unireg_abort(1);				/* purecov: tested */
  }
2152 2153

#ifndef __WIN__
2154 2155 2156 2157
  /*
    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
2158
  arg= 1;
2159
  (void) setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,sizeof(arg));
unknown's avatar
unknown committed
2160
#endif /* __WIN__ */
2161 2162

#ifdef IPV6_V6ONLY
Sergei Golubchik's avatar
Sergei Golubchik committed
2163 2164 2165 2166
   /*
     For interoperability with older clients, IPv6 socket should
     listen on both IPv6 and IPv4 wildcard addresses.
     Turn off IPV6_V6ONLY option.
2167

Sergei Golubchik's avatar
Sergei Golubchik committed
2168 2169 2170 2171 2172 2173 2174 2175 2176 2177
     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));
  }
2178
#endif
2179 2180 2181 2182 2183 2184 2185 2186
  /*
    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=#).
  */
2187 2188
  int ret;
  uint waited, retry, this_wait;
2189 2190
  for (waited= 0, retry= 1; ; retry++, waited+= this_wait)
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
2191
    if (((ret= bind(ip_sock, a->ai_addr, a->ai_addrlen)) >= 0 ) ||
2192 2193 2194
        (socket_errno != SOCKET_EADDRINUSE) ||
        (waited >= mysqld_port_timeout))
      break;
2195
    sql_print_information("Retrying bind on TCP/IP port %u", port);
2196 2197
    this_wait= retry * retry / 3 + 1;
    sleep(this_wait);
unknown's avatar
unknown committed
2198
  }
Sergei Golubchik's avatar
Sergei Golubchik committed
2199
  freeaddrinfo(ai);
2200 2201
  if (ret < 0)
  {
2202 2203 2204 2205
    char buff[100];
    sprintf(buff, "Can't start server: Bind on TCP/IP port. Got error: %d",
            (int) socket_errno);
    sql_perror(buff);
2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218
    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);
}
2219

2220 2221 2222 2223
static void network_init(void)
{
#ifdef HAVE_SYS_UN_H
  struct sockaddr_un	UNIXaddr;
2224
  int	arg;
2225
#endif
unknown's avatar
unknown committed
2226
  DBUG_ENTER("network_init");
unknown's avatar
unknown committed
2227

Sergei Golubchik's avatar
Sergei Golubchik committed
2228
  if (MYSQL_CALLBACK_ELSE(thread_scheduler, init, (), 0))
unknown's avatar
unknown committed
2229 2230
    unireg_abort(1);			/* purecov: inspected */

unknown's avatar
unknown committed
2231 2232
  set_ports();

Sergei Golubchik's avatar
Sergei Golubchik committed
2233
  if (report_port == 0)
unknown's avatar
unknown committed
2234
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
2235
    report_port= mysqld_port;
unknown's avatar
unknown committed
2236
  }
Sergei Golubchik's avatar
c  
Sergei Golubchik committed
2237 2238 2239
#ifndef DBUG_OFF
  if (!opt_disable_networking)
    DBUG_ASSERT(report_port != 0);
2240
#endif
2241
  if (!opt_disable_networking && !opt_bootstrap)
unknown's avatar
unknown committed
2242
  {
2243 2244 2245 2246
    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
2247
  }
2248

2249
#ifdef _WIN32
unknown's avatar
unknown committed
2250
  /* create named pipe */
2251
  if (Service.IsNT() && mysqld_unix_port[0] && !opt_bootstrap &&
unknown's avatar
unknown committed
2252
      opt_enable_named_pipe)
unknown's avatar
unknown committed
2253
  {
2254

2255
    strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\.\\pipe\\",
2256
	     mysqld_unix_port, NullS);
2257 2258
    bzero((char*) &saPipeSecurity, sizeof(saPipeSecurity));
    bzero((char*) &sdPipeDescriptor, sizeof(sdPipeDescriptor));
2259
    if (!InitializeSecurityDescriptor(&sdPipeDescriptor,
2260
				      SECURITY_DESCRIPTOR_REVISION))
unknown's avatar
unknown committed
2261 2262 2263 2264 2265 2266 2267 2268 2269
    {
      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
2270
    saPipeSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
unknown's avatar
unknown committed
2271 2272
    saPipeSecurity.lpSecurityDescriptor = &sdPipeDescriptor;
    saPipeSecurity.bInheritHandle = FALSE;
2273
    if ((hPipe= CreateNamedPipe(pipe_name,
2274
				PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
2275 2276 2277 2278 2279 2280 2281 2282
				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
2283 2284 2285 2286 2287 2288 2289
      {
	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 );
2290
	sql_perror((char *)lpMsgBuf);
unknown's avatar
Merge  
unknown committed
2291
	LocalFree(lpMsgBuf);
unknown's avatar
unknown committed
2292 2293 2294 2295 2296
	unireg_abort(1);
      }
  }
#endif

2297
#if defined(HAVE_SYS_UN_H)
unknown's avatar
unknown committed
2298 2299 2300
  /*
  ** Create the UNIX socket
  */
2301
  if (mysqld_unix_port[0] && !opt_bootstrap)
unknown's avatar
unknown committed
2302
  {
2303
    DBUG_PRINT("general",("UNIX Socket is %s",mysqld_unix_port));
unknown's avatar
unknown committed
2304

unknown's avatar
unknown committed
2305 2306
    if (strlen(mysqld_unix_port) > (sizeof(UNIXaddr.sun_path) - 1))
    {
2307
      sql_print_error("The socket file path is too long (> %u): %s",
unknown's avatar
unknown committed
2308
                      (uint) sizeof(UNIXaddr.sun_path) - 1, mysqld_unix_port);
unknown's avatar
unknown committed
2309 2310
      unireg_abort(1);
    }
2311
    if ((unix_sock= socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
unknown's avatar
unknown committed
2312 2313 2314 2315 2316 2317
    {
      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;
2318 2319
    strmov(UNIXaddr.sun_path, mysqld_unix_port);
    (void) unlink(mysqld_unix_port);
2320
    arg= 1;
unknown's avatar
unknown committed
2321 2322 2323
    (void) setsockopt(unix_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,
		      sizeof(arg));
    umask(0);
2324
    if (bind(unix_sock, reinterpret_cast<struct sockaddr *>(&UNIXaddr),
unknown's avatar
unknown committed
2325 2326 2327
	     sizeof(UNIXaddr)) < 0)
    {
      sql_perror("Can't start server : Bind on unix socket"); /* purecov: tested */
2328
      sql_print_error("Do you already have another mysqld server running on socket: %s ?",mysqld_unix_port);
unknown's avatar
unknown committed
2329 2330 2331 2332
      unireg_abort(1);					/* purecov: tested */
    }
    umask(((~my_umask) & 0666));
#if defined(S_IFSOCK) && defined(SECURE_SOCKETS)
2333
    (void) chmod(mysqld_unix_port,S_IFSOCK);	/* Fix solaris 2.6 bug */
unknown's avatar
unknown committed
2334
#endif
2335
    if (listen(unix_sock,(int) back_log) < 0)
2336
      sql_print_warning("listen() on Unix socket failed with error %d",
unknown's avatar
unknown committed
2337
		      socket_errno);
unknown's avatar
unknown committed
2338 2339 2340 2341 2342 2343
  }
#endif
  DBUG_PRINT("info",("server started"));
  DBUG_VOID_RETURN;
}

Sergei Golubchik's avatar
Sergei Golubchik committed
2344

unknown's avatar
unknown committed
2345 2346
/**
  Close a connection.
2347

2348 2349
  @param thd        Thread handle.
  @param sql_errno  The error code to send before disconnect.
2350

unknown's avatar
unknown committed
2351
  @note
2352 2353
    For the connection that is doing shutdown, this is called twice
*/
2354
void close_connection(THD *thd, uint sql_errno)
unknown's avatar
unknown committed
2355 2356
{
  DBUG_ENTER("close_connection");
2357 2358 2359 2360

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

Sergei Golubchik's avatar
Sergei Golubchik committed
2361 2362
  thd->print_aborted_warning(3, sql_errno ? ER_DEFAULT(sql_errno)
                                          : "CLOSE_CONNECTION");
2363

2364 2365 2366 2367
  thd->disconnect();

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

2368 2369 2370 2371
  if (MYSQL_CONNECTION_DONE_ENABLED())
  {
    sleep(0); /* Workaround to avoid tailcall optimisation */
  }
2372
  MYSQL_AUDIT_NOTIFY_CONNECTION_DISCONNECT(thd, sql_errno);
unknown's avatar
unknown committed
2373 2374
  DBUG_VOID_RETURN;
}
2375 2376
#endif /* EMBEDDED_LIBRARY */

unknown's avatar
unknown committed
2377

2378
/** Called when mysqld is aborted with ^C */
unknown's avatar
unknown committed
2379
/* ARGSUSED */
2380
extern "C" sig_handler end_mysqld_signal(int sig __attribute__((unused)))
unknown's avatar
unknown committed
2381
{
2382
  DBUG_ENTER("end_mysqld_signal");
2383 2384
  /* Don't call kill_mysql() if signal thread is not running */
  if (signal_thread_in_use)
Sergei Golubchik's avatar
Sergei Golubchik committed
2385
    kill_mysql();                          // Take down mysqld nicely
unknown's avatar
unknown committed
2386 2387 2388 2389
  DBUG_VOID_RETURN;				/* purecov: deadcode */
}


2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402
/*
  Cleanup THD object

  SYNOPSIS
    thd_cleanup()
    thd		 Thread handler
*/

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

2403 2404 2405 2406 2407 2408 2409
/*
  Decrease number of connections

  SYNOPSIS
    dec_connection_count()
*/

Sergei Golubchik's avatar
Sergei Golubchik committed
2410
void dec_connection_count(THD *thd)
2411 2412
{
  mysql_mutex_lock(&LOCK_connection_count);
Sergei Golubchik's avatar
Sergei Golubchik committed
2413
  (*thd->scheduler->connection_count)--;
2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432
  mysql_mutex_unlock(&LOCK_connection_count);
}


/*
  Delete the THD object and decrease number of threads

  SYNOPSIS
    delete_thd()
    thd		 Thread handler
*/

void delete_thd(THD *thd)
{
  thread_count--;
  delete thd;
}


unknown's avatar
unknown committed
2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444
/*
  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
2445
{
unknown's avatar
unknown committed
2446 2447
  DBUG_ENTER("unlink_thd");
  DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd));
2448

2449
  thd_cleanup(thd);
Sergei Golubchik's avatar
Sergei Golubchik committed
2450
  dec_connection_count(thd);
Marc Alff's avatar
Marc Alff committed
2451
  mysql_mutex_lock(&LOCK_thread_count);
2452 2453 2454 2455 2456 2457
  /*
    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););
2458
  delete_thd(thd);
unknown's avatar
unknown committed
2459 2460 2461
  DBUG_VOID_RETURN;
}

2462

unknown's avatar
unknown committed
2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480
/*
  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
2481
  mysql_mutex_assert_owner(&LOCK_thread_count);
unknown's avatar
unknown committed
2482
  if (cached_thread_count < thread_cache_size &&
2483
      ! abort_loop && !kill_cached_threads)
unknown's avatar
unknown committed
2484 2485
  {
    /* Don't kill the thread, just put it in cache for reuse */
unknown's avatar
unknown committed
2486
    DBUG_PRINT("info", ("Adding thread to cache"));
unknown's avatar
unknown committed
2487
    cached_thread_count++;
2488 2489 2490 2491 2492 2493 2494 2495 2496 2497

#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
2498
    while (!abort_loop && ! wake_thread && ! kill_cached_threads)
Marc Alff's avatar
Marc Alff committed
2499
      mysql_cond_wait(&COND_thread_cache, &LOCK_thread_count);
unknown's avatar
unknown committed
2500 2501
    cached_thread_count--;
    if (kill_cached_threads)
Marc Alff's avatar
Marc Alff committed
2502
      mysql_cond_signal(&COND_flush_thread_cache);
unknown's avatar
unknown committed
2503 2504
    if (wake_thread)
    {
unknown's avatar
unknown committed
2505
      THD *thd;
unknown's avatar
unknown committed
2506
      wake_thread--;
unknown's avatar
unknown committed
2507
      thd= thread_cache.get();
2508
      thd->thread_stack= (char*) &thd;          // For store_globals
unknown's avatar
unknown committed
2509
      (void) thd->store_globals();
2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524

#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

2525 2526 2527 2528 2529 2530
      /*
        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;
2531
      thd->thr_create_utime= microsecond_interval_timer();
2532
      thd->start_utime= thd->thr_create_utime;
2533
      threads.append(thd);
unknown's avatar
unknown committed
2534
      return(1);
unknown's avatar
unknown committed
2535 2536
    }
  }
unknown's avatar
unknown committed
2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563
  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);
2564 2565
  /* Mark that current_thd is not valid anymore */
  my_pthread_setspecific_ptr(THR_THD,  0);
unknown's avatar
unknown committed
2566 2567
  if (put_in_cache)
    put_in_cache= cache_thread();
Marc Alff's avatar
Marc Alff committed
2568
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
2569 2570
  if (put_in_cache)
    DBUG_RETURN(0);                             // Thread is reused
unknown's avatar
unknown committed
2571

2572
  /* It's safe to broadcast outside a lock (COND... is not deleted here) */
unknown's avatar
unknown committed
2573
  DBUG_PRINT("signal", ("Broadcasting COND_thread_count"));
2574
  DBUG_LEAVE;                                   // Must match DBUG_ENTER()
2575
  my_thread_end();
Marc Alff's avatar
Marc Alff committed
2576
  mysql_cond_broadcast(&COND_thread_count);
unknown's avatar
unknown committed
2577 2578

  pthread_exit(0);
2579
  return 0;                                     // Avoid compiler warnings
unknown's avatar
unknown committed
2580 2581 2582 2583 2584
}


void flush_thread_cache()
{
Marc Alff's avatar
Marc Alff committed
2585
  mysql_mutex_lock(&LOCK_thread_count);
unknown's avatar
unknown committed
2586 2587 2588
  kill_cached_threads++;
  while (cached_thread_count)
  {
Marc Alff's avatar
Marc Alff committed
2589 2590
    mysql_cond_broadcast(&COND_thread_cache);
    mysql_cond_wait(&COND_flush_thread_cache, &LOCK_thread_count);
unknown's avatar
unknown committed
2591 2592
  }
  kill_cached_threads--;
Marc Alff's avatar
Marc Alff committed
2593
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
2594 2595 2596 2597
}


/******************************************************************************
2598 2599 2600
  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
2601 2602
******************************************************************************/

2603
#if defined(__WIN__)
2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617


/*
  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
2618
#ifndef EMBEDDED_LIBRARY
2619 2620 2621 2622 2623 2624 2625 2626
  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.
     */
2627
#ifndef EMBEDDED_LIBRARY
2628 2629 2630
     if(hEventShutdown)
       kill_mysql();
     else
2631
#endif
2632 2633 2634
       sql_print_warning("CTRL-C ignored during startup");
     DBUG_RETURN(TRUE);
  }
unknown's avatar
unknown committed
2635
#endif
2636 2637 2638 2639 2640 2641 2642 2643 2644
  DBUG_RETURN(FALSE);
}




#ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER
#define DEBUGGER_ATTACH_TIMEOUT 120
/*
2645 2646
  Wait for debugger to attach and break into debugger. If debugger is
  not attached, resume after timeout.
2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 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
*/
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
  {
2697
    my_set_exception_pointers(ex_pointers);
2698
    handle_fatal_signal(ex_pointers->ExceptionRecord->ExceptionCode);
2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716
  }
  __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
2717 2718
static void init_signals(void)
{
2719 2720
  if(opt_console)
    SetConsoleCtrlHandler(console_event_handler,TRUE);
2721

2722
    /* Avoid MessageBox()es*/
2723 2724 2725 2726 2727 2728
  _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);
2729 2730 2731 2732 2733 2734 2735 2736

   /*
     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)
   */
2737 2738
  SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS
                               | SEM_NOOPENFILEERRORBOX);
2739
  SetUnhandledExceptionFilter(my_unhandler_exception_filter);
unknown's avatar
unknown committed
2740 2741
}

unknown's avatar
unknown committed
2742

2743
static void start_signal_handler(void)
2744
{
2745
#ifndef EMBEDDED_LIBRARY
2746 2747 2748
  // Save vm id of this process
  if (!opt_bootstrap)
    create_pid_file();
2749
#endif /* EMBEDDED_LIBRARY */
2750
}
unknown's avatar
unknown committed
2751

unknown's avatar
unknown committed
2752

unknown's avatar
unknown committed
2753 2754
static void check_data_home(const char *path)
{}
2755

2756
#endif /* __WIN__ */
unknown's avatar
unknown committed
2757

unknown's avatar
unknown committed
2758 2759 2760 2761 2762 2763 2764 2765 2766

#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

2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 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

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


2838
#if !defined(__WIN__)
unknown's avatar
unknown committed
2839 2840
#ifndef SA_RESETHAND
#define SA_RESETHAND 0
2841
#endif /* SA_RESETHAND */
unknown's avatar
unknown committed
2842 2843
#ifndef SA_NODEFER
#define SA_NODEFER 0
2844
#endif /* SA_NODEFER */
2845

2846 2847
#ifndef EMBEDDED_LIBRARY

unknown's avatar
unknown committed
2848 2849 2850
static void init_signals(void)
{
  sigset_t set;
2851
  struct sigaction sa;
unknown's avatar
unknown committed
2852 2853
  DBUG_ENTER("init_signals");

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

Michael Widenius's avatar
Michael Widenius committed
2856
  if (opt_stack_trace || (test_flags & TEST_CORE_ON_SIGNAL))
unknown's avatar
unknown committed
2857
  {
unknown's avatar
unknown committed
2858 2859 2860 2861
    sa.sa_flags = SA_RESETHAND | SA_NODEFER;
    sigemptyset(&sa.sa_mask);
    sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);

2862
    my_init_stacktrace();
unknown's avatar
unknown committed
2863
#if defined(__amiga__)
2864
    sa.sa_handler=(void(*)())handle_fatal_signal;
unknown's avatar
unknown committed
2865
#else
2866
    sa.sa_handler=handle_fatal_signal;
unknown's avatar
unknown committed
2867
#endif
unknown's avatar
unknown committed
2868
    sigaction(SIGSEGV, &sa, NULL);
2869
    sigaction(SIGABRT, &sa, NULL);
unknown's avatar
unknown committed
2870
#ifdef SIGBUS
unknown's avatar
unknown committed
2871
    sigaction(SIGBUS, &sa, NULL);
unknown's avatar
unknown committed
2872
#endif
unknown's avatar
unknown committed
2873
    sigaction(SIGILL, &sa, NULL);
2874
    sigaction(SIGFPE, &sa, NULL);
unknown's avatar
unknown committed
2875
  }
2876 2877 2878 2879 2880

#ifdef HAVE_GETRLIMIT
  if (test_flags & TEST_CORE_ON_SIGNAL)
  {
    /* Change limits so that we will get a core file */
2881
    STRUCT_RLIMIT rl;
2882
    rl.rlim_cur = rl.rlim_max = (rlim_t) RLIM_INFINITY;
unknown's avatar
unknown committed
2883
    if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
2884
      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");
2885 2886
  }
#endif
unknown's avatar
unknown committed
2887
  (void) sigemptyset(&set);
2888
  my_sigset(SIGPIPE,SIG_IGN);
unknown's avatar
unknown committed
2889
  sigaddset(&set,SIGPIPE);
2890
#ifndef IGNORE_SIGHUP_SIGQUIT
unknown's avatar
unknown committed
2891 2892
  sigaddset(&set,SIGQUIT);
  sigaddset(&set,SIGHUP);
2893 2894
#endif
  sigaddset(&set,SIGTERM);
2895 2896

  /* Fix signals if blocked by parents (can happen on Mac OS X) */
unknown's avatar
unknown committed
2897
  sigemptyset(&sa.sa_mask);
2898 2899 2900 2901 2902 2903
  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
2904 2905 2906
#ifdef SIGTSTP
  sigaddset(&set,SIGTSTP);
#endif
2907 2908
  if (thd_lib_detected != THD_LIB_LT)
    sigaddset(&set,THR_SERVER_ALARM);
2909
  if (test_flags & TEST_SIGINT)
2910
  {
2911 2912
    /* Allow SIGINT to break mysqld. This is for debugging with --gdb */
    my_sigset(SIGINT, end_mysqld_signal);
unknown's avatar
unknown committed
2913
    sigdelset(&set, SIGINT);
2914
  }
2915 2916
  else
    sigaddset(&set,SIGINT);
unknown's avatar
unknown committed
2917

2918 2919
  sigprocmask(SIG_SETMASK,&set,NULL);
  pthread_sigmask(SIG_SETMASK,&set,NULL);
2920 2921 2922 2923 2924 2925 2926 2927 2928
  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
2929 2930 2931 2932

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

Marc Alff's avatar
Marc Alff committed
2935
  mysql_mutex_lock(&LOCK_thread_count);
Marc Alff's avatar
Marc Alff committed
2936 2937
  if ((error= mysql_thread_create(key_thread_signal_hand,
                                  &signal_thread, &thr_attr, signal_hand, 0)))
unknown's avatar
unknown committed
2938 2939 2940 2941 2942
  {
    sql_print_error("Can't create interrupt-thread (error %d, errno: %d)",
		    error,errno);
    exit(1);
  }
Marc Alff's avatar
Marc Alff committed
2943 2944
  mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
2945 2946 2947 2948 2949 2950

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


unknown's avatar
unknown committed
2951
/** This threads handles all signals and alarms. */
unknown's avatar
unknown committed
2952
/* ARGSUSED */
2953
pthread_handler_t signal_hand(void *arg __attribute__((unused)))
unknown's avatar
unknown committed
2954 2955 2956 2957 2958
{
  sigset_t set;
  int sig;
  my_thread_init();				// Init new thread
  DBUG_ENTER("signal_hand");
unknown's avatar
unknown committed
2959 2960
  signal_thread_in_use= 1;

unknown's avatar
unknown committed
2961 2962
  /*
    Setup alarm handler
2963 2964
    This should actually be '+ max_number_of_slaves' instead of +10,
    but the +10 should be quite safe.
unknown's avatar
unknown committed
2965
  */
Sergei Golubchik's avatar
Sergei Golubchik committed
2966
  init_thr_alarm(thread_scheduler->max_threads + extra_max_connections +
2967
		 global_system_variables.max_insert_delayed_threads + 10);
2968
  if (test_flags & TEST_SIGINT)
2969
  {
2970 2971 2972
    /* Allow SIGINT to break mysqld. This is for debugging with --gdb */
    (void) sigemptyset(&set);
    (void) sigaddset(&set,SIGINT);
2973 2974
    (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL);
  }
unknown's avatar
unknown committed
2975 2976 2977 2978
  (void) sigemptyset(&set);			// Setup up SIGINT for debug
#ifdef USE_ONE_SIGNAL_HAND
  (void) sigaddset(&set,THR_SERVER_ALARM);	// For alarms
#endif
2979
#ifndef IGNORE_SIGHUP_SIGQUIT
unknown's avatar
unknown committed
2980 2981
  (void) sigaddset(&set,SIGQUIT);
  (void) sigaddset(&set,SIGHUP);
2982 2983
#endif
  (void) sigaddset(&set,SIGTERM);
unknown's avatar
unknown committed
2984 2985 2986
  (void) sigaddset(&set,SIGTSTP);

  /* Save pid to this process (or thread on Linux) */
2987
  if (!opt_bootstrap)
2988 2989
    create_pid_file();

2990 2991 2992 2993 2994
  /*
    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
2995
    should not be any other mysql_cond_signal() calls.
2996
  */
Marc Alff's avatar
Marc Alff committed
2997 2998 2999
  mysql_mutex_lock(&LOCK_thread_count);
  mysql_mutex_unlock(&LOCK_thread_count);
  mysql_cond_broadcast(&COND_thread_count);
unknown's avatar
unknown committed
3000

3001
  (void) pthread_sigmask(SIG_BLOCK,&set,NULL);
unknown's avatar
unknown committed
3002 3003 3004 3005 3006
  for (;;)
  {
    int error;					// Used when debugging
    if (shutdown_in_progress && !abort_loop)
    {
3007
      sig= SIGTERM;
unknown's avatar
unknown committed
3008 3009 3010 3011 3012
      error=0;
    }
    else
      while ((error=my_sigwait(&set,&sig)) == EINTR) ;
    if (cleanup_done)
3013
    {
3014
      DBUG_PRINT("quit",("signal_handler: calling my_thread_end()"));
3015
      my_thread_end();
3016
      DBUG_LEAVE;                               // Must match DBUG_ENTER()
Sergei Golubchik's avatar
Sergei Golubchik committed
3017
      signal_thread_in_use= 0;
unknown's avatar
unknown committed
3018
      pthread_exit(0);				// Safety
3019
      return 0;                                 // Avoid compiler warnings
3020
    }
unknown's avatar
unknown committed
3021 3022 3023 3024 3025
    switch (sig) {
    case SIGTERM:
    case SIGQUIT:
    case SIGKILL:
#ifdef EXTRA_DEBUG
3026
      sql_print_information("Got signal %d to shutdown mysqld",sig);
unknown's avatar
unknown committed
3027
#endif
3028
      /* switch to the old log message processing */
3029 3030
      logger.set_handlers(LOG_FILE, opt_slow_log ? LOG_FILE:LOG_NONE,
                          opt_log ? LOG_FILE:LOG_NONE);
unknown's avatar
unknown committed
3031 3032 3033 3034
      DBUG_PRINT("info",("Got signal: %d  abort_loop: %d",sig,abort_loop));
      if (!abort_loop)
      {
	abort_loop=1;				// mark abort for threads
3035 3036 3037 3038 3039
#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
3040 3041
#ifdef USE_ONE_SIGNAL_HAND
	pthread_t tmp;
Marc Alff's avatar
Marc Alff committed
3042 3043 3044
        if (mysql_thread_create(0, /* Not instrumented */
                                &tmp, &connection_attrib, kill_server_thread,
                                (void*) &sig))
3045
	  sql_print_error("Can't create thread to kill server");
unknown's avatar
unknown committed
3046
#else
unknown's avatar
unknown committed
3047
	kill_server((void*) sig);	// MIT THREAD has a alarm thread
unknown's avatar
unknown committed
3048 3049 3050 3051
#endif
      }
      break;
    case SIGHUP:
unknown's avatar
unknown committed
3052 3053
      if (!abort_loop)
      {
3054
        int not_used;
unknown's avatar
Merge  
unknown committed
3055
	mysql_print_status();		// Print some debug info
unknown's avatar
unknown committed
3056 3057
	reload_acl_and_cache((THD*) 0,
			     (REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |
unknown's avatar
Merge  
unknown committed
3058
			      REFRESH_GRANT |
unknown's avatar
unknown committed
3059
			      REFRESH_THREADS | REFRESH_HOSTS),
unknown's avatar
unknown committed
3060
			     (TABLE_LIST*) 0, &not_used); // Flush logs
unknown's avatar
unknown committed
3061
      }
3062
      /* reenable logs after the options were reloaded */
3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074
      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
3075 3076 3077 3078 3079 3080 3081 3082
      break;
#ifdef USE_ONE_SIGNAL_HAND
    case THR_SERVER_ALARM:
      process_alarm(sig);			// Trigger alarms.
      break;
#endif
    default:
#ifdef EXTRA_DEBUG
3083
      sql_print_warning("Got signal: %d  error: %d",sig,error); /* purecov: tested */
unknown's avatar
unknown committed
3084 3085 3086 3087 3088 3089 3090
#endif
      break;					/* purecov: tested */
    }
  }
  return(0);					/* purecov: deadcode */
}

unknown's avatar
unknown committed
3091
static void check_data_home(const char *path)
unknown's avatar
unknown committed
3092
{}
unknown's avatar
unknown committed
3093

3094
#endif /*!EMBEDDED_LIBRARY*/
unknown's avatar
unknown committed
3095 3096 3097
#endif	/* __WIN__*/


unknown's avatar
unknown committed
3098
/**
unknown's avatar
Merge  
unknown committed
3099
  All global error messages are sent here where the first one is stored
unknown's avatar
unknown committed
3100
  for the client.
unknown's avatar
unknown committed
3101 3102
*/
/* ARGSUSED */
Marc Alff's avatar
Marc Alff committed
3103
extern "C" void my_message_sql(uint error, const char *str, myf MyFlags);
3104

Marc Alff's avatar
Marc Alff committed
3105
void my_message_sql(uint error, const char *str, myf MyFlags)
unknown's avatar
unknown committed
3106
{
Marc Alff's avatar
Marc Alff committed
3107
  THD *thd= current_thd;
3108 3109
  MYSQL_ERROR::enum_warning_level level;
  sql_print_message_func func;
Sergei Golubchik's avatar
Sergei Golubchik committed
3110

unknown's avatar
unknown committed
3111
  DBUG_ENTER("my_message_sql");
3112
  DBUG_PRINT("error", ("error: %u  message: '%s'  Flag: %d", error, str, MyFlags));
3113 3114

  DBUG_ASSERT(str != NULL);
3115
  DBUG_ASSERT(error != 0);
3116

3117
  mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_ERROR, error, str);
3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132
  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;
  }
3133

Marc Alff's avatar
Marc Alff committed
3134
  if (thd)
unknown's avatar
unknown committed
3135
  {
Marc Alff's avatar
Marc Alff committed
3136 3137
    if (MyFlags & ME_FATALERROR)
      thd->is_fatal_error= 1;
Sergei Golubchik's avatar
Sergei Golubchik committed
3138
    (void) thd->raise_condition(error, NULL, level, str);
unknown's avatar
unknown committed
3139
  }
3140 3141

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

3144
  if (!thd || thd->log_all_errors || (MyFlags & ME_NOREFRESH))
3145
    (*func)("%s: %s", my_progname_short, str); /* purecov: inspected */
Marc Alff's avatar
Marc Alff committed
3146
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
3147 3148
}

3149

3150
#ifndef EMBEDDED_LIBRARY
3151 3152 3153 3154
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)
3155 3156 3157 3158 3159
{
  return my_malloc(size, MYF(MY_FAE));
}


3160
void my_str_free_mysqld(void *ptr)
3161
{
3162
  my_free(ptr);
3163
}
3164
#endif /* EMBEDDED_LIBRARY */
3165 3166


unknown's avatar
unknown committed
3167 3168
#ifdef __WIN__

3169
pthread_handler_t handle_shutdown(void *arg)
unknown's avatar
unknown committed
3170 3171 3172 3173 3174 3175
{
  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
3176
#if !defined(EMBEDDED_LIBRARY)
unknown's avatar
unknown committed
3177
  if (WaitForSingleObject(hEventShutdown,INFINITE)==WAIT_OBJECT_0)
3178
#endif /* EMBEDDED_LIBRARY */
unknown's avatar
unknown committed
3179 3180 3181 3182 3183
     kill_server(MYSQL_KILL_SIGNAL);
  return 0;
}
#endif

3184
const char *load_default_groups[]= {
3185
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
3186 3187
"mysql_cluster",
#endif
3188 3189
"mysqld", "server", MYSQL_BASE_VERSION,
"mariadb", MARIADB_BASE_VERSION,
3190
"client-server",
3191
0, 0};
unknown's avatar
Merge  
unknown committed
3192

3193
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
3194 3195
static const int load_default_groups_sz=
sizeof(load_default_groups)/sizeof(load_default_groups[0]);
unknown's avatar
Merge  
unknown committed
3196
#endif
unknown's avatar
unknown committed
3197

unknown's avatar
unknown committed
3198

3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211
#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
3212 3213
/**
  Initialize one of the global date/time format variables.
3214

unknown's avatar
unknown committed
3215 3216
  @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
3217

unknown's avatar
unknown committed
3218
  @retval
3219
    0 ok
unknown's avatar
unknown committed
3220
  @retval
3221 3222 3223
    1 error
*/

unknown's avatar
unknown committed
3224
static bool init_global_datetime_format(timestamp_type format_type,
3225
                                        DATE_TIME_FORMAT *format)
3226
{
3227 3228 3229 3230 3231
  /*
    Get command line option
    format->format.str is already set by my_getopt
  */
  format->format.length= strlen(format->format.str);
3232

3233
  if (parse_date_time_format(format_type, format))
3234
  {
3235 3236 3237
    fprintf(stderr, "Wrong date/time format specifier: %s\n",
            format->format.str);
    return true;
3238
  }
3239
  return false;
3240 3241
}

unknown's avatar
unknown committed
3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 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
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
3313
  {"resignal",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RESIGNAL]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3314 3315 3316 3317 3318 3319 3320
  {"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
3321
  {"signal",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SIGNAL]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3322 3323 3324 3325
  {"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},
3326
  {"show_client_statistics",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CLIENT_STATS]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347
  {"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},
3348
  {"show_index_statistics",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_INDEX_STATS]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3349 3350 3351 3352 3353 3354 3355 3356 3357
  {"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
3358 3359
  {"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},
3360
  {"show_relaylog_events", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_RELAYLOG_EVENTS]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3361 3362 3363 3364
  {"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},
3365
  {"show_table_statistics",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATS]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3366 3367 3368
  {"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},
3369
  {"show_user_statistics",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_USER_STATS]), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3370 3371 3372 3373 3374 3375 3376 3377
  {"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
3378
  {"stmt_reprepare",       (char*) offsetof(STATUS_VAR, com_stmt_reprepare), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391
  {"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},
3392
  {NullS, NullS, SHOW_LONG}
unknown's avatar
unknown committed
3393
};
3394

Marc Alff's avatar
Marc Alff committed
3395
static int init_common_variables()
unknown's avatar
unknown committed
3396
{
unknown's avatar
unknown committed
3397
  umask(((~my_umask) & 0666));
unknown's avatar
Merge  
unknown committed
3398
  my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
Sergei Golubchik's avatar
Sergei Golubchik committed
3399

unknown's avatar
unknown committed
3400 3401
  tzset();			// Set tzname

3402 3403
  sf_leaking_memory= 0; // no memory leaks from now on

unknown's avatar
SCRUM  
unknown committed
3404
  max_system_variables.pseudo_thread_id= (ulong)~0;
3405
  server_start_time= flush_status_time= my_time(0);
3406

3407 3408
  rpl_filter= new Rpl_filter;
  binlog_filter= new Rpl_filter;
unknown's avatar
unknown committed
3409
  if (!rpl_filter || !binlog_filter)
3410 3411
  {
    sql_perror("Could not allocate replication and binlog filters");
3412
    return 1;
3413 3414
  }

3415 3416
  if (init_thread_environment() ||
      mysql_init_variables())
unknown's avatar
unknown committed
3417
    return 1;
unknown's avatar
unknown committed
3418

unknown's avatar
unknown committed
3419
#ifdef HAVE_TZNAME
3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435
  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 */
3436

3437
  /*
unknown's avatar
unknown committed
3438
    We set SYSTEM time zone as reasonable default and
3439 3440 3441 3442 3443
    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
3444

3445 3446 3447 3448 3449 3450 3451 3452 3453
#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,
3454 3455
                             key_file_binlog_index,
                             key_BINLOG_COND_queue_busy);
3456 3457
#endif

unknown's avatar
unknown committed
3458
  /*
3459
    Init mutexes for the global MYSQL_BIN_LOG objects.
unknown's avatar
unknown committed
3460
    As safe_mutex depends on what MY_INIT() does, we can't init the mutexes of
3461 3462
    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
3463 3464
  */
  mysql_bin_log.init_pthread_objects();
3465

3466 3467 3468 3469 3470 3471 3472
  /* 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;
  }

3473 3474
  if (gethostname(glob_hostname,sizeof(glob_hostname)) < 0)
  {
3475 3476 3477 3478
    /*
      Get hostname of computer (used by 'show variables') and as default
      basename for the pid file if --log-basename is not given.
    */
3479 3480
    strmake(glob_hostname, STRING_WITH_LEN("localhost"));
    sql_print_warning("gethostname failed, using '%s' as hostname",
3481
                        glob_hostname);
Sergei Golubchik's avatar
Sergei Golubchik committed
3482
    opt_log_basename= const_cast<char *>("mysql");
3483 3484
  }
  else
Sergei Golubchik's avatar
Sergei Golubchik committed
3485
    opt_log_basename= glob_hostname;
3486

Sergei Golubchik's avatar
Sergei Golubchik committed
3487
  if (!*pidfile_name)
3488
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
3489 3490
    strmake(pidfile_name, opt_log_basename, sizeof(pidfile_name)-5);
    strmov(fn_ext(pidfile_name),".pid");		// Add proper extension
3491
  }
unknown's avatar
unknown committed
3492

3493 3494 3495 3496 3497 3498 3499
  /*
    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.
3500 3501 3502 3503

    From MySQL 5.5 onwards, the default storage engine is InnoDB
    (except in the embedded server, where the default continues to
    be MyISAM)
3504
  */
3505
#if defined(WITH_INNOBASE_STORAGE_ENGINE) || defined(WITH_XTRADB_STORAGE_ENGINE)
3506
  default_storage_engine= const_cast<char *>("InnoDB");
3507 3508
#else
  default_storage_engine= const_cast<char *>("MyISAM");
3509
#endif
3510

3511 3512 3513
  /*
    Add server status variables to the dynamic list of
    status variables that is shown by SHOW STATUS.
3514
    Later, in plugin_init, and mysql_install_plugin
3515 3516 3517 3518 3519
    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
3520 3521 3522 3523 3524
#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
3525
    There are 8 Com_ variables which don't have corresponding SQLCOM_ values:
unknown's avatar
unknown committed
3526 3527 3528 3529 3530 3531 3532 3533
    (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
3534
      Com_stmt_reprepare       => com_stmt_reprepare
unknown's avatar
unknown committed
3535 3536 3537
      Com_stmt_reset           => com_stmt_reset
      Com_stmt_send_long_data  => com_stmt_send_long_data

3538 3539 3540
    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
3541
  */
3542
  compile_time_assert(sizeof(com_status_vars)/sizeof(com_status_vars[0]) - 1 ==
unknown's avatar
unknown committed
3543
                     SQLCOM_END + 8);
unknown's avatar
unknown committed
3544 3545
#endif

Marc Alff's avatar
Marc Alff committed
3546
  if (get_options(&remaining_argc, &remaining_argv))
3547
    return 1;
3548 3549
  set_server_version();

3550
#ifndef EMBEDDED_LIBRARY
3551
  if (opt_abort && !opt_verbose)
3552 3553 3554
    unireg_abort(0);
#endif /*!EMBEDDED_LIBRARY*/

unknown's avatar
unknown committed
3555 3556 3557
  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
3558 3559 3560 3561
#ifdef HAVE_LARGE_PAGES
  /* Initialize large page size */
  if (opt_large_pages && (opt_large_page_size= my_get_large_page_size()))
  {
3562 3563
      DBUG_PRINT("info", ("Large page set, large_page_size = %d",
                 opt_large_page_size));
unknown's avatar
Merge  
unknown committed
3564 3565 3566
      my_use_large_pages= 1;
      my_large_page_size= opt_large_page_size;
  }
3567 3568 3569 3570 3571 3572 3573 3574
  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
3575
#endif /* HAVE_LARGE_PAGES */
3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591
#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;
3592
   size_t max_desired_page_size;
3593
   if (opt_super_large_pages)
3594
     max_desired_page_size= SUPER_LARGE_PAGESIZE;
3595
   else
3596
     max_desired_page_size= LARGE_PAGESIZE;
3597 3598 3599 3600 3601 3602
   nelem = getpagesizes(NULL, 0);
   if (nelem > 0)
   {
     size_t *pagesize = (size_t *) malloc(sizeof(size_t) * nelem);
     if (pagesize != NULL && getpagesizes(pagesize, nelem) > 0)
     {
3603 3604
       size_t max_page_size= 0;
       for (int i= 0; i < nelem; i++)
3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625
       {
         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
3626

unknown's avatar
unknown committed
3627 3628
  /* connections and databases needs lots of files */
  {
3629
    uint files, wanted_files, max_open_files;
3630

3631
    /* MyISAM requires two file handles per table. */
3632 3633
    wanted_files= (10 + max_connections + extra_max_connections +
                   table_cache_size*2);
3634 3635 3636 3637 3638 3639 3640 3641 3642 3643
    /*
      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).
    */
3644 3645
    max_open_files= max(max(wanted_files,
                            (max_connections + extra_max_connections)*5),
3646 3647
                        open_files_limit);
    files= my_set_max_open_files(max_open_files);
3648 3649

    if (files < wanted_files)
unknown's avatar
unknown committed
3650
    {
3651 3652
      if (!open_files_limit)
      {
3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666
        /*
          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
3667
                                      table_cache_size);
3668 3669 3670
	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
3671
	if (global_system_variables.log_warnings)
3672
	  sql_print_warning("Changed limits: max_open_files: %u  max_connections: %ld  table_cache: %ld",
3673 3674
			files, max_connections, table_cache_size);
      }
unknown's avatar
unknown committed
3675
      else if (global_system_variables.log_warnings)
3676
	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
3677
    }
unknown's avatar
unknown committed
3678
    open_files_limit= files;
unknown's avatar
unknown committed
3679 3680
  }
  unireg_init(opt_specialflag); /* Set up extern variabels */
3681 3682 3683 3684 3685 3686 3687
  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;
3688 3689
  if (init_errmessage())	/* Read error messages from file */
    return 1;
3690
  init_client_errs();
Sergei Golubchik's avatar
Sergei Golubchik committed
3691
  mysql_library_init(unused,unused,unused); /* for replication */
unknown's avatar
unknown committed
3692
  lex_init();
3693 3694
  if (item_create_init())
    return 1;
unknown's avatar
unknown committed
3695
  item_init();
3696 3697 3698 3699
#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
3700
#endif
3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727
  /*
    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;
  }

3728 3729
  if (default_collation_name)
  {
unknown's avatar
unknown committed
3730 3731
    CHARSET_INFO *default_collation;
    default_collation= get_charset_by_name(default_collation_name, MYF(0));
unknown's avatar
unknown committed
3732 3733
    if (!default_collation)
    {
3734
      sql_print_error(ER_DEFAULT(ER_UNKNOWN_COLLATION), default_collation_name);
unknown's avatar
unknown committed
3735 3736 3737
      return 1;
    }
    if (!my_charset_same(default_charset_info, default_collation))
3738
    {
3739
      sql_print_error(ER_DEFAULT(ER_COLLATION_CHARSET_MISMATCH),
3740 3741 3742 3743 3744 3745
		      default_collation_name,
		      default_charset_info->csname);
      return 1;
    }
    default_charset_info= default_collation;
  }
3746 3747 3748 3749
  /* 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;
3750
  global_system_variables.character_set_results= default_charset_info;
3751
  global_system_variables.character_set_client=  default_charset_info;
3752

3753
  if (!(character_set_filesystem=
unknown's avatar
unknown committed
3754 3755 3756 3757 3758
        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;

3759 3760 3761
  if (!(my_default_lc_time_names=
        my_locale_by_name(lc_time_names_name)))
  {
unknown's avatar
unknown committed
3762
    sql_print_error("Unknown locale: '%s'", lc_time_names_name);
3763 3764 3765
    return 1;
  }
  global_system_variables.lc_time_names= my_default_lc_time_names;
3766

3767
  /* check log options and issue warnings if needed */
3768 3769
  if (opt_log && opt_logname && *opt_logname &&
      !(log_output_options & (LOG_FILE | LOG_NONE)))
3770 3771
    sql_print_warning("Although a path was specified for the "
                      "--log option, log tables are used. "
3772
                      "To enable logging to files use the --log-output option.");
3773

3774 3775
  if (opt_slow_log && opt_slow_logname && *opt_slow_logname &&
      !(log_output_options & (LOG_FILE | LOG_NONE)))
3776
    sql_print_warning("Although a path was specified for the "
Konstantin Osipov's avatar
Konstantin Osipov committed
3777
                      "--log-slow-queries option, log tables are used. "
3778
                      "To enable logging to files use the --log-output=file option.");
3779

Sergei Golubchik's avatar
Sergei Golubchik committed
3780 3781 3782 3783
  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);
3784

3785 3786 3787 3788 3789 3790
#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) */

3791
#if (ENABLE_TEMP_POOL)
3792
  if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
3793
    return 1;
3794 3795 3796 3797
#else
  use_temp_pool= 0;
#endif

3798
  if (my_dboptions_cache_init())
unknown's avatar
unknown committed
3799 3800
    return 1;

3801 3802 3803 3804 3805 3806
  /*
    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));
3807 3808
  lower_case_file_system= test_if_case_insensitive(mysql_real_data_home);
  if (!lower_case_table_names && lower_case_file_system == 1)
3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827
  {
    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 &&
3828
           !(lower_case_file_system= (lower_case_file_system == 1)))
3829 3830 3831 3832 3833 3834 3835 3836
  {
    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;
  }
3837 3838
  else
  {
3839
    lower_case_file_system= (lower_case_file_system == 1);
3840
  }
3841 3842 3843 3844 3845 3846

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

unknown's avatar
unknown committed
3847 3848
  return 0;
}
unknown's avatar
unknown committed
3849

3850 3851

static int init_thread_environment()
unknown's avatar
unknown committed
3852
{
Marc Alff's avatar
Marc Alff committed
3853
  mysql_mutex_init(key_LOCK_thread_count, &LOCK_thread_count, MY_MUTEX_INIT_FAST);
Marc Alff's avatar
Marc Alff committed
3854
  mysql_mutex_init(key_LOCK_status, &LOCK_status, MY_MUTEX_INIT_FAST);
Marc Alff's avatar
Marc Alff committed
3855
  mysql_mutex_init(key_LOCK_delayed_insert,
Marc Alff's avatar
Marc Alff committed
3856 3857 3858 3859 3860
                   &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
3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871
  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);
3872
  mysql_mutex_init(key_LOCK_uuid_short_generator,
Sergei Golubchik's avatar
Sergei Golubchik committed
3873
                   &LOCK_short_uuid_generator, MY_MUTEX_INIT_FAST);
Marc Alff's avatar
Marc Alff committed
3874 3875
  mysql_mutex_init(key_LOCK_connection_count,
                   &LOCK_connection_count, MY_MUTEX_INIT_FAST);
3876 3877 3878 3879 3880 3881 3882
  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
3883 3884 3885 3886
  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);
3887

3888
#ifdef HAVE_OPENSSL
Marc Alff's avatar
Marc Alff committed
3889 3890
  mysql_mutex_init(key_LOCK_des_key_file,
                   &LOCK_des_key_file, MY_MUTEX_INIT_FAST);
unknown's avatar
unknown committed
3891 3892 3893 3894
#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)
3895
    mysql_rwlock_init(key_rwlock_openssl, &openssl_stdlocks[i].lock);
unknown's avatar
unknown committed
3896 3897 3898 3899 3900 3901
  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
3902
#endif
Marc Alff's avatar
Marc Alff committed
3903 3904 3905
  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
3906 3907 3908
  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
3909
#ifdef HAVE_REPLICATION
Marc Alff's avatar
Marc Alff committed
3910 3911
  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);
3912
#endif
Marc Alff's avatar
Marc Alff committed
3913 3914 3915
  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
3916
  sp_cache_init();
3917
#ifdef HAVE_EVENT_SCHEDULER
3918
  Events::init_mutexes();
3919
#endif
unknown's avatar
unknown committed
3920 3921 3922 3923 3924
  /* 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
3925

unknown's avatar
unknown committed
3926 3927 3928 3929 3930 3931 3932 3933 3934
  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;
}

3935

unknown's avatar
unknown committed
3936
#if defined(HAVE_OPENSSL) && !defined(HAVE_YASSL)
3937
static unsigned long openssl_id_function()
3938
{
3939
  return (unsigned long) pthread_self();
3940
}
3941 3942 3943


static openssl_lock_t *openssl_dynlock_create(const char *file, int line)
3944
{
3945
  openssl_lock_t *lock= new openssl_lock_t;
3946
  mysql_rwlock_init(key_rwlock_openssl, &lock->lock);
3947 3948 3949 3950
  return lock;
}


3951
static void openssl_dynlock_destroy(openssl_lock_t *lock, const char *file,
3952 3953
				    int line)
{
3954
  mysql_rwlock_destroy(&lock->lock);
3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970
  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);
}


3971
static void openssl_lock(int mode, openssl_lock_t *lock, const char *file,
3972 3973 3974 3975 3976 3977 3978 3979
			 int line)
{
  int err;
  char const *what;

  switch (mode) {
  case CRYPTO_LOCK|CRYPTO_READ:
    what = "read lock";
3980
    err= mysql_rwlock_rdlock(&lock->lock);
3981 3982 3983
    break;
  case CRYPTO_LOCK|CRYPTO_WRITE:
    what = "write lock";
3984
    err= mysql_rwlock_wrlock(&lock->lock);
3985 3986 3987 3988
    break;
  case CRYPTO_UNLOCK|CRYPTO_READ:
  case CRYPTO_UNLOCK|CRYPTO_WRITE:
    what = "unlock";
3989
    err= mysql_rwlock_unlock(&lock->lock);
3990 3991 3992 3993 3994 3995
    break;
  default:
    /* Unknown locking mode. */
    sql_print_error("Fatal: OpenSSL interface problem (mode=0x%x)", mode);
    abort();
  }
3996
  if (err)
3997
  {
3998
    sql_print_error("Fatal: can't %s OpenSSL lock", what);
3999 4000 4001 4002 4003 4004
    abort();
  }
}
#endif /* HAVE_OPENSSL */


unknown's avatar
unknown committed
4005 4006
static void init_ssl()
{
unknown's avatar
unknown committed
4007
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
unknown's avatar
unknown committed
4008 4009
  if (opt_use_ssl)
  {
4010 4011
    enum enum_ssl_init_error error= SSL_INITERR_NOERROR;

4012 4013 4014
    /* 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,
4015
					  opt_ssl_cipher, &error);
unknown's avatar
Merge  
unknown committed
4016
    DBUG_PRINT("info",("ssl_acceptor_fd: 0x%lx", (long) ssl_acceptor_fd));
unknown's avatar
unknown committed
4017
    if (!ssl_acceptor_fd)
4018
    {
4019
      sql_print_warning("Failed to setup SSL");
4020
      sql_print_warning("SSL error: %s", sslGetErrString(error));
unknown's avatar
unknown committed
4021
      opt_use_ssl = 0;
4022
      have_ssl= SHOW_OPTION_DISABLED;
4023 4024 4025 4026
    }
  }
  else
  {
4027
    have_ssl= SHOW_OPTION_DISABLED;
unknown's avatar
unknown committed
4028
  }
unknown's avatar
unknown committed
4029 4030
  if (des_key_file)
    load_des_key_file(des_key_file);
unknown's avatar
unknown committed
4031
#endif /* HAVE_OPENSSL && ! EMBEDDED_LIBRARY */
unknown's avatar
unknown committed
4032
}
unknown's avatar
unknown committed
4033

4034

4035 4036 4037
static void end_ssl()
{
#ifdef HAVE_OPENSSL
Konstantin Osipov's avatar
Konstantin Osipov committed
4038
#ifndef EMBEDDED_LIBRARY
4039 4040 4041 4042 4043
  if (ssl_acceptor_fd)
  {
    free_vio_ssl_acceptor_fd(ssl_acceptor_fd);
    ssl_acceptor_fd= 0;
  }
Konstantin Osipov's avatar
Konstantin Osipov committed
4044
#endif /* ! EMBEDDED_LIBRARY */
4045 4046 4047
#endif /* HAVE_OPENSSL */
}

4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073
#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
4074

unknown's avatar
unknown committed
4075 4076
static int init_server_components()
{
4077
  DBUG_ENTER("init_server_components");
unknown's avatar
unknown committed
4078 4079 4080 4081
  /*
    We need to call each of these following functions to ensure that
    all things are initialized so that unireg_abort() doesn't fail
  */
4082 4083
  mdl_init();
  if (table_def_init() | hostname_cache_init())
4084
    unireg_abort(1);
unknown's avatar
unknown committed
4085

4086
  query_cache_set_min_res_unit(query_cache_min_res_unit);
unknown's avatar
unknown committed
4087
  query_cache_init();
unknown's avatar
unknown committed
4088
  query_cache_resize(query_cache_size);
4089
  my_rnd_init(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2);
4090
  setup_fpu();
unknown's avatar
unknown committed
4091
  init_thr_lock();
4092
  my_uuid_init((ulong) (my_rnd(&sql_rand))*12345,12345);
unknown's avatar
SCRUM  
unknown committed
4093
#ifdef HAVE_REPLICATION
4094
  init_slave_list();
4095
#endif
Sergei Golubchik's avatar
Sergei Golubchik committed
4096
  wt_init();
unknown's avatar
unknown committed
4097

4098 4099
  /* Setup logs */

4100 4101 4102 4103 4104
  /*
    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.
  */
4105
  if (opt_error_log && !opt_abort)
4106 4107
  {
    if (!log_error_file_ptr[0])
4108
      fn_format(log_error_file, pidfile_name, mysql_data_home, ".err",
4109 4110 4111 4112
                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);
4113 4114 4115 4116 4117
    /*
      _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;
4118
    if (!log_error_file[0])
4119
      opt_error_log= 0;                         // Too long file name
4120 4121
    else
    {
4122
      my_bool res;
4123
#ifndef EMBEDDED_LIBRARY
4124 4125 4126
      res= reopen_fstreams(log_error_file, stdout, stderr);
#else
      res= reopen_fstreams(log_error_file, NULL, stderr);
4127
#endif
4128 4129 4130

      if (!res)
        setbuf(stderr, NULL);
4131 4132 4133 4134 4135

#ifdef _WIN32
      /* Add error log to windows crash reporting. */
      add_file_to_crash_report(log_error_file);
#endif
4136 4137 4138
    }
  }

4139 4140
  /* set up the hook before initializing plugins which may use it */
  error_handler_hook= my_message_sql;
4141 4142
  proc_info_hook= set_thd_proc_info;

Marc Alff's avatar
Marc Alff committed
4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154
#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
4155 4156 4157 4158 4159 4160
  if (xid_cache_init())
  {
    sql_print_error("Out of memory");
    unireg_abort(1);
  }

4161 4162 4163 4164
  /*
    initialize delegates for extension observers, errors have already
    been reported in the function
  */
He Zhenxing's avatar
He Zhenxing committed
4165 4166 4167
  if (delegates_init())
    unireg_abort(1);

unknown's avatar
unknown committed
4168
  /* need to configure logging before initializing storage engines */
unknown's avatar
Merge  
unknown committed
4169
  if (opt_log_slave_updates && !opt_bin_log)
unknown's avatar
unknown committed
4170
  {
4171
    sql_print_warning("You need to use --log-bin to make "
4172
                    "--log-slave-updates work.");
4173
  }
4174 4175 4176
  if (!opt_bin_log && binlog_format_used)
    sql_print_warning("You need to use --log-bin to make "
                      "--binlog-format work.");
4177

4178
  /* Check that we have not let the format to unspecified at this point */
4179
  DBUG_ASSERT((uint)global_system_variables.binlog_format <=
4180
              array_elements(binlog_format_names)-1);
4181

unknown's avatar
unknown committed
4182
#ifdef HAVE_REPLICATION
unknown's avatar
unknown committed
4183 4184
  if (opt_log_slave_updates && replicate_same_server_id)
  {
4185 4186 4187
    if (opt_bin_log)
    {
      sql_print_error("using --replicate-same-server-id in conjunction with \
unknown's avatar
unknown committed
4188 4189
--log-slave-updates is impossible, it would lead to infinite loops in this \
server.");
4190 4191 4192 4193 4194 4195
      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
4196
  }
unknown's avatar
unknown committed
4197
#endif
4198

unknown's avatar
Merge  
unknown committed
4199
  if (opt_bin_log)
4200
  {
4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221
    /* 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
4222 4223 4224 4225
    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)
4226 4227
    {
      /*
unknown's avatar
Merge  
unknown committed
4228 4229 4230 4231 4232
        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.
4233
      */
4234 4235 4236 4237
      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
4238
                        "changed! Please use '--log-basename=%s' or "
4239
                        "'--log-bin=%s' to avoid this problem.",
Sergei Golubchik's avatar
Sergei Golubchik committed
4240
                        opt_log_basename, ln);
4241
    }
unknown's avatar
Merge  
unknown committed
4242
    if (ln == buf)
4243
    {
4244
      opt_bin_logname= my_once_strdup(buf, MYF(MY_WME));
4245
    }
4246
    if (mysql_bin_log.open_index_file(opt_binlog_index_name, ln, TRUE))
unknown's avatar
unknown committed
4247 4248 4249
    {
      unireg_abort(1);
    }
4250 4251
  }

4252
  /* call ha_init_key_cache() on all key caches to init them */
4253
  process_key_caches(&ha_init_key_cache, 0);
4254

4255 4256 4257
  init_global_table_stats();
  init_global_index_stats();

4258 4259 4260 4261
  /* Allow storage engine to give real error messages */
  if (ha_init_errors())
    DBUG_RETURN(1);

Marc Alff's avatar
Marc Alff committed
4262
  if (plugin_init(&remaining_argc, remaining_argv,
4263
                  (opt_noacl ? PLUGIN_INIT_SKIP_PLUGIN_TABLE : 0) |
4264
                  (opt_abort ? PLUGIN_INIT_SKIP_INITIALIZATION : 0)))
4265 4266 4267
  {
    sql_print_error("Failed to initialize plugins.");
    unireg_abort(1);
unknown's avatar
unknown committed
4268
  }
4269
  plugins_are_initialized= TRUE;  /* Don't separate from init function */
unknown's avatar
unknown committed
4270

4271 4272 4273 4274 4275 4276
  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
4277 4278

  /* we do want to exit if there are any other unknown options */
Marc Alff's avatar
Marc Alff committed
4279
  if (remaining_argc > 1)
unknown's avatar
unknown committed
4280 4281
  {
    int ho_error;
unknown's avatar
unknown committed
4282
    struct my_option no_opts[]=
unknown's avatar
unknown committed
4283 4284 4285 4286 4287
    {
      {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
4288
      that there are unprocessed options.
unknown's avatar
unknown committed
4289 4290
    */
    my_getopt_skip_unknown= 0;
unknown's avatar
unknown committed
4291

Marc Alff's avatar
Marc Alff committed
4292
    if ((ho_error= handle_options(&remaining_argc, &remaining_argv, no_opts,
4293
                                  mysqld_get_one_option)))
unknown's avatar
unknown committed
4294
      unireg_abort(ho_error);
Marc Alff's avatar
Marc Alff committed
4295 4296 4297
    /* Add back the program name handle_options removes */
    remaining_argc++;
    remaining_argv--;
4298
    my_getopt_skip_unknown= TRUE;
unknown's avatar
unknown committed
4299

Marc Alff's avatar
Marc Alff committed
4300
    if (remaining_argc > 1)
unknown's avatar
unknown committed
4301
    {
4302
      fprintf(stderr, "%s: Too many arguments (first extra is '%s').\n",
Marc Alff's avatar
Marc Alff committed
4303
              my_progname, remaining_argv[1]);
unknown's avatar
unknown committed
4304 4305
      unireg_abort(1);
    }
unknown's avatar
unknown committed
4306 4307
  }

4308
  if (opt_abort)
4309 4310
    unireg_abort(0);

unknown's avatar
unknown committed
4311
  /* if the errmsg.sys is not loaded, terminate to maintain behaviour */
4312 4313
  if (!DEFAULT_ERRMSGS[0][0])
    unireg_abort(1);  
unknown's avatar
unknown committed
4314

unknown's avatar
unknown committed
4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341
  /* 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
4342 4343
    LEX_STRING csv_name={C_STRING_WITH_LEN("csv")};
    if (!plugin_is_ready(&csv_name, MYSQL_STORAGE_ENGINE_PLUGIN))
unknown's avatar
unknown committed
4344
    {
4345
      /* purecov: begin inspected */
unknown's avatar
unknown committed
4346 4347
      sql_print_error("CSV engine is not present, falling back to the "
                      "log files");
unknown's avatar
unknown committed
4348
      log_output_options= (log_output_options & ~LOG_TABLE) | LOG_FILE;
4349
      /* purecov: end */
unknown's avatar
unknown committed
4350 4351 4352 4353 4354 4355
    }

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

4356
  /*
4357
    Set the default storage engine
4358
  */
4359 4360 4361 4362 4363 4364
  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
4365
  {
4366 4367 4368 4369 4370 4371 4372
    sql_print_error("Unknown/unsupported storage engine: %s",
                    default_storage_engine);
    unireg_abort(1);
  }
  if (!ha_storage_engine_is_enabled(hton))
  {
    if (!opt_bootstrap)
4373
    {
4374 4375
      sql_print_error("Default storage engine (%s) is not available",
                      default_storage_engine);
4376 4377
      unireg_abort(1);
    }
4378 4379 4380 4381 4382 4383 4384 4385
    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
4386
    mysql_mutex_lock(&LOCK_global_system_variables);
4387 4388
    plugin_unlock(0, global_system_variables.table_plugin);
    global_system_variables.table_plugin= plugin;
Sergei Golubchik's avatar
Sergei Golubchik committed
4389
    mysql_mutex_unlock(&LOCK_global_system_variables);
4390
  }
4391
#if defined(WITH_ARIA_STORAGE_ENGINE) && defined(USE_ARIA_FOR_TMP_TABLES)
4392
  if (!ha_storage_engine_is_enabled(maria_hton) && !opt_bootstrap)
4393
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
4394
    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");
4395 4396
    unireg_abort(1);
  }
4397 4398 4399 4400 4401
  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();
4402
#endif
4403

unknown's avatar
unknown committed
4404 4405 4406 4407
  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
4408

unknown's avatar
unknown committed
4409
  if (tc_log->open(opt_bin_log ? opt_bin_logname : opt_tc_log_file))
unknown's avatar
Merge  
unknown committed
4410 4411 4412 4413 4414
  {
    sql_print_error("Can't init tc log");
    unireg_abort(1);
  }

unknown's avatar
unknown committed
4415 4416 4417 4418 4419
  if (ha_recover(0))
  {
    unireg_abort(1);
  }

unknown's avatar
Merge  
unknown committed
4420
  if (opt_bin_log && mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0,
4421
                                        WRITE_CACHE, 0, max_binlog_size, 0, TRUE))
unknown's avatar
unknown committed
4422
    unireg_abort(1);
unknown's avatar
Merge  
unknown committed
4423 4424 4425

#ifdef HAVE_REPLICATION
  if (opt_bin_log && expire_logs_days)
4426
  {
4427
    time_t purge_time= server_start_time - expire_logs_days*24*60*60;
unknown's avatar
Merge  
unknown committed
4428 4429
    if (purge_time >= 0)
      mysql_bin_log.purge_logs_before_date(purge_time);
4430
  }
unknown's avatar
Merge  
unknown committed
4431 4432 4433 4434
#endif

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

unknown's avatar
unknown committed
4436
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && !defined(EMBEDDED_LIBRARY)
4437
  if (locked_in_memory && !getuid())
4438
  {
4439
    if (setreuid((uid_t)-1, 0) == -1)
4440
    {                        // this should never happen
4441
      sql_perror("setreuid");
4442 4443
      unireg_abort(1);
    }
4444 4445
    if (mlockall(MCL_CURRENT))
    {
4446
      if (global_system_variables.log_warnings)
4447
	sql_print_warning("Failed to lock memory. Errno: %d\n",errno);
unknown's avatar
unknown committed
4448
      locked_in_memory= 0;
4449
    }
4450 4451
    if (user_info)
      set_user(mysqld_user, user_info);
4452
  }
unknown's avatar
unknown committed
4453
  else
4454
#endif
unknown's avatar
unknown committed
4455
    locked_in_memory=0;
4456

4457
  ft_init_stopwords();
unknown's avatar
unknown committed
4458

unknown's avatar
unknown committed
4459
  init_max_user_conn();
4460
  init_update_queries();
4461 4462
  init_global_user_stats();
  init_global_client_stats();
4463
  DBUG_RETURN(0);
unknown's avatar
unknown committed
4464
}
unknown's avatar
unknown committed
4465

4466

4467
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
4468

unknown's avatar
unknown committed
4469 4470 4471
static void create_shutdown_thread()
{
#ifdef __WIN__
4472 4473
  hEventShutdown=CreateEvent(0, FALSE, FALSE, shutdown_event_name);
  pthread_t hThread;
Marc Alff's avatar
Marc Alff committed
4474 4475
  if (mysql_thread_create(key_thread_handle_shutdown,
                          &hThread, &connection_attrib, handle_shutdown, 0))
4476
    sql_print_warning("Can't create thread to handle shutdown requests");
unknown's avatar
unknown committed
4477

4478 4479
  // On "Stop Service" we have to do regular shutdown
  Service.SetShutdownEvent(hEventShutdown);
unknown's avatar
unknown committed
4480
#endif /* __WIN__ */
unknown's avatar
unknown committed
4481
}
unknown's avatar
unknown committed
4482

4483
#endif /* EMBEDDED_LIBRARY */
4484 4485


Vladislav Vaintroub's avatar
Vladislav Vaintroub committed
4486
#if (defined(_WIN32) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY)
4487
static void handle_connections_methods()
unknown's avatar
unknown committed
4488
{
4489 4490
  pthread_t hThread;
  DBUG_ENTER("handle_connections_methods");
unknown's avatar
unknown committed
4491
  if (hPipe == INVALID_HANDLE_VALUE &&
4492 4493
      (!have_tcpip || opt_disable_networking) &&
      !opt_enable_shared_memory)
unknown's avatar
unknown committed
4494
  {
unknown's avatar
unknown committed
4495
    sql_print_error("TCP/IP, --shared-memory, or --named-pipe should be configured on NT OS");
4496
    unireg_abort(1);				// Will not return
unknown's avatar
unknown committed
4497
  }
4498

Marc Alff's avatar
Marc Alff committed
4499 4500
  mysql_mutex_lock(&LOCK_thread_count);
  mysql_cond_init(key_COND_handler_count, &COND_handler_count, NULL);
4501 4502
  handler_count=0;
  if (hPipe != INVALID_HANDLE_VALUE)
unknown's avatar
unknown committed
4503
  {
4504
    handler_count++;
Marc Alff's avatar
Marc Alff committed
4505 4506 4507
    if (mysql_thread_create(key_thread_handle_con_namedpipes,
                            &hThread, &connection_attrib,
                            handle_connections_namedpipes, 0))
unknown's avatar
unknown committed
4508
    {
4509
      sql_print_warning("Can't create thread to handle named pipes");
4510 4511 4512 4513 4514 4515
      handler_count--;
    }
  }
  if (have_tcpip && !opt_disable_networking)
  {
    handler_count++;
Marc Alff's avatar
Marc Alff committed
4516 4517 4518
    if (mysql_thread_create(key_thread_handle_con_sockets,
                            &hThread, &connection_attrib,
                            handle_connections_sockets_thread, 0))
4519
    {
4520
      sql_print_warning("Can't create thread to handle TCP/IP");
4521 4522 4523 4524 4525 4526 4527
      handler_count--;
    }
  }
#ifdef HAVE_SMEM
  if (opt_enable_shared_memory)
  {
    handler_count++;
Marc Alff's avatar
Marc Alff committed
4528 4529 4530
    if (mysql_thread_create(key_thread_handle_con_sharedmem,
                            &hThread, &connection_attrib,
                            handle_connections_shared_memory, 0))
4531
    {
4532
      sql_print_warning("Can't create thread to handle shared memory");
4533
      handler_count--;
unknown's avatar
unknown committed
4534 4535
    }
  }
4536
#endif
unknown's avatar
unknown committed
4537

4538
  while (handler_count > 0)
Marc Alff's avatar
Marc Alff committed
4539 4540
    mysql_cond_wait(&COND_handler_count, &LOCK_thread_count);
  mysql_mutex_unlock(&LOCK_thread_count);
4541 4542
  DBUG_VOID_RETURN;
}
4543 4544 4545

void decrement_handler_count()
{
Marc Alff's avatar
Marc Alff committed
4546
  mysql_mutex_lock(&LOCK_thread_count);
4547
  handler_count--;
Marc Alff's avatar
Marc Alff committed
4548 4549
  mysql_cond_signal(&COND_handler_count);
  mysql_mutex_unlock(&LOCK_thread_count);
4550
  my_thread_end();
4551 4552 4553
}
#else
#define decrement_handler_count()
Vladislav Vaintroub's avatar
Vladislav Vaintroub committed
4554
#endif /* defined(_WIN32) || defined(HAVE_SMEM) */
4555 4556


4557
#ifndef EMBEDDED_LIBRARY
4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594
#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
4595 4596 4597
#ifdef __WIN__
int win_main(int argc, char **argv)
#else
4598
int mysqld_main(int argc, char **argv)
unknown's avatar
unknown committed
4599 4600
#endif
{
Marc Alff's avatar
Marc Alff committed
4601 4602 4603 4604 4605
  /*
    Perform basic thread library and malloc initialization,
    to be able to read defaults files and parse options.
  */
  my_progname= argv[0];
4606
  sf_leaking_memory= 1; // no safemalloc memory leak reports if we exit early
4607 4608 4609
#ifdef HAVE_NPTL
  ld_assume_kernel_is_set= (getenv("LD_ASSUME_KERNEL") != 0);
#endif
4610 4611 4612
#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
4613
  {
4614
    fprintf(stderr, "my_init() failed.");
Marc Alff's avatar
Marc Alff committed
4615 4616
    return 1;
  }
4617
#endif
Marc Alff's avatar
Marc Alff committed
4618 4619 4620

  orig_argc= argc;
  orig_argv= argv;
4621
  my_getopt_use_args_separator= TRUE;
Marc Alff's avatar
Marc Alff committed
4622 4623
  if (load_defaults(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv))
    return 1;
4624
  my_getopt_use_args_separator= FALSE;
Marc Alff's avatar
Marc Alff committed
4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 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
  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.
    */
4716
    my_thread_global_reinit();
Marc Alff's avatar
Marc Alff committed
4717 4718 4719 4720
  }
#endif /* HAVE_PSI_INTERFACE */

  init_error_log_mutex();
4721

4722 4723 4724
  /* Initialize audit interface globals. Audit plugins are inited later. */
  mysql_audit_initialize();

4725 4726 4727 4728 4729 4730
  /*
    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
4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752
#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
4753
#ifdef _CUSTOMSTARTUPCONFIG_
unknown's avatar
unknown committed
4754 4755 4756
  if (_cust_check_startup())
  {
    / * _cust_check_startup will report startup failure error * /
unknown's avatar
Merge  
unknown committed
4757
    exit(1);
unknown's avatar
unknown committed
4758 4759
  }
#endif
unknown's avatar
unknown committed
4760

Marc Alff's avatar
Marc Alff committed
4761
  if (init_common_variables())
4762
    unireg_abort(1);				// Will do exit
unknown's avatar
unknown committed
4763 4764

  init_signals();
4765 4766 4767

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

4769
  (void) thr_setconcurrency(concurrency);	// 10 by default
unknown's avatar
unknown committed
4770

4771 4772
  select_thread=pthread_self();
  select_thread_in_use=1;
unknown's avatar
unknown committed
4773 4774 4775 4776 4777 4778

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

4779 4780
#ifndef DBUG_OFF
  test_lc_time_sz();
4781
  srand((uint) time(NULL)); 
4782 4783
#endif

unknown's avatar
unknown committed
4784 4785 4786
  /*
    We have enough space for fiddling with the argv, continue
  */
unknown's avatar
unknown committed
4787
  check_data_home(mysql_real_data_home);
4788
  if (my_setwd(mysql_real_data_home, opt_abort ? 0 : MYF(MY_WME)) && !opt_abort)
unknown's avatar
unknown committed
4789
    unireg_abort(1);				/* purecov: inspected */
unknown's avatar
unknown committed
4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800

  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
4801 4802
  if (opt_bin_log && !server_id)
  {
4803
    server_id= 1;
unknown's avatar
unknown committed
4804
#ifdef EXTRA_DEBUG
4805 4806 4807 4808
    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.");
4809
#endif
unknown's avatar
unknown committed
4810 4811
  }

4812 4813 4814 4815 4816 4817 4818 4819
  /* 
   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
4820
  if (init_server_components())
unknown's avatar
unknown committed
4821
    unireg_abort(1);
unknown's avatar
unknown committed
4822

4823
  init_ssl();
unknown's avatar
unknown committed
4824 4825
  network_init();

unknown's avatar
unknown committed
4826 4827 4828
#ifdef __WIN__
  if (!opt_console)
  {
4829 4830
    if (reopen_fstreams(log_error_file, stdout, stderr))
      unireg_abort(1);
4831
    setbuf(stderr, NULL);
unknown's avatar
unknown committed
4832
    FreeConsole();				// Remove window
4833
  }
unknown's avatar
unknown committed
4834 4835
#endif

4836 4837 4838 4839 4840 4841
  /*
   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
4842 4843 4844 4845 4846
  /*
    init signals & alarm
    After this we can't quit by a simple unireg_abort
  */
  start_signal_handler();				// Creates pidfile
4847

4848
  if (mysql_rm_tmp_tables() || acl_init(opt_noacl) ||
4849
      my_tz_init((THD *)0, default_tz_name, opt_bootstrap))
unknown's avatar
unknown committed
4850 4851 4852
  {
    abort_loop=1;
    select_thread_in_use=0;
4853

unknown's avatar
unknown committed
4854
    (void) pthread_kill(signal_thread, MYSQL_KILL_SIGNAL);
4855

4856

unknown's avatar
unknown committed
4857
    if (!opt_bootstrap)
Marc Alff's avatar
Marc Alff committed
4858
      mysql_file_delete(key_file_pid, pidfile_name, MYF(MY_WME)); // Not needed anymore
4859

4860
    if (unix_sock != INVALID_SOCKET)
4861
      unlink(mysqld_unix_port);
unknown's avatar
unknown committed
4862 4863
    exit(1);
  }
4864

unknown's avatar
unknown committed
4865
  if (!opt_noacl)
4866
    (void) grant_init();
unknown's avatar
unknown committed
4867

unknown's avatar
unknown committed
4868 4869 4870
  if (!opt_bootstrap)
    servers_init(0);

unknown's avatar
unknown committed
4871
  if (!opt_noacl)
4872 4873
  {
#ifdef HAVE_DLOPEN
unknown's avatar
unknown committed
4874 4875
    udf_init();
#endif
4876
  }
4877

4878
  init_status_vars();
unknown's avatar
unknown committed
4879 4880
  if (opt_bootstrap) /* If running with bootstrap, do not start replication. */
    opt_skip_slave_start= 1;
4881 4882

  binlog_unsafe_map_init();
4883 4884 4885 4886 4887 4888 4889 4890 4891 4892
  /*
    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);
  }
4893

Marc Alff's avatar
Marc Alff committed
4894 4895
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
  initialize_performance_schema_acl(opt_bootstrap);
4896 4897 4898 4899 4900 4901 4902 4903
  /*
    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
4904 4905 4906 4907
#endif

  initialize_information_schema_acl();

4908 4909 4910 4911 4912
  execute_ddl_log_recovery();

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

unknown's avatar
unknown committed
4913 4914
  if (opt_bootstrap)
  {
4915
    select_thread_in_use= 0;                    // Allow 'kill' to work
Marc Alff's avatar
Marc Alff committed
4916
    bootstrap(mysql_stdin);
4917 4918 4919 4920 4921 4922 4923
    if (!kill_in_progress)
      unireg_abort(bootstrap_error ? 1 : 0);
    else
    {
      sleep(2);                                 // Wait for kill
      exit(0);
    }
unknown's avatar
unknown committed
4924
  }
4925
  if (opt_init_file && *opt_init_file)
unknown's avatar
unknown committed
4926 4927 4928 4929
  {
    if (read_init_file(opt_init_file))
      unireg_abort(1);
  }
unknown's avatar
unknown committed
4930

Sergei Golubchik's avatar
Sergei Golubchik committed
4931 4932 4933 4934 4935
  /*
    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);
4936

unknown's avatar
unknown committed
4937
  create_shutdown_thread();
4938
  start_handle_manager();
unknown's avatar
unknown committed
4939

4940
  sql_print_information(ER_DEFAULT(ER_STARTUP),my_progname,server_version,
unknown's avatar
unknown committed
4941
                        ((unix_sock == INVALID_SOCKET) ? (char*) ""
unknown's avatar
Merge  
unknown committed
4942
                                                       : mysqld_unix_port),
unknown's avatar
unknown committed
4943
                         mysqld_port,
unknown's avatar
Merge  
unknown committed
4944
                         MYSQL_COMPILATION_COMMENT);
4945 4946 4947
#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
  Service.SetRunning();
#endif
unknown's avatar
unknown committed
4948

unknown's avatar
unknown committed
4949 4950

  /* Signal threads waiting for server to be started */
Marc Alff's avatar
Marc Alff committed
4951
  mysql_mutex_lock(&LOCK_server_started);
unknown's avatar
unknown committed
4952
  mysqld_server_started= 1;
Marc Alff's avatar
Marc Alff committed
4953 4954
  mysql_cond_signal(&COND_server_started);
  mysql_mutex_unlock(&LOCK_server_started);
unknown's avatar
unknown committed
4955

4956
#if defined(_WIN32) || defined(HAVE_SMEM)
4957
  handle_connections_methods();
unknown's avatar
unknown committed
4958
#else
4959 4960
  handle_connections_sockets();
#endif /* _WIN32 || HAVE_SMEM */
unknown's avatar
unknown committed
4961 4962

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

unknown's avatar
unknown committed
4964 4965 4966
  DBUG_PRINT("quit",("Exiting main thread"));

#ifndef __WIN__
unknown's avatar
unknown committed
4967
#ifdef EXTRA_DEBUG2
unknown's avatar
unknown committed
4968 4969
  sql_print_error("Before Lock_thread_count");
#endif
Marc Alff's avatar
Marc Alff committed
4970
  mysql_mutex_lock(&LOCK_thread_count);
unknown's avatar
unknown committed
4971
  DBUG_PRINT("quit", ("Got thread_count mutex"));
unknown's avatar
unknown committed
4972
  select_thread_in_use=0;			// For close_connections
Marc Alff's avatar
Marc Alff committed
4973 4974
  mysql_mutex_unlock(&LOCK_thread_count);
  mysql_cond_broadcast(&COND_thread_count);
unknown's avatar
unknown committed
4975
#ifdef EXTRA_DEBUG2
unknown's avatar
unknown committed
4976 4977
  sql_print_error("After lock_thread_count");
#endif
unknown's avatar
merge  
unknown committed
4978
#endif /* __WIN__ */
4979

4980 4981 4982 4983 4984 4985 4986 4987 4988
#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
4989
  /* Wait until cleanup is done */
Marc Alff's avatar
Marc Alff committed
4990
  mysql_mutex_lock(&LOCK_thread_count);
unknown's avatar
unknown committed
4991
  while (!ready_to_exit)
Marc Alff's avatar
Marc Alff committed
4992 4993
    mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
merge  
unknown committed
4994 4995

#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
unknown's avatar
merge  
unknown committed
4996 4997 4998 4999
  if (Service.IsNT() && start_mode)
    Service.Stop();
  else
  {
unknown's avatar
unknown committed
5000
    Service.SetShutdownEvent(0);
unknown's avatar
merge  
unknown committed
5001 5002 5003
    if (hEventShutdown)
      CloseHandle(hEventShutdown);
  }
unknown's avatar
unknown committed
5004
#endif
5005
  mysqld_exit(0);
5006
  return 0;
unknown's avatar
unknown committed
5007 5008
}

5009
#endif /* !EMBEDDED_LIBRARY */
unknown's avatar
unknown committed
5010

unknown's avatar
SCRUM  
unknown committed
5011

5012 5013 5014 5015 5016
/****************************************************************************
  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
5017
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
unknown's avatar
unknown committed
5018 5019
int mysql_service(void *p)
{
5020 5021 5022
  if (my_thread_init())
    return 1;
  
5023 5024 5025 5026
  if (use_opt_args)
    win_main(opt_argc, opt_argv);
  else
    win_main(Service.my_argc, Service.my_argv);
5027 5028

  my_thread_end();
unknown's avatar
unknown committed
5029 5030 5031
  return 0;
}

5032 5033 5034 5035 5036 5037 5038 5039

/* 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
5040 5041
    return strmake(to, from, length-1);
  return strxnmov(to, length-1, "\"", from, "\"", NullS);
5042 5043 5044
}


unknown's avatar
unknown committed
5045 5046
/**
  Handle basic handling of services, like installation and removal.
5047

unknown's avatar
unknown committed
5048 5049 5050 5051 5052 5053
  @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

5054 5055
  @retval 0	option handled
  @retval 1	Could not handle option
unknown's avatar
unknown committed
5056
*/
5057

5058 5059 5060 5061 5062
static bool
default_service_handling(char **argv,
			 const char *servicename,
			 const char *displayname,
			 const char *file_path,
unknown's avatar
Merge  
unknown committed
5063 5064
			 const char *extra_opt,
			 const char *account_name)
5065
{
5066
  char path_and_service[FN_REFLEN+FN_REFLEN+32], *pos, *end;
5067
  const char *opt_delim;
5068
  end= path_and_service + sizeof(path_and_service)-3;
5069 5070 5071 5072 5073

  /* We have to quote filename if it contains spaces */
  pos= add_quoted_string(path_and_service, file_path, end);
  if (*extra_opt)
  {
5074 5075 5076 5077 5078
    /* 
     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.  
    */
5079
    *pos++= ' ';
5080 5081 5082
    if (opt_delim= strchr(extra_opt, '='))
    {
      size_t length= ++opt_delim - extra_opt;
5083
      pos= strnmov(pos, extra_opt, length);
5084 5085 5086 5087 5088
    }
    else
      opt_delim= extra_opt;
    
    pos= add_quoted_string(pos, opt_delim, end);
5089
  }
5090 5091
  /* We must have servicename last */
  *pos++= ' ';
unknown's avatar
unknown committed
5092
  (void) add_quoted_string(pos, servicename, end);
5093

5094 5095
  if (Service.got_service_option(argv, "install"))
  {
unknown's avatar
Merge  
unknown committed
5096 5097
    Service.Install(1, servicename, displayname, path_and_service,
                    account_name);
5098 5099 5100 5101
    return 0;
  }
  if (Service.got_service_option(argv, "install-manual"))
  {
unknown's avatar
Merge  
unknown committed
5102 5103
    Service.Install(0, servicename, displayname, path_and_service,
                    account_name);
5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114
    return 0;
  }
  if (Service.got_service_option(argv, "remove"))
  {
    Service.Remove(servicename);
    return 0;
  }
  return 1;
}


5115
int mysqld_main(int argc, char **argv)
unknown's avatar
unknown committed
5116
{
5117 5118
  my_progname= argv[0];

unknown's avatar
unknown committed
5119 5120 5121 5122
  /*
    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
5123
  */
5124
  int10_to_str((int) GetCurrentProcessId(),strmov(shutdown_event_name,
unknown's avatar
Merge  
unknown committed
5125 5126
                                                  "MySQLShutdown"), 10);

5127 5128 5129
  /* Must be initialized early for comparison of service name */
  system_charset_info= &my_charset_utf8_general_ci;

5130 5131 5132 5133 5134 5135
  if (my_init())
  {
    fprintf(stderr, "my_init() failed.");
    return 1;
  }

unknown's avatar
unknown committed
5136
  if (Service.GetOS())	/* true NT family */
unknown's avatar
unknown committed
5137
  {
unknown's avatar
unknown committed
5138
    char file_path[FN_REFLEN];
5139
    my_path(file_path, argv[0], "");		      /* Find name in path */
unknown's avatar
unknown committed
5140 5141
    fn_format(file_path,argv[0],file_path,"",
	      MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_RESOLVE_SYMLINKS);
unknown's avatar
unknown committed
5142

unknown's avatar
unknown committed
5143
    if (argc == 2)
5144
    {
5145
      if (!default_service_handling(argv, MYSQL_SERVICENAME, MYSQL_SERVICENAME,
unknown's avatar
Merge  
unknown committed
5146
				   file_path, "", NULL))
5147
	return 0;
unknown's avatar
unknown committed
5148
      if (Service.IsService(argv[1]))        /* Start an optional service */
unknown's avatar
unknown committed
5149
      {
unknown's avatar
unknown committed
5150 5151 5152 5153 5154 5155
	/*
	  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.
	*/
5156
	if (my_strcasecmp(system_charset_info, argv[1],"mysql"))
5157
	  load_default_groups[load_default_groups_sz-2]= argv[1];
unknown's avatar
unknown committed
5158
        start_mode= 1;
5159
        Service.Init(argv[1], mysql_service);
unknown's avatar
unknown committed
5160 5161 5162 5163
        return 0;
      }
    }
    else if (argc == 3) /* install or remove any optional service */
unknown's avatar
unknown committed
5164
    {
unknown's avatar
Merge  
unknown committed
5165 5166
      if (!default_service_handling(argv, argv[2], argv[2], file_path, "",
                                    NULL))
5167 5168
	return 0;
      if (Service.IsService(argv[2]))
unknown's avatar
unknown committed
5169
      {
5170 5171 5172 5173
	/*
	  mysqld was started as
	  mysqld --defaults-file=my_path\my.ini service-name
	*/
5174
	use_opt_args=1;
5175
	opt_argc= 2;				// Skip service-name
5176 5177
	opt_argv=argv;
	start_mode= 1;
5178
	if (my_strcasecmp(system_charset_info, argv[2],"mysql"))
5179
	  load_default_groups[load_default_groups_sz-2]= argv[2];
5180
	Service.Init(argv[2], mysql_service);
5181
	return 0;
unknown's avatar
unknown committed
5182 5183
      }
    }
unknown's avatar
Merge  
unknown committed
5184
    else if (argc == 4 || argc == 5)
5185 5186
    {
      /*
unknown's avatar
Merge  
unknown committed
5187 5188 5189 5190 5191
        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.)
5192
      */
unknown's avatar
Merge  
unknown committed
5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207
      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;
5208
    }
unknown's avatar
unknown committed
5209
    else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME))
unknown's avatar
unknown committed
5210
    {
unknown's avatar
unknown committed
5211 5212 5213
      /* start the default service */
      start_mode= 1;
      Service.Init(MYSQL_SERVICENAME, mysql_service);
unknown's avatar
unknown committed
5214 5215 5216
      return 0;
    }
  }
unknown's avatar
unknown committed
5217
  /* Start as standalone server */
unknown's avatar
unknown committed
5218 5219 5220 5221 5222 5223 5224 5225
  Service.my_argc=argc;
  Service.my_argv=argv;
  mysql_service(NULL);
  return 0;
}
#endif


unknown's avatar
unknown committed
5226
/**
5227 5228 5229
  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.
*/
5230

Marc Alff's avatar
Marc Alff committed
5231
static void bootstrap(MYSQL_FILE *file)
unknown's avatar
unknown committed
5232
{
5233
  DBUG_ENTER("bootstrap");
5234

5235
  THD *thd= new THD;
unknown's avatar
unknown committed
5236
  thd->bootstrap=1;
unknown's avatar
unknown committed
5237
  my_net_init(&thd->net,(st_vio*) 0);
unknown's avatar
unknown committed
5238
  thd->max_client_packet_length= thd->net.max_packet;
5239
  thd->security_ctx->master_access= ~(ulong)0;
unknown's avatar
unknown committed
5240
  thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
unknown's avatar
unknown committed
5241
  thread_count++;
5242
  in_bootstrap= TRUE;
5243 5244

  bootstrap_file=file;
unknown's avatar
unknown committed
5245
#ifndef EMBEDDED_LIBRARY			// TODO:  Enable this
Marc Alff's avatar
Marc Alff committed
5246 5247 5248
  if (mysql_thread_create(key_thread_bootstrap,
                          &thd->real_id, &connection_attrib, handle_bootstrap,
                          (void*) thd))
5249
  {
5250
    sql_print_warning("Can't create thread to handle bootstrap");
unknown's avatar
Merge  
unknown committed
5251 5252
    bootstrap_error=-1;
    DBUG_VOID_RETURN;
5253 5254
  }
  /* Wait for thread to die */
Marc Alff's avatar
Marc Alff committed
5255
  mysql_mutex_lock(&LOCK_thread_count);
5256
  while (in_bootstrap)
5257
  {
Marc Alff's avatar
Marc Alff committed
5258
    mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
5259 5260
    DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
  }
Marc Alff's avatar
Marc Alff committed
5261
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
5262 5263
#else
  thd->mysql= 0;
Marc Alff's avatar
Marc Alff committed
5264
  do_handle_bootstrap(thd);
unknown's avatar
unknown committed
5265 5266
#endif

unknown's avatar
Merge  
unknown committed
5267
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
5268 5269
}

5270

unknown's avatar
unknown committed
5271 5272
static bool read_init_file(char *file_name)
{
Marc Alff's avatar
Marc Alff committed
5273
  MYSQL_FILE *file;
unknown's avatar
unknown committed
5274 5275
  DBUG_ENTER("read_init_file");
  DBUG_PRINT("enter",("name: %s",file_name));
Marc Alff's avatar
Marc Alff committed
5276 5277
  if (!(file= mysql_file_fopen(key_file_init, file_name,
                               O_RDONLY, MYF(MY_WME))))
5278
    DBUG_RETURN(TRUE);
unknown's avatar
Merge  
unknown committed
5279
  bootstrap(file);
Marc Alff's avatar
Marc Alff committed
5280
  mysql_file_fclose(file, MYF(MY_WME));
5281
  DBUG_RETURN(FALSE);
unknown's avatar
unknown committed
5282 5283 5284
}


Mikael Ronström's avatar
Mikael Ronström committed
5285 5286 5287 5288 5289 5290 5291 5292
/**
  Increment number of created threads
*/
void inc_thread_created(void)
{
  thread_created++;
}

5293
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
5294 5295 5296 5297 5298 5299 5300 5301 5302 5303

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

unknown's avatar
unknown committed
5305 5306
void handle_connection_in_main_thread(THD *thd)
{
Marc Alff's avatar
Marc Alff committed
5307
  mysql_mutex_assert_owner(&LOCK_thread_count);
unknown's avatar
unknown committed
5308 5309
  thread_cache_size=0;			// Safety
  threads.append(thd);
Marc Alff's avatar
Marc Alff committed
5310
  mysql_mutex_unlock(&LOCK_thread_count);
5311
  thd->start_utime= microsecond_interval_timer();
Marc Alff's avatar
Marc Alff committed
5312
  do_handle_one_connection(thd);
unknown's avatar
unknown committed
5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326
}


/*
  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 */
    thread_cache.append(thd);
    wake_thread++;
Marc Alff's avatar
Marc Alff committed
5327
    mysql_cond_signal(&COND_thread_cache);
unknown's avatar
unknown committed
5328 5329 5330
  }
  else
  {
5331
    char error_message_buff[MYSQL_ERRMSG_SIZE];
unknown's avatar
unknown committed
5332 5333 5334 5335 5336
    /* Create new thread to handle connection */
    int error;
    thread_created++;
    threads.append(thd);
    DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id));
5337
    thd->prior_thr_create_utime= microsecond_interval_timer();
Marc Alff's avatar
Marc Alff committed
5338 5339 5340 5341
    if ((error= mysql_thread_create(key_thread_one_connection,
                                    &thd->real_id, &connection_attrib,
                                    handle_one_connection,
                                    (void*) thd)))
unknown's avatar
unknown committed
5342
    {
5343
      /* purecov: begin inspected */
unknown's avatar
unknown committed
5344 5345 5346 5347
      DBUG_PRINT("error",
                 ("Can't create thread to handle request (error %d)",
                  error));
      thread_count--;
5348
      thd->killed= KILL_CONNECTION;             // Safety
Marc Alff's avatar
Marc Alff committed
5349
      mysql_mutex_unlock(&LOCK_thread_count);
5350

Marc Alff's avatar
Marc Alff committed
5351
      mysql_mutex_lock(&LOCK_connection_count);
5352
      (*thd->scheduler->connection_count)--;
Marc Alff's avatar
Marc Alff committed
5353
      mysql_mutex_unlock(&LOCK_connection_count);
5354

unknown's avatar
unknown committed
5355
      statistic_increment(aborted_connects,&LOCK_status);
5356 5357
      /* Can't use my_error() since store_globals has not been called. */
      my_snprintf(error_message_buff, sizeof(error_message_buff),
5358
                  ER_THD(thd, ER_CANT_CREATE_THREAD), error);
Marc Alff's avatar
Marc Alff committed
5359
      net_send_error(thd, ER_CANT_CREATE_THREAD, error_message_buff, NULL);
Sergei Golubchik's avatar
Sergei Golubchik committed
5360
      close_connection(thd, ER_OUT_OF_RESOURCES);
Marc Alff's avatar
Marc Alff committed
5361
      mysql_mutex_lock(&LOCK_thread_count);
unknown's avatar
unknown committed
5362
      delete thd;
Marc Alff's avatar
Marc Alff committed
5363
      mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
5364 5365 5366 5367
      return;
      /* purecov: end */
    }
  }
Marc Alff's avatar
Marc Alff committed
5368
  mysql_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
5369 5370 5371 5372
  DBUG_PRINT("info",("Thread created"));
}


unknown's avatar
unknown committed
5373
/**
5374 5375 5376 5377 5378 5379
  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
5380
    In single-threaded mode (\#define ONE_THREAD) connection will be
5381 5382
    handled inside this function.

unknown's avatar
unknown committed
5383
  @param[in,out] thd    Thread handle of future thread.
5384 5385
*/

unknown's avatar
unknown committed
5386 5387 5388 5389
static void create_new_thread(THD *thd)
{
  DBUG_ENTER("create_new_thread");

5390 5391 5392 5393 5394
  /*
    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
5395
  mysql_mutex_lock(&LOCK_connection_count);
5396

5397 5398
  if (*thd->scheduler->connection_count >=
      *thd->scheduler->max_connections + 1|| abort_loop)
unknown's avatar
unknown committed
5399
  {
Marc Alff's avatar
Marc Alff committed
5400
    mysql_mutex_unlock(&LOCK_connection_count);
5401

unknown's avatar
unknown committed
5402
    DBUG_PRINT("error",("Too many connections"));
5403
    close_connection(thd, ER_CON_COUNT_ERROR);
5404
    statistic_increment(denied_connections, &LOCK_status);
unknown's avatar
unknown committed
5405 5406 5407
    delete thd;
    DBUG_VOID_RETURN;
  }
5408

5409
  ++*thd->scheduler->connection_count;
5410

5411 5412
  if (connection_count + extra_connection_count > max_used_connections)
    max_used_connections= connection_count + extra_connection_count;
5413

Marc Alff's avatar
Marc Alff committed
5414
  mysql_mutex_unlock(&LOCK_connection_count);
5415 5416 5417

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

Marc Alff's avatar
Marc Alff committed
5418
  mysql_mutex_lock(&LOCK_thread_count);
5419

5420 5421 5422 5423 5424
  /*
    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
5425
  thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
unknown's avatar
unknown committed
5426

5427 5428
  thread_count++;

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

unknown's avatar
unknown committed
5431 5432
  DBUG_VOID_RETURN;
}
5433 5434
#endif /* EMBEDDED_LIBRARY */

unknown's avatar
unknown committed
5435

unknown's avatar
unknown committed
5436 5437 5438 5439
#ifdef SIGNALS_DONT_BREAK_READ
inline void kill_broken_server()
{
  /* hack to get around signals ignored in syscalls for problem OS's */
5440
  if (unix_sock == INVALID_SOCKET ||
Michael Widenius's avatar
Michael Widenius committed
5441
      (!opt_disable_networking && base_ip_sock == INVALID_SOCKET))
unknown's avatar
unknown committed
5442 5443
  {
    select_thread_in_use = 0;
unknown's avatar
unknown committed
5444
    /* The following call will never return */
5445
    DBUG_PRINT("general", ("killing server because socket is closed"));
5446
    kill_server((void*) MYSQL_KILL_SIGNAL);
unknown's avatar
unknown committed
5447 5448 5449 5450 5451 5452
  }
}
#define MAYBE_BROKEN_SYSCALL kill_broken_server();
#else
#define MAYBE_BROKEN_SYSCALL
#endif
unknown's avatar
unknown committed
5453 5454 5455

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

5456
#ifndef EMBEDDED_LIBRARY
5457

5458
void handle_connections_sockets()
unknown's avatar
unknown committed
5459
{
5460
  my_socket UNINIT_VAR(sock), UNINIT_VAR(new_sock);
unknown's avatar
unknown committed
5461 5462
  uint error_count=0;
  THD *thd;
5463
  struct sockaddr_storage cAddr;
Michael Widenius's avatar
Michael Widenius committed
5464 5465 5466 5467
  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
5468
  st_vio *vio_tmp;
5469 5470
#ifdef HAVE_POLL
  int socket_count= 0;
Sergei Golubchik's avatar
Sergei Golubchik committed
5471 5472 5473 5474 5475
  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++
5476 5477
#else
  fd_set readFDs,clientFDs;
5478 5479
  uint max_used_connection= (uint)
    max(max(base_ip_sock, unix_sock), extra_ip_sock) + 1;
Sergei Golubchik's avatar
Sergei Golubchik committed
5480 5481
#define setup_fds(X)    FD_SET(X,&clientFDs)
  FD_ZERO(&clientFDs);
5482 5483
#endif

unknown's avatar
unknown committed
5484 5485
  DBUG_ENTER("handle_connections_sockets");

5486
  if (base_ip_sock != INVALID_SOCKET)
unknown's avatar
unknown committed
5487
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
5488 5489
    setup_fds(base_ip_sock);
    ip_flags = fcntl(base_ip_sock, F_GETFL, 0);
unknown's avatar
unknown committed
5490
  }
5491 5492
  if (extra_ip_sock != INVALID_SOCKET)
  {
Sergei Golubchik's avatar
Sergei Golubchik committed
5493
    setup_fds(extra_ip_sock);
5494
    extra_ip_flags = fcntl(extra_ip_sock, F_GETFL, 0);
unknown's avatar
unknown committed
5495 5496
  }
#ifdef HAVE_SYS_UN_H
Sergei Golubchik's avatar
Sergei Golubchik committed
5497
  setup_fds(unix_sock);
unknown's avatar
unknown committed
5498 5499 5500 5501
  socket_flags=fcntl(unix_sock, F_GETFL, 0);
#endif

  DBUG_PRINT("general",("Waiting for connections."));
unknown's avatar
unknown committed
5502
  MAYBE_BROKEN_SYSCALL;
unknown's avatar
unknown committed
5503 5504
  while (!abort_loop)
  {
5505 5506
#ifdef HAVE_POLL
    retval= poll(fds, socket_count, -1);
unknown's avatar
unknown committed
5507
#else
5508 5509 5510 5511 5512 5513
    readFDs=clientFDs;

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

    if (retval < 0)
unknown's avatar
unknown committed
5514
    {
unknown's avatar
unknown committed
5515
      if (socket_errno != SOCKET_EINTR)
unknown's avatar
unknown committed
5516 5517
      {
	if (!select_errors++ && !abort_loop)	/* purecov: inspected */
unknown's avatar
unknown committed
5518
	  sql_print_error("mysqld: Got error %d from select",socket_errno); /* purecov: inspected */
unknown's avatar
unknown committed
5519
      }
unknown's avatar
unknown committed
5520
      MAYBE_BROKEN_SYSCALL
unknown's avatar
unknown committed
5521 5522
      continue;
    }
5523

unknown's avatar
unknown committed
5524
    if (abort_loop)
unknown's avatar
unknown committed
5525 5526
    {
      MAYBE_BROKEN_SYSCALL;
unknown's avatar
unknown committed
5527
      break;
unknown's avatar
unknown committed
5528
    }
unknown's avatar
unknown committed
5529

5530
    /* Is this a new connection request ? */
5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541
#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
5542
    if (FD_ISSET(base_ip_sock,&readFDs))
unknown's avatar
unknown committed
5543
    {
Sergei Golubchik's avatar
Sergei Golubchik committed
5544 5545
      sock=  base_ip_sock;
      flags= ip_flags;
unknown's avatar
unknown committed
5546 5547
    }
    else
Sergei Golubchik's avatar
Sergei Golubchik committed
5548
    if (FD_ISSET(extra_ip_sock,&readFDs))
unknown's avatar
unknown committed
5549
    {
Sergei Golubchik's avatar
Sergei Golubchik committed
5550 5551 5552 5553 5554 5555 5556
      sock=  extra_ip_sock;
      flags= extra_ip_flags;
    }
    else
    {
      sock = unix_sock;
      flags= socket_flags;
unknown's avatar
unknown committed
5557
    }
5558
#endif // HAVE_POLL
unknown's avatar
unknown committed
5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571

#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++)
    {
5572 5573 5574
      size_socket length= sizeof(struct sockaddr_storage);
      new_sock= accept(sock, (struct sockaddr *)(&cAddr),
                       &length);
unknown's avatar
unknown committed
5575 5576
      if (new_sock != INVALID_SOCKET ||
	  (socket_errno != SOCKET_EINTR && socket_errno != SOCKET_EAGAIN))
unknown's avatar
unknown committed
5577
	break;
unknown's avatar
unknown committed
5578
      MAYBE_BROKEN_SYSCALL;
unknown's avatar
unknown committed
5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590
#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
5591
    if (new_sock == INVALID_SOCKET)
unknown's avatar
unknown committed
5592 5593 5594
    {
      if ((error_count++ & 255) == 0)		// This can happen often
	sql_perror("Error in accept");
unknown's avatar
unknown committed
5595
      MAYBE_BROKEN_SYSCALL;
unknown's avatar
unknown committed
5596
      if (socket_errno == SOCKET_ENFILE || socket_errno == SOCKET_EMFILE)
unknown's avatar
unknown committed
5597 5598 5599 5600 5601 5602
	sleep(1);				// Give other threads some time
      continue;
    }

#ifdef HAVE_LIBWRAP
    {
5603
      if (sock == base_ip_sock || sock == extra_ip_sock)
unknown's avatar
unknown committed
5604 5605 5606 5607
      {
	struct request_info req;
	signal(SIGCHLD, SIG_DFL);
	request_init(&req, RQ_DAEMON, libwrapName, RQ_FILE, new_sock, NULL);
5608 5609
	my_fromhost(&req);
	if (!my_hosts_access(&req))
unknown's avatar
unknown committed
5610
	{
unknown's avatar
unknown committed
5611 5612 5613 5614 5615
	  /*
	    This may be stupid but refuse() includes an exit(0)
	    which we surely don't want...
	    clean_exit() - same stupid thing ...
	  */
5616
	  syslog(deny_severity, "refused connect from %s",
5617
		 my_eval_client(&req));
unknown's avatar
unknown committed
5618

unknown's avatar
unknown committed
5619 5620 5621 5622 5623 5624
	  /*
	    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
5625 5626 5627
	  if (req.sink)
	    ((void (*)(int))req.sink)(req.fd);

5628
	  (void) mysql_socket_shutdown(new_sock, SHUT_RDWR);
unknown's avatar
unknown committed
5629 5630 5631 5632 5633 5634 5635 5636 5637
	  (void) closesocket(new_sock);
	  continue;
	}
      }
    }
#endif /* HAVE_LIBWRAP */

    {
      size_socket dummyLen;
5638 5639 5640 5641
      struct sockaddr_storage dummy;
      dummyLen = sizeof(dummy);
      if (  getsockname(new_sock,(struct sockaddr *)&dummy, 
                  (SOCKET_SIZE_TYPE *)&dummyLen) < 0  )
unknown's avatar
unknown committed
5642 5643
      {
	sql_perror("Error on new connection socket");
5644
	(void) mysql_socket_shutdown(new_sock, SHUT_RDWR);
unknown's avatar
unknown committed
5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655
	(void) closesocket(new_sock);
	continue;
      }
    }

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

    if (!(thd= new THD))
    {
5656
      (void) mysql_socket_shutdown(new_sock, SHUT_RDWR);
Konstantin Osipov's avatar
Konstantin Osipov committed
5657
      (void) closesocket(new_sock);
unknown's avatar
unknown committed
5658 5659 5660
      continue;
    }
    if (!(vio_tmp=vio_new(new_sock,
5661
			  sock == unix_sock ? VIO_TYPE_SOCKET :
unknown's avatar
unknown committed
5662
			  VIO_TYPE_TCPIP,
5663
			  sock == unix_sock ? VIO_LOCALHOST: 0)) ||
unknown's avatar
unknown committed
5664 5665
	my_net_init(&thd->net,vio_tmp))
    {
5666 5667 5668 5669 5670 5671 5672
      /*
        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
5673 5674
      else
      {
5675
	(void) mysql_socket_shutdown(new_sock, SHUT_RDWR);
unknown's avatar
unknown committed
5676 5677 5678 5679 5680 5681
	(void) closesocket(new_sock);
      }
      delete thd;
      continue;
    }
    if (sock == unix_sock)
5682
      thd->security_ctx->host=(char*) my_localhost;
5683

5684 5685 5686
    if (sock == extra_ip_sock)
    {
      thd->extra_port= 1;
Sergei Golubchik's avatar
Sergei Golubchik committed
5687
      thd->scheduler= extra_thread_scheduler;
5688
    }
unknown's avatar
unknown committed
5689 5690
    create_new_thread(thd);
  }
5691 5692 5693
  DBUG_VOID_RETURN;
}

unknown's avatar
unknown committed
5694

5695 5696 5697 5698 5699
#ifdef _WIN32
pthread_handler_t handle_connections_sockets_thread(void *arg)
{
  my_thread_init();
  handle_connections_sockets();
5700
  decrement_handler_count();
5701
  return 0;
unknown's avatar
unknown committed
5702 5703
}

5704
pthread_handler_t handle_connections_namedpipes(void *arg)
unknown's avatar
unknown committed
5705 5706
{
  HANDLE hConnectedPipe;
5707
  OVERLAPPED connectOverlapped= {0};
unknown's avatar
unknown committed
5708 5709 5710
  THD *thd;
  my_thread_init();
  DBUG_ENTER("handle_connections_namedpipes");
5711 5712 5713 5714 5715 5716
  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
5717 5718 5719 5720
  DBUG_PRINT("general",("Waiting for named pipe connections."));
  while (!abort_loop)
  {
    /* wait for named pipe connection */
5721 5722 5723 5724 5725 5726 5727 5728 5729 5730
    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
5731 5732
    if (abort_loop)
      break;
unknown's avatar
unknown committed
5733
    if (!fConnected)
unknown's avatar
unknown committed
5734
      fConnected = GetLastError() == ERROR_PIPE_CONNECTED;
unknown's avatar
unknown committed
5735
    if (!fConnected)
unknown's avatar
unknown committed
5736
    {
unknown's avatar
Merge  
unknown committed
5737 5738
      CloseHandle(hPipe);
      if ((hPipe= CreateNamedPipe(pipe_name,
5739 5740
                                  PIPE_ACCESS_DUPLEX |
                                  FILE_FLAG_OVERLAPPED,
unknown's avatar
Merge  
unknown committed
5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751
                                  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
5752 5753 5754 5755 5756 5757 5758
      {
	sql_perror("Can't create new named pipe!");
	break;					// Abort
      }
    }
    hConnectedPipe = hPipe;
    /* create new pipe for new connection */
5759
    if ((hPipe = CreateNamedPipe(pipe_name,
5760 5761
                 PIPE_ACCESS_DUPLEX |
                 FILE_FLAG_OVERLAPPED,
unknown's avatar
unknown committed
5762 5763 5764 5765
				 PIPE_TYPE_BYTE |
				 PIPE_READMODE_BYTE |
				 PIPE_WAIT,
				 PIPE_UNLIMITED_INSTANCES,
5766 5767
				 (int) global_system_variables.net_buffer_length,
				 (int) global_system_variables.net_buffer_length,
unknown's avatar
unknown committed
5768 5769 5770 5771 5772 5773 5774 5775 5776
				 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
5777
    if (!(thd = new THD))
unknown's avatar
unknown committed
5778
    {
unknown's avatar
Merge  
unknown committed
5779 5780
      DisconnectNamedPipe(hConnectedPipe);
      CloseHandle(hConnectedPipe);
unknown's avatar
unknown committed
5781 5782
      continue;
    }
5783
    if (!(thd->net.vio= vio_new_win32pipe(hConnectedPipe)) ||
unknown's avatar
unknown committed
5784 5785
	my_net_init(&thd->net, thd->net.vio))
    {
5786
      close_connection(thd, ER_OUT_OF_RESOURCES);
unknown's avatar
unknown committed
5787 5788 5789
      delete thd;
      continue;
    }
5790 5791
    /* Host is unknown */
    thd->security_ctx->host= my_strdup(my_localhost, MYF(0));
unknown's avatar
unknown committed
5792 5793
    create_new_thread(thd);
  }
5794
  CloseHandle(connectOverlapped.hEvent);
5795
  DBUG_LEAVE;
5796
  decrement_handler_count();
5797
  return 0;
unknown's avatar
unknown committed
5798
}
Vladislav Vaintroub's avatar
Vladislav Vaintroub committed
5799
#endif /* _WIN32 */
unknown's avatar
unknown committed
5800

5801

unknown's avatar
unknown committed
5802
#ifdef HAVE_SMEM
5803

unknown's avatar
unknown committed
5804 5805
/**
  Thread of shared memory's service.
5806

unknown's avatar
unknown committed
5807 5808
  @param arg                              Arguments of thread
*/
5809
pthread_handler_t handle_connections_shared_memory(void *arg)
5810
{
5811 5812
  /* file-mapping object, use for create shared memory */
  HANDLE handle_connect_file_map= 0;
5813
  char  *handle_connect_map= 0;                 // pointer on shared memory
5814 5815 5816
  HANDLE event_connect_answer= 0;
  ulong smem_buffer_length= shared_memory_buffer_length + 4;
  ulong connect_number= 1;
5817
  char *tmp= NULL;
5818 5819
  char *suffix_pos;
  char connect_number_char[22], *p;
5820
  const char *errmsg= 0;
5821
  SECURITY_ATTRIBUTES *sa_event= 0, *sa_mapping= 0;
5822 5823 5824 5825
  my_thread_init();
  DBUG_ENTER("handle_connections_shared_memorys");
  DBUG_PRINT("general",("Waiting for allocated shared memory."));

5826 5827 5828 5829 5830 5831
  /*
     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;

5832 5833 5834 5835 5836 5837 5838 5839
  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;

5840 5841 5842 5843 5844 5845 5846
  /*
    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)
  */
5847
  suffix_pos= strxmov(tmp,shared_memory_base_name,"_",NullS);
5848
  strmov(suffix_pos, "CONNECT_REQUEST");
5849 5850
  if ((smem_event_connect_request= CreateEvent(sa_event,
                                               FALSE, FALSE, tmp)) == 0)
5851
  {
5852
    errmsg= "Could not create request event";
5853 5854
    goto error;
  }
5855
  strmov(suffix_pos, "CONNECT_ANSWER");
5856
  if ((event_connect_answer= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
5857
  {
5858
    errmsg="Could not create answer event";
5859 5860
    goto error;
  }
5861
  strmov(suffix_pos, "CONNECT_DATA");
5862 5863 5864
  if ((handle_connect_file_map=
       CreateFileMapping(INVALID_HANDLE_VALUE, sa_mapping,
                         PAGE_READWRITE, 0, sizeof(connect_number), tmp)) == 0)
5865
  {
5866
    errmsg= "Could not create file mapping";
5867 5868
    goto error;
  }
5869 5870 5871
  if ((handle_connect_map= (char *)MapViewOfFile(handle_connect_file_map,
						  FILE_MAP_WRITE,0,0,
						  sizeof(DWORD))) == 0)
5872
  {
5873
    errmsg= "Could not create shared memory service";
5874 5875 5876 5877 5878
    goto error;
  }

  while (!abort_loop)
  {
5879
    /* Wait a request from client */
5880
    WaitForSingleObject(smem_event_connect_request,INFINITE);
5881

unknown's avatar
unknown committed
5882 5883 5884
    /*
       it can be after shutdown command
    */
unknown's avatar
Merge  
unknown committed
5885
    if (abort_loop)
unknown's avatar
unknown committed
5886
      goto error;
5887

5888 5889 5890 5891 5892 5893
    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
5894
    HANDLE event_conn_closed= 0;
5895
    THD *thd= 0;
5896

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

  /* End shared memory handling */
6017
error:
6018
  if (tmp)
6019
    my_free(tmp);
6020

6021 6022 6023 6024 6025 6026
  if (errmsg)
  {
    char buff[180];
    strxmov(buff, "Can't create shared memory service: ", errmsg, ".", NullS);
    sql_perror(buff);
  }
6027 6028
  my_security_attr_free(sa_event);
  my_security_attr_free(sa_mapping);
6029 6030 6031
  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);
6032
  if (smem_event_connect_request) CloseHandle(smem_event_connect_request);
6033
  DBUG_LEAVE;
6034
  decrement_handler_count();
6035
  return 0;
6036 6037
}
#endif /* HAVE_SMEM */
6038
#endif /* EMBEDDED_LIBRARY */
unknown's avatar
unknown committed
6039

6040 6041 6042

/****************************************************************************
  Handle start options
unknown's avatar
unknown committed
6043 6044
******************************************************************************/

6045 6046 6047 6048 6049
/**
  System variables are automatically command-line options (few
  exceptions are documented in sys_var.h), so don't need
  to be listed here.
*/
6050

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

6473

6474
static int show_queries(THD *thd, SHOW_VAR *var, char *buff)
6475
{
6476
  var->type= SHOW_LONGLONG;
6477 6478 6479 6480
  var->value= (char *)&thd->query_id;
  return 0;
}

6481

6482
static int show_net_compression(THD *thd, SHOW_VAR *var, char *buff)
6483
{
6484
  var->type= SHOW_MY_BOOL;
6485 6486 6487 6488
  var->value= (char *)&thd->net.compress;
  return 0;
}

6489
static int show_starttime(THD *thd, SHOW_VAR *var, char *buff)
6490
{
6491
  var->type= SHOW_LONG;
6492
  var->value= buff;
unknown's avatar
unknown committed
6493
  *((long *)buff)= (long) (thd->query_start() - server_start_time);
6494 6495 6496
  return 0;
}

6497
#ifdef ENABLED_PROFILING
6498 6499 6500 6501 6502 6503 6504
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;
}
6505
#endif
6506

6507
#ifdef HAVE_REPLICATION
6508
static int show_rpl_status(THD *thd, SHOW_VAR *var, char *buff)
6509
{
6510
  var->type= SHOW_CHAR;
6511 6512 6513 6514
  var->value= const_cast<char*>(rpl_status_type[(int)rpl_status]);
  return 0;
}

6515
static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff)
6516
{
6517
  var->type= SHOW_MY_BOOL;
Marc Alff's avatar
Marc Alff committed
6518
  mysql_mutex_lock(&LOCK_active_mi);
6519
  var->value= buff;
6520 6521
  *((my_bool *)buff)= (my_bool) (active_mi && 
                                 active_mi->slave_running == MYSQL_SLAVE_RUN_CONNECT &&
6522
                                 active_mi->rli.slave_running);
Marc Alff's avatar
Marc Alff committed
6523
  mysql_mutex_unlock(&LOCK_active_mi);
6524 6525 6526
  return 0;
}

6527
static int show_slave_retried_trans(THD *thd, SHOW_VAR *var, char *buff)
6528 6529 6530 6531 6532
{
  /*
    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
6533
  mysql_mutex_lock(&LOCK_active_mi);
6534 6535
  if (active_mi)
  {
6536
    var->type= SHOW_LONG;
6537
    var->value= buff;
Marc Alff's avatar
Marc Alff committed
6538
    mysql_mutex_lock(&active_mi->rli.data_lock);
6539
    *((long *)buff)= (long)active_mi->rli.retried_trans;
Marc Alff's avatar
Marc Alff committed
6540
    mysql_mutex_unlock(&active_mi->rli.data_lock);
6541 6542
  }
  else
6543
    var->type= SHOW_UNDEF;
Marc Alff's avatar
Marc Alff committed
6544
  mysql_mutex_unlock(&LOCK_active_mi);
6545 6546
  return 0;
}
Andrei Elkin's avatar
Andrei Elkin committed
6547 6548 6549

static int show_slave_received_heartbeats(THD *thd, SHOW_VAR *var, char *buff)
{
Marc Alff's avatar
Marc Alff committed
6550
  mysql_mutex_lock(&LOCK_active_mi);
Andrei Elkin's avatar
Andrei Elkin committed
6551 6552 6553 6554
  if (active_mi)
  {
    var->type= SHOW_LONGLONG;
    var->value= buff;
Marc Alff's avatar
Marc Alff committed
6555
    mysql_mutex_lock(&active_mi->rli.data_lock);
Andrei Elkin's avatar
Andrei Elkin committed
6556
    *((longlong *)buff)= active_mi->received_heartbeats;
Marc Alff's avatar
Marc Alff committed
6557
    mysql_mutex_unlock(&active_mi->rli.data_lock);
Andrei Elkin's avatar
Andrei Elkin committed
6558 6559 6560
  }
  else
    var->type= SHOW_UNDEF;
Marc Alff's avatar
Marc Alff committed
6561
  mysql_mutex_unlock(&LOCK_active_mi);
Andrei Elkin's avatar
Andrei Elkin committed
6562 6563 6564 6565 6566
  return 0;
}

static int show_heartbeat_period(THD *thd, SHOW_VAR *var, char *buff)
{
Marc Alff's avatar
Marc Alff committed
6567
  mysql_mutex_lock(&LOCK_active_mi);
Andrei Elkin's avatar
Andrei Elkin committed
6568 6569 6570 6571
  if (active_mi)
  {
    var->type= SHOW_CHAR;
    var->value= buff;
6572
    sprintf(buff, "%.3f", active_mi->heartbeat_period);
Andrei Elkin's avatar
Andrei Elkin committed
6573 6574 6575
  }
  else
    var->type= SHOW_UNDEF;
Marc Alff's avatar
Marc Alff committed
6576
  mysql_mutex_unlock(&LOCK_active_mi);
Andrei Elkin's avatar
Andrei Elkin committed
6577 6578 6579 6580
  return 0;
}


6581 6582
#endif /* HAVE_REPLICATION */

6583
static int show_open_tables(THD *thd, SHOW_VAR *var, char *buff)
6584
{
6585
  var->type= SHOW_LONG;
6586 6587 6588 6589 6590
  var->value= buff;
  *((long *)buff)= (long)cached_open_tables();
  return 0;
}

unknown's avatar
unknown committed
6591 6592 6593 6594
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
6595
  mysql_mutex_lock(&LOCK_prepared_stmt_count);
unknown's avatar
unknown committed
6596
  *((long *)buff)= (long)prepared_stmt_count;
Marc Alff's avatar
Marc Alff committed
6597
  mysql_mutex_unlock(&LOCK_prepared_stmt_count);
unknown's avatar
unknown committed
6598 6599 6600
  return 0;
}

6601
static int show_table_definitions(THD *thd, SHOW_VAR *var, char *buff)
6602
{
6603
  var->type= SHOW_LONG;
6604 6605 6606 6607 6608
  var->value= buff;
  *((long *)buff)= (long)cached_table_definitions();
  return 0;
}

Konstantin Osipov's avatar
Konstantin Osipov committed
6609
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
6610
/* Functions relying on CTX */
6611
static int show_ssl_ctx_sess_accept(THD *thd, SHOW_VAR *var, char *buff)
6612
{
6613
  var->type= SHOW_LONG;
6614 6615 6616 6617 6618 6619
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_accept(ssl_acceptor_fd->ssl_context));
  return 0;
}

6620
static int show_ssl_ctx_sess_accept_good(THD *thd, SHOW_VAR *var, char *buff)
6621
{
6622
  var->type= SHOW_LONG;
6623 6624 6625 6626 6627 6628
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_accept_good(ssl_acceptor_fd->ssl_context));
  return 0;
}

6629
static int show_ssl_ctx_sess_connect_good(THD *thd, SHOW_VAR *var, char *buff)
6630
{
6631
  var->type= SHOW_LONG;
6632 6633 6634 6635 6636 6637
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_connect_good(ssl_acceptor_fd->ssl_context));
  return 0;
}

6638
static int show_ssl_ctx_sess_accept_renegotiate(THD *thd, SHOW_VAR *var, char *buff)
6639
{
6640
  var->type= SHOW_LONG;
6641 6642 6643 6644 6645 6646
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context));
  return 0;
}

6647
static int show_ssl_ctx_sess_connect_renegotiate(THD *thd, SHOW_VAR *var, char *buff)
6648
{
6649
  var->type= SHOW_LONG;
6650 6651 6652 6653 6654 6655
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_connect_renegotiate(ssl_acceptor_fd->ssl_context));
  return 0;
}

6656
static int show_ssl_ctx_sess_cb_hits(THD *thd, SHOW_VAR *var, char *buff)
6657
{
6658
  var->type= SHOW_LONG;
6659 6660 6661 6662 6663 6664
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_cb_hits(ssl_acceptor_fd->ssl_context));
  return 0;
}

6665
static int show_ssl_ctx_sess_hits(THD *thd, SHOW_VAR *var, char *buff)
6666
{
6667
  var->type= SHOW_LONG;
6668 6669 6670 6671 6672 6673
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_hits(ssl_acceptor_fd->ssl_context));
  return 0;
}

6674
static int show_ssl_ctx_sess_cache_full(THD *thd, SHOW_VAR *var, char *buff)
6675
{
6676
  var->type= SHOW_LONG;
6677 6678 6679 6680 6681 6682
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_cache_full(ssl_acceptor_fd->ssl_context));
  return 0;
}

6683
static int show_ssl_ctx_sess_misses(THD *thd, SHOW_VAR *var, char *buff)
6684
{
6685
  var->type= SHOW_LONG;
6686 6687 6688 6689 6690 6691
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_misses(ssl_acceptor_fd->ssl_context));
  return 0;
}

6692
static int show_ssl_ctx_sess_timeouts(THD *thd, SHOW_VAR *var, char *buff)
6693
{
6694
  var->type= SHOW_LONG;
6695 6696 6697 6698 6699 6700
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_timeouts(ssl_acceptor_fd->ssl_context));
  return 0;
}

6701
static int show_ssl_ctx_sess_number(THD *thd, SHOW_VAR *var, char *buff)
6702
{
6703
  var->type= SHOW_LONG;
6704 6705 6706 6707 6708 6709
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context));
  return 0;
}

6710
static int show_ssl_ctx_sess_connect(THD *thd, SHOW_VAR *var, char *buff)
6711
{
6712
  var->type= SHOW_LONG;
6713 6714 6715 6716 6717 6718
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_connect(ssl_acceptor_fd->ssl_context));
  return 0;
}

6719
static int show_ssl_ctx_sess_get_cache_size(THD *thd, SHOW_VAR *var, char *buff)
6720
{
6721
  var->type= SHOW_LONG;
6722 6723 6724 6725 6726 6727
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context));
  return 0;
}

6728
static int show_ssl_ctx_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff)
6729
{
6730
  var->type= SHOW_LONG;
6731 6732 6733 6734 6735 6736
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_get_verify_mode(ssl_acceptor_fd->ssl_context));
  return 0;
}

6737
static int show_ssl_ctx_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff)
6738
{
6739
  var->type= SHOW_LONG;
6740 6741 6742 6743 6744 6745
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_get_verify_depth(ssl_acceptor_fd->ssl_context));
  return 0;
}

6746
static int show_ssl_ctx_get_session_cache_mode(THD *thd, SHOW_VAR *var, char *buff)
6747
{
6748
  var->type= SHOW_CHAR;
6749
  if (!ssl_acceptor_fd)
unknown's avatar
unknown committed
6750
    var->value= const_cast<char*>("NONE");
6751 6752 6753 6754
  else
    switch (SSL_CTX_get_session_cache_mode(ssl_acceptor_fd->ssl_context))
    {
    case SSL_SESS_CACHE_OFF:
unknown's avatar
unknown committed
6755
      var->value= const_cast<char*>("OFF"); break;
6756
    case SSL_SESS_CACHE_CLIENT:
unknown's avatar
unknown committed
6757
      var->value= const_cast<char*>("CLIENT"); break;
6758
    case SSL_SESS_CACHE_SERVER:
unknown's avatar
unknown committed
6759
      var->value= const_cast<char*>("SERVER"); break;
6760
    case SSL_SESS_CACHE_BOTH:
unknown's avatar
unknown committed
6761
      var->value= const_cast<char*>("BOTH"); break;
6762
    case SSL_SESS_CACHE_NO_AUTO_CLEAR:
unknown's avatar
unknown committed
6763
      var->value= const_cast<char*>("NO_AUTO_CLEAR"); break;
6764
    case SSL_SESS_CACHE_NO_INTERNAL_LOOKUP:
unknown's avatar
unknown committed
6765
      var->value= const_cast<char*>("NO_INTERNAL_LOOKUP"); break;
6766
    default:
unknown's avatar
unknown committed
6767
      var->value= const_cast<char*>("Unknown"); break;
6768 6769 6770 6771
    }
  return 0;
}

6772
/*
6773
   Functions relying on SSL
6774 6775 6776 6777 6778
   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.
 */
6779
static int show_ssl_get_version(THD *thd, SHOW_VAR *var, char *buff)
6780
{
6781
  var->type= SHOW_CHAR;
6782 6783 6784
  if( thd->vio_ok() && thd->net.vio->ssl_arg )
    var->value= const_cast<char*>(SSL_get_version((SSL*) thd->net.vio->ssl_arg));
  else
6785
    var->value= (char *)"";
6786 6787 6788
  return 0;
}

6789
static int show_ssl_session_reused(THD *thd, SHOW_VAR *var, char *buff)
6790
{
6791
  var->type= SHOW_LONG;
6792
  var->value= buff;
6793 6794 6795 6796
  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
6797
  return 0;
6798 6799
}

6800
static int show_ssl_get_default_timeout(THD *thd, SHOW_VAR *var, char *buff)
6801
{
6802
  var->type= SHOW_LONG;
6803
  var->value= buff;
6804 6805 6806 6807
  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;
6808 6809 6810
  return 0;
}

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

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

6833
static int show_ssl_get_cipher(THD *thd, SHOW_VAR *var, char *buff)
6834
{
6835
  var->type= SHOW_CHAR;
6836 6837 6838
  if( thd->vio_ok() && thd->net.vio->ssl_arg )
    var->value= const_cast<char*>(SSL_get_cipher((SSL*) thd->net.vio->ssl_arg));
  else
6839
    var->value= (char *)"";
6840 6841 6842
  return 0;
}

6843
static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff)
6844
{
6845
  var->type= SHOW_CHAR;
6846
  var->value= buff;
6847
  if (thd->vio_ok() && thd->net.vio->ssl_arg)
6848 6849 6850
  {
    int i;
    const char *p;
6851 6852 6853
    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++)
6854
    {
6855
      buff= strnmov(buff, p, end-buff-1);
6856 6857 6858 6859 6860 6861 6862 6863 6864
      *buff++= ':';
    }
    if (i)
      buff--;
  }
  *buff=0;
  return 0;
}

Konstantin Osipov's avatar
Konstantin Osipov committed
6865
#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
6866

6867 6868 6869 6870 6871 6872 6873 6874 6875 6876 6877 6878 6879 6880 6881 6882 6883 6884 6885 6886 6887 6888 6889 6890 6891
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
6892
  set_one_keycache_var("blocks_warm",        blocks_warm);
6893 6894 6895 6896 6897 6898 6899 6900 6901 6902 6903 6904 6905 6906
  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;
}

6907 6908 6909 6910 6911 6912 6913 6914 6915
#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
6916

6917 6918 6919 6920
/*
  Variables shown by SHOW STATUS in alphabetical order
*/

6921
SHOW_VAR status_vars[]= {
6922 6923
  {"Aborted_clients",          (char*) &aborted_threads,        SHOW_LONG},
  {"Aborted_connects",         (char*) &aborted_connects,       SHOW_LONG},
6924
  {"Access_denied_errors",     (char*) offsetof(STATUS_VAR, access_denied_errors), SHOW_LONG_STATUS},
6925 6926
  {"Binlog_cache_disk_use",    (char*) &binlog_cache_disk_use,  SHOW_LONG},
  {"Binlog_cache_use",         (char*) &binlog_cache_use,       SHOW_LONG},
6927 6928
  {"Binlog_stmt_cache_disk_use",(char*) &binlog_stmt_cache_disk_use,  SHOW_LONG},
  {"Binlog_stmt_cache_use",    (char*) &binlog_stmt_cache_use,       SHOW_LONG},
6929
  {"Busy_time",                (char*) offsetof(STATUS_VAR, busy_time), SHOW_DOUBLE_STATUS},
6930 6931
  {"Bytes_received",           (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONGLONG_STATUS},
  {"Bytes_sent",               (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS},
6932
  {"Binlog_bytes_written",     (char*) offsetof(STATUS_VAR, binlog_bytes_written), SHOW_LONGLONG_STATUS},
unknown's avatar
unknown committed
6933
  {"Com",                      (char*) com_status_vars, SHOW_ARRAY},
6934
  {"Compression",              (char*) &show_net_compression, SHOW_FUNC},
6935
  {"Connections",              (char*) &thread_id,              SHOW_LONG_NOFLUSH},
6936
  {"Cpu_time",                 (char*) offsetof(STATUS_VAR, cpu_time), SHOW_DOUBLE_STATUS},
unknown's avatar
Merge  
unknown committed
6937
  {"Created_tmp_disk_tables",  (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS},
6938
  {"Created_tmp_files",	       (char*) &my_tmp_file_created,	SHOW_LONG},
unknown's avatar
Merge  
unknown committed
6939
  {"Created_tmp_tables",       (char*) offsetof(STATUS_VAR, created_tmp_tables), SHOW_LONG_STATUS},
6940
  {"Delayed_errors",           (char*) &delayed_insert_errors,  SHOW_LONG},
6941
  {"Delayed_insert_threads",   (char*) &delayed_insert_threads, SHOW_LONG_NOFLUSH},
6942
  {"Delayed_writes",           (char*) &delayed_insert_writes,  SHOW_LONG},
6943
  {"Empty_queries",            (char*) offsetof(STATUS_VAR, empty_queries), SHOW_LONG_STATUS},
6944
  {"Flush_commands",           (char*) &refresh_version,        SHOW_LONG_NOFLUSH},
unknown's avatar
Merge  
unknown committed
6945 6946 6947
  {"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},
6948

6949
  {"Handler_icp_attempts",     (char*) offsetof(STATUS_VAR, ha_icp_attempts), SHOW_LONG_STATUS},
6950 6951 6952
  {"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},
6953 6954 6955
  {"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
6956 6957 6958
  {"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},
6959
  {"Handler_read_last",        (char*) offsetof(STATUS_VAR, ha_read_last_count), SHOW_LONG_STATUS},
unknown's avatar
Merge  
unknown committed
6960 6961 6962
  {"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},
6963
  {"Handler_read_rnd_deleted", (char*) offsetof(STATUS_VAR, ha_read_rnd_deleted_count), SHOW_LONG_STATUS},
unknown's avatar
Merge  
unknown committed
6964 6965 6966 6967
  {"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},
6968 6969
  {"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},
6970 6971
  {"Handler_update",           (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS},
  {"Handler_write",            (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS},
6972
  {"Key",                      (char*) &show_default_keycache, SHOW_FUNC},
6973
  {"Last_query_cost",          (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS},
6974
  {"Max_used_connections",     (char*) &max_used_connections,  SHOW_LONG},
6975 6976 6977
  {"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},
6978 6979
  {"Open_table_definitions",   (char*) &show_table_definitions, SHOW_FUNC},
  {"Open_tables",              (char*) &show_open_tables,       SHOW_FUNC},
6980
  {"Opened_files",             (char*) &my_file_total_opened, SHOW_LONG_NOFLUSH},
unknown's avatar
Merge  
unknown committed
6981
  {"Opened_tables",            (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS},
6982
  {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
6983
  {"Prepared_stmt_count",      (char*) &show_prepared_stmt_count, SHOW_FUNC},
6984 6985
  {"Rows_sent",                (char*) offsetof(STATUS_VAR, rows_sent), SHOW_LONGLONG_STATUS},
  {"Rows_read",                (char*) offsetof(STATUS_VAR, rows_read), SHOW_LONGLONG_STATUS},
6986
  {"Rows_tmp_read",            (char*) offsetof(STATUS_VAR, rows_tmp_read), SHOW_LONGLONG_STATUS},
unknown's avatar
unknown committed
6987
#ifdef HAVE_QUERY_CACHE
6988 6989
  {"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
6990
  {"Qcache_hits",              (char*) &query_cache.hits,       SHOW_LONG},
6991
  {"Qcache_inserts",           (char*) &query_cache.inserts,    SHOW_LONG},
6992
  {"Qcache_lowmem_prunes",     (char*) &query_cache.lowmem_prunes, SHOW_LONG},
unknown's avatar
unknown committed
6993
  {"Qcache_not_cached",        (char*) &query_cache.refused,    SHOW_LONG},
6994 6995
  {"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
6996
#endif /*HAVE_QUERY_CACHE*/
6997
  {"Queries",                  (char*) &show_queries,            SHOW_FUNC},
6998
  {"Questions",                (char*) offsetof(STATUS_VAR, questions), SHOW_LONG_STATUS},
6999 7000 7001
#ifdef HAVE_REPLICATION
  {"Rpl_status",               (char*) &show_rpl_status,          SHOW_FUNC},
#endif
unknown's avatar
Merge  
unknown committed
7002 7003 7004 7005 7006
  {"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},
7007
  {"Slave_open_temp_tables",   (char*) &slave_open_temp_tables, SHOW_LONG},
7008 7009
#ifdef HAVE_REPLICATION
  {"Slave_retried_transactions",(char*) &show_slave_retried_trans, SHOW_FUNC},
Andrei Elkin's avatar
Andrei Elkin committed
7010 7011
  {"Slave_heartbeat_period",   (char*) &show_heartbeat_period, SHOW_FUNC},
  {"Slave_received_heartbeats",(char*) &show_slave_received_heartbeats, SHOW_FUNC},
7012 7013
  {"Slave_running",            (char*) &show_slave_running,     SHOW_FUNC},
#endif
7014
  {"Slow_launch_threads",      (char*) &slow_launch_threads,    SHOW_LONG},
unknown's avatar
Merge  
unknown committed
7015 7016 7017 7018 7019
  {"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
7020
#ifdef HAVE_OPENSSL
Konstantin Osipov's avatar
Konstantin Osipov committed
7021
#ifndef EMBEDDED_LIBRARY
7022 7023 7024 7025 7026 7027 7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038 7039 7040 7041 7042 7043 7044
  {"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
7045
#endif
unknown's avatar
unknown committed
7046
#endif /* HAVE_OPENSSL */
7047
  {"Syncs",                    (char*) &my_sync_count,          SHOW_LONG_NOFLUSH},
unknown's avatar
unknown committed
7048 7049 7050 7051
  /*
    Expression cache used only for caching subqueries now, so its statistic
    variables we call subquery_cache*.
  */
7052 7053
  {"Subquery_cache_hit",       (char*) &subquery_cache_hit,     SHOW_LONG},
  {"Subquery_cache_miss",      (char*) &subquery_cache_miss,    SHOW_LONG},
unknown's avatar
unknown committed
7054 7055
  {"Table_locks_immediate",    (char*) &locks_immediate,        SHOW_LONG},
  {"Table_locks_waited",       (char*) &locks_waited,           SHOW_LONG},
7056
#ifdef HAVE_MMAP
unknown's avatar
Merge  
unknown committed
7057
  {"Tc_log_max_pages_used",    (char*) &tc_log_max_pages_used,  SHOW_LONG},
7058
  {"Tc_log_page_size",         (char*) &tc_log_page_size,       SHOW_LONG_NOFLUSH},
unknown's avatar
Merge  
unknown committed
7059
  {"Tc_log_page_waits",        (char*) &tc_log_page_waits,      SHOW_LONG},
7060
#endif
7061 7062
#ifdef HAVE_POOL_OF_THREADS
  {"Threadpool_idle_threads",  (char *) &show_threadpool_idle_threads, SHOW_FUNC},
7063
  {"Threadpool_threads",       (char *) &tp_stats.num_worker_threads, SHOW_INT},
7064
#endif
7065
  {"Threads_cached",           (char*) &cached_thread_count,    SHOW_LONG_NOFLUSH},
Konstantin Osipov's avatar
Konstantin Osipov committed
7066
  {"Threads_connected",        (char*) &connection_count,       SHOW_INT},
7067 7068
  {"Threads_created",	       (char*) &thread_created,		SHOW_LONG_NOFLUSH},
  {"Threads_running",          (char*) &thread_running,         SHOW_INT},
7069
  {"Uptime",                   (char*) &show_starttime,         SHOW_FUNC},
7070
#ifdef ENABLED_PROFILING
7071
  {"Uptime_since_flush_status",(char*) &show_flushstatustime,   SHOW_FUNC},
7072
#endif
7073
  {NullS, NullS, SHOW_LONG}
unknown's avatar
unknown committed
7074 7075
};

Marc Alff's avatar
Marc Alff committed
7076
bool add_terminator(DYNAMIC_ARRAY *options)
7077 7078
{
  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
7079
  return insert_dynamic(options, (uchar *)&empty_element);
7080 7081
}

7082
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
7083 7084
static void print_version(void)
{
7085
  set_server_version();
7086

7087 7088
  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
7089 7090
}

7091 7092 7093 7094 7095 7096 7097 7098 7099 7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115 7116 7117 7118 7119 7120 7121 7122
/** 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
7123
  sys_var_add_options(&all_options, sys_var::PARSE_EARLY);
7124 7125
  add_plugin_options(&all_options, &mem_root);
  sort_dynamic(&all_options, (qsort_cmp) option_cmp);
Marc Alff's avatar
Marc Alff committed
7126
  add_terminator(&all_options);
7127 7128 7129 7130 7131 7132 7133

  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
7134 7135
static void usage(void)
{
7136
  DBUG_ENTER("usage");
7137
  if (!(default_charset_info= get_charset_by_csname(default_character_set_name,
unknown's avatar
unknown committed
7138 7139 7140 7141 7142
					           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
7143
  print_version();
unknown's avatar
unknown committed
7144
  puts("\
Staale Smedseng's avatar
Staale Smedseng committed
7145
Copyright (C) 2000-2008 MySQL AB, by Monty and others.\n\
7146
Copyright (C) 2000, 2011 Oracle.\n\
7147
Copyright (C) 2009-2011 Monty Program Ab.\n\
unknown's avatar
unknown committed
7148
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
7149
and you are welcome to modify and redistribute it under the GPL license\n\n\
7150
Starts the MariaDB database server.\n");
unknown's avatar
unknown committed
7151 7152

  printf("Usage: %s [OPTIONS]\n", my_progname);
7153
  if (!opt_verbose)
Staale Smedseng's avatar
Staale Smedseng committed
7154
    puts("\nFor more help options (several pages), use mysqld --verbose --help.");
7155 7156
  else
  {
unknown's avatar
unknown committed
7157 7158
#ifdef __WIN__
  puts("NT and Win32 specific options:\n\
Staale Smedseng's avatar
Staale Smedseng committed
7159 7160 7161 7162 7163 7164 7165 7166
  --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
7167
");
7168
  puts("");
unknown's avatar
unknown committed
7169
#endif
7170
  print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
unknown's avatar
unknown committed
7171 7172
  puts("");
  set_ports();
7173

unknown's avatar
unknown committed
7174
  /* Print out all the options including plugin supplied options */
7175
  print_help();
7176

7177 7178 7179 7180 7181 7182 7183
  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
7184
  puts("\n\
unknown's avatar
unknown committed
7185
To see what values a running MySQL server is using, type\n\
7186
'mysqladmin variables' instead of 'mysqld --verbose --help'.");
7187
  }
7188
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
7189
}
7190
#endif /*!EMBEDDED_LIBRARY*/
unknown's avatar
unknown committed
7191

unknown's avatar
unknown committed
7192
/**
7193
  Initialize MySQL global variables to default values.
unknown's avatar
unknown committed
7194

unknown's avatar
unknown committed
7195
  @note
unknown's avatar
unknown committed
7196 7197 7198 7199
    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
7200

7201
    We don't need to set variables refered to in my_long_options
unknown's avatar
unknown committed
7202 7203
    as these are initialized by my_getopt.
*/
unknown's avatar
unknown committed
7204

7205
static int mysql_init_variables(void)
unknown's avatar
unknown committed
7206 7207 7208 7209
{
  /* Things reset to zero */
  opt_skip_slave_start= opt_reckless_slave = 0;
  mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0;
7210
#if defined(HAVE_REALPATH) && !defined(HAVE_valgrind) && !defined(HAVE_BROKEN_REALPATH)
7211
  /*  We can only test for sub paths if my_symlink.c is using realpath */
7212
  myisam_test_invalid_symlink= test_if_data_home_dir;
7213
#endif
unknown's avatar
unknown committed
7214
  opt_log= opt_slow_log= 0;
7215
  opt_bin_log= 0;
unknown's avatar
unknown committed
7216
  opt_disable_networking= opt_skip_show_db=0;
7217
  opt_skip_name_resolve= 0;
7218
  opt_ignore_builtin_innodb= 0;
Sergei Golubchik's avatar
Sergei Golubchik committed
7219
  opt_logname= opt_binlog_index_name= opt_slow_logname= 0;
7220
  opt_log_basename= 0;
unknown's avatar
Merge  
unknown committed
7221
  opt_tc_log_file= (char *)"tc.log";      // no hostname in tc_log file name !
7222 7223
  opt_secure_auth= 0;
  opt_bootstrap= opt_myisam_log= 0;
unknown's avatar
unknown committed
7224
  mqh_used= 0;
7225
  kill_in_progress= 0;
unknown's avatar
unknown committed
7226 7227 7228 7229 7230 7231 7232
  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;
7233
  opt_using_transactions= 0;
unknown's avatar
unknown committed
7234 7235
  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
7236
  aborted_threads= aborted_connects= 0;
unknown's avatar
unknown committed
7237
  subquery_cache_miss= subquery_cache_hit= 0;
unknown's avatar
unknown committed
7238 7239
  delayed_insert_threads= delayed_insert_writes= delayed_rows_in_use= 0;
  delayed_insert_errors= thread_created= 0;
unknown's avatar
Merge  
unknown committed
7240
  specialflag= 0;
7241
  binlog_cache_use=  binlog_cache_disk_use= 0;
unknown's avatar
unknown committed
7242 7243
  max_used_connections= slow_launch_threads = 0;
  mysqld_user= mysqld_chroot= opt_init_file= opt_bin_logname = 0;
7244
  prepared_stmt_count= 0;
7245
  mysqld_unix_port= opt_mysql_tmpdir= my_bind_addr_str= NullS;
7246
  bzero((uchar*) &mysql_tmpdir_list, sizeof(mysql_tmpdir_list));
unknown's avatar
Merge  
unknown committed
7247
  bzero((char *) &global_status_var, sizeof(global_status_var));
7248
  opt_large_pages= 0;
7249
  opt_super_large_pages= 0;
7250 7251 7252
#if defined(ENABLED_DEBUG_SYNC)
  opt_debug_sync_timeout= 0;
#endif /* defined(ENABLED_DEBUG_SYNC) */
7253
  key_map_full.set_all();
unknown's avatar
unknown committed
7254

7255 7256 7257 7258 7259
  /* 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
7260
  character_set_filesystem= &my_charset_bin;
7261

unknown's avatar
unknown committed
7262
  opt_specialflag= SPECIAL_ENGLISH;
7263
  unix_sock= base_ip_sock= extra_ip_sock= INVALID_SOCKET;
unknown's avatar
unknown committed
7264 7265 7266
  mysql_home_ptr= mysql_home;
  pidfile_name_ptr= pidfile_name;
  log_error_file_ptr= log_error_file;
7267
  lc_messages_dir_ptr= lc_messages_dir;
unknown's avatar
unknown committed
7268 7269
  protocol_version= PROTOCOL_VERSION;
  what_to_log= ~ (1L << (uint) COM_TIME);
7270
  refresh_version= 1L;	/* Increments on each reload */
7271
  global_query_id= thread_id= 1L;
7272
  my_atomic_rwlock_init(&global_query_id_lock);
7273
  my_atomic_rwlock_init(&thread_running_lock);
unknown's avatar
unknown committed
7274 7275 7276
  strmov(server_version, MYSQL_SERVER_VERSION);
  threads.empty();
  thread_cache.empty();
7277
  key_caches.empty();
unknown's avatar
unknown committed
7278
  if (!(dflt_key_cache= get_or_create_key_cache(default_key_cache_base.str,
7279
                                                default_key_cache_base.length)))
7280 7281 7282 7283
  {
    sql_print_error("Cannot allocate the keycache");
    return 1;
  }
7284

7285 7286
  /* set key_cache_hash.default_value = dflt_key_cache */
  multi_keycache_init();
unknown's avatar
unknown committed
7287 7288

  /* Set directory paths */
7289 7290 7291
  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
7292 7293
  /* Replication parameters */
  master_info_file= (char*) "master.info",
unknown's avatar
unknown committed
7294
    relay_log_info_file= (char*) "relay-log.info";
unknown's avatar
unknown committed
7295 7296 7297 7298 7299
  report_user= report_password = report_host= 0;	/* TO BE DELETED */
  opt_relay_logname= opt_relaylog_index_name= 0;

  /* Variables in libraries */
  charsets_dir= 0;
7300
  default_character_set_name= (char*) MYSQL_DEFAULT_CHARSET_NAME;
7301
  default_collation_name= compiled_default_collation_name;
unknown's avatar
unknown committed
7302
  character_set_filesystem_name= (char*) "binary";
7303
  lc_messages= (char*) "en_US";
7304
  lc_time_names_name= (char*) "en_US";
7305
  
unknown's avatar
unknown committed
7306 7307 7308 7309
  /* 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");
7310
  current_dbug_option= default_dbug_option;
unknown's avatar
unknown committed
7311 7312
#endif
  opt_error_log= IF_WIN(1,0);
7313 7314
#ifdef ENABLED_PROFILING
    have_profiling = SHOW_OPTION_YES;
7315
#else
7316
    have_profiling = SHOW_OPTION_NO;
7317
#endif
7318

unknown's avatar
unknown committed
7319
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
7320
  have_ssl=SHOW_OPTION_YES;
unknown's avatar
unknown committed
7321
#else
7322
  have_ssl=SHOW_OPTION_NO;
unknown's avatar
unknown committed
7323
#endif
unknown's avatar
unknown committed
7324
#ifdef HAVE_BROKEN_REALPATH
unknown's avatar
unknown committed
7325 7326 7327 7328
  have_symlink=SHOW_OPTION_NO;
#else
  have_symlink=SHOW_OPTION_YES;
#endif
7329 7330 7331 7332 7333
#ifdef HAVE_DLOPEN
  have_dlopen=SHOW_OPTION_YES;
#else
  have_dlopen=SHOW_OPTION_NO;
#endif
unknown's avatar
unknown committed
7334 7335 7336 7337 7338
#ifdef HAVE_QUERY_CACHE
  have_query_cache=SHOW_OPTION_YES;
#else
  have_query_cache=SHOW_OPTION_NO;
#endif
7339 7340 7341 7342 7343 7344 7345 7346 7347 7348
#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
7349 7350 7351 7352 7353 7354
#ifdef HAVE_CRYPT
  have_crypt=SHOW_OPTION_YES;
#else
  have_crypt=SHOW_OPTION_NO;
#endif
#ifdef HAVE_COMPRESS
7355
  have_compress= SHOW_OPTION_YES;
unknown's avatar
unknown committed
7356
#else
7357
  have_compress= SHOW_OPTION_NO;
unknown's avatar
unknown committed
7358 7359 7360 7361 7362 7363
#endif
#ifdef HAVE_LIBWRAP
  libwrapName= NullS;
#endif
#ifdef HAVE_OPENSSL
  des_key_file = 0;
Konstantin Osipov's avatar
Konstantin Osipov committed
7364
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
7365
  ssl_acceptor_fd= 0;
Konstantin Osipov's avatar
Konstantin Osipov committed
7366 7367
#endif /* ! EMBEDDED_LIBRARY */
#endif /* HAVE_OPENSSL */
unknown's avatar
unknown committed
7368 7369 7370 7371
#ifdef HAVE_SMEM
  shared_memory_base_name= default_shared_memory_base_name;
#endif

7372 7373
#if defined(__WIN__)
  /* Allow Win32 users to move MySQL anywhere */
unknown's avatar
unknown committed
7374 7375
  {
    char prg_dev[LIBLEN];
7376 7377 7378 7379 7380 7381 7382 7383 7384 7385 7386
    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
7387 7388 7389 7390 7391
    strcat(prg_dev,"/../");			// Remove 'bin' to get base dir
    cleanup_dirname(mysql_home,prg_dev);
  }
#else
  const char *tmpenv;
unknown's avatar
unknown committed
7392
  if (!(tmpenv = getenv("MY_BASEDIR_VERSION")))
unknown's avatar
unknown committed
7393
    tmpenv = DEFAULT_MYSQL_HOME;
unknown's avatar
unknown committed
7394
  (void) strmake(mysql_home, tmpenv, sizeof(mysql_home)-1);
unknown's avatar
unknown committed
7395
#endif
7396
  return 0;
unknown's avatar
unknown committed
7397 7398
}

7399 7400 7401 7402
my_bool
mysqld_get_one_option(int optid,
                      const struct my_option *opt __attribute__((unused)),
                      char *argument)
unknown's avatar
unknown committed
7403
{
7404 7405
  switch(optid) {
  case '#':
7406
#ifndef DBUG_OFF
7407 7408 7409
    if (!argument)
      argument= (char*) default_dbug_option;
    if (argument[0] == '0' && !argument[1])
unknown's avatar
unknown committed
7410 7411 7412 7413
    {
      DEBUGGER_OFF;
      break;
    }
7414
    DEBUGGER_ON;
7415
    if (argument[0] == '1' && !argument[1])
unknown's avatar
unknown committed
7416
      break;
7417
    DBUG_SET_INITIAL(argument);
7418
    opt_endinfo=1;				/* unireg: memory allocation */
7419 7420
#else
    sql_print_warning("'%s' is disabled in this build", opt->name);
7421
#endif
7422
    break;
7423
  case OPT_DEPRECATED_OPTION:
Sergei Golubchik's avatar
Sergei Golubchik committed
7424 7425
    sql_print_warning("'%s' is deprecated. It does nothing and exists only "
                      "for compatiblity with old my.cnf files.",
7426 7427
                      opt->name);
    break;
7428
  case 'a':
7429
    global_system_variables.sql_mode= MODE_ANSI;
unknown's avatar
unknown committed
7430
    global_system_variables.tx_isolation= ISO_SERIALIZABLE;
7431 7432 7433 7434
    break;
  case 'b':
    strmake(mysql_home,argument,sizeof(mysql_home)-1);
    break;
7435
  case 'C':
7436 7437
    if (default_collation_name == compiled_default_collation_name)
      default_collation_name= 0;
7438
    break;
7439
  case 'l':
7440
    WARN_DEPRECATED(NULL, 10, 1, "--log", "'--general-log'/'--general-log-file'");
7441 7442 7443 7444
    opt_log=1;
    break;
  case 'h':
    strmake(mysql_real_data_home,argument, sizeof(mysql_real_data_home)-1);
7445
    /* Correct pointer set by my_getopt (for embedded library) */
7446
    mysql_real_data_home_ptr= mysql_real_data_home;
7447
    break;
7448
  case 'u':
7449
    if (!mysqld_user || !strcmp(mysqld_user, argument))
unknown's avatar
unknown committed
7450
      mysqld_user= argument;
7451
    else
7452
      sql_print_warning("Ignoring user change to '%s' because the user was set to '%s' earlier on the command line\n", argument, mysqld_user);
7453
    break;
7454
  case 'L':
7455
    strmake(lc_messages_dir, argument, sizeof(lc_messages_dir)-1);
7456
    lc_messages_dir_ptr= lc_messages_dir;
7457
    break;
7458 7459
  case OPT_BINLOG_FORMAT:
    binlog_format_used= true;
7460
    break;
7461
#include <sslopt-case.h>
7462
#ifndef EMBEDDED_LIBRARY
7463 7464
  case 'V':
    print_version();
7465 7466
    opt_abort= 1;                    // Abort after parsing all options
    break;
7467
#endif /*EMBEDDED_LIBRARY*/
7468 7469 7470 7471 7472 7473 7474 7475
  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;
7476 7477 7478 7479 7480 7481 7482 7483
  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:
7484
    opt_bin_log= test(argument != disabled_my_option);
7485
    break;
7486 7487 7488 7489 7490 7491 7492 7493
  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
7494 7495
    if (log_error_file_ptr != disabled_my_option)
      log_error_file_ptr= opt_log_basename;
7496

Sergei Golubchik's avatar
Sergei Golubchik committed
7497 7498 7499 7500 7501 7502
    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);
7503 7504 7505 7506 7507 7508 7509

    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
7510
        ! opt_slow_logname || !pidfile_name_ptr)
7511 7512 7513
      return 1;                                 // out of memory error
    break;
  }
unknown's avatar
SCRUM  
unknown committed
7514
#ifdef HAVE_REPLICATION
7515
  case (int)OPT_REPLICATE_IGNORE_DB:
7516
  {
7517
    rpl_filter->add_ignore_db(argument);
7518 7519 7520 7521
    break;
  }
  case (int)OPT_REPLICATE_DO_DB:
  {
7522
    rpl_filter->add_do_db(argument);
7523 7524 7525 7526
    break;
  }
  case (int)OPT_REPLICATE_REWRITE_DB:
  {
7527
    /* See also OPT_REWRITE_DB handling in client/mysqlbinlog.cc */
7528
    char* key = argument,*p, *val;
7529

7530
    if (!(p= strstr(argument, "->")))
7531
    {
7532 7533
      sql_print_error("Bad syntax in replicate-rewrite-db - missing '->'!\n");
      return 1;
7534
    }
7535
    val= p--;
unknown's avatar
unknown committed
7536
    while (my_isspace(mysqld_charset, *p) && p > argument)
7537 7538
      *p-- = 0;
    if (p == argument)
7539
    {
7540 7541
      sql_print_error("Bad syntax in replicate-rewrite-db - empty FROM db!\n");
      return 1;
7542
    }
7543 7544
    *val= 0;
    val+= 2;
unknown's avatar
unknown committed
7545
    while (*val && my_isspace(mysqld_charset, *val))
7546
      val++;
7547
    if (!*val)
7548
    {
7549 7550
      sql_print_error("Bad syntax in replicate-rewrite-db - empty TO db!\n");
      return 1;
7551 7552
    }

7553
    rpl_filter->add_db_rewrite(key, val);
7554 7555 7556
    break;
  }

7557
  case (int)OPT_BINLOG_IGNORE_DB:
7558
  {
7559
    binlog_filter->add_ignore_db(argument);
7560 7561
    break;
  }
7562
  case (int)OPT_BINLOG_DO_DB:
7563
  {
7564
    binlog_filter->add_do_db(argument);
7565 7566
    break;
  }
7567
  case (int)OPT_REPLICATE_DO_TABLE:
7568
  {
7569
    if (rpl_filter->add_do_table(argument))
7570
    {
7571 7572
      sql_print_error("Could not add do table rule '%s'!\n", argument);
      return 1;
7573
    }
7574 7575
    break;
  }
7576
  case (int)OPT_REPLICATE_WILD_DO_TABLE:
7577
  {
7578
    if (rpl_filter->add_wild_do_table(argument))
7579
    {
7580 7581
      sql_print_error("Could not add do table rule '%s'!\n", argument);
      return 1;
7582
    }
7583 7584
    break;
  }
7585
  case (int)OPT_REPLICATE_WILD_IGNORE_TABLE:
7586
  {
7587
    if (rpl_filter->add_wild_ignore_table(argument))
7588
    {
7589 7590
      sql_print_error("Could not add ignore table rule '%s'!\n", argument);
      return 1;
7591
    }
7592 7593
    break;
  }
7594
  case (int)OPT_REPLICATE_IGNORE_TABLE:
7595
  {
7596
    if (rpl_filter->add_ignore_table(argument))
7597
    {
7598 7599
      sql_print_error("Could not add ignore table rule '%s'!\n", argument);
      return 1;
7600
    }
7601 7602
    break;
  }
unknown's avatar
SCRUM  
unknown committed
7603
#endif /* HAVE_REPLICATION */
7604
  case (int) OPT_SLOW_QUERY_LOG:
7605
    WARN_DEPRECATED(NULL, 10, 1, "--log-slow-queries", "'--slow-query-log'/'--slow-query-log-file'");
7606
    opt_slow_log= 1;
7607
    break;
7608
  case (int) OPT_SAFE:
7609
    opt_specialflag|= SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC;
7610
    delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
7611 7612
    myisam_recover_options= HA_RECOVER_DEFAULT;
    ha_open_options&= ~(HA_OPEN_DELAY_KEY_WRITE);
unknown's avatar
unknown committed
7613
#ifdef HAVE_QUERY_CACHE
7614 7615
    query_cache_size=0;
#endif
7616 7617
    sql_print_warning("The syntax '--safe-mode' is deprecated and will be "
                      "removed in a future release.");
7618 7619 7620
    break;
  case (int) OPT_SKIP_PRIOR:
    opt_specialflag|= SPECIAL_NO_PRIOR;
7621
    sql_print_warning("The --skip-thread-priority startup option is deprecated "
7622
                      "and will be removed in MySQL 11.0. This option has no effect "
Konstantin Osipov's avatar
Konstantin Osipov committed
7623
                      "as the implied behavior is already the default.");
7624
    break;
7625 7626 7627 7628
  case (int) OPT_SKIP_HOST_CACHE:
    opt_specialflag|= SPECIAL_NO_HOST_CACHE;
    break;
  case (int) OPT_SKIP_RESOLVE:
7629
    opt_skip_name_resolve= 1;
7630 7631 7632 7633 7634 7635 7636
    opt_specialflag|=SPECIAL_NO_RESOLVE;
    break;
  case (int) OPT_WANT_CORE:
    test_flags |= TEST_CORE_ON_SIGNAL;
    break;
  case (int) OPT_BIND_ADDRESS:
    {
7637 7638 7639 7640 7641 7642 7643
      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
7644
      {
7645 7646
        sql_print_error("Can't start server: cannot resolve hostname!");
        return 1;
unknown's avatar
unknown committed
7647
      }
7648 7649

      if (res_lst->ai_next)
7650
      {
7651
        sql_print_error("Can't start server: bind-address refers to multiple interfaces!");
7652
        return 1;
7653
      }
7654
      freeaddrinfo(res_lst);
7655 7656
    }
    break;
7657 7658 7659 7660
  case OPT_CONSOLE:
    if (opt_console)
      opt_error_log= 0;			// Force logs to stdout
    break;
7661 7662 7663 7664 7665 7666
  case OPT_BOOTSTRAP:
    opt_noacl=opt_bootstrap=1;
    break;
  case OPT_SERVER_ID:
    server_id_supplied = 1;
    break;
unknown's avatar
unknown committed
7667
  case OPT_ONE_THREAD:
7668
    thread_handling= SCHEDULER_NO_THREADS;
7669
    break;
unknown's avatar
unknown committed
7670
  case OPT_LOWER_CASE_TABLE_NAMES:
7671
    lower_case_table_names_used= 1;
unknown's avatar
unknown committed
7672
    break;
7673 7674 7675 7676 7677 7678 7679 7680 7681 7682 7683 7684 7685 7686 7687 7688
#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) */
7689 7690 7691 7692 7693 7694 7695 7696 7697 7698 7699 7700
  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;
7701 7702 7703 7704 7705 7706 7707 7708
  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;
7709 7710 7711
  case OPT_MAX_LONG_DATA_SIZE:
    max_long_data_size_used= true;
    break;
unknown's avatar
unknown committed
7712
  }
7713 7714
  return 0;
}
7715

7716

unknown's avatar
unknown committed
7717
/** Handle arguments for multiple key caches. */
7718

7719
C_MODE_START
7720

7721
static void*
7722
mysql_getopt_value(const char *keyname, uint key_length,
7723
		   const struct my_option *option, int *error)
7724
{
7725 7726
  if (error)
    *error= 0;
7727 7728
  switch (option->id) {
  case OPT_KEY_BUFFER_SIZE:
unknown's avatar
unknown committed
7729
  case OPT_KEY_CACHE_BLOCK_SIZE:
7730 7731
  case OPT_KEY_CACHE_DIVISION_LIMIT:
  case OPT_KEY_CACHE_AGE_THRESHOLD:
7732
  case OPT_KEY_CACHE_PARTITIONS:
7733
  {
unknown's avatar
unknown committed
7734
    KEY_CACHE *key_cache;
7735
    if (!(key_cache= get_or_create_key_cache(keyname, key_length)))
7736 7737 7738 7739 7740
    {
      if (error)
        *error= EXIT_OUT_OF_MEMORY;
      return 0;
    }
7741 7742
    switch (option->id) {
    case OPT_KEY_BUFFER_SIZE:
7743
      return &key_cache->param_buff_size;
7744
    case OPT_KEY_CACHE_BLOCK_SIZE:
7745
      return &key_cache->param_block_size;
7746
    case OPT_KEY_CACHE_DIVISION_LIMIT:
7747
      return &key_cache->param_division_limit;
7748
    case OPT_KEY_CACHE_AGE_THRESHOLD:
7749
      return &key_cache->param_age_threshold;
7750 7751
    case OPT_KEY_CACHE_PARTITIONS:
      return (uchar**) &key_cache->param_partitions;
7752
    }
7753 7754
  }
  }
7755
  return option->value;
7756 7757
}

7758
static void option_error_reporter(enum loglevel level, const char *format, ...)
unknown's avatar
unknown committed
7759
{
7760
  va_list args;
unknown's avatar
unknown committed
7761
  va_start(args, format);
7762 7763 7764 7765 7766 7767 7768

  /* 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
7769
  va_end(args);
unknown's avatar
unknown committed
7770
}
7771

7772
C_MODE_END
unknown's avatar
unknown committed
7773

unknown's avatar
unknown committed
7774
/**
Marc Alff's avatar
Marc Alff committed
7775 7776 7777 7778 7779 7780
  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
7781 7782 7783
  @todo
  - FIXME add EXIT_TOO_MANY_ARGUMENTS to "mysys_err.h" and return that code?
*/
Marc Alff's avatar
Marc Alff committed
7784
static int get_options(int *argc_ptr, char ***argv_ptr)
7785 7786 7787
{
  int ho_error;

7788
  my_getopt_register_get_addr(mysql_getopt_value);
7789
  my_getopt_error_reporter= option_error_reporter;
unknown's avatar
unknown committed
7790

Marc Alff's avatar
Marc Alff committed
7791 7792 7793 7794
  /* prepare all_options array */
  my_init_dynamic_array(&all_options, sizeof(my_option),
                        array_elements(my_long_options),
                        array_elements(my_long_options)/4);
7795 7796 7797
  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
7798
    insert_dynamic(&all_options, (uchar*) opt);
7799
  sys_var_add_options(&all_options, 0);
Marc Alff's avatar
Marc Alff committed
7800
  add_terminator(&all_options);
7801

unknown's avatar
unknown committed
7802 7803 7804
  /* Skip unknown options so that they may be processed later by plugins */
  my_getopt_skip_unknown= TRUE;

Marc Alff's avatar
Marc Alff committed
7805
  if ((ho_error= handle_options(argc_ptr, argv_ptr, (my_option*)(all_options.buffer),
7806
                                mysqld_get_one_option)))
7807
    return ho_error;
7808 7809 7810

  if (!opt_help)
    delete_dynamic(&all_options);
7811 7812
  else
    opt_abort= 1;
7813

Marc Alff's avatar
Marc Alff committed
7814 7815 7816
  /* Add back the program name handle_options removes */
  (*argc_ptr)++;
  (*argv_ptr)--;
7817

7818 7819 7820 7821 7822 7823
  /*
    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.
  */
7824

7825 7826
  if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes ||
       opt_log_slow_slave_statements) &&
7827
      !opt_slow_log)
7828
    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");
7829 7830 7831 7832 7833 7834 7835 7836
  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);
  }
7837

7838 7839 7840 7841 7842 7843 7844 7845 7846 7847 7848 7849 7850 7851 7852 7853 7854 7855 7856
  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
7857
    mysqld_port= mysqld_extra_port= 0;
7858

7859 7860 7861 7862 7863 7864 7865 7866 7867 7868 7869 7870 7871 7872 7873 7874
  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;

7875 7876 7877 7878 7879 7880
  // 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;
7881 7882 7883

  global_system_variables.sql_mode=
    expand_sql_mode(global_system_variables.sql_mode);
unknown's avatar
unknown committed
7884
#if defined(HAVE_BROKEN_REALPATH)
7885 7886 7887 7888 7889 7890 7891 7892 7893 7894
  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
7895 7896 7897
  if (opt_debugging)
  {
    /* Allow break with SIGINT, no core or stack trace */
Michael Widenius's avatar
Michael Widenius committed
7898 7899
    test_flags|= TEST_SIGINT;
    opt_stack_trace= 1;
7900 7901
    test_flags&= ~TEST_CORE_ON_SIGNAL;
  }
7902
  /* Set global MyISAM variables from delay_key_write_options */
7903
  fix_delay_key_write(0, 0, OPT_GLOBAL);
7904

7905
#ifndef EMBEDDED_LIBRARY
7906 7907
  if (mysqld_chroot)
    set_root(mysqld_chroot);
7908
#else
7909
  thread_handling = SCHEDULER_NO_THREADS;
7910 7911
  max_allowed_packet= global_system_variables.max_allowed_packet;
  net_buffer_length= global_system_variables.net_buffer_length;
7912
#endif
7913 7914
  if (fix_paths())
    return 1;
unknown's avatar
unknown committed
7915

unknown's avatar
unknown committed
7916 7917 7918 7919
  /*
    Set some global variables from the global_system_variables
    In most cases the global variables will not be used
  */
7920
  my_disable_locking= myisam_single_user= test(opt_external_locking == 0);
unknown's avatar
unknown committed
7921
  my_default_record_cache_size=global_system_variables.read_buff_size;
unknown's avatar
unknown committed
7922

7923
  /*
7924 7925 7926
    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.
7927 7928 7929 7930 7931 7932
  */
  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;
7933 7934
  if (my_assert_on_error)
    debug_assert_if_crashed_table= 1;
7935

7936 7937
  global_system_variables.long_query_time= (ulonglong)
    (global_system_variables.long_query_time_double * 1e6);
7938

7939 7940
  if (opt_short_log_format)
    opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT;
7941

7942
  if (init_global_datetime_format(MYSQL_TIMESTAMP_DATE,
7943
                                  &global_date_format) ||
7944
      init_global_datetime_format(MYSQL_TIMESTAMP_TIME,
7945
                                  &global_time_format) ||
7946
      init_global_datetime_format(MYSQL_TIMESTAMP_DATETIME,
7947
                                  &global_datetime_format))
7948
    return 1;
7949

unknown's avatar
unknown committed
7950
#ifdef EMBEDDED_LIBRARY
Sergei Golubchik's avatar
Sergei Golubchik committed
7951 7952
  one_thread_scheduler(thread_scheduler);
  one_thread_scheduler(extra_thread_scheduler);
unknown's avatar
unknown committed
7953
#else
7954 7955 7956 7957 7958 7959 7960 7961

#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

7962
  if (thread_handling <= SCHEDULER_ONE_THREAD_PER_CONNECTION)
Sergei Golubchik's avatar
Sergei Golubchik committed
7963
    one_thread_per_connection_scheduler(thread_scheduler, &max_connections,
7964
                                        &connection_count);
7965
  else if (thread_handling == SCHEDULER_NO_THREADS)
Sergei Golubchik's avatar
Sergei Golubchik committed
7966
    one_thread_scheduler(thread_scheduler);
unknown's avatar
unknown committed
7967
  else
7968 7969 7970
    pool_of_threads_scheduler(thread_scheduler,  &max_connections,
                                        &connection_count); 

Sergei Golubchik's avatar
Sergei Golubchik committed
7971
  one_thread_per_connection_scheduler(extra_thread_scheduler,
7972 7973
                                      &extra_max_connections,
                                      &extra_connection_count);
unknown's avatar
unknown committed
7974
#endif
7975 7976 7977 7978 7979

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

7980 7981
  opt_readonly= read_only;

7982 7983 7984 7985 7986 7987 7988
  /*
    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;

7989
  /* Rember if max_user_connections was 0 at startup */
Sergei Golubchik's avatar
Sergei Golubchik committed
7990
  max_user_connections_checking= global_system_variables.max_user_connections != 0;
7991
  return 0;
unknown's avatar
unknown committed
7992 7993 7994
}


7995 7996 7997 7998 7999 8000 8001
/*
  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
8002
void set_server_version(void)
8003 8004
{
  char *end= strxmov(server_version, MYSQL_SERVER_VERSION,
8005
                     MYSQL_SERVER_SUFFIX_STR, NullS);
8006 8007 8008 8009
#ifdef EMBEDDED_LIBRARY
  end= strmov(end, "-embedded");
#endif
#ifndef DBUG_OFF
8010
  if (!strstr(MYSQL_SERVER_SUFFIX_STR, "-debug"))
8011 8012
    end= strmov(end, "-debug");
#endif
8013
  if (opt_log || opt_slow_log || opt_bin_log)
8014 8015 8016 8017
    strmov(end, "-log");                        // This may slow down system
}


unknown's avatar
unknown committed
8018 8019 8020
static char *get_relative_path(const char *path)
{
  if (test_if_hard_path(path) &&
8021
      is_prefix(path,DEFAULT_MYSQL_HOME) &&
unknown's avatar
unknown committed
8022 8023
      strcmp(DEFAULT_MYSQL_HOME,FN_ROOTDIR))
  {
unknown's avatar
unknown committed
8024
    path+=(uint) strlen(DEFAULT_MYSQL_HOME);
8025
    while (*path == FN_LIBCHAR || *path == FN_LIBCHAR2)
unknown's avatar
unknown committed
8026 8027 8028 8029 8030 8031
      path++;
  }
  return (char*) path;
}


unknown's avatar
unknown committed
8032
/**
8033 8034
  Fix filename and replace extension where 'dir' is relative to
  mysql_real_data_home.
unknown's avatar
unknown committed
8035 8036
  @return
    1 if len(path) > FN_REFLEN
8037 8038 8039
*/

bool
8040
fn_format_relative_to_data_home(char * to, const char *name,
8041 8042 8043 8044 8045 8046 8047 8048 8049 8050
				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,
8051
		    MY_APPEND_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH);
8052 8053 8054
}


8055 8056 8057 8058 8059 8060 8061 8062 8063 8064 8065 8066 8067 8068
/**
  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];
8069
  size_t opt_secure_file_priv_len;
8070 8071 8072 8073 8074 8075
  /*
    All paths are secure if opt_secure_file_path is 0
  */
  if (!opt_secure_file_priv)
    return TRUE;

8076 8077
  opt_secure_file_priv_len= strlen(opt_secure_file_priv);

Georgi Kodinov's avatar
Georgi Kodinov committed
8078 8079 8080
  if (strlen(path) >= FN_REFLEN)
    return FALSE;

8081 8082 8083 8084 8085
  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
8086
    size_t length= dirname_length(path);        // Guaranteed to be < FN_REFLEN
8087 8088 8089 8090 8091 8092
    memcpy(buff2, path, length);
    buff2[length]= '\0';
    if (length == 0 || my_realpath(buff1, buff2, 0))
      return FALSE;
  }
  convert_dirname(buff2, buff1, NullS);
8093 8094 8095 8096 8097 8098 8099 8100 8101 8102 8103 8104 8105 8106
  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;
  }
8107 8108 8109
  return TRUE;
}

Michael Widenius's avatar
Michael Widenius committed
8110

8111
static int fix_paths(void)
unknown's avatar
unknown committed
8112
{
8113
  char buff[FN_REFLEN],*pos;
8114 8115
  DBUG_ENTER("fix_paths");

8116
  convert_dirname(mysql_home,mysql_home,NullS);
8117
  /* Resolve symlinks to allow 'mysql_home' to be a relative symlink */
8118
  my_realpath(mysql_home,mysql_home,MYF(0));
8119 8120 8121 8122 8123 8124 8125
  /* Ensure that mysql_home ends in FN_LIBCHAR */
  pos=strend(mysql_home);
  if (pos[-1] != FN_LIBCHAR)
  {
    pos[0]= FN_LIBCHAR;
    pos[1]= 0;
  }
8126
  convert_dirname(lc_messages_dir, lc_messages_dir, NullS);
8127
  convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
unknown's avatar
unknown committed
8128 8129
  (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);
8130
  (void) my_load_path(pidfile_name, pidfile_name_ptr, mysql_real_data_home);
Marc Alff's avatar
Marc Alff committed
8131

Sergei Golubchik's avatar
Sergei Golubchik committed
8132 8133 8134
  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);
8135
  opt_plugin_dir_ptr= opt_plugin_dir;
Sergei Golubchik's avatar
Sergei Golubchik committed
8136
  pidfile_name_ptr= pidfile_name;
unknown's avatar
unknown committed
8137

8138 8139 8140 8141 8142 8143
  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
8144
  char *sharedir=get_relative_path(SHAREDIR);
unknown's avatar
unknown committed
8145
  if (test_if_hard_path(sharedir))
unknown's avatar
unknown committed
8146
    strmake(buff,sharedir,sizeof(buff)-1);		/* purecov: tested */
unknown's avatar
unknown committed
8147
  else
unknown's avatar
unknown committed
8148
    strxnmov(buff,sizeof(buff)-1,mysql_home,sharedir,NullS);
8149
  convert_dirname(buff,buff,NullS);
8150
  (void) my_load_path(lc_messages_dir, lc_messages_dir, buff);
unknown's avatar
unknown committed
8151 8152

  /* If --character-sets-dir isn't given, use shared library dir */
8153 8154 8155
  if (charsets_dir)
    strmake(mysql_charsets_dir, charsets_dir, sizeof(mysql_charsets_dir)-1);
  else
unknown's avatar
unknown committed
8156 8157
    strxnmov(mysql_charsets_dir, sizeof(mysql_charsets_dir)-1, buff,
	     CHARSET_DIR, NullS);
unknown's avatar
unknown committed
8158
  (void) my_load_path(mysql_charsets_dir, mysql_charsets_dir, buff);
8159
  convert_dirname(mysql_charsets_dir, mysql_charsets_dir, NullS);
unknown's avatar
unknown committed
8160
  charsets_dir=mysql_charsets_dir;
unknown's avatar
unknown committed
8161

unknown's avatar
unknown committed
8162
  if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir))
8163
    DBUG_RETURN(1);
8164 8165
  if (!opt_mysql_tmpdir)
    opt_mysql_tmpdir= mysql_tmpdir;
unknown's avatar
SCRUM  
unknown committed
8166
#ifdef HAVE_REPLICATION
8167
  if (!slave_load_tmpdir)
8168
    slave_load_tmpdir= mysql_tmpdir;
8169
#endif /* HAVE_REPLICATION */
8170 8171 8172
  /*
    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
8173
  */
8174 8175
  if (opt_secure_file_priv)
  {
8176 8177
    if (*opt_secure_file_priv == 0)
    {
8178
      my_free(opt_secure_file_priv);
8179 8180 8181 8182
      opt_secure_file_priv= 0;
    }
    else
    {
8183 8184
      if (strlen(opt_secure_file_priv) >= FN_REFLEN)
        opt_secure_file_priv[FN_REFLEN-1]= '\0';
8185
      if (my_realpath(buff, opt_secure_file_priv, 0))
8186 8187
      {
        sql_print_warning("Failed to normalize the argument for --secure-file-priv.");
8188
        DBUG_RETURN(1);
8189
      }
8190
      char *secure_file_real_path= (char *)my_malloc(FN_REFLEN, MYF(MY_FAE));
8191
      convert_dirname(secure_file_real_path, buff, NullS);
8192
      my_free(opt_secure_file_priv);
8193 8194
      opt_secure_file_priv= secure_file_real_path;
    }
8195
  }
8196
  DBUG_RETURN(0);
unknown's avatar
unknown committed
8197 8198
}

unknown's avatar
unknown committed
8199 8200
/**
  Check if file system used for databases is case insensitive.
8201

unknown's avatar
unknown committed
8202
  @param dir_name			Directory to test
8203

8204 8205 8206
  @retval -1  Don't know (Test failed)
  @retval  0   File system is case sensitive
  @retval  1   File system is case insensitive
8207 8208 8209 8210 8211 8212 8213 8214
*/

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;
8215
  DBUG_ENTER("test_if_case_insensitive");
8216 8217 8218 8219 8220

  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
8221 8222 8223
  mysql_file_delete(key_file_casetest, buff2, MYF(0));
  if ((file= mysql_file_create(key_file_casetest,
                               buff, 0666, O_RDWR, MYF(0))) < 0)
8224
  {
8225
    if (!opt_abort)
8226
      sql_print_warning("Can't create test file %s", buff);
8227
    DBUG_RETURN(-1);
8228
  }
Marc Alff's avatar
Marc Alff committed
8229 8230
  mysql_file_close(file, MYF(0));
  if (mysql_file_stat(key_file_casetest, buff2, &stat_info, MYF(0)))
8231
    result= 1;					// Can access file
Marc Alff's avatar
Marc Alff committed
8232
  mysql_file_delete(key_file_casetest, buff, MYF(MY_WME));
8233 8234
  DBUG_PRINT("exit", ("result: %d", result));
  DBUG_RETURN(result);
8235 8236 8237
}


8238 8239
#ifndef EMBEDDED_LIBRARY

unknown's avatar
unknown committed
8240 8241 8242
/**
  Create file to store pid number.
*/
8243 8244 8245
static void create_pid_file()
{
  File file;
Marc Alff's avatar
Marc Alff committed
8246 8247
  if ((file= mysql_file_create(key_file_pid, pidfile_name, 0664,
                               O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0)
8248
  {
unknown's avatar
unknown committed
8249
    char buff[21], *end;
8250
    end= int10_to_str((long) getpid(), buff, 10);
unknown's avatar
unknown committed
8251
    *end++= '\n';
Marc Alff's avatar
Marc Alff committed
8252 8253
    if (!mysql_file_write(file, (uchar*) buff, (uint) (end-buff),
                          MYF(MY_WME | MY_NABP)))
8254
    {
Marc Alff's avatar
Marc Alff committed
8255
      mysql_file_close(file, MYF(0));
8256 8257
      return;
    }
Marc Alff's avatar
Marc Alff committed
8258
    mysql_file_close(file, MYF(0));
8259
  }
8260
  sql_perror("Can't start server: can't create PID file");
unknown's avatar
foo1  
unknown committed
8261
  exit(1);
8262
}
8263
#endif /* EMBEDDED_LIBRARY */
8264

unknown's avatar
unknown committed
8265
/** Clear most status variables. */
8266 8267
void refresh_status(THD *thd)
{
Marc Alff's avatar
Marc Alff committed
8268
  mysql_mutex_lock(&LOCK_status);
8269

8270
  /* Add thread's status variabes to global status */
8271
  add_to_status(&global_status_var, &thd->status_var);
8272 8273

  /* Reset thread's status variables */
8274
  bzero((uchar*) &thd->status_var, sizeof(thd->status_var));
8275 8276
  bzero((uchar*) &thd->org_status_var, sizeof(thd->org_status_var)); 
  thd->start_bytes_received= 0;
8277

8278
  /* Reset some global variables */
unknown's avatar
unknown committed
8279
  reset_status_vars();
8280

8281
  /* Reset the counters of all key caches (default and named). */
8282
  process_key_caches(reset_key_cache_counters, 0);
8283
  flush_status_time= time((time_t*) 0);
Marc Alff's avatar
Marc Alff committed
8284
  mysql_mutex_unlock(&LOCK_status);
8285 8286 8287 8288 8289 8290 8291

  /*
    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
8292
  mysql_mutex_lock(&LOCK_thread_count);
8293
  max_used_connections= thread_count-delayed_insert_threads;
Marc Alff's avatar
Marc Alff committed
8294
  mysql_mutex_unlock(&LOCK_thread_count);
8295 8296 8297
}


8298
/*****************************************************************************
unknown's avatar
unknown committed
8299 8300
  Instantiate variables for missing storage engines
  This section should go away soon
8301 8302
*****************************************************************************/

unknown's avatar
unknown committed
8303
/*****************************************************************************
8304
  Instantiate templates
unknown's avatar
unknown committed
8305 8306
*****************************************************************************/

8307
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
unknown's avatar
unknown committed
8308 8309 8310 8311
/* Used templates */
template class I_List<THD>;
template class I_List_iterator<THD>;
template class I_List<i_string>;
8312
template class I_List<i_string_pair>;
8313 8314
template class I_List<Statement>;
template class I_List_iterator<Statement>;
unknown's avatar
unknown committed
8315
#endif
Marc Alff's avatar
Marc Alff committed
8316