mysqld.cc 310 KB
Newer Older
unknown's avatar
unknown committed
1
/* Copyright (C) 2000-2003 MySQL AB
2

unknown's avatar
unknown committed
3 4
   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
5
   the Free Software Foundation; version 2 of the License.
6

unknown's avatar
unknown committed
7 8 9 10
   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.
11

unknown's avatar
unknown committed
12 13 14 15 16 17
   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 */

#include "mysql_priv.h"
#include <m_ctype.h>
18
#include <my_dir.h>
19
#include <my_bit.h>
20
#include "slave.h"
21
#include "rpl_mi.h"
22
#include "sql_repl.h"
unknown's avatar
unknown committed
23
#include "rpl_filter.h"
24
#include "repl_failsafe.h"
25
#include <my_stacktrace.h>
26
#include "mysqld_suffix.h"
unknown's avatar
Merge  
unknown committed
27
#include "mysys_err.h"
28
#include "events.h"
29

30
#include "../storage/myisam/ha_myisam.h"
31

32 33
#include "rpl_injector.h"

34 35
#ifdef HAVE_SYS_PRCTL_H
#include <sys/prctl.h>
36 37
#endif

38
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
unknown's avatar
Merge  
unknown committed
39 40
#if defined(NOT_ENOUGH_TESTED) \
  && defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000
41 42 43 44
#define OPT_NDB_SHM_DEFAULT 1
#else
#define OPT_NDB_SHM_DEFAULT 0
#endif
45 46
#endif

unknown's avatar
unknown committed
47 48 49 50
#ifndef DEFAULT_SKIP_THREAD_PRIORITY
#define DEFAULT_SKIP_THREAD_PRIORITY 0
#endif

unknown's avatar
unknown committed
51 52
#include <thr_alarm.h>
#include <ft_global.h>
53
#include <errmsg.h>
unknown's avatar
Merge  
unknown committed
54 55
#include "sp_rcontext.h"
#include "sp_cache.h"
unknown's avatar
unknown committed
56

unknown's avatar
unknown committed
57
#define mysqld_charset &my_charset_latin1
unknown's avatar
unknown committed
58

59 60 61 62 63 64
#ifdef HAVE_purify
#define IF_PURIFY(A,B) (A)
#else
#define IF_PURIFY(A,B) (B)
#endif

65 66 67 68 69 70
#if SIZEOF_CHARP == 4
#define MAX_MEM_TABLE_SIZE ~(ulong) 0
#else
#define MAX_MEM_TABLE_SIZE ~(ulonglong) 0
#endif

71
/* stack traces are only supported on linux intel */
72 73 74 75 76 77
#if defined(__linux__)  && defined(__i386__) && defined(USE_PSTACK)
#define	HAVE_STACK_TRACE_ON_SEGV
#include "../pstack/pstack.h"
char pstack_file_name[80];
#endif /* __linux__ */

78 79 80
/* We have HAVE_purify below as this speeds up the shutdown of MySQL */

#if defined(HAVE_DEC_3_2_THREADS) || defined(SIGNALS_DONT_BREAK_READ) || defined(HAVE_purify) && defined(__linux__)
unknown's avatar
unknown committed
81
#define HAVE_CLOSE_SERVER_SOCK 1
82
#endif
unknown's avatar
unknown committed
83

unknown's avatar
unknown committed
84 85 86 87
extern "C" {					// Because of SCO 3.2V4.2
#include <errno.h>
#include <sys/stat.h>
#ifndef __GNU_LIBRARY__
88
#define __GNU_LIBRARY__				// Skip warnings in getopt.h
unknown's avatar
unknown committed
89
#endif
90
#include <my_getopt.h>
unknown's avatar
unknown committed
91 92 93 94 95 96 97 98 99
#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
100
#include <my_net.h>
unknown's avatar
unknown committed
101

102
#if !defined(__WIN__)
unknown's avatar
unknown committed
103
#  ifndef __NETWARE__
unknown's avatar
unknown committed
104
#include <sys/resource.h>
unknown's avatar
unknown committed
105
#  endif /* __NETWARE__ */
unknown's avatar
unknown committed
106 107 108 109 110 111 112 113 114 115 116
#ifdef HAVE_SYS_UN_H
#  include <sys/un.h>
#endif
#include <netdb.h>
#ifdef HAVE_SELECT_H
#  include <select.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#include <sys/utsname.h>
unknown's avatar
unknown committed
117
#endif /* __WIN__ */
unknown's avatar
unknown committed
118

119
#include <my_libwrap.h>
unknown's avatar
unknown committed
120

121 122 123 124
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif

125 126 127 128 129 130 131
#ifdef __WIN__ 
#include <crtdbg.h>
#define SIGNAL_FMT "exception 0x%x"
#else
#define SIGNAL_FMT "signal %d"
#endif

unknown's avatar
Merge  
unknown committed
132
#ifdef __NETWARE__
unknown's avatar
unknown committed
133 134 135 136
#define zVOLSTATE_ACTIVE 6
#define zVOLSTATE_DEACTIVE 2
#define zVOLSTATE_MAINTENANCE 3

unknown's avatar
unknown committed
137 138 139 140 141 142 143
#undef __event_h__
#include <../include/event.h>
/*
  This #undef exists here because both libc of NetWare and MySQL have
  files named event.h which causes compilation errors.
*/

144
#include <nks/netware.h>
unknown's avatar
unknown committed
145 146 147
#include <nks/vm.h>
#include <library.h>
#include <monitor.h>
unknown's avatar
unknown committed
148 149 150 151 152 153
#include <zOmni.h>                              //For NEB
#include <neb.h>                                //For NEB
#include <nebpub.h>                             //For NEB
#include <zEvent.h>                             //For NSS event structures
#include <zPublics.h>

154 155 156
static void *neb_consumer_id= NULL;             //For storing NEB consumer id
static char datavolname[256]= {0};
static VolumeID_t datavolid;
unknown's avatar
unknown committed
157 158
static event_handle_t eh;
static Report_t ref;
159
static void *refneb= NULL;
160
my_bool event_flag= FALSE;
161
static int volumeid= -1;
unknown's avatar
unknown committed
162 163 164

  /* NEB event callback */
unsigned long neb_event_callback(struct EventBlock *eblock);
165 166 167
static void registerwithneb();
static void getvolumename();
static void getvolumeID(BYTE *volumeName);
unknown's avatar
unknown committed
168
#endif /* __NETWARE__ */
169
  
unknown's avatar
unknown committed
170

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

unknown's avatar
unknown committed
175 176 177 178 179 180
#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
#include <ieeefp.h>
#ifdef HAVE_FP_EXCEPT				// Fix type conflict
typedef fp_except fp_except_t;
#endif

unknown's avatar
unknown committed
181 182 183 184
/**
  We can't handle floating point exceptions with threads, so disable
  this on freebsd.
*/
185
inline void set_proper_floating_point_mode()
unknown's avatar
unknown committed
186 187
{
  /* Don't fall for overflow, underflow,divide-by-zero or loss of precision */
unknown's avatar
unknown committed
188 189 190
#if defined(__i386__)
  fpsetmask(~(FP_X_INV | FP_X_DNML | FP_X_OFL | FP_X_UFL | FP_X_DZ |
	      FP_X_IMP));
unknown's avatar
unknown committed
191
#else
unknown's avatar
unknown committed
192 193 194
 fpsetmask(~(FP_X_INV |             FP_X_OFL | FP_X_UFL | FP_X_DZ |
	     FP_X_IMP));
#endif
unknown's avatar
unknown committed
195
}
196 197 198 199 200 201 202 203 204 205 206 207 208 209
#elif defined(__sgi)
/* for IRIX to use set_fpc_csr() */
#include <sys/fpu.h>

inline void set_proper_floating_point_mode()
{
  /* Enable denormalized DOUBLE values support for IRIX */
  {
    union fpc_csr n;
    n.fc_word = get_fpc_csr();
    n.fc_struct.flush = 0;
    set_fpc_csr(n.fc_word);
  }
}
unknown's avatar
unknown committed
210
#else
211
#define set_proper_floating_point_mode()
unknown's avatar
unknown committed
212 213
#endif /* __FreeBSD__ && HAVE_IEEEFP_H */

unknown's avatar
unknown committed
214 215
} /* cplusplus */

unknown's avatar
unknown committed
216
#define MYSQL_KILL_SIGNAL SIGTERM
unknown's avatar
unknown committed
217 218 219 220 221 222 223 224 225 226 227

#ifdef HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R
#include <sys/types.h>
#else
#include <my_pthread.h>			// For thr_setconcurency()
#endif

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

228
extern "C" sig_handler handle_segfault(int sig);
229

unknown's avatar
unknown committed
230
/* Constants */
231

unknown's avatar
unknown committed
232
const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"};
233 234 235 236 237
/*
  WARNING: When adding new SQL modes don't forget to update the
           tables definitions that stores it's value.
           (ie: mysql.event, mysql.proc)
*/
238
static const char *sql_mode_names[]=
unknown's avatar
unknown committed
239 240
{
  "REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE",
241
  "?", "ONLY_FULL_GROUP_BY", "NO_UNSIGNED_SUBTRACTION",
unknown's avatar
unknown committed
242
  "NO_DIR_IN_CREATE",
243
  "POSTGRESQL", "ORACLE", "MSSQL", "DB2", "MAXDB", "NO_KEY_OPTIONS",
244
  "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", "MYSQL323", "MYSQL40", "ANSI",
245 246 247 248
  "NO_AUTO_VALUE_ON_ZERO", "NO_BACKSLASH_ESCAPES", "STRICT_TRANS_TABLES",
  "STRICT_ALL_TABLES",
  "NO_ZERO_IN_DATE", "NO_ZERO_DATE", "ALLOW_INVALID_DATES",
  "ERROR_FOR_DIVISION_BY_ZERO",
unknown's avatar
Merge  
unknown committed
249
  "TRADITIONAL", "NO_AUTO_CREATE_USER", "HIGH_NOT_PRECEDENCE",
250
  "NO_ENGINE_SUBSTITUTION",
251
  "PAD_CHAR_TO_FULL_LENGTH",
unknown's avatar
Merge  
unknown committed
252
  NullS
unknown's avatar
unknown committed
253
};
254

255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
static const unsigned int sql_mode_names_len[]=
{
  /*REAL_AS_FLOAT*/               13,
  /*PIPES_AS_CONCAT*/             15,
  /*ANSI_QUOTES*/                 11,
  /*IGNORE_SPACE*/                12,
  /*?*/                           1,
  /*ONLY_FULL_GROUP_BY*/          18,
  /*NO_UNSIGNED_SUBTRACTION*/     23,
  /*NO_DIR_IN_CREATE*/            16,
  /*POSTGRESQL*/                  10,
  /*ORACLE*/                      6,
  /*MSSQL*/                       5,
  /*DB2*/                         3,
  /*MAXDB*/                       5,
  /*NO_KEY_OPTIONS*/              14,
  /*NO_TABLE_OPTIONS*/            16,
  /*NO_FIELD_OPTIONS*/            16,
  /*MYSQL323*/                    8,
  /*MYSQL40*/                     7,
  /*ANSI*/                        4,
  /*NO_AUTO_VALUE_ON_ZERO*/       21,
  /*NO_BACKSLASH_ESCAPES*/        20,
  /*STRICT_TRANS_TABLES*/         19,
  /*STRICT_ALL_TABLES*/           17,
  /*NO_ZERO_IN_DATE*/             15,
  /*NO_ZERO_DATE*/                12,
  /*ALLOW_INVALID_DATES*/         19,
  /*ERROR_FOR_DIVISION_BY_ZERO*/  26,
  /*TRADITIONAL*/                 11,
  /*NO_AUTO_CREATE_USER*/         19,
  /*HIGH_NOT_PRECEDENCE*/         19,
287 288
  /*NO_ENGINE_SUBSTITUTION*/      22,
  /*PAD_CHAR_TO_FULL_LENGTH*/     23
289
};
290

unknown's avatar
unknown committed
291
TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"",
292 293
			    sql_mode_names,
                            (unsigned int *)sql_mode_names_len };
unknown's avatar
unknown committed
294 295 296 297 298 299 300 301 302
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
303 304

static const char *thread_handling_names[]=
unknown's avatar
unknown committed
305 306 307 308 309
{ "one-thread-per-connection", "no-threads",
#if HAVE_POOL_OF_THREADS == 1
  "pool-of-threads",
#endif
  NullS};
unknown's avatar
unknown committed
310 311 312 313 314 315 316

TYPELIB thread_handling_typelib=
{
  array_elements(thread_handling_names) - 1, "",
  thread_handling_names, NULL
};

unknown's avatar
unknown committed
317
const char *first_keyword= "first", *binary_keyword= "BINARY";
unknown's avatar
unknown committed
318
const char *my_localhost= "localhost", *delayed_user= "DELAYED";
319 320 321 322 323 324
#if SIZEOF_OFF_T > 4 && defined(BIG_TABLES)
#define GET_HA_ROWS GET_ULL
#else
#define GET_HA_ROWS GET_ULONG
#endif

unknown's avatar
unknown committed
325
bool opt_large_files= sizeof(my_off_t) > 4;
326 327 328 329

/*
  Used with --help for detailed option
*/
330
static my_bool opt_help= 0, opt_verbose= 0;
331

unknown's avatar
Merge  
unknown committed
332
arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
333 334 335
{{&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
336 337
 {&Arg_comparator::compare_row,        &Arg_comparator::compare_e_row},
 {&Arg_comparator::compare_decimal,    &Arg_comparator::compare_e_decimal}};
unknown's avatar
unknown committed
338

339 340
const char *log_output_names[] = { "NONE", "FILE", "TABLE", NullS};
static const unsigned int log_output_names_len[]= { 4, 4, 5, 0 };
341
TYPELIB log_output_typelib= {array_elements(log_output_names)-1,"",
342 343
                             log_output_names, 
                             (unsigned int *) log_output_names_len};
344

unknown's avatar
unknown committed
345 346
/* static variables */

347
/* the default log output is log tables */
unknown's avatar
unknown committed
348 349 350 351 352 353 354 355
static bool lower_case_table_names_used= 0;
static bool volatile select_thread_in_use, signal_thread_in_use;
static bool volatile ready_to_exit;
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;
static ulong killed_threads, thread_created;
static ulong max_used_connections;
unknown's avatar
unknown committed
356
static ulong my_bind_addr;			/**< the address we bind to */
unknown's avatar
unknown committed
357 358 359 360 361
static volatile ulong cached_thread_count= 0;
static const char *sql_mode_str= "OFF";
static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr;
static char *opt_init_slave, *language_ptr, *opt_init_connect;
static char *default_character_set_name;
unknown's avatar
unknown committed
362
static char *character_set_filesystem_name;
363
static char *lc_time_names_name;
unknown's avatar
unknown committed
364
static char *my_bind_addr_str;
365 366
static char *default_collation_name; 
static char *default_storage_engine_str;
367
static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME;
unknown's avatar
unknown committed
368
static I_List<THD> thread_cache;
369
static double long_query_time;
unknown's avatar
unknown committed
370 371 372

static pthread_cond_t COND_thread_cache, COND_flush_thread_cache;

unknown's avatar
unknown committed
373
/* Global variables */
unknown's avatar
unknown committed
374

375 376
bool opt_update_log, opt_bin_log;
my_bool opt_log, opt_slow_log;
unknown's avatar
unknown committed
377
ulong log_output_options;
378
my_bool opt_log_queries_not_using_indexes= 0;
379
bool opt_error_log= IF_WIN(1,0);
unknown's avatar
unknown committed
380
bool opt_disable_networking=0, opt_skip_show_db=0;
381
my_bool opt_character_set_client_handshake= 1;
unknown's avatar
unknown committed
382
bool server_id_supplied = 0;
383
bool opt_endinfo, using_udf_functions;
384
my_bool locked_in_memory;
unknown's avatar
unknown committed
385
bool opt_using_transactions, using_update_log;
unknown's avatar
unknown committed
386
bool volatile abort_loop;
387 388 389 390 391 392 393 394 395
bool volatile shutdown_in_progress;
/**
   @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.
   @note This flag is dropped in 5.1 
   @see grant_init()
 */
bool volatile grant_option;
unknown's avatar
unknown committed
396

unknown's avatar
unknown committed
397
my_bool opt_skip_slave_start = 0; ///< If set, slave is not autostarted
unknown's avatar
unknown committed
398
my_bool opt_reckless_slave = 0;
unknown's avatar
unknown committed
399 400
my_bool opt_enable_named_pipe= 0;
my_bool opt_local_infile, opt_slave_compressed_protocol;
401 402
my_bool opt_safe_user_create = 0, opt_no_mix_types = 0;
my_bool opt_show_slave_auth_info, opt_sql_bin_update = 0;
403
my_bool opt_log_slave_updates= 0;
404
bool slave_warning_issued = false; 
405 406 407 408 409 410

/*
  Legacy global handlerton. These will be removed (please do not add more).
*/
handlerton *heap_hton;
handlerton *myisam_hton;
411
handlerton *partition_hton;
412

413
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
414
const char *opt_ndbcluster_connectstring= 0;
unknown's avatar
Merge  
unknown committed
415
const char *opt_ndb_connectstring= 0;
416
char opt_ndb_constrbuf[1024]= {0};
unknown's avatar
Merge  
unknown committed
417
unsigned opt_ndb_constrbuf_len= 0;
418
my_bool	opt_ndb_shm, opt_ndb_optimized_node_selection;
unknown's avatar
Merge  
unknown committed
419 420 421
ulong opt_ndb_cache_check_time;
const char *opt_ndb_mgmd;
ulong opt_ndb_nodeid;
unknown's avatar
unknown committed
422 423 424 425 426
ulong ndb_extra_logging;
#ifdef HAVE_NDB_BINLOG
ulong ndb_report_thresh_binlog_epoch_slip;
ulong ndb_report_thresh_binlog_mem_usage;
#endif
427

428 429 430 431
extern const char *ndb_distribution_names[];
extern TYPELIB ndb_distribution_typelib;
extern const char *opt_ndb_distribution;
extern enum ndb_distribution opt_ndb_distribution_id;
432
#endif
unknown's avatar
unknown committed
433
my_bool opt_readonly, use_temp_pool, relay_log_purge;
unknown's avatar
unknown committed
434
my_bool opt_sync_frm, opt_allow_suspicious_udfs;
435
my_bool opt_secure_auth= 0;
436
char* opt_secure_file_priv= 0;
437
my_bool opt_log_slow_admin_statements= 0;
438
my_bool opt_log_slow_slave_statements= 0;
unknown's avatar
unknown committed
439
my_bool lower_case_file_system= 0;
unknown's avatar
Merge  
unknown committed
440
my_bool opt_large_pages= 0;
unknown's avatar
unknown committed
441
my_bool opt_myisam_use_mmap= 0;
unknown's avatar
Merge  
unknown committed
442
uint    opt_large_page_size= 0;
443
my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
unknown's avatar
Merge  
unknown committed
444 445 446 447 448
/*
  True if there is at least one per-hour limit for some user, so we should
  check them before each query (and possibly reset counters when hour is
  changed). False otherwise.
*/
unknown's avatar
unknown committed
449
volatile bool mqh_used = 0;
450
my_bool opt_noacl;
unknown's avatar
Merge  
unknown committed
451
my_bool sp_automatic_privileges= 1;
452

453
ulong opt_binlog_rows_event_max_size;
unknown's avatar
unknown committed
454
const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS};
455
TYPELIB binlog_format_typelib=
456
  { array_elements(binlog_format_names) - 1, "",
457
    binlog_format_names, NULL };
458 459
ulong opt_binlog_format_id= (ulong) BINLOG_FORMAT_UNSPEC;
const char *opt_binlog_format= binlog_format_names[opt_binlog_format_id];
460
#ifdef HAVE_INITGROUPS
unknown's avatar
unknown committed
461
static bool calling_initgroups= FALSE; /**< Used in SIGSEGV handler. */
462
#endif
463
uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
464
uint mysqld_port_timeout;
unknown's avatar
unknown committed
465
uint delay_key_write_options, protocol_version;
unknown's avatar
unknown committed
466
uint lower_case_table_names;
unknown's avatar
Merge  
unknown committed
467
uint tc_heuristic_recover= 0;
unknown's avatar
unknown committed
468
uint volatile thread_count, thread_running;
469 470
ulonglong thd_startup_options;
ulong back_log, connect_timeout, concurrency, server_id;
unknown's avatar
unknown committed
471
ulong table_cache_size, table_def_size;
472
ulong what_to_log;
unknown's avatar
unknown committed
473
ulong query_buff_size, slow_launch_time, slave_open_temp_tables;
unknown's avatar
unknown committed
474
ulong open_files_limit, max_binlog_size, max_relay_log_size;
475
ulong slave_net_timeout, slave_trans_retries;
476 477
ulong slave_exec_mode_options;
const char *slave_exec_mode_str= "STRICT";
unknown's avatar
unknown committed
478 479
ulong thread_cache_size=0, thread_pool_size= 0;
ulong binlog_cache_size=0, max_binlog_cache_size=0;
480
ulong query_cache_size=0;
481
ulong refresh_version;  /* Increments on each reload */
482
query_id_t global_query_id;
unknown's avatar
unknown committed
483
ulong aborted_threads, aborted_connects;
unknown's avatar
unknown committed
484 485
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
486
ulong delayed_insert_errors,flush_time;
unknown's avatar
Merge  
unknown committed
487
ulong specialflag=0;
488
ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
unknown's avatar
unknown committed
489
ulong max_connections, max_connect_errors;
unknown's avatar
Merge  
unknown committed
490
uint  max_user_connections= 0;
unknown's avatar
unknown committed
491
/**
492 493 494 495
  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
496
/**
497 498 499 500 501 502 503 504 505 506
  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
507
ulong thread_id=1L,current_pid;
508
ulong slow_launch_threads = 0, sync_binlog_period;
unknown's avatar
unknown committed
509
ulong expire_logs_days = 0;
unknown's avatar
unknown committed
510
ulong rpl_recovery_rank=0;
511
const char *log_output_str= "FILE";
unknown's avatar
unknown committed
512

513
time_t server_start_time, flush_status_time;
514

515 516
char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
char *default_tz_name;
unknown's avatar
unknown committed
517
char log_error_file[FN_REFLEN], glob_hostname[FN_REFLEN];
unknown's avatar
unknown committed
518
char mysql_real_data_home[FN_REFLEN],
519
     language[FN_REFLEN], reg_ext[FN_EXTLEN], mysql_charsets_dir[FN_REFLEN],
unknown's avatar
unknown committed
520
     *opt_init_file, *opt_tc_log_file,
521
     def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
522
char mysql_unpacked_real_data_home[FN_REFLEN];
523
int mysql_unpacked_real_data_home_len;
524
uint reg_ext_length;
525 526 527
const key_map key_map_empty(0);
key_map key_map_full(0);                        // Will be initialized later

528
const char *opt_date_time_formats[3];
529

530
uint mysql_data_home_len;
unknown's avatar
unknown committed
531
char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home;
532
char server_version[SERVER_VERSION_LENGTH];
533
char *mysqld_unix_port, *opt_mysql_tmpdir;
unknown's avatar
unknown committed
534
const char **errmesg;			/**< Error messages */
535
const char *myisam_recover_options_str="OFF";
536
const char *myisam_stats_method_str="nulls_unequal";
537

unknown's avatar
unknown committed
538
/** name of reference on left espression in rewritten IN subquery */
539
const char *in_left_expr_name= "<left expr>";
unknown's avatar
unknown committed
540
/** name of additional condition */
541
const char *in_additional_cond= "<IN COND>";
542 543
const char *in_having_cond= "<IN HAVING>";

unknown's avatar
Merge  
unknown committed
544
my_decimal decimal_zero;
unknown's avatar
unknown committed
545 546 547 548 549 550 551 552
/* 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;

unknown's avatar
unknown committed
553
FILE *bootstrap_file;
unknown's avatar
Merge  
unknown committed
554
int bootstrap_error;
555
FILE *stderror_file=0;
unknown's avatar
unknown committed
556

unknown's avatar
unknown committed
557
I_List<THD> threads;
558
I_List<NAMED_LIST> key_caches;
unknown's avatar
unknown committed
559 560
Rpl_filter* rpl_filter;
Rpl_filter* binlog_filter;
unknown's avatar
unknown committed
561

unknown's avatar
unknown committed
562 563
struct system_variables global_system_variables;
struct system_variables max_system_variables;
unknown's avatar
Merge  
unknown committed
564
struct system_status_var global_status_var;
unknown's avatar
unknown committed
565

unknown's avatar
unknown committed
566
MY_TMPDIR mysql_tmpdir_list;
567
MY_BITMAP temp_pool;
unknown's avatar
unknown committed
568

569 570
CHARSET_INFO *system_charset_info, *files_charset_info ;
CHARSET_INFO *national_charset_info, *table_alias_charset;
unknown's avatar
unknown committed
571
CHARSET_INFO *character_set_filesystem;
572

573 574
MY_LOCALE *my_default_lc_time_names;

575
SHOW_COMP_OPTION have_ssl, have_symlink, have_dlopen, have_query_cache;
576
SHOW_COMP_OPTION have_geometry, have_rtree_keys;
unknown's avatar
unknown committed
577
SHOW_COMP_OPTION have_crypt, have_compress;
578
SHOW_COMP_OPTION have_community_features;
unknown's avatar
unknown committed
579 580

/* Thread specific variables */
581

unknown's avatar
unknown committed
582
pthread_key(MEM_ROOT**,THR_MALLOC);
unknown's avatar
unknown committed
583 584
pthread_key(THD*, THR_THD);
pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
585
		LOCK_mapped_file, LOCK_status, LOCK_global_read_lock,
unknown's avatar
unknown committed
586
		LOCK_error_log, LOCK_uuid_generator,
unknown's avatar
unknown committed
587
		LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
588
		LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
589
	        LOCK_global_system_variables,
590 591
		LOCK_user_conn, LOCK_slave_list, LOCK_active_mi,
                LOCK_connection_count;
unknown's avatar
unknown committed
592
/**
593 594 595 596 597 598 599
  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.
*/
pthread_mutex_t LOCK_prepared_stmt_count;
600 601 602
#ifdef HAVE_OPENSSL
pthread_mutex_t LOCK_des_key_file;
#endif
unknown's avatar
unknown committed
603
rw_lock_t	LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
unknown's avatar
unknown committed
604
rw_lock_t	LOCK_system_variables_hash;
605
pthread_cond_t COND_refresh, COND_thread_count, COND_global_read_lock;
unknown's avatar
unknown committed
606 607
pthread_t signal_thread;
pthread_attr_t connection_attrib;
unknown's avatar
unknown committed
608 609 610 611
pthread_mutex_t  LOCK_server_started;
pthread_cond_t  COND_server_started;

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

613 614
File_parser_dummy_hook file_parser_dummy_hook;

unknown's avatar
unknown committed
615 616 617 618 619
/* replication parameters, if master_host is not NULL, we are a slave */
uint master_port= MYSQL_PORT, master_connect_retry = 60;
uint report_port= MYSQL_PORT;
ulong master_retry_count=0;
char *master_user, *master_password, *master_host, *master_info_file;
unknown's avatar
unknown committed
620
char *relay_log_info_file, *report_user, *report_password, *report_host;
unknown's avatar
unknown committed
621
char *opt_relay_logname = 0, *opt_relaylog_index_name=0;
unknown's avatar
unknown committed
622 623 624
my_bool master_ssl;
char *master_ssl_key, *master_ssl_cert;
char *master_ssl_ca, *master_ssl_capath, *master_ssl_cipher;
625
char *opt_logname, *opt_slow_logname;
unknown's avatar
unknown committed
626 627 628 629

/* Static variables */

static bool kill_in_progress, segfaulted;
630 631 632 633
#ifdef HAVE_STACK_TRACE_ON_SEGV
static my_bool opt_do_pstack;
#endif /* HAVE_STACK_TRACE_ON_SEGV */
static my_bool opt_bootstrap, opt_myisam_log;
unknown's avatar
unknown committed
634 635
static int cleanup_done;
static ulong opt_specialflag, opt_myisam_block_size;
636 637
static char *opt_update_logname, *opt_binlog_index_name;
static char *opt_tc_heuristic_recover;
unknown's avatar
unknown committed
638
static char *mysql_home_ptr, *pidfile_name_ptr;
unknown's avatar
unknown committed
639
static int defaults_argc;
unknown's avatar
unknown committed
640 641 642 643
static char **defaults_argv;
static char *opt_bin_logname;

static my_socket unix_sock,ip_sock;
unknown's avatar
unknown committed
644
struct rand_struct sql_rand; ///< used by sql_class.cc:THD::THD()
unknown's avatar
unknown committed
645

unknown's avatar
unknown committed
646 647 648
#ifndef EMBEDDED_LIBRARY
struct passwd *user_info;
static pthread_t select_thread;
unknown's avatar
unknown committed
649
static uint thr_kill_signal;
unknown's avatar
unknown committed
650 651
#endif

unknown's avatar
unknown committed
652 653
/* OS specific variables */

unknown's avatar
unknown committed
654 655 656
#ifdef __WIN__
#undef	 getpid
#include <process.h>
unknown's avatar
unknown committed
657 658 659 660 661 662 663

static pthread_cond_t COND_handler_count;
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
664
#if !defined(EMBEDDED_LIBRARY)
unknown's avatar
unknown committed
665
static HANDLE hEventShutdown;
666
static char shutdown_event_name[40];
unknown's avatar
unknown committed
667
#include "nt_servc.h"
unknown's avatar
unknown committed
668
static	 NTService  Service;	      ///< Service object for WinNT
unknown's avatar
unknown committed
669 670 671 672
#endif /* EMBEDDED_LIBRARY */
#endif /* __WIN__ */

#ifdef __NT__
673
static char pipe_name[512];
unknown's avatar
unknown committed
674 675 676
static SECURITY_ATTRIBUTES saPipeSecurity;
static SECURITY_DESCRIPTOR sdPipeDescriptor;
static HANDLE hPipe = INVALID_HANDLE_VALUE;
unknown's avatar
unknown committed
677
#endif
unknown's avatar
unknown committed
678

unknown's avatar
unknown committed
679
#ifndef EMBEDDED_LIBRARY
680
bool mysqld_embedded=0;
unknown's avatar
unknown committed
681
#else
682
bool mysqld_embedded=1;
unknown's avatar
unknown committed
683 684 685 686 687 688
#endif

#ifndef DBUG_OFF
static const char* default_dbug_option;
#endif
#ifdef HAVE_LIBWRAP
689
const char *libwrapName= NULL;
690 691
int allow_severity = LOG_INFO;
int deny_severity = LOG_WARNING;
unknown's avatar
unknown committed
692 693
#endif
#ifdef HAVE_QUERY_CACHE
unknown's avatar
unknown committed
694
static ulong query_cache_limit= 0;
unknown's avatar
unknown committed
695 696 697 698 699
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;
700
my_bool opt_enable_shared_memory;
701
HANDLE smem_event_connect_request= 0;
unknown's avatar
unknown committed
702 703
#endif

unknown's avatar
unknown committed
704 705
scheduler_functions thread_scheduler;

706
#define SSL_VARS_NOT_STATIC
unknown's avatar
unknown committed
707 708
#include "sslopt-vars.h"
#ifdef HAVE_OPENSSL
709
#include <openssl/crypto.h>
unknown's avatar
unknown committed
710
#ifndef HAVE_YASSL
711 712 713 714 715 716 717 718 719 720 721
typedef struct CRYPTO_dynlock_value
{
  rw_lock_t lock;
} 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
722
#endif
unknown's avatar
unknown committed
723
char *des_key_file;
unknown's avatar
unknown committed
724
struct st_VioSSLFd *ssl_acceptor_fd;
unknown's avatar
unknown committed
725 726
#endif /* HAVE_OPENSSL */

727 728 729 730 731
/**
  Number of currently active user connections. The variable is protected by
  LOCK_connection_count.
*/
uint connection_count= 0;
unknown's avatar
unknown committed
732 733 734

/* Function declarations */

735
pthread_handler_t signal_hand(void *arg);
unknown's avatar
unknown committed
736
static void mysql_init_variables(void);
unknown's avatar
unknown committed
737
static void get_options(int *argc,char **argv);
738
extern "C" my_bool mysqld_get_one_option(int, const struct my_option *, char *);
739
static void set_server_version(void);
740
static int init_thread_environment();
unknown's avatar
unknown committed
741 742
static char *get_relative_path(const char *path);
static void fix_paths(void);
743 744
pthread_handler_t handle_connections_sockets(void *arg);
pthread_handler_t kill_server_thread(void *arg);
unknown's avatar
Merge  
unknown committed
745
static void bootstrap(FILE *file);
unknown's avatar
unknown committed
746 747
static bool read_init_file(char *file_name);
#ifdef __NT__
748
pthread_handler_t handle_connections_namedpipes(void *arg);
unknown's avatar
unknown committed
749
#endif
750
#ifdef HAVE_SMEM
751
pthread_handler_t handle_connections_shared_memory(void *arg);
752
#endif
753
pthread_handler_t handle_slave(void *arg);
754
static ulong find_bit_type(const char *x, TYPELIB *bit_lib);
755 756
static ulong find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
                                   const char *option);
unknown's avatar
unknown committed
757
static void clean_up(bool print_message);
758 759 760
static int test_if_case_insensitive(const char *dir_name);

#ifndef EMBEDDED_LIBRARY
761
static void usage(void);
762 763
static void start_signal_handler(void);
static void close_server_sock();
unknown's avatar
unknown committed
764
static void clean_up_mutexes(void);
765
static void wait_for_signal_thread_to_end(void);
766
static void create_pid_file();
767
static void end_ssl();
768 769
#endif

770 771

#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787
/****************************************************************************
** 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 flush thread */
788 789
  (void) pthread_mutex_lock(&LOCK_manager);
  if (manager_thread_in_use)
unknown's avatar
unknown committed
790
  {
unknown's avatar
unknown committed
791 792
    DBUG_PRINT("quit", ("killing manager thread: 0x%lx",
                        (ulong)manager_thread));
793
   (void) pthread_cond_signal(&COND_manager);
unknown's avatar
unknown committed
794
  }
795
  (void) pthread_mutex_unlock(&LOCK_manager);
unknown's avatar
unknown committed
796 797

  /* kill connection thread */
798
#if !defined(__WIN__) && !defined(__NETWARE__)
unknown's avatar
unknown committed
799 800
  DBUG_PRINT("quit", ("waiting for select thread: 0x%lx",
                      (ulong) select_thread));
unknown's avatar
unknown committed
801 802 803 804 805 806 807
  (void) pthread_mutex_lock(&LOCK_thread_count);

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

unknown's avatar
unknown committed
810
#ifndef DONT_USE_THR_ALARM
811
    if (pthread_kill(select_thread, thr_client_alarm))
unknown's avatar
unknown committed
812 813
      break;					// allready dead
#endif
814
    set_timespec(abstime, 2);
815
    for (uint tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
unknown's avatar
unknown committed
816 817 818 819 820 821 822 823 824 825
    {
      error=pthread_cond_timedwait(&COND_thread_count,&LOCK_thread_count,
				   &abstime);
      if (error != EINTR)
	break;
    }
#ifdef EXTRA_DEBUG
    if (error != 0 && !count++)
      sql_print_error("Got error %d from pthread_cond_timedwait",error);
#endif
unknown's avatar
unknown committed
826
    close_server_sock();
unknown's avatar
unknown committed
827 828 829 830 831 832 833
  }
  (void) pthread_mutex_unlock(&LOCK_thread_count);
#endif /* __WIN__ */


  /* Abort listening to new connections */
  DBUG_PRINT("quit",("Closing sockets"));
unknown's avatar
Merge  
unknown committed
834
  if (!opt_disable_networking )
unknown's avatar
unknown committed
835 836 837
  {
    if (ip_sock != INVALID_SOCKET)
    {
838
      (void) shutdown(ip_sock, SHUT_RDWR);
unknown's avatar
unknown committed
839 840 841 842 843
      (void) closesocket(ip_sock);
      ip_sock= INVALID_SOCKET;
    }
  }
#ifdef __NT__
unknown's avatar
unknown committed
844
  if (hPipe != INVALID_HANDLE_VALUE && opt_enable_named_pipe)
unknown's avatar
unknown committed
845
  {
unknown's avatar
merge  
unknown committed
846
    HANDLE temp;
unknown's avatar
Merge  
unknown committed
847
    DBUG_PRINT("quit", ("Closing named pipes") );
848

unknown's avatar
merge  
unknown committed
849
    /* Create connection to the handle named pipe handler to break the loop */
850
    if ((temp = CreateFile(pipe_name,
unknown's avatar
merge  
unknown committed
851 852 853 854 855 856 857
			   GENERIC_READ | GENERIC_WRITE,
			   0,
			   NULL,
			   OPEN_EXISTING,
			   0,
			   NULL )) != INVALID_HANDLE_VALUE)
    {
858
      WaitNamedPipe(pipe_name, 1000);
unknown's avatar
merge  
unknown committed
859 860 861 862 863 864
      DWORD dwMode = PIPE_READMODE_BYTE | PIPE_WAIT;
      SetNamedPipeHandleState(temp, &dwMode, NULL, NULL);
      CancelIo(temp);
      DisconnectNamedPipe(temp);
      CloseHandle(temp);
    }
unknown's avatar
unknown committed
865 866 867 868 869
  }
#endif
#ifdef HAVE_SYS_UN_H
  if (unix_sock != INVALID_SOCKET)
  {
870
    (void) shutdown(unix_sock, SHUT_RDWR);
unknown's avatar
unknown committed
871
    (void) closesocket(unix_sock);
872
    (void) unlink(mysqld_unix_port);
unknown's avatar
unknown committed
873 874 875
    unix_sock= INVALID_SOCKET;
  }
#endif
876
  end_thr_alarm(0);			 // Abort old alarms.
unknown's avatar
unknown committed
877

878 879 880 881 882
  /*
    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
883 884 885 886 887 888 889 890 891

  THD *tmp;
  (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list

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

unknown's avatar
unknown committed
896
    tmp->killed= THD::KILL_CONNECTION;
unknown's avatar
unknown committed
897
    thread_scheduler.post_kill_notification(tmp);
unknown's avatar
unknown committed
898 899 900
    if (tmp->mysys_var)
    {
      tmp->mysys_var->abort=1;
unknown's avatar
unknown committed
901 902
      pthread_mutex_lock(&tmp->mysys_var->mutex);
      if (tmp->mysys_var->current_cond)
unknown's avatar
unknown committed
903 904 905 906 907
      {
	pthread_mutex_lock(tmp->mysys_var->current_mutex);
	pthread_cond_broadcast(tmp->mysys_var->current_cond);
	pthread_mutex_unlock(tmp->mysys_var->current_mutex);
      }
unknown's avatar
unknown committed
908
      pthread_mutex_unlock(&tmp->mysys_var->mutex);
unknown's avatar
unknown committed
909 910 911 912
    }
  }
  (void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list

913
  Events::deinit();
914 915
  end_slave();

unknown's avatar
unknown committed
916
  if (thread_count)
917
    sleep(2);					// Give threads time to die
unknown's avatar
unknown committed
918

919 920 921 922 923
  /*
    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
924 925 926 927 928 929 930 931 932 933 934 935

  for (;;)
  {
    DBUG_PRINT("quit",("Locking LOCK_thread_count"));
    (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
    if (!(tmp=threads.get()))
    {
      DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
      (void) pthread_mutex_unlock(&LOCK_thread_count);
      break;
    }
#ifndef __bsdi__				// Bug in BSDI kernel
936
    if (tmp->vio_ok())
unknown's avatar
unknown committed
937
    {
938 939
      if (global_system_variables.log_warnings)
        sql_print_warning(ER(ER_FORCING_CLOSE),my_progname,
940
                          tmp->thread_id,
941 942
                          (tmp->main_security_ctx.user ?
                           tmp->main_security_ctx.user : ""));
943
      close_connection(tmp,0,0);
unknown's avatar
unknown committed
944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962
    }
#endif
    DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
    (void) pthread_mutex_unlock(&LOCK_thread_count);
  }
  /* All threads has now been aborted */
  DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count));
  (void) pthread_mutex_lock(&LOCK_thread_count);
  while (thread_count)
  {
    (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
    DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
  }
  (void) pthread_mutex_unlock(&LOCK_thread_count);

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

963

964
static void close_server_sock()
unknown's avatar
unknown committed
965
{
966
#ifdef HAVE_CLOSE_SERVER_SOCK
unknown's avatar
unknown committed
967
  DBUG_ENTER("close_server_sock");
968 969 970
  my_socket tmp_sock;
  tmp_sock=ip_sock;
  if (tmp_sock != INVALID_SOCKET)
unknown's avatar
unknown committed
971 972
  {
    ip_sock=INVALID_SOCKET;
973
    DBUG_PRINT("info",("calling shutdown on TCP/IP socket"));
974
    VOID(shutdown(tmp_sock, SHUT_RDWR));
unknown's avatar
unknown committed
975
#if defined(__NETWARE__)
976
    /*
unknown's avatar
unknown committed
977 978
      The following code is disabled for normal systems as it causes MySQL
      to hang on AIX 4.3 during shutdown
979
    */
980
    DBUG_PRINT("info",("calling closesocket on TCP/IP socket"));
981
    VOID(closesocket(tmp_sock));
982
#endif
unknown's avatar
unknown committed
983
  }
984 985
  tmp_sock=unix_sock;
  if (tmp_sock != INVALID_SOCKET)
unknown's avatar
unknown committed
986
  {
987
    unix_sock=INVALID_SOCKET;
988
    DBUG_PRINT("info",("calling shutdown on unix socket"));
989
    VOID(shutdown(tmp_sock, SHUT_RDWR));
unknown's avatar
unknown committed
990
#if defined(__NETWARE__)
unknown's avatar
unknown committed
991
    /*
992 993
      The following code is disabled for normal systems as it may cause MySQL
      to hang on AIX 4.3 during shutdown
unknown's avatar
unknown committed
994 995
    */
    DBUG_PRINT("info",("calling closesocket on unix/IP socket"));
996
    VOID(closesocket(tmp_sock));
unknown's avatar
unknown committed
997
#endif
998
    VOID(unlink(mysqld_unix_port));
unknown's avatar
unknown committed
999 1000 1001
  }
  DBUG_VOID_RETURN;
#endif
1002
}
unknown's avatar
unknown committed
1003

1004 1005
#endif /*EMBEDDED_LIBRARY*/

1006

unknown's avatar
unknown committed
1007 1008 1009 1010
void kill_mysql(void)
{
  DBUG_ENTER("kill_mysql");

1011
#if defined(SIGNALS_DONT_BREAK_READ) && !defined(EMBEDDED_LIBRARY)
1012 1013
  abort_loop=1;					// Break connection loops
  close_server_sock();				// Force accept to wake up
1014
#endif
unknown's avatar
unknown committed
1015

unknown's avatar
unknown committed
1016
#if defined(__WIN__)
unknown's avatar
unknown committed
1017
#if !defined(EMBEDDED_LIBRARY)
unknown's avatar
unknown committed
1018 1019 1020 1021 1022
  {
    if (!SetEvent(hEventShutdown))
    {
      DBUG_PRINT("error",("Got error: %ld from SetEvent",GetLastError()));
    }
1023 1024 1025 1026 1027 1028
    /*
      or:
      HANDLE hEvent=OpenEvent(0, FALSE, "MySqlShutdown");
      SetEvent(hEventShutdown);
      CloseHandle(hEvent);
    */
unknown's avatar
unknown committed
1029
  }
unknown's avatar
unknown committed
1030
#endif
unknown's avatar
unknown committed
1031
#elif defined(HAVE_PTHREAD_KILL)
1032
  if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL))
unknown's avatar
unknown committed
1033 1034 1035 1036
  {
    DBUG_PRINT("error",("Got error %d from pthread_kill",errno)); /* purecov: inspected */
  }
#elif !defined(SIGNALS_DONT_BREAK_READ)
1037
  kill(current_pid, MYSQL_KILL_SIGNAL);
unknown's avatar
unknown committed
1038
#endif
unknown's avatar
unknown committed
1039 1040 1041
  DBUG_PRINT("quit",("After pthread_kill"));
  shutdown_in_progress=1;			// Safety if kill didn't work
#ifdef SIGNALS_DONT_BREAK_READ
1042
  if (!kill_in_progress)
unknown's avatar
unknown committed
1043 1044
  {
    pthread_t tmp;
unknown's avatar
unknown committed
1045
    abort_loop=1;
unknown's avatar
unknown committed
1046 1047
    if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
			   (void*) 0))
1048
      sql_print_error("Can't create thread to kill server");
unknown's avatar
unknown committed
1049
  }
1050
#endif
unknown's avatar
unknown committed
1051
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
1052 1053
}

unknown's avatar
unknown committed
1054 1055
/**
  Force server down. Kill all connections and threads and exit.
1056

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

unknown's avatar
unknown committed
1059
  @note
1060 1061 1062 1063
    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
1064

1065
#if defined(__NETWARE__)
unknown's avatar
unknown committed
1066
extern "C" void kill_server(int sig_ptr)
1067
#define RETURN_FROM_KILL_SERVER DBUG_VOID_RETURN
unknown's avatar
unknown committed
1068
#elif !defined(__WIN__)
unknown's avatar
unknown committed
1069
static void *kill_server(void *sig_ptr)
unknown's avatar
unknown committed
1070
#define RETURN_FROM_KILL_SERVER DBUG_RETURN(0)
unknown's avatar
unknown committed
1071 1072
#else
static void __cdecl kill_server(int sig_ptr)
unknown's avatar
unknown committed
1073
#define RETURN_FROM_KILL_SERVER DBUG_VOID_RETURN
unknown's avatar
unknown committed
1074 1075 1076
#endif
{
  DBUG_ENTER("kill_server");
1077
#ifndef EMBEDDED_LIBRARY
unknown's avatar
Merge  
unknown committed
1078
  int sig=(int) (long) sig_ptr;			// This is passed a int
1079
  // if there is a signal during the kill in progress, ignore the other
unknown's avatar
unknown committed
1080 1081 1082 1083
  if (kill_in_progress)				// Safety
    RETURN_FROM_KILL_SERVER;
  kill_in_progress=TRUE;
  abort_loop=1;					// This should be set
1084
  if (sig != 0) // 0 is not a valid signal number
1085
    my_sigset(sig, SIG_IGN);                    /* purify inspected */
unknown's avatar
unknown committed
1086
  if (sig == MYSQL_KILL_SIGNAL || sig == 0)
1087
    sql_print_information(ER(ER_NORMAL_SHUTDOWN),my_progname);
unknown's avatar
unknown committed
1088 1089 1090
  else
    sql_print_error(ER(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */

1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102
#if defined(HAVE_SMEM) && defined(__WIN__)    
  /*    
   Send event to smem_event_connect_request for aborting    
   */    
  if (!SetEvent(smem_event_connect_request))    
  {      
	  DBUG_PRINT("error",
		("Got error: %ld from SetEvent of smem_event_connect_request",
		 GetLastError()));    
  }
#endif  
  
unknown's avatar
unknown committed
1103
  close_connections();
1104 1105
  if (sig != MYSQL_KILL_SIGNAL &&
      sig != 0)
unknown's avatar
unknown committed
1106 1107
    unireg_abort(1);				/* purecov: inspected */
  else
1108
    unireg_end();
unknown's avatar
Merge  
unknown committed
1109

1110
  /* purecov: begin deadcode */
unknown's avatar
unknown committed
1111
#ifdef __NETWARE__
unknown's avatar
unknown committed
1112
  if (!event_flag)
unknown's avatar
Merge  
unknown committed
1113
    pthread_join(select_thread, NULL);		// wait for main thread
unknown's avatar
unknown committed
1114
#endif /* __NETWARE__ */
1115

1116
  my_thread_end();
1117 1118
  pthread_exit(0);
  /* purecov: end */
unknown's avatar
unknown committed
1119

1120
#endif /* EMBEDDED_LIBRARY */
unknown's avatar
unknown committed
1121 1122 1123 1124
  RETURN_FROM_KILL_SERVER;
}


unknown's avatar
unknown committed
1125
#if defined(USE_ONE_SIGNAL_HAND) || (defined(__NETWARE__) && defined(SIGNALS_DONT_BREAK_READ))
1126
pthread_handler_t kill_server_thread(void *arg __attribute__((unused)))
unknown's avatar
unknown committed
1127 1128 1129
{
  my_thread_init();				// Initialize new thread
  kill_server(0);
1130 1131 1132
  /* purecov: begin deadcode */
  my_thread_end();
  pthread_exit(0);
unknown's avatar
unknown committed
1133
  return 0;
1134
  /* purecov: end */
unknown's avatar
unknown committed
1135 1136 1137
}
#endif

1138

1139
extern "C" sig_handler print_signal_warning(int sig)
unknown's avatar
unknown committed
1140
{
unknown's avatar
unknown committed
1141
  if (global_system_variables.log_warnings)
1142
    sql_print_warning("Got signal %d from thread %ld", sig,my_thread_id());
unknown's avatar
unknown committed
1143
#ifdef DONT_REMEMBER_SIGNAL
1144
  my_sigset(sig,print_signal_warning);		/* int. thread system calls */
unknown's avatar
unknown committed
1145
#endif
1146
#if !defined(__WIN__) && !defined(__NETWARE__)
unknown's avatar
unknown committed
1147 1148 1149 1150 1151
  if (sig == SIGALRM)
    alarm(2);					/* reschedule alarm */
#endif
}

unknown's avatar
unknown committed
1152
#ifndef EMBEDDED_LIBRARY
1153

unknown's avatar
unknown committed
1154 1155
/**
  cleanup all memory and end program nicely.
unknown's avatar
unknown committed
1156

1157 1158 1159
    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
1160

unknown's avatar
unknown committed
1161 1162 1163
  @note
    This function never returns.
*/
1164
void unireg_end(void)
unknown's avatar
unknown committed
1165
{
unknown's avatar
unknown committed
1166
  clean_up(1);
unknown's avatar
unknown committed
1167
  my_thread_end();
1168
#if defined(SIGNALS_DONT_BREAK_READ) && !defined(__NETWARE__)
1169 1170
  exit(0);
#else
unknown's avatar
unknown committed
1171
  pthread_exit(0);				// Exit is in main thread
1172
#endif
unknown's avatar
unknown committed
1173 1174
}

1175
extern "C" void unireg_abort(int exit_code)
unknown's avatar
unknown committed
1176
{
1177
  DBUG_ENTER("unireg_abort");
1178

unknown's avatar
unknown committed
1179 1180
  if (exit_code)
    sql_print_error("Aborting\n");
1181 1182
  else if (opt_help)
    usage();
1183
  clean_up(!opt_help && (exit_code || !opt_bootstrap)); /* purecov: inspected */
1184
  DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
1185
  wait_for_signal_thread_to_end();
unknown's avatar
unknown committed
1186 1187
  clean_up_mutexes();
  my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
unknown's avatar
unknown committed
1188 1189
  exit(exit_code); /* purecov: inspected */
}
1190
#endif
unknown's avatar
unknown committed
1191

unknown's avatar
unknown committed
1192

1193
void clean_up(bool print_message)
unknown's avatar
unknown committed
1194 1195 1196 1197
{
  DBUG_PRINT("exit",("clean_up"));
  if (cleanup_done++)
    return; /* purecov: inspected */
unknown's avatar
unknown committed
1198

1199 1200
  release_ddl_log();

unknown's avatar
unknown committed
1201 1202 1203 1204 1205
  /*
    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
1206 1207 1208

  logger.cleanup_base();

1209
  injector::free_instance();
unknown's avatar
unknown committed
1210 1211
  mysql_bin_log.cleanup();

unknown's avatar
SCRUM  
unknown committed
1212
#ifdef HAVE_REPLICATION
unknown's avatar
unknown committed
1213 1214
  if (use_slave_mask)
    bitmap_free(&slave_error_mask);
1215
#endif
1216
  my_tz_free();
unknown's avatar
unknown committed
1217
  my_database_names_free();
unknown's avatar
unknown committed
1218
#ifndef NO_EMBEDDED_ACCESS_CHECKS
unknown's avatar
unknown committed
1219
  servers_free(1);
unknown's avatar
unknown committed
1220 1221
  acl_free(1);
  grant_free();
unknown's avatar
unknown committed
1222
#endif
unknown's avatar
unknown committed
1223
  query_cache_destroy();
unknown's avatar
unknown committed
1224
  table_cache_free();
unknown's avatar
unknown committed
1225
  table_def_free();
unknown's avatar
unknown committed
1226 1227 1228
  hostname_cache_free();
  item_user_lock_free();
  lex_free();				/* Free some memory */
1229
  item_create_cleanup();
unknown's avatar
unknown committed
1230
  set_var_free();
1231
  free_charsets();
unknown's avatar
unknown committed
1232
  if (!opt_noacl)
1233
  {
1234
#ifdef HAVE_DLOPEN
unknown's avatar
unknown committed
1235
    udf_free();
1236
#endif
1237
  }
1238
  plugin_shutdown();
1239
  ha_end();
unknown's avatar
Merge  
unknown committed
1240 1241
  if (tc_log)
    tc_log->close();
1242
  xid_cache_free();
1243
  delete_elements(&key_caches, (void (*)(const char*, uchar*)) free_key_cache);
1244
  multi_keycache_free();
1245
  free_status_vars();
1246
  end_thr_alarm(1);			/* Free allocated memory */
1247
  my_free_open_file_info();
1248 1249 1250 1251 1252 1253
  my_free((char*) global_system_variables.date_format,
	  MYF(MY_ALLOW_ZERO_PTR));
  my_free((char*) global_system_variables.time_format,
	  MYF(MY_ALLOW_ZERO_PTR));
  my_free((char*) global_system_variables.datetime_format,
	  MYF(MY_ALLOW_ZERO_PTR));
unknown's avatar
unknown committed
1254 1255
  if (defaults_argv)
    free_defaults(defaults_argv);
unknown's avatar
unknown committed
1256 1257
  my_free(sys_init_connect.value, MYF(MY_ALLOW_ZERO_PTR));
  my_free(sys_init_slave.value, MYF(MY_ALLOW_ZERO_PTR));
1258 1259
  my_free(sys_var_general_log_path.value, MYF(MY_ALLOW_ZERO_PTR));
  my_free(sys_var_slow_log_path.value, MYF(MY_ALLOW_ZERO_PTR));
unknown's avatar
unknown committed
1260
  free_tmpdir(&mysql_tmpdir_list);
unknown's avatar
SCRUM  
unknown committed
1261
#ifdef HAVE_REPLICATION
1262
  my_free(slave_load_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
1263
#endif
1264
  x_free(opt_bin_logname);
1265
  x_free(opt_relay_logname);
1266
  x_free(opt_secure_file_priv);
unknown's avatar
unknown committed
1267
  bitmap_free(&temp_pool);
unknown's avatar
unknown committed
1268
  free_max_user_conn();
unknown's avatar
SCRUM  
unknown committed
1269
#ifdef HAVE_REPLICATION
1270
  end_slave_list();
1271
#endif
unknown's avatar
unknown committed
1272 1273
  delete binlog_filter;
  delete rpl_filter;
unknown's avatar
unknown committed
1274
#ifndef EMBEDDED_LIBRARY
1275
  end_ssl();
unknown's avatar
unknown committed
1276
#endif
1277
  vio_end();
unknown's avatar
unknown committed
1278
#ifdef USE_REGEX
unknown's avatar
unknown committed
1279
  my_regex_end();
unknown's avatar
unknown committed
1280
#endif
unknown's avatar
unknown committed
1281

1282
#if !defined(EMBEDDED_LIBRARY)
1283 1284
  if (!opt_bootstrap)
    (void) my_delete(pidfile_name,MYF(0));	// This may not always exist
unknown's avatar
unknown committed
1285
#endif
1286 1287
  if (print_message && errmesg && server_start_time)
    sql_print_information(ER(ER_SHUTDOWN_COMPLETE),my_progname);
unknown's avatar
unknown committed
1288
  thread_scheduler.end();
unknown's avatar
Merge  
unknown committed
1289
  finish_client_errs();
1290
  my_free((uchar*) my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST),
1291
          MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
1292
  DBUG_PRINT("quit", ("Error messages freed"));
unknown's avatar
unknown committed
1293
  /* Tell main we are ready */
unknown's avatar
unknown committed
1294
  logger.cleanup_end();
unknown's avatar
unknown committed
1295
  (void) pthread_mutex_lock(&LOCK_thread_count);
1296
  DBUG_PRINT("quit", ("got thread count lock"));
unknown's avatar
unknown committed
1297
  ready_to_exit=1;
unknown's avatar
unknown committed
1298
  /* do the broadcast inside the lock to ensure that my_end() is not called */
unknown's avatar
unknown committed
1299 1300
  (void) pthread_cond_broadcast(&COND_thread_count);
  (void) pthread_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
1301

unknown's avatar
unknown committed
1302 1303 1304 1305
  /*
    The following lines may never be executed as the main thread may have
    killed us
  */
1306
  DBUG_PRINT("quit", ("done with cleanup"));
unknown's avatar
unknown committed
1307 1308 1309
} /* clean_up */


1310 1311
#ifndef EMBEDDED_LIBRARY

unknown's avatar
unknown committed
1312
/**
1313
  This is mainly needed when running with purify, but it's still nice to
unknown's avatar
unknown committed
1314
  know that all child threads have died when mysqld exits.
1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325
*/
static void wait_for_signal_thread_to_end()
{
#ifndef __NETWARE__
  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++)
  {
1326
    if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL) != ESRCH)
1327 1328 1329 1330 1331 1332 1333
      break;
    my_sleep(100);				// Give it time to die
  }
#endif
}


unknown's avatar
unknown committed
1334 1335 1336
static void clean_up_mutexes()
{
  (void) pthread_mutex_destroy(&LOCK_mysql_create_db);
unknown's avatar
unknown committed
1337
  (void) pthread_mutex_destroy(&LOCK_lock_db);
unknown's avatar
unknown committed
1338
  (void) pthread_mutex_destroy(&LOCK_Acl);
1339
  (void) rwlock_destroy(&LOCK_grant);
unknown's avatar
unknown committed
1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352
  (void) pthread_mutex_destroy(&LOCK_open);
  (void) pthread_mutex_destroy(&LOCK_thread_count);
  (void) pthread_mutex_destroy(&LOCK_mapped_file);
  (void) pthread_mutex_destroy(&LOCK_status);
  (void) pthread_mutex_destroy(&LOCK_error_log);
  (void) pthread_mutex_destroy(&LOCK_delayed_insert);
  (void) pthread_mutex_destroy(&LOCK_delayed_status);
  (void) pthread_mutex_destroy(&LOCK_delayed_create);
  (void) pthread_mutex_destroy(&LOCK_manager);
  (void) pthread_mutex_destroy(&LOCK_crypt);
  (void) pthread_mutex_destroy(&LOCK_bytes_sent);
  (void) pthread_mutex_destroy(&LOCK_bytes_received);
  (void) pthread_mutex_destroy(&LOCK_user_conn);
1353
  (void) pthread_mutex_destroy(&LOCK_connection_count);
1354
  Events::destroy_mutexes();
1355 1356
#ifdef HAVE_OPENSSL
  (void) pthread_mutex_destroy(&LOCK_des_key_file);
unknown's avatar
unknown committed
1357
#ifndef HAVE_YASSL
1358 1359 1360
  for (int i= 0; i < CRYPTO_num_locks(); ++i)
    (void) rwlock_destroy(&openssl_stdlocks[i].lock);
  OPENSSL_free(openssl_stdlocks);
1361 1362
#endif
#endif
1363
#ifdef HAVE_REPLICATION
unknown's avatar
unknown committed
1364
  (void) pthread_mutex_destroy(&LOCK_rpl_status);
1365 1366
  (void) pthread_cond_destroy(&COND_rpl_status);
#endif
unknown's avatar
unknown committed
1367
  (void) pthread_mutex_destroy(&LOCK_active_mi);
unknown's avatar
unknown committed
1368 1369
  (void) rwlock_destroy(&LOCK_sys_init_connect);
  (void) rwlock_destroy(&LOCK_sys_init_slave);
unknown's avatar
unknown committed
1370
  (void) pthread_mutex_destroy(&LOCK_global_system_variables);
unknown's avatar
unknown committed
1371
  (void) rwlock_destroy(&LOCK_system_variables_hash);
1372
  (void) pthread_mutex_destroy(&LOCK_global_read_lock);
unknown's avatar
unknown committed
1373
  (void) pthread_mutex_destroy(&LOCK_uuid_generator);
1374
  (void) pthread_mutex_destroy(&LOCK_prepared_stmt_count);
unknown's avatar
unknown committed
1375 1376
  (void) pthread_cond_destroy(&COND_thread_count);
  (void) pthread_cond_destroy(&COND_refresh);
unknown's avatar
unknown committed
1377
  (void) pthread_cond_destroy(&COND_global_read_lock);
unknown's avatar
unknown committed
1378 1379 1380 1381
  (void) pthread_cond_destroy(&COND_thread_cache);
  (void) pthread_cond_destroy(&COND_flush_thread_cache);
  (void) pthread_cond_destroy(&COND_manager);
}
unknown's avatar
unknown committed
1382

1383 1384 1385
#endif /*EMBEDDED_LIBRARY*/


unknown's avatar
unknown committed
1386 1387 1388 1389
/****************************************************************************
** Init IP and UNIX socket
****************************************************************************/

unknown's avatar
unknown committed
1390
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
1391 1392 1393
static void set_ports()
{
  char	*env;
1394
  if (!mysqld_port && !opt_disable_networking)
unknown's avatar
unknown committed
1395
  {					// Get port if not from commandline
1396
    mysqld_port= MYSQL_PORT;
1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408

    /*
      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
1409
    struct  servent *serv_ptr;
1410 1411
    if ((serv_ptr= getservbyname("mysql", "tcp")))
      mysqld_port= ntohs((u_short) serv_ptr->s_port); /* purecov: inspected */
1412
#endif
unknown's avatar
unknown committed
1413
    if ((env = getenv("MYSQL_TCP_PORT")))
1414
      mysqld_port= (uint) atoi(env);		/* purecov: inspected */
unknown's avatar
unknown committed
1415
  }
1416
  if (!mysqld_unix_port)
unknown's avatar
unknown committed
1417 1418
  {
#ifdef __WIN__
1419
    mysqld_unix_port= (char*) MYSQL_NAMEDPIPE;
unknown's avatar
unknown committed
1420
#else
1421
    mysqld_unix_port= (char*) MYSQL_UNIX_ADDR;
unknown's avatar
unknown committed
1422 1423
#endif
    if ((env = getenv("MYSQL_UNIX_PORT")))
1424
      mysqld_unix_port= env;			/* purecov: inspected */
unknown's avatar
unknown committed
1425 1426 1427 1428 1429
  }
}

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

1430
static struct passwd *check_user(const char *user)
unknown's avatar
unknown committed
1431
{
1432
#if !defined(__WIN__) && !defined(__NETWARE__)
1433
  struct passwd *tmp_user_info;
1434
  uid_t user_id= geteuid();
unknown's avatar
unknown committed
1435

1436
  // Don't bother if we aren't superuser
1437
  if (user_id)
unknown's avatar
unknown committed
1438 1439
  {
    if (user)
1440
    {
1441 1442 1443 1444
      /* 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) &&
1445
	  global_system_variables.log_warnings)
1446 1447
        sql_print_warning(
                    "One can only use the --user switch if running as root\n");
unknown's avatar
unknown committed
1448
      /* purecov: end */
1449
    }
1450
    return NULL;
unknown's avatar
unknown committed
1451
  }
1452
  if (!user)
unknown's avatar
unknown committed
1453 1454 1455
  {
    if (!opt_bootstrap)
    {
unknown's avatar
unknown committed
1456
      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
1457 1458
      unireg_abort(1);
    }
1459
    return NULL;
unknown's avatar
unknown committed
1460
  }
1461
  /* purecov: begin tested */
unknown's avatar
unknown committed
1462
  if (!strcmp(user,"root"))
unknown's avatar
unknown committed
1463
    return NULL;                        // Avoid problem with dynamic libraries
unknown's avatar
unknown committed
1464

1465
  if (!(tmp_user_info= getpwnam(user)))
unknown's avatar
unknown committed
1466
  {
1467
    // Allow a numeric uid to be used
unknown's avatar
unknown committed
1468
    const char *pos;
unknown's avatar
unknown committed
1469 1470
    for (pos= user; my_isdigit(mysqld_charset,*pos); pos++) ;
    if (*pos)                                   // Not numeric id
1471
      goto err;
1472
    if (!(tmp_user_info= getpwuid(atoi(user))))
1473
      goto err;
unknown's avatar
unknown committed
1474
  }
unknown's avatar
unknown committed
1475 1476
  return tmp_user_info;
  /* purecov: end */
1477 1478

err:
unknown's avatar
unknown committed
1479
  sql_print_error("Fatal error: Can't change to run as user '%s' ;  Please check that the user exists!\n",user);
1480
  unireg_abort(1);
1481 1482 1483 1484 1485 1486 1487 1488 1489

#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
1490 1491
#endif
  return NULL;
1492 1493
}

1494
static void set_user(const char *user, struct passwd *user_info_arg)
1495
{
1496
  /* purecov: begin tested */
1497
#if !defined(__WIN__) && !defined(__NETWARE__)
1498
  DBUG_ASSERT(user_info_arg != 0);
unknown's avatar
unknown committed
1499
#ifdef HAVE_INITGROUPS
1500 1501 1502 1503 1504 1505 1506
  /*
    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.
  */
  calling_initgroups= TRUE;
1507
  initgroups((char*) user, user_info_arg->pw_gid);
1508
  calling_initgroups= FALSE;
unknown's avatar
unknown committed
1509
#endif
1510
  if (setgid(user_info_arg->pw_gid) == -1)
1511 1512 1513
  {
    sql_perror("setgid");
    unireg_abort(1);
unknown's avatar
unknown committed
1514
  }
1515
  if (setuid(user_info_arg->pw_uid) == -1)
unknown's avatar
unknown committed
1516 1517 1518 1519 1520
  {
    sql_perror("setuid");
    unireg_abort(1);
  }
#endif
unknown's avatar
unknown committed
1521
  /* purecov: end */
unknown's avatar
unknown committed
1522 1523
}

unknown's avatar
unknown committed
1524

1525
static void set_effective_user(struct passwd *user_info_arg)
1526
{
1527
#if !defined(__WIN__) && !defined(__NETWARE__)
1528 1529
  DBUG_ASSERT(user_info_arg != 0);
  if (setregid((gid_t)-1, user_info_arg->pw_gid) == -1)
1530
  {
1531
    sql_perror("setregid");
1532
    unireg_abort(1);
unknown's avatar
unknown committed
1533
  }
1534
  if (setreuid((uid_t)-1, user_info_arg->pw_uid) == -1)
1535
  {
1536
    sql_perror("setreuid");
1537 1538 1539 1540 1541 1542
    unireg_abort(1);
  }
#endif
}


unknown's avatar
unknown committed
1543
/** Change root user if started with @c --chroot . */
unknown's avatar
unknown committed
1544 1545
static void set_root(const char *path)
{
1546
#if !defined(__WIN__) && !defined(__NETWARE__)
unknown's avatar
unknown committed
1547 1548 1549 1550 1551
  if (chroot(path) == -1)
  {
    sql_perror("chroot");
    unireg_abort(1);
  }
1552
  my_setwd("/", MYF(0));
unknown's avatar
unknown committed
1553 1554 1555
#endif
}

unknown's avatar
unknown committed
1556
static void network_init(void)
unknown's avatar
unknown committed
1557 1558 1559 1560 1561 1562
{
  struct sockaddr_in	IPaddr;
#ifdef HAVE_SYS_UN_H
  struct sockaddr_un	UNIXaddr;
#endif
  int	arg=1;
1563 1564 1565 1566
  int   ret;
  uint  waited;
  uint  this_wait;
  uint  retry;
unknown's avatar
unknown committed
1567
  DBUG_ENTER("network_init");
1568
  LINT_INIT(ret);
unknown's avatar
unknown committed
1569

unknown's avatar
unknown committed
1570 1571 1572
  if (thread_scheduler.init())
    unireg_abort(1);			/* purecov: inspected */

unknown's avatar
unknown committed
1573 1574
  set_ports();

1575
  if (mysqld_port != 0 && !opt_disable_networking && !opt_bootstrap)
unknown's avatar
unknown committed
1576
  {
1577
    DBUG_PRINT("general",("IP Socket is %d",mysqld_port));
unknown's avatar
unknown committed
1578 1579 1580 1581 1582 1583 1584 1585 1586 1587
    ip_sock = socket(AF_INET, SOCK_STREAM, 0);
    if (ip_sock == INVALID_SOCKET)
    {
      DBUG_PRINT("error",("Got error: %d from socket()",socket_errno));
      sql_perror(ER(ER_IPSOCK_ERROR));		/* purecov: tested */
      unireg_abort(1);				/* purecov: tested */
    }
    bzero((char*) &IPaddr, sizeof(IPaddr));
    IPaddr.sin_family = AF_INET;
    IPaddr.sin_addr.s_addr = my_bind_addr;
1588
    IPaddr.sin_port = (unsigned short) htons((unsigned short) mysqld_port);
1589 1590 1591 1592 1593 1594

#ifndef __WIN__
    /*
      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.
    */
unknown's avatar
unknown committed
1595
    (void) setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,sizeof(arg));
unknown's avatar
unknown committed
1596
#endif /* __WIN__ */
1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608
    /*
      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=#).
    */
    for (waited= 0, retry= 1; ; retry++, waited+= this_wait)
    {
      if (((ret= bind(ip_sock, my_reinterpret_cast(struct sockaddr *) (&IPaddr),
                      sizeof(IPaddr))) >= 0) ||
1609
          (socket_errno != SOCKET_EADDRINUSE) ||
1610 1611 1612 1613 1614 1615 1616
          (waited >= mysqld_port_timeout))
        break;
      sql_print_information("Retrying bind on TCP/IP port %u", mysqld_port);
      this_wait= retry * retry / 3 + 1;
      sleep(this_wait);
    }
    if (ret < 0)
unknown's avatar
unknown committed
1617 1618
    {
      DBUG_PRINT("error",("Got error: %d from bind",socket_errno));
1619
      sql_perror("Can't start server: Bind on TCP/IP port");
1620
      sql_print_error("Do you already have another mysqld server running on port: %d ?",mysqld_port);
unknown's avatar
unknown committed
1621 1622
      unireg_abort(1);
    }
1623
    if (listen(ip_sock,(int) back_log) < 0)
unknown's avatar
unknown committed
1624
    {
1625
      sql_perror("Can't start server: listen() on TCP/IP port");
1626
      sql_print_error("listen() on TCP/IP failed with error %d",
unknown's avatar
unknown committed
1627
		      socket_errno);
unknown's avatar
unknown committed
1628 1629
      unireg_abort(1);
    }
unknown's avatar
unknown committed
1630
  }
1631

unknown's avatar
unknown committed
1632 1633
#ifdef __NT__
  /* create named pipe */
1634
  if (Service.IsNT() && mysqld_unix_port[0] && !opt_bootstrap &&
unknown's avatar
unknown committed
1635
      opt_enable_named_pipe)
unknown's avatar
unknown committed
1636
  {
1637 1638 1639
    
    pipe_name[sizeof(pipe_name)-1]= 0;		/* Safety if too long string */
    strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\.\\pipe\\",
1640
	     mysqld_unix_port, NullS);
1641 1642
    bzero((char*) &saPipeSecurity, sizeof(saPipeSecurity));
    bzero((char*) &sdPipeDescriptor, sizeof(sdPipeDescriptor));
1643
    if (!InitializeSecurityDescriptor(&sdPipeDescriptor,
1644
				      SECURITY_DESCRIPTOR_REVISION))
unknown's avatar
unknown committed
1645 1646 1647 1648 1649 1650 1651 1652 1653
    {
      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
1654
    saPipeSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
unknown's avatar
unknown committed
1655 1656
    saPipeSecurity.lpSecurityDescriptor = &sdPipeDescriptor;
    saPipeSecurity.bInheritHandle = FALSE;
1657 1658 1659 1660 1661 1662 1663 1664 1665 1666
    if ((hPipe= CreateNamedPipe(pipe_name,
				PIPE_ACCESS_DUPLEX,
				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
1667 1668 1669 1670 1671 1672 1673
      {
	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 );
1674
	sql_perror((char *)lpMsgBuf);
unknown's avatar
Merge  
unknown committed
1675
	LocalFree(lpMsgBuf);
unknown's avatar
unknown committed
1676 1677 1678 1679 1680
	unireg_abort(1);
      }
  }
#endif

1681
#if defined(HAVE_SYS_UN_H)
unknown's avatar
unknown committed
1682 1683 1684
  /*
  ** Create the UNIX socket
  */
1685
  if (mysqld_unix_port[0] && !opt_bootstrap)
unknown's avatar
unknown committed
1686
  {
1687
    DBUG_PRINT("general",("UNIX Socket is %s",mysqld_unix_port));
unknown's avatar
unknown committed
1688

unknown's avatar
unknown committed
1689 1690
    if (strlen(mysqld_unix_port) > (sizeof(UNIXaddr.sun_path) - 1))
    {
1691
      sql_print_error("The socket file path is too long (> %u): %s",
unknown's avatar
unknown committed
1692
                      (uint) sizeof(UNIXaddr.sun_path) - 1, mysqld_unix_port);
unknown's avatar
unknown committed
1693 1694
      unireg_abort(1);
    }
1695
    if ((unix_sock= socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
unknown's avatar
unknown committed
1696 1697 1698 1699 1700 1701
    {
      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;
1702 1703
    strmov(UNIXaddr.sun_path, mysqld_unix_port);
    (void) unlink(mysqld_unix_port);
unknown's avatar
unknown committed
1704 1705 1706 1707 1708 1709 1710
    (void) setsockopt(unix_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,
		      sizeof(arg));
    umask(0);
    if (bind(unix_sock, my_reinterpret_cast(struct sockaddr *) (&UNIXaddr),
	     sizeof(UNIXaddr)) < 0)
    {
      sql_perror("Can't start server : Bind on unix socket"); /* purecov: tested */
1711
      sql_print_error("Do you already have another mysqld server running on socket: %s ?",mysqld_unix_port);
unknown's avatar
unknown committed
1712 1713 1714 1715
      unireg_abort(1);					/* purecov: tested */
    }
    umask(((~my_umask) & 0666));
#if defined(S_IFSOCK) && defined(SECURE_SOCKETS)
1716
    (void) chmod(mysqld_unix_port,S_IFSOCK);	/* Fix solaris 2.6 bug */
unknown's avatar
unknown committed
1717
#endif
1718
    if (listen(unix_sock,(int) back_log) < 0)
1719
      sql_print_warning("listen() on Unix socket failed with error %d",
unknown's avatar
unknown committed
1720
		      socket_errno);
unknown's avatar
unknown committed
1721 1722 1723 1724 1725 1726
  }
#endif
  DBUG_PRINT("info",("server started"));
  DBUG_VOID_RETURN;
}

1727
#endif /*!EMBEDDED_LIBRARY*/
unknown's avatar
unknown committed
1728

1729

1730
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
1731 1732
/**
  Close a connection.
1733

unknown's avatar
unknown committed
1734 1735 1736
  @param thd		Thread handle
  @param errcode	Error code to print to console
  @param lock	        1 if we have have to lock LOCK_thread_count
1737

unknown's avatar
unknown committed
1738
  @note
1739 1740
    For the connection that is doing shutdown, this is called twice
*/
1741
void close_connection(THD *thd, uint errcode, bool lock)
unknown's avatar
unknown committed
1742
{
1743
  st_vio *vio;
unknown's avatar
unknown committed
1744 1745
  DBUG_ENTER("close_connection");
  DBUG_PRINT("enter",("fd: %s  error: '%s'",
1746 1747 1748
		      thd->net.vio ? vio_description(thd->net.vio) :
		      "(not connected)",
		      errcode ? ER(errcode) : ""));
unknown's avatar
unknown committed
1749 1750
  if (lock)
    (void) pthread_mutex_lock(&LOCK_thread_count);
unknown's avatar
unknown committed
1751 1752
  thd->killed= THD::KILL_CONNECTION;
  if ((vio= thd->net.vio) != 0)
unknown's avatar
unknown committed
1753 1754
  {
    if (errcode)
unknown's avatar
Merge  
unknown committed
1755
      net_send_error(thd, errcode, ER(errcode)); /* purecov: inspected */
unknown's avatar
unknown committed
1756 1757 1758 1759 1760 1761
    vio_close(vio);			/* vio is freed in delete thd */
  }
  if (lock)
    (void) pthread_mutex_unlock(&LOCK_thread_count);
  DBUG_VOID_RETURN;
}
1762 1763
#endif /* EMBEDDED_LIBRARY */

unknown's avatar
unknown committed
1764

unknown's avatar
unknown committed
1765 1766
/** Called when a thread is aborted. */
/* ARGSUSED */
1767
extern "C" sig_handler end_thread_signal(int sig __attribute__((unused)))
unknown's avatar
unknown committed
1768 1769 1770
{
  THD *thd=current_thd;
  DBUG_ENTER("end_thread_signal");
1771
  if (thd && ! thd->bootstrap)
1772 1773
  {
    statistic_increment(killed_threads, &LOCK_status);
unknown's avatar
unknown committed
1774
    thread_scheduler.end_thread(thd,0);		/* purecov: inspected */
1775
  }
unknown's avatar
unknown committed
1776 1777 1778 1779
  DBUG_VOID_RETURN;				/* purecov: deadcode */
}


unknown's avatar
unknown committed
1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791
/*
  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
1792
{
unknown's avatar
unknown committed
1793 1794
  DBUG_ENTER("unlink_thd");
  DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd));
unknown's avatar
unknown committed
1795
  thd->cleanup();
1796 1797 1798 1799 1800

  pthread_mutex_lock(&LOCK_connection_count);
  --connection_count;
  pthread_mutex_unlock(&LOCK_connection_count);

unknown's avatar
unknown committed
1801 1802 1803
  (void) pthread_mutex_lock(&LOCK_thread_count);
  thread_count--;
  delete thd;
unknown's avatar
unknown committed
1804 1805 1806
  DBUG_VOID_RETURN;
}

1807

unknown's avatar
unknown committed
1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827
/*
  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()
{
  safe_mutex_assert_owner(&LOCK_thread_count);
  if (cached_thread_count < thread_cache_size &&
1828
      ! abort_loop && !kill_cached_threads)
unknown's avatar
unknown committed
1829 1830
  {
    /* Don't kill the thread, just put it in cache for reuse */
unknown's avatar
unknown committed
1831
    DBUG_PRINT("info", ("Adding thread to cache"));
unknown's avatar
unknown committed
1832 1833 1834 1835 1836 1837 1838 1839
    cached_thread_count++;
    while (!abort_loop && ! wake_thread && ! kill_cached_threads)
      (void) pthread_cond_wait(&COND_thread_cache, &LOCK_thread_count);
    cached_thread_count--;
    if (kill_cached_threads)
      pthread_cond_signal(&COND_flush_thread_cache);
    if (wake_thread)
    {
unknown's avatar
unknown committed
1840
      THD *thd;
unknown's avatar
unknown committed
1841
      wake_thread--;
unknown's avatar
unknown committed
1842
      thd= thread_cache.get();
1843
      thd->thread_stack= (char*) &thd;          // For store_globals
unknown's avatar
unknown committed
1844
      (void) thd->store_globals();
1845 1846 1847 1848 1849 1850
      /*
        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;
1851
      thd->thr_create_utime= my_micro_time();
1852
      threads.append(thd);
unknown's avatar
unknown committed
1853
      return(1);
unknown's avatar
unknown committed
1854 1855
    }
  }
unknown's avatar
unknown committed
1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887
  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);
  if (put_in_cache)
    put_in_cache= cache_thread();
  pthread_mutex_unlock(&LOCK_thread_count);
  if (put_in_cache)
    DBUG_RETURN(0);                             // Thread is reused
unknown's avatar
unknown committed
1888

1889
  /* It's safe to broadcast outside a lock (COND... is not deleted here) */
unknown's avatar
unknown committed
1890
  DBUG_PRINT("signal", ("Broadcasting COND_thread_count"));
1891
  my_thread_end();
unknown's avatar
unknown committed
1892
  (void) pthread_cond_broadcast(&COND_thread_count);
unknown's avatar
unknown committed
1893 1894 1895

  pthread_exit(0);
  DBUG_RETURN(0);                               // Impossible
unknown's avatar
unknown committed
1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913
}


void flush_thread_cache()
{
  (void) pthread_mutex_lock(&LOCK_thread_count);
  kill_cached_threads++;
  while (cached_thread_count)
  {
    pthread_cond_broadcast(&COND_thread_cache);
    pthread_cond_wait(&COND_flush_thread_cache,&LOCK_thread_count);
  }
  kill_cached_threads--;
  (void) pthread_mutex_unlock(&LOCK_thread_count);
}


#ifdef THREAD_SPECIFIC_SIGPIPE
unknown's avatar
unknown committed
1914 1915 1916 1917 1918 1919
/**
  Aborts a thread nicely. Comes here on SIGPIPE.

  @todo
    One should have to fix that thr_alarm know about this thread too.
*/
1920
extern "C" sig_handler abort_thread(int sig __attribute__((unused)))
unknown's avatar
unknown committed
1921 1922 1923 1924
{
  THD *thd=current_thd;
  DBUG_ENTER("abort_thread");
  if (thd)
unknown's avatar
Merge  
unknown committed
1925
    thd->killed= THD::KILL_CONNECTION;
unknown's avatar
unknown committed
1926 1927 1928 1929
  DBUG_VOID_RETURN;
}
#endif

unknown's avatar
unknown committed
1930

unknown's avatar
unknown committed
1931
/******************************************************************************
1932 1933 1934
  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
1935 1936
******************************************************************************/

1937
#if defined(__WIN__)
1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951


/*
  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
1952
#ifndef EMBEDDED_LIBRARY
1953 1954 1955 1956 1957 1958 1959 1960
  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.
     */
1961
#ifndef EMBEDDED_LIBRARY
1962 1963 1964
     if(hEventShutdown)
       kill_mysql();
     else
1965
#endif
1966 1967 1968
       sql_print_warning("CTRL-C ignored during startup");
     DBUG_RETURN(TRUE);
  }
unknown's avatar
unknown committed
1969
#endif
1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052
  DBUG_RETURN(FALSE);
}


/*
  In Visual Studio 2005 and later, default SIGABRT handler will overwrite
  any unhandled exception filter set by the application  and will try to
  call JIT debugger. This is not what we want, this we calling __debugbreak
  to stop in debugger, if process is being debugged or to generate 
  EXCEPTION_BREAKPOINT and then handle_segfault will do its magic.
*/

#if (_MSC_VER >= 1400)
static void my_sigabrt_handler(int sig)
{
  __debugbreak();
}
#endif /*_MSC_VER >=1400 */

void win_install_sigabrt_handler(void)
{
#if (_MSC_VER >=1400)
  /*abort() should not override our exception filter*/
  _set_abort_behavior(0,_CALL_REPORTFAULT);
  signal(SIGABRT,my_sigabrt_handler);
#endif /* _MSC_VER >=1400 */
}

#ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER
#define DEBUGGER_ATTACH_TIMEOUT 120
/*
  Wait for debugger to attach and break into debugger. If debugger is not attached,
  resume after timeout.
*/
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
  {
2053
    my_set_exception_pointers(ex_pointers);
2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072
    handle_segfault(ex_pointers->ExceptionRecord->ExceptionCode);
  }
  __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
2073 2074
static void init_signals(void)
{
2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097
  win_install_sigabrt_handler();
  if(opt_console)
    SetConsoleCtrlHandler(console_event_handler,TRUE);
  else
  {
    /* Avoid MessageBox()es*/
   _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);

   /*
     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)
   */
   SetErrorMode(SetErrorMode(0)|SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
  }
  SetUnhandledExceptionFilter(my_unhandler_exception_filter);
unknown's avatar
unknown committed
2098 2099
}

unknown's avatar
unknown committed
2100

2101
static void start_signal_handler(void)
2102
{
2103
#ifndef EMBEDDED_LIBRARY
2104 2105 2106
  // Save vm id of this process
  if (!opt_bootstrap)
    create_pid_file();
2107
#endif /* EMBEDDED_LIBRARY */
2108
}
unknown's avatar
unknown committed
2109

unknown's avatar
unknown committed
2110

unknown's avatar
unknown committed
2111 2112
static void check_data_home(const char *path)
{}
2113

unknown's avatar
unknown committed
2114

unknown's avatar
unknown committed
2115 2116
#elif defined(__NETWARE__)

unknown's avatar
unknown committed
2117
/// down server event callback.
unknown's avatar
unknown committed
2118 2119
void mysql_down_server_cb(void *, void *)
{
unknown's avatar
Merge  
unknown committed
2120
  event_flag= TRUE;
unknown's avatar
unknown committed
2121 2122 2123
  kill_server(0);
}

unknown's avatar
unknown committed
2124

unknown's avatar
unknown committed
2125
/// destroy callback resources.
unknown's avatar
unknown committed
2126
void mysql_cb_destroy(void *)
unknown's avatar
Merge  
unknown committed
2127 2128
{
  UnRegisterEventNotification(eh);  // cleanup down event notification
unknown's avatar
unknown committed
2129
  NX_UNWRAP_INTERFACE(ref);
unknown's avatar
Merge  
unknown committed
2130 2131
  /* Deregister NSS volume deactivation event */
  NX_UNWRAP_INTERFACE(refneb);
unknown's avatar
unknown committed
2132
  if (neb_consumer_id)
2133
    UnRegisterConsumer(neb_consumer_id, NULL);
unknown's avatar
unknown committed
2134 2135
}

unknown's avatar
unknown committed
2136

unknown's avatar
unknown committed
2137
/// initialize callbacks.
unknown's avatar
unknown committed
2138 2139 2140 2141
void mysql_cb_init()
{
  // register for down server event
  void *handle = getnlmhandle();
unknown's avatar
unknown committed
2142 2143
  rtag_t rt= AllocateResourceTag(handle, "MySQL Down Server Callback",
                                 EventSignature);
unknown's avatar
unknown committed
2144
  NX_WRAP_INTERFACE((void *)mysql_down_server_cb, 2, (void **)&ref);
unknown's avatar
unknown committed
2145 2146 2147 2148 2149 2150 2151 2152
  eh= RegisterForEventNotification(rt, EVENT_PRE_DOWN_SERVER,
                                   EVENT_PRIORITY_APPLICATION,
                                   NULL, ref, NULL);

  /*
    Register for volume deactivation event
    Wrap the callback function, as it is called by non-LibC thread
  */
2153
  (void *) NX_WRAP_INTERFACE(neb_event_callback, 1, &refneb);
unknown's avatar
unknown committed
2154 2155
  registerwithneb();

unknown's avatar
unknown committed
2156 2157 2158
  NXVmRegisterExitHandler(mysql_cb_destroy, NULL);  // clean-up
}

unknown's avatar
unknown committed
2159

unknown's avatar
unknown committed
2160
/** To get the name of the NetWare volume having MySQL data folder. */
2161
static void getvolumename()
unknown's avatar
unknown committed
2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173
{
  char *p;
  /*
    We assume that data path is already set.
    If not it won't come here. Terminate after volume name
  */
  if ((p= strchr(mysql_real_data_home, ':')))
    strmake(datavolname, mysql_real_data_home,
            (uint) (p - mysql_real_data_home));
}


unknown's avatar
unknown committed
2174 2175
/**
  Registering with NEB for NSS Volume Deactivation event.
unknown's avatar
unknown committed
2176 2177
*/

2178
static void registerwithneb()
unknown's avatar
unknown committed
2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226
{

  ConsumerRegistrationInfo reg_info;
    
  /* Clear NEB registration structure */
  bzero((char*) &reg_info, sizeof(struct ConsumerRegistrationInfo));

  /* Fill the NEB consumer information structure */
  reg_info.CRIVersion= 1;  	            // NEB version
  /* NEB Consumer name */
  reg_info.CRIConsumerName= (BYTE *) "MySQL Database Server";
  /* Event of interest */
  reg_info.CRIEventName= (BYTE *) "NSS.ChangeVolState.Enter";
  reg_info.CRIUserParameter= NULL;	    // Consumer Info
  reg_info.CRIEventFlags= 0;	            // Event flags
  /* Consumer NLM handle */
  reg_info.CRIOwnerID= (LoadDefinitionStructure *)getnlmhandle();
  reg_info.CRIConsumerESR= NULL;	    // No consumer ESR required
  reg_info.CRISecurityToken= 0;	            // No security token for the event
  reg_info.CRIConsumerFlags= 0;             // SMP_ENABLED_BIT;	
  reg_info.CRIFilterName= 0;	            // No event filtering
  reg_info.CRIFilterDataLength= 0;          // No filtering data
  reg_info.CRIFilterData= 0;	            // No filtering data
  /* Callback function for the event */
  (void *)reg_info.CRIConsumerCallback= (void *) refneb;
  reg_info.CRIOrder= 0;	                    // Event callback order
  reg_info.CRIConsumerType= CHECK_CONSUMER; // Consumer type

  /* Register for the event with NEB */
  if (RegisterConsumer(&reg_info))
  {
    consoleprintf("Failed to register for NSS Volume Deactivation event \n");
    return;
  }
  /* This ID is required for deregistration */
  neb_consumer_id= reg_info.CRIConsumerID;

  /* Get MySQL data volume name, stored in global variable datavolname */
  getvolumename();

  /*
    Get the NSS volume ID of the MySQL Data volume.
    Volume ID is stored in a global variable
  */
  getvolumeID((BYTE*) datavolname);	
}


unknown's avatar
unknown committed
2227 2228
/**
  Callback for NSS Volume Deactivation event.
unknown's avatar
unknown committed
2229
*/
2230

unknown's avatar
unknown committed
2231 2232 2233
ulong neb_event_callback(struct EventBlock *eblock)
{
  EventChangeVolStateEnter_s *voldata;
2234 2235
  extern bool nw_panic;

unknown's avatar
unknown committed
2236 2237 2238
  voldata= (EventChangeVolStateEnter_s *)eblock->EBEventData;

  /* Deactivation of a volume */
unknown's avatar
unknown committed
2239 2240 2241
  if ((voldata->oldState == zVOLSTATE_ACTIVE &&
       voldata->newState == zVOLSTATE_DEACTIVE ||
       voldata->newState == zVOLSTATE_MAINTENANCE))
unknown's avatar
unknown committed
2242 2243 2244 2245 2246 2247 2248 2249
  {
    /*
      Ensure that we bring down MySQL server only for MySQL data
      volume deactivation
    */
    if (!memcmp(&voldata->volID, &datavolid, sizeof(VolumeID_t)))
    {
      consoleprintf("MySQL data volume is deactivated, shutting down MySQL Server \n");
unknown's avatar
unknown committed
2250
      event_flag= TRUE;
2251
      nw_panic = TRUE;
2252
      event_flag= TRUE;
unknown's avatar
unknown committed
2253 2254 2255 2256 2257 2258 2259 2260 2261
      kill_server(0);
    }
  }
  return 0;
}


#define ADMIN_VOL_PATH					"_ADMIN:/Volumes/"

unknown's avatar
unknown committed
2262 2263 2264
/**
  Function to get NSS volume ID of the MySQL data.
*/
2265
static void getvolumeID(BYTE *volumeName)
unknown's avatar
unknown committed
2266 2267 2268 2269 2270 2271 2272
{
  char path[zMAX_FULL_NAME];
  Key_t rootKey= 0, fileKey= 0;
  QUAD getInfoMask;
  zInfo_s info;
  STATUS status;

2273
  /* Get the root key */
unknown's avatar
unknown committed
2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309
  if ((status= zRootKey(0, &rootKey)) != zOK)
  {
    consoleprintf("\nGetNSSVolumeProperties - Failed to get root key, status: %d\n.", (int) status);
    goto exit;
  }

  /*
    Get the file key. This is the key to the volume object in the
    NSS admin volumes directory.
  */

  strxmov(path, (const char *) ADMIN_VOL_PATH, (const char *) volumeName,
          NullS);
  if ((status= zOpen(rootKey, zNSS_TASK, zNSPACE_LONG|zMODE_UTF8, 
                     (BYTE *) path, zRR_READ_ACCESS, &fileKey)) != zOK)
  {
    consoleprintf("\nGetNSSVolumeProperties - Failed to get file, status: %d\n.", (int) status);
    goto exit;
  }

  getInfoMask= zGET_IDS | zGET_VOLUME_INFO ;
  if ((status= zGetInfo(fileKey, getInfoMask, sizeof(info), 
                        zINFO_VERSION_A, &info)) != zOK)
  {
    consoleprintf("\nGetNSSVolumeProperties - Failed in zGetInfo, status: %d\n.", (int) status);
    goto exit;
  }

  /* Copy the data to global variable */
  datavolid.timeLow= info.vol.volumeID.timeLow;
  datavolid.timeMid= info.vol.volumeID.timeMid;
  datavolid.timeHighAndVersion= info.vol.volumeID.timeHighAndVersion;
  datavolid.clockSeqHighAndReserved= info.vol.volumeID.clockSeqHighAndReserved;
  datavolid.clockSeqLow= info.vol.volumeID.clockSeqLow;
  /* This is guranteed to be 6-byte length (but sizeof() would be better) */
  memcpy(datavolid.node, info.vol.volumeID.node, (unsigned int) 6);
unknown's avatar
Merge  
unknown committed
2310

unknown's avatar
unknown committed
2311 2312 2313 2314 2315 2316 2317 2318
exit:
  if (rootKey)
    zClose(rootKey);
  if (fileKey)
    zClose(fileKey);
}


unknown's avatar
unknown committed
2319 2320 2321 2322 2323 2324 2325 2326
static void init_signals(void)
{
  int signals[] = {SIGINT,SIGILL,SIGFPE,SIGSEGV,SIGTERM,SIGABRT};

  for (uint i=0 ; i < sizeof(signals)/sizeof(int) ; i++)
    signal(signals[i], kill_server);
  mysql_cb_init();  // initialize callbacks

2327
}
unknown's avatar
unknown committed
2328

2329

unknown's avatar
unknown committed
2330 2331 2332 2333
static void start_signal_handler(void)
{
  // Save vm id of this process
  if (!opt_bootstrap)
2334
    create_pid_file();
unknown's avatar
unknown committed
2335 2336 2337 2338
  // no signal handler
}


unknown's avatar
unknown committed
2339 2340
/**
  Warn if the data is on a Traditional volume.
unknown's avatar
unknown committed
2341

unknown's avatar
unknown committed
2342
  @note
unknown's avatar
unknown committed
2343 2344
    Already done by mysqld_safe
*/
unknown's avatar
unknown committed
2345 2346

static void check_data_home(const char *path)
2347 2348 2349
{
}

2350
#endif /*__WIN__ || __NETWARE */
unknown's avatar
unknown committed
2351

unknown's avatar
unknown committed
2352 2353
#ifdef HAVE_LINUXTHREADS
#define UNSAFE_DEFAULT_LINUX_THREADS 200
2354
#endif
2355

unknown's avatar
unknown committed
2356 2357 2358 2359 2360 2361 2362 2363 2364 2365

#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


2366
extern "C" sig_handler handle_segfault(int sig)
2367
{
2368 2369
  time_t curr_time;
  struct tm tm;
unknown's avatar
unknown committed
2370
  THD *thd=current_thd;
2371

2372 2373 2374 2375 2376 2377
  /*
    Strictly speaking, one needs a mutex here
    but since we have got SIGSEGV already, things are a mess
    so not having the mutex is not as bad as possibly using a buggy
    mutex - so we keep things simple
  */
2378
  if (segfaulted)
unknown's avatar
unknown committed
2379
  {
2380
    fprintf(stderr, "Fatal " SIGNAL_FMT " while backtracing\n", sig);
unknown's avatar
unknown committed
2381 2382
    exit(1);
  }
2383

2384
  segfaulted = 1;
2385

2386
  curr_time= my_time(0);
2387 2388
  localtime_r(&curr_time, &tm);

2389
  fprintf(stderr,"\
2390
%02d%02d%02d %2d:%02d:%02d - mysqld got " SIGNAL_FMT " ;\n\
unknown's avatar
unknown committed
2391
This could be because you hit a bug. It is also possible that this binary\n\
unknown's avatar
unknown committed
2392
or one of the libraries it was linked against is corrupt, improperly built,\n\
unknown's avatar
unknown committed
2393
or misconfigured. This error can also be caused by malfunctioning hardware.\n",
2394 2395
          tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday,
          tm.tm_hour, tm.tm_min, tm.tm_sec,
unknown's avatar
unknown committed
2396 2397 2398 2399
	  sig);
  fprintf(stderr, "\
We will try our best to scrape up some info that will hopefully help diagnose\n\
the problem, but since we have already crashed, something is definitely wrong\n\
unknown's avatar
unknown committed
2400
and this may fail.\n\n");
2401
  fprintf(stderr, "key_buffer_size=%lu\n",
unknown's avatar
unknown committed
2402
          (ulong) dflt_key_cache->key_cache_mem_size);
unknown's avatar
unknown committed
2403 2404
  fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
  fprintf(stderr, "max_used_connections=%lu\n", max_used_connections);
unknown's avatar
unknown committed
2405
  fprintf(stderr, "max_threads=%u\n", thread_scheduler.max_threads);
unknown's avatar
unknown committed
2406
  fprintf(stderr, "threads_connected=%u\n", thread_count);
unknown's avatar
unknown committed
2407
  fprintf(stderr, "It is possible that mysqld could use up to \n\
unknown's avatar
unknown committed
2408
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = %lu K\n\
unknown's avatar
unknown committed
2409
bytes of memory\n", ((ulong) dflt_key_cache->key_cache_mem_size +
2410
		     (global_system_variables.read_buff_size +
unknown's avatar
unknown committed
2411
		      global_system_variables.sortbuff_size) *
unknown's avatar
unknown committed
2412 2413
		     thread_scheduler.max_threads +
                     max_connections * sizeof(THD)) / 1024);
unknown's avatar
unknown committed
2414
  fprintf(stderr, "Hope that's ok; if not, decrease some variables in the equation.\n\n");
2415

2416
#if defined(HAVE_LINUXTHREADS)
unknown's avatar
unknown committed
2417 2418 2419 2420
  if (sizeof(char*) == 4 && thread_count > UNSAFE_DEFAULT_LINUX_THREADS)
  {
    fprintf(stderr, "\
You seem to be running 32-bit Linux and have %d concurrent connections.\n\
unknown's avatar
unknown committed
2421 2422
If you have not changed STACK_SIZE in LinuxThreads and built the binary \n\
yourself, LinuxThreads is quite likely to steal a part of the global heap for\n\
unknown's avatar
unknown committed
2423
the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n",
unknown's avatar
unknown committed
2424 2425 2426
	    thread_count);
  }
#endif /* HAVE_LINUXTHREADS */
unknown's avatar
unknown committed
2427

unknown's avatar
unknown committed
2428
#ifdef HAVE_STACKTRACE
2429
  if (!(test_flags & TEST_NO_STACKTRACE))
unknown's avatar
unknown committed
2430
  {
unknown's avatar
unknown committed
2431
    fprintf(stderr,"thd: 0x%lx\n",(long) thd);
2432 2433 2434
    fprintf(stderr,"\
Attempting backtrace. You can use the following information to find out\n\
where mysqld died. If you see no messages after this, something went\n\
2435
terribly wrong...\n");  
2436 2437
    my_print_stacktrace(thd ? (uchar*) thd->thread_stack : NULL,
                        my_thread_stack_size);
unknown's avatar
unknown committed
2438
  }
unknown's avatar
unknown committed
2439 2440
  if (thd)
  {
unknown's avatar
unknown committed
2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458
    const char *kreason= "UNKNOWN";
    switch (thd->killed) {
    case THD::NOT_KILLED:
      kreason= "NOT_KILLED";
      break;
    case THD::KILL_BAD_DATA:
      kreason= "KILL_BAD_DATA";
      break;
    case THD::KILL_CONNECTION:
      kreason= "KILL_CONNECTION";
      break;
    case THD::KILL_QUERY:
      kreason= "KILL_QUERY";
      break;
    case THD::KILLED_NO_VALUE:
      kreason= "KILLED_NO_VALUE";
      break;
    }
unknown's avatar
unknown committed
2459 2460
    fprintf(stderr, "Trying to get some variables.\n\
Some pointers may be invalid and cause the dump to abort...\n");
2461
    my_safe_print_str("thd->query", thd->query, 1024);
unknown's avatar
unknown committed
2462
    fprintf(stderr, "thd->thread_id=%lu\n", (ulong) thd->thread_id);
unknown's avatar
unknown committed
2463
    fprintf(stderr, "thd->killed=%s\n", kreason);
unknown's avatar
unknown committed
2464 2465
  }
  fprintf(stderr, "\
unknown's avatar
unknown committed
2466
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains\n\
unknown's avatar
unknown committed
2467
information that should help you find out what is causing the crash.\n");
2468
  fflush(stderr);
unknown's avatar
unknown committed
2469 2470
#endif /* HAVE_STACKTRACE */

2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481
#ifdef HAVE_INITGROUPS
  if (calling_initgroups)
    fprintf(stderr, "\n\
This crash occured while the server was calling initgroups(). This is\n\
often due to the use of a mysqld that is statically linked against glibc\n\
and configured to use LDAP in /etc/nsswitch.conf. You will need to either\n\
upgrade to a version of glibc that does not have this problem (2.3.4 or\n\
later when used with nscd), disable LDAP in your nsswitch.conf, or use a\n\
mysqld that is not statically linked.\n");
#endif

2482 2483 2484 2485 2486 2487 2488 2489 2490 2491
#ifdef HAVE_NPTL
  if (thd_lib_detected == THD_LIB_LT && !getenv("LD_ASSUME_KERNEL"))
    fprintf(stderr,"\n\
You are running a statically-linked LinuxThreads binary on an NPTL system.\n\
This can result in crashes on some distributions due to LT/NPTL conflicts.\n\
You should either build a dynamically-linked binary, or force LinuxThreads\n\
to be used with the LD_ASSUME_KERNEL environment variable. Please consult\n\
the documentation for your distribution on how to do that.\n");
#endif
  
2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502
  if (locked_in_memory)
  {
    fprintf(stderr, "\n\
The \"--memlock\" argument, which was enabled, uses system calls that are\n\
unreliable and unstable on some operating systems and operating-system\n\
versions (notably, some versions of Linux).  This crash could be due to use\n\
of those buggy OS calls.  You should consider whether you really need the\n\
\"--memlock\" parameter and/or consult the OS distributer about \"mlockall\"\n\
bugs.\n");
  }

2503
#ifdef HAVE_WRITE_CORE
2504 2505 2506 2507
  if (test_flags & TEST_CORE_ON_SIGNAL)
  {
    fprintf(stderr, "Writing a core file\n");
    fflush(stderr);
2508
    my_write_core(sig);
2509
  }
2510 2511 2512 2513
#endif

#ifndef __WIN__
  /* On Windows, do not terminate, but pass control to exception filter */
2514
  exit(1);
2515
#endif
2516 2517
}

2518
#if !defined(__WIN__) && !defined(__NETWARE__)
unknown's avatar
unknown committed
2519 2520 2521 2522 2523 2524
#ifndef SA_RESETHAND
#define SA_RESETHAND 0
#endif
#ifndef SA_NODEFER
#define SA_NODEFER 0
#endif
2525

2526 2527
#ifndef EMBEDDED_LIBRARY

unknown's avatar
unknown committed
2528 2529 2530
static void init_signals(void)
{
  sigset_t set;
2531
  struct sigaction sa;
unknown's avatar
unknown committed
2532 2533
  DBUG_ENTER("init_signals");

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

unknown's avatar
unknown committed
2536
  if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL))
unknown's avatar
unknown committed
2537
  {
unknown's avatar
unknown committed
2538 2539 2540 2541
    sa.sa_flags = SA_RESETHAND | SA_NODEFER;
    sigemptyset(&sa.sa_mask);
    sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);

2542
#ifdef HAVE_STACKTRACE
2543
    my_init_stacktrace();
2544
#endif
unknown's avatar
unknown committed
2545 2546 2547
#if defined(__amiga__)
    sa.sa_handler=(void(*)())handle_segfault;
#else
unknown's avatar
unknown committed
2548
    sa.sa_handler=handle_segfault;
unknown's avatar
unknown committed
2549
#endif
unknown's avatar
unknown committed
2550
    sigaction(SIGSEGV, &sa, NULL);
2551
    sigaction(SIGABRT, &sa, NULL);
unknown's avatar
unknown committed
2552
#ifdef SIGBUS
unknown's avatar
unknown committed
2553
    sigaction(SIGBUS, &sa, NULL);
unknown's avatar
unknown committed
2554
#endif
unknown's avatar
unknown committed
2555
    sigaction(SIGILL, &sa, NULL);
2556
    sigaction(SIGFPE, &sa, NULL);
unknown's avatar
unknown committed
2557
  }
2558 2559 2560 2561 2562

#ifdef HAVE_GETRLIMIT
  if (test_flags & TEST_CORE_ON_SIGNAL)
  {
    /* Change limits so that we will get a core file */
2563
    STRUCT_RLIMIT rl;
2564
    rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
unknown's avatar
unknown committed
2565
    if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
2566
      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");
2567 2568
  }
#endif
unknown's avatar
unknown committed
2569
  (void) sigemptyset(&set);
2570
  my_sigset(SIGPIPE,SIG_IGN);
unknown's avatar
unknown committed
2571
  sigaddset(&set,SIGPIPE);
2572
#ifndef IGNORE_SIGHUP_SIGQUIT
unknown's avatar
unknown committed
2573 2574
  sigaddset(&set,SIGQUIT);
  sigaddset(&set,SIGHUP);
2575 2576
#endif
  sigaddset(&set,SIGTERM);
2577 2578

  /* Fix signals if blocked by parents (can happen on Mac OS X) */
unknown's avatar
unknown committed
2579
  sigemptyset(&sa.sa_mask);
2580 2581 2582 2583 2584 2585
  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
2586 2587 2588
#ifdef SIGTSTP
  sigaddset(&set,SIGTSTP);
#endif
2589 2590
  if (thd_lib_detected != THD_LIB_LT)
    sigaddset(&set,THR_SERVER_ALARM);
2591
  if (test_flags & TEST_SIGINT)
2592
  {
2593
    my_sigset(thr_kill_signal, end_thread_signal);
2594 2595 2596
    // May be SIGINT
    sigdelset(&set, thr_kill_signal);
  }
2597 2598
  else
    sigaddset(&set,SIGINT);
2599 2600
  sigprocmask(SIG_SETMASK,&set,NULL);
  pthread_sigmask(SIG_SETMASK,&set,NULL);
2601 2602 2603 2604 2605 2606 2607 2608 2609
  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
2610 2611 2612 2613 2614 2615 2616

  (void) pthread_attr_init(&thr_attr);
#if !defined(HAVE_DEC_3_2_THREADS)
  pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_SYSTEM);
  (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
  if (!(opt_specialflag & SPECIAL_NO_PRIOR))
    my_pthread_attr_setprio(&thr_attr,INTERRUPT_PRIOR);
2617
#if defined(__ia64__) || defined(__ia64)
2618 2619 2620 2621
  /*
    Peculiar things with ia64 platforms - it seems we only have half the
    stack size in reality, so we have to double it here
  */
2622
  pthread_attr_setstacksize(&thr_attr,my_thread_stack_size*2);
2623
#else
2624
  pthread_attr_setstacksize(&thr_attr,my_thread_stack_size);
2625
#endif
unknown's avatar
unknown committed
2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642
#endif

  (void) pthread_mutex_lock(&LOCK_thread_count);
  if ((error=pthread_create(&signal_thread,&thr_attr,signal_hand,0)))
  {
    sql_print_error("Can't create interrupt-thread (error %d, errno: %d)",
		    error,errno);
    exit(1);
  }
  (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
  pthread_mutex_unlock(&LOCK_thread_count);

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


unknown's avatar
unknown committed
2643
/** This threads handles all signals and alarms. */
unknown's avatar
unknown committed
2644
/* ARGSUSED */
2645
pthread_handler_t signal_hand(void *arg __attribute__((unused)))
unknown's avatar
unknown committed
2646 2647 2648 2649 2650
{
  sigset_t set;
  int sig;
  my_thread_init();				// Init new thread
  DBUG_ENTER("signal_hand");
unknown's avatar
unknown committed
2651 2652
  signal_thread_in_use= 1;

unknown's avatar
unknown committed
2653 2654
  /*
    Setup alarm handler
2655 2656
    This should actually be '+ max_number_of_slaves' instead of +10,
    but the +10 should be quite safe.
unknown's avatar
unknown committed
2657
  */
unknown's avatar
unknown committed
2658
  init_thr_alarm(thread_scheduler.max_threads +
2659
		 global_system_variables.max_insert_delayed_threads + 10);
2660
  if (thd_lib_detected != THD_LIB_LT && (test_flags & TEST_SIGINT))
2661 2662 2663 2664 2665
  {
    (void) sigemptyset(&set);			// Setup up SIGINT for debug
    (void) sigaddset(&set,SIGINT);		// For debugging
    (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL);
  }
unknown's avatar
unknown committed
2666 2667 2668 2669
  (void) sigemptyset(&set);			// Setup up SIGINT for debug
#ifdef USE_ONE_SIGNAL_HAND
  (void) sigaddset(&set,THR_SERVER_ALARM);	// For alarms
#endif
2670
#ifndef IGNORE_SIGHUP_SIGQUIT
unknown's avatar
unknown committed
2671 2672
  (void) sigaddset(&set,SIGQUIT);
  (void) sigaddset(&set,SIGHUP);
2673 2674
#endif
  (void) sigaddset(&set,SIGTERM);
unknown's avatar
unknown committed
2675 2676 2677
  (void) sigaddset(&set,SIGTSTP);

  /* Save pid to this process (or thread on Linux) */
2678
  if (!opt_bootstrap)
2679 2680
    create_pid_file();

2681 2682 2683 2684 2685 2686 2687
#ifdef HAVE_STACK_TRACE_ON_SEGV
  if (opt_do_pstack)
  {
    sprintf(pstack_file_name,"mysqld-%lu-%%d-%%d.backtrace", (ulong)getpid());
    pstack_install_segv_action(pstack_file_name);
  }
#endif /* HAVE_STACK_TRACE_ON_SEGV */
unknown's avatar
unknown committed
2688

2689 2690 2691 2692 2693 2694 2695
  /*
    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
    should not be any other pthread_cond_signal() calls.
  */
unknown's avatar
unknown committed
2696 2697
  (void) pthread_mutex_lock(&LOCK_thread_count);
  (void) pthread_mutex_unlock(&LOCK_thread_count);
2698
  (void) pthread_cond_broadcast(&COND_thread_count);
unknown's avatar
unknown committed
2699

2700
  (void) pthread_sigmask(SIG_BLOCK,&set,NULL);
unknown's avatar
unknown committed
2701 2702 2703 2704 2705
  for (;;)
  {
    int error;					// Used when debugging
    if (shutdown_in_progress && !abort_loop)
    {
2706
      sig= SIGTERM;
unknown's avatar
unknown committed
2707 2708 2709 2710 2711
      error=0;
    }
    else
      while ((error=my_sigwait(&set,&sig)) == EINTR) ;
    if (cleanup_done)
2712
    {
2713
      DBUG_PRINT("quit",("signal_handler: calling my_thread_end()"));
2714
      my_thread_end();
unknown's avatar
unknown committed
2715
      signal_thread_in_use= 0;
unknown's avatar
unknown committed
2716
      pthread_exit(0);				// Safety
2717
    }
unknown's avatar
unknown committed
2718 2719 2720 2721 2722
    switch (sig) {
    case SIGTERM:
    case SIGQUIT:
    case SIGKILL:
#ifdef EXTRA_DEBUG
2723
      sql_print_information("Got signal %d to shutdown mysqld",sig);
unknown's avatar
unknown committed
2724
#endif
2725
      /* switch to the old log message processing */
2726 2727
      logger.set_handlers(LOG_FILE, opt_slow_log ? LOG_FILE:LOG_NONE,
                          opt_log ? LOG_FILE:LOG_NONE);
unknown's avatar
unknown committed
2728 2729 2730 2731 2732 2733 2734 2735 2736
      DBUG_PRINT("info",("Got signal: %d  abort_loop: %d",sig,abort_loop));
      if (!abort_loop)
      {
	abort_loop=1;				// mark abort for threads
#ifdef USE_ONE_SIGNAL_HAND
	pthread_t tmp;
	if (!(opt_specialflag & SPECIAL_NO_PRIOR))
	  my_pthread_attr_setprio(&connection_attrib,INTERRUPT_PRIOR);
	if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
unknown's avatar
Merge  
unknown committed
2737
			   (void*) &sig))
2738
	  sql_print_error("Can't create thread to kill server");
unknown's avatar
unknown committed
2739
#else
unknown's avatar
unknown committed
2740
	kill_server((void*) sig);	// MIT THREAD has a alarm thread
unknown's avatar
unknown committed
2741 2742 2743 2744
#endif
      }
      break;
    case SIGHUP:
unknown's avatar
unknown committed
2745 2746
      if (!abort_loop)
      {
unknown's avatar
unknown committed
2747
        bool not_used;
unknown's avatar
Merge  
unknown committed
2748
	mysql_print_status();		// Print some debug info
unknown's avatar
unknown committed
2749 2750
	reload_acl_and_cache((THD*) 0,
			     (REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |
unknown's avatar
Merge  
unknown committed
2751
			      REFRESH_GRANT |
unknown's avatar
unknown committed
2752
			      REFRESH_THREADS | REFRESH_HOSTS),
unknown's avatar
unknown committed
2753
			     (TABLE_LIST*) 0, &not_used); // Flush logs
unknown's avatar
unknown committed
2754
      }
2755
      /* reenable logs after the options were reloaded */
2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767
      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
2768 2769 2770 2771 2772 2773 2774 2775
      break;
#ifdef USE_ONE_SIGNAL_HAND
    case THR_SERVER_ALARM:
      process_alarm(sig);			// Trigger alarms.
      break;
#endif
    default:
#ifdef EXTRA_DEBUG
2776
      sql_print_warning("Got signal: %d  error: %d",sig,error); /* purecov: tested */
unknown's avatar
unknown committed
2777 2778 2779 2780 2781 2782 2783
#endif
      break;					/* purecov: tested */
    }
  }
  return(0);					/* purecov: deadcode */
}

unknown's avatar
unknown committed
2784
static void check_data_home(const char *path)
unknown's avatar
unknown committed
2785
{}
unknown's avatar
unknown committed
2786

2787
#endif /*!EMBEDDED_LIBRARY*/
unknown's avatar
unknown committed
2788 2789 2790
#endif	/* __WIN__*/


unknown's avatar
unknown committed
2791
/**
unknown's avatar
Merge  
unknown committed
2792
  All global error messages are sent here where the first one is stored
unknown's avatar
unknown committed
2793
  for the client.
unknown's avatar
unknown committed
2794 2795
*/
/* ARGSUSED */
2796 2797 2798
extern "C" int my_message_sql(uint error, const char *str, myf MyFlags);

int my_message_sql(uint error, const char *str, myf MyFlags)
unknown's avatar
unknown committed
2799
{
2800
  THD *thd;
unknown's avatar
unknown committed
2801
  DBUG_ENTER("my_message_sql");
unknown's avatar
Merge  
unknown committed
2802 2803 2804 2805 2806 2807
  DBUG_PRINT("error", ("error: %u  message: '%s'", error, str));
  /*
    Put here following assertion when situation with EE_* error codes
    will be fixed
    DBUG_ASSERT(error != 0);
  */
2808
  if ((thd= current_thd))
unknown's avatar
unknown committed
2809
  {
2810 2811 2812 2813
    /*
      TODO: There are two exceptions mechanism (THD and sp_rcontext),
      this could be improved by having a common stack of handlers.
    */
2814
    if (thd->handle_error(error, str,
2815 2816 2817
                          MYSQL_ERROR::WARN_LEVEL_ERROR))
      DBUG_RETURN(0);

2818
    thd->is_slave_error=  1; // needed to catch query errors during replication
unknown's avatar
Merge  
unknown committed
2819

unknown's avatar
unknown committed
2820
    /*
2821
      thd->lex->current_select == 0 if lex structure is not inited
unknown's avatar
unknown committed
2822 2823
      (not query command (COM_QUERY))
    */
2824 2825
    if (thd->lex->current_select &&
	thd->lex->current_select->no_error && !thd->is_fatal_error)
unknown's avatar
unknown committed
2826
    {
2827 2828 2829 2830 2831 2832
      DBUG_PRINT("error",
                 ("Error converted to warning: current_select: no_error %d  "
                  "fatal_error: %d",
                  (thd->lex->current_select ?
                   thd->lex->current_select->no_error : 0),
                  (int) thd->is_fatal_error));
2833 2834 2835
    }
    else
    {
2836
      if (! thd->main_da.is_error())            // Return only first message
2837
      {
2838 2839 2840 2841 2842
        if (error == 0)
          error= ER_UNKNOWN_ERROR;
        if (str == NULL)
          str= ER(error);
        thd->main_da.set_error_status(thd, error, str);
2843
      }
2844 2845 2846 2847 2848 2849 2850
      query_cache_abort(&thd->net);
    }
    /*
      If a continue handler is found, the error message will be cleared
      by the stored procedures code.
    */
    if (thd->spcont &&
2851
        ! (MyFlags & ME_NO_SP_HANDLER) &&
2852 2853 2854 2855 2856 2857 2858 2859 2860
        thd->spcont->handle_error(error, MYSQL_ERROR::WARN_LEVEL_ERROR, thd))
    {
      /*
        Do not push any warnings, a handled error must be completely
        silenced.
      */
      DBUG_RETURN(0);
    }

2861 2862
    if (!thd->no_warnings_for_error &&
        !(MyFlags & ME_NO_WARNING_FOR_ERROR))
2863 2864 2865 2866 2867 2868 2869 2870
    {
      /*
        Suppress infinite recursion if there a memory allocation error
        inside push_warning.
      */
      thd->no_warnings_for_error= TRUE;
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str);
      thd->no_warnings_for_error= FALSE;
unknown's avatar
unknown committed
2871 2872
    }
  }
unknown's avatar
unknown committed
2873
  if (!thd || MyFlags & ME_NOREFRESH)
unknown's avatar
unknown committed
2874 2875 2876 2877
    sql_print_error("%s: %s",my_progname,str); /* purecov: inspected */
  DBUG_RETURN(0);
}

2878

2879
#ifndef EMBEDDED_LIBRARY
2880 2881 2882 2883
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)
2884 2885 2886 2887 2888
{
  return my_malloc(size, MYF(MY_FAE));
}


2889
void my_str_free_mysqld(void *ptr)
2890
{
2891
  my_free((uchar*)ptr, MYF(MY_FAE));
2892
}
2893
#endif /* EMBEDDED_LIBRARY */
2894 2895


unknown's avatar
unknown committed
2896 2897
#ifdef __WIN__

2898
pthread_handler_t handle_shutdown(void *arg)
unknown's avatar
unknown committed
2899 2900 2901 2902 2903 2904
{
  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
2905
#if !defined(EMBEDDED_LIBRARY)
unknown's avatar
unknown committed
2906
  if (WaitForSingleObject(hEventShutdown,INFINITE)==WAIT_OBJECT_0)
2907
#endif /* EMBEDDED_LIBRARY */
unknown's avatar
unknown committed
2908 2909 2910 2911 2912
     kill_server(MYSQL_KILL_SIGNAL);
  return 0;
}
#endif

unknown's avatar
unknown committed
2913
#if !defined(EMBEDDED_LIBRARY)
unknown's avatar
unknown committed
2914
static const char *load_default_groups[]= {
2915
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
2916 2917
"mysql_cluster",
#endif
unknown's avatar
Merge  
unknown committed
2918 2919
"mysqld","server", MYSQL_BASE_VERSION, 0, 0};

unknown's avatar
unknown committed
2920
#if defined(__WIN__)
2921 2922
static const int load_default_groups_sz=
sizeof(load_default_groups)/sizeof(load_default_groups[0]);
unknown's avatar
Merge  
unknown committed
2923
#endif
unknown's avatar
unknown committed
2924
#endif /*!EMBEDDED_LIBRARY*/
unknown's avatar
unknown committed
2925

unknown's avatar
unknown committed
2926

unknown's avatar
unknown committed
2927 2928
/**
  Initialize one of the global date/time format variables.
2929

unknown's avatar
unknown committed
2930 2931
  @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
2932

unknown's avatar
unknown committed
2933
  @note
2934 2935 2936
    The default value is taken from either opt_date_time_formats[] or
    the ISO format (ANSI SQL)

unknown's avatar
unknown committed
2937
  @retval
2938
    0 ok
unknown's avatar
unknown committed
2939
  @retval
2940 2941 2942
    1 error
*/

unknown's avatar
unknown committed
2943 2944
static bool init_global_datetime_format(timestamp_type format_type,
                                        DATE_TIME_FORMAT **var_ptr)
2945
{
2946 2947
  /* Get command line option */
  const char *str= opt_date_time_formats[format_type];
2948

2949
  if (!str)					// No specified format
2950
  {
2951 2952 2953 2954 2955 2956 2957
    str= get_date_time_format_str(&known_date_time_formats[ISO_FORMAT],
				  format_type);
    /*
      Set the "command line" option to point to the generated string so
      that we can set global formats back to default
    */
    opt_date_time_formats[format_type]= str;
2958
  }
2959
  if (!(*var_ptr= date_time_format_make(format_type, str, strlen(str))))
2960
  {
2961 2962
    fprintf(stderr, "Wrong date/time format specifier: %s\n", str);
    return 1;
2963
  }
2964
  return 0;
2965 2966
}

unknown's avatar
unknown committed
2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084
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},
  {"backup_table",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BACKUP_TABLE]), 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},
  {"load_master_data",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOAD_MASTER_DATA]), SHOW_LONG_STATUS},
  {"load_master_table",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOAD_MASTER_TABLE]), 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},
  {"restore_table",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RESTORE_TABLE]), SHOW_LONG_STATUS},
  {"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},
  {"show_authors",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_AUTHORS]), SHOW_LONG_STATUS},
  {"show_binlog_events",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOG_EVENTS]), SHOW_LONG_STATUS},
  {"show_binlogs",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOGS]), SHOW_LONG_STATUS},
  {"show_charsets",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CHARSETS]), SHOW_LONG_STATUS},
  {"show_collations",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLLATIONS]), SHOW_LONG_STATUS},
  {"show_column_types",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLUMN_TYPES]), 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},
  {"show_master_status",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_MASTER_STAT]), SHOW_LONG_STATUS},
  {"show_new_master",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_NEW_MASTER]), 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
3085 3086
  {"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},
unknown's avatar
unknown committed
3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101
  {"show_slave_hosts",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_HOSTS]), SHOW_LONG_STATUS},
  {"show_slave_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_STAT]), SHOW_LONG_STATUS},
  {"show_status",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS},
  {"show_storage_engines", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STORAGE_ENGINES]), SHOW_LONG_STATUS},
  {"show_table_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS},
  {"show_tables",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLES]), SHOW_LONG_STATUS},
  {"show_triggers",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TRIGGERS]), SHOW_LONG_STATUS},
  {"show_variables",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS},
  {"show_warnings",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
  {"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
3102
  {"stmt_reprepare",       (char*) offsetof(STATUS_VAR, com_stmt_reprepare), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115
  {"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},
3116
  {NullS, NullS, SHOW_LONG}
unknown's avatar
unknown committed
3117
};
3118

3119 3120
static int init_common_variables(const char *conf_file_name, int argc,
				 char **argv, const char **groups)
unknown's avatar
unknown committed
3121
{
unknown's avatar
unknown committed
3122
  char buff[FN_REFLEN], *s;
unknown's avatar
unknown committed
3123
  umask(((~my_umask) & 0666));
unknown's avatar
Merge  
unknown committed
3124
  my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
unknown's avatar
unknown committed
3125 3126
  tzset();			// Set tzname

unknown's avatar
SCRUM  
unknown committed
3127
  max_system_variables.pseudo_thread_id= (ulong)~0;
3128
  server_start_time= flush_status_time= my_time(0);
3129 3130
  rpl_filter= new Rpl_filter;
  binlog_filter= new Rpl_filter;
unknown's avatar
unknown committed
3131
  if (!rpl_filter || !binlog_filter)
3132 3133 3134 3135 3136
  {
    sql_perror("Could not allocate replication and binlog filters");
    exit(1);
  }

unknown's avatar
unknown committed
3137 3138
  if (init_thread_environment())
    return 1;
unknown's avatar
unknown committed
3139
  mysql_init_variables();
unknown's avatar
unknown committed
3140

unknown's avatar
unknown committed
3141 3142 3143
#ifdef HAVE_TZNAME
  {
    struct tm tm_tmp;
3144
    localtime_r(&server_start_time,&tm_tmp);
3145 3146 3147 3148
    strmake(system_time_zone, tzname[tm_tmp.tm_isdst != 0 ? 1 : 0],
            sizeof(system_time_zone)-1);

 }
unknown's avatar
unknown committed
3149
#endif
3150
  /*
unknown's avatar
unknown committed
3151
    We set SYSTEM time zone as reasonable default and
3152 3153 3154 3155 3156
    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
3157

unknown's avatar
unknown committed
3158
  /*
3159
    Init mutexes for the global MYSQL_BIN_LOG objects.
unknown's avatar
unknown committed
3160
    As safe_mutex depends on what MY_INIT() does, we can't init the mutexes of
3161 3162
    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
3163 3164
  */
  mysql_bin_log.init_pthread_objects();
3165

3166 3167 3168 3169 3170 3171 3172 3173
  if (gethostname(glob_hostname,sizeof(glob_hostname)) < 0)
  {
    strmake(glob_hostname, STRING_WITH_LEN("localhost"));
    sql_print_warning("gethostname failed, using '%s' as hostname",
                      glob_hostname);
    strmake(pidfile_name, STRING_WITH_LEN("mysql"));
  }
  else
unknown's avatar
unknown committed
3174
  strmake(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
3175
  strmov(fn_ext(pidfile_name),".pid");		// Add proper extension
unknown's avatar
unknown committed
3176

3177 3178 3179
  /*
    Add server status variables to the dynamic list of
    status variables that is shown by SHOW STATUS.
3180
    Later, in plugin_init, and mysql_install_plugin
3181 3182 3183 3184 3185
    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
3186 3187 3188 3189 3190
#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
3191
    There are 8 Com_ variables which don't have corresponding SQLCOM_ values:
unknown's avatar
unknown committed
3192 3193 3194 3195 3196 3197 3198 3199
    (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
3200
      Com_stmt_reprepare       => com_stmt_reprepare
unknown's avatar
unknown committed
3201 3202 3203
      Com_stmt_reset           => com_stmt_reset
      Com_stmt_send_long_data  => com_stmt_send_long_data

3204 3205 3206
    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
3207
  */
3208
  compile_time_assert(sizeof(com_status_vars)/sizeof(com_status_vars[0]) - 1 ==
unknown's avatar
unknown committed
3209
                     SQLCOM_END + 8);
unknown's avatar
unknown committed
3210 3211
#endif

unknown's avatar
unknown committed
3212 3213
  load_defaults(conf_file_name, groups, &argc, &argv);
  defaults_argv=argv;
unknown's avatar
unknown committed
3214 3215
  defaults_argc=argc;
  get_options(&defaults_argc, defaults_argv);
3216 3217
  set_server_version();

unknown's avatar
unknown committed
3218 3219 3220
  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
3221 3222 3223 3224 3225 3226 3227 3228 3229
#ifdef HAVE_LARGE_PAGES
  /* Initialize large page size */
  if (opt_large_pages && (opt_large_page_size= my_get_large_page_size()))
  {
      my_use_large_pages= 1;
      my_large_page_size= opt_large_page_size;
  }
#endif /* HAVE_LARGE_PAGES */

unknown's avatar
unknown committed
3230 3231
  /* connections and databases needs lots of files */
  {
3232
    uint files, wanted_files, max_open_files;
3233

3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248
    /* MyISAM requires two file handles per table. */
    wanted_files= 10+max_connections+table_cache_size*2;
    /*
      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).
    */
    max_open_files= max(max(wanted_files, max_connections*5),
                        open_files_limit);
    files= my_set_max_open_files(max_open_files);
3249 3250

    if (files < wanted_files)
unknown's avatar
unknown committed
3251
    {
3252 3253
      if (!open_files_limit)
      {
3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267
        /*
          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
3268
                                      table_cache_size);
3269 3270 3271
	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
3272
	if (global_system_variables.log_warnings)
3273
	  sql_print_warning("Changed limits: max_open_files: %u  max_connections: %ld  table_cache: %ld",
3274 3275
			files, max_connections, table_cache_size);
      }
unknown's avatar
unknown committed
3276
      else if (global_system_variables.log_warnings)
3277
	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
3278
    }
unknown's avatar
unknown committed
3279
    open_files_limit= files;
unknown's avatar
unknown committed
3280 3281
  }
  unireg_init(opt_specialflag); /* Set up extern variabels */
3282 3283
  if (init_errmessage())	/* Read error messages from file */
    return 1;
3284
  init_client_errs();
unknown's avatar
unknown committed
3285
  lex_init();
3286 3287
  if (item_create_init())
    return 1;
unknown's avatar
unknown committed
3288
  item_init();
unknown's avatar
unknown committed
3289 3290 3291 3292 3293 3294
  if (set_var_init())
    return 1;
#ifdef HAVE_REPLICATION
  if (init_replication_sys_vars())
    return 1;
#endif
unknown's avatar
unknown committed
3295 3296
  mysys_uses_curses=0;
#ifdef USE_REGEX
unknown's avatar
unknown committed
3297
  my_regex_init(&my_charset_latin1);
unknown's avatar
unknown committed
3298
#endif
3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325
  /*
    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;
  }

3326 3327
  if (default_collation_name)
  {
unknown's avatar
unknown committed
3328 3329
    CHARSET_INFO *default_collation;
    default_collation= get_charset_by_name(default_collation_name, MYF(0));
unknown's avatar
unknown committed
3330 3331 3332 3333 3334 3335
    if (!default_collation)
    {
      sql_print_error(ER(ER_UNKNOWN_COLLATION), default_collation_name);
      return 1;
    }
    if (!my_charset_same(default_charset_info, default_collation))
3336 3337 3338 3339 3340 3341 3342 3343
    {
      sql_print_error(ER(ER_COLLATION_CHARSET_MISMATCH),
		      default_collation_name,
		      default_charset_info->csname);
      return 1;
    }
    default_charset_info= default_collation;
  }
3344 3345 3346 3347
  /* 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;
3348
  global_system_variables.character_set_results= default_charset_info;
3349
  global_system_variables.character_set_client= default_charset_info;
3350

unknown's avatar
unknown committed
3351 3352 3353 3354 3355 3356
  if (!(character_set_filesystem= 
        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;

3357 3358 3359
  if (!(my_default_lc_time_names=
        my_locale_by_name(lc_time_names_name)))
  {
unknown's avatar
unknown committed
3360
    sql_print_error("Unknown locale: '%s'", lc_time_names_name);
3361 3362 3363 3364
    return 1;
  }
  global_system_variables.lc_time_names= my_default_lc_time_names;
  
unknown's avatar
unknown committed
3365 3366 3367
  sys_init_connect.value_length= 0;
  if ((sys_init_connect.value= opt_init_connect))
    sys_init_connect.value_length= strlen(opt_init_connect);
3368 3369
  else
    sys_init_connect.value=my_strdup("",MYF(0));
unknown's avatar
unknown committed
3370 3371 3372 3373

  sys_init_slave.value_length= 0;
  if ((sys_init_slave.value= opt_init_slave))
    sys_init_slave.value_length= strlen(opt_init_slave);
3374 3375
  else
    sys_init_slave.value=my_strdup("",MYF(0));
3376

3377 3378 3379 3380 3381
  /* check log options and issue warnings if needed */
  if (opt_log && opt_logname && !(log_output_options & LOG_FILE) &&
      !(log_output_options & LOG_NONE))
    sql_print_warning("Although a path was specified for the "
                      "--log option, log tables are used. "
3382
                      "To enable logging to files use the --log-output option.");
3383 3384 3385 3386 3387

  if (opt_slow_log && opt_slow_logname && !(log_output_options & LOG_FILE)
      && !(log_output_options & LOG_NONE))
    sql_print_warning("Although a path was specified for the "
                      "--log-slow-queries option, log tables are used. "
3388
                      "To enable logging to files use the --log-output=file option.");
3389

unknown's avatar
unknown committed
3390 3391 3392
  s= opt_logname ? opt_logname : make_default_log_name(buff, ".log");
  sys_var_general_log_path.value= my_strdup(s, MYF(0));
  sys_var_general_log_path.value_length= strlen(s);
3393

unknown's avatar
unknown committed
3394 3395 3396
  s= opt_slow_logname ? opt_slow_logname : make_default_log_name(buff, "-slow.log");
  sys_var_slow_log_path.value= my_strdup(s, MYF(0));
  sys_var_slow_log_path.value_length= strlen(s);
3397

3398
  if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
3399
    return 1;
unknown's avatar
unknown committed
3400
  if (my_database_names_init())
unknown's avatar
unknown committed
3401 3402
    return 1;

3403 3404 3405 3406 3407 3408
  /*
    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));
3409 3410
  lower_case_file_system= test_if_case_insensitive(mysql_real_data_home);
  if (!lower_case_table_names && lower_case_file_system == 1)
3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439
  {
    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 &&
           !(lower_case_file_system=
             (test_if_case_insensitive(mysql_real_data_home) == 1)))
  {
    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;
  }
3440 3441 3442 3443 3444
  else
  {
    lower_case_file_system=
      (test_if_case_insensitive(mysql_real_data_home) == 1);
  }
3445 3446 3447 3448 3449 3450

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

Mikael Ronstrom's avatar
Mikael Ronstrom committed
3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463

  /*
    If we explicitly turn off query cache from the command line query cache will
    be disabled for the reminder of the server life time. This is because we
    want to avoid locking the QC specific mutex if query cache isn't going to
    be used.
  */
  if (global_system_variables.query_cache_type == 0)
  {
    have_query_cache= SHOW_OPTION_NO;
    query_cache.disable_query_cache();
  }

unknown's avatar
unknown committed
3464 3465
  return 0;
}
unknown's avatar
unknown committed
3466

3467 3468

static int init_thread_environment()
unknown's avatar
unknown committed
3469
{
3470
  (void) pthread_mutex_init(&LOCK_mysql_create_db,MY_MUTEX_INIT_SLOW);
unknown's avatar
unknown committed
3471
  (void) pthread_mutex_init(&LOCK_lock_db,MY_MUTEX_INIT_SLOW);
3472
  (void) pthread_mutex_init(&LOCK_Acl,MY_MUTEX_INIT_SLOW);
unknown's avatar
unknown committed
3473
  (void) pthread_mutex_init(&LOCK_open, NULL);
3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485
  (void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
  (void) pthread_mutex_init(&LOCK_mapped_file,MY_MUTEX_INIT_SLOW);
  (void) pthread_mutex_init(&LOCK_status,MY_MUTEX_INIT_FAST);
  (void) pthread_mutex_init(&LOCK_error_log,MY_MUTEX_INIT_FAST);
  (void) pthread_mutex_init(&LOCK_delayed_insert,MY_MUTEX_INIT_FAST);
  (void) pthread_mutex_init(&LOCK_delayed_status,MY_MUTEX_INIT_FAST);
  (void) pthread_mutex_init(&LOCK_delayed_create,MY_MUTEX_INIT_SLOW);
  (void) pthread_mutex_init(&LOCK_manager,MY_MUTEX_INIT_FAST);
  (void) pthread_mutex_init(&LOCK_crypt,MY_MUTEX_INIT_FAST);
  (void) pthread_mutex_init(&LOCK_bytes_sent,MY_MUTEX_INIT_FAST);
  (void) pthread_mutex_init(&LOCK_bytes_received,MY_MUTEX_INIT_FAST);
  (void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
3486
  (void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
3487
  (void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
unknown's avatar
unknown committed
3488
  (void) my_rwlock_init(&LOCK_system_variables_hash, NULL);
3489
  (void) pthread_mutex_init(&LOCK_global_read_lock, MY_MUTEX_INIT_FAST);
3490
  (void) pthread_mutex_init(&LOCK_prepared_stmt_count, MY_MUTEX_INIT_FAST);
unknown's avatar
unknown committed
3491
  (void) pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST);
3492
  (void) pthread_mutex_init(&LOCK_connection_count, MY_MUTEX_INIT_FAST);
3493 3494
#ifdef HAVE_OPENSSL
  (void) pthread_mutex_init(&LOCK_des_key_file,MY_MUTEX_INIT_FAST);
unknown's avatar
unknown committed
3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505
#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)
    (void) my_rwlock_init(&openssl_stdlocks[i].lock, NULL); 
  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
3506
#endif
unknown's avatar
unknown committed
3507 3508
  (void) my_rwlock_init(&LOCK_sys_init_connect, NULL);
  (void) my_rwlock_init(&LOCK_sys_init_slave, NULL);
3509
  (void) my_rwlock_init(&LOCK_grant, NULL);
unknown's avatar
unknown committed
3510 3511
  (void) pthread_cond_init(&COND_thread_count,NULL);
  (void) pthread_cond_init(&COND_refresh,NULL);
unknown's avatar
unknown committed
3512
  (void) pthread_cond_init(&COND_global_read_lock,NULL);
unknown's avatar
unknown committed
3513 3514
  (void) pthread_cond_init(&COND_thread_cache,NULL);
  (void) pthread_cond_init(&COND_flush_thread_cache,NULL);
3515
  (void) pthread_cond_init(&COND_manager,NULL);
unknown's avatar
SCRUM  
unknown committed
3516
#ifdef HAVE_REPLICATION
3517
  (void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST);
3518
  (void) pthread_cond_init(&COND_rpl_status, NULL);
3519
#endif
unknown's avatar
unknown committed
3520 3521
  (void) pthread_mutex_init(&LOCK_server_started, MY_MUTEX_INIT_FAST);
  (void) pthread_cond_init(&COND_server_started,NULL);
unknown's avatar
Merge  
unknown committed
3522
  sp_cache_init();
3523
#ifdef HAVE_EVENT_SCHEDULER
3524
  Events::init_mutexes();
3525
#endif
unknown's avatar
unknown committed
3526 3527 3528 3529 3530
  /* 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);
3531 3532
  if (!(opt_specialflag & SPECIAL_NO_PRIOR))
    my_pthread_attr_setprio(&connection_attrib,WAIT_PRIOR);
unknown's avatar
unknown committed
3533

unknown's avatar
unknown committed
3534 3535 3536 3537 3538 3539 3540 3541 3542
  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;
}

3543

unknown's avatar
unknown committed
3544
#if defined(HAVE_OPENSSL) && !defined(HAVE_YASSL)
3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605
static unsigned long openssl_id_function()
{ 
  return (unsigned long) pthread_self();
} 


static openssl_lock_t *openssl_dynlock_create(const char *file, int line)
{ 
  openssl_lock_t *lock= new openssl_lock_t;
  my_rwlock_init(&lock->lock, NULL);
  return lock;
}


static void openssl_dynlock_destroy(openssl_lock_t *lock, const char *file, 
				    int line)
{
  rwlock_destroy(&lock->lock);
  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);
}


static void openssl_lock(int mode, openssl_lock_t *lock, const char *file, 
			 int line)
{
  int err;
  char const *what;

  switch (mode) {
  case CRYPTO_LOCK|CRYPTO_READ:
    what = "read lock";
    err = rw_rdlock(&lock->lock);
    break;
  case CRYPTO_LOCK|CRYPTO_WRITE:
    what = "write lock";
    err = rw_wrlock(&lock->lock);
    break;
  case CRYPTO_UNLOCK|CRYPTO_READ:
  case CRYPTO_UNLOCK|CRYPTO_WRITE:
    what = "unlock";
    err = rw_unlock(&lock->lock);
    break;
  default:
    /* Unknown locking mode. */
    sql_print_error("Fatal: OpenSSL interface problem (mode=0x%x)", mode);
    abort();
  }
  if (err) 
  {
3606
    sql_print_error("Fatal: can't %s OpenSSL lock", what);
3607 3608 3609 3610 3611 3612
    abort();
  }
}
#endif /* HAVE_OPENSSL */


3613 3614
#ifndef EMBEDDED_LIBRARY

unknown's avatar
unknown committed
3615 3616
static void init_ssl()
{
unknown's avatar
unknown committed
3617 3618 3619
#ifdef HAVE_OPENSSL
  if (opt_use_ssl)
  {
3620 3621 3622 3623
    /* 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,
					  opt_ssl_cipher);
unknown's avatar
Merge  
unknown committed
3624
    DBUG_PRINT("info",("ssl_acceptor_fd: 0x%lx", (long) ssl_acceptor_fd));
unknown's avatar
unknown committed
3625
    if (!ssl_acceptor_fd)
3626
    {
3627
      sql_print_warning("Failed to setup SSL");
unknown's avatar
unknown committed
3628
      opt_use_ssl = 0;
3629
      have_ssl= SHOW_OPTION_DISABLED;
3630 3631 3632 3633
    }
  }
  else
  {
3634
    have_ssl= SHOW_OPTION_DISABLED;
unknown's avatar
unknown committed
3635
  }
unknown's avatar
unknown committed
3636 3637
  if (des_key_file)
    load_des_key_file(des_key_file);
unknown's avatar
unknown committed
3638
#endif /* HAVE_OPENSSL */
unknown's avatar
unknown committed
3639
}
unknown's avatar
unknown committed
3640

3641

3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652
static void end_ssl()
{
#ifdef HAVE_OPENSSL
  if (ssl_acceptor_fd)
  {
    free_vio_ssl_acceptor_fd(ssl_acceptor_fd);
    ssl_acceptor_fd= 0;
  }
#endif /* HAVE_OPENSSL */
}

3653
#endif /* EMBEDDED_LIBRARY */
3654

3655

unknown's avatar
unknown committed
3656 3657
static int init_server_components()
{
3658
  DBUG_ENTER("init_server_components");
unknown's avatar
unknown committed
3659 3660 3661 3662 3663
  /*
    We need to call each of these following functions to ensure that
    all things are initialized so that unireg_abort() doesn't fail
  */
  if (table_cache_init() | table_def_init() | hostname_cache_init())
3664
    unireg_abort(1);
unknown's avatar
unknown committed
3665

unknown's avatar
unknown committed
3666
  query_cache_result_size_limit(query_cache_limit);
3667
  query_cache_set_min_res_unit(query_cache_min_res_unit);
unknown's avatar
unknown committed
3668
  query_cache_init();
unknown's avatar
unknown committed
3669
  query_cache_resize(query_cache_size);
3670
  randominit(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2);
3671
  set_proper_floating_point_mode();
unknown's avatar
unknown committed
3672
  init_thr_lock();
unknown's avatar
SCRUM  
unknown committed
3673
#ifdef HAVE_REPLICATION
3674
  init_slave_list();
3675
#endif
unknown's avatar
unknown committed
3676

3677 3678
  /* Setup logs */

3679 3680 3681 3682 3683 3684
  /*
    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.
  */
  if (opt_error_log && !opt_help)
3685 3686
  {
    if (!log_error_file_ptr[0])
3687
      fn_format(log_error_file, pidfile_name, mysql_data_home, ".err",
3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702
                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);
    if (!log_error_file[0])
      opt_error_log= 1;				// Too long file name
    else
    {
#ifndef EMBEDDED_LIBRARY
      if (freopen(log_error_file, "a+", stdout))
#endif
        freopen(log_error_file, "a+", stderr);
    }
  }

unknown's avatar
unknown committed
3703 3704 3705 3706 3707 3708
  if (xid_cache_init())
  {
    sql_print_error("Out of memory");
    unireg_abort(1);
  }

unknown's avatar
unknown committed
3709
  /* need to configure logging before initializing storage engines */
unknown's avatar
unknown committed
3710
  if (opt_update_log)
unknown's avatar
unknown committed
3711
  {
unknown's avatar
Merge  
unknown committed
3712 3713 3714 3715
    /*
      Update log is removed since 5.0. But we still accept the option.
      The idea is if the user already uses the binlog and the update log,
      we completely ignore any option/variable related to the update log, like
unknown's avatar
unknown committed
3716 3717
      if the update log did not exist. But if the user uses only the update
      log, then we translate everything into binlog for him (with warnings).
unknown's avatar
Merge  
unknown committed
3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730
      Implementation of the above :
      - If mysqld is started with --log-update and --log-bin,
      ignore --log-update (print a warning), push a warning when SQL_LOG_UPDATE
      is used, and turn off --sql-bin-update-same.
      This will completely ignore SQL_LOG_UPDATE
      - If mysqld is started with --log-update only,
      change it to --log-bin (with the filename passed to log-update,
      plus '-bin') (print a warning), push a warning when SQL_LOG_UPDATE is
      used, and turn on --sql-bin-update-same.
      This will translate SQL_LOG_UPDATE to SQL_LOG_BIN.

      Note that we tell the user that --sql-bin-update-same is deprecated and
      does nothing, and we don't take into account if he used this option or
unknown's avatar
unknown committed
3731 3732
      not; but internally we give this variable a value to have the behaviour
      we want (i.e. have SQL_LOG_UPDATE influence SQL_LOG_BIN or not).
unknown's avatar
Merge  
unknown committed
3733
      As sql-bin-update-same, log-update and log-bin cannot be changed by the
unknown's avatar
unknown committed
3734 3735
      user after starting the server (they are not variables), the user will
      not later interfere with the settings we do here.
unknown's avatar
Merge  
unknown committed
3736 3737
    */
    if (opt_bin_log)
unknown's avatar
unknown committed
3738
    {
unknown's avatar
Merge  
unknown committed
3739 3740 3741 3742 3743 3744 3745 3746 3747 3748
      opt_sql_bin_update= 0;
      sql_print_error("The update log is no longer supported by MySQL in \
version 5.0 and above. It is replaced by the binary log.");
    }
    else
    {
      opt_sql_bin_update= 1;
      opt_bin_log= 1;
      if (opt_update_logname)
      {
unknown's avatar
unknown committed
3749
        /* as opt_bin_log==0, no need to free opt_bin_logname */
unknown's avatar
Merge  
unknown committed
3750 3751 3752 3753 3754 3755 3756 3757 3758 3759
        if (!(opt_bin_logname= my_strdup(opt_update_logname, MYF(MY_WME))))
          exit(EXIT_OUT_OF_MEMORY);
        sql_print_error("The update log is no longer supported by MySQL in \
version 5.0 and above. It is replaced by the binary log. Now starting MySQL \
with --log-bin='%s' instead.",opt_bin_logname);
      }
      else
        sql_print_error("The update log is no longer supported by MySQL in \
version 5.0 and above. It is replaced by the binary log. Now starting MySQL \
with --log-bin instead.");
unknown's avatar
unknown committed
3760
    }
3761
  }
unknown's avatar
Merge  
unknown committed
3762
  if (opt_log_slave_updates && !opt_bin_log)
unknown's avatar
unknown committed
3763
  {
3764 3765
    sql_print_error("You need to use --log-bin to make "
                    "--log-slave-updates work.");
3766 3767
    unireg_abort(1);
  }
3768 3769
  if (!opt_bin_log)
    if (opt_binlog_format_id != BINLOG_FORMAT_UNSPEC)
3770
  {
3771 3772
    sql_print_error("You need to use --log-bin to make "
                    "--binlog-format work.");
3773
    unireg_abort(1);
unknown's avatar
unknown committed
3774
  }
3775
    else
3776
  {
3777
      global_system_variables.binlog_format= BINLOG_FORMAT_MIXED;
3778 3779 3780
    }
  else
    if (opt_binlog_format_id == BINLOG_FORMAT_UNSPEC)
3781
      global_system_variables.binlog_format= BINLOG_FORMAT_MIXED;
3782 3783 3784
    else
    { 
      DBUG_ASSERT(global_system_variables.binlog_format != BINLOG_FORMAT_UNSPEC);
3785
  }
3786

3787
  /* Check that we have not let the format to unspecified at this point */
3788
  DBUG_ASSERT((uint)global_system_variables.binlog_format <=
3789
              array_elements(binlog_format_names)-1);
3790

unknown's avatar
unknown committed
3791
#ifdef HAVE_REPLICATION
unknown's avatar
unknown committed
3792 3793 3794
  if (opt_log_slave_updates && replicate_same_server_id)
  {
    sql_print_error("\
3795
using --replicate-same-server-id in conjunction with \
unknown's avatar
unknown committed
3796 3797 3798 3799
--log-slave-updates is impossible, it would lead to infinite loops in this \
server.");
    unireg_abort(1);
  }
unknown's avatar
unknown committed
3800
#endif
3801

unknown's avatar
Merge  
unknown committed
3802
  if (opt_bin_log)
3803
  {
unknown's avatar
Merge  
unknown committed
3804 3805 3806 3807
    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)
3808 3809
    {
      /*
unknown's avatar
Merge  
unknown committed
3810 3811 3812 3813 3814
        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.
3815
      */
unknown's avatar
Merge  
unknown committed
3816 3817 3818 3819 3820
      sql_print_warning("No argument was provided to --log-bin, and "
                        "--log-bin-index was not used; so replication "
                        "may break when this MySQL server acts as a "
                        "master and has his hostname changed!! Please "
                        "use '--log-bin=%s' to avoid this problem.", ln);
3821
    }
unknown's avatar
Merge  
unknown committed
3822
    if (ln == buf)
3823
    {
unknown's avatar
Merge  
unknown committed
3824 3825
      my_free(opt_bin_logname, MYF(MY_ALLOW_ZERO_PTR));
      opt_bin_logname=my_strdup(buf, MYF(0));
3826
    }
unknown's avatar
unknown committed
3827 3828 3829 3830 3831 3832 3833 3834 3835
    if (mysql_bin_log.open_index_file(opt_binlog_index_name, ln))
    {
      unireg_abort(1);
    }

    /*
      Used to specify which type of lock we need to use for queries of type
      INSERT ... SELECT. This will change when we have row level logging.
    */
unknown's avatar
Merge  
unknown committed
3836
    using_update_log=1;
3837 3838
  }

3839 3840 3841 3842 3843 3844 3845
  /* call ha_init_key_cache() on all key caches to init them */
  process_key_caches(&ha_init_key_cache);

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

unknown's avatar
unknown committed
3846
  if (plugin_init(&defaults_argc, defaults_argv,
unknown's avatar
unknown committed
3847 3848
                  (opt_noacl ? PLUGIN_INIT_SKIP_PLUGIN_TABLE : 0) |
                  (opt_help ? PLUGIN_INIT_SKIP_INITIALIZATION : 0)))
unknown's avatar
unknown committed
3849
  {
unknown's avatar
unknown committed
3850 3851
    sql_print_error("Failed to initialize plugins.");
    unireg_abort(1);
unknown's avatar
unknown committed
3852 3853
  }

unknown's avatar
unknown committed
3854 3855 3856 3857 3858 3859 3860
  if (opt_help)
    unireg_abort(0);

  /* we do want to exit if there are any other unknown options */
  if (defaults_argc > 1)
  {
    int ho_error;
unknown's avatar
unknown committed
3861 3862
    char **tmp_argv= defaults_argv;
    struct my_option no_opts[]=
unknown's avatar
unknown committed
3863 3864 3865 3866 3867
    {
      {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
3868 3869 3870
      that there are unprocessed options.
      But we need to preserve defaults_argv pointer intact for
      free_defaults() to work. Thus we use a copy here.
unknown's avatar
unknown committed
3871 3872
    */
    my_getopt_skip_unknown= 0;
unknown's avatar
unknown committed
3873 3874

    if ((ho_error= handle_options(&defaults_argc, &tmp_argv, no_opts,
3875
                                  mysqld_get_one_option)))
unknown's avatar
unknown committed
3876
      unireg_abort(ho_error);
unknown's avatar
unknown committed
3877

unknown's avatar
unknown committed
3878 3879 3880
    if (defaults_argc)
    {
      fprintf(stderr, "%s: Too many arguments (first extra is '%s').\n"
unknown's avatar
unknown committed
3881 3882
              "Use --verbose --help to get a list of available options\n",
              my_progname, *tmp_argv);
unknown's avatar
unknown committed
3883 3884
      unireg_abort(1);
    }
unknown's avatar
unknown committed
3885 3886
  }

unknown's avatar
unknown committed
3887 3888 3889 3890
  /* if the errmsg.sys is not loaded, terminate to maintain behaviour */
  if (!errmesg[0][0])
    unireg_abort(1);

unknown's avatar
unknown committed
3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918
  /* We have to initialize the storage engines before CSV logging */
  if (ha_init())
  {
    sql_print_error("Can't init databases");
    unireg_abort(1);
  }

#ifdef WITH_CSV_STORAGE_ENGINE
  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
3919 3920
    LEX_STRING csv_name={C_STRING_WITH_LEN("csv")};
    if (!plugin_is_ready(&csv_name, MYSQL_STORAGE_ENGINE_PLUGIN))
unknown's avatar
unknown committed
3921
    {
3922
      /* purecov: begin inspected */
unknown's avatar
unknown committed
3923 3924
      sql_print_error("CSV engine is not present, falling back to the "
                      "log files");
unknown's avatar
unknown committed
3925
      log_output_options= (log_output_options & ~LOG_TABLE) | LOG_FILE;
3926
      /* purecov: end */
unknown's avatar
unknown committed
3927 3928 3929 3930 3931 3932 3933 3934 3935 3936
    }

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

3937 3938 3939
  /*
    Check that the default storage engine is actually available.
  */
unknown's avatar
unknown committed
3940
  if (default_storage_engine_str)
3941
  {
unknown's avatar
unknown committed
3942 3943
    LEX_STRING name= { default_storage_engine_str,
                       strlen(default_storage_engine_str) };
unknown's avatar
unknown committed
3944 3945 3946 3947 3948 3949
    plugin_ref plugin;
    handlerton *hton;
    
    if ((plugin= ha_resolve_by_name(0, &name)))
      hton= plugin_data(plugin, handlerton*);
    else
3950
    {
unknown's avatar
unknown committed
3951 3952
      sql_print_error("Unknown/unsupported table type: %s",
                      default_storage_engine_str);
3953 3954
      unireg_abort(1);
    }
unknown's avatar
unknown committed
3955 3956 3957 3958 3959 3960 3961 3962
    if (!ha_storage_engine_is_enabled(hton))
    {
      if (!opt_bootstrap)
      {
        sql_print_error("Default storage engine (%s) is not available",
                        default_storage_engine_str);
        unireg_abort(1);
      }
unknown's avatar
unknown committed
3963 3964 3965 3966 3967 3968 3969 3970 3971 3972
      DBUG_ASSERT(global_system_variables.table_plugin);
    }
    else
    {
      /*
        Need to unlock as global_system_variables.table_plugin 
        was acquired during plugin_init()
      */
      plugin_unlock(0, global_system_variables.table_plugin);
      global_system_variables.table_plugin= plugin;
unknown's avatar
unknown committed
3973
    }
3974 3975
  }

unknown's avatar
unknown committed
3976 3977 3978 3979
  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
3980

unknown's avatar
unknown committed
3981
  if (tc_log->open(opt_bin_log ? opt_bin_logname : opt_tc_log_file))
unknown's avatar
Merge  
unknown committed
3982 3983 3984 3985 3986
  {
    sql_print_error("Can't init tc log");
    unireg_abort(1);
  }

unknown's avatar
unknown committed
3987 3988 3989 3990 3991
  if (ha_recover(0))
  {
    unireg_abort(1);
  }

unknown's avatar
Merge  
unknown committed
3992 3993
  if (opt_bin_log && mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0,
                                        WRITE_CACHE, 0, max_binlog_size, 0))
unknown's avatar
unknown committed
3994
    unireg_abort(1);
unknown's avatar
Merge  
unknown committed
3995 3996 3997

#ifdef HAVE_REPLICATION
  if (opt_bin_log && expire_logs_days)
3998
  {
3999
    time_t purge_time= server_start_time - expire_logs_days*24*60*60;
unknown's avatar
Merge  
unknown committed
4000 4001
    if (purge_time >= 0)
      mysql_bin_log.purge_logs_before_date(purge_time);
4002
  }
unknown's avatar
Merge  
unknown committed
4003
#endif
unknown's avatar
unknown committed
4004 4005 4006 4007
#ifdef __NETWARE__
  /* Increasing stacksize of threads on NetWare */
  pthread_attr_setstacksize(&connection_attrib, NW_THD_STACKSIZE);
#endif
unknown's avatar
Merge  
unknown committed
4008 4009 4010

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

unknown's avatar
unknown committed
4012
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && !defined(EMBEDDED_LIBRARY)
4013
  if (locked_in_memory && !getuid())
4014
  {
4015
    if (setreuid((uid_t)-1, 0) == -1)
4016
    {                        // this should never happen
4017
      sql_perror("setreuid");
4018 4019
      unireg_abort(1);
    }
4020 4021
    if (mlockall(MCL_CURRENT))
    {
4022
      if (global_system_variables.log_warnings)
4023
	sql_print_warning("Failed to lock memory. Errno: %d\n",errno);
unknown's avatar
unknown committed
4024
      locked_in_memory= 0;
4025
    }
4026 4027
    if (user_info)
      set_user(mysqld_user, user_info);
4028
  }
unknown's avatar
unknown committed
4029
  else
4030
#endif
unknown's avatar
unknown committed
4031
    locked_in_memory=0;
4032

4033
  ft_init_stopwords();
unknown's avatar
unknown committed
4034

unknown's avatar
unknown committed
4035
  init_max_user_conn();
4036
  init_update_queries();
4037
  DBUG_RETURN(0);
unknown's avatar
unknown committed
4038
}
unknown's avatar
unknown committed
4039

4040

4041
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
4042

unknown's avatar
unknown committed
4043 4044
static void create_maintenance_thread()
{
4045
  if (flush_time && flush_time != ~(ulong) 0L)
unknown's avatar
unknown committed
4046
  {
unknown's avatar
unknown committed
4047 4048
    pthread_t hThread;
    if (pthread_create(&hThread,&connection_attrib,handle_manager,0))
4049
      sql_print_warning("Can't create thread to manage maintenance");
unknown's avatar
unknown committed
4050
  }
unknown's avatar
unknown committed
4051 4052
}

4053

unknown's avatar
unknown committed
4054 4055 4056
static void create_shutdown_thread()
{
#ifdef __WIN__
4057 4058 4059
  hEventShutdown=CreateEvent(0, FALSE, FALSE, shutdown_event_name);
  pthread_t hThread;
  if (pthread_create(&hThread,&connection_attrib,handle_shutdown,0))
4060
    sql_print_warning("Can't create thread to handle shutdown requests");
unknown's avatar
unknown committed
4061

4062 4063
  // On "Stop Service" we have to do regular shutdown
  Service.SetShutdownEvent(hEventShutdown);
unknown's avatar
unknown committed
4064
#endif /* __WIN__ */
unknown's avatar
unknown committed
4065
}
unknown's avatar
unknown committed
4066

4067
#endif /* EMBEDDED_LIBRARY */
4068 4069


4070
#if (defined(__NT__) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY)
4071
static void handle_connections_methods()
unknown's avatar
unknown committed
4072
{
4073 4074 4075
  pthread_t hThread;
  DBUG_ENTER("handle_connections_methods");
#ifdef __NT__
unknown's avatar
unknown committed
4076
  if (hPipe == INVALID_HANDLE_VALUE &&
4077 4078
      (!have_tcpip || opt_disable_networking) &&
      !opt_enable_shared_memory)
unknown's avatar
unknown committed
4079
  {
unknown's avatar
unknown committed
4080
    sql_print_error("TCP/IP, --shared-memory, or --named-pipe should be configured on NT OS");
4081
    unireg_abort(1);				// Will not return
unknown's avatar
unknown committed
4082
  }
4083 4084 4085 4086 4087 4088 4089
#endif

  pthread_mutex_lock(&LOCK_thread_count);
  (void) pthread_cond_init(&COND_handler_count,NULL);
  handler_count=0;
#ifdef __NT__
  if (hPipe != INVALID_HANDLE_VALUE)
unknown's avatar
unknown committed
4090
  {
4091 4092 4093
    handler_count++;
    if (pthread_create(&hThread,&connection_attrib,
		       handle_connections_namedpipes, 0))
unknown's avatar
unknown committed
4094
    {
4095
      sql_print_warning("Can't create thread to handle named pipes");
4096 4097 4098 4099 4100 4101 4102 4103 4104 4105
      handler_count--;
    }
  }
#endif /* __NT__ */
  if (have_tcpip && !opt_disable_networking)
  {
    handler_count++;
    if (pthread_create(&hThread,&connection_attrib,
		       handle_connections_sockets, 0))
    {
4106
      sql_print_warning("Can't create thread to handle TCP/IP");
4107 4108 4109 4110 4111 4112 4113 4114 4115 4116
      handler_count--;
    }
  }
#ifdef HAVE_SMEM
  if (opt_enable_shared_memory)
  {
    handler_count++;
    if (pthread_create(&hThread,&connection_attrib,
		       handle_connections_shared_memory, 0))
    {
4117
      sql_print_warning("Can't create thread to handle shared memory");
4118
      handler_count--;
unknown's avatar
unknown committed
4119 4120
    }
  }
4121
#endif 
unknown's avatar
unknown committed
4122

4123 4124 4125 4126 4127
  while (handler_count > 0)
    pthread_cond_wait(&COND_handler_count,&LOCK_thread_count);
  pthread_mutex_unlock(&LOCK_thread_count);
  DBUG_VOID_RETURN;
}
4128 4129 4130 4131 4132 4133

void decrement_handler_count()
{
  pthread_mutex_lock(&LOCK_thread_count);
  handler_count--;
  pthread_cond_signal(&COND_handler_count);
4134 4135
  pthread_mutex_unlock(&LOCK_thread_count);  
  my_thread_end();
4136 4137 4138
}
#else
#define decrement_handler_count()
4139 4140 4141
#endif /* defined(__NT__) || defined(HAVE_SMEM) */


4142
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
4143 4144 4145 4146 4147 4148
#ifdef __WIN__
int win_main(int argc, char **argv)
#else
int main(int argc, char **argv)
#endif
{
4149 4150 4151
  MY_INIT(argv[0]);		// init my_sys library & pthreads
  /* nothing should come before this line ^^^ */

4152 4153 4154 4155 4156 4157 4158
  /* Set signal used to kill MySQL */
#if defined(SIGUSR2)
  thr_kill_signal= thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2;
#else
  thr_kill_signal= SIGINT;
#endif

4159 4160 4161 4162 4163 4164
  /*
    Perform basic logger initialization logger. Should be called after
    MY_INIT, as it initializes mutexes. Log tables are inited later.
  */
  logger.init_base();

unknown's avatar
unknown committed
4165
#ifdef _CUSTOMSTARTUPCONFIG_
unknown's avatar
unknown committed
4166 4167 4168
  if (_cust_check_startup())
  {
    / * _cust_check_startup will report startup failure error * /
unknown's avatar
Merge  
unknown committed
4169
    exit(1);
unknown's avatar
unknown committed
4170 4171
  }
#endif
unknown's avatar
unknown committed
4172

4173
#ifdef	__WIN__
unknown's avatar
unknown committed
4174 4175 4176 4177
  /*
    Before performing any socket operation (like retrieving hostname
    in init_common_variables we have to call WSAStartup
  */
4178 4179 4180 4181
  {
    WSADATA WsaData;
    if (SOCKET_ERROR == WSAStartup (0x0101, &WsaData))
    {
unknown's avatar
unknown committed
4182
      /* errors are not read yet, so we use english text here */
4183 4184 4185 4186 4187 4188
      my_message(ER_WSAS_FAILED, "WSAStartup Failed", MYF(0));
      unireg_abort(1);
    }
  }
#endif /* __WIN__ */

4189 4190 4191
  if (init_common_variables(MYSQL_CONFIG_NAME,
			    argc, argv, load_default_groups))
    unireg_abort(1);				// Will do exit
unknown's avatar
unknown committed
4192 4193 4194 4195

  init_signals();
  if (!(opt_specialflag & SPECIAL_NO_PRIOR))
    my_pthread_setprio(pthread_self(),CONNECT_PRIOR);
4196
#if defined(__ia64__) || defined(__ia64)
4197 4198 4199 4200
  /*
    Peculiar things with ia64 platforms - it seems we only have half the
    stack size in reality, so we have to double it here
  */
4201
  pthread_attr_setstacksize(&connection_attrib,my_thread_stack_size*2);
4202
#else
4203
  pthread_attr_setstacksize(&connection_attrib,my_thread_stack_size);
4204
#endif
4205 4206 4207 4208 4209
#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
  {
    /* Retrieve used stack size;  Needed for checking stack overflows */
    size_t stack_size= 0;
    pthread_attr_getstacksize(&connection_attrib, &stack_size);
4210 4211 4212
#if defined(__ia64__) || defined(__ia64)
    stack_size/= 2;
#endif
4213
    /* We must check if stack_size = 0 as Solaris 2.9 can return 0 here */
4214
    if (stack_size && stack_size < my_thread_stack_size)
4215 4216
    {
      if (global_system_variables.log_warnings)
unknown's avatar
unknown committed
4217
	sql_print_warning("Asked for %lu thread stack, but got %ld",
4218
			  my_thread_stack_size, (long) stack_size);
4219
#if defined(__ia64__) || defined(__ia64)
4220
      my_thread_stack_size= stack_size*2;
4221
#else
4222
      my_thread_stack_size= stack_size;
4223
#endif
4224 4225 4226
    }
  }
#endif
4227 4228 4229 4230
#ifdef __NETWARE__
  /* Increasing stacksize of threads on NetWare */
  pthread_attr_setstacksize(&connection_attrib, NW_THD_STACKSIZE);
#endif
unknown's avatar
unknown committed
4231

4232
  (void) thr_setconcurrency(concurrency);	// 10 by default
unknown's avatar
unknown committed
4233

4234 4235
  select_thread=pthread_self();
  select_thread_in_use=1;
unknown's avatar
unknown committed
4236 4237 4238 4239 4240 4241 4242 4243 4244 4245
  init_ssl();

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

  /*
    We have enough space for fiddling with the argv, continue
  */
unknown's avatar
unknown committed
4246
  check_data_home(mysql_real_data_home);
unknown's avatar
unknown committed
4247
  if (my_setwd(mysql_real_data_home,MYF(MY_WME)) && !opt_help)
unknown's avatar
unknown committed
4248 4249 4250 4251
    unireg_abort(1);				/* purecov: inspected */
  mysql_data_home= mysql_data_home_buff;
  mysql_data_home[0]=FN_CURLIB;		// all paths are relative from here
  mysql_data_home[1]=0;
4252
  mysql_data_home_len= 2;
unknown's avatar
unknown committed
4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263

  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
4264 4265 4266 4267
  if (opt_bin_log && !server_id)
  {
    server_id= !master_host ? 1 : 2;
#ifdef EXTRA_DEBUG
4268
    switch (server_id) {
unknown's avatar
unknown committed
4269
    case 1:
4270 4271
      sql_print_warning("\
You have enabled the binary log, but you haven't set server-id to \
4272 4273
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.");
unknown's avatar
unknown committed
4274 4275
      break;
    case 2:
4276 4277
      sql_print_warning("\
You should set server-id to a non-0 value if master_host is set; \
4278
we force server id to 2, but this MySQL server will not act as a slave.");
unknown's avatar
unknown committed
4279 4280
      break;
    }
4281
#endif
unknown's avatar
unknown committed
4282 4283 4284
  }

  if (init_server_components())
unknown's avatar
unknown committed
4285
    unireg_abort(1);
unknown's avatar
unknown committed
4286

unknown's avatar
unknown committed
4287 4288
  network_init();

unknown's avatar
unknown committed
4289 4290 4291
#ifdef __WIN__
  if (!opt_console)
  {
4292 4293
    freopen(log_error_file,"a+",stdout);
    freopen(log_error_file,"a+",stderr);
unknown's avatar
unknown committed
4294
    FreeConsole();				// Remove window
4295
  }
unknown's avatar
unknown committed
4296 4297
#endif

4298 4299 4300 4301 4302 4303
  /*
   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
4304 4305 4306 4307
  /*
    init signals & alarm
    After this we can't quit by a simple unireg_abort
  */
4308
  error_handler_hook= my_message_sql;
unknown's avatar
unknown committed
4309
  start_signal_handler();				// Creates pidfile
4310

4311
  if (mysql_rm_tmp_tables() || acl_init(opt_noacl) ||
4312
      my_tz_init((THD *)0, default_tz_name, opt_bootstrap))
unknown's avatar
unknown committed
4313 4314 4315
  {
    abort_loop=1;
    select_thread_in_use=0;
unknown's avatar
unknown committed
4316 4317 4318
#ifndef __NETWARE__
    (void) pthread_kill(signal_thread, MYSQL_KILL_SIGNAL);
#endif /* __NETWARE__ */
4319

unknown's avatar
unknown committed
4320 4321
    if (!opt_bootstrap)
      (void) my_delete(pidfile_name,MYF(MY_WME));	// Not needed anymore
4322

4323
    if (unix_sock != INVALID_SOCKET)
4324
      unlink(mysqld_unix_port);
unknown's avatar
unknown committed
4325 4326 4327
    exit(1);
  }
  if (!opt_noacl)
4328
    (void) grant_init();
unknown's avatar
unknown committed
4329

unknown's avatar
unknown committed
4330 4331 4332
  if (!opt_bootstrap)
    servers_init(0);

unknown's avatar
unknown committed
4333
  if (!opt_noacl)
4334 4335
  {
#ifdef HAVE_DLOPEN
unknown's avatar
unknown committed
4336 4337
    udf_init();
#endif
4338
  }
4339

4340
  init_status_vars();
unknown's avatar
unknown committed
4341 4342
  if (opt_bootstrap) /* If running with bootstrap, do not start replication. */
    opt_skip_slave_start= 1;
4343 4344 4345 4346 4347 4348 4349 4350 4351 4352
  /*
    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);
  }
4353

unknown's avatar
unknown committed
4354 4355
  if (opt_bootstrap)
  {
4356
    select_thread_in_use= 0;                    // Allow 'kill' to work
unknown's avatar
Merge  
unknown committed
4357 4358
    bootstrap(stdin);
    unireg_abort(bootstrap_error ? 1 : 0);
unknown's avatar
unknown committed
4359 4360 4361 4362 4363 4364
  }
  if (opt_init_file)
  {
    if (read_init_file(opt_init_file))
      unireg_abort(1);
  }
4365
  execute_ddl_log_recovery();
unknown's avatar
unknown committed
4366

unknown's avatar
unknown committed
4367
  create_shutdown_thread();
unknown's avatar
unknown committed
4368 4369
  create_maintenance_thread();

4370 4371 4372
  if (Events::init(opt_noacl))
    unireg_abort(1);

4373
  sql_print_information(ER(ER_STARTUP),my_progname,server_version,
unknown's avatar
unknown committed
4374
                        ((unix_sock == INVALID_SOCKET) ? (char*) ""
unknown's avatar
Merge  
unknown committed
4375
                                                       : mysqld_unix_port),
unknown's avatar
unknown committed
4376
                         mysqld_port,
unknown's avatar
Merge  
unknown committed
4377
                         MYSQL_COMPILATION_COMMENT);
unknown's avatar
unknown committed
4378

unknown's avatar
unknown committed
4379 4380 4381 4382 4383 4384 4385

  /* Signal threads waiting for server to be started */
  pthread_mutex_lock(&LOCK_server_started);
  mysqld_server_started= 1;
  pthread_cond_signal(&COND_server_started);
  pthread_mutex_unlock(&LOCK_server_started);

4386 4387
#if defined(__NT__) || defined(HAVE_SMEM)
  handle_connections_methods();
unknown's avatar
unknown committed
4388
#else
unknown's avatar
unknown committed
4389
#ifdef __WIN__
unknown's avatar
Merge  
unknown committed
4390
  if (!have_tcpip || opt_disable_networking)
unknown's avatar
unknown committed
4391
  {
unknown's avatar
unknown committed
4392
    sql_print_error("TCP/IP unavailable or disabled with --skip-networking; no available interfaces");
unknown's avatar
unknown committed
4393 4394 4395
    unireg_abort(1);
  }
#endif
unknown's avatar
unknown committed
4396 4397 4398 4399
  handle_connections_sockets(0);
#endif /* __NT__ */

  /* (void) pthread_attr_destroy(&connection_attrib); */
4400
  
unknown's avatar
unknown committed
4401 4402 4403
  DBUG_PRINT("quit",("Exiting main thread"));

#ifndef __WIN__
unknown's avatar
unknown committed
4404
#ifdef EXTRA_DEBUG2
unknown's avatar
unknown committed
4405 4406 4407
  sql_print_error("Before Lock_thread_count");
#endif
  (void) pthread_mutex_lock(&LOCK_thread_count);
unknown's avatar
unknown committed
4408
  DBUG_PRINT("quit", ("Got thread_count mutex"));
unknown's avatar
unknown committed
4409 4410
  select_thread_in_use=0;			// For close_connections
  (void) pthread_mutex_unlock(&LOCK_thread_count);
4411
  (void) pthread_cond_broadcast(&COND_thread_count);
unknown's avatar
unknown committed
4412
#ifdef EXTRA_DEBUG2
unknown's avatar
unknown committed
4413 4414
  sql_print_error("After lock_thread_count");
#endif
unknown's avatar
merge  
unknown committed
4415
#endif /* __WIN__ */
4416

unknown's avatar
unknown committed
4417 4418 4419 4420 4421
  /* Wait until cleanup is done */
  (void) pthread_mutex_lock(&LOCK_thread_count);
  while (!ready_to_exit)
    pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
  (void) pthread_mutex_unlock(&LOCK_thread_count);
unknown's avatar
merge  
unknown committed
4422 4423

#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
unknown's avatar
merge  
unknown committed
4424 4425 4426 4427
  if (Service.IsNT() && start_mode)
    Service.Stop();
  else
  {
unknown's avatar
unknown committed
4428
    Service.SetShutdownEvent(0);
unknown's avatar
merge  
unknown committed
4429 4430 4431
    if (hEventShutdown)
      CloseHandle(hEventShutdown);
  }
unknown's avatar
unknown committed
4432
#endif
unknown's avatar
unknown committed
4433
  clean_up(1);
4434
  wait_for_signal_thread_to_end();
unknown's avatar
unknown committed
4435
  clean_up_mutexes();
unknown's avatar
unknown committed
4436
  my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
4437

unknown's avatar
unknown committed
4438 4439 4440 4441
  exit(0);
  return(0);					/* purecov: deadcode */
}

4442
#endif /* EMBEDDED_LIBRARY */
unknown's avatar
unknown committed
4443

unknown's avatar
SCRUM  
unknown committed
4444

4445 4446 4447 4448 4449
/****************************************************************************
  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
4450
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
unknown's avatar
unknown committed
4451 4452
int mysql_service(void *p)
{
4453 4454 4455 4456
  if (use_opt_args)
    win_main(opt_argc, opt_argv);
  else
    win_main(Service.my_argc, Service.my_argv);
unknown's avatar
unknown committed
4457 4458 4459
  return 0;
}

4460 4461 4462 4463 4464 4465 4466 4467

/* 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
4468 4469
    return strmake(to, from, length-1);
  return strxnmov(to, length-1, "\"", from, "\"", NullS);
4470 4471 4472
}


unknown's avatar
unknown committed
4473 4474
/**
  Handle basic handling of services, like installation and removal.
4475

unknown's avatar
unknown committed
4476 4477 4478 4479 4480 4481 4482
  @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

  @retval
4483
    0		option handled
unknown's avatar
unknown committed
4484
  @retval
4485
    1		Could not handle option
unknown's avatar
unknown committed
4486
*/
4487

4488 4489 4490 4491 4492
static bool
default_service_handling(char **argv,
			 const char *servicename,
			 const char *displayname,
			 const char *file_path,
unknown's avatar
Merge  
unknown committed
4493 4494
			 const char *extra_opt,
			 const char *account_name)
4495
{
4496
  char path_and_service[FN_REFLEN+FN_REFLEN+32], *pos, *end;
4497
  end= path_and_service + sizeof(path_and_service)-3;
4498 4499 4500 4501 4502 4503 4504 4505 4506

  /* We have to quote filename if it contains spaces */
  pos= add_quoted_string(path_and_service, file_path, end);
  if (*extra_opt)
  {
    /* Add (possible quoted) option after file_path */
    *pos++= ' ';
    pos= add_quoted_string(pos, extra_opt, end);
  }
4507 4508
  /* We must have servicename last */
  *pos++= ' ';
unknown's avatar
unknown committed
4509
  (void) add_quoted_string(pos, servicename, end);
4510

4511 4512
  if (Service.got_service_option(argv, "install"))
  {
unknown's avatar
Merge  
unknown committed
4513 4514
    Service.Install(1, servicename, displayname, path_and_service,
                    account_name);
4515 4516 4517 4518
    return 0;
  }
  if (Service.got_service_option(argv, "install-manual"))
  {
unknown's avatar
Merge  
unknown committed
4519 4520
    Service.Install(0, servicename, displayname, path_and_service,
                    account_name);
4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531
    return 0;
  }
  if (Service.got_service_option(argv, "remove"))
  {
    Service.Remove(servicename);
    return 0;
  }
  return 1;
}


unknown's avatar
unknown committed
4532 4533
int main(int argc, char **argv)
{
unknown's avatar
unknown committed
4534 4535 4536 4537
  /*
    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
4538
  */
4539
  int10_to_str((int) GetCurrentProcessId(),strmov(shutdown_event_name,
unknown's avatar
Merge  
unknown committed
4540 4541
                                                  "MySQLShutdown"), 10);

4542 4543 4544
  /* Must be initialized early for comparison of service name */
  system_charset_info= &my_charset_utf8_general_ci;

unknown's avatar
unknown committed
4545
  if (Service.GetOS())	/* true NT family */
unknown's avatar
unknown committed
4546
  {
unknown's avatar
unknown committed
4547
    char file_path[FN_REFLEN];
4548
    my_path(file_path, argv[0], "");		      /* Find name in path */
unknown's avatar
unknown committed
4549 4550
    fn_format(file_path,argv[0],file_path,"",
	      MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_RESOLVE_SYMLINKS);
unknown's avatar
unknown committed
4551

unknown's avatar
unknown committed
4552
    if (argc == 2)
4553
    {
4554
      if (!default_service_handling(argv, MYSQL_SERVICENAME, MYSQL_SERVICENAME,
unknown's avatar
Merge  
unknown committed
4555
				   file_path, "", NULL))
4556
	return 0;
unknown's avatar
unknown committed
4557
      if (Service.IsService(argv[1]))        /* Start an optional service */
unknown's avatar
unknown committed
4558
      {
unknown's avatar
unknown committed
4559 4560 4561 4562 4563 4564
	/*
	  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.
	*/
4565
	if (my_strcasecmp(system_charset_info, argv[1],"mysql"))
4566
	  load_default_groups[load_default_groups_sz-2]= argv[1];
unknown's avatar
unknown committed
4567
        start_mode= 1;
4568
        Service.Init(argv[1], mysql_service);
unknown's avatar
unknown committed
4569 4570 4571 4572
        return 0;
      }
    }
    else if (argc == 3) /* install or remove any optional service */
unknown's avatar
unknown committed
4573
    {
unknown's avatar
Merge  
unknown committed
4574 4575
      if (!default_service_handling(argv, argv[2], argv[2], file_path, "",
                                    NULL))
4576 4577
	return 0;
      if (Service.IsService(argv[2]))
unknown's avatar
unknown committed
4578
      {
4579 4580 4581 4582
	/*
	  mysqld was started as
	  mysqld --defaults-file=my_path\my.ini service-name
	*/
4583
	use_opt_args=1;
4584
	opt_argc= 2;				// Skip service-name
4585 4586
	opt_argv=argv;
	start_mode= 1;
4587
	if (my_strcasecmp(system_charset_info, argv[2],"mysql"))
4588
	  load_default_groups[load_default_groups_sz-2]= argv[2];
4589
	Service.Init(argv[2], mysql_service);
4590
	return 0;
unknown's avatar
unknown committed
4591 4592
      }
    }
unknown's avatar
Merge  
unknown committed
4593
    else if (argc == 4 || argc == 5)
4594 4595
    {
      /*
unknown's avatar
Merge  
unknown committed
4596 4597 4598 4599 4600
        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.)
4601
      */
unknown's avatar
Merge  
unknown committed
4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616
      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;
4617
    }
unknown's avatar
unknown committed
4618
    else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME))
unknown's avatar
unknown committed
4619
    {
unknown's avatar
unknown committed
4620 4621 4622
      /* start the default service */
      start_mode= 1;
      Service.Init(MYSQL_SERVICENAME, mysql_service);
unknown's avatar
unknown committed
4623 4624 4625
      return 0;
    }
  }
unknown's avatar
unknown committed
4626
  /* Start as standalone server */
unknown's avatar
unknown committed
4627 4628 4629 4630 4631 4632 4633 4634
  Service.my_argc=argc;
  Service.my_argv=argv;
  mysql_service(NULL);
  return 0;
}
#endif


unknown's avatar
unknown committed
4635
/**
4636 4637 4638
  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.
*/
4639

unknown's avatar
Merge  
unknown committed
4640
static void bootstrap(FILE *file)
unknown's avatar
unknown committed
4641
{
4642
  DBUG_ENTER("bootstrap");
4643

4644
  THD *thd= new THD;
unknown's avatar
unknown committed
4645
  thd->bootstrap=1;
unknown's avatar
unknown committed
4646
  my_net_init(&thd->net,(st_vio*) 0);
unknown's avatar
unknown committed
4647
  thd->max_client_packet_length= thd->net.max_packet;
4648
  thd->security_ctx->master_access= ~(ulong)0;
unknown's avatar
unknown committed
4649
  thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
unknown's avatar
unknown committed
4650
  thread_count++;
4651 4652

  bootstrap_file=file;
unknown's avatar
unknown committed
4653
#ifndef EMBEDDED_LIBRARY			// TODO:  Enable this
4654 4655 4656
  if (pthread_create(&thd->real_id,&connection_attrib,handle_bootstrap,
		     (void*) thd))
  {
4657
    sql_print_warning("Can't create thread to handle bootstrap");
unknown's avatar
Merge  
unknown committed
4658 4659
    bootstrap_error=-1;
    DBUG_VOID_RETURN;
4660 4661 4662 4663 4664 4665 4666 4667 4668
  }
  /* Wait for thread to die */
  (void) pthread_mutex_lock(&LOCK_thread_count);
  while (thread_count)
  {
    (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
    DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
  }
  (void) pthread_mutex_unlock(&LOCK_thread_count);
unknown's avatar
unknown committed
4669 4670 4671 4672 4673
#else
  thd->mysql= 0;
  handle_bootstrap((void *)thd);
#endif

unknown's avatar
Merge  
unknown committed
4674
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
4675 4676
}

4677

unknown's avatar
unknown committed
4678 4679 4680 4681 4682 4683 4684
static bool read_init_file(char *file_name)
{
  FILE *file;
  DBUG_ENTER("read_init_file");
  DBUG_PRINT("enter",("name: %s",file_name));
  if (!(file=my_fopen(file_name,O_RDONLY,MYF(MY_WME))))
    return(1);
unknown's avatar
Merge  
unknown committed
4685
  bootstrap(file);
unknown's avatar
unknown committed
4686 4687 4688 4689 4690
  (void) my_fclose(file,MYF(MY_WME));
  return 0;
}


4691
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727

/*
   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!
*/
   
void handle_connection_in_main_thread(THD *thd)
{
  safe_mutex_assert_owner(&LOCK_thread_count);
  thread_cache_size=0;			// Safety
  threads.append(thd);
  (void) pthread_mutex_unlock(&LOCK_thread_count);
  handle_one_connection((void*) thd);
}


/*
  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++;
    pthread_cond_signal(&COND_thread_cache);
  }
  else
  {
4728
    char error_message_buff[MYSQL_ERRMSG_SIZE];
unknown's avatar
unknown committed
4729 4730 4731 4732 4733
    /* Create new thread to handle connection */
    int error;
    thread_created++;
    threads.append(thd);
    DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id));
4734
    thd->connect_utime= thd->start_utime= my_micro_time();
unknown's avatar
unknown committed
4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745
    if ((error=pthread_create(&thd->real_id,&connection_attrib,
                              handle_one_connection,
                              (void*) thd)))
    {
      /* purify: begin inspected */
      DBUG_PRINT("error",
                 ("Can't create thread to handle request (error %d)",
                  error));
      thread_count--;
      thd->killed= THD::KILL_CONNECTION;			// Safety
      (void) pthread_mutex_unlock(&LOCK_thread_count);
4746 4747 4748 4749 4750

      pthread_mutex_lock(&LOCK_connection_count);
      --connection_count;
      pthread_mutex_unlock(&LOCK_connection_count);

unknown's avatar
unknown committed
4751
      statistic_increment(aborted_connects,&LOCK_status);
4752 4753 4754 4755
      /* Can't use my_error() since store_globals has not been called. */
      my_snprintf(error_message_buff, sizeof(error_message_buff),
                  ER(ER_CANT_CREATE_THREAD), error);
      net_send_error(thd, ER_CANT_CREATE_THREAD, error_message_buff);
unknown's avatar
unknown committed
4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768
      (void) pthread_mutex_lock(&LOCK_thread_count);
      close_connection(thd,0,0);
      delete thd;
      (void) pthread_mutex_unlock(&LOCK_thread_count);
      return;
      /* purecov: end */
    }
  }
  (void) pthread_mutex_unlock(&LOCK_thread_count);
  DBUG_PRINT("info",("Thread created"));
}


unknown's avatar
unknown committed
4769
/**
4770 4771 4772 4773 4774 4775
  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
4776
    In single-threaded mode (\#define ONE_THREAD) connection will be
4777 4778
    handled inside this function.

unknown's avatar
unknown committed
4779
  @param[in,out] thd    Thread handle of future thread.
4780 4781
*/

unknown's avatar
unknown committed
4782 4783
static void create_new_thread(THD *thd)
{
4784
  NET *net=&thd->net;
unknown's avatar
unknown committed
4785 4786 4787 4788 4789
  DBUG_ENTER("create_new_thread");

  if (protocol_version > 9)
    net->return_errno=1;

4790 4791 4792 4793 4794 4795 4796 4797
  /*
    Don't allow too many connections. We roughly check here that we allow
    only (max_connections + 1) connections.
  */

  pthread_mutex_lock(&LOCK_connection_count);

  if (connection_count >= max_connections + 1 || abort_loop)
unknown's avatar
unknown committed
4798
  {
4799 4800
    pthread_mutex_unlock(&LOCK_connection_count);

unknown's avatar
unknown committed
4801
    DBUG_PRINT("error",("Too many connections"));
4802
    close_connection(thd, ER_CON_COUNT_ERROR, 1);
unknown's avatar
unknown committed
4803 4804 4805
    delete thd;
    DBUG_VOID_RETURN;
  }
4806 4807 4808

  ++connection_count;

4809 4810 4811
  if (connection_count > max_used_connections)
    max_used_connections= connection_count;

4812 4813 4814 4815
  pthread_mutex_unlock(&LOCK_connection_count);

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

4816
  pthread_mutex_lock(&LOCK_thread_count);
4817

4818 4819 4820 4821 4822
  /*
    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
4823
  thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
unknown's avatar
unknown committed
4824

4825 4826
  thread_count++;

unknown's avatar
unknown committed
4827
  thread_scheduler.add_connection(thd);
4828

unknown's avatar
unknown committed
4829 4830
  DBUG_VOID_RETURN;
}
4831 4832
#endif /* EMBEDDED_LIBRARY */

unknown's avatar
unknown committed
4833

unknown's avatar
unknown committed
4834 4835 4836 4837
#ifdef SIGNALS_DONT_BREAK_READ
inline void kill_broken_server()
{
  /* hack to get around signals ignored in syscalls for problem OS's */
unknown's avatar
unknown committed
4838 4839 4840 4841
  if (
#if !defined(__NETWARE__)
      unix_sock == INVALID_SOCKET ||
#endif
4842
      (!opt_disable_networking && ip_sock == INVALID_SOCKET))
unknown's avatar
unknown committed
4843 4844
  {
    select_thread_in_use = 0;
unknown's avatar
unknown committed
4845 4846
    /* The following call will never return */
    kill_server(IF_NETWARE(MYSQL_KILL_SIGNAL, (void*) MYSQL_KILL_SIGNAL));
unknown's avatar
unknown committed
4847 4848 4849 4850 4851 4852
  }
}
#define MAYBE_BROKEN_SYSCALL kill_broken_server();
#else
#define MAYBE_BROKEN_SYSCALL
#endif
unknown's avatar
unknown committed
4853 4854 4855

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

4856
#ifndef EMBEDDED_LIBRARY
4857
pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused)))
unknown's avatar
unknown committed
4858 4859 4860 4861 4862 4863 4864 4865
{
  my_socket sock,new_sock;
  uint error_count=0;
  uint max_used_connection= (uint) (max(ip_sock,unix_sock)+1);
  fd_set readFDs,clientFDs;
  THD *thd;
  struct sockaddr_in cAddr;
  int ip_flags=0,socket_flags=0,flags;
unknown's avatar
unknown committed
4866
  st_vio *vio_tmp;
unknown's avatar
unknown committed
4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882
  DBUG_ENTER("handle_connections_sockets");

  LINT_INIT(new_sock);

  (void) my_pthread_getprio(pthread_self());		// For debugging

  FD_ZERO(&clientFDs);
  if (ip_sock != INVALID_SOCKET)
  {
    FD_SET(ip_sock,&clientFDs);
#ifdef HAVE_FCNTL
    ip_flags = fcntl(ip_sock, F_GETFL, 0);
#endif
  }
#ifdef HAVE_SYS_UN_H
  FD_SET(unix_sock,&clientFDs);
unknown's avatar
unknown committed
4883
#ifdef HAVE_FCNTL
unknown's avatar
unknown committed
4884
  socket_flags=fcntl(unix_sock, F_GETFL, 0);
unknown's avatar
unknown committed
4885
#endif
unknown's avatar
unknown committed
4886 4887 4888
#endif

  DBUG_PRINT("general",("Waiting for connections."));
unknown's avatar
unknown committed
4889
  MAYBE_BROKEN_SYSCALL;
unknown's avatar
unknown committed
4890 4891 4892
  while (!abort_loop)
  {
    readFDs=clientFDs;
4893
#ifdef HPUX10
unknown's avatar
unknown committed
4894 4895 4896 4897 4898
    if (select(max_used_connection,(int*) &readFDs,0,0,0) < 0)
      continue;
#else
    if (select((int) max_used_connection,&readFDs,0,0,0) < 0)
    {
unknown's avatar
unknown committed
4899
      if (socket_errno != SOCKET_EINTR)
unknown's avatar
unknown committed
4900 4901
      {
	if (!select_errors++ && !abort_loop)	/* purecov: inspected */
unknown's avatar
unknown committed
4902
	  sql_print_error("mysqld: Got error %d from select",socket_errno); /* purecov: inspected */
unknown's avatar
unknown committed
4903
      }
unknown's avatar
unknown committed
4904
      MAYBE_BROKEN_SYSCALL
unknown's avatar
unknown committed
4905 4906
      continue;
    }
4907
#endif	/* HPUX10 */
unknown's avatar
unknown committed
4908
    if (abort_loop)
unknown's avatar
unknown committed
4909 4910
    {
      MAYBE_BROKEN_SYSCALL;
unknown's avatar
unknown committed
4911
      break;
unknown's avatar
unknown committed
4912
    }
unknown's avatar
unknown committed
4913

4914
    /* Is this a new connection request ? */
unknown's avatar
unknown committed
4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942
#ifdef HAVE_SYS_UN_H
    if (FD_ISSET(unix_sock,&readFDs))
    {
      sock = unix_sock;
      flags= socket_flags;
    }
    else
#endif
    {
      sock = ip_sock;
      flags= ip_flags;
    }

#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++)
    {
      size_socket length=sizeof(struct sockaddr_in);
      new_sock = accept(sock, my_reinterpret_cast(struct sockaddr *) (&cAddr),
			&length);
unknown's avatar
unknown committed
4943 4944 4945 4946 4947 4948 4949
#ifdef __NETWARE__ 
      // TODO: temporary fix, waiting for TCP/IP fix - DEFECT000303149
      if ((new_sock == INVALID_SOCKET) && (socket_errno == EINVAL))
      {
        kill_server(SIGTERM);
      }
#endif
unknown's avatar
unknown committed
4950 4951
      if (new_sock != INVALID_SOCKET ||
	  (socket_errno != SOCKET_EINTR && socket_errno != SOCKET_EAGAIN))
unknown's avatar
unknown committed
4952
	break;
unknown's avatar
unknown committed
4953
      MAYBE_BROKEN_SYSCALL;
unknown's avatar
unknown committed
4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965
#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
4966
    if (new_sock == INVALID_SOCKET)
unknown's avatar
unknown committed
4967 4968 4969
    {
      if ((error_count++ & 255) == 0)		// This can happen often
	sql_perror("Error in accept");
unknown's avatar
unknown committed
4970
      MAYBE_BROKEN_SYSCALL;
unknown's avatar
unknown committed
4971
      if (socket_errno == SOCKET_ENFILE || socket_errno == SOCKET_EMFILE)
unknown's avatar
unknown committed
4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982
	sleep(1);				// Give other threads some time
      continue;
    }

#ifdef HAVE_LIBWRAP
    {
      if (sock == ip_sock)
      {
	struct request_info req;
	signal(SIGCHLD, SIG_DFL);
	request_init(&req, RQ_DAEMON, libwrapName, RQ_FILE, new_sock, NULL);
4983 4984
	my_fromhost(&req);
	if (!my_hosts_access(&req))
unknown's avatar
unknown committed
4985
	{
unknown's avatar
unknown committed
4986 4987 4988 4989 4990
	  /*
	    This may be stupid but refuse() includes an exit(0)
	    which we surely don't want...
	    clean_exit() - same stupid thing ...
	  */
4991
	  syslog(deny_severity, "refused connect from %s",
4992
		 my_eval_client(&req));
unknown's avatar
unknown committed
4993

unknown's avatar
unknown committed
4994 4995 4996 4997 4998 4999
	  /*
	    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
5000 5001 5002
	  if (req.sink)
	    ((void (*)(int))req.sink)(req.fd);

5003
	  (void) shutdown(new_sock, SHUT_RDWR);
unknown's avatar
unknown committed
5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017
	  (void) closesocket(new_sock);
	  continue;
	}
      }
    }
#endif /* HAVE_LIBWRAP */

    {
      size_socket dummyLen;
      struct sockaddr dummy;
      dummyLen = sizeof(struct sockaddr);
      if (getsockname(new_sock,&dummy, &dummyLen) < 0)
      {
	sql_perror("Error on new connection socket");
5018
	(void) shutdown(new_sock, SHUT_RDWR);
unknown's avatar
unknown committed
5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029
	(void) closesocket(new_sock);
	continue;
      }
    }

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

    if (!(thd= new THD))
    {
5030
      (void) shutdown(new_sock, SHUT_RDWR);
unknown's avatar
unknown committed
5031
      VOID(closesocket(new_sock));
unknown's avatar
unknown committed
5032 5033 5034
      continue;
    }
    if (!(vio_tmp=vio_new(new_sock,
5035
			  sock == unix_sock ? VIO_TYPE_SOCKET :
unknown's avatar
unknown committed
5036
			  VIO_TYPE_TCPIP,
5037
			  sock == unix_sock ? VIO_LOCALHOST: 0)) ||
unknown's avatar
unknown committed
5038 5039
	my_net_init(&thd->net,vio_tmp))
    {
5040 5041 5042 5043 5044 5045 5046
      /*
        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
5047 5048
      else
      {
5049
	(void) shutdown(new_sock, SHUT_RDWR);
unknown's avatar
unknown committed
5050 5051 5052 5053 5054 5055
	(void) closesocket(new_sock);
      }
      delete thd;
      continue;
    }
    if (sock == unix_sock)
5056
      thd->security_ctx->host=(char*) my_localhost;
5057

unknown's avatar
unknown committed
5058 5059 5060
    create_new_thread(thd);
  }

5061
  decrement_handler_count();
unknown's avatar
unknown committed
5062 5063 5064 5065 5066
  DBUG_RETURN(0);
}


#ifdef __NT__
5067
pthread_handler_t handle_connections_namedpipes(void *arg)
unknown's avatar
unknown committed
5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079
{
  HANDLE hConnectedPipe;
  BOOL fConnected;
  THD *thd;
  my_thread_init();
  DBUG_ENTER("handle_connections_namedpipes");
  (void) my_pthread_getprio(pthread_self());		// For debugging

  DBUG_PRINT("general",("Waiting for named pipe connections."));
  while (!abort_loop)
  {
    /* wait for named pipe connection */
unknown's avatar
Merge  
unknown committed
5080
    fConnected = ConnectNamedPipe(hPipe, NULL);
unknown's avatar
unknown committed
5081 5082
    if (abort_loop)
      break;
unknown's avatar
unknown committed
5083
    if (!fConnected)
unknown's avatar
unknown committed
5084
      fConnected = GetLastError() == ERROR_PIPE_CONNECTED;
unknown's avatar
unknown committed
5085
    if (!fConnected)
unknown's avatar
unknown committed
5086
    {
unknown's avatar
Merge  
unknown committed
5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100
      CloseHandle(hPipe);
      if ((hPipe= CreateNamedPipe(pipe_name,
                                  PIPE_ACCESS_DUPLEX,
                                  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
5101 5102 5103 5104 5105 5106 5107
      {
	sql_perror("Can't create new named pipe!");
	break;					// Abort
      }
    }
    hConnectedPipe = hPipe;
    /* create new pipe for new connection */
5108
    if ((hPipe = CreateNamedPipe(pipe_name,
unknown's avatar
unknown committed
5109 5110 5111 5112 5113
				 PIPE_ACCESS_DUPLEX,
				 PIPE_TYPE_BYTE |
				 PIPE_READMODE_BYTE |
				 PIPE_WAIT,
				 PIPE_UNLIMITED_INSTANCES,
5114 5115
				 (int) global_system_variables.net_buffer_length,
				 (int) global_system_variables.net_buffer_length,
unknown's avatar
unknown committed
5116 5117 5118 5119 5120 5121 5122 5123 5124
				 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
5125
    if (!(thd = new THD))
unknown's avatar
unknown committed
5126
    {
unknown's avatar
Merge  
unknown committed
5127 5128
      DisconnectNamedPipe(hConnectedPipe);
      CloseHandle(hConnectedPipe);
unknown's avatar
unknown committed
5129 5130 5131 5132 5133
      continue;
    }
    if (!(thd->net.vio = vio_new_win32pipe(hConnectedPipe)) ||
	my_net_init(&thd->net, thd->net.vio))
    {
5134
      close_connection(thd, ER_OUT_OF_RESOURCES, 1);
unknown's avatar
unknown committed
5135 5136 5137
      delete thd;
      continue;
    }
5138 5139
    /* Host is unknown */
    thd->security_ctx->host= my_strdup(my_localhost, MYF(0));
unknown's avatar
unknown committed
5140 5141 5142
    create_new_thread(thd);
  }

5143
  decrement_handler_count();
unknown's avatar
unknown committed
5144 5145 5146 5147
  DBUG_RETURN(0);
}
#endif /* __NT__ */

5148

unknown's avatar
unknown committed
5149
#ifdef HAVE_SMEM
5150

unknown's avatar
unknown committed
5151 5152
/**
  Thread of shared memory's service.
5153

unknown's avatar
unknown committed
5154 5155
  @param arg                              Arguments of thread
*/
5156
pthread_handler_t handle_connections_shared_memory(void *arg)
5157
{
5158 5159
  /* file-mapping object, use for create shared memory */
  HANDLE handle_connect_file_map= 0;
5160
  char  *handle_connect_map= 0;                 // pointer on shared memory
5161 5162 5163
  HANDLE event_connect_answer= 0;
  ulong smem_buffer_length= shared_memory_buffer_length + 4;
  ulong connect_number= 1;
5164
  char *tmp= NULL;
5165 5166
  char *suffix_pos;
  char connect_number_char[22], *p;
5167
  const char *errmsg= 0;
5168
  SECURITY_ATTRIBUTES *sa_event= 0, *sa_mapping= 0;
5169 5170 5171 5172
  my_thread_init();
  DBUG_ENTER("handle_connections_shared_memorys");
  DBUG_PRINT("general",("Waiting for allocated shared memory."));

5173 5174 5175 5176 5177 5178
  /*
     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;

5179 5180 5181 5182 5183 5184 5185 5186
  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;

5187 5188 5189 5190 5191 5192 5193
  /*
    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)
  */
5194
  suffix_pos= strxmov(tmp,shared_memory_base_name,"_",NullS);
5195
  strmov(suffix_pos, "CONNECT_REQUEST");
5196 5197
  if ((smem_event_connect_request= CreateEvent(sa_event,
                                               FALSE, FALSE, tmp)) == 0)
5198
  {
5199
    errmsg= "Could not create request event";
5200 5201
    goto error;
  }
5202
  strmov(suffix_pos, "CONNECT_ANSWER");
5203
  if ((event_connect_answer= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
5204
  {
5205
    errmsg="Could not create answer event";
5206 5207
    goto error;
  }
5208
  strmov(suffix_pos, "CONNECT_DATA");
5209 5210 5211
  if ((handle_connect_file_map=
       CreateFileMapping(INVALID_HANDLE_VALUE, sa_mapping,
                         PAGE_READWRITE, 0, sizeof(connect_number), tmp)) == 0)
5212
  {
5213
    errmsg= "Could not create file mapping";
5214 5215
    goto error;
  }
5216 5217 5218
  if ((handle_connect_map= (char *)MapViewOfFile(handle_connect_file_map,
						  FILE_MAP_WRITE,0,0,
						  sizeof(DWORD))) == 0)
5219
  {
5220
    errmsg= "Could not create shared memory service";
5221 5222 5223 5224 5225
    goto error;
  }

  while (!abort_loop)
  {
5226
    /* Wait a request from client */
5227
    WaitForSingleObject(smem_event_connect_request,INFINITE);
5228

unknown's avatar
unknown committed
5229 5230 5231
    /*
       it can be after shutdown command
    */
unknown's avatar
Merge  
unknown committed
5232
    if (abort_loop)
unknown's avatar
unknown committed
5233
      goto error;
5234

5235 5236 5237 5238 5239 5240
    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
5241
    HANDLE event_conn_closed= 0;
5242
    THD *thd= 0;
5243

5244
    p= int10_to_str(connect_number, connect_number_char, 10);
5245 5246 5247 5248 5249 5250 5251 5252 5253 5254
    /*
      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);
5255
    strmov(suffix_pos, "DATA");
5256 5257 5258
    if ((handle_client_file_map=
         CreateFileMapping(INVALID_HANDLE_VALUE, sa_mapping,
                           PAGE_READWRITE, 0, smem_buffer_length, tmp)) == 0)
5259
    {
5260
      errmsg= "Could not create file mapping";
5261 5262
      goto errorconn;
    }
5263 5264 5265
    if ((handle_client_map= (char*)MapViewOfFile(handle_client_file_map,
						  FILE_MAP_WRITE,0,0,
						  smem_buffer_length)) == 0)
5266
    {
5267
      errmsg= "Could not create memory map";
5268 5269 5270
      goto errorconn;
    }
    strmov(suffix_pos, "CLIENT_WROTE");
5271
    if ((event_client_wrote= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
5272
    {
5273
      errmsg= "Could not create client write event";
5274 5275 5276
      goto errorconn;
    }
    strmov(suffix_pos, "CLIENT_READ");
5277
    if ((event_client_read= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
5278
    {
5279
      errmsg= "Could not create client read event";
5280 5281 5282
      goto errorconn;
    }
    strmov(suffix_pos, "SERVER_READ");
5283
    if ((event_server_read= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
5284
    {
5285
      errmsg= "Could not create server read event";
5286 5287 5288
      goto errorconn;
    }
    strmov(suffix_pos, "SERVER_WROTE");
5289 5290
    if ((event_server_wrote= CreateEvent(sa_event,
                                         FALSE, FALSE, tmp)) == 0)
5291
    {
5292
      errmsg= "Could not create server write event";
5293 5294
      goto errorconn;
    }
unknown's avatar
unknown committed
5295
    strmov(suffix_pos, "CONNECTION_CLOSED");
5296 5297
    if ((event_conn_closed= CreateEvent(sa_event,
                                        TRUE, FALSE, tmp)) == 0)
unknown's avatar
unknown committed
5298 5299 5300 5301
    {
      errmsg= "Could not create closed connection event";
      goto errorconn;
    }
5302
    if (abort_loop)
5303
      goto errorconn;
5304 5305 5306
    if (!(thd= new THD))
      goto errorconn;
    /* Send number of connection to client */
5307
    int4store(handle_connect_map, connect_number);
5308
    if (!SetEvent(event_connect_answer))
5309
    {
5310
      errmsg= "Could not send answer event";
5311 5312
      goto errorconn;
    }
5313
    /* Set event that client should receive data */
5314 5315
    if (!SetEvent(event_client_read))
    {
5316
      errmsg= "Could not set client to read mode";
5317 5318
      goto errorconn;
    }
5319
    if (!(thd->net.vio= vio_new_win32shared_memory(&thd->net,
unknown's avatar
unknown committed
5320 5321 5322 5323 5324 5325
                                                   handle_client_file_map,
                                                   handle_client_map,
                                                   event_client_wrote,
                                                   event_client_read,
                                                   event_server_wrote,
                                                   event_server_read,
unknown's avatar
unknown committed
5326
                                                   event_conn_closed)) ||
unknown's avatar
unknown committed
5327
                        my_net_init(&thd->net, thd->net.vio))
5328
    {
5329
      close_connection(thd, ER_OUT_OF_RESOURCES, 1);
5330 5331
      errmsg= 0;
      goto errorconn;
5332
    }
5333
    thd->security_ctx->host= my_strdup(my_localhost, MYF(0)); /* Host is unknown */
5334
    create_new_thread(thd);
5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346
    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);
    }
unknown's avatar
unknown committed
5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360
    if (handle_client_file_map) 
      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);
5361
    delete thd;
5362
  }
5363 5364

  /* End shared memory handling */
5365
error:
5366 5367 5368
  if (tmp)
    my_free(tmp, MYF(0));

5369 5370 5371 5372 5373 5374
  if (errmsg)
  {
    char buff[180];
    strxmov(buff, "Can't create shared memory service: ", errmsg, ".", NullS);
    sql_perror(buff);
  }
5375 5376
  my_security_attr_free(sa_event);
  my_security_attr_free(sa_mapping);
5377 5378 5379
  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);
5380
  if (smem_event_connect_request) CloseHandle(smem_event_connect_request);
5381 5382

  decrement_handler_count();
5383 5384 5385
  DBUG_RETURN(0);
}
#endif /* HAVE_SMEM */
5386
#endif /* EMBEDDED_LIBRARY */
unknown's avatar
unknown committed
5387

5388 5389 5390

/****************************************************************************
  Handle start options
unknown's avatar
unknown committed
5391 5392
******************************************************************************/

unknown's avatar
unknown committed
5393
enum options_mysqld
5394
{
5395 5396 5397
  OPT_ISAM_LOG=256,            OPT_SKIP_NEW, 
  OPT_SKIP_GRANT,              OPT_SKIP_LOCK, 
  OPT_ENABLE_LOCK,             OPT_USE_LOCKING,
5398 5399
  OPT_SOCKET,                  OPT_UPDATE_LOG,
  OPT_BIN_LOG,                 OPT_SKIP_RESOLVE,
5400 5401
  OPT_SKIP_NETWORKING,         OPT_BIN_LOG_INDEX,
  OPT_BIND_ADDRESS,            OPT_PID_FILE,
5402
  OPT_SKIP_PRIOR,              OPT_BIG_TABLES,
5403 5404
  OPT_STANDALONE,              OPT_ONE_THREAD,
  OPT_CONSOLE,                 OPT_LOW_PRIORITY_UPDATES,
5405
  OPT_SKIP_HOST_CACHE,         OPT_SHORT_LOG_FORMAT,
5406
  OPT_FLUSH,                   OPT_SAFE,
5407
  OPT_BOOTSTRAP,               OPT_SKIP_SHOW_DB,
unknown's avatar
unknown committed
5408
  OPT_STORAGE_ENGINE,          OPT_INIT_FILE,
5409
  OPT_DELAY_KEY_WRITE_ALL,     OPT_SLOW_QUERY_LOG,
5410
  OPT_DELAY_KEY_WRITE,	       OPT_CHARSETS_DIR,
5411 5412 5413
  OPT_MASTER_HOST,             OPT_MASTER_USER,
  OPT_MASTER_PASSWORD,         OPT_MASTER_PORT,
  OPT_MASTER_INFO_FILE,        OPT_MASTER_CONNECT_RETRY,
unknown's avatar
Merge  
unknown committed
5414
  OPT_MASTER_RETRY_COUNT,      OPT_LOG_TC, OPT_LOG_TC_SIZE,
unknown's avatar
unknown committed
5415 5416
  OPT_MASTER_SSL,              OPT_MASTER_SSL_KEY,
  OPT_MASTER_SSL_CERT,         OPT_MASTER_SSL_CAPATH,
unknown's avatar
unknown committed
5417
  OPT_MASTER_SSL_CIPHER,       OPT_MASTER_SSL_CA,
5418
  OPT_SQL_BIN_UPDATE_SAME,     OPT_REPLICATE_DO_DB,
5419 5420
  OPT_REPLICATE_IGNORE_DB,     OPT_LOG_SLAVE_UPDATES,
  OPT_BINLOG_DO_DB,            OPT_BINLOG_IGNORE_DB,
5421 5422 5423 5424 5425
  OPT_BINLOG_FORMAT,
#ifndef DBUG_OFF
  OPT_BINLOG_SHOW_XID,
#endif
  OPT_BINLOG_ROWS_EVENT_MAX_SIZE, 
5426 5427
  OPT_WANT_CORE,               OPT_CONCURRENT_INSERT,
  OPT_MEMLOCK,                 OPT_MYISAM_RECOVER,
5428
  OPT_REPLICATE_REWRITE_DB,    OPT_SERVER_ID,
unknown's avatar
unknown committed
5429
  OPT_SKIP_SLAVE_START,        OPT_SAFE_SHOW_DB, 
5430 5431
  OPT_SAFEMALLOC_MEM_LIMIT,    OPT_REPLICATE_DO_TABLE,
  OPT_REPLICATE_IGNORE_TABLE,  OPT_REPLICATE_WILD_DO_TABLE,
5432
  OPT_REPLICATE_WILD_IGNORE_TABLE, OPT_REPLICATE_SAME_SERVER_ID,
unknown's avatar
Merge  
unknown committed
5433
  OPT_DISCONNECT_SLAVE_EVENT_COUNT, OPT_TC_HEURISTIC_RECOVER,
5434
  OPT_ABORT_SLAVE_EVENT_COUNT,
5435
  OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
unknown's avatar
unknown committed
5436
  OPT_ENGINE_CONDITION_PUSHDOWN, OPT_NDB_CONNECTSTRING, 
unknown's avatar
unknown committed
5437
  OPT_NDB_USE_EXACT_COUNT, OPT_NDB_USE_TRANSACTIONS,
5438
  OPT_NDB_FORCE_SEND, OPT_NDB_AUTOINCREMENT_PREFETCH_SZ,
unknown's avatar
Merge  
unknown committed
5439 5440
  OPT_NDB_SHM, OPT_NDB_OPTIMIZED_NODE_SELECTION, OPT_NDB_CACHE_CHECK_TIME,
  OPT_NDB_MGMD, OPT_NDB_NODEID,
unknown's avatar
unknown committed
5441
  OPT_NDB_DISTRIBUTION,
5442
  OPT_NDB_INDEX_STAT_ENABLE,
unknown's avatar
unknown committed
5443 5444 5445
  OPT_NDB_EXTRA_LOGGING,
  OPT_NDB_REPORT_THRESH_BINLOG_EPOCH_SLIP,
  OPT_NDB_REPORT_THRESH_BINLOG_MEM_USAGE,
5446
  OPT_NDB_USE_COPYING_ALTER_TABLE,
5447
  OPT_SKIP_SAFEMALLOC,
unknown's avatar
Merge  
unknown committed
5448
  OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE,
5449 5450 5451 5452
  OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
  OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL,
  OPT_SAFE_USER_CREATE, OPT_SQL_MODE,
  OPT_HAVE_NAMED_PIPE,
5453
  OPT_DO_PSTACK, OPT_EVENT_SCHEDULER, OPT_REPORT_HOST,
5454
  OPT_REPORT_USER, OPT_REPORT_PASSWORD, OPT_REPORT_PORT,
5455
  OPT_SHOW_SLAVE_AUTH_INFO,
5456 5457 5458 5459 5460 5461 5462 5463 5464
  OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE,
  OPT_RPL_RECOVERY_RANK,OPT_INIT_RPL_ROLE,
  OPT_RELAY_LOG, OPT_RELAY_LOG_INDEX, OPT_RELAY_LOG_INFO_FILE,
  OPT_SLAVE_SKIP_ERRORS, OPT_DES_KEY_FILE, OPT_LOCAL_INFILE,
  OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA,
  OPT_SSL_CAPATH, OPT_SSL_CIPHER,
  OPT_BACK_LOG, OPT_BINLOG_CACHE_SIZE,
  OPT_CONNECT_TIMEOUT, OPT_DELAYED_INSERT_TIMEOUT,
  OPT_DELAYED_INSERT_LIMIT, OPT_DELAYED_QUEUE_SIZE,
unknown's avatar
unknown committed
5465
  OPT_FLUSH_TIME, OPT_FT_MIN_WORD_LEN, OPT_FT_BOOLEAN_SYNTAX,
5466
  OPT_FT_MAX_WORD_LEN, OPT_FT_QUERY_EXPANSION_LIMIT, OPT_FT_STOPWORD_FILE,
5467
  OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE,
5468 5469 5470
  OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_BLOCK_SIZE,
  OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_AGE_THRESHOLD,
  OPT_LONG_QUERY_TIME,
5471 5472 5473 5474
  OPT_LOWER_CASE_TABLE_NAMES, OPT_MAX_ALLOWED_PACKET,
  OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE,
  OPT_MAX_CONNECTIONS, OPT_MAX_CONNECT_ERRORS,
  OPT_MAX_DELAYED_THREADS, OPT_MAX_HEP_TABLE_SIZE,
5475 5476
  OPT_MAX_JOIN_SIZE, OPT_MAX_PREPARED_STMT_COUNT,
  OPT_MAX_RELAY_LOG_SIZE, OPT_MAX_SORT_LENGTH,
5477
  OPT_MAX_SEEKS_FOR_KEY, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS,
unknown's avatar
unknown committed
5478
  OPT_MAX_LENGTH_FOR_SORT_DATA,
unknown's avatar
unknown committed
5479
  OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE,
unknown's avatar
Merge  
unknown committed
5480
  OPT_MAX_ERROR_COUNT, OPT_MULTI_RANGE_COUNT, OPT_MYISAM_DATA_POINTER_SIZE,
5481 5482
  OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
  OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
5483
  OPT_MYISAM_USE_MMAP, OPT_MYISAM_REPAIR_THREADS,
5484
  OPT_MYISAM_STATS_METHOD,
5485 5486
  OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT,
  OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT,
5487
  OPT_OPEN_FILES_LIMIT,
unknown's avatar
unknown committed
5488
  OPT_PRELOAD_BUFFER_SIZE,
5489
  OPT_QUERY_CACHE_LIMIT, OPT_QUERY_CACHE_MIN_RES_UNIT, OPT_QUERY_CACHE_SIZE,
5490
  OPT_QUERY_CACHE_TYPE, OPT_QUERY_CACHE_WLOCK_INVALIDATE, OPT_RECORD_BUFFER,
unknown's avatar
unknown committed
5491 5492
  OPT_RECORD_RND_BUFFER, OPT_DIV_PRECINCREMENT, OPT_RELAY_LOG_SPACE_LIMIT,
  OPT_RELAY_LOG_PURGE,
5493
  OPT_SLAVE_NET_TIMEOUT, OPT_SLAVE_COMPRESSED_PROTOCOL, OPT_SLOW_LAUNCH_TIME,
5494
  OPT_SLAVE_TRANS_RETRIES, OPT_READONLY, OPT_DEBUGGING,
unknown's avatar
unknown committed
5495
  OPT_SORT_BUFFER, OPT_TABLE_OPEN_CACHE, OPT_TABLE_DEF_CACHE,
5496 5497
  OPT_THREAD_CONCURRENCY, OPT_THREAD_CACHE_SIZE,
  OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK,
5498
  OPT_WAIT_TIMEOUT,
unknown's avatar
merge  
unknown committed
5499
  OPT_ERROR_LOG_FILE,
5500
  OPT_DEFAULT_WEEK_FORMAT,
5501
  OPT_RANGE_ALLOC_BLOCK_SIZE, OPT_ALLOW_SUSPICIOUS_UDFS,
5502
  OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE,
5503
  OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE,
5504 5505 5506 5507
  OPT_SYNC_FRM, OPT_SYNC_BINLOG,
  OPT_SYNC_REPLICATION,
  OPT_SYNC_REPLICATION_SLAVE_ID,
  OPT_SYNC_REPLICATION_TIMEOUT,
5508
  OPT_ENABLE_SHARED_MEMORY,
unknown's avatar
unknown committed
5509
  OPT_SHARED_MEMORY_BASE_NAME,
5510
  OPT_OLD_PASSWORDS,
unknown's avatar
unknown committed
5511
  OPT_OLD_ALTER_TABLE,
unknown's avatar
unknown committed
5512
  OPT_EXPIRE_LOGS_DAYS,
5513
  OPT_GROUP_CONCAT_MAX_LEN,
5514
  OPT_DEFAULT_COLLATION,
5515
  OPT_CHARACTER_SET_CLIENT_HANDSHAKE,
unknown's avatar
unknown committed
5516
  OPT_CHARACTER_SET_FILESYSTEM,
5517
  OPT_LC_TIME_NAMES,
unknown's avatar
unknown committed
5518
  OPT_INIT_CONNECT,
unknown's avatar
unknown committed
5519
  OPT_INIT_SLAVE,
5520
  OPT_SECURE_AUTH,
5521 5522
  OPT_DATE_FORMAT,
  OPT_TIME_FORMAT,
unknown's avatar
unknown committed
5523
  OPT_DATETIME_FORMAT,
5524
  OPT_LOG_QUERIES_NOT_USING_INDEXES,
unknown's avatar
Merge  
unknown committed
5525
  OPT_DEFAULT_TIME_ZONE,
5526
  OPT_SYSDATE_IS_NOW,
unknown's avatar
Merge  
unknown committed
5527 5528 5529 5530
  OPT_OPTIMIZER_SEARCH_DEPTH,
  OPT_OPTIMIZER_PRUNE_LEVEL,
  OPT_UPDATABLE_VIEWS_WITH_LIMIT,
  OPT_SP_AUTOMATIC_PRIVILEGES,
5531
  OPT_MAX_SP_RECURSION_DEPTH,
unknown's avatar
Merge  
unknown committed
5532 5533 5534
  OPT_AUTO_INCREMENT, OPT_AUTO_INCREMENT_OFFSET,
  OPT_ENABLE_LARGE_PAGES,
  OPT_TIMED_MUTEXES,
unknown's avatar
unknown committed
5535
  OPT_OLD_STYLE_USER_LIMITS,
5536
  OPT_LOG_SLOW_ADMIN_STATEMENTS,
5537
  OPT_TABLE_LOCK_WAIT_TIMEOUT,
unknown's avatar
unknown committed
5538
  OPT_PLUGIN_LOAD,
5539
  OPT_PLUGIN_DIR,
5540
  OPT_LOG_OUTPUT,
5541
  OPT_PORT_OPEN_TIMEOUT,
5542
  OPT_PROFILING,
unknown's avatar
unknown committed
5543
  OPT_KEEP_FILES_ON_CREATE,
5544
  OPT_GENERAL_LOG,
5545
  OPT_SLOW_LOG,
unknown's avatar
unknown committed
5546
  OPT_THREAD_HANDLING,
5547
  OPT_INNODB_ROLLBACK_ON_TIMEOUT,
5548
  OPT_SECURE_FILE_PRIV,
5549 5550
  OPT_MIN_EXAMINED_ROW_LIMIT,
  OPT_LOG_SLOW_SLAVE_STATEMENTS,
5551 5552
  OPT_OLD_MODE,
  OPT_SLAVE_EXEC_MODE
unknown's avatar
unknown committed
5553
};
5554

5555 5556 5557

#define LONG_TIMEOUT ((ulong) 3600L*24L*365L)

unknown's avatar
unknown committed
5558
struct my_option my_long_options[] =
5559
{
unknown's avatar
unknown committed
5560
  {"help", '?', "Display this help and exit.", 
5561
   (uchar**) &opt_help, (uchar**) &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
unknown's avatar
unknown committed
5562 5563 5564 5565
   0, 0},
#ifdef HAVE_REPLICATION
  {"abort-slave-event-count", OPT_ABORT_SLAVE_EVENT_COUNT,
   "Option used by mysql-test for debugging and testing of replication.",
5566
   (uchar**) &abort_slave_event_count,  (uchar**) &abort_slave_event_count,
unknown's avatar
unknown committed
5567 5568
   0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif /* HAVE_REPLICATION */
5569
  {"allow-suspicious-udfs", OPT_ALLOW_SUSPICIOUS_UDFS,
unknown's avatar
unknown committed
5570 5571
   "Allows use of UDFs consisting of only one symbol xxx() "
   "without corresponding xxx_init() or xxx_deinit(). That also means "
5572 5573
   "that one can load any function from any library, for example exit() "
   "from libc.so",
5574
   (uchar**) &opt_allow_suspicious_udfs, (uchar**) &opt_allow_suspicious_udfs,
5575
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
5576 5577
  {"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax. This mode will also set transaction isolation level 'serializable'.", 0, 0, 0,
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
Merge  
unknown committed
5578 5579
  {"auto-increment-increment", OPT_AUTO_INCREMENT,
   "Auto-increment columns are incremented by this",
5580 5581
   (uchar**) &global_system_variables.auto_increment_increment,
   (uchar**) &max_system_variables.auto_increment_increment, 0, GET_ULONG,
unknown's avatar
Merge  
unknown committed
5582 5583 5584
   OPT_ARG, 1, 1, 65535, 0, 1, 0 },
  {"auto-increment-offset", OPT_AUTO_INCREMENT_OFFSET,
   "Offset added to Auto-increment columns. Used when auto-increment-increment != 1",
5585 5586
   (uchar**) &global_system_variables.auto_increment_offset,
   (uchar**) &max_system_variables.auto_increment_offset, 0, GET_ULONG, OPT_ARG,
unknown's avatar
Merge  
unknown committed
5587 5588 5589
   1, 1, 65535, 0, 1, 0 },
  {"automatic-sp-privileges", OPT_SP_AUTOMATIC_PRIVILEGES,
   "Creating and dropping stored procedures alters ACLs. Disable with --skip-automatic-sp-privileges.",
5590
   (uchar**) &sp_automatic_privileges, (uchar**) &sp_automatic_privileges,
unknown's avatar
Merge  
unknown committed
5591
   0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
5592 5593
  {"basedir", 'b',
   "Path to installation directory. All paths are usually resolved relative to this.",
5594
   (uchar**) &mysql_home_ptr, (uchar**) &mysql_home_ptr, 0, GET_STR, REQUIRED_ARG,
5595
   0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
5596
  {"big-tables", OPT_BIG_TABLES,
5597
   "Allow big result sets by saving all temporary sets on file (Solves most 'table full' errors).",
5598
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
5599
  {"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
5600
   (uchar**) &my_bind_addr_str, (uchar**) &my_bind_addr_str, 0, GET_STR,
unknown's avatar
unknown committed
5601
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5602
  {"binlog_format", OPT_BINLOG_FORMAT,
5603
   "Does not have any effect without '--log-bin'. "
5604
   "Tell the master the form of binary logging to use: either 'row' for "
5605 5606 5607 5608 5609
   "row-based binary logging, or 'statement' for statement-based binary "
   "logging, or 'mixed'. 'mixed' is statement-based binary logging except "
   "for those statements where only row-based is correct: those which "
   "involve user-defined functions (i.e. UDFs) or the UUID() function; for "
   "those, row-based binary logging is automatically used. "
unknown's avatar
unknown committed
5610
#ifdef HAVE_NDB_BINLOG
5611 5612
   "If ndbcluster is enabled and binlog_format is `mixed', the format switches"
   " to 'row' and back implicitly per each query accessing a NDB table."
5613
#endif
5614
   ,(uchar**) &opt_binlog_format, (uchar**) &opt_binlog_format,
5615
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5616 5617 5618
  {"binlog-do-db", OPT_BINLOG_DO_DB,
   "Tells the master it should log updates for the specified database, and exclude all others not explicitly mentioned.",
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
5619
  {"binlog-ignore-db", OPT_BINLOG_IGNORE_DB,
5620
   "Tells the master that updates to the given database should not be logged tothe binary log.",
5621
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5622 5623 5624 5625
  {"binlog-row-event-max-size", OPT_BINLOG_ROWS_EVENT_MAX_SIZE,
   "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.",
5626 5627
   (uchar**) &opt_binlog_rows_event_max_size, 
   (uchar**) &opt_binlog_rows_event_max_size, 0, 
5628 5629 5630 5631 5632
   GET_ULONG, REQUIRED_ARG, 
   /* def_value */ 1024, /* min_value */  256, /* max_value */ ULONG_MAX, 
   /* sub_size */     0, /* block_size */ 256, 
   /* app_type */ 0
  },
5633
#ifndef DISABLE_GRANT_OPTIONS
5634
  {"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts.", 0, 0, 0,
5635
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
5636
#endif
5637
  {"character-set-client-handshake", OPT_CHARACTER_SET_CLIENT_HANDSHAKE,
unknown's avatar
unknown committed
5638
   "Don't ignore client side character set value sent during handshake.",
5639 5640
   (uchar**) &opt_character_set_client_handshake,
   (uchar**) &opt_character_set_client_handshake,
5641
    0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
5642 5643
  {"character-set-filesystem", OPT_CHARACTER_SET_FILESYSTEM,
   "Set the filesystem character set.",
5644 5645
   (uchar**) &character_set_filesystem_name,
   (uchar**) &character_set_filesystem_name,
unknown's avatar
unknown committed
5646
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
unknown's avatar
unknown committed
5647
  {"character-set-server", 'C', "Set the default character set.",
5648
   (uchar**) &default_character_set_name, (uchar**) &default_character_set_name,
unknown's avatar
unknown committed
5649
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
unknown's avatar
unknown committed
5650
  {"character-sets-dir", OPT_CHARSETS_DIR,
5651 5652
   "Directory where character sets are.", (uchar**) &charsets_dir,
   (uchar**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
5653
  {"chroot", 'r', "Chroot mysqld daemon during startup.",
5654
   (uchar**) &mysqld_chroot, (uchar**) &mysqld_chroot, 0, GET_STR, REQUIRED_ARG,
unknown's avatar
unknown committed
5655 5656
   0, 0, 0, 0, 0, 0},
  {"collation-server", OPT_DEFAULT_COLLATION, "Set the default collation.",
5657
   (uchar**) &default_collation_name, (uchar**) &default_collation_name,
unknown's avatar
unknown committed
5658
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
unknown's avatar
Merge  
unknown committed
5659
  {"completion-type", OPT_COMPLETION_TYPE, "Default completion type.",
5660 5661
   (uchar**) &global_system_variables.completion_type,
   (uchar**) &max_system_variables.completion_type, 0, GET_ULONG,
unknown's avatar
Merge  
unknown committed
5662
   REQUIRED_ARG, 0, 0, 2, 0, 1, 0},
unknown's avatar
unknown committed
5663
  {"concurrent-insert", OPT_CONCURRENT_INSERT,
5664
   "Use concurrent insert with MyISAM. Disable with --concurrent-insert=0",
5665
   (uchar**) &myisam_concurrent_insert, (uchar**) &myisam_concurrent_insert,
5666
   0, GET_ULONG, OPT_ARG, 1, 0, 2, 0, 0, 0},
5667
  {"console", OPT_CONSOLE, "Write error output on screen; Don't remove the console window on windows.",
5668
   (uchar**) &opt_console, (uchar**) &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0,
5669
   0, 0, 0},
5670
  {"core-file", OPT_WANT_CORE, "Write core on errors.", 0, 0, 0, GET_NO_ARG,
5671
   NO_ARG, 0, 0, 0, 0, 0, 0},
5672 5673
  {"datadir", 'h', "Path to the database root.", (uchar**) &mysql_data_home,
   (uchar**) &mysql_data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5674
#ifndef DBUG_OFF
5675 5676
  {"debug", '#', "Debug log.", (uchar**) &default_dbug_option,
   (uchar**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
5677
#endif
unknown's avatar
unknown committed
5678
  {"default-character-set", 'C', "Set the default character set (deprecated option, use --character-set-server instead).",
5679
   (uchar**) &default_character_set_name, (uchar**) &default_character_set_name,
5680
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
unknown's avatar
unknown committed
5681
  {"default-collation", OPT_DEFAULT_COLLATION, "Set the default collation (deprecated option, use --collation-server instead).",
5682
   (uchar**) &default_collation_name, (uchar**) &default_collation_name,
5683
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
unknown's avatar
unknown committed
5684
  {"default-storage-engine", OPT_STORAGE_ENGINE,
unknown's avatar
unknown committed
5685
   "Set the default storage engine (table type) for tables.",
5686
   (uchar**)&default_storage_engine_str, (uchar**)&default_storage_engine_str,
unknown's avatar
unknown committed
5687 5688
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
  {"default-table-type", OPT_STORAGE_ENGINE,
unknown's avatar
unknown committed
5689
   "(deprecated) Use --default-storage-engine.",
5690
   (uchar**)&default_storage_engine_str, (uchar**)&default_storage_engine_str,
5691
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5692
  {"default-time-zone", OPT_DEFAULT_TIME_ZONE, "Set the default time zone.",
5693
   (uchar**) &default_tz_name, (uchar**) &default_tz_name,
5694
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
5695
  {"delay-key-write", OPT_DELAY_KEY_WRITE, "Type of DELAY_KEY_WRITE.",
5696 5697
   0,0,0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
  {"delay-key-write-for-all-tables", OPT_DELAY_KEY_WRITE_ALL,
5698
   "Don't flush key buffers between writes for any MyISAM table (Deprecated option, use --delay-key-write=all instead).",
5699
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
5700 5701 5702
#ifdef HAVE_OPENSSL
  {"des-key-file", OPT_DES_KEY_FILE,
   "Load keys for des_encrypt() and des_encrypt from given file.",
5703
   (uchar**) &des_key_file, (uchar**) &des_key_file, 0, GET_STR, REQUIRED_ARG,
unknown's avatar
unknown committed
5704 5705 5706 5707 5708
   0, 0, 0, 0, 0, 0},
#endif /* HAVE_OPENSSL */
#ifdef HAVE_REPLICATION
  {"disconnect-slave-event-count", OPT_DISCONNECT_SLAVE_EVENT_COUNT,
   "Option used by mysql-test for debugging and testing of replication.",
5709 5710
   (uchar**) &disconnect_slave_event_count,
   (uchar**) &disconnect_slave_event_count, 0, GET_INT, REQUIRED_ARG, 0, 0, 0,
unknown's avatar
unknown committed
5711 5712
   0, 0, 0},
#endif /* HAVE_REPLICATION */
5713
  {"enable-locking", OPT_ENABLE_LOCK,
5714
   "Deprecated option, use --external-locking instead.",
5715
   (uchar**) &opt_external_locking, (uchar**) &opt_external_locking,
5716
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
5717
#ifdef __NT__
5718
  {"enable-named-pipe", OPT_HAVE_NAMED_PIPE, "Enable the named pipe (NT).",
5719
   (uchar**) &opt_enable_named_pipe, (uchar**) &opt_enable_named_pipe, 0, GET_BOOL,
5720 5721
   NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
5722
#ifdef HAVE_STACK_TRACE_ON_SEGV
5723
  {"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure.",
5724
   (uchar**) &opt_do_pstack, (uchar**) &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0,
5725
   0, 0, 0, 0},
5726
#endif /* HAVE_STACK_TRACE_ON_SEGV */
unknown's avatar
Merge  
unknown committed
5727 5728 5729
  {"engine-condition-pushdown",
   OPT_ENGINE_CONDITION_PUSHDOWN,
   "Push supported query conditions to the storage engine.",
5730 5731
   (uchar**) &global_system_variables.engine_condition_pushdown,
   (uchar**) &global_system_variables.engine_condition_pushdown,
5732
   0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
5733
  /* See how it's handled in get_one_option() */
5734
  {"event-scheduler", OPT_EVENT_SCHEDULER, "Enable/disable the event scheduler.",
5735
   NULL,  NULL, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
5736 5737
  {"exit-info", 'T', "Used for debugging;  Use at your own risk!", 0, 0, 0,
   GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
5738
  {"external-locking", OPT_USE_LOCKING, "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.",
5739
   (uchar**) &opt_external_locking, (uchar**) &opt_external_locking,
unknown's avatar
unknown committed
5740
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
5741
  {"flush", OPT_FLUSH, "Flush tables to disk between SQL commands.", 0, 0, 0,
5742 5743 5744
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
  /* We must always support the next option to make scripts like mysqltest
     easier to do */
5745 5746
  {"gdb", OPT_DEBUGGING,
   "Set up signals usable for debugging",
5747
   (uchar**) &opt_debugging, (uchar**) &opt_debugging,
5748
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
5749
  {"general-log", OPT_GENERAL_LOG,
5750 5751
   "Enable|disable general log", (uchar**) &opt_log,
   (uchar**) &opt_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
Merge  
unknown committed
5752 5753 5754
#ifdef HAVE_LARGE_PAGES
  {"large-pages", OPT_ENABLE_LARGE_PAGES, "Enable support for large pages. \
Disable with --skip-large-pages.",
5755
   (uchar**) &opt_large_pages, (uchar**) &opt_large_pages, 0, GET_BOOL, NO_ARG, 0, 0, 0,
unknown's avatar
Merge  
unknown committed
5756 5757
   0, 0, 0},
#endif
unknown's avatar
unknown committed
5758
  {"init-connect", OPT_INIT_CONNECT, "Command(s) that are executed for each new connection",
5759
   (uchar**) &opt_init_connect, (uchar**) &opt_init_connect, 0, GET_STR_ALLOC,
unknown's avatar
unknown committed
5760
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5761
#ifndef DISABLE_GRANT_OPTIONS
unknown's avatar
unknown committed
5762
  {"init-file", OPT_INIT_FILE, "Read SQL commands from this file at startup.",
5763
   (uchar**) &opt_init_file, (uchar**) &opt_init_file, 0, GET_STR, REQUIRED_ARG,
unknown's avatar
unknown committed
5764
   0, 0, 0, 0, 0, 0},
5765
#endif
5766
  {"init-rpl-role", OPT_INIT_RPL_ROLE, "Set the replication role.", 0, 0, 0,
5767
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
5768
  {"init-slave", OPT_INIT_SLAVE, "Command(s) that are executed when a slave connects to this master",
5769
   (uchar**) &opt_init_slave, (uchar**) &opt_init_slave, 0, GET_STR_ALLOC,
unknown's avatar
unknown committed
5770
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5771
  {"language", 'L',
5772
   "Client error messages in given language. May be given as a full path.",
5773
   (uchar**) &language_ptr, (uchar**) &language_ptr, 0, GET_STR, REQUIRED_ARG,
5774
   0, 0, 0, 0, 0, 0},
5775 5776
  {"lc-time-names", OPT_LC_TIME_NAMES,
   "Set the language used for the month names and the days of the week.",
5777 5778
   (uchar**) &lc_time_names_name,
   (uchar**) &lc_time_names_name,
5779
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
5780
  {"local-infile", OPT_LOCAL_INFILE,
5781
   "Enable/disable LOAD DATA LOCAL INFILE (takes values 1|0).",
5782 5783
   (uchar**) &opt_local_infile,
   (uchar**) &opt_local_infile, 0, GET_BOOL, OPT_ARG,
5784
   1, 0, 0, 0, 0, 0},
5785 5786
  {"log", 'l', "Log connections and queries to file.", (uchar**) &opt_logname,
   (uchar**) &opt_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
5787
  {"log-bin", OPT_BIN_LOG,
unknown's avatar
Merge  
unknown committed
5788 5789 5790
   "Log update queries in binary format. Optional (but strongly recommended "
   "to avoid replication problems if server's hostname changes) argument "
   "should be the chosen location for the binary log files.",
5791
   (uchar**) &opt_bin_logname, (uchar**) &opt_bin_logname, 0, GET_STR_ALLOC,
unknown's avatar
unknown committed
5792
   OPT_ARG, 0, 0, 0, 0, 0, 0},
5793
  {"log-bin-index", OPT_BIN_LOG_INDEX,
5794
   "File that holds the names for last binary log files.",
5795
   (uchar**) &opt_binlog_index_name, (uchar**) &opt_binlog_index_name, 0, GET_STR,
5796
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5797 5798 5799 5800 5801 5802 5803 5804 5805
#ifndef TO_BE_REMOVED_IN_5_1_OR_6_0
  /*
    In 5.0.6 we introduced the below option, then in 5.0.16 we renamed it to
    log-bin-trust-function-creators but kept also the old name for
    compatibility; the behaviour was also changed to apply only to functions
    (and triggers). In a future release this old name could be removed.
  */
  {"log-bin-trust-routine-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
   "(deprecated) Use log-bin-trust-function-creators.",
5806
   (uchar**) &trust_function_creators, (uchar**) &trust_function_creators, 0,
5807 5808
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
5809 5810
  /*
    This option starts with "log-bin" to emphasize that it is specific of
5811
    binary logging.
5812
  */
5813
  {"log-bin-trust-function-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
5814
   "If equal to 0 (the default), then when --log-bin is used, creation of "
5815 5816
   "a stored function (or trigger) is allowed only to users having the SUPER privilege "
   "and only if this stored function (trigger) may not break binary logging."
5817 5818 5819
   "Note that if ALL connections to this server ALWAYS use row-based binary "
   "logging, the security issues do not exist and the binary logging cannot "
   "break, so you can safely set this to 1."
5820
   ,(uchar**) &trust_function_creators, (uchar**) &trust_function_creators, 0,
5821
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
Merge  
unknown committed
5822
  {"log-error", OPT_ERROR_LOG_FILE, "Error log file.",
5823
   (uchar**) &log_error_file_ptr, (uchar**) &log_error_file_ptr, 0, GET_STR,
unknown's avatar
unknown committed
5824
   OPT_ARG, 0, 0, 0, 0, 0, 0},
5825
  {"log-isam", OPT_ISAM_LOG, "Log all MyISAM changes to file.",
5826
   (uchar**) &myisam_log_filename, (uchar**) &myisam_log_filename, 0, GET_STR,
5827
   OPT_ARG, 0, 0, 0, 0, 0, 0},
5828 5829 5830
  {"log-long-format", '0',
   "Log some extra information to update log. Please note that this option is deprecated; see --log-short-format option.", 
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
5831 5832
#ifdef WITH_CSV_STORAGE_ENGINE
  {"log-output", OPT_LOG_OUTPUT,
5833
   "Syntax: log-output[=value[,value...]], where \"value\" could be TABLE, "
5834
   "FILE or NONE.",
5835
   (uchar**) &log_output_str, (uchar**) &log_output_str, 0,
5836 5837
   GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#endif
5838
  {"log-queries-not-using-indexes", OPT_LOG_QUERIES_NOT_USING_INDEXES,
5839
   "Log queries that are executed without benefit of any index to the slow log if it is open.",
5840
   (uchar**) &opt_log_queries_not_using_indexes, (uchar**) &opt_log_queries_not_using_indexes,
5841
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
5842 5843
  {"log-short-format", OPT_SHORT_LOG_FORMAT,
   "Don't log extra information to update and slow-query logs.",
5844
   (uchar**) &opt_short_log_format, (uchar**) &opt_short_log_format,
unknown's avatar
unknown committed
5845
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
5846
  {"log-slave-updates", OPT_LOG_SLAVE_UPDATES,
unknown's avatar
unknown committed
5847
   "Tells the slave to log the updates from the slave thread to the binary log. You will need to turn it on if you plan to daisy-chain the slaves.",
5848
   (uchar**) &opt_log_slave_updates, (uchar**) &opt_log_slave_updates, 0, GET_BOOL,
5849
   NO_ARG, 0, 0, 0, 0, 0, 0},
5850 5851
  {"log-slow-admin-statements", OPT_LOG_SLOW_ADMIN_STATEMENTS,
   "Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements to the slow log if it is open.",
5852 5853
   (uchar**) &opt_log_slow_admin_statements,
   (uchar**) &opt_log_slow_admin_statements,
5854
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
5855 5856 5857 5858 5859
 {"log-slow-slave-statements", OPT_LOG_SLOW_SLAVE_STATEMENTS,
  "Log slow statements executed by slave thread to the slow log if it is open.",
  (uchar**) &opt_log_slow_slave_statements,
  (uchar**) &opt_log_slow_slave_statements,
  0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
5860
  {"log-slow-queries", OPT_SLOW_QUERY_LOG,
5861
    "Log slow queries to a table or log file. Defaults logging to table mysql.slow_log or hostname-slow.log if --log-output=file is used. Must be enabled to activate other slow log options.",
5862
   (uchar**) &opt_slow_logname, (uchar**) &opt_slow_logname, 0, GET_STR, OPT_ARG,
unknown's avatar
unknown committed
5863
   0, 0, 0, 0, 0, 0},
unknown's avatar
Merge  
unknown committed
5864 5865 5866
  {"log-tc", OPT_LOG_TC,
   "Path to transaction coordinator log (used for transactions that affect "
   "more than one storage engine, when binary log is disabled)",
5867
   (uchar**) &opt_tc_log_file, (uchar**) &opt_tc_log_file, 0, GET_STR,
unknown's avatar
Merge  
unknown committed
5868
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5869
#ifdef HAVE_MMAP
unknown's avatar
Merge  
unknown committed
5870
  {"log-tc-size", OPT_LOG_TC_SIZE, "Size of transaction coordinator log.",
5871
   (uchar**) &opt_tc_log_size, (uchar**) &opt_tc_log_size, 0, GET_ULONG,
5872 5873
   REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, ULONG_MAX, 0,
   TC_LOG_PAGE_SIZE, 0},
5874
#endif
unknown's avatar
unknown committed
5875
  {"log-update", OPT_UPDATE_LOG,
unknown's avatar
Merge  
unknown committed
5876 5877
   "The update log is deprecated since version 5.0, is replaced by the binary \
log and this option justs turns on --log-bin instead.",
5878
   (uchar**) &opt_update_logname, (uchar**) &opt_update_logname, 0, GET_STR,
unknown's avatar
unknown committed
5879
   OPT_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
Merge  
unknown committed
5880
  {"log-warnings", 'W', "Log some not critical warnings to the log file.",
5881 5882
   (uchar**) &global_system_variables.log_warnings,
   (uchar**) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0,
unknown's avatar
unknown committed
5883
   0, 0, 0},
5884
  {"low-priority-updates", OPT_LOW_PRIORITY_UPDATES,
5885
   "INSERT/DELETE/UPDATE has lower priority than selects.",
5886 5887
   (uchar**) &global_system_variables.low_priority_updates,
   (uchar**) &max_system_variables.low_priority_updates,
unknown's avatar
unknown committed
5888
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
5889 5890
  {"master-connect-retry", OPT_MASTER_CONNECT_RETRY,
   "The number of seconds the slave thread will sleep before retrying to connect to the master in case the master goes down or the connection is lost.",
5891
   (uchar**) &master_connect_retry, (uchar**) &master_connect_retry, 0, GET_UINT,
unknown's avatar
unknown committed
5892
   REQUIRED_ARG, 60, 0, 0, 0, 0, 0},
5893
  {"master-host", OPT_MASTER_HOST,
5894
   "Master hostname or IP address for replication. If not set, the slave thread will not be started. Note that the setting of master-host will be ignored if there exists a valid master.info file.",
5895
   (uchar**) &master_host, (uchar**) &master_host, 0, GET_STR, REQUIRED_ARG, 0, 0,
5896
   0, 0, 0, 0},
unknown's avatar
unknown committed
5897 5898 5899
  {"master-info-file", OPT_MASTER_INFO_FILE,
   "The location and name of the file that remembers the master and where the I/O replication \
thread is in the master's binlogs.",
5900
   (uchar**) &master_info_file, (uchar**) &master_info_file, 0, GET_STR,
unknown's avatar
unknown committed
5901
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5902 5903
  {"master-password", OPT_MASTER_PASSWORD,
   "The password the slave thread will authenticate with when connecting to the master. If not set, an empty password is assumed.The value in master.info will take precedence if it can be read.",
5904
   (uchar**)&master_password, (uchar**)&master_password, 0,
unknown's avatar
unknown committed
5905
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5906
  {"master-port", OPT_MASTER_PORT,
5907
   "The port the master is listening on. If not set, the compiled setting of MYSQL_PORT is assumed. If you have not tinkered with configure options, this should be 3306. The value in master.info will take precedence if it can be read.",
5908
   (uchar**) &master_port, (uchar**) &master_port, 0, GET_UINT, REQUIRED_ARG,
5909 5910 5911
   MYSQL_PORT, 0, 0, 0, 0, 0},
  {"master-retry-count", OPT_MASTER_RETRY_COUNT,
   "The number of tries the slave will make to connect to the master before giving up.",
5912
   (uchar**) &master_retry_count, (uchar**) &master_retry_count, 0, GET_ULONG,
5913
   REQUIRED_ARG, 3600*24, 0, 0, 0, 0, 0},
5914
  {"master-ssl", OPT_MASTER_SSL,
unknown's avatar
unknown committed
5915
   "Enable the slave to connect to the master using SSL.",
5916
   (uchar**) &master_ssl, (uchar**) &master_ssl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
5917
   0, 0},
unknown's avatar
unknown committed
5918 5919
  {"master-ssl-ca", OPT_MASTER_SSL_CA,
   "Master SSL CA file. Only applies if you have enabled master-ssl.",
5920
   (uchar**) &master_ssl_ca, (uchar**) &master_ssl_ca, 0, GET_STR, OPT_ARG,
unknown's avatar
unknown committed
5921
   0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
5922
  {"master-ssl-capath", OPT_MASTER_SSL_CAPATH,
unknown's avatar
unknown committed
5923
   "Master SSL CA path. Only applies if you have enabled master-ssl.",
5924
   (uchar**) &master_ssl_capath, (uchar**) &master_ssl_capath, 0, GET_STR, OPT_ARG,
unknown's avatar
unknown committed
5925
   0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
5926 5927 5928
  {"master-ssl-cert", OPT_MASTER_SSL_CERT,
   "Master SSL certificate file name. Only applies if you have enabled \
master-ssl",
5929
   (uchar**) &master_ssl_cert, (uchar**) &master_ssl_cert, 0, GET_STR, OPT_ARG,
unknown's avatar
unknown committed
5930
   0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
5931
  {"master-ssl-cipher", OPT_MASTER_SSL_CIPHER,
unknown's avatar
unknown committed
5932
   "Master SSL cipher. Only applies if you have enabled master-ssl.",
5933
   (uchar**) &master_ssl_cipher, (uchar**) &master_ssl_capath, 0, GET_STR, OPT_ARG,
5934
   0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
5935 5936
  {"master-ssl-key", OPT_MASTER_SSL_KEY,
   "Master SSL keyfile name. Only applies if you have enabled master-ssl.",
5937
   (uchar**) &master_ssl_key, (uchar**) &master_ssl_key, 0, GET_STR, OPT_ARG,
unknown's avatar
unknown committed
5938 5939 5940
   0, 0, 0, 0, 0, 0},
  {"master-user", OPT_MASTER_USER,
   "The username the slave thread will use for authentication when connecting to the master. The user must have FILE privilege. If the master user is not set, user test is assumed. The value in master.info will take precedence if it can be read.",
5941
   (uchar**) &master_user, (uchar**) &master_user, 0, GET_STR, REQUIRED_ARG, 0, 0,
unknown's avatar
unknown committed
5942
   0, 0, 0, 0},
unknown's avatar
SCRUM  
unknown committed
5943
#ifdef HAVE_REPLICATION
5944
  {"max-binlog-dump-events", OPT_MAX_BINLOG_DUMP_EVENTS,
5945
   "Option used by mysql-test for debugging and testing of replication.",
5946
   (uchar**) &max_binlog_dump_events, (uchar**) &max_binlog_dump_events, 0,
5947
   GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
SCRUM  
unknown committed
5948
#endif /* HAVE_REPLICATION */
5949 5950
  {"memlock", OPT_MEMLOCK, "Lock mysqld in memory.", (uchar**) &locked_in_memory,
   (uchar**) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
5951 5952
  {"myisam-recover", OPT_MYISAM_RECOVER,
   "Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.",
5953
   (uchar**) &myisam_recover_options_str, (uchar**) &myisam_recover_options_str, 0,
unknown's avatar
unknown committed
5954
   GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
5955
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
5956 5957
  {"ndb-connectstring", OPT_NDB_CONNECTSTRING,
   "Connect string for ndbcluster.",
5958 5959
   (uchar**) &opt_ndb_connectstring,
   (uchar**) &opt_ndb_connectstring,
unknown's avatar
Merge  
unknown committed
5960 5961 5962
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
  {"ndb-mgmd-host", OPT_NDB_MGMD,
   "Set host and port for ndb_mgmd. Syntax: hostname[:port]",
5963 5964
   (uchar**) &opt_ndb_mgmd,
   (uchar**) &opt_ndb_mgmd,
5965
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
Merge  
unknown committed
5966 5967
  {"ndb-nodeid", OPT_NDB_NODEID,
   "Nodeid for this mysqlserver in the cluster.",
5968 5969
   (uchar**) &opt_ndb_nodeid,
   (uchar**) &opt_ndb_nodeid,
unknown's avatar
Merge  
unknown committed
5970
   0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
5971 5972
  {"ndb-autoincrement-prefetch-sz", OPT_NDB_AUTOINCREMENT_PREFETCH_SZ,
   "Specify number of autoincrement values that are prefetched.",
5973
   (uchar**) &global_system_variables.ndb_autoincrement_prefetch_sz,
5974
   (uchar**) &max_system_variables.ndb_autoincrement_prefetch_sz,
unknown's avatar
unknown committed
5975
   0, GET_ULONG, REQUIRED_ARG, 1, 1, 256, 0, 0, 0},
5976 5977 5978
  {"ndb-force-send", OPT_NDB_FORCE_SEND,
   "Force send of buffers to ndb immediately without waiting for "
   "other threads.",
5979 5980
   (uchar**) &global_system_variables.ndb_force_send,
   (uchar**) &global_system_variables.ndb_force_send,
5981
   0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
5982
  {"ndb_force_send", OPT_NDB_FORCE_SEND,
5983
   "same as --ndb-force-send.",
5984 5985
   (uchar**) &global_system_variables.ndb_force_send,
   (uchar**) &global_system_variables.ndb_force_send,
5986
   0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
5987 5988
  {"ndb-extra-logging", OPT_NDB_EXTRA_LOGGING,
   "Turn on more logging in the error log.",
5989 5990
   (uchar**) &ndb_extra_logging,
   (uchar**) &ndb_extra_logging,
unknown's avatar
unknown committed
5991 5992 5993 5994 5995 5996 5997
   0, GET_INT, OPT_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_NDB_BINLOG
  {"ndb-report-thresh-binlog-epoch-slip", OPT_NDB_REPORT_THRESH_BINLOG_EPOCH_SLIP,
   "Threshold on number of epochs to be behind before reporting binlog status. "
   "E.g. 3 means that if the difference between what epoch has been received "
   "from the storage nodes and what has been applied to the binlog is 3 or more, "
   "a status message will be sent to the cluster log.",
5998 5999
   (uchar**) &ndb_report_thresh_binlog_epoch_slip,
   (uchar**) &ndb_report_thresh_binlog_epoch_slip,
unknown's avatar
unknown committed
6000 6001 6002 6003 6004 6005
   0, GET_ULONG, REQUIRED_ARG, 3, 0, 256, 0, 0, 0},
  {"ndb-report-thresh-binlog-mem-usage", OPT_NDB_REPORT_THRESH_BINLOG_MEM_USAGE,
   "Threshold on percentage of free memory before reporting binlog status. E.g. "
   "10 means that if amount of available memory for receiving binlog data from "
   "the storage nodes goes below 10%, "
   "a status message will be sent to the cluster log.",
6006 6007
   (uchar**) &ndb_report_thresh_binlog_mem_usage,
   (uchar**) &ndb_report_thresh_binlog_mem_usage,
unknown's avatar
unknown committed
6008 6009
   0, GET_ULONG, REQUIRED_ARG, 10, 0, 100, 0, 0, 0},
#endif
6010 6011 6012
  {"ndb-use-exact-count", OPT_NDB_USE_EXACT_COUNT,
   "Use exact records count during query planning and for fast "
   "select count(*), disable for faster queries.",
6013 6014
   (uchar**) &global_system_variables.ndb_use_exact_count,
   (uchar**) &global_system_variables.ndb_use_exact_count,
6015
   0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
6016
  {"ndb_use_exact_count", OPT_NDB_USE_EXACT_COUNT,
6017
   "same as --ndb-use-exact-count.",
6018 6019
   (uchar**) &global_system_variables.ndb_use_exact_count,
   (uchar**) &global_system_variables.ndb_use_exact_count,
6020
   0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
6021 6022 6023
  {"ndb-use-transactions", OPT_NDB_USE_TRANSACTIONS,
   "Use transactions for large inserts, if enabled then large "
   "inserts will be split into several smaller transactions",
6024 6025
   (uchar**) &global_system_variables.ndb_use_transactions,
   (uchar**) &global_system_variables.ndb_use_transactions,
unknown's avatar
unknown committed
6026 6027 6028
   0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
  {"ndb_use_transactions", OPT_NDB_USE_TRANSACTIONS,
   "same as --ndb-use-transactions.",
6029 6030
   (uchar**) &global_system_variables.ndb_use_transactions,
   (uchar**) &global_system_variables.ndb_use_transactions,
unknown's avatar
unknown committed
6031
   0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
6032 6033
  {"ndb-shm", OPT_NDB_SHM,
   "Use shared memory connections when available.",
6034 6035
   (uchar**) &opt_ndb_shm,
   (uchar**) &opt_ndb_shm,
6036 6037 6038
   0, GET_BOOL, OPT_ARG, OPT_NDB_SHM_DEFAULT, 0, 0, 0, 0, 0},
  {"ndb-optimized-node-selection", OPT_NDB_OPTIMIZED_NODE_SELECTION,
   "Select nodes for transactions in a more optimal way.",
6039 6040
   (uchar**) &opt_ndb_optimized_node_selection,
   (uchar**) &opt_ndb_optimized_node_selection,
6041
   0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
unknown's avatar
Merge  
unknown committed
6042 6043
  { "ndb-cache-check-time", OPT_NDB_CACHE_CHECK_TIME,
    "A dedicated thread is created to, at the given millisecons interval, invalidate the query cache if another MySQL server in the cluster has changed the data in the database.",
6044
    (uchar**) &opt_ndb_cache_check_time, (uchar**) &opt_ndb_cache_check_time, 0, GET_ULONG, REQUIRED_ARG,
unknown's avatar
Merge  
unknown committed
6045
    0, 0, LONG_TIMEOUT, 0, 1, 0},
6046 6047
  {"ndb-index-stat-enable", OPT_NDB_INDEX_STAT_ENABLE,
   "Use ndb index statistics in query optimization.",
6048 6049
   (uchar**) &global_system_variables.ndb_index_stat_enable,
   (uchar**) &max_system_variables.ndb_index_stat_enable,
6050
   0, GET_BOOL, OPT_ARG, 0, 0, 1, 0, 0, 0},
6051
#endif
unknown's avatar
unknown committed
6052
  {"ndb-use-copying-alter-table",
6053
   OPT_NDB_USE_COPYING_ALTER_TABLE,
unknown's avatar
unknown committed
6054
   "Force ndbcluster to always copy tables at alter table (should only be used if on-line alter table fails).",
6055 6056
   (uchar**) &global_system_variables.ndb_use_copying_alter_table,
   (uchar**) &global_system_variables.ndb_use_copying_alter_table,
6057
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},  
6058
  {"new", 'n', "Use very new possible 'unsafe' functions.",
6059 6060
   (uchar**) &global_system_variables.new_mode,
   (uchar**) &max_system_variables.new_mode,
6061
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
6062
#ifdef NOT_YET
6063
  {"no-mix-table-types", OPT_NO_MIX_TYPE, "Don't allow commands with uses two different table types.",
6064
   (uchar**) &opt_no_mix_types, (uchar**) &opt_no_mix_types, 0, GET_BOOL, NO_ARG,
6065 6066
   0, 0, 0, 0, 0, 0},
#endif
unknown's avatar
unknown committed
6067 6068
  {"old-alter-table", OPT_OLD_ALTER_TABLE,
   "Use old, non-optimized alter table.",
6069 6070
   (uchar**) &global_system_variables.old_alter_table,
   (uchar**) &max_system_variables.old_alter_table, 0, GET_BOOL, NO_ARG,
unknown's avatar
unknown committed
6071
   0, 0, 0, 0, 0, 0},
6072
  {"old-passwords", OPT_OLD_PASSWORDS, "Use old password encryption method (needed for 4.0 and older clients).",
6073 6074
   (uchar**) &global_system_variables.old_passwords,
   (uchar**) &max_system_variables.old_passwords, 0, GET_BOOL, NO_ARG,
6075
   0, 0, 0, 0, 0, 0},
6076
  {"one-thread", OPT_ONE_THREAD,
unknown's avatar
unknown committed
6077 6078
   "(deprecated): Only use one thread (for debugging under Linux). Use thread-handling=no-threads instead",
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
Merge  
unknown committed
6079 6080
  {"old-style-user-limits", OPT_OLD_STYLE_USER_LIMITS,
   "Enable old-style user limits (before 5.0.3 user resources were counted per each user+host vs. per account)",
6081
   (uchar**) &opt_old_style_user_limits, (uchar**) &opt_old_style_user_limits,
unknown's avatar
Merge  
unknown committed
6082
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
6083
  {"pid-file", OPT_PID_FILE, "Pid file used by safe_mysqld.",
6084
   (uchar**) &pidfile_name_ptr, (uchar**) &pidfile_name_ptr, 0, GET_STR,
6085
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6086 6087 6088 6089 6090 6091
  {"port", 'P', "Port number to use for connection or 0 for default to, in "
   "order of preference, my.cnf, $MYSQL_TCP_PORT, "
#if MYSQL_PORT_DEFAULT == 0
   "/etc/services, "
#endif
   "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
6092
   (uchar**) &mysqld_port,
6093
   (uchar**) &mysqld_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6094 6095
  {"port-open-timeout", OPT_PORT_OPEN_TIMEOUT,
   "Maximum time in seconds to wait for the port to become free. "
6096 6097
   "(Default: no wait)", (uchar**) &mysqld_port_timeout,
   (uchar**) &mysqld_port_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6098
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
6099
  {"profiling_history_size", OPT_PROFILING, "Limit of query profiling memory",
6100 6101
   (uchar**) &global_system_variables.profiling_history_size,
   (uchar**) &max_system_variables.profiling_history_size,
unknown's avatar
unknown committed
6102
   0, GET_ULONG, REQUIRED_ARG, 15, 0, 100, 0, 0, 0},
6103
#endif
unknown's avatar
unknown committed
6104 6105
  {"relay-log", OPT_RELAY_LOG,
   "The location and name to use for relay logs.",
6106
   (uchar**) &opt_relay_logname, (uchar**) &opt_relay_logname, 0,
unknown's avatar
unknown committed
6107 6108 6109 6110
   GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
  {"relay-log-index", OPT_RELAY_LOG_INDEX,
   "The location and name to use for the file that keeps a list of the last \
relay logs.",
6111
   (uchar**) &opt_relaylog_index_name, (uchar**) &opt_relaylog_index_name, 0,
unknown's avatar
unknown committed
6112 6113 6114 6115
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
  {"relay-log-info-file", OPT_RELAY_LOG_INFO_FILE,
   "The location and name of the file that remembers where the SQL replication \
thread is in the relay logs.",
6116
   (uchar**) &relay_log_info_file, (uchar**) &relay_log_info_file, 0, GET_STR,
unknown's avatar
unknown committed
6117
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130
  {"replicate-do-db", OPT_REPLICATE_DO_DB,
   "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.%.",
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
  {"replicate-do-table", OPT_REPLICATE_DO_TABLE,
   "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},
  {"replicate-ignore-db", OPT_REPLICATE_IGNORE_DB,
   "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},
  {"replicate-ignore-table", OPT_REPLICATE_IGNORE_TABLE,
   "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-datbase updates, in contrast to replicate-ignore-db.",
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
  {"replicate-rewrite-db", OPT_REPLICATE_REWRITE_DB,
6131
   "Updates to a database with a different name than the original. Example: replicate-rewrite-db=master_db_name->slave_db_name.",
6132
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
6133
#ifdef HAVE_REPLICATION
6134 6135 6136 6137
  {"replicate-same-server-id", OPT_REPLICATE_SAME_SERVER_ID,
   "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.",
6138 6139
   (uchar**) &replicate_same_server_id,
   (uchar**) &replicate_same_server_id,
6140
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
6141
#endif
unknown's avatar
unknown committed
6142 6143 6144 6145 6146 6147
  {"replicate-wild-do-table", OPT_REPLICATE_WILD_DO_TABLE,
   "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.",
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
  {"replicate-wild-ignore-table", OPT_REPLICATE_WILD_IGNORE_TABLE,
   "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.",
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6148
  // In replication, we may need to tell the other servers how to connect
6149 6150
  {"report-host", OPT_REPORT_HOST,
   "Hostname or IP of the slave to be reported to to the master during slave registration. Will appear in the output of SHOW SLAVE HOSTS. Leave unset if you do not want the slave to register itself with the master. Note that it is not sufficient for the master to simply read the IP of the slave off the socket once the slave connects. Due to NAT and other routing issues, that IP may not be valid for connecting to the slave from the master or other hosts.",
6151
   (uchar**) &report_host, (uchar**) &report_host, 0, GET_STR, REQUIRED_ARG, 0, 0,
6152
   0, 0, 0, 0},
6153
  {"report-password", OPT_REPORT_PASSWORD, "Undocumented.",
6154
   (uchar**) &report_password, (uchar**) &report_password, 0, GET_STR,
6155 6156 6157
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
  {"report-port", OPT_REPORT_PORT,
   "Port for connecting to slave reported to the master during slave registration. Set it only if the slave is listening on a non-default port or if you have a special tunnel from the master or other clients to the slave. If not sure, leave this option unset.",
6158
   (uchar**) &report_port, (uchar**) &report_port, 0, GET_UINT, REQUIRED_ARG,
6159
   MYSQL_PORT, 0, 0, 0, 0, 0},
6160 6161
  {"report-user", OPT_REPORT_USER, "Undocumented.", (uchar**) &report_user,
   (uchar**) &report_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6162
  {"rpl-recovery-rank", OPT_RPL_RECOVERY_RANK, "Undocumented.",
6163
   (uchar**) &rpl_recovery_rank, (uchar**) &rpl_recovery_rank, 0, GET_ULONG,
6164 6165 6166
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
  {"safe-mode", OPT_SAFE, "Skip some optimize stages (for testing).",
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
6167
#ifndef TO_BE_DELETED
6168
  {"safe-show-database", OPT_SAFE_SHOW_DB,
unknown's avatar
unknown committed
6169
   "Deprecated option; use GRANT SHOW DATABASES instead...",
6170
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
6171
#endif
6172
  {"safe-user-create", OPT_SAFE_USER_CREATE,
6173
   "Don't allow new user creation by the user who has no write privileges to the mysql.user table.",
6174
   (uchar**) &opt_safe_user_create, (uchar**) &opt_safe_user_create, 0, GET_BOOL,
6175
   NO_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
6176 6177 6178
  {"safemalloc-mem-limit", OPT_SAFEMALLOC_MEM_LIMIT,
   "Simulate memory shortage when compiled with the --with-debug=full option.",
   0, 0, 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6179
  {"secure-auth", OPT_SECURE_AUTH, "Disallow authentication for accounts that have old (pre-4.1) passwords.",
6180
   (uchar**) &opt_secure_auth, (uchar**) &opt_secure_auth, 0, GET_BOOL, NO_ARG,
6181
   my_bool(0), 0, 0, 0, 0, 0},
6182 6183
  {"secure-file-priv", OPT_SECURE_FILE_PRIV,
   "Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files within specified directory",
6184
   (uchar**) &opt_secure_file_priv, (uchar**) &opt_secure_file_priv, 0,
6185
   GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6186
  {"server-id",	OPT_SERVER_ID,
6187
   "Uniquely identifies the server instance in the community of replication partners.",
6188
   (uchar**) &server_id, (uchar**) &server_id, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 0,
6189 6190 6191 6192
   0, 0, 0},
  {"set-variable", 'O',
   "Change the value of a variable. Please note that this option is deprecated;you can set variables directly with --variable-name=value.",
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6193
#ifdef HAVE_SMEM
unknown's avatar
unknown committed
6194
  {"shared-memory", OPT_ENABLE_SHARED_MEMORY,
6195
   "Enable the shared memory.",(uchar**) &opt_enable_shared_memory, (uchar**) &opt_enable_shared_memory,
unknown's avatar
unknown committed
6196 6197 6198 6199
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
#ifdef HAVE_SMEM
  {"shared-memory-base-name",OPT_SHARED_MEMORY_BASE_NAME,
6200
   "Base name of shared memory.", (uchar**) &shared_memory_base_name, (uchar**) &shared_memory_base_name,
6201 6202
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
unknown's avatar
unknown committed
6203
  {"show-slave-auth-info", OPT_SHOW_SLAVE_AUTH_INFO,
6204
   "Show user and password in SHOW SLAVE HOSTS on this master",
6205
   (uchar**) &opt_show_slave_auth_info, (uchar**) &opt_show_slave_auth_info, 0,
6206
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
6207
#ifndef DISABLE_GRANT_OPTIONS
6208 6209
  {"skip-grant-tables", OPT_SKIP_GRANT,
   "Start without grant tables. This gives all users FULL ACCESS to all tables!",
6210
   (uchar**) &opt_noacl, (uchar**) &opt_noacl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
6211
   0},
6212
#endif
unknown's avatar
unknown committed
6213 6214
  {"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},
6215
  {"skip-locking", OPT_SKIP_LOCK,
6216
   "Deprecated option, use --skip-external-locking instead.",
6217 6218
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
  {"skip-name-resolve", OPT_SKIP_RESOLVE,
6219
   "Don't resolve hostnames. All hostnames are IP's or 'localhost'.",
6220 6221 6222 6223 6224 6225
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
  {"skip-networking", OPT_SKIP_NETWORKING,
   "Don't allow connection with TCP/IP.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0,
   0, 0, 0},
  {"skip-new", OPT_SKIP_NEW, "Don't use new, possible wrong routines.",
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
6226 6227 6228 6229 6230 6231 6232
#ifndef DBUG_OFF
#ifdef SAFEMALLOC
  {"skip-safemalloc", OPT_SKIP_SAFEMALLOC,
   "Don't use the memory allocation checking.", 0, 0, 0, GET_NO_ARG, NO_ARG,
   0, 0, 0, 0, 0, 0},
#endif
#endif
6233
  {"skip-show-database", OPT_SKIP_SHOW_DB,
6234
   "Don't allow 'SHOW DATABASE' commands.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
6235 6236
   0, 0, 0, 0},
  {"skip-slave-start", OPT_SKIP_SLAVE_START,
6237 6238
   "If set, slave is not autostarted.", (uchar**) &opt_skip_slave_start,
   (uchar**) &opt_skip_slave_start, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
6239
  {"skip-stack-trace", OPT_SKIP_STACK_TRACE,
6240
   "Don't print a stack trace on failure.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
6241
   0, 0, 0, 0},
unknown's avatar
unknown committed
6242
  {"skip-symlink", OPT_SKIP_SYMLINKS, "Don't allow symlinking of tables. Deprecated option.  Use --skip-symbolic-links instead.",
6243 6244
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
  {"skip-thread-priority", OPT_SKIP_PRIOR,
unknown's avatar
unknown committed
6245 6246
   "Don't give threads different priorities.", 0, 0, 0, GET_NO_ARG, NO_ARG,
   DEFAULT_SKIP_THREAD_PRIORITY, 0, 0, 0, 0, 0},
unknown's avatar
SCRUM  
unknown committed
6247
#ifdef HAVE_REPLICATION
6248
  {"slave-load-tmpdir", OPT_SLAVE_LOAD_TMPDIR,
6249
   "The location where the slave should put its temporary files when \
6250
replicating a LOAD DATA INFILE command.",
6251
   (uchar**) &slave_load_tmpdir, (uchar**) &slave_load_tmpdir, 0, GET_STR_ALLOC,
6252 6253
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
  {"slave-skip-errors", OPT_SLAVE_SKIP_ERRORS,
6254
   "Tells the slave thread to continue replication when a query event returns an error from the provided list.",
6255
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6256 6257 6258
  {"slave-exec-mode", OPT_SLAVE_EXEC_MODE,
   "Modes for how replication events should be executed.  Legal values are STRICT (default) and IDEMPOTENT. In IDEMPOTENT mode, replication will not stop for operations that are idempotent. In STRICT mode, replication will stop on any unexpected difference between the master and the slave.",
   (uchar**) &slave_exec_mode_str, (uchar**) &slave_exec_mode_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6259
#endif
6260
  {"slow-query-log", OPT_SLOW_LOG,
6261 6262
   "Enable|disable slow query log", (uchar**) &opt_slow_log,
   (uchar**) &opt_slow_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
6263
  {"socket", OPT_SOCKET, "Socket file to use for connection.",
6264
   (uchar**) &mysqld_unix_port, (uchar**) &mysqld_unix_port, 0, GET_STR,
6265
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
6266 6267 6268
#ifdef HAVE_REPLICATION
  {"sporadic-binlog-dump-fail", OPT_SPORADIC_BINLOG_DUMP_FAIL,
   "Option used by mysql-test for debugging and testing of replication.",
6269 6270
   (uchar**) &opt_sporadic_binlog_dump_fail,
   (uchar**) &opt_sporadic_binlog_dump_fail, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
unknown's avatar
unknown committed
6271 6272
   0},
#endif /* HAVE_REPLICATION */
6273
  {"sql-bin-update-same", OPT_SQL_BIN_UPDATE_SAME,
unknown's avatar
Merge  
unknown committed
6274 6275
   "The update log is deprecated since version 5.0, is replaced by the binary \
log and this option does nothing anymore.",
6276
   0, 0, 0, GET_DISABLED, NO_ARG, 0, 0, 0, 0, 0, 0},
6277
  {"sql-mode", OPT_SQL_MODE,
6278
   "Syntax: sql-mode=option[,option[,option...]] where option can be one of: REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, ONLY_FULL_GROUP_BY, NO_UNSIGNED_SUBTRACTION.",
6279
   (uchar**) &sql_mode_str, (uchar**) &sql_mode_str, 0, GET_STR, REQUIRED_ARG, 0,
6280
   0, 0, 0, 0, 0},
6281
#ifdef HAVE_OPENSSL
6282 6283
#include "sslopt-longopts.h"
#endif
unknown's avatar
unknown committed
6284 6285 6286 6287 6288 6289
#ifdef __WIN__
  {"standalone", OPT_STANDALONE,
  "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.",
6290
   (uchar**) &my_use_symdir, (uchar**) &my_use_symdir, 0, GET_BOOL, NO_ARG,
6291 6292 6293 6294 6295
   /*
     The system call realpath() produces warnings under valgrind and
     purify. These are not suppressed: instead we disable symlinks
     option if compiled with valgrind support.
   */
6296
   IF_PURIFY(0,1), 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
6297 6298
  {"sysdate-is-now", OPT_SYSDATE_IS_NOW,
   "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.",
6299
   (uchar**) &global_system_variables.sysdate_is_now,
unknown's avatar
unknown committed
6300
   0, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
unknown's avatar
Merge  
unknown committed
6301
  {"tc-heuristic-recover", OPT_TC_HEURISTIC_RECOVER,
unknown's avatar
unknown committed
6302
   "Decision to use in heuristic recover process. Possible values are COMMIT or ROLLBACK.",
6303
   (uchar**) &opt_tc_heuristic_recover, (uchar**) &opt_tc_heuristic_recover,
unknown's avatar
Merge  
unknown committed
6304
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
6305
  {"temp-pool", OPT_TEMP_POOL,
6306
   "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.",
6307
   (uchar**) &use_temp_pool, (uchar**) &use_temp_pool, 0, GET_BOOL, NO_ARG, 1,
unknown's avatar
unknown committed
6308
   0, 0, 0, 0, 0},
unknown's avatar
Merge  
unknown committed
6309 6310
  {"timed_mutexes", OPT_TIMED_MUTEXES,
   "Specify whether to time mutexes (only InnoDB mutexes are currently supported)",
6311
   (uchar**) &timed_mutexes, (uchar**) &timed_mutexes, 0, GET_BOOL, NO_ARG, 0, 
unknown's avatar
Merge  
unknown committed
6312
    0, 0, 0, 0, 0},
unknown's avatar
unknown committed
6313 6314
  {"tmpdir", 't',
   "Path for temporary files. Several paths may be specified, separated by a "
6315
#if defined(__WIN__) || defined(__NETWARE__)
unknown's avatar
unknown committed
6316 6317 6318 6319 6320
   "semicolon (;)"
#else
   "colon (:)"
#endif
   ", in this case they are used in a round-robin fashion.",
6321 6322
   (uchar**) &opt_mysql_tmpdir,
   (uchar**) &opt_mysql_tmpdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6323
  {"transaction-isolation", OPT_TX_ISOLATION,
6324
   "Default transaction isolation level.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0,
unknown's avatar
unknown committed
6325
   0, 0, 0, 0, 0},
unknown's avatar
unknown committed
6326
  {"use-symbolic-links", 's', "Enable symbolic link support. Deprecated option; use --symbolic-links instead.",
6327
   (uchar**) &my_use_symdir, (uchar**) &my_use_symdir, 0, GET_BOOL, NO_ARG,
6328
   IF_PURIFY(0,1), 0, 0, 0, 0, 0},
6329
  {"user", 'u', "Run mysqld daemon as user.", 0, 0, 0, GET_STR, REQUIRED_ARG,
unknown's avatar
unknown committed
6330
   0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
6331
  {"verbose", 'v', "Used with --help option for detailed help",
6332
   (uchar**) &opt_verbose, (uchar**) &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
unknown's avatar
unknown committed
6333
   0, 0},
6334
  {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
6335
   NO_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
6336
  {"warnings", 'W', "Deprecated; use --log-warnings instead.",
6337
   (uchar**) &global_system_variables.log_warnings,
6338
   (uchar**) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG,
6339
   1, 0, ULONG_MAX, 0, 0, 0},
6340
  { "back_log", OPT_BACK_LOG,
6341
    "The number of outstanding connection requests MySQL can have. This comes into play when the main MySQL thread gets very many connection requests in a very short time.",
6342
    (uchar**) &back_log, (uchar**) &back_log, 0, GET_ULONG,
6343 6344 6345
    REQUIRED_ARG, 50, 1, 65535, 0, 1, 0 },
  {"binlog_cache_size", OPT_BINLOG_CACHE_SIZE,
   "The size of the cache to hold the SQL statements for the binary log during a transaction. If you often use big, multi-statement transactions you can increase this to get more performance.",
6346
   (uchar**) &binlog_cache_size, (uchar**) &binlog_cache_size, 0, GET_ULONG,
6347
   REQUIRED_ARG, 32*1024L, IO_SIZE, ULONG_MAX, 0, IO_SIZE, 0},
unknown's avatar
unknown committed
6348 6349
  {"bulk_insert_buffer_size", OPT_BULK_INSERT_BUFFER_SIZE,
   "Size of tree cache used in bulk insert optimisation. Note that this is a limit per thread!",
6350 6351
   (uchar**) &global_system_variables.bulk_insert_buff_size,
   (uchar**) &max_system_variables.bulk_insert_buff_size,
6352
   0, GET_ULONG, REQUIRED_ARG, 8192*1024, 0, ULONG_MAX, 0, 1, 0},
6353
  {"connect_timeout", OPT_CONNECT_TIMEOUT,
6354
   "The number of seconds the mysqld server is waiting for a connect packet before responding with 'Bad handshake'.",
6355
    (uchar**) &connect_timeout, (uchar**) &connect_timeout,
unknown's avatar
unknown committed
6356
   0, GET_ULONG, REQUIRED_ARG, CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1, 0 },
unknown's avatar
unknown committed
6357 6358
  { "date_format", OPT_DATE_FORMAT,
    "The DATE format (For future).",
6359 6360
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_DATE],
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_DATE],
unknown's avatar
unknown committed
6361 6362 6363
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
  { "datetime_format", OPT_DATETIME_FORMAT,
    "The DATETIME/TIMESTAMP format (for future).",
6364 6365
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME],
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME],
unknown's avatar
unknown committed
6366 6367 6368
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
  { "default_week_format", OPT_DEFAULT_WEEK_FORMAT,
    "The default week format used by WEEK() functions.",
6369 6370
    (uchar**) &global_system_variables.default_week_format,
    (uchar**) &max_system_variables.default_week_format,
unknown's avatar
unknown committed
6371
    0, GET_ULONG, REQUIRED_ARG, 0, 0, 7L, 0, 1, 0},
6372 6373
  {"delayed_insert_limit", OPT_DELAYED_INSERT_LIMIT,
   "After inserting delayed_insert_limit rows, the INSERT DELAYED handler will check if there are any SELECT statements pending. If so, it allows these to execute before continuing.",
6374
    (uchar**) &delayed_insert_limit, (uchar**) &delayed_insert_limit, 0, GET_ULONG,
6375
    REQUIRED_ARG, DELAYED_LIMIT, 1, ULONG_MAX, 0, 1, 0},
unknown's avatar
unknown committed
6376 6377
  {"delayed_insert_timeout", OPT_DELAYED_INSERT_TIMEOUT,
   "How long a INSERT DELAYED thread should wait for INSERT statements before terminating.",
6378
   (uchar**) &delayed_insert_timeout, (uchar**) &delayed_insert_timeout, 0,
unknown's avatar
unknown committed
6379
   GET_ULONG, REQUIRED_ARG, DELAYED_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
6380 6381
  { "delayed_queue_size", OPT_DELAYED_QUEUE_SIZE,
    "What size queue (in rows) should be allocated for handling INSERT DELAYED. If the queue becomes full, any client that does INSERT DELAYED will wait until there is room in the queue again.",
6382
    (uchar**) &delayed_queue_size, (uchar**) &delayed_queue_size, 0, GET_ULONG,
6383
    REQUIRED_ARG, DELAYED_QUEUE_SIZE, 1, ULONG_MAX, 0, 1, 0},
unknown's avatar
unknown committed
6384 6385
  {"div_precision_increment", OPT_DIV_PRECINCREMENT,
   "Precision of the result of '/' operator will be increased on that value.",
6386 6387
   (uchar**) &global_system_variables.div_precincrement,
   (uchar**) &max_system_variables.div_precincrement, 0, GET_ULONG,
unknown's avatar
unknown committed
6388
   REQUIRED_ARG, 4, 0, DECIMAL_MAX_SCALE, 0, 0, 0},
unknown's avatar
unknown committed
6389
  {"expire_logs_days", OPT_EXPIRE_LOGS_DAYS,
6390 6391
   "If non-zero, binary logs will be purged after expire_logs_days "
   "days; possible purges happen at startup and at binary log rotation.",
6392 6393
   (uchar**) &expire_logs_days,
   (uchar**) &expire_logs_days, 0, GET_ULONG,
unknown's avatar
unknown committed
6394
   REQUIRED_ARG, 0, 0, 99, 0, 1, 0},
6395 6396
  { "flush_time", OPT_FLUSH_TIME,
    "A dedicated thread is created to flush all tables at the given interval.",
6397
    (uchar**) &flush_time, (uchar**) &flush_time, 0, GET_ULONG, REQUIRED_ARG,
6398
    FLUSH_TIME, 0, LONG_TIMEOUT, 0, 1, 0},
unknown's avatar
unknown committed
6399 6400 6401 6402
  { "ft_boolean_syntax", OPT_FT_BOOLEAN_SYNTAX,
    "List of operators for MATCH ... AGAINST ( ... IN BOOLEAN MODE)",
    0, 0, 0, GET_STR,
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6403 6404
  { "ft_max_word_len", OPT_FT_MAX_WORD_LEN,
    "The maximum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable.",
6405
    (uchar**) &ft_max_word_len, (uchar**) &ft_max_word_len, 0, GET_ULONG,
6406
    REQUIRED_ARG, HA_FT_MAXCHARLEN, 10, HA_FT_MAXCHARLEN, 0, 1, 0},
unknown's avatar
unknown committed
6407 6408
  { "ft_min_word_len", OPT_FT_MIN_WORD_LEN,
    "The minimum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable.",
6409
    (uchar**) &ft_min_word_len, (uchar**) &ft_min_word_len, 0, GET_ULONG,
unknown's avatar
unknown committed
6410
    REQUIRED_ARG, 4, 1, HA_FT_MAXCHARLEN, 0, 1, 0},
6411 6412
  { "ft_query_expansion_limit", OPT_FT_QUERY_EXPANSION_LIMIT,
    "Number of best matches to use for query expansion",
6413
    (uchar**) &ft_query_expansion_limit, (uchar**) &ft_query_expansion_limit, 0, GET_ULONG,
6414
    REQUIRED_ARG, 20, 0, 1000, 0, 1, 0},
6415 6416
  { "ft_stopword_file", OPT_FT_STOPWORD_FILE,
    "Use stopwords from this file instead of built-in list.",
6417
    (uchar**) &ft_stopword_file, (uchar**) &ft_stopword_file, 0, GET_STR,
6418
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
6419 6420
  { "group_concat_max_len", OPT_GROUP_CONCAT_MAX_LEN,
    "The maximum length of the result of function  group_concat.",
6421 6422
    (uchar**) &global_system_variables.group_concat_max_len,
    (uchar**) &max_system_variables.group_concat_max_len, 0, GET_ULONG,
6423
    REQUIRED_ARG, 1024, 4, ULONG_MAX, 0, 1, 0},
6424 6425
  {"interactive_timeout", OPT_INTERACTIVE_TIMEOUT,
   "The number of seconds the server waits for activity on an interactive connection before closing it.",
6426 6427
   (uchar**) &global_system_variables.net_interactive_timeout,
   (uchar**) &max_system_variables.net_interactive_timeout, 0,
6428 6429 6430
   GET_ULONG, REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
  {"join_buffer_size", OPT_JOIN_BUFF_SIZE,
   "The size of the buffer that is used for full joins.",
6431 6432
   (uchar**) &global_system_variables.join_buff_size,
   (uchar**) &max_system_variables.join_buff_size, 0, GET_ULONG,
6433 6434
   REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ULONG_MAX,
   MALLOC_OVERHEAD, IO_SIZE, 0},
unknown's avatar
unknown committed
6435 6436
  {"keep_files_on_create", OPT_KEEP_FILES_ON_CREATE,
   "Don't overwrite stale .MYD and .MYI even if no directory is specified.",
unknown's avatar
unknown committed
6437 6438
   (uchar**) &global_system_variables.keep_files_on_create,
   (uchar**) &max_system_variables.keep_files_on_create,
unknown's avatar
unknown committed
6439
   0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
6440
  {"key_buffer_size", OPT_KEY_BUFFER_SIZE,
6441
   "The size of the buffer used for index blocks for MyISAM tables. Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford; 64M on a 256M machine that mainly runs MySQL is quite common.",
6442 6443
   (uchar**) &dflt_key_cache_var.param_buff_size,
   (uchar**) 0,
unknown's avatar
unknown committed
6444
   0, (GET_ULL | GET_ASK_ADDR),
6445
   REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, SIZE_T_MAX, MALLOC_OVERHEAD,
6446
   IO_SIZE, 0},
unknown's avatar
unknown committed
6447 6448
  {"key_cache_age_threshold", OPT_KEY_CACHE_AGE_THRESHOLD,
   "This characterizes the number of hits a hot block has to be untouched until it is considered aged enough to be downgraded to a warm block. This specifies the percentage ratio of that number of hits to the total number of blocks in key cache",
6449 6450
   (uchar**) &dflt_key_cache_var.param_age_threshold,
   (uchar**) 0,
unknown's avatar
unknown committed
6451
   0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG, 
6452
   300, 100, ULONG_MAX, 0, 100, 0},
unknown's avatar
unknown committed
6453 6454
  {"key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE,
   "The default size of key cache blocks",
6455 6456
   (uchar**) &dflt_key_cache_var.param_block_size,
   (uchar**) 0,
unknown's avatar
unknown committed
6457
   0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG,
6458
   KEY_CACHE_BLOCK_SIZE, 512, 1024 * 16, 0, 512, 0},
6459 6460
  {"key_cache_division_limit", OPT_KEY_CACHE_DIVISION_LIMIT,
   "The minimum percentage of warm blocks in key cache",
6461 6462
   (uchar**) &dflt_key_cache_var.param_division_limit,
   (uchar**) 0,
unknown's avatar
unknown committed
6463
   0, (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100,
6464
   1, 100, 0, 1, 0},
6465
  {"long_query_time", OPT_LONG_QUERY_TIME,
6466 6467 6468 6469
   "Log all queries that have taken more than long_query_time seconds to execute to file. "
   "The argument will be treated as a decimal value with microsecond precission.",
   (uchar**) &long_query_time, (uchar**) &long_query_time, 0, GET_DOUBLE,
   REQUIRED_ARG, 10, 0, LONG_TIMEOUT, 0, 0, 0},
6470
  {"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES,
unknown's avatar
unknown committed
6471
   "If set to 1 table names are stored in lowercase on disk and table names will be case-insensitive.  Should be set to 2 if you are using a case insensitive file system",
6472 6473
   (uchar**) &lower_case_table_names,
   (uchar**) &lower_case_table_names, 0, GET_UINT, OPT_ARG,
6474 6475 6476 6477 6478
#ifdef FN_NO_CASE_SENCE
    1
#else
    0
#endif
unknown's avatar
unknown committed
6479
   , 0, 2, 0, 1, 0},
6480 6481
  {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
   "Max packetlength to send/receive from to server.",
6482 6483
   (uchar**) &global_system_variables.max_allowed_packet,
   (uchar**) &max_system_variables.max_allowed_packet, 0, GET_ULONG,
unknown's avatar
unknown committed
6484
   REQUIRED_ARG, 1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
6485 6486
  {"max_binlog_cache_size", OPT_MAX_BINLOG_CACHE_SIZE,
   "Can be used to restrict the total size used to cache a multi-transaction query.",
6487
   (uchar**) &max_binlog_cache_size, (uchar**) &max_binlog_cache_size, 0,
6488
   GET_ULONG, REQUIRED_ARG, ULONG_MAX, IO_SIZE, ULONG_MAX, 0, IO_SIZE, 0},
6489
  {"max_binlog_size", OPT_MAX_BINLOG_SIZE,
6490 6491 6492
   "Binary log will be rotated automatically when the size exceeds this \
value. Will also apply to relay logs if max_relay_log_size is 0. \
The minimum value for this variable is 4096.",
6493
   (uchar**) &max_binlog_size, (uchar**) &max_binlog_size, 0, GET_ULONG,
6494
   REQUIRED_ARG, 1024*1024L*1024L, IO_SIZE, 1024*1024L*1024L, 0, IO_SIZE, 0},
6495 6496
  {"max_connect_errors", OPT_MAX_CONNECT_ERRORS,
   "If there is more than this number of interrupted connections from a host this host will be blocked from further connections.",
6497
   (uchar**) &max_connect_errors, (uchar**) &max_connect_errors, 0, GET_ULONG,
6498
    REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ULONG_MAX, 0, 1, 0},
6499 6500
  // Default max_connections of 151 is larger than Apache's default max
  // children, to avoid "too many connections" error in a common setup
unknown's avatar
unknown committed
6501
  {"max_connections", OPT_MAX_CONNECTIONS,
6502 6503
   "The number of simultaneous clients allowed.", (uchar**) &max_connections,
   (uchar**) &max_connections, 0, GET_ULONG, REQUIRED_ARG, 151, 1, 100000, 0, 1,
unknown's avatar
unknown committed
6504
   0},
6505
  {"max_delayed_threads", OPT_MAX_DELAYED_THREADS,
6506
   "Don't start more than this number of threads to handle INSERT DELAYED statements. If set to zero, which means INSERT DELAYED is not used.",
6507 6508
   (uchar**) &global_system_variables.max_insert_delayed_threads,
   (uchar**) &max_system_variables.max_insert_delayed_threads,
6509
   0, GET_ULONG, REQUIRED_ARG, 20, 0, 16384, 0, 1, 0},
6510
  {"max_error_count", OPT_MAX_ERROR_COUNT,
6511
   "Max number of errors/warnings to store for a statement.",
6512 6513
   (uchar**) &global_system_variables.max_error_count,
   (uchar**) &max_system_variables.max_error_count,
6514
   0, GET_ULONG, REQUIRED_ARG, DEFAULT_ERROR_COUNT, 0, 65535, 0, 1, 0},
6515 6516
  {"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE,
   "Don't allow creation of heap tables bigger than this.",
6517 6518
   (uchar**) &global_system_variables.max_heap_table_size,
   (uchar**) &max_system_variables.max_heap_table_size, 0, GET_ULL,
6519 6520
   REQUIRED_ARG, 16*1024*1024L, 16384, MAX_MEM_TABLE_SIZE,
   MALLOC_OVERHEAD, 1024, 0},
6521 6522
  {"max_join_size", OPT_MAX_JOIN_SIZE,
   "Joins that are probably going to read more than max_join_size records return an error.",
6523 6524
   (uchar**) &global_system_variables.max_join_size,
   (uchar**) &max_system_variables.max_join_size, 0, GET_HA_ROWS, REQUIRED_ARG,
6525
   ~0L, 1, ~0L, 0, 1, 0},
unknown's avatar
unknown committed
6526
   {"max_length_for_sort_data", OPT_MAX_LENGTH_FOR_SORT_DATA,
6527
    "Max number of bytes in sorted records.",
6528 6529
    (uchar**) &global_system_variables.max_length_for_sort_data,
    (uchar**) &max_system_variables.max_length_for_sort_data, 0, GET_ULONG,
unknown's avatar
unknown committed
6530
    REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
6531
  {"max_prepared_stmt_count", OPT_MAX_PREPARED_STMT_COUNT,
unknown's avatar
unknown committed
6532
   "Maximum number of prepared statements in the server.",
6533
   (uchar**) &max_prepared_stmt_count, (uchar**) &max_prepared_stmt_count,
6534
   0, GET_ULONG, REQUIRED_ARG, 16382, 0, 1*1024*1024, 0, 1, 0},
6535
  {"max_relay_log_size", OPT_MAX_RELAY_LOG_SIZE,
6536
   "If non-zero: relay log will be rotated automatically when the size exceeds this value; if zero (the default): when the size exceeds max_binlog_size. 0 excepted, the minimum value for this variable is 4096.",
6537
   (uchar**) &max_relay_log_size, (uchar**) &max_relay_log_size, 0, GET_ULONG,
6538
   REQUIRED_ARG, 0L, 0L, 1024*1024L*1024L, 0, IO_SIZE, 0},
6539 6540
  { "max_seeks_for_key", OPT_MAX_SEEKS_FOR_KEY,
    "Limit assumed max number of seeks when looking up rows based on a key",
6541 6542
    (uchar**) &global_system_variables.max_seeks_for_key,
    (uchar**) &max_system_variables.max_seeks_for_key, 0, GET_ULONG,
6543
    REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0 },
6544 6545
  {"max_sort_length", OPT_MAX_SORT_LENGTH,
   "The number of bytes to use when sorting BLOB or TEXT values (only the first max_sort_length bytes of each value are used; the rest are ignored).",
6546 6547
   (uchar**) &global_system_variables.max_sort_length,
   (uchar**) &max_system_variables.max_sort_length, 0, GET_ULONG,
6548
   REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
unknown's avatar
unknown committed
6549 6550
  {"max_sp_recursion_depth", OPT_MAX_SP_RECURSION_DEPTH,
   "Maximum stored procedure recursion depth. (discussed with docs).",
6551 6552
   (uchar**) &global_system_variables.max_sp_recursion_depth,
   (uchar**) &max_system_variables.max_sp_recursion_depth, 0, GET_ULONG,
unknown's avatar
unknown committed
6553
   OPT_ARG, 0, 0, 255, 0, 1, 0 },
6554 6555
  {"max_tmp_tables", OPT_MAX_TMP_TABLES,
   "Maximum number of temporary tables a client can keep open at a time.",
6556 6557
   (uchar**) &global_system_variables.max_tmp_tables,
   (uchar**) &max_system_variables.max_tmp_tables, 0, GET_ULONG,
6558
   REQUIRED_ARG, 32, 1, ULONG_MAX, 0, 1, 0},
6559 6560
  {"max_user_connections", OPT_MAX_USER_CONNECTIONS,
   "The maximum number of active connections for a single user (0 = no limit).",
6561
   (uchar**) &max_user_connections, (uchar**) &max_user_connections, 0, GET_UINT,
6562
   REQUIRED_ARG, 0, 1, UINT_MAX, 0, 1, 0},
6563 6564
  {"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
   "After this many write locks, allow some read locks to run in between.",
6565
   (uchar**) &max_write_lock_count, (uchar**) &max_write_lock_count, 0, GET_ULONG,
6566
   REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0},
6567 6568 6569 6570
  {"min_examined_row_limit", OPT_MIN_EXAMINED_ROW_LIMIT,
   "Don't log queries which examine less than min_examined_row_limit rows to file.",
   (uchar**) &global_system_variables.min_examined_row_limit,
   (uchar**) &max_system_variables.min_examined_row_limit, 0, GET_ULONG,
6571
  REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1L, 0},
unknown's avatar
Merge  
unknown committed
6572 6573
  {"multi_range_count", OPT_MULTI_RANGE_COUNT,
   "Number of key ranges to request at once.",
6574 6575
   (uchar**) &global_system_variables.multi_range_count,
   (uchar**) &max_system_variables.multi_range_count, 0,
6576
   GET_ULONG, REQUIRED_ARG, 256, 1, ULONG_MAX, 0, 1, 0},
6577
  {"myisam_block_size", OPT_MYISAM_BLOCK_SIZE,
6578
   "Block size to be used for MyISAM index pages.",
6579 6580
   (uchar**) &opt_myisam_block_size,
   (uchar**) &opt_myisam_block_size, 0, GET_ULONG, REQUIRED_ARG,
6581 6582
   MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, MI_MAX_KEY_BLOCK_LENGTH,
   0, MI_MIN_KEY_BLOCK_LENGTH, 0},
unknown's avatar
unknown committed
6583 6584
  {"myisam_data_pointer_size", OPT_MYISAM_DATA_POINTER_SIZE,
   "Default pointer size to be used for MyISAM tables.",
6585 6586
   (uchar**) &myisam_data_pointer_size,
   (uchar**) &myisam_data_pointer_size, 0, GET_ULONG, REQUIRED_ARG,
unknown's avatar
unknown committed
6587
   6, 2, 7, 0, 1, 0},
6588
  {"myisam_max_extra_sort_file_size", OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
unknown's avatar
unknown committed
6589
   "Deprecated option",
6590 6591
   (uchar**) &global_system_variables.myisam_max_extra_sort_file_size,
   (uchar**) &max_system_variables.myisam_max_extra_sort_file_size,
unknown's avatar
unknown committed
6592
   0, GET_ULL, REQUIRED_ARG, (ulonglong) MI_MAX_TEMP_LENGTH,
6593
   0, (ulonglong) MAX_FILE_SIZE, 0, 1, 0},
6594
  {"myisam_max_sort_file_size", OPT_MYISAM_MAX_SORT_FILE_SIZE,
6595
   "Don't use the fast sort index method to created index if the temporary file would get bigger than this.",
6596 6597
   (uchar**) &global_system_variables.myisam_max_sort_file_size,
   (uchar**) &max_system_variables.myisam_max_sort_file_size, 0,
6598 6599
   GET_ULL, REQUIRED_ARG, (longlong) LONG_MAX, 0, (ulonglong) MAX_FILE_SIZE,
   0, 1024*1024, 0},
6600 6601
  {"myisam_repair_threads", OPT_MYISAM_REPAIR_THREADS,
   "Number of threads to use when repairing MyISAM tables. The value of 1 disables parallel repair.",
6602 6603
   (uchar**) &global_system_variables.myisam_repair_threads,
   (uchar**) &max_system_variables.myisam_repair_threads, 0,
6604
   GET_ULONG, REQUIRED_ARG, 1, 1, ULONG_MAX, 0, 1, 0},
6605 6606
  {"myisam_sort_buffer_size", OPT_MYISAM_SORT_BUFFER_SIZE,
   "The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE.",
6607 6608
   (uchar**) &global_system_variables.myisam_sort_buff_size,
   (uchar**) &max_system_variables.myisam_sort_buff_size, 0,
6609
   GET_ULONG, REQUIRED_ARG, 8192*1024, 4, ~0L, 0, 1, 0},
unknown's avatar
unknown committed
6610
  {"myisam_use_mmap", OPT_MYISAM_USE_MMAP,
unknown's avatar
unknown committed
6611
   "Use memory mapping for reading and writing MyISAM tables",
6612 6613
   (uchar**) &opt_myisam_use_mmap,
   (uchar**) &opt_myisam_use_mmap, 0, GET_BOOL, NO_ARG, 0, 
unknown's avatar
unknown committed
6614
    0, 0, 0, 0, 0},
6615 6616
  {"myisam_stats_method", OPT_MYISAM_STATS_METHOD,
   "Specifies how MyISAM index statistics collection code should threat NULLs. "
6617 6618
   "Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), "
   "\"nulls_equal\" (emulate 4.0 behavior), and \"nulls_ignored\".",
6619
   (uchar**) &myisam_stats_method_str, (uchar**) &myisam_stats_method_str, 0,
6620
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6621
  {"net_buffer_length", OPT_NET_BUFFER_LENGTH,
6622
   "Buffer length for TCP/IP and socket communication.",
6623 6624
   (uchar**) &global_system_variables.net_buffer_length,
   (uchar**) &max_system_variables.net_buffer_length, 0, GET_ULONG,
unknown's avatar
unknown committed
6625
   REQUIRED_ARG, 16384, 1024, 1024*1024L, 0, 1024, 0},
6626 6627
  {"net_read_timeout", OPT_NET_READ_TIMEOUT,
   "Number of seconds to wait for more data from a connection before aborting the read.",
6628 6629
   (uchar**) &global_system_variables.net_read_timeout,
   (uchar**) &max_system_variables.net_read_timeout, 0, GET_ULONG,
6630
   REQUIRED_ARG, NET_READ_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
unknown's avatar
unknown committed
6631 6632
  {"net_retry_count", OPT_NET_RETRY_COUNT,
   "If a read on a communication port is interrupted, retry this many times before giving up.",
6633 6634
   (uchar**) &global_system_variables.net_retry_count,
   (uchar**) &max_system_variables.net_retry_count,0,
6635
   GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, ULONG_MAX, 0, 1, 0},
6636 6637
  {"net_write_timeout", OPT_NET_WRITE_TIMEOUT,
   "Number of seconds to wait for a block to be written to a connection  before aborting the write.",
6638 6639
   (uchar**) &global_system_variables.net_write_timeout,
   (uchar**) &max_system_variables.net_write_timeout, 0, GET_ULONG,
6640
   REQUIRED_ARG, NET_WRITE_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
unknown's avatar
unknown committed
6641
  { "old", OPT_OLD_MODE, "Use compatible behavior.", 
6642 6643
    (uchar**) &global_system_variables.old_mode,
    (uchar**) &max_system_variables.old_mode, 0, GET_BOOL, NO_ARG, 
6644
    0, 0, 0, 0, 0, 0},
6645 6646
  {"open_files_limit", OPT_OPEN_FILES_LIMIT,
   "If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of files.",
6647
   (uchar**) &open_files_limit, (uchar**) &open_files_limit, 0, GET_ULONG,
6648
   REQUIRED_ARG, 0, 0, OS_FILE_LIMIT, 0, 1, 0},
unknown's avatar
Merge  
unknown committed
6649 6650
  {"optimizer_prune_level", OPT_OPTIMIZER_PRUNE_LEVEL,
   "Controls the heuristic(s) applied during query optimization to prune less-promising partial plans from the optimizer search space. Meaning: 0 - do not apply any heuristic, thus perform exhaustive search; 1 - prune plans based on number of retrieved rows.",
6651 6652
   (uchar**) &global_system_variables.optimizer_prune_level,
   (uchar**) &max_system_variables.optimizer_prune_level,
unknown's avatar
Merge  
unknown committed
6653 6654 6655
   0, GET_ULONG, OPT_ARG, 1, 0, 1, 0, 1, 0},
  {"optimizer_search_depth", OPT_OPTIMIZER_SEARCH_DEPTH,
   "Maximum depth of search performed by the query optimizer. Values larger than the number of relations in a query result in better query plans, but take longer to compile a query. Smaller values than the number of tables in a relation result in faster optimization, but may produce very bad query plans. If set to 0, the system will automatically pick a reasonable value; if set to MAX_TABLES+2, the optimizer will switch to the original find_best (used for testing/comparison).",
6656 6657
   (uchar**) &global_system_variables.optimizer_search_depth,
   (uchar**) &max_system_variables.optimizer_search_depth,
unknown's avatar
Merge  
unknown committed
6658
   0, GET_ULONG, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0},
6659 6660
  {"plugin_dir", OPT_PLUGIN_DIR,
   "Directory for plugins.",
6661
   (uchar**) &opt_plugin_dir_ptr, (uchar**) &opt_plugin_dir_ptr, 0,
6662
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
unknown committed
6663 6664 6665
  {"plugin_load", OPT_PLUGIN_LOAD,
   "Optional colon separated list of plugins to load, where each plugin is "
   "identified by name and path to library seperated by an equals.",
6666
   (uchar**) &opt_plugin_load, (uchar**) &opt_plugin_load, 0,
unknown's avatar
unknown committed
6667
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6668
  {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
6669 6670 6671 6672
   "The size of the buffer that is allocated when preloading indexes",
   (uchar**) &global_system_variables.preload_buff_size,
   (uchar**) &max_system_variables.preload_buff_size, 0, GET_ULONG,
   REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0},
6673 6674
  {"query_alloc_block_size", OPT_QUERY_ALLOC_BLOCK_SIZE,
   "Allocation block size for query parsing and execution",
6675 6676
   (uchar**) &global_system_variables.query_alloc_block_size,
   (uchar**) &max_system_variables.query_alloc_block_size, 0, GET_ULONG,
6677
   REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
unknown's avatar
unknown committed
6678
#ifdef HAVE_QUERY_CACHE
6679 6680
  {"query_cache_limit", OPT_QUERY_CACHE_LIMIT,
   "Don't cache results that are bigger than this.",
6681
   (uchar**) &query_cache_limit, (uchar**) &query_cache_limit, 0, GET_ULONG,
6682
   REQUIRED_ARG, 1024*1024L, 0, ULONG_MAX, 0, 1, 0},
6683 6684
  {"query_cache_min_res_unit", OPT_QUERY_CACHE_MIN_RES_UNIT,
   "minimal size of unit in wich space for results is allocated (last unit will be trimed after writing all result data.",
6685
   (uchar**) &query_cache_min_res_unit, (uchar**) &query_cache_min_res_unit,
6686
   0, GET_ULONG, REQUIRED_ARG, QUERY_CACHE_MIN_RESULT_DATA_SIZE,
6687
   0, ULONG_MAX, 0, 1, 0},
6688 6689
  {"query_cache_size", OPT_QUERY_CACHE_SIZE,
   "The memory allocated to store results from old queries.",
6690
   (uchar**) &query_cache_size, (uchar**) &query_cache_size, 0, GET_ULONG,
unknown's avatar
unknown committed
6691 6692
   REQUIRED_ARG, 0, 0, (longlong) ULONG_MAX, 0, 1024, 0},
  {"query_cache_type", OPT_QUERY_CACHE_TYPE,
6693
   "0 = OFF = Don't cache or retrieve results. 1 = ON = Cache all results except SELECT SQL_NO_CACHE ... queries. 2 = DEMAND = Cache only SELECT SQL_CACHE ... queries.",
6694 6695
   (uchar**) &global_system_variables.query_cache_type,
   (uchar**) &max_system_variables.query_cache_type,
unknown's avatar
unknown committed
6696
   0, GET_ULONG, REQUIRED_ARG, 1, 0, 2, 0, 1, 0},
6697 6698
  {"query_cache_wlock_invalidate", OPT_QUERY_CACHE_WLOCK_INVALIDATE,
   "Invalidate queries in query cache on LOCK for write",
6699 6700
   (uchar**) &global_system_variables.query_cache_wlock_invalidate,
   (uchar**) &max_system_variables.query_cache_wlock_invalidate,
6701 6702
   0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
#endif /*HAVE_QUERY_CACHE*/
6703 6704
  {"query_prealloc_size", OPT_QUERY_PREALLOC_SIZE,
   "Persistent buffer for query parsing and execution",
6705 6706
   (uchar**) &global_system_variables.query_prealloc_size,
   (uchar**) &max_system_variables.query_prealloc_size, 0, GET_ULONG,
6707
   REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, QUERY_ALLOC_PREALLOC_SIZE,
6708
   ULONG_MAX, 0, 1024, 0},
unknown's avatar
unknown committed
6709 6710
  {"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE,
   "Allocation block size for storing ranges during optimization",
6711 6712
   (uchar**) &global_system_variables.range_alloc_block_size,
   (uchar**) &max_system_variables.range_alloc_block_size, 0, GET_ULONG,
6713 6714
   REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, ULONG_MAX,
   0, 1024, 0},
unknown's avatar
unknown committed
6715
  {"read_buffer_size", OPT_RECORD_BUFFER,
6716
   "Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value.",
6717 6718
   (uchar**) &global_system_variables.read_buff_size,
   (uchar**) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
6719
   128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, INT_MAX32, MALLOC_OVERHEAD, IO_SIZE,
6720
   0},
unknown's avatar
unknown committed
6721
  {"read_only", OPT_READONLY,
6722
   "Make all non-temporary tables read-only, with the exception for replication (slave) threads and users with the SUPER privilege",
6723 6724
   (uchar**) &opt_readonly,
   (uchar**) &opt_readonly,
unknown's avatar
unknown committed
6725
   0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
unknown's avatar
unknown committed
6726
  {"read_rnd_buffer_size", OPT_RECORD_RND_BUFFER,
6727
   "When reading rows in sorted order after a sort, the rows are read through this buffer to avoid a disk seeks. If not set, then it's set to the value of record_buffer.",
6728 6729
   (uchar**) &global_system_variables.read_rnd_buff_size,
   (uchar**) &max_system_variables.read_rnd_buff_size, 0,
unknown's avatar
unknown committed
6730
   GET_ULONG, REQUIRED_ARG, 256*1024L, IO_SIZE*2+MALLOC_OVERHEAD,
6731
   INT_MAX32, MALLOC_OVERHEAD, IO_SIZE, 0},
unknown's avatar
unknown committed
6732 6733
  {"record_buffer", OPT_RECORD_BUFFER,
   "Alias for read_buffer_size",
6734 6735
   (uchar**) &global_system_variables.read_buff_size,
   (uchar**) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
6736
   128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, INT_MAX32, MALLOC_OVERHEAD, IO_SIZE, 0},
unknown's avatar
SCRUM  
unknown committed
6737
#ifdef HAVE_REPLICATION
6738 6739
  {"relay_log_purge", OPT_RELAY_LOG_PURGE,
   "0 = do not purge relay logs. 1 = purge them as soon as they are no more needed.",
6740 6741
   (uchar**) &relay_log_purge,
   (uchar**) &relay_log_purge, 0, GET_BOOL, NO_ARG,
6742
   1, 0, 1, 0, 1, 0},
6743
  {"relay_log_space_limit", OPT_RELAY_LOG_SPACE_LIMIT,
6744
   "Maximum space to use for all relay logs.",
6745 6746
   (uchar**) &relay_log_space_limit,
   (uchar**) &relay_log_space_limit, 0, GET_ULL, REQUIRED_ARG, 0L, 0L,
6747
   (longlong) ULONG_MAX, 0, 1, 0},
6748
  {"slave_compressed_protocol", OPT_SLAVE_COMPRESSED_PROTOCOL,
6749
   "Use compression on master/slave protocol.",
6750 6751
   (uchar**) &opt_slave_compressed_protocol,
   (uchar**) &opt_slave_compressed_protocol,
6752
   0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
6753
  {"slave_net_timeout", OPT_SLAVE_NET_TIMEOUT,
unknown's avatar
unknown committed
6754
   "Number of seconds to wait for more data from a master/slave connection before aborting the read.",
6755
   (uchar**) &slave_net_timeout, (uchar**) &slave_net_timeout, 0,
6756
   GET_ULONG, REQUIRED_ARG, SLAVE_NET_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
6757 6758 6759 6760
  {"slave_transaction_retries", OPT_SLAVE_TRANS_RETRIES,
   "Number of times the slave SQL thread will retry a transaction in case "
   "it failed with a deadlock or elapsed lock wait timeout, "
   "before giving up and stopping.",
6761
   (uchar**) &slave_trans_retries, (uchar**) &slave_trans_retries, 0,
6762
   GET_ULONG, REQUIRED_ARG, 10L, 0L, (longlong) ULONG_MAX, 0, 1, 0},
6763
#endif /* HAVE_REPLICATION */
6764 6765
  {"slow_launch_time", OPT_SLOW_LAUNCH_TIME,
   "If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented.",
6766
   (uchar**) &slow_launch_time, (uchar**) &slow_launch_time, 0, GET_ULONG,
6767
   REQUIRED_ARG, 2L, 0L, LONG_TIMEOUT, 0, 1, 0},
unknown's avatar
unknown committed
6768
  {"sort_buffer_size", OPT_SORT_BUFFER,
6769
   "Each thread that needs to do a sort allocates a buffer of this size.",
6770 6771
   (uchar**) &global_system_variables.sortbuff_size,
   (uchar**) &max_system_variables.sortbuff_size, 0, GET_ULONG, REQUIRED_ARG,
6772 6773
   MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, ~0L, MALLOC_OVERHEAD,
   1, 0},
6774
  {"sync-binlog", OPT_SYNC_BINLOG,
6775 6776
   "Synchronously flush binary log to disk after every #th event. "
   "Use 0 (default) to disable synchronous flushing.",
6777
   (uchar**) &sync_binlog_period, (uchar**) &sync_binlog_period, 0, GET_ULONG,
6778
   REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1, 0},
6779
  {"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default.",
6780
   (uchar**) &opt_sync_frm, (uchar**) &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0,
6781
   0, 0, 0, 0},
unknown's avatar
unknown committed
6782 6783
  {"table_cache", OPT_TABLE_OPEN_CACHE,
   "Deprecated; use --table_open_cache instead.",
6784
   (uchar**) &table_cache_size, (uchar**) &table_cache_size, 0, GET_ULONG,
6785
   REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
unknown's avatar
unknown committed
6786 6787
  {"table_definition_cache", OPT_TABLE_DEF_CACHE,
   "The number of cached table definitions.",
6788
   (uchar**) &table_def_size, (uchar**) &table_def_size,
unknown's avatar
unknown committed
6789 6790
   0, GET_ULONG, REQUIRED_ARG, TABLE_DEF_CACHE_DEFAULT, TABLE_DEF_CACHE_MIN,
   512*1024L, 0, 1, 0},
unknown's avatar
unknown committed
6791 6792
  {"table_open_cache", OPT_TABLE_OPEN_CACHE,
   "The number of cached open tables.",
6793
   (uchar**) &table_cache_size, (uchar**) &table_cache_size, 0, GET_ULONG,
6794
   REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
unknown's avatar
unknown committed
6795 6796 6797
  {"table_lock_wait_timeout", OPT_TABLE_LOCK_WAIT_TIMEOUT,
   "Timeout in seconds to wait for a table level lock before returning an "
   "error. Used only if the connection has active cursors.",
6798
   (uchar**) &table_lock_wait_timeout, (uchar**) &table_lock_wait_timeout,
6799
   0, GET_ULONG, REQUIRED_ARG, 50, 1, 1024 * 1024 * 1024, 0, 1, 0},
6800 6801
  {"thread_cache_size", OPT_THREAD_CACHE_SIZE,
   "How many threads we should keep in a cache for reuse.",
6802
   (uchar**) &thread_cache_size, (uchar**) &thread_cache_size, 0, GET_ULONG,
6803
   REQUIRED_ARG, 0, 0, 16384, 0, 1, 0},
unknown's avatar
unknown committed
6804 6805
  {"thread_concurrency", OPT_THREAD_CONCURRENCY,
   "Permits the application to give the threads system a hint for the desired number of threads that should be run at the same time.",
6806
   (uchar**) &concurrency, (uchar**) &concurrency, 0, GET_ULONG, REQUIRED_ARG,
unknown's avatar
unknown committed
6807
   DEFAULT_CONCURRENCY, 1, 512, 0, 1, 0},
unknown's avatar
unknown committed
6808 6809 6810
#if HAVE_POOL_OF_THREADS == 1
  {"thread_pool_size", OPT_THREAD_CACHE_SIZE,
   "How many threads we should create to handle query requests in case of 'thread_handling=pool-of-threads'",
6811
   (uchar**) &thread_pool_size, (uchar**) &thread_pool_size, 0, GET_ULONG,
unknown's avatar
unknown committed
6812 6813
   REQUIRED_ARG, 20, 1, 16384, 0, 1, 0},
#endif
unknown's avatar
unknown committed
6814
  {"thread_stack", OPT_THREAD_STACK,
6815 6816
   "The stack size for each thread.", (uchar**) &my_thread_stack_size,
   (uchar**) &my_thread_stack_size, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK,
6817
   1024L*128L, ULONG_MAX, 0, 1024, 0},
unknown's avatar
unknown committed
6818 6819
  { "time_format", OPT_TIME_FORMAT,
    "The TIME format (for future).",
6820 6821
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_TIME],
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_TIME],
unknown's avatar
unknown committed
6822
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
6823
  {"tmp_table_size", OPT_TMP_TABLE_SIZE,
6824 6825
   "If an internal in-memory temporary table exceeds this size, MySQL will"
   " automatically convert it to an on-disk MyISAM table.",
6826 6827
   (uchar**) &global_system_variables.tmp_table_size,
   (uchar**) &max_system_variables.tmp_table_size, 0, GET_ULL,
unknown's avatar
unknown committed
6828
   REQUIRED_ARG, 16*1024*1024L, 1024, MAX_MEM_TABLE_SIZE, 0, 1, 0},
6829
  {"transaction_alloc_block_size", OPT_TRANS_ALLOC_BLOCK_SIZE,
6830
   "Allocation block size for transactions to be stored in binary log",
6831 6832
   (uchar**) &global_system_variables.trans_alloc_block_size,
   (uchar**) &max_system_variables.trans_alloc_block_size, 0, GET_ULONG,
6833
   REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
6834
  {"transaction_prealloc_size", OPT_TRANS_PREALLOC_SIZE,
6835
   "Persistent buffer for transactions to be stored in binary log",
6836 6837
   (uchar**) &global_system_variables.trans_prealloc_size,
   (uchar**) &max_system_variables.trans_prealloc_size, 0, GET_ULONG,
6838
   REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
unknown's avatar
unknown committed
6839 6840 6841 6842
  {"thread_handling", OPT_THREAD_HANDLING,
   "Define threads usage for handling queries:  "
   "one-thread-per-connection or no-threads", 0, 0,
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
unknown's avatar
Merge  
unknown committed
6843 6844
  {"updatable_views_with_limit", OPT_UPDATABLE_VIEWS_WITH_LIMIT,
   "1 = YES = Don't issue an error message (warning only) if a VIEW without presence of a key of the underlying table is used in queries with a LIMIT clause for updating. 0 = NO = Prohibit update of a VIEW, which does not contain a key of the underlying table and the query uses a LIMIT clause (usually get from GUI tools).",
6845 6846
   (uchar**) &global_system_variables.updatable_views_with_limit,
   (uchar**) &max_system_variables.updatable_views_with_limit,
unknown's avatar
Merge  
unknown committed
6847
   0, GET_ULONG, REQUIRED_ARG, 1, 0, 1, 0, 1, 0},
6848
  {"wait_timeout", OPT_WAIT_TIMEOUT,
6849
   "The number of seconds the server waits for activity on a connection before closing it.",
6850 6851
   (uchar**) &global_system_variables.net_wait_timeout,
   (uchar**) &max_system_variables.net_wait_timeout, 0, GET_ULONG,
6852 6853
   REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT),
   0, 1, 0},
6854
  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
6855
};
unknown's avatar
unknown committed
6856

6857
static int show_question(THD *thd, SHOW_VAR *var, char *buff)
6858
{
6859
  var->type= SHOW_LONGLONG;
6860 6861 6862 6863
  var->value= (char *)&thd->query_id;
  return 0;
}

6864
static int show_net_compression(THD *thd, SHOW_VAR *var, char *buff)
6865
{
6866
  var->type= SHOW_MY_BOOL;
6867 6868 6869 6870
  var->value= (char *)&thd->net.compress;
  return 0;
}

6871
static int show_starttime(THD *thd, SHOW_VAR *var, char *buff)
6872
{
6873
  var->type= SHOW_LONG;
6874
  var->value= buff;
unknown's avatar
unknown committed
6875
  *((long *)buff)= (long) (thd->query_start() - server_start_time);
6876 6877 6878
  return 0;
}

6879
#ifdef COMMUNITY_SERVER
6880 6881 6882 6883 6884 6885 6886
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;
}
6887
#endif
6888

6889
#ifdef HAVE_REPLICATION
6890
static int show_rpl_status(THD *thd, SHOW_VAR *var, char *buff)
6891
{
6892
  var->type= SHOW_CHAR;
6893 6894 6895 6896
  var->value= const_cast<char*>(rpl_status_type[(int)rpl_status]);
  return 0;
}

6897
static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff)
6898
{
6899
  var->type= SHOW_MY_BOOL;
6900
  pthread_mutex_lock(&LOCK_active_mi);
6901 6902 6903
  var->value= buff;
  *((my_bool *)buff)= (my_bool) (active_mi && active_mi->slave_running &&
                                 active_mi->rli.slave_running);
6904 6905 6906 6907
  pthread_mutex_unlock(&LOCK_active_mi);
  return 0;
}

6908
static int show_slave_retried_trans(THD *thd, SHOW_VAR *var, char *buff)
6909 6910 6911 6912 6913 6914 6915 6916
{
  /*
    TODO: with multimaster, have one such counter per line in
    SHOW SLAVE STATUS, and have the sum over all lines here.
  */
  pthread_mutex_lock(&LOCK_active_mi);
  if (active_mi)
  {
6917
    var->type= SHOW_LONG;
6918 6919 6920 6921 6922 6923
    var->value= buff;
    pthread_mutex_lock(&active_mi->rli.data_lock);
    *((long *)buff)= (long)active_mi->rli.retried_trans;
    pthread_mutex_unlock(&active_mi->rli.data_lock);
  }
  else
6924
    var->type= SHOW_UNDEF;
6925 6926 6927 6928 6929
  pthread_mutex_unlock(&LOCK_active_mi);
  return 0;
}
#endif /* HAVE_REPLICATION */

6930
static int show_open_tables(THD *thd, SHOW_VAR *var, char *buff)
6931
{
6932
  var->type= SHOW_LONG;
6933 6934 6935 6936 6937
  var->value= buff;
  *((long *)buff)= (long)cached_open_tables();
  return 0;
}

unknown's avatar
unknown committed
6938 6939 6940 6941 6942 6943 6944 6945 6946 6947
static int show_prepared_stmt_count(THD *thd, SHOW_VAR *var, char *buff)
{
  var->type= SHOW_LONG;
  var->value= buff;
  pthread_mutex_lock(&LOCK_prepared_stmt_count);
  *((long *)buff)= (long)prepared_stmt_count;
  pthread_mutex_unlock(&LOCK_prepared_stmt_count);
  return 0;
}

6948
static int show_table_definitions(THD *thd, SHOW_VAR *var, char *buff)
6949
{
6950
  var->type= SHOW_LONG;
6951 6952 6953 6954 6955 6956 6957
  var->value= buff;
  *((long *)buff)= (long)cached_table_definitions();
  return 0;
}

#ifdef HAVE_OPENSSL
/* Functions relying on CTX */
6958
static int show_ssl_ctx_sess_accept(THD *thd, SHOW_VAR *var, char *buff)
6959
{
6960
  var->type= SHOW_LONG;
6961 6962 6963 6964 6965 6966
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_accept(ssl_acceptor_fd->ssl_context));
  return 0;
}

6967
static int show_ssl_ctx_sess_accept_good(THD *thd, SHOW_VAR *var, char *buff)
6968
{
6969
  var->type= SHOW_LONG;
6970 6971 6972 6973 6974 6975
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_accept_good(ssl_acceptor_fd->ssl_context));
  return 0;
}

6976
static int show_ssl_ctx_sess_connect_good(THD *thd, SHOW_VAR *var, char *buff)
6977
{
6978
  var->type= SHOW_LONG;
6979 6980 6981 6982 6983 6984
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_connect_good(ssl_acceptor_fd->ssl_context));
  return 0;
}

6985
static int show_ssl_ctx_sess_accept_renegotiate(THD *thd, SHOW_VAR *var, char *buff)
6986
{
6987
  var->type= SHOW_LONG;
6988 6989 6990 6991 6992 6993
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context));
  return 0;
}

6994
static int show_ssl_ctx_sess_connect_renegotiate(THD *thd, SHOW_VAR *var, char *buff)
6995
{
6996
  var->type= SHOW_LONG;
6997 6998 6999 7000 7001 7002
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_connect_renegotiate(ssl_acceptor_fd->ssl_context));
  return 0;
}

7003
static int show_ssl_ctx_sess_cb_hits(THD *thd, SHOW_VAR *var, char *buff)
7004
{
7005
  var->type= SHOW_LONG;
7006 7007 7008 7009 7010 7011
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_cb_hits(ssl_acceptor_fd->ssl_context));
  return 0;
}

7012
static int show_ssl_ctx_sess_hits(THD *thd, SHOW_VAR *var, char *buff)
7013
{
7014
  var->type= SHOW_LONG;
7015 7016 7017 7018 7019 7020
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_hits(ssl_acceptor_fd->ssl_context));
  return 0;
}

7021
static int show_ssl_ctx_sess_cache_full(THD *thd, SHOW_VAR *var, char *buff)
7022
{
7023
  var->type= SHOW_LONG;
7024 7025 7026 7027 7028 7029
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_cache_full(ssl_acceptor_fd->ssl_context));
  return 0;
}

7030
static int show_ssl_ctx_sess_misses(THD *thd, SHOW_VAR *var, char *buff)
7031
{
7032
  var->type= SHOW_LONG;
7033 7034 7035 7036 7037 7038
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_misses(ssl_acceptor_fd->ssl_context));
  return 0;
}

7039
static int show_ssl_ctx_sess_timeouts(THD *thd, SHOW_VAR *var, char *buff)
7040
{
7041
  var->type= SHOW_LONG;
7042 7043 7044 7045 7046 7047
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_timeouts(ssl_acceptor_fd->ssl_context));
  return 0;
}

7048
static int show_ssl_ctx_sess_number(THD *thd, SHOW_VAR *var, char *buff)
7049
{
7050
  var->type= SHOW_LONG;
7051 7052 7053 7054 7055 7056
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context));
  return 0;
}

7057
static int show_ssl_ctx_sess_connect(THD *thd, SHOW_VAR *var, char *buff)
7058
{
7059
  var->type= SHOW_LONG;
7060 7061 7062 7063 7064 7065
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_connect(ssl_acceptor_fd->ssl_context));
  return 0;
}

7066
static int show_ssl_ctx_sess_get_cache_size(THD *thd, SHOW_VAR *var, char *buff)
7067
{
7068
  var->type= SHOW_LONG;
7069 7070 7071 7072 7073 7074
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context));
  return 0;
}

7075
static int show_ssl_ctx_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff)
7076
{
7077
  var->type= SHOW_LONG;
7078 7079 7080 7081 7082 7083
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_get_verify_mode(ssl_acceptor_fd->ssl_context));
  return 0;
}

7084
static int show_ssl_ctx_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff)
7085
{
7086
  var->type= SHOW_LONG;
7087 7088 7089 7090 7091 7092
  var->value= buff;
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
                     SSL_CTX_get_verify_depth(ssl_acceptor_fd->ssl_context));
  return 0;
}

7093
static int show_ssl_ctx_get_session_cache_mode(THD *thd, SHOW_VAR *var, char *buff)
7094
{
7095
  var->type= SHOW_CHAR;
7096
  if (!ssl_acceptor_fd)
unknown's avatar
unknown committed
7097
    var->value= const_cast<char*>("NONE");
7098 7099 7100 7101
  else
    switch (SSL_CTX_get_session_cache_mode(ssl_acceptor_fd->ssl_context))
    {
    case SSL_SESS_CACHE_OFF:
unknown's avatar
unknown committed
7102
      var->value= const_cast<char*>("OFF"); break;
7103
    case SSL_SESS_CACHE_CLIENT:
unknown's avatar
unknown committed
7104
      var->value= const_cast<char*>("CLIENT"); break;
7105
    case SSL_SESS_CACHE_SERVER:
unknown's avatar
unknown committed
7106
      var->value= const_cast<char*>("SERVER"); break;
7107
    case SSL_SESS_CACHE_BOTH:
unknown's avatar
unknown committed
7108
      var->value= const_cast<char*>("BOTH"); break;
7109
    case SSL_SESS_CACHE_NO_AUTO_CLEAR:
unknown's avatar
unknown committed
7110
      var->value= const_cast<char*>("NO_AUTO_CLEAR"); break;
7111
    case SSL_SESS_CACHE_NO_INTERNAL_LOOKUP:
unknown's avatar
unknown committed
7112
      var->value= const_cast<char*>("NO_INTERNAL_LOOKUP"); break;
7113
    default:
unknown's avatar
unknown committed
7114
      var->value= const_cast<char*>("Unknown"); break;
7115 7116 7117 7118
    }
  return 0;
}

7119 7120 7121 7122 7123 7124 7125
/*
   Functions relying on SSL 
   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.
 */
7126
static int show_ssl_get_version(THD *thd, SHOW_VAR *var, char *buff)
7127
{
7128
  var->type= SHOW_CHAR;
7129 7130 7131
  if( thd->vio_ok() && thd->net.vio->ssl_arg )
    var->value= const_cast<char*>(SSL_get_version((SSL*) thd->net.vio->ssl_arg));
  else
7132
    var->value= (char *)"";
7133 7134 7135
  return 0;
}

7136
static int show_ssl_session_reused(THD *thd, SHOW_VAR *var, char *buff)
7137
{
7138
  var->type= SHOW_LONG;
7139
  var->value= buff;
7140 7141 7142 7143
  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
7144
  return 0;
7145 7146
}

7147
static int show_ssl_get_default_timeout(THD *thd, SHOW_VAR *var, char *buff)
7148
{
7149
  var->type= SHOW_LONG;
7150
  var->value= buff;
7151 7152 7153 7154
  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;
7155 7156 7157
  return 0;
}

7158
static int show_ssl_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff)
7159
{
7160
  var->type= SHOW_LONG;
7161
  var->value= buff;
7162 7163 7164 7165
  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;
7166 7167 7168
  return 0;
}

7169
static int show_ssl_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff)
7170
{
7171
  var->type= SHOW_LONG;
7172
  var->value= buff;
7173 7174 7175 7176
  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;
7177 7178 7179
  return 0;
}

7180
static int show_ssl_get_cipher(THD *thd, SHOW_VAR *var, char *buff)
7181
{
7182
  var->type= SHOW_CHAR;
7183 7184 7185
  if( thd->vio_ok() && thd->net.vio->ssl_arg )
    var->value= const_cast<char*>(SSL_get_cipher((SSL*) thd->net.vio->ssl_arg));
  else
7186
    var->value= (char *)"";
7187 7188 7189
  return 0;
}

7190
static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff)
7191
{
7192
  var->type= SHOW_CHAR;
7193
  var->value= buff;
7194
  if (thd->vio_ok() && thd->net.vio->ssl_arg)
7195 7196 7197
  {
    int i;
    const char *p;
7198 7199 7200
    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++)
7201
    {
7202
      buff= strnmov(buff, p, end-buff-1);
7203 7204 7205 7206 7207 7208 7209 7210 7211 7212 7213
      *buff++= ':';
    }
    if (i)
      buff--;
  }
  *buff=0;
  return 0;
}

#endif /* HAVE_OPENSSL */

7214

7215 7216 7217 7218
/*
  Variables shown by SHOW STATUS in alphabetical order
*/

7219
SHOW_VAR status_vars[]= {
7220 7221
  {"Aborted_clients",          (char*) &aborted_threads,        SHOW_LONG},
  {"Aborted_connects",         (char*) &aborted_connects,       SHOW_LONG},
7222 7223
  {"Binlog_cache_disk_use",    (char*) &binlog_cache_disk_use,  SHOW_LONG},
  {"Binlog_cache_use",         (char*) &binlog_cache_use,       SHOW_LONG},
7224 7225
  {"Bytes_received",           (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONGLONG_STATUS},
  {"Bytes_sent",               (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS},
unknown's avatar
unknown committed
7226
  {"Com",                      (char*) com_status_vars, SHOW_ARRAY},
7227
  {"Compression",              (char*) &show_net_compression, SHOW_FUNC},
7228
  {"Connections",              (char*) &thread_id,              SHOW_LONG_NOFLUSH},
unknown's avatar
Merge  
unknown committed
7229
  {"Created_tmp_disk_tables",  (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS},
7230
  {"Created_tmp_files",	       (char*) &my_tmp_file_created,	SHOW_LONG},
unknown's avatar
Merge  
unknown committed
7231
  {"Created_tmp_tables",       (char*) offsetof(STATUS_VAR, created_tmp_tables), SHOW_LONG_STATUS},
7232
  {"Delayed_errors",           (char*) &delayed_insert_errors,  SHOW_LONG},
7233
  {"Delayed_insert_threads",   (char*) &delayed_insert_threads, SHOW_LONG_NOFLUSH},
7234
  {"Delayed_writes",           (char*) &delayed_insert_writes,  SHOW_LONG},
7235
  {"Flush_commands",           (char*) &refresh_version,        SHOW_LONG_NOFLUSH},
unknown's avatar
Merge  
unknown committed
7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 7246 7247 7248 7249 7250
  {"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},
  {"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},
  {"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},
  {"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},
  {"Handler_update",           (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS},
  {"Handler_write",            (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS},
7251
  {"Key_blocks_not_flushed",   (char*) offsetof(KEY_CACHE, global_blocks_changed), SHOW_KEY_CACHE_LONG},
7252 7253
  {"Key_blocks_unused",        (char*) offsetof(KEY_CACHE, blocks_unused), SHOW_KEY_CACHE_LONG},
  {"Key_blocks_used",          (char*) offsetof(KEY_CACHE, blocks_used), SHOW_KEY_CACHE_LONG},
7254 7255 7256 7257
  {"Key_read_requests",        (char*) offsetof(KEY_CACHE, global_cache_r_requests), SHOW_KEY_CACHE_LONGLONG},
  {"Key_reads",                (char*) offsetof(KEY_CACHE, global_cache_read), SHOW_KEY_CACHE_LONGLONG},
  {"Key_write_requests",       (char*) offsetof(KEY_CACHE, global_cache_w_requests), SHOW_KEY_CACHE_LONGLONG},
  {"Key_writes",               (char*) offsetof(KEY_CACHE, global_cache_write), SHOW_KEY_CACHE_LONGLONG},
7258
  {"Last_query_cost",          (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS},
7259
  {"Max_used_connections",     (char*) &max_used_connections,  SHOW_LONG},
7260 7261 7262
  {"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},
7263 7264
  {"Open_table_definitions",   (char*) &show_table_definitions, SHOW_FUNC},
  {"Open_tables",              (char*) &show_open_tables,       SHOW_FUNC},
7265
  {"Opened_files",             (char*) &my_file_total_opened, SHOW_LONG_NOFLUSH},
unknown's avatar
Merge  
unknown committed
7266
  {"Opened_tables",            (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS},
7267
  {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS},
unknown's avatar
unknown committed
7268
  {"Prepared_stmt_count",      (char*) &show_prepared_stmt_count, SHOW_FUNC},
unknown's avatar
unknown committed
7269
#ifdef HAVE_QUERY_CACHE
7270 7271
  {"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
7272
  {"Qcache_hits",              (char*) &query_cache.hits,       SHOW_LONG},
7273
  {"Qcache_inserts",           (char*) &query_cache.inserts,    SHOW_LONG},
7274
  {"Qcache_lowmem_prunes",     (char*) &query_cache.lowmem_prunes, SHOW_LONG},
unknown's avatar
unknown committed
7275
  {"Qcache_not_cached",        (char*) &query_cache.refused,    SHOW_LONG},
7276 7277
  {"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
7278
#endif /*HAVE_QUERY_CACHE*/
7279 7280 7281 7282
  {"Questions",                (char*) &show_question,            SHOW_FUNC},
#ifdef HAVE_REPLICATION
  {"Rpl_status",               (char*) &show_rpl_status,          SHOW_FUNC},
#endif
unknown's avatar
Merge  
unknown committed
7283 7284 7285 7286 7287
  {"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},
7288
  {"Slave_open_temp_tables",   (char*) &slave_open_temp_tables, SHOW_LONG},
7289 7290 7291 7292
#ifdef HAVE_REPLICATION
  {"Slave_retried_transactions",(char*) &show_slave_retried_trans, SHOW_FUNC},
  {"Slave_running",            (char*) &show_slave_running,     SHOW_FUNC},
#endif
7293
  {"Slow_launch_threads",      (char*) &slow_launch_threads,    SHOW_LONG},
unknown's avatar
Merge  
unknown committed
7294 7295 7296 7297 7298
  {"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
7299
#ifdef HAVE_OPENSSL
7300 7301 7302 7303 7304 7305 7306 7307 7308 7309 7310 7311 7312 7313 7314 7315 7316 7317 7318 7319 7320 7321 7322
  {"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},
unknown's avatar
unknown committed
7323
#endif /* HAVE_OPENSSL */
unknown's avatar
unknown committed
7324 7325
  {"Table_locks_immediate",    (char*) &locks_immediate,        SHOW_LONG},
  {"Table_locks_waited",       (char*) &locks_waited,           SHOW_LONG},
7326
#ifdef HAVE_MMAP
unknown's avatar
Merge  
unknown committed
7327 7328 7329
  {"Tc_log_max_pages_used",    (char*) &tc_log_max_pages_used,  SHOW_LONG},
  {"Tc_log_page_size",         (char*) &tc_log_page_size,       SHOW_LONG},
  {"Tc_log_page_waits",        (char*) &tc_log_page_waits,      SHOW_LONG},
7330
#endif
7331 7332 7333 7334
  {"Threads_cached",           (char*) &cached_thread_count,    SHOW_LONG_NOFLUSH},
  {"Threads_connected",        (char*) &thread_count,           SHOW_INT},
  {"Threads_created",	       (char*) &thread_created,		SHOW_LONG_NOFLUSH},
  {"Threads_running",          (char*) &thread_running,         SHOW_INT},
7335
  {"Uptime",                   (char*) &show_starttime,         SHOW_FUNC},
7336
#ifdef COMMUNITY_SERVER
7337
  {"Uptime_since_flush_status",(char*) &show_flushstatustime,   SHOW_FUNC},
7338
#endif
7339
  {NullS, NullS, SHOW_LONG}
unknown's avatar
unknown committed
7340 7341 7342 7343
};

static void print_version(void)
{
7344
  set_server_version();
7345 7346 7347 7348
  /*
    Note: the instance manager keys off the string 'Ver' so it can find the
    version from the output of 'mysqld --version', so don't change it!
  */
7349 7350
  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
7351 7352
}

7353
#ifndef EMBEDDED_LIBRARY
unknown's avatar
unknown committed
7354 7355
static void usage(void)
{
7356
  if (!(default_charset_info= get_charset_by_csname(default_character_set_name,
unknown's avatar
unknown committed
7357 7358 7359 7360 7361
					           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
7362
  print_version();
unknown's avatar
unknown committed
7363 7364 7365
  puts("\
Copyright (C) 2000 MySQL AB, by Monty and others\n\
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
7366 7367
and you are welcome to modify and redistribute it under the GPL license\n\n\
Starts the MySQL database server\n");
unknown's avatar
unknown committed
7368 7369

  printf("Usage: %s [OPTIONS]\n", my_progname);
7370
  if (!opt_verbose)
7371
    puts("\nFor more help options (several pages), use mysqld --verbose --help");
7372 7373
  else
  {
unknown's avatar
unknown committed
7374 7375
#ifdef __WIN__
  puts("NT and Win32 specific options:\n\
7376 7377
  --install                     Install the default service (NT)\n\
  --install-manual              Install the default service started manually (NT)\n\
unknown's avatar
unknown committed
7378 7379
  --install service_name        Install an optional service (NT)\n\
  --install-manual service_name Install an optional service started manually (NT)\n\
7380
  --remove                      Remove the default service from the service list (NT)\n\
unknown's avatar
unknown committed
7381 7382 7383
  --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
7384
");
7385
  puts("");
unknown's avatar
unknown committed
7386
#endif
7387
  print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
unknown's avatar
unknown committed
7388 7389
  puts("");
  set_ports();
7390

unknown's avatar
unknown committed
7391 7392
  /* Print out all the options including plugin supplied options */
  my_print_help_inc_plugins(my_long_options, sizeof(my_long_options)/sizeof(my_option));
7393

unknown's avatar
unknown committed
7394
  puts("\n\
unknown's avatar
unknown committed
7395
To see what values a running MySQL server is using, type\n\
7396
'mysqladmin variables' instead of 'mysqld --verbose --help'.");
7397
  }
unknown's avatar
unknown committed
7398
}
7399
#endif /*!EMBEDDED_LIBRARY*/
unknown's avatar
unknown committed
7400 7401


unknown's avatar
unknown committed
7402 7403
/**
  Initialize all MySQL global variables to default values.
unknown's avatar
unknown committed
7404

unknown's avatar
unknown committed
7405 7406
  We don't need to set numeric variables refered to in my_long_options
  as these are initialized by my_getopt.
unknown's avatar
unknown committed
7407

unknown's avatar
unknown committed
7408
  @note
unknown's avatar
unknown committed
7409 7410 7411 7412
    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
7413

unknown's avatar
unknown committed
7414 7415 7416
    We don't need to set numeric variables refered to in my_long_options
    as these are initialized by my_getopt.
*/
unknown's avatar
unknown committed
7417

unknown's avatar
unknown committed
7418 7419 7420 7421 7422
static void mysql_init_variables(void)
{
  /* Things reset to zero */
  opt_skip_slave_start= opt_reckless_slave = 0;
  mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0;
7423
  myisam_test_invalid_symlink= test_if_data_home_dir;
unknown's avatar
unknown committed
7424 7425
  opt_log= opt_slow_log= 0;
  opt_update_log= 0;
7426
  log_output_options= find_bit_type(log_output_str, &log_output_typelib);
7427
  opt_bin_log= 0;
unknown's avatar
unknown committed
7428
  opt_disable_networking= opt_skip_show_db=0;
unknown's avatar
Merge  
unknown committed
7429 7430
  opt_logname= opt_update_logname= opt_binlog_index_name= opt_slow_logname= 0;
  opt_tc_log_file= (char *)"tc.log";      // no hostname in tc_log file name !
7431
  opt_secure_auth= 0;
7432
  opt_secure_file_priv= 0;
7433
  opt_bootstrap= opt_myisam_log= 0;
unknown's avatar
unknown committed
7434 7435 7436
  mqh_used= 0;
  segfaulted= kill_in_progress= 0;
  cleanup_done= 0;
unknown's avatar
unknown committed
7437
  defaults_argc= 0;
unknown's avatar
unknown committed
7438 7439 7440 7441 7442 7443 7444 7445 7446 7447
  defaults_argv= 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;
  opt_using_transactions= using_update_log= 0;
  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
7448
  aborted_threads= aborted_connects= 0;
unknown's avatar
unknown committed
7449 7450
  delayed_insert_threads= delayed_insert_writes= delayed_rows_in_use= 0;
  delayed_insert_errors= thread_created= 0;
unknown's avatar
Merge  
unknown committed
7451
  specialflag= 0;
7452
  binlog_cache_use=  binlog_cache_disk_use= 0;
unknown's avatar
unknown committed
7453 7454
  max_used_connections= slow_launch_threads = 0;
  mysqld_user= mysqld_chroot= opt_init_file= opt_bin_logname = 0;
7455
  prepared_stmt_count= 0;
unknown's avatar
unknown committed
7456
  errmesg= 0;
7457
  mysqld_unix_port= opt_mysql_tmpdir= my_bind_addr_str= NullS;
7458
  bzero((uchar*) &mysql_tmpdir_list, sizeof(mysql_tmpdir_list));
unknown's avatar
Merge  
unknown committed
7459 7460
  bzero((char *) &global_status_var, sizeof(global_status_var));
  opt_large_pages= 0;
7461
  key_map_full.set_all();
unknown's avatar
unknown committed
7462

7463 7464 7465 7466 7467
  /* 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
7468
  character_set_filesystem= &my_charset_bin;
7469

7470 7471
  opt_date_time_formats[0]= opt_date_time_formats[1]= opt_date_time_formats[2]= 0;

unknown's avatar
unknown committed
7472 7473
  /* Things with default values that are not zero */
  delay_key_write_options= (uint) DELAY_KEY_WRITE_ON;
7474 7475 7476
  slave_exec_mode_options= 0;
  slave_exec_mode_options= (uint)
    find_bit_type_or_exit(slave_exec_mode_str, &slave_exec_mode_typelib, NULL);
unknown's avatar
unknown committed
7477 7478 7479 7480 7481 7482 7483
  opt_specialflag= SPECIAL_ENGLISH;
  unix_sock= ip_sock= INVALID_SOCKET;
  mysql_home_ptr= mysql_home;
  pidfile_name_ptr= pidfile_name;
  log_error_file_ptr= log_error_file;
  language_ptr= language;
  mysql_data_home= mysql_real_data_home;
7484 7485
  thd_startup_options= (OPTION_AUTO_IS_NULL | OPTION_BIN_LOG |
                        OPTION_QUOTE_SHOW_CREATE | OPTION_SQL_NOTES);
unknown's avatar
unknown committed
7486 7487
  protocol_version= PROTOCOL_VERSION;
  what_to_log= ~ (1L << (uint) COM_TIME);
7488
  refresh_version= 1L;	/* Increments on each reload */
7489
  global_query_id= thread_id= 1L;
unknown's avatar
unknown committed
7490 7491
  strmov(server_version, MYSQL_SERVER_VERSION);
  myisam_recover_options_str= sql_mode_str= "OFF";
7492
  myisam_stats_method_str= "nulls_unequal";
unknown's avatar
unknown committed
7493 7494 7495
  my_bind_addr = htonl(INADDR_ANY);
  threads.empty();
  thread_cache.empty();
7496
  key_caches.empty();
unknown's avatar
unknown committed
7497
  if (!(dflt_key_cache= get_or_create_key_cache(default_key_cache_base.str,
7498
                                                default_key_cache_base.length)))
7499
    exit(1);
7500 7501
  /* set key_cache_hash.default_value = dflt_key_cache */
  multi_keycache_init();
unknown's avatar
unknown committed
7502 7503 7504 7505 7506 7507 7508

  /* Set directory paths */
  strmake(language, LANGUAGE, sizeof(language)-1);
  strmake(mysql_real_data_home, get_relative_path(DATADIR),
	  sizeof(mysql_real_data_home)-1);
  mysql_data_home_buff[0]=FN_CURLIB;	// all paths are relative from here
  mysql_data_home_buff[1]=0;
7509
  mysql_data_home_len= 2;
unknown's avatar
unknown committed
7510 7511 7512 7513 7514

  /* Replication parameters */
  master_user= (char*) "test";
  master_password= master_host= 0;
  master_info_file= (char*) "master.info",
unknown's avatar
unknown committed
7515
    relay_log_info_file= (char*) "relay-log.info";
7516
  master_ssl_key= master_ssl_cert= master_ssl_ca=
unknown's avatar
unknown committed
7517
    master_ssl_capath= master_ssl_cipher= 0;
unknown's avatar
unknown committed
7518 7519 7520 7521 7522
  report_user= report_password = report_host= 0;	/* TO BE DELETED */
  opt_relay_logname= opt_relaylog_index_name= 0;

  /* Variables in libraries */
  charsets_dir= 0;
7523
  default_character_set_name= (char*) MYSQL_DEFAULT_CHARSET_NAME;
7524
  default_collation_name= compiled_default_collation_name;
7525
  sys_charset_system.value= (char*) system_charset_info->csname;
unknown's avatar
unknown committed
7526
  character_set_filesystem_name= (char*) "binary";
7527
  lc_time_names_name= (char*) "en_US";
unknown's avatar
unknown committed
7528
  /* Set default values for some option variables */
unknown's avatar
unknown committed
7529
  default_storage_engine_str= (char*) "MyISAM";
unknown's avatar
unknown committed
7530
  global_system_variables.table_plugin= NULL;
unknown's avatar
unknown committed
7531
  global_system_variables.tx_isolation= ISO_REPEATABLE_READ;
7532
  global_system_variables.select_limit= (ulonglong) HA_POS_ERROR;
unknown's avatar
unknown committed
7533
  max_system_variables.select_limit=    (ulonglong) HA_POS_ERROR;
7534
  global_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
unknown's avatar
unknown committed
7535
  max_system_variables.max_join_size=   (ulonglong) HA_POS_ERROR;
7536
  global_system_variables.old_passwords= 0;
unknown's avatar
unknown committed
7537
  global_system_variables.old_alter_table= 0;
7538
  global_system_variables.binlog_format= BINLOG_FORMAT_UNSPEC;
7539
  /*
7540
    Default behavior for 4.1 and 5.0 is to treat NULL values as unequal
7541 7542 7543
    when collecting index statistics for MyISAM tables.
  */
  global_system_variables.myisam_stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
unknown's avatar
unknown committed
7544

unknown's avatar
unknown committed
7545 7546 7547 7548 7549 7550
  /* 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");
#endif
  opt_error_log= IF_WIN(1,0);
7551 7552 7553 7554
#ifdef COMMUNITY_SERVER
    have_community_features = SHOW_OPTION_YES;
#else
    have_community_features = SHOW_OPTION_NO;
7555
  global_system_variables.ndb_index_stat_enable=FALSE;
7556 7557 7558 7559 7560
  max_system_variables.ndb_index_stat_enable=TRUE;
  global_system_variables.ndb_index_stat_cache_entries=32;
  max_system_variables.ndb_index_stat_cache_entries=~0L;
  global_system_variables.ndb_index_stat_update_freq=20;
  max_system_variables.ndb_index_stat_update_freq=~0L;
unknown's avatar
unknown committed
7561
#endif
unknown's avatar
unknown committed
7562
#ifdef HAVE_OPENSSL
7563
  have_ssl=SHOW_OPTION_YES;
unknown's avatar
unknown committed
7564
#else
7565
  have_ssl=SHOW_OPTION_NO;
unknown's avatar
unknown committed
7566
#endif
unknown's avatar
unknown committed
7567
#ifdef HAVE_BROKEN_REALPATH
unknown's avatar
unknown committed
7568 7569 7570 7571
  have_symlink=SHOW_OPTION_NO;
#else
  have_symlink=SHOW_OPTION_YES;
#endif
7572 7573 7574 7575 7576
#ifdef HAVE_DLOPEN
  have_dlopen=SHOW_OPTION_YES;
#else
  have_dlopen=SHOW_OPTION_NO;
#endif
unknown's avatar
unknown committed
7577 7578 7579 7580 7581
#ifdef HAVE_QUERY_CACHE
  have_query_cache=SHOW_OPTION_YES;
#else
  have_query_cache=SHOW_OPTION_NO;
#endif
7582 7583 7584 7585 7586 7587 7588 7589 7590 7591
#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
7592 7593 7594 7595 7596 7597
#ifdef HAVE_CRYPT
  have_crypt=SHOW_OPTION_YES;
#else
  have_crypt=SHOW_OPTION_NO;
#endif
#ifdef HAVE_COMPRESS
7598
  have_compress= SHOW_OPTION_YES;
unknown's avatar
unknown committed
7599
#else
7600
  have_compress= SHOW_OPTION_NO;
unknown's avatar
unknown committed
7601 7602 7603 7604 7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615
#endif
#ifdef HAVE_LIBWRAP
  libwrapName= NullS;
#endif
#ifdef HAVE_OPENSSL
  des_key_file = 0;
  ssl_acceptor_fd= 0;
#endif
#ifdef HAVE_SMEM
  shared_memory_base_name= default_shared_memory_base_name;
#endif
#if !defined(my_pthread_setprio) && !defined(HAVE_PTHREAD_SETSCHEDPARAM)
  opt_specialflag |= SPECIAL_NO_PRIOR;
#endif

unknown's avatar
unknown committed
7616 7617
#if defined(__WIN__) || defined(__NETWARE__)
  /* Allow Win32 and NetWare users to move MySQL anywhere */
unknown's avatar
unknown committed
7618 7619
  {
    char prg_dev[LIBLEN];
7620 7621 7622 7623 7624 7625 7626 7627 7628 7629 7630 7631
#if defined __WIN__
	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
#endif
unknown's avatar
unknown committed
7632 7633 7634 7635 7636 7637
    my_path(prg_dev,my_progname,"mysql/bin");
    strcat(prg_dev,"/../");			// Remove 'bin' to get base dir
    cleanup_dirname(mysql_home,prg_dev);
  }
#else
  const char *tmpenv;
unknown's avatar
unknown committed
7638
  if (!(tmpenv = getenv("MY_BASEDIR_VERSION")))
unknown's avatar
unknown committed
7639
    tmpenv = DEFAULT_MYSQL_HOME;
unknown's avatar
unknown committed
7640
  (void) strmake(mysql_home, tmpenv, sizeof(mysql_home)-1);
unknown's avatar
unknown committed
7641 7642 7643 7644
#endif
}


7645 7646 7647 7648
my_bool
mysqld_get_one_option(int optid,
                      const struct my_option *opt __attribute__((unused)),
                      char *argument)
unknown's avatar
unknown committed
7649
{
7650 7651
  switch(optid) {
  case '#':
7652
#ifndef DBUG_OFF
unknown's avatar
unknown committed
7653
    DBUG_SET_INITIAL(argument ? argument : default_dbug_option);
7654 7655 7656 7657
#endif
    opt_endinfo=1;				/* unireg: memory allocation */
    break;
  case 'a':
7658
    global_system_variables.sql_mode= fix_sql_mode(MODE_ANSI);
unknown's avatar
unknown committed
7659
    global_system_variables.tx_isolation= ISO_SERIALIZABLE;
7660 7661 7662 7663
    break;
  case 'b':
    strmake(mysql_home,argument,sizeof(mysql_home)-1);
    break;
7664
  case 'C':
7665 7666
    if (default_collation_name == compiled_default_collation_name)
      default_collation_name= 0;
7667
    break;
7668 7669 7670 7671 7672
  case 'l':
    opt_log=1;
    break;
  case 'h':
    strmake(mysql_real_data_home,argument, sizeof(mysql_real_data_home)-1);
7673 7674
    /* Correct pointer set by my_getopt (for embedded library) */
    mysql_data_home= mysql_real_data_home;
7675
    mysql_data_home_len= strlen(mysql_data_home);
7676
    break;
7677
  case 'u':
7678
    if (!mysqld_user || !strcmp(mysqld_user, argument))
unknown's avatar
unknown committed
7679
      mysqld_user= argument;
7680
    else
7681
      sql_print_warning("Ignoring user change to '%s' because the user was set to '%s' earlier on the command line\n", argument, mysqld_user);
7682
    break;
7683 7684 7685
  case 'L':
    strmake(language, argument, sizeof(language)-1);
    break;
unknown's avatar
SCRUM  
unknown committed
7686
#ifdef HAVE_REPLICATION
7687 7688 7689
  case OPT_SLAVE_SKIP_ERRORS:
    init_slave_skip_errors(argument);
    break;
7690 7691 7692 7693
  case OPT_SLAVE_EXEC_MODE:
    slave_exec_mode_options= (uint)
      find_bit_type_or_exit(argument, &slave_exec_mode_typelib, "");
    break;
7694
#endif
7695
  case OPT_SAFEMALLOC_MEM_LIMIT:
7696
#if !defined(DBUG_OFF) && defined(SAFEMALLOC)
7697
    sf_malloc_mem_limit = atoi(argument);
7698
#endif
7699
    break;
7700
#include <sslopt-case.h>
7701 7702 7703
  case 'V':
    print_version();
    exit(0);
7704 7705 7706 7707 7708 7709 7710 7711
  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;
7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725
  case 'T':
    test_flags= argument ? (uint) atoi(argument) : 0;
    opt_endinfo=1;
    break;
  case (int) OPT_BIG_TABLES:
    thd_startup_options|=OPTION_BIG_TABLES;
    break;
  case (int) OPT_ISAM_LOG:
    opt_myisam_log=1;
    break;
  case (int) OPT_UPDATE_LOG:
    opt_update_log=1;
    break;
  case (int) OPT_BIN_LOG:
7726
    opt_bin_log= test(argument != disabled_my_option);
7727
    break;
7728 7729 7730
  case (int) OPT_ERROR_LOG_FILE:
    opt_error_log= 1;
    break;
unknown's avatar
SCRUM  
unknown committed
7731
#ifdef HAVE_REPLICATION
7732
  case (int) OPT_INIT_RPL_ROLE:
7733 7734
  {
    int role;
7735
    role= find_type_or_exit(argument, &rpl_role_typelib, opt->name);
7736 7737 7738
    rpl_status = (role == 1) ?  RPL_AUTH_MASTER : RPL_IDLE_SLAVE;
    break;
  }
7739
  case (int)OPT_REPLICATE_IGNORE_DB:
7740
  {
7741
    rpl_filter->add_ignore_db(argument);
7742 7743 7744 7745
    break;
  }
  case (int)OPT_REPLICATE_DO_DB:
  {
7746
    rpl_filter->add_do_db(argument);
7747 7748 7749 7750 7751
    break;
  }
  case (int)OPT_REPLICATE_REWRITE_DB:
  {
    char* key = argument,*p, *val;
7752

7753
    if (!(p= strstr(argument, "->")))
7754
    {
7755 7756 7757
      fprintf(stderr,
	      "Bad syntax in replicate-rewrite-db - missing '->'!\n");
      exit(1);
7758
    }
7759
    val= p--;
unknown's avatar
unknown committed
7760
    while (my_isspace(mysqld_charset, *p) && p > argument)
7761 7762
      *p-- = 0;
    if (p == argument)
7763
    {
7764 7765 7766
      fprintf(stderr,
	      "Bad syntax in replicate-rewrite-db - empty FROM db!\n");
      exit(1);
7767
    }
7768 7769
    *val= 0;
    val+= 2;
unknown's avatar
unknown committed
7770
    while (*val && my_isspace(mysqld_charset, *val))
7771 7772
      *val++;
    if (!*val)
7773
    {
7774 7775 7776
      fprintf(stderr,
	      "Bad syntax in replicate-rewrite-db - empty TO db!\n");
      exit(1);
7777 7778
    }

7779
    rpl_filter->add_db_rewrite(key, val);
7780 7781 7782
    break;
  }

7783
  case (int)OPT_BINLOG_IGNORE_DB:
7784
  {
7785
    binlog_filter->add_ignore_db(argument);
7786 7787
    break;
  }
7788 7789 7790
  case OPT_BINLOG_FORMAT:
  {
    int id;
7791
    id= find_type_or_exit(argument, &binlog_format_typelib, opt->name);
7792
    global_system_variables.binlog_format= opt_binlog_format_id= id - 1;
7793 7794
    break;
  }
7795
  case (int)OPT_BINLOG_DO_DB:
7796
  {
7797
    binlog_filter->add_do_db(argument);
7798 7799
    break;
  }
7800
  case (int)OPT_REPLICATE_DO_TABLE:
7801
  {
7802
    if (rpl_filter->add_do_table(argument))
7803
    {
7804 7805
      fprintf(stderr, "Could not add do table rule '%s'!\n", argument);
      exit(1);
7806
    }
7807 7808
    break;
  }
7809
  case (int)OPT_REPLICATE_WILD_DO_TABLE:
7810
  {
7811
    if (rpl_filter->add_wild_do_table(argument))
7812
    {
7813 7814
      fprintf(stderr, "Could not add do table rule '%s'!\n", argument);
      exit(1);
7815
    }
7816 7817
    break;
  }
7818
  case (int)OPT_REPLICATE_WILD_IGNORE_TABLE:
7819
  {
7820
    if (rpl_filter->add_wild_ignore_table(argument))
7821
    {
7822 7823
      fprintf(stderr, "Could not add ignore table rule '%s'!\n", argument);
      exit(1);
7824
    }
7825 7826
    break;
  }
7827
  case (int)OPT_REPLICATE_IGNORE_TABLE:
7828
  {
7829
    if (rpl_filter->add_ignore_table(argument))
7830
    {
7831 7832
      fprintf(stderr, "Could not add ignore table rule '%s'!\n", argument);
      exit(1);
7833
    }
7834 7835
    break;
  }
unknown's avatar
SCRUM  
unknown committed
7836
#endif /* HAVE_REPLICATION */
7837
  case (int) OPT_SLOW_QUERY_LOG:
7838
    opt_slow_log= 1;
7839
    break;
7840
#ifdef WITH_CSV_STORAGE_ENGINE
7841 7842 7843 7844
  case  OPT_LOG_OUTPUT:
  {
    if (!argument || !argument[0])
    {
7845
      log_output_options= LOG_FILE;
7846 7847 7848 7849 7850
      log_output_str= log_output_typelib.type_names[1];
    }
    else
    {
      log_output_str= argument;
7851 7852 7853
      log_output_options=
        find_bit_type_or_exit(argument, &log_output_typelib, opt->name);
  }
7854
    break;
7855
  }
7856
#endif
7857
  case OPT_EVENT_SCHEDULER:
7858 7859 7860
#ifndef HAVE_EVENT_SCHEDULER
    sql_perror("Event scheduler is not supported in embedded build.");
#else
7861
    if (Events::set_opt_event_scheduler(argument))
7862
	exit(1);
7863
#endif
7864
    break;
7865 7866
  case (int) OPT_SKIP_NEW:
    opt_specialflag|= SPECIAL_NO_NEW_FUNC;
7867
    delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
7868 7869
    myisam_concurrent_insert=0;
    myisam_recover_options= HA_RECOVER_NONE;
unknown's avatar
Merge  
unknown committed
7870
    sp_automatic_privileges=0;
7871
    my_use_symdir=0;
7872
    ha_open_options&= ~(HA_OPEN_ABORT_IF_CRASHED | HA_OPEN_DELAY_KEY_WRITE);
unknown's avatar
unknown committed
7873
#ifdef HAVE_QUERY_CACHE
7874 7875 7876 7877 7878
    query_cache_size=0;
#endif
    break;
  case (int) OPT_SAFE:
    opt_specialflag|= SPECIAL_SAFE_MODE;
7879
    delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
7880 7881
    myisam_recover_options= HA_RECOVER_DEFAULT;
    ha_open_options&= ~(HA_OPEN_DELAY_KEY_WRITE);
7882 7883 7884 7885 7886
    break;
  case (int) OPT_SKIP_PRIOR:
    opt_specialflag|= SPECIAL_NO_PRIOR;
    break;
  case (int) OPT_SKIP_LOCK:
7887
    opt_external_locking=0;
7888 7889 7890 7891 7892 7893 7894 7895
    break;
  case (int) OPT_SKIP_HOST_CACHE:
    opt_specialflag|= SPECIAL_NO_HOST_CACHE;
    break;
  case (int) OPT_SKIP_RESOLVE:
    opt_specialflag|=SPECIAL_NO_RESOLVE;
    break;
  case (int) OPT_SKIP_NETWORKING:
unknown's avatar
unknown committed
7896 7897 7898
#if defined(__NETWARE__)
    sql_perror("Can't start server: skip-networking option is currently not supported on NetWare");
    exit(1);
7899
#endif
7900
    opt_disable_networking=1;
7901
    mysqld_port=0;
7902 7903 7904 7905 7906 7907 7908 7909 7910 7911 7912 7913 7914 7915 7916
    break;
  case (int) OPT_SKIP_SHOW_DB:
    opt_skip_show_db=1;
    opt_specialflag|=SPECIAL_SKIP_SHOW_DB;
    break;
  case (int) OPT_WANT_CORE:
    test_flags |= TEST_CORE_ON_SIGNAL;
    break;
  case (int) OPT_SKIP_STACK_TRACE:
    test_flags|=TEST_NO_STACKTRACE;
    break;
  case (int) OPT_SKIP_SYMLINKS:
    my_use_symdir=0;
    break;
  case (int) OPT_BIND_ADDRESS:
unknown's avatar
unknown committed
7917
    if ((my_bind_addr= (ulong) inet_addr(argument)) == INADDR_NONE)
7918 7919
    {
      struct hostent *ent;
unknown's avatar
unknown committed
7920
      if (argument[0])
7921
	ent=gethostbyname(argument);
unknown's avatar
unknown committed
7922 7923
      else
      {
7924 7925
	char myhostname[255];
	if (gethostname(myhostname,sizeof(myhostname)) < 0)
unknown's avatar
unknown committed
7926
	{
7927
	  sql_perror("Can't start server: cannot get my own hostname!");
unknown's avatar
unknown committed
7928 7929
	  exit(1);
	}
7930
	ent=gethostbyname(myhostname);
unknown's avatar
unknown committed
7931
      }
7932 7933 7934 7935 7936 7937 7938 7939 7940 7941 7942
      if (!ent)
      {
	sql_perror("Can't start server: cannot resolve hostname!");
	exit(1);
      }
      my_bind_addr = (ulong) ((in_addr*)ent->h_addr_list[0])->s_addr;
    }
    break;
  case (int) OPT_PID_FILE:
    strmake(pidfile_name, argument, sizeof(pidfile_name)-1);
    break;
unknown's avatar
unknown committed
7943
#ifdef __WIN__
7944 7945
  case (int) OPT_STANDALONE:		/* Dummy option for NT */
    break;
unknown's avatar
unknown committed
7946
#endif
7947
  /*
7948 7949 7950 7951 7952 7953 7954 7955 7956 7957 7958 7959 7960 7961 7962 7963 7964 7965
    The following change issues a deprecation warning if the slave
    configuration is specified either in the my.cnf file or on
    the command-line. See BUG#21490.
  */
  case OPT_MASTER_HOST:
  case OPT_MASTER_USER:
  case OPT_MASTER_PASSWORD:
  case OPT_MASTER_PORT:
  case OPT_MASTER_CONNECT_RETRY:
  case OPT_MASTER_SSL:          
  case OPT_MASTER_SSL_KEY:
  case OPT_MASTER_SSL_CERT:       
  case OPT_MASTER_SSL_CAPATH:
  case OPT_MASTER_SSL_CIPHER:
  case OPT_MASTER_SSL_CA:
    if (!slave_warning_issued)                 //only show the warning once
    {
      slave_warning_issued = true;   
7966
      WARN_DEPRECATED(NULL, "5.2", "for replication startup options", 
7967 7968 7969
        "'CHANGE MASTER'");
    }
    break;
7970 7971 7972 7973
  case OPT_CONSOLE:
    if (opt_console)
      opt_error_log= 0;			// Force logs to stdout
    break;
7974 7975 7976 7977 7978 7979
  case (int) OPT_FLUSH:
    myisam_flush=1;
    flush_time=0;			// No auto flush
    break;
  case OPT_LOW_PRIORITY_UPDATES:
    thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY;
unknown's avatar
unknown committed
7980
    global_system_variables.low_priority_updates=1;
7981 7982 7983 7984 7985 7986 7987
    break;
  case OPT_BOOTSTRAP:
    opt_noacl=opt_bootstrap=1;
    break;
  case OPT_SERVER_ID:
    server_id_supplied = 1;
    break;
7988 7989 7990 7991
  case OPT_DELAY_KEY_WRITE_ALL:
    if (argument != disabled_my_option)
      argument= (char*) "ALL";
    /* Fall through */
7992
  case OPT_DELAY_KEY_WRITE:
7993 7994 7995 7996 7997 7998 7999
    if (argument == disabled_my_option)
      delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
    else if (! argument)
      delay_key_write_options= (uint) DELAY_KEY_WRITE_ON;
    else
    {
      int type;
8000
      type= find_type_or_exit(argument, &delay_key_write_typelib, opt->name);
8001 8002
      delay_key_write_options= (uint) type-1;
    }
8003 8004 8005 8006 8007 8008
    break;
  case OPT_CHARSETS_DIR:
    strmake(mysql_charsets_dir, argument, sizeof(mysql_charsets_dir)-1);
    charsets_dir = mysql_charsets_dir;
    break;
  case OPT_TX_ISOLATION:
8009 8010
  {
    int type;
8011
    type= find_type_or_exit(argument, &tx_isolation_typelib, opt->name);
unknown's avatar
unknown committed
8012
    global_system_variables.tx_isolation= (type-1);
8013 8014
    break;
  }
8015
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
unknown's avatar
Merge  
unknown committed
8016 8017 8018 8019 8020 8021 8022 8023 8024 8025 8026 8027 8028 8029 8030 8031 8032 8033 8034 8035 8036 8037 8038
  case OPT_NDB_MGMD:
  case OPT_NDB_NODEID:
  {
    int len= my_snprintf(opt_ndb_constrbuf+opt_ndb_constrbuf_len,
			 sizeof(opt_ndb_constrbuf)-opt_ndb_constrbuf_len,
			 "%s%s%s",opt_ndb_constrbuf_len > 0 ? ",":"",
			 optid == OPT_NDB_NODEID ? "nodeid=" : "",
			 argument);
    opt_ndb_constrbuf_len+= len;
  }
  /* fall through to add the connectstring to the end
   * and set opt_ndbcluster_connectstring
   */
  case OPT_NDB_CONNECTSTRING:
    if (opt_ndb_connectstring && opt_ndb_connectstring[0])
      my_snprintf(opt_ndb_constrbuf+opt_ndb_constrbuf_len,
		  sizeof(opt_ndb_constrbuf)-opt_ndb_constrbuf_len,
		  "%s%s", opt_ndb_constrbuf_len > 0 ? ",":"",
		  opt_ndb_connectstring);
    else
      opt_ndb_constrbuf[opt_ndb_constrbuf_len]= 0;
    opt_ndbcluster_connectstring= opt_ndb_constrbuf;
    break;
8039 8040
  case OPT_NDB_DISTRIBUTION:
    int id;
8041
    id= find_type_or_exit(argument, &ndb_distribution_typelib, opt->name);
8042 8043
    opt_ndb_distribution_id= (enum ndb_distribution)(id-1);
    break;
unknown's avatar
unknown committed
8044 8045 8046 8047 8048 8049 8050 8051
  case OPT_NDB_EXTRA_LOGGING:
    if (!argument)
      ndb_extra_logging++;
    else if (argument == disabled_my_option)
      ndb_extra_logging= 0L;
    else
      ndb_extra_logging= atoi(argument);
    break;
unknown's avatar
Merge  
unknown committed
8052
#endif
8053
  case OPT_MYISAM_RECOVER:
8054
  {
8055
    if (!argument)
8056
    {
8057 8058
      myisam_recover_options=    HA_RECOVER_DEFAULT;
      myisam_recover_options_str= myisam_recover_typelib.type_names[0];
8059
    }
8060 8061 8062 8063 8064
    else if (!argument[0])
    {
      myisam_recover_options= HA_RECOVER_NONE;
      myisam_recover_options_str= "OFF";
    }
8065
    else
8066
    {
8067
      myisam_recover_options_str=argument;
8068 8069
      myisam_recover_options=
        find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name);
8070
    }
8071 8072 8073
    ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
    break;
  }
8074 8075 8076 8077 8078 8079 8080
  case OPT_CONCURRENT_INSERT:
    /* The following code is mainly here to emulate old behavior */
    if (!argument)                      /* --concurrent-insert */
      myisam_concurrent_insert= 1;
    else if (argument == disabled_my_option)
      myisam_concurrent_insert= 0;      /* --skip-concurrent-insert */
    break;
unknown's avatar
Merge  
unknown committed
8081
  case OPT_TC_HEURISTIC_RECOVER:
8082 8083 8084 8085
    tc_heuristic_recover= find_type_or_exit(argument,
                                            &tc_heuristic_recover_typelib,
                                            opt->name);
    break;
8086 8087
  case OPT_MYISAM_STATS_METHOD:
  {
8088
    ulong method_conv;
8089
    int method;
unknown's avatar
unknown committed
8090 8091
    LINT_INIT(method_conv);

8092
    myisam_stats_method_str= argument;
8093 8094
    method= find_type_or_exit(argument, &myisam_stats_method_typelib,
                              opt->name);
8095
    switch (method-1) {
8096 8097
    case 2:
      method_conv= MI_STATS_METHOD_IGNORE_NULLS;
8098 8099
      break;
    case 1:
8100
      method_conv= MI_STATS_METHOD_NULLS_EQUAL;
8101
      break;
8102 8103
    case 0:
    default:
8104
      method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
8105 8106 8107
      break;
    }
    global_system_variables.myisam_stats_method= method_conv;
unknown's avatar
Merge  
unknown committed
8108 8109
    break;
  }
8110 8111
  case OPT_SQL_MODE:
  {
8112
    sql_mode_str= argument;
8113 8114
    global_system_variables.sql_mode=
      find_bit_type_or_exit(argument, &sql_mode_typelib, opt->name);
8115 8116
    global_system_variables.sql_mode= fix_sql_mode(global_system_variables.
						   sql_mode);
unknown's avatar
unknown committed
8117
    break;
8118
  }
unknown's avatar
unknown committed
8119
  case OPT_ONE_THREAD:
8120 8121
    global_system_variables.thread_handling=
      SCHEDULER_ONE_THREAD_PER_CONNECTION;
unknown's avatar
unknown committed
8122 8123 8124
    break;
  case OPT_THREAD_HANDLING:
  {
unknown's avatar
unknown committed
8125
    global_system_variables.thread_handling=
8126
      find_type_or_exit(argument, &thread_handling_typelib, opt->name)-1;
unknown's avatar
unknown committed
8127 8128
    break;
  }
unknown's avatar
unknown committed
8129
  case OPT_FT_BOOLEAN_SYNTAX:
8130
    if (ft_boolean_check_syntax_string((uchar*) argument))
unknown's avatar
unknown committed
8131 8132 8133 8134
    {
      fprintf(stderr, "Invalid ft-boolean-syntax string: %s\n", argument);
      exit(1);
    }
8135
    strmake(ft_boolean_syntax, argument, sizeof(ft_boolean_syntax)-1);
8136 8137
    break;
  case OPT_SKIP_SAFEMALLOC:
8138
#ifdef SAFEMALLOC
8139
    sf_malloc_quick=1;
8140
#endif
8141
    break;
unknown's avatar
unknown committed
8142 8143
  case OPT_LOWER_CASE_TABLE_NAMES:
    lower_case_table_names= argument ? atoi(argument) : 1;
8144
    lower_case_table_names_used= 1;
unknown's avatar
unknown committed
8145
    break;
unknown's avatar
unknown committed
8146
  }
8147 8148
  return 0;
}
8149

8150

unknown's avatar
unknown committed
8151
/** Handle arguments for multiple key caches. */
8152

8153 8154 8155 8156
extern "C" uchar **mysql_getopt_value(const char *keyname, uint key_length,
                                      const struct my_option *option);

uchar* *
8157
mysql_getopt_value(const char *keyname, uint key_length,
8158 8159
		   const struct my_option *option)
{
8160 8161
  switch (option->id) {
  case OPT_KEY_BUFFER_SIZE:
unknown's avatar
unknown committed
8162
  case OPT_KEY_CACHE_BLOCK_SIZE:
8163 8164
  case OPT_KEY_CACHE_DIVISION_LIMIT:
  case OPT_KEY_CACHE_AGE_THRESHOLD:
8165
  {
unknown's avatar
unknown committed
8166
    KEY_CACHE *key_cache;
8167 8168
    if (!(key_cache= get_or_create_key_cache(keyname, key_length)))
      exit(1);
8169 8170
    switch (option->id) {
    case OPT_KEY_BUFFER_SIZE:
8171
      return (uchar**) &key_cache->param_buff_size;
8172
    case OPT_KEY_CACHE_BLOCK_SIZE:
8173
      return (uchar**) &key_cache->param_block_size;
8174
    case OPT_KEY_CACHE_DIVISION_LIMIT:
8175
      return (uchar**) &key_cache->param_division_limit;
8176
    case OPT_KEY_CACHE_AGE_THRESHOLD:
8177
      return (uchar**) &key_cache->param_age_threshold;
8178
    }
8179 8180
  }
  }
8181
  return option->value;
8182 8183
}

unknown's avatar
unknown committed
8184

8185 8186 8187
extern "C" void option_error_reporter(enum loglevel level, const char *format, ...);

void option_error_reporter(enum loglevel level, const char *format, ...)
unknown's avatar
unknown committed
8188
{
8189
  va_list args;
unknown's avatar
unknown committed
8190
  va_start(args, format);
8191 8192 8193 8194 8195 8196 8197

  /* 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
8198
  va_end(args);
unknown's avatar
unknown committed
8199
}
8200

unknown's avatar
unknown committed
8201

unknown's avatar
unknown committed
8202 8203 8204 8205
/**
  @todo
  - FIXME add EXIT_TOO_MANY_ARGUMENTS to "mysys_err.h" and return that code?
*/
unknown's avatar
unknown committed
8206
static void get_options(int *argc,char **argv)
8207 8208 8209
{
  int ho_error;

8210
  my_getopt_register_get_addr(mysql_getopt_value);
8211
  strmake(def_ft_boolean_syntax, ft_boolean_syntax,
unknown's avatar
unknown committed
8212
	  sizeof(ft_boolean_syntax)-1);
8213
  my_getopt_error_reporter= option_error_reporter;
unknown's avatar
unknown committed
8214 8215 8216 8217 8218

  /* Skip unknown options so that they may be processed later by plugins */
  my_getopt_skip_unknown= TRUE;

  if ((ho_error= handle_options(argc, &argv, my_long_options,
8219
                                mysqld_get_one_option)))
8220
    exit(ho_error);
unknown's avatar
unknown committed
8221 8222
  (*argc)++; /* add back one for the progname handle_options removes */
             /* no need to do this for argv as we are discarding it. */
8223

8224 8225
  if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes ||
       opt_log_slow_slave_statements) &&
8226
      !opt_slow_log)
8227
    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");
8228

unknown's avatar
unknown committed
8229
#if defined(HAVE_BROKEN_REALPATH)
8230 8231 8232 8233 8234 8235 8236 8237 8238 8239
  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
8240 8241 8242 8243 8244 8245
  if (opt_debugging)
  {
    /* Allow break with SIGINT, no core or stack trace */
    test_flags|= TEST_SIGINT | TEST_NO_STACKTRACE;
    test_flags&= ~TEST_CORE_ON_SIGNAL;
  }
8246 8247
  /* Set global MyISAM variables from delay_key_write_options */
  fix_delay_key_write((THD*) 0, OPT_GLOBAL);
8248 8249
  /* Set global slave_exec_mode from its option */
  fix_slave_exec_mode(OPT_GLOBAL);
8250

8251
#ifndef EMBEDDED_LIBRARY
8252 8253
  if (mysqld_chroot)
    set_root(mysqld_chroot);
8254
#else
unknown's avatar
unknown committed
8255
  global_system_variables.thread_handling = SCHEDULER_NO_THREADS;
8256 8257
  max_allowed_packet= global_system_variables.max_allowed_packet;
  net_buffer_length= global_system_variables.net_buffer_length;
8258
#endif
unknown's avatar
unknown committed
8259
  fix_paths();
unknown's avatar
unknown committed
8260

unknown's avatar
unknown committed
8261 8262 8263 8264
  /*
    Set some global variables from the global_system_variables
    In most cases the global variables will not be used
  */
8265
  my_disable_locking= myisam_single_user= test(opt_external_locking == 0);
unknown's avatar
unknown committed
8266
  my_default_record_cache_size=global_system_variables.read_buff_size;
8267
  myisam_max_temp_length=
8268
    (my_off_t) global_system_variables.myisam_max_sort_file_size;
unknown's avatar
unknown committed
8269

unknown's avatar
unknown committed
8270
  /* Set global variables based on startup options */
unknown's avatar
unknown committed
8271
  myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size);
unknown's avatar
unknown committed
8272

8273 8274 8275 8276
  /* long_query_time is in microseconds */
  global_system_variables.long_query_time= max_system_variables.long_query_time=
    (longlong) (long_query_time * 1000000.0);

8277 8278
  if (opt_short_log_format)
    opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT;
8279

8280
  if (init_global_datetime_format(MYSQL_TIMESTAMP_DATE,
8281
				  &global_system_variables.date_format) ||
8282
      init_global_datetime_format(MYSQL_TIMESTAMP_TIME,
8283
				  &global_system_variables.time_format) ||
8284
      init_global_datetime_format(MYSQL_TIMESTAMP_DATETIME,
8285 8286
				  &global_system_variables.datetime_format))
    exit(1);
8287

unknown's avatar
unknown committed
8288 8289 8290 8291 8292 8293 8294 8295 8296 8297 8298
#ifdef EMBEDDED_LIBRARY
  one_thread_scheduler(&thread_scheduler);
#else
  if (global_system_variables.thread_handling <=
      SCHEDULER_ONE_THREAD_PER_CONNECTION)
    one_thread_per_connection_scheduler(&thread_scheduler);
  else if (global_system_variables.thread_handling == SCHEDULER_NO_THREADS)
    one_thread_scheduler(&thread_scheduler);
  else
    pool_of_threads_scheduler(&thread_scheduler);  /* purecov: tested */
#endif
unknown's avatar
unknown committed
8299 8300 8301
}


8302 8303 8304 8305 8306 8307 8308 8309 8310 8311
/*
  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)
*/

static void set_server_version(void)
{
  char *end= strxmov(server_version, MYSQL_SERVER_VERSION,
8312
                     MYSQL_SERVER_SUFFIX_STR, NullS);
8313 8314 8315 8316
#ifdef EMBEDDED_LIBRARY
  end= strmov(end, "-embedded");
#endif
#ifndef DBUG_OFF
8317
  if (!strstr(MYSQL_SERVER_SUFFIX_STR, "-debug"))
8318 8319 8320 8321 8322 8323 8324
    end= strmov(end, "-debug");
#endif
  if (opt_log || opt_update_log || opt_slow_log || opt_bin_log)
    strmov(end, "-log");                        // This may slow down system
}


unknown's avatar
unknown committed
8325 8326 8327
static char *get_relative_path(const char *path)
{
  if (test_if_hard_path(path) &&
8328
      is_prefix(path,DEFAULT_MYSQL_HOME) &&
unknown's avatar
unknown committed
8329 8330
      strcmp(DEFAULT_MYSQL_HOME,FN_ROOTDIR))
  {
unknown's avatar
unknown committed
8331
    path+=(uint) strlen(DEFAULT_MYSQL_HOME);
unknown's avatar
unknown committed
8332 8333 8334 8335 8336 8337 8338
    while (*path == FN_LIBCHAR)
      path++;
  }
  return (char*) path;
}


unknown's avatar
unknown committed
8339
/**
8340 8341
  Fix filename and replace extension where 'dir' is relative to
  mysql_real_data_home.
unknown's avatar
unknown committed
8342 8343
  @return
    1 if len(path) > FN_REFLEN
8344 8345 8346
*/

bool
8347
fn_format_relative_to_data_home(char * to, const char *name,
8348 8349 8350 8351 8352 8353 8354 8355 8356 8357
				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,
8358
		    MY_APPEND_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH);
8359 8360 8361
}


unknown's avatar
unknown committed
8362 8363
static void fix_paths(void)
{
8364
  char buff[FN_REFLEN],*pos;
8365
  convert_dirname(mysql_home,mysql_home,NullS);
8366
  /* Resolve symlinks to allow 'mysql_home' to be a relative symlink */
8367
  my_realpath(mysql_home,mysql_home,MYF(0));
8368 8369 8370 8371 8372 8373 8374
  /* Ensure that mysql_home ends in FN_LIBCHAR */
  pos=strend(mysql_home);
  if (pos[-1] != FN_LIBCHAR)
  {
    pos[0]= FN_LIBCHAR;
    pos[1]= 0;
  }
8375
  convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
8376 8377 8378 8379 8380 8381
  my_realpath(mysql_unpacked_real_data_home, mysql_real_data_home, MYF(0));
  mysql_unpacked_real_data_home_len= 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;


8382
  convert_dirname(language,language,NullS);
unknown's avatar
unknown committed
8383 8384 8385
  (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);
  (void) my_load_path(pidfile_name,pidfile_name,mysql_real_data_home);
unknown's avatar
unknown committed
8386
  (void) my_load_path(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr :
8387
                                      get_relative_path(PLUGINDIR), mysql_home);
8388
  opt_plugin_dir_ptr= opt_plugin_dir;
unknown's avatar
unknown committed
8389

unknown's avatar
unknown committed
8390
  char *sharedir=get_relative_path(SHAREDIR);
unknown's avatar
unknown committed
8391
  if (test_if_hard_path(sharedir))
unknown's avatar
unknown committed
8392
    strmake(buff,sharedir,sizeof(buff)-1);		/* purecov: tested */
unknown's avatar
unknown committed
8393
  else
unknown's avatar
unknown committed
8394
    strxnmov(buff,sizeof(buff)-1,mysql_home,sharedir,NullS);
8395
  convert_dirname(buff,buff,NullS);
unknown's avatar
unknown committed
8396 8397 8398 8399 8400
  (void) my_load_path(language,language,buff);

  /* If --character-sets-dir isn't given, use shared library dir */
  if (charsets_dir != mysql_charsets_dir)
  {
unknown's avatar
unknown committed
8401 8402
    strxnmov(mysql_charsets_dir, sizeof(mysql_charsets_dir)-1, buff,
	     CHARSET_DIR, NullS);
unknown's avatar
unknown committed
8403
  }
unknown's avatar
unknown committed
8404
  (void) my_load_path(mysql_charsets_dir, mysql_charsets_dir, buff);
8405
  convert_dirname(mysql_charsets_dir, mysql_charsets_dir, NullS);
unknown's avatar
unknown committed
8406
  charsets_dir=mysql_charsets_dir;
unknown's avatar
unknown committed
8407

unknown's avatar
unknown committed
8408
  if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir))
unknown's avatar
unknown committed
8409
    exit(1);
unknown's avatar
SCRUM  
unknown committed
8410
#ifdef HAVE_REPLICATION
8411 8412
  if (!slave_load_tmpdir)
  {
unknown's avatar
unknown committed
8413 8414
    if (!(slave_load_tmpdir = (char*) my_strdup(mysql_tmpdir, MYF(MY_FAE))))
      exit(1);
8415
  }
8416
#endif /* HAVE_REPLICATION */
8417 8418 8419 8420 8421 8422 8423 8424 8425 8426
  /*
    Convert the secure-file-priv option to system format, allowing
    a quick strcmp to check if read or write is in an allowed dir
   */
  if (opt_secure_file_priv)
  {
    convert_dirname(buff, opt_secure_file_priv, NullS);
    my_free(opt_secure_file_priv, MYF(0));
    opt_secure_file_priv= my_strdup(buff, MYF(MY_FAE));
  }
unknown's avatar
unknown committed
8427 8428 8429
}


8430 8431 8432 8433 8434 8435 8436 8437 8438 8439 8440 8441 8442 8443 8444 8445 8446 8447 8448 8449 8450 8451 8452 8453
static ulong find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
                                   const char *option)
{
  ulong res;

  const char **ptr;
  
  if ((res= find_bit_type(x, bit_lib)) == ~(ulong) 0)
  {
    ptr= bit_lib->type_names;
    if (!*x)
      fprintf(stderr, "No option given to %s\n", option);
    else
      fprintf(stderr, "Wrong option to %s. Option(s) given: %s\n", option, x);
    fprintf(stderr, "Alternatives are: '%s'", *ptr);
    while (*++ptr)
      fprintf(stderr, ",'%s'", *ptr);
    fprintf(stderr, "\n");
    exit(1);
  }
  return res;
}


unknown's avatar
unknown committed
8454 8455 8456 8457 8458
/**
  @return
    a bitfield from a string of substrings separated by ','
    or
    ~(ulong) 0 on error.
8459
*/
8460 8461 8462 8463 8464 8465 8466 8467 8468 8469 8470 8471 8472

static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
{
  bool found_end;
  int  found_count;
  const char *end,*i,*j;
  const char **array, *pos;
  ulong found,found_int,bit;
  DBUG_ENTER("find_bit_type");
  DBUG_PRINT("enter",("x: '%s'",x));

  found=0;
  found_end= 0;
8473
  pos=(char *) x;
8474 8475 8476
  while (*pos == ' ') pos++;
  found_end= *pos == 0;
  while (!found_end)
8477 8478 8479 8480
  {
    if (!*(end=strcend(pos,',')))		/* Let end point at fieldend */
    {
      while (end > pos && end[-1] == ' ')
unknown's avatar
unknown committed
8481
	end--;					/* Skip end-space */
8482 8483 8484 8485 8486 8487 8488 8489
      found_end=1;
    }
    found_int=0; found_count=0;
    for (array=bit_lib->type_names, bit=1 ; (i= *array++) ; bit<<=1)
    {
      j=pos;
      while (j != end)
      {
unknown's avatar
unknown committed
8490 8491
	if (my_toupper(mysqld_charset,*i++) !=
            my_toupper(mysqld_charset,*j++))
8492
	  goto skip;
8493 8494 8495 8496 8497 8498 8499 8500 8501 8502 8503
      }
      found_int=bit;
      if (! *i)
      {
	found_count=1;
	break;
      }
      else if (j != pos)			// Half field found
      {
	found_count++;				// Could be one of two values
      }
8504
skip: ;
8505 8506 8507 8508 8509
    }
    if (found_count != 1)
      DBUG_RETURN(~(ulong) 0);				// No unique value
    found|=found_int;
    pos=end+1;
8510
  }
8511 8512 8513 8514 8515 8516

  DBUG_PRINT("exit",("bit-field: %ld",(ulong) found));
  DBUG_RETURN(found);
} /* find_bit_type */


unknown's avatar
unknown committed
8517 8518
/**
  Check if file system used for databases is case insensitive.
8519

unknown's avatar
unknown committed
8520
  @param dir_name			Directory to test
8521

unknown's avatar
unknown committed
8522
  @retval
8523
    -1  Don't know (Test failed)
unknown's avatar
unknown committed
8524
  @retval
8525
    0   File system is case sensitive
unknown's avatar
unknown committed
8526
  @retval
8527 8528 8529 8530 8531 8532 8533 8534 8535
    1   File system is case insensitive
*/

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;
8536
  DBUG_ENTER("test_if_case_insensitive");
8537 8538 8539 8540 8541 8542 8543 8544

  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);
  (void) my_delete(buff2, MYF(0));
  if ((file= my_create(buff, 0666, O_RDWR, MYF(0))) < 0)
  {
8545
    sql_print_warning("Can't create test file %s", buff);
8546
    DBUG_RETURN(-1);
8547 8548 8549 8550 8551
  }
  my_close(file, MYF(0));
  if (my_stat(buff2, &stat_info, MYF(0)))
    result= 1;					// Can access file
  (void) my_delete(buff, MYF(MY_WME));
8552 8553
  DBUG_PRINT("exit", ("result: %d", result));
  DBUG_RETURN(result);
8554 8555 8556
}


8557 8558
#ifndef EMBEDDED_LIBRARY

unknown's avatar
unknown committed
8559 8560 8561
/**
  Create file to store pid number.
*/
8562 8563 8564 8565 8566 8567
static void create_pid_file()
{
  File file;
  if ((file = my_create(pidfile_name,0664,
			O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0)
  {
unknown's avatar
unknown committed
8568
    char buff[21], *end;
8569
    end= int10_to_str((long) getpid(), buff, 10);
unknown's avatar
unknown committed
8570
    *end++= '\n';
8571
    if (!my_write(file, (uchar*) buff, (uint) (end-buff), MYF(MY_WME | MY_NABP)))
8572 8573 8574 8575
    {
      (void) my_close(file, MYF(0));
      return;
    }
8576 8577
    (void) my_close(file, MYF(0));
  }
8578
  sql_perror("Can't start server: can't create PID file");
unknown's avatar
foo1  
unknown committed
8579
  exit(1);
8580
}
8581
#endif /* EMBEDDED_LIBRARY */
8582

unknown's avatar
unknown committed
8583
/** Clear most status variables. */
8584 8585 8586 8587
void refresh_status(THD *thd)
{
  pthread_mutex_lock(&LOCK_status);

8588
  /* Add thread's status variabes to global status */
8589
  add_to_status(&global_status_var, &thd->status_var);
8590 8591

  /* Reset thread's status variables */
8592
  bzero((uchar*) &thd->status_var, sizeof(thd->status_var));
8593

8594
  /* Reset some global variables */
unknown's avatar
unknown committed
8595
  reset_status_vars();
8596

8597 8598
  /* Reset the counters of all key caches (default and named). */
  process_key_caches(reset_key_cache_counters);
8599
#ifdef COMMUNITY_SERVER
8600
  flush_status_time= time((time_t*) 0);
8601
#endif
8602 8603 8604 8605 8606 8607 8608 8609 8610 8611 8612
  pthread_mutex_unlock(&LOCK_status);

  /*
    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.
  */
  pthread_mutex_lock(&LOCK_thread_count);
  max_used_connections= thread_count-delayed_insert_threads;
  pthread_mutex_unlock(&LOCK_thread_count);
8613 8614 8615
}


8616
/*****************************************************************************
unknown's avatar
unknown committed
8617 8618
  Instantiate variables for missing storage engines
  This section should go away soon
8619 8620 8621 8622
*****************************************************************************/

#ifndef WITH_NDBCLUSTER_STORAGE_ENGINE
ulong ndb_cache_check_time;
unknown's avatar
unknown committed
8623
ulong ndb_extra_logging;
8624 8625
#endif

unknown's avatar
unknown committed
8626
/*****************************************************************************
8627
  Instantiate templates
unknown's avatar
unknown committed
8628 8629
*****************************************************************************/

8630
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
unknown's avatar
unknown committed
8631 8632 8633 8634
/* Used templates */
template class I_List<THD>;
template class I_List_iterator<THD>;
template class I_List<i_string>;
8635
template class I_List<i_string_pair>;
8636
template class I_List<NAMED_LIST>;
8637 8638
template class I_List<Statement>;
template class I_List_iterator<Statement>;
unknown's avatar
unknown committed
8639
#endif