~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2003 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
#include "mysql_priv.h"
17
#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"
23
#include "rpl_filter.h"
24
#include "repl_failsafe.h"
25
#include "stacktrace.h"
26
#include "mysqld_suffix.h"
27
#include "mysys_err.h"
28
29
#include "../storage/myisam/ha_myisam.h"
30
31
#ifdef HAVE_SYS_PRCTL_H
32
#include <sys/prctl.h>
33
#endif
34
35
#ifndef DEFAULT_SKIP_THREAD_PRIORITY
36
#define DEFAULT_SKIP_THREAD_PRIORITY 0
37
#endif
38
39
#include <thr_alarm.h>
40
#include <errmsg.h>
41
42
#define mysqld_charset &my_charset_latin1
43
44
#ifdef HAVE_purify
45
#define IF_PURIFY(A,B) (A)
46
#else
47
#define IF_PURIFY(A,B) (B)
48
#endif
49
50
#if SIZEOF_CHARP == 4
51
#define MAX_MEM_TABLE_SIZE ~(ulong) 0
52
#else
53
#define MAX_MEM_TABLE_SIZE ~(ulonglong) 0
54
#endif
55
56
/* We have HAVE_purify below as this speeds up the shutdown of MySQL */
57
58
#if defined(HAVE_DEC_3_2_THREADS) || defined(SIGNALS_DONT_BREAK_READ) || defined(HAVE_purify) && defined(__linux__)
59
#define HAVE_CLOSE_SERVER_SOCK 1
60
#endif
61
62
extern "C" {					// Because of SCO 3.2V4.2
63
#include <errno.h>
64
#include <sys/stat.h>
65
#ifndef __GNU_LIBRARY__
66
#define __GNU_LIBRARY__				// Skip warnings in getopt.h
67
#endif
68
#include <my_getopt.h>
69
#ifdef HAVE_SYSENT_H
70
#include <sysent.h>
71
#endif
72
#ifdef HAVE_PWD_H
73
#include <pwd.h>				// For getpwent
74
#endif
75
#ifdef HAVE_GRP_H
76
#include <grp.h>
77
#endif
78
#include <my_net.h>
79
80
#include <sys/resource.h>
81
82
#ifdef HAVE_SELECT_H
83
#  include <select.h>
84
#endif
85
86
#ifdef HAVE_SYS_SELECT_H
87
#include <sys/select.h>
88
#endif
89
90
#include <sys/utsname.h>
91
92
#ifdef HAVE_SYS_MMAN_H
93
#include <sys/mman.h>
94
#endif
95
96
#define SIGNAL_FMT "signal %d"
97
  
98
99
#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
100
#include <ieeefp.h>
101
#ifdef HAVE_FP_EXCEPT				// Fix type conflict
102
typedef fp_except fp_except_t;
103
#endif
104
#endif /* __FreeBSD__ && HAVE_IEEEFP_H */
105
106
#ifdef HAVE_FPU_CONTROL_H
107
#include <fpu_control.h>
108
#endif
109
110
#ifdef HAVE_SYS_FPU_H
111
/* for IRIX to use set_fpc_csr() */
112
#include <sys/fpu.h>
113
#endif
114
115
inline void setup_fpu()
116
{
117
#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
118
  /*
119
     We can't handle floating point exceptions with threads, so disable
120
     this on freebsd.
121
     Don't fall for overflow, underflow,divide-by-zero or loss of precision
122
  */
123
#if defined(__i386__)
124
  fpsetmask(~(FP_X_INV | FP_X_DNML | FP_X_OFL | FP_X_UFL | FP_X_DZ |
125
	      FP_X_IMP));
126
#else
127
  fpsetmask(~(FP_X_INV |             FP_X_OFL | FP_X_UFL | FP_X_DZ |
128
              FP_X_IMP));
129
#endif /* __i386__ */
130
#endif /* __FreeBSD__ && HAVE_IEEEFP_H */
131
132
  /*
133
    x86 (32-bit) requires FPU precision to be explicitly set to 64 bit for
134
    portable results of floating point operations
135
  */
136
#if defined(__i386__) && defined(HAVE_FPU_CONTROL_H) && defined(_FPU_DOUBLE)
137
  fpu_control_t cw;
138
  _FPU_GETCW(cw);
139
  cw= (cw & ~_FPU_EXTENDED) | _FPU_DOUBLE;
140
  _FPU_SETCW(cw);
141
#endif /* __i386__ && HAVE_FPU_CONTROL_H && _FPU_DOUBLE */
142
}
143
144
} /* cplusplus */
145
146
#define MYSQL_KILL_SIGNAL SIGTERM
147
148
#include <my_pthread.h>			// For thr_setconcurency()
149
150
#ifdef SOLARIS
151
extern "C" int gethostname(char *name, int namelen);
152
#endif
153
154
extern "C" sig_handler handle_segfault(int sig);
155
156
/* Constants */
157
158
const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"};
159
/*
160
  WARNING: When adding new SQL modes don't forget to update the
161
           tables definitions that stores it's value.
162
           (ie: mysql.event, mysql.proc)
163
*/
164
static const char *optimizer_switch_names[]=
165
{
166
  "no_materialization", "no_semijoin",
167
  NullS
168
};
169
170
/* Corresponding defines are named OPTIMIZER_SWITCH_XXX */
171
static const unsigned int optimizer_switch_names_len[]=
172
{
173
  /*no_materialization*/          19,
174
  /*no_semijoin*/                 11
175
};
176
177
TYPELIB optimizer_switch_typelib= { array_elements(optimizer_switch_names)-1,"",
178
                                    optimizer_switch_names,
179
                                    (unsigned int *)optimizer_switch_names_len };
180
181
static const char *tc_heuristic_recover_names[]=
182
{
183
  "COMMIT", "ROLLBACK", NullS
184
};
185
static TYPELIB tc_heuristic_recover_typelib=
186
{
187
  array_elements(tc_heuristic_recover_names)-1,"",
188
  tc_heuristic_recover_names, NULL
189
};
190
191
const char *first_keyword= "first", *binary_keyword= "BINARY";
192
const char *my_localhost= "localhost";
193
#if SIZEOF_OFF_T > 4 && defined(BIG_TABLES)
194
#define GET_HA_ROWS GET_ULL
195
#else
196
#define GET_HA_ROWS GET_ULONG
197
#endif
198
199
/*
200
  Used with --help for detailed option
201
*/
202
static my_bool opt_help= 0, opt_verbose= 0;
203
204
arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
205
{{&Arg_comparator::compare_string,     &Arg_comparator::compare_e_string},
206
 {&Arg_comparator::compare_real,       &Arg_comparator::compare_e_real},
207
 {&Arg_comparator::compare_int_signed, &Arg_comparator::compare_e_int},
208
 {&Arg_comparator::compare_row,        &Arg_comparator::compare_e_row},
209
 {&Arg_comparator::compare_decimal,    &Arg_comparator::compare_e_decimal}};
210
211
const char *log_output_names[] = { "NONE", "FILE", "TABLE", NullS};
212
static const unsigned int log_output_names_len[]= { 4, 4, 5, 0 };
213
TYPELIB log_output_typelib= {array_elements(log_output_names)-1,"",
214
                             log_output_names, 
215
                             (unsigned int *) log_output_names_len};
216
217
/* static variables */
218
219
/* the default log output is log tables */
220
static bool lower_case_table_names_used= 0;
221
static bool volatile select_thread_in_use, signal_thread_in_use;
222
static bool volatile ready_to_exit;
223
static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0;
224
static my_bool opt_short_log_format= 0;
225
static uint kill_cached_threads, wake_thread;
226
static ulong killed_threads, thread_created;
227
static ulong max_used_connections;
228
static volatile ulong cached_thread_count= 0;
229
static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr;
230
static char *opt_init_slave, *language_ptr, *opt_init_connect;
231
static char *default_character_set_name;
232
static char *character_set_filesystem_name;
233
static char *lc_time_names_name;
234
static char *my_bind_addr_str;
235
static char *default_collation_name; 
236
static char *default_storage_engine_str;
237
static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME;
238
static I_List<THD> thread_cache;
239
static double long_query_time;
240
241
static pthread_cond_t COND_thread_cache, COND_flush_thread_cache;
242
243
/* Global variables */
244
245
bool opt_update_log, opt_bin_log;
246
my_bool opt_log, opt_slow_log;
247
ulong log_output_options;
248
my_bool opt_log_queries_not_using_indexes= 0;
249
bool opt_error_log= IF_WIN(1,0);
250
bool opt_disable_networking=0, opt_skip_show_db=0;
251
my_bool opt_character_set_client_handshake= 1;
252
bool server_id_supplied = 0;
253
bool opt_endinfo, using_udf_functions;
254
my_bool locked_in_memory;
255
bool opt_using_transactions, using_update_log;
256
bool volatile abort_loop;
257
bool volatile shutdown_in_progress;
258
my_bool opt_skip_slave_start = 0; ///< If set, slave is not autostarted
259
my_bool opt_reckless_slave = 0;
260
my_bool opt_enable_named_pipe= 0;
261
my_bool opt_local_infile, opt_slave_compressed_protocol;
262
my_bool opt_safe_user_create = 0;
263
my_bool opt_show_slave_auth_info, opt_sql_bin_update = 0;
264
my_bool opt_log_slave_updates= 0;
265
266
/*
267
  Legacy global handlerton. These will be removed (please do not add more).
268
*/
269
handlerton *heap_hton;
270
handlerton *myisam_hton;
271
272
my_bool opt_readonly, use_temp_pool, relay_log_purge;
273
my_bool opt_sync_frm, opt_allow_suspicious_udfs;
274
my_bool opt_secure_auth= 0;
275
char* opt_secure_file_priv= 0;
276
my_bool opt_log_slow_admin_statements= 0;
277
my_bool opt_log_slow_slave_statements= 0;
278
my_bool lower_case_file_system= 0;
279
my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
280
/*
281
  True if there is at least one per-hour limit for some user, so we should
282
  check them before each query (and possibly reset counters when hour is
283
  changed). False otherwise.
284
*/
285
volatile bool mqh_used = 0;
286
my_bool opt_noacl;
287
288
ulong opt_binlog_rows_event_max_size;
289
const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS};
290
TYPELIB binlog_format_typelib=
291
  { array_elements(binlog_format_names) - 1, "",
292
    binlog_format_names, NULL };
293
ulong opt_binlog_format_id= (ulong) BINLOG_FORMAT_UNSPEC;
294
const char *opt_binlog_format= binlog_format_names[opt_binlog_format_id];
295
#ifdef HAVE_INITGROUPS
296
static bool calling_initgroups= FALSE; /**< Used in SIGSEGV handler. */
297
#endif
298
uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
299
uint mysqld_port_timeout;
300
uint delay_key_write_options, protocol_version;
301
uint lower_case_table_names;
302
uint tc_heuristic_recover= 0;
303
uint volatile thread_count, thread_running;
304
ulonglong thd_startup_options;
9 by Brian Aker
Warnings cleanup
305
ulong back_log, connect_timeout, server_id;
1 by brian
clean slate
306
ulong table_cache_size, table_def_size;
307
ulong what_to_log;
308
ulong query_buff_size, slow_launch_time, slave_open_temp_tables;
309
ulong open_files_limit, max_binlog_size, max_relay_log_size;
310
ulong slave_net_timeout, slave_trans_retries;
311
my_bool slave_allow_batching;
312
ulong slave_exec_mode_options;
313
const char *slave_exec_mode_str= "STRICT";
314
ulong thread_cache_size=0, thread_pool_size= 0;
315
ulong binlog_cache_size=0, max_binlog_cache_size=0;
316
ulong refresh_version;  /* Increments on each reload */
317
query_id_t global_query_id;
318
ulong aborted_threads, aborted_connects;
319
ulong flush_time;
320
ulong specialflag=0;
321
ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
322
ulong max_connections, max_connect_errors;
323
uint  max_user_connections= 0;
324
ulong thread_id=1L,current_pid;
325
ulong slow_launch_threads = 0, sync_binlog_period;
326
ulong expire_logs_days = 0;
327
ulong rpl_recovery_rank=0;
328
const char *log_output_str= "FILE";
329
330
const double log_10[] = {
331
  1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007, 1e008, 1e009,
332
  1e010, 1e011, 1e012, 1e013, 1e014, 1e015, 1e016, 1e017, 1e018, 1e019,
333
  1e020, 1e021, 1e022, 1e023, 1e024, 1e025, 1e026, 1e027, 1e028, 1e029,
334
  1e030, 1e031, 1e032, 1e033, 1e034, 1e035, 1e036, 1e037, 1e038, 1e039,
335
  1e040, 1e041, 1e042, 1e043, 1e044, 1e045, 1e046, 1e047, 1e048, 1e049,
336
  1e050, 1e051, 1e052, 1e053, 1e054, 1e055, 1e056, 1e057, 1e058, 1e059,
337
  1e060, 1e061, 1e062, 1e063, 1e064, 1e065, 1e066, 1e067, 1e068, 1e069,
338
  1e070, 1e071, 1e072, 1e073, 1e074, 1e075, 1e076, 1e077, 1e078, 1e079,
339
  1e080, 1e081, 1e082, 1e083, 1e084, 1e085, 1e086, 1e087, 1e088, 1e089,
340
  1e090, 1e091, 1e092, 1e093, 1e094, 1e095, 1e096, 1e097, 1e098, 1e099,
341
  1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109,
342
  1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119,
343
  1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129,
344
  1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139,
345
  1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149,
346
  1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159,
347
  1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169,
348
  1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179,
349
  1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189,
350
  1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199,
351
  1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209,
352
  1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219,
353
  1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229,
354
  1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239,
355
  1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249,
356
  1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259,
357
  1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269,
358
  1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279,
359
  1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289,
360
  1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299,
361
  1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308
362
};
363
364
time_t server_start_time, flush_status_time;
365
366
char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
367
char *default_tz_name;
368
char log_error_file[FN_REFLEN], glob_hostname[FN_REFLEN];
369
char mysql_real_data_home[FN_REFLEN],
370
     language[FN_REFLEN], reg_ext[FN_EXTLEN], mysql_charsets_dir[FN_REFLEN],
371
     *opt_init_file, *opt_tc_log_file;
372
char mysql_unpacked_real_data_home[FN_REFLEN];
373
uint reg_ext_length;
374
const key_map key_map_empty(0);
375
key_map key_map_full(0);                        // Will be initialized later
376
377
const char *opt_date_time_formats[3];
378
379
uint mysql_data_home_len;
380
char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home;
381
char server_version[SERVER_VERSION_LENGTH];
11 by Brian Aker
Removing old UNIX socket bits
382
char *opt_mysql_tmpdir;
1 by brian
clean slate
383
const char **errmesg;			/**< Error messages */
384
const char *myisam_recover_options_str="OFF";
385
const char *myisam_stats_method_str="nulls_unequal";
386
387
/** name of reference on left espression in rewritten IN subquery */
388
const char *in_left_expr_name= "<left expr>";
389
/** name of additional condition */
390
const char *in_additional_cond= "<IN COND>";
391
const char *in_having_cond= "<IN HAVING>";
392
393
my_decimal decimal_zero;
394
/* classes for comparation parsing/processing */
395
Eq_creator eq_creator;
396
Ne_creator ne_creator;
397
Gt_creator gt_creator;
398
Lt_creator lt_creator;
399
Ge_creator ge_creator;
400
Le_creator le_creator;
401
402
FILE *bootstrap_file;
403
int bootstrap_error;
404
FILE *stderror_file=0;
405
406
I_List<THD> threads;
407
I_List<NAMED_LIST> key_caches;
408
Rpl_filter* rpl_filter;
409
Rpl_filter* binlog_filter;
410
411
struct system_variables global_system_variables;
412
struct system_variables max_system_variables;
413
struct system_status_var global_status_var;
414
415
MY_TMPDIR mysql_tmpdir_list;
416
MY_BITMAP temp_pool;
417
418
CHARSET_INFO *system_charset_info, *files_charset_info ;
419
CHARSET_INFO *national_charset_info, *table_alias_charset;
420
CHARSET_INFO *character_set_filesystem;
421
422
MY_LOCALE *my_default_lc_time_names;
423
424
SHOW_COMP_OPTION have_symlink, have_dlopen;
425
SHOW_COMP_OPTION have_crypt, have_compress;
426
427
/* Thread specific variables */
428
429
pthread_key(MEM_ROOT**,THR_MALLOC);
430
pthread_key(THD*, THR_THD);
431
pthread_mutex_t LOCK_mysql_create_db, LOCK_open, LOCK_thread_count,
432
		LOCK_mapped_file, LOCK_status, LOCK_global_read_lock,
433
		LOCK_error_log, LOCK_uuid_generator,
12 by Brian Aker
More dead code removal.
434
		LOCK_crypt,
1 by brian
clean slate
435
	        LOCK_global_system_variables,
436
		LOCK_user_conn, LOCK_slave_list, LOCK_active_mi,
437
                LOCK_connection_count;
438
439
rw_lock_t	LOCK_sys_init_connect, LOCK_sys_init_slave;
440
rw_lock_t	LOCK_system_variables_hash;
441
pthread_cond_t COND_refresh, COND_thread_count, COND_global_read_lock;
442
pthread_t signal_thread;
443
pthread_attr_t connection_attrib;
444
pthread_cond_t  COND_server_started;
445
446
/* replication parameters, if master_host is not NULL, we are a slave */
447
uint report_port= MYSQL_PORT;
448
ulong master_retry_count=0;
449
char *master_info_file;
450
char *relay_log_info_file, *report_user, *report_password, *report_host;
451
char *opt_relay_logname = 0, *opt_relaylog_index_name=0;
452
char *opt_logname, *opt_slow_logname;
453
454
/* Static variables */
455
456
static bool kill_in_progress, segfaulted;
457
#ifdef HAVE_STACK_TRACE_ON_SEGV
458
static my_bool opt_do_pstack;
459
#endif /* HAVE_STACK_TRACE_ON_SEGV */
460
static my_bool opt_bootstrap, opt_myisam_log;
461
static int cleanup_done;
462
static ulong opt_specialflag, opt_myisam_block_size;
463
static char *opt_update_logname, *opt_binlog_index_name;
464
static char *opt_tc_heuristic_recover;
465
static char *mysql_home_ptr, *pidfile_name_ptr;
466
static int defaults_argc;
467
static char **defaults_argv;
468
static char *opt_bin_logname;
469
11 by Brian Aker
Removing old UNIX socket bits
470
static my_socket ip_sock;
1 by brian
clean slate
471
struct rand_struct sql_rand; ///< used by sql_class.cc:THD::THD()
472
473
struct passwd *user_info;
474
static pthread_t select_thread;
475
static uint thr_kill_signal;
476
477
/* OS specific variables */
478
479
bool mysqld_embedded=0;
480
481
#ifndef DBUG_OFF
482
static const char* default_dbug_option;
483
#endif
484
485
scheduler_functions thread_scheduler;
486
487
/**
488
  Number of currently active user connections. The variable is protected by
489
  LOCK_connection_count.
490
*/
491
uint connection_count= 0;
492
493
/* Function declarations */
494
495
pthread_handler_t signal_hand(void *arg);
496
static void mysql_init_variables(void);
497
static void get_options(int *argc,char **argv);
498
extern "C" my_bool mysqld_get_one_option(int, const struct my_option *, char *);
499
static void set_server_version(void);
500
static int init_thread_environment();
501
static char *get_relative_path(const char *path);
502
static void fix_paths(void);
11 by Brian Aker
Removing old UNIX socket bits
503
void handle_connections_sockets();
1 by brian
clean slate
504
pthread_handler_t kill_server_thread(void *arg);
505
static void bootstrap(FILE *file);
506
static bool read_init_file(char *file_name);
507
pthread_handler_t handle_slave(void *arg);
508
static ulong find_bit_type(const char *x, TYPELIB *bit_lib);
509
static ulong find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
510
                                   const char *option);
511
static void clean_up(bool print_message);
512
static int test_if_case_insensitive(const char *dir_name);
513
514
static void usage(void);
515
static void start_signal_handler(void);
516
static void close_server_sock();
517
static void clean_up_mutexes(void);
518
static void wait_for_signal_thread_to_end(void);
519
static void create_pid_file();
520
static void mysqld_exit(int exit_code) __attribute__((noreturn));
521
522
/****************************************************************************
523
** Code to end mysqld
524
****************************************************************************/
525
526
static void close_connections(void)
527
{
528
#ifdef EXTRA_DEBUG
529
  int count=0;
530
#endif
531
  DBUG_ENTER("close_connections");
532
533
  /* Clear thread cache */
534
  kill_cached_threads++;
535
  flush_thread_cache();
536
537
  /* kill flush thread */
538
  (void) pthread_mutex_lock(&LOCK_manager);
539
  if (manager_thread_in_use)
540
  {
541
    DBUG_PRINT("quit", ("killing manager thread: 0x%lx",
542
                        (ulong)manager_thread));
543
   (void) pthread_cond_signal(&COND_manager);
544
  }
545
  (void) pthread_mutex_unlock(&LOCK_manager);
546
547
  /* kill connection thread */
548
  DBUG_PRINT("quit", ("waiting for select thread: 0x%lx",
549
                      (ulong) select_thread));
550
  (void) pthread_mutex_lock(&LOCK_thread_count);
551
552
  while (select_thread_in_use)
553
  {
554
    struct timespec abstime;
555
    int error;
556
    DBUG_PRINT("info",("Waiting for select thread"));
557
558
#ifndef DONT_USE_THR_ALARM
559
    if (pthread_kill(select_thread, thr_client_alarm))
560
      break;					// allready dead
561
#endif
562
    set_timespec(abstime, 2);
563
    for (uint tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
564
    {
565
      error=pthread_cond_timedwait(&COND_thread_count,&LOCK_thread_count,
566
				   &abstime);
567
      if (error != EINTR)
568
	break;
569
    }
570
#ifdef EXTRA_DEBUG
571
    if (error != 0 && !count++)
572
      sql_print_error("Got error %d from pthread_cond_timedwait",error);
573
#endif
574
    close_server_sock();
575
  }
576
  (void) pthread_mutex_unlock(&LOCK_thread_count);
577
578
579
  /* Abort listening to new connections */
580
  DBUG_PRINT("quit",("Closing sockets"));
581
  if (!opt_disable_networking )
582
  {
583
    if (ip_sock != INVALID_SOCKET)
584
    {
585
      (void) shutdown(ip_sock, SHUT_RDWR);
586
      (void) closesocket(ip_sock);
587
      ip_sock= INVALID_SOCKET;
588
    }
589
  }
590
  end_thr_alarm(0);			 // Abort old alarms.
591
592
  /*
593
    First signal all threads that it's time to die
594
    This will give the threads some time to gracefully abort their
595
    statements and inform their clients that the server is about to die.
596
  */
597
598
  THD *tmp;
599
  (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
600
601
  I_List_iterator<THD> it(threads);
602
  while ((tmp=it++))
603
  {
604
    DBUG_PRINT("quit",("Informing thread %ld that it's time to die",
605
		       tmp->thread_id));
606
    /* We skip slave threads & scheduler on this first loop through. */
607
    if (tmp->slave_thread)
608
      continue;
609
610
    tmp->killed= THD::KILL_CONNECTION;
611
    thread_scheduler.post_kill_notification(tmp);
612
    if (tmp->mysys_var)
613
    {
614
      tmp->mysys_var->abort=1;
615
      pthread_mutex_lock(&tmp->mysys_var->mutex);
616
      if (tmp->mysys_var->current_cond)
617
      {
618
	pthread_mutex_lock(tmp->mysys_var->current_mutex);
619
	pthread_cond_broadcast(tmp->mysys_var->current_cond);
620
	pthread_mutex_unlock(tmp->mysys_var->current_mutex);
621
      }
622
      pthread_mutex_unlock(&tmp->mysys_var->mutex);
623
    }
624
  }
625
  (void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list
626
627
  end_slave();
628
629
  if (thread_count)
630
    sleep(2);					// Give threads time to die
631
632
  /*
633
    Force remaining threads to die by closing the connection to the client
634
    This will ensure that threads that are waiting for a command from the
635
    client on a blocking read call are aborted.
636
  */
637
638
  for (;;)
639
  {
640
    DBUG_PRINT("quit",("Locking LOCK_thread_count"));
641
    (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
642
    if (!(tmp=threads.get()))
643
    {
644
      DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
645
      (void) pthread_mutex_unlock(&LOCK_thread_count);
646
      break;
647
    }
648
    if (tmp->vio_ok())
649
    {
650
      if (global_system_variables.log_warnings)
651
        sql_print_warning(ER(ER_FORCING_CLOSE),my_progname,
652
                          tmp->thread_id,
653
                          (tmp->main_security_ctx.user ?
654
                           tmp->main_security_ctx.user : ""));
655
      close_connection(tmp,0,0);
656
    }
657
    DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
658
    (void) pthread_mutex_unlock(&LOCK_thread_count);
659
  }
660
  /* All threads has now been aborted */
661
  DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count));
662
  (void) pthread_mutex_lock(&LOCK_thread_count);
663
  while (thread_count)
664
  {
665
    (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
666
    DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
667
  }
668
  (void) pthread_mutex_unlock(&LOCK_thread_count);
669
670
  DBUG_PRINT("quit",("close_connections thread"));
671
  DBUG_VOID_RETURN;
672
}
673
674
675
static void close_server_sock()
676
{
677
#ifdef HAVE_CLOSE_SERVER_SOCK
678
  DBUG_ENTER("close_server_sock");
679
  my_socket tmp_sock;
680
  tmp_sock=ip_sock;
681
  if (tmp_sock != INVALID_SOCKET)
682
  {
683
    ip_sock=INVALID_SOCKET;
684
    DBUG_PRINT("info",("calling shutdown on TCP/IP socket"));
685
    VOID(shutdown(tmp_sock, SHUT_RDWR));
686
  }
687
  DBUG_VOID_RETURN;
688
#endif
689
}
690
691
692
void kill_mysql(void)
693
{
694
  DBUG_ENTER("kill_mysql");
695
696
#if defined(SIGNALS_DONT_BREAK_READ)
697
  abort_loop=1;					// Break connection loops
698
  close_server_sock();				// Force accept to wake up
699
#endif
700
701
#if defined(HAVE_PTHREAD_KILL)
702
  if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL))
703
  {
704
    DBUG_PRINT("error",("Got error %d from pthread_kill",errno)); /* purecov: inspected */
705
  }
706
#elif !defined(SIGNALS_DONT_BREAK_READ)
707
  kill(current_pid, MYSQL_KILL_SIGNAL);
708
#endif
709
  DBUG_PRINT("quit",("After pthread_kill"));
710
  shutdown_in_progress=1;			// Safety if kill didn't work
711
#ifdef SIGNALS_DONT_BREAK_READ
712
  if (!kill_in_progress)
713
  {
714
    pthread_t tmp;
715
    abort_loop=1;
716
    if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
717
			   (void*) 0))
718
      sql_print_error("Can't create thread to kill server");
719
  }
720
#endif
721
  DBUG_VOID_RETURN;
722
}
723
724
/**
725
  Force server down. Kill all connections and threads and exit.
726
727
  @param  sig_ptr       Signal number that caused kill_server to be called.
728
729
  @note
730
    A signal number of 0 mean that the function was not called
731
    from a signal handler and there is thus no signal to block
732
    or stop, we just want to kill the server.
733
*/
734
735
static void *kill_server(void *sig_ptr)
736
#define RETURN_FROM_KILL_SERVER DBUG_RETURN(0)
737
{
738
  DBUG_ENTER("kill_server");
739
  int sig=(int) (long) sig_ptr;			// This is passed a int
740
  // if there is a signal during the kill in progress, ignore the other
741
  if (kill_in_progress)				// Safety
742
    RETURN_FROM_KILL_SERVER;
743
  kill_in_progress=TRUE;
744
  abort_loop=1;					// This should be set
745
  if (sig != 0) // 0 is not a valid signal number
746
    my_sigset(sig, SIG_IGN);                    /* purify inspected */
747
  if (sig == MYSQL_KILL_SIGNAL || sig == 0)
748
    sql_print_information(ER(ER_NORMAL_SHUTDOWN),my_progname);
749
  else
750
    sql_print_error(ER(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */
751
  
752
  close_connections();
753
  if (sig != MYSQL_KILL_SIGNAL &&
754
      sig != 0)
755
    unireg_abort(1);				/* purecov: inspected */
756
  else
757
    unireg_end();
758
759
  /* purecov: begin deadcode */
760
761
  my_thread_end();
762
  pthread_exit(0);
763
  /* purecov: end */
764
765
  RETURN_FROM_KILL_SERVER;
766
}
767
768
769
#if defined(USE_ONE_SIGNAL_HAND)
770
pthread_handler_t kill_server_thread(void *arg __attribute__((unused)))
771
{
772
  my_thread_init();				// Initialize new thread
773
  kill_server(0);
774
  /* purecov: begin deadcode */
775
  my_thread_end();
776
  pthread_exit(0);
777
  return 0;
778
  /* purecov: end */
779
}
780
#endif
781
782
783
extern "C" sig_handler print_signal_warning(int sig)
784
{
785
  if (global_system_variables.log_warnings)
786
    sql_print_warning("Got signal %d from thread %ld", sig,my_thread_id());
787
#ifdef DONT_REMEMBER_SIGNAL
788
  my_sigset(sig,print_signal_warning);		/* int. thread system calls */
789
#endif
790
  if (sig == SIGALRM)
791
    alarm(2);					/* reschedule alarm */
792
}
793
794
/**
795
  cleanup all memory and end program nicely.
796
797
    If SIGNALS_DONT_BREAK_READ is defined, this function is called
798
    by the main thread. To get MySQL to shut down nicely in this case
799
    (Mac OS X) we have to call exit() instead if pthread_exit().
800
801
  @note
802
    This function never returns.
803
*/
804
void unireg_end(void)
805
{
806
  clean_up(1);
807
  my_thread_end();
808
#if defined(SIGNALS_DONT_BREAK_READ)
809
  exit(0);
810
#else
811
  pthread_exit(0);				// Exit is in main thread
812
#endif
813
}
814
815
816
extern "C" void unireg_abort(int exit_code)
817
{
818
  DBUG_ENTER("unireg_abort");
819
820
  if (exit_code)
821
    sql_print_error("Aborting\n");
822
  else if (opt_help)
823
    usage();
824
  clean_up(!opt_help && (exit_code || !opt_bootstrap)); /* purecov: inspected */
825
  DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
826
  mysqld_exit(exit_code);
827
}
828
829
830
static void mysqld_exit(int exit_code)
831
{
832
  wait_for_signal_thread_to_end();
833
  clean_up_mutexes();
834
  my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
835
  exit(exit_code); /* purecov: inspected */
836
}
837
838
839
void clean_up(bool print_message)
840
{
841
  DBUG_PRINT("exit",("clean_up"));
842
  if (cleanup_done++)
843
    return; /* purecov: inspected */
844
845
  /*
846
    make sure that handlers finish up
847
    what they have that is dependent on the binlog
848
  */
849
  ha_binlog_end(current_thd);
850
851
  logger.cleanup_base();
852
853
  mysql_bin_log.cleanup();
854
855
  if (use_slave_mask)
856
    bitmap_free(&slave_error_mask);
857
  my_database_names_free();
858
  table_cache_free();
859
  table_def_free();
860
  lex_free();				/* Free some memory */
861
  item_create_cleanup();
862
  set_var_free();
863
  free_charsets();
864
  udf_free();
865
  plugin_shutdown();
866
  ha_end();
867
  if (tc_log)
868
    tc_log->close();
869
  xid_cache_free();
870
  delete_elements(&key_caches, (void (*)(const char*, uchar*)) free_key_cache);
871
  multi_keycache_free();
872
  free_status_vars();
873
  end_thr_alarm(1);			/* Free allocated memory */
874
  my_free_open_file_info();
875
  my_free((char*) global_system_variables.date_format,
876
	  MYF(MY_ALLOW_ZERO_PTR));
877
  my_free((char*) global_system_variables.time_format,
878
	  MYF(MY_ALLOW_ZERO_PTR));
879
  my_free((char*) global_system_variables.datetime_format,
880
	  MYF(MY_ALLOW_ZERO_PTR));
881
  if (defaults_argv)
882
    free_defaults(defaults_argv);
883
  my_free(sys_init_connect.value, MYF(MY_ALLOW_ZERO_PTR));
884
  my_free(sys_init_slave.value, MYF(MY_ALLOW_ZERO_PTR));
885
  my_free(sys_var_general_log_path.value, MYF(MY_ALLOW_ZERO_PTR));
886
  my_free(sys_var_slow_log_path.value, MYF(MY_ALLOW_ZERO_PTR));
887
  free_tmpdir(&mysql_tmpdir_list);
888
  my_free(slave_load_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
889
  x_free(opt_bin_logname);
890
  x_free(opt_relay_logname);
891
  x_free(opt_secure_file_priv);
892
  bitmap_free(&temp_pool);
893
  end_slave_list();
894
  delete binlog_filter;
895
  delete rpl_filter;
896
  vio_end();
897
898
  if (!opt_bootstrap)
899
    (void) my_delete(pidfile_name,MYF(0));	// This may not always exist
900
  if (print_message && errmesg && server_start_time)
901
    sql_print_information(ER(ER_SHUTDOWN_COMPLETE),my_progname);
902
  thread_scheduler.end();
903
  finish_client_errs();
904
  my_free((uchar*) my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST),
905
          MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
906
  DBUG_PRINT("quit", ("Error messages freed"));
907
  /* Tell main we are ready */
908
  logger.cleanup_end();
909
  (void) pthread_mutex_lock(&LOCK_thread_count);
910
  DBUG_PRINT("quit", ("got thread count lock"));
911
  ready_to_exit=1;
912
  /* do the broadcast inside the lock to ensure that my_end() is not called */
913
  (void) pthread_cond_broadcast(&COND_thread_count);
914
  (void) pthread_mutex_unlock(&LOCK_thread_count);
915
916
  /*
917
    The following lines may never be executed as the main thread may have
918
    killed us
919
  */
920
  DBUG_PRINT("quit", ("done with cleanup"));
921
} /* clean_up */
922
923
924
/**
925
  This is mainly needed when running with purify, but it's still nice to
926
  know that all child threads have died when mysqld exits.
927
*/
928
static void wait_for_signal_thread_to_end()
929
{
930
  uint i;
931
  /*
932
    Wait up to 10 seconds for signal thread to die. We use this mainly to
933
    avoid getting warnings that my_thread_end has not been called
934
  */
935
  for (i= 0 ; i < 100 && signal_thread_in_use; i++)
936
  {
937
    if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL) != ESRCH)
938
      break;
939
    my_sleep(100);				// Give it time to die
940
  }
941
}
942
943
944
static void clean_up_mutexes()
945
{
946
  (void) pthread_mutex_destroy(&LOCK_mysql_create_db);
947
  (void) pthread_mutex_destroy(&LOCK_lock_db);
948
  (void) pthread_mutex_destroy(&LOCK_open);
949
  (void) pthread_mutex_destroy(&LOCK_thread_count);
950
  (void) pthread_mutex_destroy(&LOCK_mapped_file);
951
  (void) pthread_mutex_destroy(&LOCK_status);
952
  (void) pthread_mutex_destroy(&LOCK_error_log);
953
  (void) pthread_mutex_destroy(&LOCK_manager);
954
  (void) pthread_mutex_destroy(&LOCK_crypt);
955
  (void) pthread_mutex_destroy(&LOCK_user_conn);
956
  (void) pthread_mutex_destroy(&LOCK_connection_count);
957
  (void) pthread_mutex_destroy(&LOCK_rpl_status);
958
  (void) pthread_cond_destroy(&COND_rpl_status);
959
  (void) pthread_mutex_destroy(&LOCK_active_mi);
960
  (void) rwlock_destroy(&LOCK_sys_init_connect);
961
  (void) rwlock_destroy(&LOCK_sys_init_slave);
962
  (void) pthread_mutex_destroy(&LOCK_global_system_variables);
963
  (void) rwlock_destroy(&LOCK_system_variables_hash);
964
  (void) pthread_mutex_destroy(&LOCK_global_read_lock);
965
  (void) pthread_mutex_destroy(&LOCK_uuid_generator);
966
  (void) pthread_cond_destroy(&COND_thread_count);
967
  (void) pthread_cond_destroy(&COND_refresh);
968
  (void) pthread_cond_destroy(&COND_global_read_lock);
969
  (void) pthread_cond_destroy(&COND_thread_cache);
970
  (void) pthread_cond_destroy(&COND_flush_thread_cache);
971
  (void) pthread_cond_destroy(&COND_manager);
972
}
973
974
975
/****************************************************************************
976
** Init IP and UNIX socket
977
****************************************************************************/
978
979
static void set_ports()
980
{
981
  char	*env;
982
  if (!mysqld_port && !opt_disable_networking)
983
  {					// Get port if not from commandline
984
    mysqld_port= MYSQL_PORT;
985
986
    /*
987
      if builder specifically requested a default port, use that
988
      (even if it coincides with our factory default).
989
      only if they didn't do we check /etc/services (and, failing
990
      on that, fall back to the factory default of 3306).
991
      either default can be overridden by the environment variable
992
      MYSQL_TCP_PORT, which in turn can be overridden with command
993
      line options.
994
    */
995
996
#if MYSQL_PORT_DEFAULT == 0
997
    struct  servent *serv_ptr;
998
    if ((serv_ptr= getservbyname("mysql", "tcp")))
999
      mysqld_port= ntohs((u_short) serv_ptr->s_port); /* purecov: inspected */
1000
#endif
1001
    if ((env = getenv("MYSQL_TCP_PORT")))
1002
      mysqld_port= (uint) atoi(env);		/* purecov: inspected */
1003
  }
1004
}
1005
1006
/* Change to run as another user if started with --user */
1007
1008
static struct passwd *check_user(const char *user)
1009
{
1010
  struct passwd *tmp_user_info;
1011
  uid_t user_id= geteuid();
1012
1013
  // Don't bother if we aren't superuser
1014
  if (user_id)
1015
  {
1016
    if (user)
1017
    {
1018
      /* Don't give a warning, if real user is same as given with --user */
1019
      /* purecov: begin tested */
1020
      tmp_user_info= getpwnam(user);
1021
      if ((!tmp_user_info || user_id != tmp_user_info->pw_uid) &&
1022
	  global_system_variables.log_warnings)
1023
        sql_print_warning(
1024
                    "One can only use the --user switch if running as root\n");
1025
      /* purecov: end */
1026
    }
1027
    return NULL;
1028
  }
1029
  if (!user)
1030
  {
1031
    if (!opt_bootstrap)
1032
    {
1033
      sql_print_error("Fatal error: Please read \"Security\" section of the manual to find out how to run mysqld as root!\n");
1034
      unireg_abort(1);
1035
    }
1036
    return NULL;
1037
  }
1038
  /* purecov: begin tested */
1039
  if (!strcmp(user,"root"))
1040
    return NULL;                        // Avoid problem with dynamic libraries
1041
1042
  if (!(tmp_user_info= getpwnam(user)))
1043
  {
1044
    // Allow a numeric uid to be used
1045
    const char *pos;
1046
    for (pos= user; my_isdigit(mysqld_charset,*pos); pos++) ;
1047
    if (*pos)                                   // Not numeric id
1048
      goto err;
1049
    if (!(tmp_user_info= getpwuid(atoi(user))))
1050
      goto err;
1051
  }
1052
  return tmp_user_info;
1053
  /* purecov: end */
1054
1055
err:
1056
  sql_print_error("Fatal error: Can't change to run as user '%s' ;  Please check that the user exists!\n",user);
1057
  unireg_abort(1);
1058
1059
#ifdef PR_SET_DUMPABLE
1060
  if (test_flags & TEST_CORE_ON_SIGNAL)
1061
  {
1062
    /* inform kernel that process is dumpable */
1063
    (void) prctl(PR_SET_DUMPABLE, 1);
1064
  }
1065
#endif
1066
1067
  return NULL;
1068
}
1069
1070
static void set_user(const char *user, struct passwd *user_info_arg)
1071
{
1072
  /* purecov: begin tested */
1073
  DBUG_ASSERT(user_info_arg != 0);
1074
#ifdef HAVE_INITGROUPS
1075
  /*
1076
    We can get a SIGSEGV when calling initgroups() on some systems when NSS
1077
    is configured to use LDAP and the server is statically linked.  We set
1078
    calling_initgroups as a flag to the SIGSEGV handler that is then used to
1079
    output a specific message to help the user resolve this problem.
1080
  */
1081
  calling_initgroups= TRUE;
1082
  initgroups((char*) user, user_info_arg->pw_gid);
1083
  calling_initgroups= FALSE;
1084
#endif
1085
  if (setgid(user_info_arg->pw_gid) == -1)
1086
  {
1087
    sql_perror("setgid");
1088
    unireg_abort(1);
1089
  }
1090
  if (setuid(user_info_arg->pw_uid) == -1)
1091
  {
1092
    sql_perror("setuid");
1093
    unireg_abort(1);
1094
  }
1095
  /* purecov: end */
1096
}
1097
1098
1099
static void set_effective_user(struct passwd *user_info_arg)
1100
{
1101
  DBUG_ASSERT(user_info_arg != 0);
1102
  if (setregid((gid_t)-1, user_info_arg->pw_gid) == -1)
1103
  {
1104
    sql_perror("setregid");
1105
    unireg_abort(1);
1106
  }
1107
  if (setreuid((uid_t)-1, user_info_arg->pw_uid) == -1)
1108
  {
1109
    sql_perror("setreuid");
1110
    unireg_abort(1);
1111
  }
1112
}
1113
1114
1115
/** Change root user if started with @c --chroot . */
1116
static void set_root(const char *path)
1117
{
1118
  if (chroot(path) == -1)
1119
  {
1120
    sql_perror("chroot");
1121
    unireg_abort(1);
1122
  }
1123
  my_setwd("/", MYF(0));
1124
}
1125
1126
1127
static void network_init(void)
1128
{
1129
  int	arg;
1130
  int   ret;
1131
  uint  waited;
1132
  uint  this_wait;
1133
  uint  retry;
1134
  char port_buf[NI_MAXSERV];
1135
  DBUG_ENTER("network_init");
1136
1137
  if (thread_scheduler.init())
1138
    unireg_abort(1);			/* purecov: inspected */
1139
1140
  set_ports();
1141
1142
  if (mysqld_port != 0 && !opt_disable_networking && !opt_bootstrap)
1143
  {
1144
    struct addrinfo *ai;
1145
    struct addrinfo hints;
1146
    int error;
1147
    DBUG_PRINT("general",("IP Socket is %d",mysqld_port));
1148
1149
    bzero(&hints, sizeof (hints));
1150
    hints.ai_flags= AI_PASSIVE;
1151
    hints.ai_socktype= SOCK_STREAM;
1152
    hints.ai_family= AF_UNSPEC;
1153
1154
    my_snprintf(port_buf, NI_MAXSERV, "%d", mysqld_port);
1155
    error= getaddrinfo(my_bind_addr_str, port_buf, &hints, &ai);
1156
    if (error != 0)
1157
    {
1158
      DBUG_PRINT("error",("Got error: %d from getaddrinfo()", error));
1159
      sql_perror(ER(ER_IPSOCK_ERROR));		/* purecov: tested */
1160
      unireg_abort(1);				/* purecov: tested */
1161
    }
1162
1163
1164
    ip_sock= socket(ai->ai_family, ai->ai_socktype,
1165
                    ai->ai_protocol);
1166
1167
    if (ip_sock == INVALID_SOCKET)
1168
    {
1169
      DBUG_PRINT("error",("Got error: %d from socket()",socket_errno));
1170
      sql_perror(ER(ER_IPSOCK_ERROR));		/* purecov: tested */
1171
      unireg_abort(1);				/* purecov: tested */
1172
    }
1173
1174
    /*
1175
      We should not use SO_REUSEADDR on windows as this would enable a
1176
      user to open two mysqld servers with the same TCP/IP port.
1177
    */
1178
    arg= 1;
1179
    (void) setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,sizeof(arg));
1180
1181
#ifdef IPV6_V6ONLY
1182
     /*
1183
       For interoperability with older clients, IPv6 socket should
1184
       listen on both IPv6 and IPv4 wildcard addresses.
1185
       Turn off IPV6_V6ONLY option.
1186
     */
1187
    if (ai->ai_family == AF_INET6)
1188
    {
1189
      arg= 0;      
1190
      (void) setsockopt(ip_sock, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
1191
                sizeof(arg));
1192
    }
1193
#endif
1194
    /*
1195
      Sometimes the port is not released fast enough when stopping and
1196
      restarting the server. This happens quite often with the test suite
1197
      on busy Linux systems. Retry to bind the address at these intervals:
1198
      Sleep intervals: 1, 2, 4,  6,  9, 13, 17, 22, ...
1199
      Retry at second: 1, 3, 7, 13, 22, 35, 52, 74, ...
1200
      Limit the sequence by mysqld_port_timeout (set --port-open-timeout=#).
1201
    */
1202
    for (waited= 0, retry= 1; ; retry++, waited+= this_wait)
1203
    {
1204
      if (((ret= bind(ip_sock, ai->ai_addr, ai->ai_addrlen)) >= 0 ) ||
1205
          (socket_errno != SOCKET_EADDRINUSE) ||
1206
          (waited >= mysqld_port_timeout))
1207
        break;
1208
      sql_print_information("Retrying bind on TCP/IP port %u", mysqld_port);
1209
      this_wait= retry * retry / 3 + 1;
1210
      sleep(this_wait);
1211
    }
1212
    freeaddrinfo(ai);
1213
    if (ret < 0)
1214
    {
1215
      DBUG_PRINT("error",("Got error: %d from bind",socket_errno));
1216
      sql_perror("Can't start server: Bind on TCP/IP port");
1217
      sql_print_error("Do you already have another mysqld server running on port: %d ?",mysqld_port);
1218
      unireg_abort(1);
1219
    }
1220
    if (listen(ip_sock,(int) back_log) < 0)
1221
    {
1222
      sql_perror("Can't start server: listen() on TCP/IP port");
1223
      sql_print_error("listen() on TCP/IP failed with error %d",
1224
		      socket_errno);
1225
      unireg_abort(1);
1226
    }
1227
  }
1228
1229
  DBUG_PRINT("info",("server started"));
1230
  DBUG_VOID_RETURN;
1231
}
1232
1233
/**
1234
  Close a connection.
1235
1236
  @param thd		Thread handle
1237
  @param errcode	Error code to print to console
1238
  @param lock	        1 if we have have to lock LOCK_thread_count
1239
1240
  @note
1241
    For the connection that is doing shutdown, this is called twice
1242
*/
1243
void close_connection(THD *thd, uint errcode, bool lock)
1244
{
1245
  st_vio *vio;
1246
  DBUG_ENTER("close_connection");
1247
  DBUG_PRINT("enter",("fd: %s  error: '%s'",
1248
		      thd->net.vio ? vio_description(thd->net.vio) :
1249
		      "(not connected)",
1250
		      errcode ? ER(errcode) : ""));
1251
  if (lock)
1252
    (void) pthread_mutex_lock(&LOCK_thread_count);
1253
  thd->killed= THD::KILL_CONNECTION;
1254
  if ((vio= thd->net.vio) != 0)
1255
  {
1256
    if (errcode)
1257
      net_send_error(thd, errcode, ER(errcode)); /* purecov: inspected */
1258
    vio_close(vio);			/* vio is freed in delete thd */
1259
  }
1260
  if (lock)
1261
    (void) pthread_mutex_unlock(&LOCK_thread_count);
1262
  DBUG_VOID_RETURN;
1263
}
1264
1265
1266
/** Called when a thread is aborted. */
1267
/* ARGSUSED */
1268
extern "C" sig_handler end_thread_signal(int sig __attribute__((unused)))
1269
{
1270
  THD *thd=current_thd;
1271
  DBUG_ENTER("end_thread_signal");
1272
  if (thd && ! thd->bootstrap)
1273
  {
1274
    statistic_increment(killed_threads, &LOCK_status);
1275
    thread_scheduler.end_thread(thd,0);		/* purecov: inspected */
1276
  }
1277
  DBUG_VOID_RETURN;				/* purecov: deadcode */
1278
}
1279
1280
1281
/*
1282
  Unlink thd from global list of available connections and free thd
1283
1284
  SYNOPSIS
1285
    unlink_thd()
1286
    thd		 Thread handler
1287
1288
  NOTES
1289
    LOCK_thread_count is locked and left locked
1290
*/
1291
1292
void unlink_thd(THD *thd)
1293
{
1294
  DBUG_ENTER("unlink_thd");
1295
  DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd));
1296
  thd->cleanup();
1297
1298
  pthread_mutex_lock(&LOCK_connection_count);
1299
  --connection_count;
1300
  pthread_mutex_unlock(&LOCK_connection_count);
1301
1302
  (void) pthread_mutex_lock(&LOCK_thread_count);
1303
  thread_count--;
1304
  delete thd;
1305
  DBUG_VOID_RETURN;
1306
}
1307
1308
1309
/*
1310
  Store thread in cache for reuse by new connections
1311
1312
  SYNOPSIS
1313
    cache_thread()
1314
1315
  NOTES
1316
    LOCK_thread_count has to be locked
1317
1318
  RETURN
1319
    0  Thread was not put in cache
1320
    1  Thread is to be reused by new connection.
1321
       (ie, caller should return, not abort with pthread_exit())
1322
*/
1323
1324
1325
static bool cache_thread()
1326
{
1327
  safe_mutex_assert_owner(&LOCK_thread_count);
1328
  if (cached_thread_count < thread_cache_size &&
1329
      ! abort_loop && !kill_cached_threads)
1330
  {
1331
    /* Don't kill the thread, just put it in cache for reuse */
1332
    DBUG_PRINT("info", ("Adding thread to cache"));
1333
    cached_thread_count++;
1334
    while (!abort_loop && ! wake_thread && ! kill_cached_threads)
1335
      (void) pthread_cond_wait(&COND_thread_cache, &LOCK_thread_count);
1336
    cached_thread_count--;
1337
    if (kill_cached_threads)
1338
      pthread_cond_signal(&COND_flush_thread_cache);
1339
    if (wake_thread)
1340
    {
1341
      THD *thd;
1342
      wake_thread--;
1343
      thd= thread_cache.get();
1344
      thd->thread_stack= (char*) &thd;          // For store_globals
1345
      (void) thd->store_globals();
1346
      /*
1347
        THD::mysys_var::abort is associated with physical thread rather
1348
        than with THD object. So we need to reset this flag before using
1349
        this thread for handling of new THD object/connection.
1350
      */
1351
      thd->mysys_var->abort= 0;
1352
      thd->thr_create_utime= my_micro_time();
1353
      threads.append(thd);
1354
      return(1);
1355
    }
1356
  }
1357
  return(0);
1358
}
1359
1360
1361
/*
1362
  End thread for the current connection
1363
1364
  SYNOPSIS
1365
    one_thread_per_connection_end()
1366
    thd		  Thread handler
1367
    put_in_cache  Store thread in cache, if there is room in it
1368
                  Normally this is true in all cases except when we got
1369
                  out of resources initializing the current thread
1370
1371
  NOTES
1372
    If thread is cached, we will wait until thread is scheduled to be
1373
    reused and then we will return.
1374
    If thread is not cached, we end the thread.
1375
1376
  RETURN
1377
    0    Signal to handle_one_connection to reuse connection
1378
*/
1379
1380
bool one_thread_per_connection_end(THD *thd, bool put_in_cache)
1381
{
1382
  DBUG_ENTER("one_thread_per_connection_end");
1383
  unlink_thd(thd);
1384
  if (put_in_cache)
1385
    put_in_cache= cache_thread();
1386
  pthread_mutex_unlock(&LOCK_thread_count);
1387
  if (put_in_cache)
1388
    DBUG_RETURN(0);                             // Thread is reused
1389
1390
  /* It's safe to broadcast outside a lock (COND... is not deleted here) */
1391
  DBUG_PRINT("signal", ("Broadcasting COND_thread_count"));
1392
  my_thread_end();
1393
  (void) pthread_cond_broadcast(&COND_thread_count);
1394
1395
  pthread_exit(0);
1396
  DBUG_RETURN(0);                               // Impossible
1397
}
1398
1399
1400
void flush_thread_cache()
1401
{
1402
  (void) pthread_mutex_lock(&LOCK_thread_count);
1403
  kill_cached_threads++;
1404
  while (cached_thread_count)
1405
  {
1406
    pthread_cond_broadcast(&COND_thread_cache);
1407
    pthread_cond_wait(&COND_flush_thread_cache,&LOCK_thread_count);
1408
  }
1409
  kill_cached_threads--;
1410
  (void) pthread_mutex_unlock(&LOCK_thread_count);
1411
}
1412
1413
1414
#ifdef THREAD_SPECIFIC_SIGPIPE
1415
/**
1416
  Aborts a thread nicely. Comes here on SIGPIPE.
1417
1418
  @todo
1419
    One should have to fix that thr_alarm know about this thread too.
1420
*/
1421
extern "C" sig_handler abort_thread(int sig __attribute__((unused)))
1422
{
1423
  THD *thd=current_thd;
1424
  DBUG_ENTER("abort_thread");
1425
  if (thd)
1426
    thd->killed= THD::KILL_CONNECTION;
1427
  DBUG_VOID_RETURN;
1428
}
1429
#endif
1430
1431
#if BACKTRACE_DEMANGLE
1432
#include <cxxabi.h>
1433
extern "C" char *my_demangle(const char *mangled_name, int *status)
1434
{
1435
  return abi::__cxa_demangle(mangled_name, NULL, NULL, status);
1436
}
1437
#endif
1438
1439
1440
extern "C" sig_handler handle_segfault(int sig)
1441
{
1442
  time_t curr_time;
1443
  struct tm tm;
1444
  THD *thd=current_thd;
1445
1446
  /*
1447
    Strictly speaking, one needs a mutex here
1448
    but since we have got SIGSEGV already, things are a mess
1449
    so not having the mutex is not as bad as possibly using a buggy
1450
    mutex - so we keep things simple
1451
  */
1452
  if (segfaulted)
1453
  {
1454
    fprintf(stderr, "Fatal " SIGNAL_FMT " while backtracing\n", sig);
1455
    exit(1);
1456
  }
1457
1458
  segfaulted = 1;
1459
1460
  curr_time= my_time(0);
1461
  localtime_r(&curr_time, &tm);
1462
1463
  fprintf(stderr,"\
1464
%02d%02d%02d %2d:%02d:%02d - mysqld got " SIGNAL_FMT " ;\n\
1465
This could be because you hit a bug. It is also possible that this binary\n\
1466
or one of the libraries it was linked against is corrupt, improperly built,\n\
1467
or misconfigured. This error can also be caused by malfunctioning hardware.\n",
1468
          tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday,
1469
          tm.tm_hour, tm.tm_min, tm.tm_sec,
1470
	  sig);
1471
  fprintf(stderr, "\
1472
We will try our best to scrape up some info that will hopefully help diagnose\n\
1473
the problem, but since we have already crashed, something is definitely wrong\n\
1474
and this may fail.\n\n");
1475
  fprintf(stderr, "key_buffer_size=%lu\n",
1476
          (ulong) dflt_key_cache->key_cache_mem_size);
1477
  fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
1478
  fprintf(stderr, "max_used_connections=%lu\n", max_used_connections);
1479
  fprintf(stderr, "max_threads=%u\n", thread_scheduler.max_threads);
1480
  fprintf(stderr, "thread_count=%u\n", thread_count);
1481
  fprintf(stderr, "connection_count=%u\n", connection_count);
1482
  fprintf(stderr, "It is possible that mysqld could use up to \n\
1483
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = %lu K\n\
1484
bytes of memory\n", ((ulong) dflt_key_cache->key_cache_mem_size +
1485
		     (global_system_variables.read_buff_size +
1486
		      global_system_variables.sortbuff_size) *
1487
		     thread_scheduler.max_threads +
1488
                     max_connections * sizeof(THD)) / 1024);
1489
  fprintf(stderr, "Hope that's ok; if not, decrease some variables in the equation.\n\n");
1490
1491
#ifdef HAVE_STACKTRACE
1492
  if (!(test_flags & TEST_NO_STACKTRACE))
1493
  {
1494
    fprintf(stderr,"thd: 0x%lx\n",(long) thd);
1495
    fprintf(stderr,"\
1496
Attempting backtrace. You can use the following information to find out\n\
1497
where mysqld died. If you see no messages after this, something went\n\
1498
terribly wrong...\n");  
1499
    print_stacktrace(thd ? (uchar*) thd->thread_stack : (uchar*) 0,
1500
                     my_thread_stack_size);
1501
  }
1502
  if (thd)
1503
  {
1504
    const char *kreason= "UNKNOWN";
1505
    switch (thd->killed) {
1506
    case THD::NOT_KILLED:
1507
      kreason= "NOT_KILLED";
1508
      break;
1509
    case THD::KILL_BAD_DATA:
1510
      kreason= "KILL_BAD_DATA";
1511
      break;
1512
    case THD::KILL_CONNECTION:
1513
      kreason= "KILL_CONNECTION";
1514
      break;
1515
    case THD::KILL_QUERY:
1516
      kreason= "KILL_QUERY";
1517
      break;
1518
    case THD::KILLED_NO_VALUE:
1519
      kreason= "KILLED_NO_VALUE";
1520
      break;
1521
    }
1522
    fprintf(stderr, "Trying to get some variables.\n\
1523
Some pointers may be invalid and cause the dump to abort...\n");
1524
    safe_print_str("thd->query", thd->query, 1024);
1525
    fprintf(stderr, "thd->thread_id=%lu\n", (ulong) thd->thread_id);
1526
    fprintf(stderr, "thd->killed=%s\n", kreason);
1527
  }
1528
  fprintf(stderr, "\
1529
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains\n\
1530
information that should help you find out what is causing the crash.\n");
1531
  fflush(stderr);
1532
#endif /* HAVE_STACKTRACE */
1533
1534
#ifdef HAVE_INITGROUPS
1535
  if (calling_initgroups)
1536
    fprintf(stderr, "\n\
1537
This crash occured while the server was calling initgroups(). This is\n\
1538
often due to the use of a mysqld that is statically linked against glibc\n\
1539
and configured to use LDAP in /etc/nsswitch.conf. You will need to either\n\
1540
upgrade to a version of glibc that does not have this problem (2.3.4 or\n\
1541
later when used with nscd), disable LDAP in your nsswitch.conf, or use a\n\
1542
mysqld that is not statically linked.\n");
1543
#endif
1544
1545
  if (thd_lib_detected == THD_LIB_LT && !getenv("LD_ASSUME_KERNEL"))
1546
    fprintf(stderr,"\n\
1547
You are running a statically-linked LinuxThreads binary on an NPTL system.\n\
1548
This can result in crashes on some distributions due to LT/NPTL conflicts.\n\
1549
You should either build a dynamically-linked binary, or force LinuxThreads\n\
1550
to be used with the LD_ASSUME_KERNEL environment variable. Please consult\n\
1551
the documentation for your distribution on how to do that.\n");
1552
  
1553
  if (locked_in_memory)
1554
  {
1555
    fprintf(stderr, "\n\
1556
The \"--memlock\" argument, which was enabled, uses system calls that are\n\
1557
unreliable and unstable on some operating systems and operating-system\n\
1558
versions (notably, some versions of Linux).  This crash could be due to use\n\
1559
of those buggy OS calls.  You should consider whether you really need the\n\
1560
\"--memlock\" parameter and/or consult the OS distributer about \"mlockall\"\n\
1561
bugs.\n");
1562
  }
1563
1564
#ifdef HAVE_WRITE_CORE
1565
  if (test_flags & TEST_CORE_ON_SIGNAL)
1566
  {
1567
    fprintf(stderr, "Writing a core file\n");
1568
    fflush(stderr);
1569
    write_core(sig);
1570
  }
1571
#endif
1572
1573
  exit(1);
1574
}
1575
1576
#ifndef SA_RESETHAND
1577
#define SA_RESETHAND 0
1578
#endif
1579
#ifndef SA_NODEFER
1580
#define SA_NODEFER 0
1581
#endif
1582
1583
static void init_signals(void)
1584
{
1585
  sigset_t set;
1586
  struct sigaction sa;
1587
  DBUG_ENTER("init_signals");
1588
1589
  my_sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called!
1590
1591
  if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL))
1592
  {
1593
    sa.sa_flags = SA_RESETHAND | SA_NODEFER;
1594
    sigemptyset(&sa.sa_mask);
1595
    sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
1596
1597
    init_stacktrace();
1598
    sa.sa_handler=handle_segfault;
1599
    sigaction(SIGSEGV, &sa, NULL);
1600
    sigaction(SIGABRT, &sa, NULL);
1601
#ifdef SIGBUS
1602
    sigaction(SIGBUS, &sa, NULL);
1603
#endif
1604
    sigaction(SIGILL, &sa, NULL);
1605
    sigaction(SIGFPE, &sa, NULL);
1606
  }
1607
1608
#ifdef HAVE_GETRLIMIT
1609
  if (test_flags & TEST_CORE_ON_SIGNAL)
1610
  {
1611
    /* Change limits so that we will get a core file */
1612
    STRUCT_RLIMIT rl;
1613
    rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
1614
    if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
1615
      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");
1616
  }
1617
#endif
1618
  (void) sigemptyset(&set);
1619
  my_sigset(SIGPIPE,SIG_IGN);
1620
  sigaddset(&set,SIGPIPE);
1621
#ifndef IGNORE_SIGHUP_SIGQUIT
1622
  sigaddset(&set,SIGQUIT);
1623
  sigaddset(&set,SIGHUP);
1624
#endif
1625
  sigaddset(&set,SIGTERM);
1626
1627
  /* Fix signals if blocked by parents (can happen on Mac OS X) */
1628
  sigemptyset(&sa.sa_mask);
1629
  sa.sa_flags = 0;
1630
  sa.sa_handler = print_signal_warning;
1631
  sigaction(SIGTERM, &sa, (struct sigaction*) 0);
1632
  sa.sa_flags = 0;
1633
  sa.sa_handler = print_signal_warning;
1634
  sigaction(SIGHUP, &sa, (struct sigaction*) 0);
1635
#ifdef SIGTSTP
1636
  sigaddset(&set,SIGTSTP);
1637
#endif
1638
  if (thd_lib_detected != THD_LIB_LT)
1639
    sigaddset(&set,THR_SERVER_ALARM);
1640
  if (test_flags & TEST_SIGINT)
1641
  {
1642
    my_sigset(thr_kill_signal, end_thread_signal);
1643
    // May be SIGINT
1644
    sigdelset(&set, thr_kill_signal);
1645
  }
1646
  else
1647
    sigaddset(&set,SIGINT);
1648
  sigprocmask(SIG_SETMASK,&set,NULL);
1649
  pthread_sigmask(SIG_SETMASK,&set,NULL);
1650
  DBUG_VOID_RETURN;
1651
}
1652
1653
1654
static void start_signal_handler(void)
1655
{
1656
  int error;
1657
  pthread_attr_t thr_attr;
1658
  DBUG_ENTER("start_signal_handler");
1659
1660
  (void) pthread_attr_init(&thr_attr);
6 by Brian Aker
Second pass on pthread cleanup
1661
  pthread_attr_setscope(&thr_attr, PTHREAD_SCOPE_SYSTEM);
1662
  (void) pthread_attr_setdetachstate(&thr_attr, PTHREAD_CREATE_DETACHED);
1 by brian
clean slate
1663
  if (!(opt_specialflag & SPECIAL_NO_PRIOR))
6 by Brian Aker
Second pass on pthread cleanup
1664
  {
1665
    struct sched_param tmp_sched_param;
1666
1667
    memset(&tmp_sched_param, 0, sizeof(tmp_sched_param));
1668
    tmp_sched_param.sched_priority= INTERRUPT_PRIOR;
1669
    (void)pthread_attr_setschedparam(&thr_attr, &tmp_sched_param);
1670
  }
1 by brian
clean slate
1671
#if defined(__ia64__) || defined(__ia64)
1672
  /*
1673
    Peculiar things with ia64 platforms - it seems we only have half the
1674
    stack size in reality, so we have to double it here
1675
  */
1676
  pthread_attr_setstacksize(&thr_attr,my_thread_stack_size*2);
1677
#else
1678
  pthread_attr_setstacksize(&thr_attr,my_thread_stack_size);
1679
1680
  (void) pthread_mutex_lock(&LOCK_thread_count);
1681
  if ((error=pthread_create(&signal_thread,&thr_attr,signal_hand,0)))
1682
  {
1683
    sql_print_error("Can't create interrupt-thread (error %d, errno: %d)",
1684
		    error,errno);
1685
    exit(1);
1686
  }
1687
  (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
1688
  pthread_mutex_unlock(&LOCK_thread_count);
1689
1690
  (void) pthread_attr_destroy(&thr_attr);
1691
  DBUG_VOID_RETURN;
1692
}
1693
1694
1695
/** This threads handles all signals and alarms. */
1696
/* ARGSUSED */
1697
pthread_handler_t signal_hand(void *arg __attribute__((unused)))
1698
{
1699
  sigset_t set;
1700
  int sig;
1701
  my_thread_init();				// Init new thread
1702
  DBUG_ENTER("signal_hand");
1703
  signal_thread_in_use= 1;
1704
1705
  /*
1706
    Setup alarm handler
1707
    This should actually be '+ max_number_of_slaves' instead of +10,
1708
    but the +10 should be quite safe.
1709
  */
1710
  init_thr_alarm(thread_scheduler.max_threads + 10);
1711
  if (thd_lib_detected != THD_LIB_LT && (test_flags & TEST_SIGINT))
1712
  {
1713
    (void) sigemptyset(&set);			// Setup up SIGINT for debug
1714
    (void) sigaddset(&set,SIGINT);		// For debugging
1715
    (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL);
1716
  }
1717
  (void) sigemptyset(&set);			// Setup up SIGINT for debug
1718
#ifdef USE_ONE_SIGNAL_HAND
1719
  (void) sigaddset(&set,THR_SERVER_ALARM);	// For alarms
1720
#endif
1721
#ifndef IGNORE_SIGHUP_SIGQUIT
1722
  (void) sigaddset(&set,SIGQUIT);
1723
  (void) sigaddset(&set,SIGHUP);
1724
#endif
1725
  (void) sigaddset(&set,SIGTERM);
1726
  (void) sigaddset(&set,SIGTSTP);
1727
1728
  /* Save pid to this process (or thread on Linux) */
1729
  if (!opt_bootstrap)
1730
    create_pid_file();
1731
1732
#ifdef HAVE_STACK_TRACE_ON_SEGV
1733
  if (opt_do_pstack)
1734
  {
1735
    sprintf(pstack_file_name,"mysqld-%lu-%%d-%%d.backtrace", (ulong)getpid());
1736
    pstack_install_segv_action(pstack_file_name);
1737
  }
1738
#endif /* HAVE_STACK_TRACE_ON_SEGV */
1739
1740
  /*
1741
    signal to start_signal_handler that we are ready
1742
    This works by waiting for start_signal_handler to free mutex,
1743
    after which we signal it that we are ready.
1744
    At this pointer there is no other threads running, so there
1745
    should not be any other pthread_cond_signal() calls.
1746
  */
1747
  (void) pthread_mutex_lock(&LOCK_thread_count);
1748
  (void) pthread_mutex_unlock(&LOCK_thread_count);
1749
  (void) pthread_cond_broadcast(&COND_thread_count);
1750
1751
  (void) pthread_sigmask(SIG_BLOCK,&set,NULL);
1752
  for (;;)
1753
  {
1754
    int error;					// Used when debugging
1755
    if (shutdown_in_progress && !abort_loop)
1756
    {
1757
      sig= SIGTERM;
1758
      error=0;
1759
    }
1760
    else
1761
      while ((error=my_sigwait(&set,&sig)) == EINTR) ;
1762
    if (cleanup_done)
1763
    {
1764
      DBUG_PRINT("quit",("signal_handler: calling my_thread_end()"));
1765
      my_thread_end();
1766
      signal_thread_in_use= 0;
1767
      pthread_exit(0);				// Safety
1768
    }
1769
    switch (sig) {
1770
    case SIGTERM:
1771
    case SIGQUIT:
1772
    case SIGKILL:
1773
#ifdef EXTRA_DEBUG
1774
      sql_print_information("Got signal %d to shutdown mysqld",sig);
1775
#endif
1776
      /* switch to the old log message processing */
1777
      logger.set_handlers(LOG_FILE, opt_slow_log ? LOG_FILE:LOG_NONE,
1778
                          opt_log ? LOG_FILE:LOG_NONE);
1779
      DBUG_PRINT("info",("Got signal: %d  abort_loop: %d",sig,abort_loop));
1780
      if (!abort_loop)
1781
      {
1782
	abort_loop=1;				// mark abort for threads
1783
#ifdef USE_ONE_SIGNAL_HAND
1784
	pthread_t tmp;
1785
	if (!(opt_specialflag & SPECIAL_NO_PRIOR))
6 by Brian Aker
Second pass on pthread cleanup
1786
        {
1787
          struct sched_param tmp_sched_param;
1788
1789
          memset(&tmp_sched_param, 0, sizeof(tmp_sched_param));
1790
          tmp_sched_param.sched_priority= INTERRUPT_PRIOR;
1791
          (void)pthread_attr_setschedparam(&connection_attrib, &tmp_sched_param);
1792
        }
1 by brian
clean slate
1793
	if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
1794
			   (void*) &sig))
1795
	  sql_print_error("Can't create thread to kill server");
1796
#else
1797
	kill_server((void*) sig);	// MIT THREAD has a alarm thread
1798
#endif
1799
      }
1800
      break;
1801
    case SIGHUP:
1802
      if (!abort_loop)
1803
      {
1804
        bool not_used;
1805
	mysql_print_status();		// Print some debug info
1806
        reload_cache((THD*) 0,
1807
                     (REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |
1808
                      REFRESH_GRANT |
1809
                      REFRESH_THREADS | REFRESH_HOSTS),
1810
                     (TABLE_LIST*) 0, &not_used); // Flush logs
1811
      }
1812
      /* reenable logs after the options were reloaded */
1813
      if (log_output_options & LOG_NONE)
1814
      {
1815
        logger.set_handlers(LOG_FILE,
1816
                            opt_slow_log ? LOG_TABLE : LOG_NONE,
1817
                            opt_log ? LOG_TABLE : LOG_NONE);
1818
      }
1819
      else
1820
      {
1821
        logger.set_handlers(LOG_FILE,
1822
                            opt_slow_log ? log_output_options : LOG_NONE,
1823
                            opt_log ? log_output_options : LOG_NONE);
1824
      }
1825
      break;
1826
#ifdef USE_ONE_SIGNAL_HAND
1827
    case THR_SERVER_ALARM:
1828
      process_alarm(sig);			// Trigger alarms.
1829
      break;
1830
#endif
1831
    default:
1832
#ifdef EXTRA_DEBUG
1833
      sql_print_warning("Got signal: %d  error: %d",sig,error); /* purecov: tested */
1834
#endif
1835
      break;					/* purecov: tested */
1836
    }
1837
  }
1838
  return(0);					/* purecov: deadcode */
1839
}
1840
1841
static void check_data_home(const char *path)
1842
{}
1843
1844
#endif	/* __WIN__*/
1845
1846
1847
/**
1848
  All global error messages are sent here where the first one is stored
1849
  for the client.
1850
*/
1851
/* ARGSUSED */
1852
extern "C" void my_message_sql(uint error, const char *str, myf MyFlags);
1853
1854
void my_message_sql(uint error, const char *str, myf MyFlags)
1855
{
1856
  THD *thd;
1857
  DBUG_ENTER("my_message_sql");
1858
  DBUG_PRINT("error", ("error: %u  message: '%s'", error, str));
1859
  /*
1860
    Put here following assertion when situation with EE_* error codes
1861
    will be fixed
1862
    DBUG_ASSERT(error != 0);
1863
  */
1864
  if ((thd= current_thd))
1865
  {
1866
    if (MyFlags & ME_FATALERROR)
1867
      thd->is_fatal_error= 1;
1868
1869
#ifdef BUG_36098_FIXED
1870
    mysql_audit_general(thd,MYSQL_AUDIT_GENERAL_ERROR,error,my_time(0),
1871
                        0,0,str,str ? strlen(str) : 0,
1872
                        thd->query,thd->query_length,
1873
                        thd->variables.character_set_client,
1874
                        thd->row_count);
1875
#endif
1876
1877
1878
    /*
1879
      TODO: There are two exceptions mechanism (THD and sp_rcontext),
1880
      this could be improved by having a common stack of handlers.
1881
    */
1882
    if (thd->handle_error(error, str,
1883
                          MYSQL_ERROR::WARN_LEVEL_ERROR))
1884
      DBUG_VOID_RETURN;
1885
1886
    thd->is_slave_error=  1; // needed to catch query errors during replication
1887
1888
    /*
1889
      thd->lex->current_select == 0 if lex structure is not inited
1890
      (not query command (COM_QUERY))
1891
    */
1892
    if (thd->lex->current_select &&
1893
	thd->lex->current_select->no_error && !thd->is_fatal_error)
1894
    {
1895
      DBUG_PRINT("error",
1896
                 ("Error converted to warning: current_select: no_error %d  "
1897
                  "fatal_error: %d",
1898
                  (thd->lex->current_select ?
1899
                   thd->lex->current_select->no_error : 0),
1900
                  (int) thd->is_fatal_error));
1901
    }
1902
    else
1903
    {
1904
      if (! thd->main_da.is_error())            // Return only first message
1905
      {
1906
        if (error == 0)
1907
          error= ER_UNKNOWN_ERROR;
1908
        if (str == NULL)
1909
          str= ER(error);
1910
        thd->main_da.set_error_status(thd, error, str);
1911
      }
1912
    }
1913
1914
    if (!thd->no_warnings_for_error && !thd->is_fatal_error)
1915
    {
1916
      /*
1917
        Suppress infinite recursion if there a memory allocation error
1918
        inside push_warning.
1919
      */
1920
      thd->no_warnings_for_error= TRUE;
1921
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str);
1922
      thd->no_warnings_for_error= FALSE;
1923
    }
1924
  }
1925
  if (!thd || MyFlags & ME_NOREFRESH)
1926
    sql_print_error("%s: %s",my_progname,str); /* purecov: inspected */
1927
  DBUG_VOID_RETURN;
1928
}
1929
1930
1931
extern "C" void *my_str_malloc_mysqld(size_t size);
1932
extern "C" void my_str_free_mysqld(void *ptr);
1933
1934
void *my_str_malloc_mysqld(size_t size)
1935
{
1936
  return my_malloc(size, MYF(MY_FAE));
1937
}
1938
1939
1940
void my_str_free_mysqld(void *ptr)
1941
{
1942
  my_free((uchar*)ptr, MYF(MY_FAE));
1943
}
1944
1945
1946
static const char *load_default_groups[]= {
1947
"mysqld","server", MYSQL_BASE_VERSION, 0, 0};
1948
1949
1950
/**
1951
  Initialize one of the global date/time format variables.
1952
1953
  @param format_type		What kind of format should be supported
1954
  @param var_ptr		Pointer to variable that should be updated
1955
1956
  @note
1957
    The default value is taken from either opt_date_time_formats[] or
1958
    the ISO format (ANSI SQL)
1959
1960
  @retval
1961
    0 ok
1962
  @retval
1963
    1 error
1964
*/
1965
1966
static bool init_global_datetime_format(timestamp_type format_type,
1967
                                        DATE_TIME_FORMAT **var_ptr)
1968
{
1969
  /* Get command line option */
1970
  const char *str= opt_date_time_formats[format_type];
1971
1972
  if (!str)					// No specified format
1973
  {
1974
    str= get_date_time_format_str(&known_date_time_formats[ISO_FORMAT],
1975
				  format_type);
1976
    /*
1977
      Set the "command line" option to point to the generated string so
1978
      that we can set global formats back to default
1979
    */
1980
    opt_date_time_formats[format_type]= str;
1981
  }
1982
  if (!(*var_ptr= date_time_format_make(format_type, str, strlen(str))))
1983
  {
1984
    fprintf(stderr, "Wrong date/time format specifier: %s\n", str);
1985
    return 1;
1986
  }
1987
  return 0;
1988
}
1989
1990
SHOW_VAR com_status_vars[]= {
1991
  {"admin_commands",       (char*) offsetof(STATUS_VAR, com_other), SHOW_LONG_STATUS},
1992
  {"assign_to_keycache",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ASSIGN_TO_KEYCACHE]), SHOW_LONG_STATUS},
1993
  {"alter_db",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_DB]), SHOW_LONG_STATUS},
1994
  {"alter_db_upgrade",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_DB_UPGRADE]), SHOW_LONG_STATUS},
1995
  {"alter_table",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_TABLE]), SHOW_LONG_STATUS},
1996
  {"alter_tablespace",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_TABLESPACE]), SHOW_LONG_STATUS},
1997
  {"analyze",              (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ANALYZE]), SHOW_LONG_STATUS},
1998
  {"begin",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BEGIN]), SHOW_LONG_STATUS},
1999
  {"binlog",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BINLOG_BASE64_EVENT]), SHOW_LONG_STATUS},
2000
  {"change_db",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHANGE_DB]), SHOW_LONG_STATUS},
2001
  {"change_master",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHANGE_MASTER]), SHOW_LONG_STATUS},
2002
  {"check",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHECK]), SHOW_LONG_STATUS},
2003
  {"checksum",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHECKSUM]), SHOW_LONG_STATUS},
2004
  {"commit",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_COMMIT]), SHOW_LONG_STATUS},
2005
  {"create_db",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_DB]), SHOW_LONG_STATUS},
2006
  {"create_index",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_INDEX]), SHOW_LONG_STATUS},
2007
  {"create_table",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_TABLE]), SHOW_LONG_STATUS},
2008
  {"delete",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DELETE]), SHOW_LONG_STATUS},
2009
  {"delete_multi",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DELETE_MULTI]), SHOW_LONG_STATUS},
2010
  {"drop_db",              (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_DB]), SHOW_LONG_STATUS},
2011
  {"drop_index",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_INDEX]), SHOW_LONG_STATUS},
2012
  {"drop_table",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_TABLE]), SHOW_LONG_STATUS},
2013
  {"empty_query",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EMPTY_QUERY]), SHOW_LONG_STATUS},
2014
  {"flush",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_FLUSH]), SHOW_LONG_STATUS},
2015
  {"insert",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_INSERT]), SHOW_LONG_STATUS},
2016
  {"insert_select",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_INSERT_SELECT]), SHOW_LONG_STATUS},
2017
  {"kill",                 (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_KILL]), SHOW_LONG_STATUS},
2018
  {"load",                 (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOAD]), SHOW_LONG_STATUS},
2019
  {"lock_tables",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOCK_TABLES]), SHOW_LONG_STATUS},
2020
  {"optimize",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_OPTIMIZE]), SHOW_LONG_STATUS},
2021
  {"purge",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PURGE]), SHOW_LONG_STATUS},
2022
  {"purge_before_date",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PURGE_BEFORE]), SHOW_LONG_STATUS},
2023
  {"release_savepoint",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RELEASE_SAVEPOINT]), SHOW_LONG_STATUS},
2024
  {"rename_table",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RENAME_TABLE]), SHOW_LONG_STATUS},
2025
  {"repair",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPAIR]), SHOW_LONG_STATUS},
2026
  {"replace",              (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPLACE]), SHOW_LONG_STATUS},
2027
  {"replace_select",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPLACE_SELECT]), SHOW_LONG_STATUS},
2028
  {"reset",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RESET]), SHOW_LONG_STATUS},
2029
  {"rollback",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ROLLBACK]), SHOW_LONG_STATUS},
2030
  {"rollback_to_savepoint",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ROLLBACK_TO_SAVEPOINT]), SHOW_LONG_STATUS},
2031
  {"savepoint",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SAVEPOINT]), SHOW_LONG_STATUS},
2032
  {"select",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SELECT]), SHOW_LONG_STATUS},
2033
  {"set_option",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SET_OPTION]), SHOW_LONG_STATUS},
2034
  {"show_binlog_events",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOG_EVENTS]), SHOW_LONG_STATUS},
2035
  {"show_binlogs",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOGS]), SHOW_LONG_STATUS},
2036
  {"show_charsets",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CHARSETS]), SHOW_LONG_STATUS},
2037
  {"show_collations",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLLATIONS]), SHOW_LONG_STATUS},
2038
  {"show_create_db",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_DB]), SHOW_LONG_STATUS},
2039
  {"show_create_table",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE]), SHOW_LONG_STATUS},
2040
  {"show_databases",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_DATABASES]), SHOW_LONG_STATUS},
2041
  {"show_engine_status",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_STATUS]), SHOW_LONG_STATUS},
2042
  {"show_errors",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ERRORS]), SHOW_LONG_STATUS},
2043
  {"show_fields",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_FIELDS]), SHOW_LONG_STATUS},
2044
  {"show_keys",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_KEYS]), SHOW_LONG_STATUS},
2045
  {"show_master_status",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_MASTER_STAT]), SHOW_LONG_STATUS},
2046
  {"show_open_tables",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_OPEN_TABLES]), SHOW_LONG_STATUS},
2047
  {"show_plugins",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PLUGINS]), SHOW_LONG_STATUS},
2048
  {"show_processlist",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROCESSLIST]), SHOW_LONG_STATUS},
2049
  {"show_slave_hosts",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_HOSTS]), SHOW_LONG_STATUS},
2050
  {"show_slave_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_STAT]), SHOW_LONG_STATUS},
2051
  {"show_status",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS},
2052
  {"show_table_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS},
2053
  {"show_tables",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLES]), SHOW_LONG_STATUS},
2054
  {"show_variables",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS},
2055
  {"show_warnings",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
2056
  {"slave_start",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_START]), SHOW_LONG_STATUS},
2057
  {"slave_stop",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_STOP]), SHOW_LONG_STATUS},
2058
  {"truncate",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_TRUNCATE]), SHOW_LONG_STATUS},
2059
  {"unlock_tables",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNLOCK_TABLES]), SHOW_LONG_STATUS},
2060
  {"update",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UPDATE]), SHOW_LONG_STATUS},
2061
  {"update_multi",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UPDATE_MULTI]), SHOW_LONG_STATUS},
2062
  {NullS, NullS, SHOW_LONG}
2063
};
2064
2065
static int init_common_variables(const char *conf_file_name, int argc,
2066
				 char **argv, const char **groups)
2067
{
2068
  char buff[FN_REFLEN], *s;
2069
  umask(((~my_umask) & 0666));
2070
  my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
2071
  tzset();			// Set tzname
2072
2073
  max_system_variables.pseudo_thread_id= (ulong)~0;
2074
  server_start_time= flush_status_time= my_time(0);
2075
  rpl_filter= new Rpl_filter;
2076
  binlog_filter= new Rpl_filter;
2077
  if (!rpl_filter || !binlog_filter) 
2078
  {
2079
    sql_perror("Could not allocate replication and binlog filters");
2080
    exit(1);
2081
  }
2082
2083
  if (init_thread_environment())
2084
    return 1;
2085
  mysql_init_variables();
2086
2087
#ifdef HAVE_TZNAME
2088
  {
2089
    struct tm tm_tmp;
2090
    localtime_r(&server_start_time,&tm_tmp);
2091
    strmake(system_time_zone, tzname[tm_tmp.tm_isdst != 0 ? 1 : 0],
2092
            sizeof(system_time_zone)-1);
2093
2094
 }
2095
#endif
2096
  /*
2097
    We set SYSTEM time zone as reasonable default and
2098
    also for failure of my_tz_init() and bootstrap mode.
2099
    If user explicitly set time zone with --default-time-zone
2100
    option we will change this value in my_tz_init().
2101
  */
2102
  global_system_variables.time_zone= my_tz_SYSTEM;
2103
2104
  /*
2105
    Init mutexes for the global MYSQL_BIN_LOG objects.
2106
    As safe_mutex depends on what MY_INIT() does, we can't init the mutexes of
2107
    global MYSQL_BIN_LOGs in their constructors, because then they would be
2108
    inited before MY_INIT(). So we do it here.
2109
  */
2110
  mysql_bin_log.init_pthread_objects();
2111
2112
  if (gethostname(glob_hostname,sizeof(glob_hostname)) < 0)
2113
  {
2114
    strmake(glob_hostname, STRING_WITH_LEN("localhost"));
2115
    sql_print_warning("gethostname failed, using '%s' as hostname",
2116
                      glob_hostname);
2117
    strmake(pidfile_name, STRING_WITH_LEN("mysql"));
2118
  }
2119
  else
2120
  strmake(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
2121
  strmov(fn_ext(pidfile_name),".pid");		// Add proper extension
2122
2123
  /*
2124
    Add server status variables to the dynamic list of
2125
    status variables that is shown by SHOW STATUS.
2126
    Later, in plugin_init, and mysql_install_plugin
2127
    new entries could be added to that list.
2128
  */
2129
  if (add_status_vars(status_vars))
2130
    return 1; // an error was already reported
2131
2132
#ifndef DBUG_OFF
2133
  /*
2134
    We have few debug-only commands in com_status_vars, only visible in debug
2135
    builds. for simplicity we enable the assert only in debug builds
2136
2137
    There are 7 Com_ variables which don't have corresponding SQLCOM_ values:
2138
    (TODO strictly speaking they shouldn't be here, should not have Com_ prefix
2139
    that is. Perhaps Stmt_ ? Comstmt_ ? Prepstmt_ ?)
2140
2141
      Com_admin_commands       => com_other
2142
      Com_stmt_close           => com_stmt_close
2143
      Com_stmt_execute         => com_stmt_execute
2144
      Com_stmt_fetch           => com_stmt_fetch
2145
      Com_stmt_prepare         => com_stmt_prepare
2146
      Com_stmt_reset           => com_stmt_reset
2147
      Com_stmt_send_long_data  => com_stmt_send_long_data
2148
2149
    With this correction the number of Com_ variables (number of elements in
2150
    the array, excluding the last element - terminator) must match the number
2151
    of SQLCOM_ constants.
2152
  */
2153
  compile_time_assert(sizeof(com_status_vars)/sizeof(com_status_vars[0]) - 1 ==
2154
                     SQLCOM_END + 7);
2155
#endif
2156
2157
  load_defaults(conf_file_name, groups, &argc, &argv);
2158
  defaults_argv=argv;
2159
  defaults_argc=argc;
2160
  get_options(&defaults_argc, defaults_argv);
2161
  set_server_version();
2162
2163
  DBUG_PRINT("info",("%s  Ver %s for %s on %s\n",my_progname,
2164
		     server_version, SYSTEM_TYPE,MACHINE_TYPE));
2165
2166
  /* connections and databases needs lots of files */
2167
  {
2168
    uint files, wanted_files, max_open_files;
2169
2170
    /* MyISAM requires two file handles per table. */
2171
    wanted_files= 10+max_connections+table_cache_size*2;
2172
    /*
2173
      We are trying to allocate no less than max_connections*5 file
2174
      handles (i.e. we are trying to set the limit so that they will
2175
      be available).  In addition, we allocate no less than how much
2176
      was already allocated.  However below we report a warning and
2177
      recompute values only if we got less file handles than were
2178
      explicitly requested.  No warning and re-computation occur if we
2179
      can't get max_connections*5 but still got no less than was
2180
      requested (value of wanted_files).
2181
    */
2182
    max_open_files= max(max(wanted_files, max_connections*5),
2183
                        open_files_limit);
2184
    files= my_set_max_open_files(max_open_files);
2185
2186
    if (files < wanted_files)
2187
    {
2188
      if (!open_files_limit)
2189
      {
2190
        /*
2191
          If we have requested too much file handles than we bring
2192
          max_connections in supported bounds.
2193
        */
2194
        max_connections= (ulong) min(files-10-TABLE_OPEN_CACHE_MIN*2,
2195
                                     max_connections);
2196
        /*
2197
          Decrease table_cache_size according to max_connections, but
2198
          not below TABLE_OPEN_CACHE_MIN.  Outer min() ensures that we
2199
          never increase table_cache_size automatically (that could
2200
          happen if max_connections is decreased above).
2201
        */
2202
        table_cache_size= (ulong) min(max((files-10-max_connections)/2,
2203
                                          TABLE_OPEN_CACHE_MIN),
2204
                                      table_cache_size);
2205
	DBUG_PRINT("warning",
2206
		   ("Changed limits: max_open_files: %u  max_connections: %ld  table_cache: %ld",
2207
		    files, max_connections, table_cache_size));
2208
	if (global_system_variables.log_warnings)
2209
	  sql_print_warning("Changed limits: max_open_files: %u  max_connections: %ld  table_cache: %ld",
2210
			files, max_connections, table_cache_size);
2211
      }
2212
      else if (global_system_variables.log_warnings)
2213
	sql_print_warning("Could not increase number of max_open_files to more than %u (request: %u)", files, wanted_files);
2214
    }
2215
    open_files_limit= files;
2216
  }
2217
  unireg_init(opt_specialflag); /* Set up extern variabels */
2218
  if (init_errmessage())	/* Read error messages from file */
2219
    return 1;
2220
  init_client_errs();
2221
  lex_init();
2222
  if (item_create_init())
2223
    return 1;
2224
  item_init();
2225
  if (set_var_init())
2226
    return 1;
2227
  if (init_replication_sys_vars())
2228
    return 1;
2229
  mysys_uses_curses=0;
2230
  /*
2231
    Process a comma-separated character set list and choose
2232
    the first available character set. This is mostly for
2233
    test purposes, to be able to start "mysqld" even if
2234
    the requested character set is not available (see bug#18743).
2235
  */
2236
  for (;;)
2237
  {
2238
    char *next_character_set_name= strchr(default_character_set_name, ',');
2239
    if (next_character_set_name)
2240
      *next_character_set_name++= '\0';
2241
    if (!(default_charset_info=
2242
          get_charset_by_csname(default_character_set_name,
2243
                                MY_CS_PRIMARY, MYF(MY_WME))))
2244
    {
2245
      if (next_character_set_name)
2246
      {
2247
        default_character_set_name= next_character_set_name;
2248
        default_collation_name= 0;          // Ignore collation
2249
      }
2250
      else
2251
        return 1;                           // Eof of the list
2252
    }
2253
    else
2254
      break;
2255
  }
2256
2257
  if (default_collation_name)
2258
  {
2259
    CHARSET_INFO *default_collation;
2260
    default_collation= get_charset_by_name(default_collation_name, MYF(0));
2261
    if (!default_collation)
2262
    {
2263
      sql_print_error(ER(ER_UNKNOWN_COLLATION), default_collation_name);
2264
      return 1;
2265
    }
2266
    if (!my_charset_same(default_charset_info, default_collation))
2267
    {
2268
      sql_print_error(ER(ER_COLLATION_CHARSET_MISMATCH),
2269
		      default_collation_name,
2270
		      default_charset_info->csname);
2271
      return 1;
2272
    }
2273
    default_charset_info= default_collation;
2274
  }
2275
  /* Set collactions that depends on the default collation */
2276
  global_system_variables.collation_server=	 default_charset_info;
2277
  global_system_variables.collation_database=	 default_charset_info;
2278
  global_system_variables.collation_connection=  default_charset_info;
2279
  global_system_variables.character_set_results= default_charset_info;
2280
  global_system_variables.character_set_client= default_charset_info;
2281
2282
  global_system_variables.optimizer_use_mrr= 1;
2283
  global_system_variables.optimizer_switch= 0;
2284
2285
  if (!(character_set_filesystem= 
2286
        get_charset_by_csname(character_set_filesystem_name,
2287
                              MY_CS_PRIMARY, MYF(MY_WME))))
2288
    return 1;
2289
  global_system_variables.character_set_filesystem= character_set_filesystem;
2290
2291
  if (!(my_default_lc_time_names=
2292
        my_locale_by_name(lc_time_names_name)))
2293
  {
2294
    sql_print_error("Unknown locale: '%s'", lc_time_names_name);
2295
    return 1;
2296
  }
2297
  global_system_variables.lc_time_names= my_default_lc_time_names;
2298
  
2299
  sys_init_connect.value_length= 0;
2300
  if ((sys_init_connect.value= opt_init_connect))
2301
    sys_init_connect.value_length= strlen(opt_init_connect);
2302
  else
2303
    sys_init_connect.value=my_strdup("",MYF(0));
2304
2305
  sys_init_slave.value_length= 0;
2306
  if ((sys_init_slave.value= opt_init_slave))
2307
    sys_init_slave.value_length= strlen(opt_init_slave);
2308
  else
2309
    sys_init_slave.value=my_strdup("",MYF(0));
2310
2311
  /* check log options and issue warnings if needed */
2312
  if (opt_log && opt_logname && !(log_output_options & LOG_FILE) &&
2313
      !(log_output_options & LOG_NONE))
2314
    sql_print_warning("Although a path was specified for the "
2315
                      "--log option, log tables are used. "
2316
                      "To enable logging to files use the --log-output option.");
2317
2318
  if (opt_slow_log && opt_slow_logname && !(log_output_options & LOG_FILE)
2319
      && !(log_output_options & LOG_NONE))
2320
    sql_print_warning("Although a path was specified for the "
2321
                      "--log-slow-queries option, log tables are used. "
2322
                      "To enable logging to files use the --log-output=file option.");
2323
2324
  s= opt_logname ? opt_logname : make_default_log_name(buff, ".log");
2325
  sys_var_general_log_path.value= my_strdup(s, MYF(0));
2326
  sys_var_general_log_path.value_length= strlen(s);
2327
2328
  s= opt_slow_logname ? opt_slow_logname : make_default_log_name(buff, "-slow.log");
2329
  sys_var_slow_log_path.value= my_strdup(s, MYF(0));
2330
  sys_var_slow_log_path.value_length= strlen(s);
2331
2332
  if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
2333
    return 1;
2334
  if (my_database_names_init())
2335
    return 1;
2336
2337
  /*
2338
    Ensure that lower_case_table_names is set on system where we have case
2339
    insensitive names.  If this is not done the users MyISAM tables will
2340
    get corrupted if accesses with names of different case.
2341
  */
2342
  DBUG_PRINT("info", ("lower_case_table_names: %d", lower_case_table_names));
2343
  lower_case_file_system= test_if_case_insensitive(mysql_real_data_home);
2344
  if (!lower_case_table_names && lower_case_file_system == 1)
2345
  {
2346
    if (lower_case_table_names_used)
2347
    {
2348
      if (global_system_variables.log_warnings)
2349
	sql_print_warning("\
2350
You have forced lower_case_table_names to 0 through a command-line \
2351
option, even though your file system '%s' is case insensitive.  This means \
2352
that you can corrupt a MyISAM table by accessing it with different cases. \
2353
You should consider changing lower_case_table_names to 1 or 2",
2354
			mysql_real_data_home);
2355
    }
2356
    else
2357
    {
2358
      if (global_system_variables.log_warnings)
2359
	sql_print_warning("Setting lower_case_table_names=2 because file system for %s is case insensitive", mysql_real_data_home);
2360
      lower_case_table_names= 2;
2361
    }
2362
  }
2363
  else if (lower_case_table_names == 2 &&
2364
           !(lower_case_file_system=
2365
             (test_if_case_insensitive(mysql_real_data_home) == 1)))
2366
  {
2367
    if (global_system_variables.log_warnings)
2368
      sql_print_warning("lower_case_table_names was set to 2, even though your "
2369
                        "the file system '%s' is case sensitive.  Now setting "
2370
                        "lower_case_table_names to 0 to avoid future problems.",
2371
			mysql_real_data_home);
2372
    lower_case_table_names= 0;
2373
  }
2374
  else
2375
  {
2376
    lower_case_file_system=
2377
      (test_if_case_insensitive(mysql_real_data_home) == 1);
2378
  }
2379
2380
  /* Reset table_alias_charset, now that lower_case_table_names is set. */
2381
  table_alias_charset= (lower_case_table_names ?
2382
			files_charset_info :
2383
			&my_charset_bin);
2384
2385
  return 0;
2386
}
2387
2388
2389
static int init_thread_environment()
2390
{
2391
  (void) pthread_mutex_init(&LOCK_mysql_create_db,MY_MUTEX_INIT_SLOW);
2392
  (void) pthread_mutex_init(&LOCK_lock_db,MY_MUTEX_INIT_SLOW);
2393
  (void) pthread_mutex_init(&LOCK_open, NULL);
2394
  (void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
2395
  (void) pthread_mutex_init(&LOCK_mapped_file,MY_MUTEX_INIT_SLOW);
2396
  (void) pthread_mutex_init(&LOCK_status,MY_MUTEX_INIT_FAST);
2397
  (void) pthread_mutex_init(&LOCK_error_log,MY_MUTEX_INIT_FAST);
2398
  (void) pthread_mutex_init(&LOCK_manager,MY_MUTEX_INIT_FAST);
2399
  (void) pthread_mutex_init(&LOCK_crypt,MY_MUTEX_INIT_FAST);
2400
  (void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
2401
  (void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
2402
  (void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
2403
  (void) my_rwlock_init(&LOCK_system_variables_hash, NULL);
2404
  (void) pthread_mutex_init(&LOCK_global_read_lock, MY_MUTEX_INIT_FAST);
2405
  (void) pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST);
2406
  (void) pthread_mutex_init(&LOCK_connection_count, MY_MUTEX_INIT_FAST);
2407
  (void) my_rwlock_init(&LOCK_sys_init_connect, NULL);
2408
  (void) my_rwlock_init(&LOCK_sys_init_slave, NULL);
2409
  (void) pthread_cond_init(&COND_thread_count,NULL);
2410
  (void) pthread_cond_init(&COND_refresh,NULL);
2411
  (void) pthread_cond_init(&COND_global_read_lock,NULL);
2412
  (void) pthread_cond_init(&COND_thread_cache,NULL);
2413
  (void) pthread_cond_init(&COND_flush_thread_cache,NULL);
2414
  (void) pthread_cond_init(&COND_manager,NULL);
2415
  (void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST);
2416
  (void) pthread_cond_init(&COND_rpl_status, NULL);
2417
2418
  /* Parameter for threads created for connections */
2419
  (void) pthread_attr_init(&connection_attrib);
2420
  (void) pthread_attr_setdetachstate(&connection_attrib,
2421
				     PTHREAD_CREATE_DETACHED);
2422
  pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM);
2423
  if (!(opt_specialflag & SPECIAL_NO_PRIOR))
6 by Brian Aker
Second pass on pthread cleanup
2424
  {
2425
    struct sched_param tmp_sched_param;
2426
2427
    memset(&tmp_sched_param, 0, sizeof(tmp_sched_param));
2428
    tmp_sched_param.sched_priority= WAIT_PRIOR;
2429
    (void)pthread_attr_setschedparam(&connection_attrib, &tmp_sched_param);
2430
  }
1 by brian
clean slate
2431
2432
  if (pthread_key_create(&THR_THD,NULL) ||
2433
      pthread_key_create(&THR_MALLOC,NULL))
2434
  {
2435
    sql_print_error("Can't create thread-keys");
2436
    return 1;
2437
  }
2438
  return 0;
2439
}
2440
2441
2442
static int init_server_components()
2443
{
2444
  DBUG_ENTER("init_server_components");
2445
  /*
2446
    We need to call each of these following functions to ensure that
2447
    all things are initialized so that unireg_abort() doesn't fail
2448
  */
2449
  if (table_cache_init() | table_def_init())
2450
    unireg_abort(1);
2451
2452
  randominit(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2);
2453
  setup_fpu();
2454
  init_thr_lock();
2455
  init_slave_list();
2456
2457
  /* Setup logs */
2458
2459
  /*
2460
    Enable old-fashioned error log, except when the user has requested
2461
    help information. Since the implementation of plugin server
2462
    variables the help output is now written much later.
2463
  */
2464
  if (opt_error_log && !opt_help)
2465
  {
2466
    if (!log_error_file_ptr[0])
2467
      fn_format(log_error_file, pidfile_name, mysql_data_home, ".err",
2468
                MY_REPLACE_EXT); /* replace '.<domain>' by '.err', bug#4997 */
2469
    else
2470
      fn_format(log_error_file, log_error_file_ptr, mysql_data_home, ".err",
2471
                MY_UNPACK_FILENAME | MY_SAFE_PATH);
2472
    if (!log_error_file[0])
2473
      opt_error_log= 1;				// Too long file name
2474
    else
2475
    {
2476
      if (freopen(log_error_file, "a+", stdout))
2477
        freopen(log_error_file, "a+", stderr);
2478
    }
2479
  }
2480
2481
  if (xid_cache_init())
2482
  {
2483
    sql_print_error("Out of memory");
2484
    unireg_abort(1);
2485
  }
2486
2487
  /* need to configure logging before initializing storage engines */
2488
  if (opt_update_log)
2489
  {
2490
    /*
2491
      Update log is removed since 5.0. But we still accept the option.
2492
      The idea is if the user already uses the binlog and the update log,
2493
      we completely ignore any option/variable related to the update log, like
2494
      if the update log did not exist. But if the user uses only the update
2495
      log, then we translate everything into binlog for him (with warnings).
2496
      Implementation of the above :
2497
      - If mysqld is started with --log-update and --log-bin,
2498
      ignore --log-update (print a warning), push a warning when SQL_LOG_UPDATE
2499
      is used, and turn off --sql-bin-update-same.
2500
      This will completely ignore SQL_LOG_UPDATE
2501
      - If mysqld is started with --log-update only,
2502
      change it to --log-bin (with the filename passed to log-update,
2503
      plus '-bin') (print a warning), push a warning when SQL_LOG_UPDATE is
2504
      used, and turn on --sql-bin-update-same.
2505
      This will translate SQL_LOG_UPDATE to SQL_LOG_BIN.
2506
2507
      Note that we tell the user that --sql-bin-update-same is deprecated and
2508
      does nothing, and we don't take into account if he used this option or
2509
      not; but internally we give this variable a value to have the behaviour
2510
      we want (i.e. have SQL_LOG_UPDATE influence SQL_LOG_BIN or not).
2511
      As sql-bin-update-same, log-update and log-bin cannot be changed by the
2512
      user after starting the server (they are not variables), the user will
2513
      not later interfere with the settings we do here.
2514
    */
2515
    if (opt_bin_log)
2516
    {
2517
      opt_sql_bin_update= 0;
2518
      sql_print_error("The update log is no longer supported by MySQL in \
2519
version 5.0 and above. It is replaced by the binary log.");
2520
    }
2521
    else
2522
    {
2523
      opt_sql_bin_update= 1;
2524
      opt_bin_log= 1;
2525
      if (opt_update_logname)
2526
      {
2527
        /* as opt_bin_log==0, no need to free opt_bin_logname */
2528
        if (!(opt_bin_logname= my_strdup(opt_update_logname, MYF(MY_WME))))
2529
          exit(EXIT_OUT_OF_MEMORY);
2530
        sql_print_error("The update log is no longer supported by MySQL in \
2531
version 5.0 and above. It is replaced by the binary log. Now starting MySQL \
2532
with --log-bin='%s' instead.",opt_bin_logname);
2533
      }
2534
      else
2535
        sql_print_error("The update log is no longer supported by MySQL in \
2536
version 5.0 and above. It is replaced by the binary log. Now starting MySQL \
2537
with --log-bin instead.");
2538
    }
2539
  }
2540
  if (opt_log_slave_updates && !opt_bin_log)
2541
  {
2542
    sql_print_error("You need to use --log-bin to make "
2543
                    "--log-slave-updates work.");
2544
    unireg_abort(1);
2545
  }
2546
  if (!opt_bin_log)
2547
    if (opt_binlog_format_id != BINLOG_FORMAT_UNSPEC)
2548
  {
2549
    sql_print_error("You need to use --log-bin to make "
2550
                    "--binlog-format work.");
2551
    unireg_abort(1);
2552
  }
2553
    else
2554
  {
2555
      global_system_variables.binlog_format= BINLOG_FORMAT_MIXED;
2556
    }
2557
  else
2558
    if (opt_binlog_format_id == BINLOG_FORMAT_UNSPEC)
2559
      global_system_variables.binlog_format= BINLOG_FORMAT_MIXED;
2560
    else
2561
    { 
2562
      DBUG_ASSERT(global_system_variables.binlog_format != BINLOG_FORMAT_UNSPEC);
2563
  }
2564
2565
  /* Check that we have not let the format to unspecified at this point */
2566
  DBUG_ASSERT((uint)global_system_variables.binlog_format <=
2567
              array_elements(binlog_format_names)-1);
2568
2569
  if (opt_log_slave_updates && replicate_same_server_id)
2570
  {
2571
    sql_print_error("\
2572
using --replicate-same-server-id in conjunction with \
2573
--log-slave-updates is impossible, it would lead to infinite loops in this \
2574
server.");
2575
    unireg_abort(1);
2576
  }
2577
2578
  if (opt_bin_log)
2579
  {
2580
    char buf[FN_REFLEN];
2581
    const char *ln;
2582
    ln= mysql_bin_log.generate_name(opt_bin_logname, "-bin", 1, buf);
2583
    if (!opt_bin_logname && !opt_binlog_index_name)
2584
    {
2585
      /*
2586
        User didn't give us info to name the binlog index file.
2587
        Picking `hostname`-bin.index like did in 4.x, causes replication to
2588
        fail if the hostname is changed later. So, we would like to instead
2589
        require a name. But as we don't want to break many existing setups, we
2590
        only give warning, not error.
2591
      */
2592
      sql_print_warning("No argument was provided to --log-bin, and "
2593
                        "--log-bin-index was not used; so replication "
2594
                        "may break when this MySQL server acts as a "
2595
                        "master and has his hostname changed!! Please "
2596
                        "use '--log-bin=%s' to avoid this problem.", ln);
2597
    }
2598
    if (ln == buf)
2599
    {
2600
      my_free(opt_bin_logname, MYF(MY_ALLOW_ZERO_PTR));
2601
      opt_bin_logname=my_strdup(buf, MYF(0));
2602
    }
2603
    if (mysql_bin_log.open_index_file(opt_binlog_index_name, ln))
2604
    {
2605
      unireg_abort(1);
2606
    }
2607
2608
    /*
2609
      Used to specify which type of lock we need to use for queries of type
2610
      INSERT ... SELECT. This will change when we have row level logging.
2611
    */
2612
    using_update_log=1;
2613
  }
2614
2615
  /* call ha_init_key_cache() on all key caches to init them */
2616
  process_key_caches(&ha_init_key_cache);
2617
2618
  /* Allow storage engine to give real error messages */
2619
  if (ha_init_errors())
2620
    DBUG_RETURN(1);
2621
2622
  if (plugin_init(&defaults_argc, defaults_argv,
2623
                  (opt_noacl ? PLUGIN_INIT_SKIP_PLUGIN_TABLE : 0) |
2624
                  (opt_help ? PLUGIN_INIT_SKIP_INITIALIZATION : 0)))
2625
  {
2626
    sql_print_error("Failed to initialize plugins.");
2627
    unireg_abort(1);
2628
  }
2629
2630
  if (opt_help)
2631
    unireg_abort(0);
2632
2633
  /* we do want to exit if there are any other unknown options */
2634
  if (defaults_argc > 1)
2635
  {
2636
    int ho_error;
2637
    char **tmp_argv= defaults_argv;
2638
    struct my_option no_opts[]=
2639
    {
2640
      {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
2641
    };
2642
    /*
2643
      We need to eat any 'loose' arguments first before we conclude
2644
      that there are unprocessed options.
2645
      But we need to preserve defaults_argv pointer intact for
2646
      free_defaults() to work. Thus we use a copy here.
2647
    */
2648
    my_getopt_skip_unknown= 0;
2649
2650
    if ((ho_error= handle_options(&defaults_argc, &tmp_argv, no_opts,
2651
                                  mysqld_get_one_option)))
2652
      unireg_abort(ho_error);
2653
2654
    if (defaults_argc)
2655
    {
2656
      fprintf(stderr, "%s: Too many arguments (first extra is '%s').\n"
2657
              "Use --verbose --help to get a list of available options\n",
2658
              my_progname, *tmp_argv);
2659
      unireg_abort(1);
2660
    }
2661
  }
2662
2663
  /* if the errmsg.sys is not loaded, terminate to maintain behaviour */
2664
  if (!errmesg[0][0])
2665
    unireg_abort(1);
2666
2667
  /* We have to initialize the storage engines before CSV logging */
2668
  if (ha_init())
2669
  {
2670
    sql_print_error("Can't init databases");
2671
    unireg_abort(1);
2672
  }
2673
2674
  logger.set_handlers(LOG_FILE, opt_slow_log ? LOG_FILE:LOG_NONE,
2675
                      opt_log ? LOG_FILE:LOG_NONE);
2676
2677
  /*
2678
    Check that the default storage engine is actually available.
2679
  */
2680
  if (default_storage_engine_str)
2681
  {
2682
    LEX_STRING name= { default_storage_engine_str,
2683
                       strlen(default_storage_engine_str) };
2684
    plugin_ref plugin;
2685
    handlerton *hton;
2686
    
2687
    if ((plugin= ha_resolve_by_name(0, &name)))
2688
      hton= plugin_data(plugin, handlerton*);
2689
    else
2690
    {
2691
      sql_print_error("Unknown/unsupported table type: %s",
2692
                      default_storage_engine_str);
2693
      unireg_abort(1);
2694
    }
2695
    if (!ha_storage_engine_is_enabled(hton))
2696
    {
2697
      if (!opt_bootstrap)
2698
      {
2699
        sql_print_error("Default storage engine (%s) is not available",
2700
                        default_storage_engine_str);
2701
        unireg_abort(1);
2702
      }
2703
      DBUG_ASSERT(global_system_variables.table_plugin);
2704
    }
2705
    else
2706
    {
2707
      /*
2708
        Need to unlock as global_system_variables.table_plugin 
2709
        was acquired during plugin_init()
2710
      */
2711
      plugin_unlock(0, global_system_variables.table_plugin);
2712
      global_system_variables.table_plugin= plugin;
2713
    }
2714
  }
2715
2716
  tc_log= (total_ha_2pc > 1 ? (opt_bin_log  ?
2717
                               (TC_LOG *) &mysql_bin_log :
2718
                               (TC_LOG *) &tc_log_mmap) :
2719
           (TC_LOG *) &tc_log_dummy);
2720
2721
  if (tc_log->open(opt_bin_log ? opt_bin_logname : opt_tc_log_file))
2722
  {
2723
    sql_print_error("Can't init tc log");
2724
    unireg_abort(1);
2725
  }
2726
2727
  if (ha_recover(0))
2728
  {
2729
    unireg_abort(1);
2730
  }
2731
2732
  if (opt_bin_log && mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0,
2733
                                        WRITE_CACHE, 0, max_binlog_size, 0))
2734
    unireg_abort(1);
2735
2736
  if (opt_bin_log && expire_logs_days)
2737
  {
2738
    time_t purge_time= server_start_time - expire_logs_days*24*60*60;
2739
    if (purge_time >= 0)
2740
      mysql_bin_log.purge_logs_before_date(purge_time);
2741
  }
2742
2743
  if (opt_myisam_log)
2744
    (void) mi_log(1);
2745
2746
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
2747
  if (locked_in_memory && !getuid())
2748
  {
2749
    if (setreuid((uid_t)-1, 0) == -1)
2750
    {                        // this should never happen
2751
      sql_perror("setreuid");
2752
      unireg_abort(1);
2753
    }
2754
    if (mlockall(MCL_CURRENT))
2755
    {
2756
      if (global_system_variables.log_warnings)
2757
	sql_print_warning("Failed to lock memory. Errno: %d\n",errno);
2758
      locked_in_memory= 0;
2759
    }
2760
    if (user_info)
2761
      set_user(mysqld_user, user_info);
2762
  }
2763
  else
2764
#endif
2765
    locked_in_memory=0;
2766
2767
  ft_init_stopwords();
2768
2769
  init_update_queries();
2770
  DBUG_RETURN(0);
2771
}
2772
2773
2774
static void create_maintenance_thread()
2775
{
2776
  if (flush_time && flush_time != ~(ulong) 0L)
2777
  {
2778
    pthread_t hThread;
2779
    if (pthread_create(&hThread,&connection_attrib,handle_manager,0))
2780
      sql_print_warning("Can't create thread to manage maintenance");
2781
  }
2782
}
2783
2784
2785
int main(int argc, char **argv)
2786
{
2787
  MY_INIT(argv[0]);		// init my_sys library & pthreads
2788
  /* nothing should come before this line ^^^ */
2789
2790
  /* Set signal used to kill MySQL */
2791
#if defined(SIGUSR2)
2792
  thr_kill_signal= thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2;
2793
#else
2794
  thr_kill_signal= SIGINT;
2795
#endif
2796
2797
  /*
2798
    Perform basic logger initialization logger. Should be called after
2799
    MY_INIT, as it initializes mutexes. Log tables are inited later.
2800
  */
2801
  logger.init_base();
2802
2803
#ifdef _CUSTOMSTARTUPCONFIG_
2804
  if (_cust_check_startup())
2805
  {
2806
    / * _cust_check_startup will report startup failure error * /
2807
    exit(1);
2808
  }
2809
#endif
2810
2811
  if (init_common_variables(MYSQL_CONFIG_NAME,
2812
			    argc, argv, load_default_groups))
2813
    unireg_abort(1);				// Will do exit
2814
2815
  init_signals();
2816
  if (!(opt_specialflag & SPECIAL_NO_PRIOR))
5 by Brian Aker
Removed my_pthread_setprio()
2817
  {
2818
    struct sched_param tmp_sched_param;
2819
2820
    memset(&tmp_sched_param, 0, sizeof(tmp_sched_param));
2821
    tmp_sched_param.sched_priority= my_thread_stack_size*2;
2822
    (void)pthread_setschedparam(pthread_self(), SCHED_OTHER, &tmp_sched_param);
2823
  }
1 by brian
clean slate
2824
  pthread_attr_setstacksize(&connection_attrib,my_thread_stack_size);
2825
#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
2826
  {
2827
    /* Retrieve used stack size;  Needed for checking stack overflows */
2828
    size_t stack_size= 0;
2829
    pthread_attr_getstacksize(&connection_attrib, &stack_size);
2830
    /* We must check if stack_size = 0 as Solaris 2.9 can return 0 here */
2831
    if (stack_size && stack_size < my_thread_stack_size)
2832
    {
2833
      if (global_system_variables.log_warnings)
2834
	sql_print_warning("Asked for %lu thread stack, but got %ld",
2835
			  my_thread_stack_size, (long) stack_size);
2836
      my_thread_stack_size= stack_size;
2837
    }
2838
  }
2839
#endif
2840
2841
  select_thread=pthread_self();
2842
  select_thread_in_use=1;
2843
2844
  /*
2845
    We have enough space for fiddling with the argv, continue
2846
  */
2847
  check_data_home(mysql_real_data_home);
2848
  if (my_setwd(mysql_real_data_home,MYF(MY_WME)) && !opt_help)
2849
    unireg_abort(1);				/* purecov: inspected */
2850
  mysql_data_home= mysql_data_home_buff;
2851
  mysql_data_home[0]=FN_CURLIB;		// all paths are relative from here
2852
  mysql_data_home[1]=0;
2853
  mysql_data_home_len= 2;
2854
2855
  if ((user_info= check_user(mysqld_user)))
2856
  {
2857
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
2858
    if (locked_in_memory) // getuid() == 0 here
2859
      set_effective_user(user_info);
2860
    else
2861
#endif
2862
      set_user(mysqld_user, user_info);
2863
  }
2864
2865
  if (opt_bin_log && !server_id)
2866
  {
2867
    server_id= 1;
2868
#ifdef EXTRA_DEBUG
2869
    sql_print_warning("You have enabled the binary log, but you haven't set "
2870
                      "server-id to a non-zero value: we force server id to 1; "
2871
                      "updates will be logged to the binary log, but "
2872
                      "connections from slaves will not be accepted.");
2873
#endif
2874
  }
2875
2876
  if (init_server_components())
2877
    unireg_abort(1);
2878
2879
  network_init();
2880
2881
  /*
2882
   Initialize my_str_malloc() and my_str_free()
2883
  */
2884
  my_str_malloc= &my_str_malloc_mysqld;
2885
  my_str_free= &my_str_free_mysqld;
2886
2887
  /*
2888
    init signals & alarm
2889
    After this we can't quit by a simple unireg_abort
2890
  */
2891
  error_handler_hook= my_message_sql;
2892
  start_signal_handler();				// Creates pidfile
2893
2894
  if (mysql_rm_tmp_tables() || my_tz_init((THD *)0, default_tz_name, opt_bootstrap))
2895
  {
2896
    abort_loop=1;
2897
    select_thread_in_use=0;
2898
    (void) pthread_kill(signal_thread, MYSQL_KILL_SIGNAL);
2899
2900
    if (!opt_bootstrap)
2901
      (void) my_delete(pidfile_name,MYF(MY_WME));	// Not needed anymore
2902
2903
    exit(1);
2904
  }
2905
2906
  udf_init();
2907
2908
  init_status_vars();
2909
  if (opt_bootstrap) /* If running with bootstrap, do not start replication. */
2910
    opt_skip_slave_start= 1;
2911
  /*
2912
    init_slave() must be called after the thread keys are created.
2913
    Some parts of the code (e.g. SHOW STATUS LIKE 'slave_running' and other
2914
    places) assume that active_mi != 0, so let's fail if it's 0 (out of
2915
    memory); a message has already been printed.
2916
  */
2917
  if (init_slave() && !active_mi)
2918
  {
2919
    unireg_abort(1);
2920
  }
2921
2922
  if (opt_bootstrap)
2923
  {
2924
    select_thread_in_use= 0;                    // Allow 'kill' to work
2925
    bootstrap(stdin);
2926
    unireg_abort(bootstrap_error ? 1 : 0);
2927
  }
2928
  if (opt_init_file)
2929
  {
2930
    if (read_init_file(opt_init_file))
2931
      unireg_abort(1);
2932
  }
2933
2934
  create_maintenance_thread();
2935
2936
  sql_print_information(ER(ER_STARTUP),my_progname,server_version,
11 by Brian Aker
Removing old UNIX socket bits
2937
                        "", mysqld_port, MYSQL_COMPILATION_COMMENT);
2938
2939
2940
  handle_connections_sockets();
1 by brian
clean slate
2941
2942
  /* (void) pthread_attr_destroy(&connection_attrib); */
2943
  
2944
  DBUG_PRINT("quit",("Exiting main thread"));
2945
2946
#ifdef EXTRA_DEBUG2
2947
  sql_print_error("Before Lock_thread_count");
2948
#endif
2949
  (void) pthread_mutex_lock(&LOCK_thread_count);
2950
  DBUG_PRINT("quit", ("Got thread_count mutex"));
2951
  select_thread_in_use=0;			// For close_connections
2952
  (void) pthread_mutex_unlock(&LOCK_thread_count);
2953
  (void) pthread_cond_broadcast(&COND_thread_count);
2954
#ifdef EXTRA_DEBUG2
2955
  sql_print_error("After lock_thread_count");
2956
#endif
2957
2958
  /* Wait until cleanup is done */
2959
  (void) pthread_mutex_lock(&LOCK_thread_count);
2960
  while (!ready_to_exit)
2961
    pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
2962
  (void) pthread_mutex_unlock(&LOCK_thread_count);
2963
2964
  clean_up(1);
2965
  mysqld_exit(0);
2966
}
2967
2968
2969
/**
2970
  Execute all commands from a file. Used by the mysql_install_db script to
2971
  create MySQL privilege tables without having to start a full MySQL server.
2972
*/
2973
2974
static void bootstrap(FILE *file)
2975
{
2976
  DBUG_ENTER("bootstrap");
2977
2978
  THD *thd= new THD;
2979
  thd->bootstrap=1;
2980
  my_net_init(&thd->net,(st_vio*) 0);
2981
  thd->max_client_packet_length= thd->net.max_packet;
2982
  thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
2983
  thread_count++;
2984
2985
  bootstrap_file=file;
2986
  if (pthread_create(&thd->real_id,&connection_attrib,handle_bootstrap,
2987
		     (void*) thd))
2988
  {
2989
    sql_print_warning("Can't create thread to handle bootstrap");
2990
    bootstrap_error=-1;
2991
    DBUG_VOID_RETURN;
2992
  }
2993
  /* Wait for thread to die */
2994
  (void) pthread_mutex_lock(&LOCK_thread_count);
2995
  while (thread_count)
2996
  {
2997
    (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
2998
    DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
2999
  }
3000
  (void) pthread_mutex_unlock(&LOCK_thread_count);
3001
3002
  DBUG_VOID_RETURN;
3003
}
3004
3005
3006
static bool read_init_file(char *file_name)
3007
{
3008
  FILE *file;
3009
  DBUG_ENTER("read_init_file");
3010
  DBUG_PRINT("enter",("name: %s",file_name));
3011
  if (!(file=my_fopen(file_name,O_RDONLY,MYF(MY_WME))))
3012
    return(1);
3013
  bootstrap(file);
3014
  (void) my_fclose(file,MYF(MY_WME));
3015
  return 0;
3016
}
3017
3018
3019
/**
3020
  Create new thread to handle incoming connection.
3021
3022
    This function will create new thread to handle the incoming
3023
    connection.  If there are idle cached threads one will be used.
3024
    'thd' will be pushed into 'threads'.
3025
3026
    In single-threaded mode (\#define ONE_THREAD) connection will be
3027
    handled inside this function.
3028
3029
  @param[in,out] thd    Thread handle of future thread.
3030
*/
3031
3032
static void create_new_thread(THD *thd)
3033
{
3034
  DBUG_ENTER("create_new_thread");
3035
3036
  /*
3037
    Don't allow too many connections. We roughly check here that we allow
3038
    only (max_connections + 1) connections.
3039
  */
3040
3041
  pthread_mutex_lock(&LOCK_connection_count);
3042
3043
  if (connection_count >= max_connections + 1 || abort_loop)
3044
  {
3045
    pthread_mutex_unlock(&LOCK_connection_count);
3046
3047
    DBUG_PRINT("error",("Too many connections"));
3048
    close_connection(thd, ER_CON_COUNT_ERROR, 1);
3049
    delete thd;
3050
    DBUG_VOID_RETURN;
3051
  }
3052
3053
  ++connection_count;
3054
3055
  if (connection_count > max_used_connections)
3056
    max_used_connections= connection_count;
3057
3058
  pthread_mutex_unlock(&LOCK_connection_count);
3059
3060
  /* Start a new thread to handle connection. */
3061
3062
  pthread_mutex_lock(&LOCK_thread_count);
3063
3064
  /*
3065
    The initialization of thread_id is done in create_embedded_thd() for
3066
    the embedded library.
3067
    TODO: refactor this to avoid code duplication there
3068
  */
3069
  thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
3070
3071
  thread_count++;
3072
3073
  thread_scheduler.add_connection(thd);
3074
3075
  DBUG_VOID_RETURN;
3076
}
3077
3078
3079
#ifdef SIGNALS_DONT_BREAK_READ
3080
inline void kill_broken_server()
3081
{
3082
  /* hack to get around signals ignored in syscalls for problem OS's */
3083
  if ((!opt_disable_networking && ip_sock == INVALID_SOCKET))
3084
  {
3085
    select_thread_in_use = 0;
3086
    /* The following call will never return */
3087
    kill_server((void*) MYSQL_KILL_SIGNAL);
3088
  }
3089
}
3090
#define MAYBE_BROKEN_SYSCALL kill_broken_server();
3091
#else
3092
#define MAYBE_BROKEN_SYSCALL
3093
#endif
3094
3095
	/* Handle new connections and spawn new process to handle them */
3096
11 by Brian Aker
Removing old UNIX socket bits
3097
void handle_connections_sockets()
1 by brian
clean slate
3098
{
3099
  my_socket sock,new_sock;
3100
  uint error_count=0;
11 by Brian Aker
Removing old UNIX socket bits
3101
  uint max_used_connection= (uint)ip_sock+1;
1 by brian
clean slate
3102
  fd_set readFDs,clientFDs;
3103
  THD *thd;
3104
  struct sockaddr_storage cAddr;
3105
  int ip_flags=0, flags;
3106
  st_vio *vio_tmp;
3107
3108
  FD_ZERO(&clientFDs);
3109
  if (ip_sock != INVALID_SOCKET)
3110
  {
3111
    FD_SET(ip_sock,&clientFDs);
3112
#ifdef HAVE_FCNTL
3113
    ip_flags = fcntl(ip_sock, F_GETFL, 0);
3114
#endif
3115
  }
3116
  DBUG_PRINT("general",("Waiting for connections."));
3117
  MAYBE_BROKEN_SYSCALL;
3118
  while (!abort_loop)
3119
  {
3120
    readFDs=clientFDs;
3121
    if (select((int) max_used_connection,&readFDs,0,0,0) < 0)
3122
    {
3123
      if (socket_errno != SOCKET_EINTR)
3124
      {
3125
	if (!select_errors++ && !abort_loop)	/* purecov: inspected */
3126
	  sql_print_error("mysqld: Got error %d from select",socket_errno); /* purecov: inspected */
3127
      }
3128
      MAYBE_BROKEN_SYSCALL
3129
      continue;
3130
    }
3131
    if (abort_loop)
3132
    {
3133
      MAYBE_BROKEN_SYSCALL;
3134
      break;
3135
    }
3136
3137
    /* Is this a new connection request ? */
3138
    {
3139
      sock = ip_sock;
3140
      flags= ip_flags;
3141
    }
3142
3143
#if !defined(NO_FCNTL_NONBLOCK)
3144
    if (!(test_flags & TEST_BLOCKING))
3145
    {
3146
#if defined(O_NONBLOCK)
3147
      fcntl(sock, F_SETFL, flags | O_NONBLOCK);
3148
#elif defined(O_NDELAY)
3149
      fcntl(sock, F_SETFL, flags | O_NDELAY);
3150
#endif
3151
    }
3152
#endif /* NO_FCNTL_NONBLOCK */
3153
    for (uint retry=0; retry < MAX_ACCEPT_RETRY; retry++)
3154
    {
3155
      size_socket length= sizeof(struct sockaddr_storage);
3156
      new_sock= accept(sock, (struct sockaddr *)(&cAddr),
3157
                       &length);
3158
      if (new_sock != INVALID_SOCKET ||
3159
	  (socket_errno != SOCKET_EINTR && socket_errno != SOCKET_EAGAIN))
3160
	break;
3161
      MAYBE_BROKEN_SYSCALL;
3162
#if !defined(NO_FCNTL_NONBLOCK)
3163
      if (!(test_flags & TEST_BLOCKING))
3164
      {
3165
	if (retry == MAX_ACCEPT_RETRY - 1)
3166
	  fcntl(sock, F_SETFL, flags);		// Try without O_NONBLOCK
3167
      }
3168
#endif
3169
    }
3170
#if !defined(NO_FCNTL_NONBLOCK)
3171
    if (!(test_flags & TEST_BLOCKING))
3172
      fcntl(sock, F_SETFL, flags);
3173
#endif
3174
    if (new_sock == INVALID_SOCKET)
3175
    {
3176
      if ((error_count++ & 255) == 0)		// This can happen often
3177
	sql_perror("Error in accept");
3178
      MAYBE_BROKEN_SYSCALL;
3179
      if (socket_errno == SOCKET_ENFILE || socket_errno == SOCKET_EMFILE)
3180
	sleep(1);				// Give other threads some time
3181
      continue;
3182
    }
3183
3184
    {
3185
      size_socket dummyLen;
3186
      struct sockaddr_storage dummy;
3187
      dummyLen = sizeof(dummy);
3188
      if (  getsockname(new_sock,(struct sockaddr *)&dummy, 
3189
                  (socklen_t *)&dummyLen) < 0  )
3190
      {
3191
	sql_perror("Error on new connection socket");
3192
	(void) shutdown(new_sock, SHUT_RDWR);
3193
	(void) closesocket(new_sock);
3194
	continue;
3195
      }
3196
    }
3197
3198
    /*
3199
    ** Don't allow too many connections
3200
    */
3201
3202
    if (!(thd= new THD))
3203
    {
3204
      (void) shutdown(new_sock, SHUT_RDWR);
3205
      VOID(closesocket(new_sock));
3206
      continue;
3207
    }
11 by Brian Aker
Removing old UNIX socket bits
3208
    if (!(vio_tmp=vio_new(new_sock, VIO_TYPE_TCPIP, sock == 0)) ||
1 by brian
clean slate
3209
	my_net_init(&thd->net,vio_tmp))
3210
    {
3211
      /*
3212
        Only delete the temporary vio if we didn't already attach it to the
3213
        NET object. The destructor in THD will delete any initialized net
3214
        structure.
3215
      */
3216
      if (vio_tmp && thd->net.vio != vio_tmp)
3217
        vio_delete(vio_tmp);
3218
      else
3219
      {
3220
	(void) shutdown(new_sock, SHUT_RDWR);
3221
	(void) closesocket(new_sock);
3222
      }
3223
      delete thd;
3224
      continue;
3225
    }
3226
3227
    create_new_thread(thd);
3228
  }
3229
}
3230
3231
3232
/****************************************************************************
3233
  Handle start options
3234
******************************************************************************/
3235
3236
enum options_mysqld
3237
{
3238
  OPT_ISAM_LOG=256,            OPT_SKIP_NEW, 
3239
  OPT_SKIP_GRANT,              OPT_SKIP_LOCK, 
3240
  OPT_ENABLE_LOCK,             OPT_USE_LOCKING,
3241
  OPT_SOCKET,                  OPT_UPDATE_LOG,
3242
  OPT_BIN_LOG,                 
3243
  OPT_BIN_LOG_INDEX,
3244
  OPT_BIND_ADDRESS,            OPT_PID_FILE,
3245
  OPT_SKIP_PRIOR,              OPT_BIG_TABLES,
12.1.3 by Brian Aker
Removal of dead code/remove non-used Falcon tests.
3246
  OPT_STANDALONE,
1 by brian
clean slate
3247
  OPT_CONSOLE,                 OPT_LOW_PRIORITY_UPDATES,
3248
  OPT_SHORT_LOG_FORMAT,
3249
  OPT_FLUSH,                   OPT_SAFE,
3250
  OPT_BOOTSTRAP,               OPT_SKIP_SHOW_DB,
3251
  OPT_STORAGE_ENGINE,          OPT_INIT_FILE,
3252
  OPT_DELAY_KEY_WRITE_ALL,     OPT_SLOW_QUERY_LOG,
3253
  OPT_DELAY_KEY_WRITE,	       OPT_CHARSETS_DIR,
3254
  OPT_MASTER_INFO_FILE,
3255
  OPT_MASTER_RETRY_COUNT,      OPT_LOG_TC, OPT_LOG_TC_SIZE,
3256
  OPT_SQL_BIN_UPDATE_SAME,     OPT_REPLICATE_DO_DB,
3257
  OPT_REPLICATE_IGNORE_DB,     OPT_LOG_SLAVE_UPDATES,
3258
  OPT_BINLOG_DO_DB,            OPT_BINLOG_IGNORE_DB,
3259
  OPT_BINLOG_FORMAT,
3260
#ifndef DBUG_OFF
3261
  OPT_BINLOG_SHOW_XID,
3262
#endif
3263
  OPT_BINLOG_ROWS_EVENT_MAX_SIZE, 
3264
  OPT_WANT_CORE,
3265
  OPT_MEMLOCK,                 OPT_MYISAM_RECOVER,
3266
  OPT_REPLICATE_REWRITE_DB,    OPT_SERVER_ID,
3267
  OPT_SKIP_SLAVE_START,
3268
  OPT_REPLICATE_DO_TABLE,
3269
  OPT_REPLICATE_IGNORE_TABLE,  OPT_REPLICATE_WILD_DO_TABLE,
3270
  OPT_REPLICATE_WILD_IGNORE_TABLE, OPT_REPLICATE_SAME_SERVER_ID,
3271
  OPT_DISCONNECT_SLAVE_EVENT_COUNT, OPT_TC_HEURISTIC_RECOVER,
3272
  OPT_ABORT_SLAVE_EVENT_COUNT,
3273
  OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
3274
  OPT_ENGINE_CONDITION_PUSHDOWN, 
3275
  OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE,
3276
  OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
3277
  OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL,
3278
  OPT_SAFE_USER_CREATE,
3279
  OPT_DO_PSTACK, OPT_REPORT_HOST,
3280
  OPT_REPORT_USER, OPT_REPORT_PASSWORD, OPT_REPORT_PORT,
3281
  OPT_SHOW_SLAVE_AUTH_INFO,
3282
  OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE,
3283
  OPT_RPL_RECOVERY_RANK,
3284
  OPT_RELAY_LOG, OPT_RELAY_LOG_INDEX, OPT_RELAY_LOG_INFO_FILE,
3285
  OPT_SLAVE_SKIP_ERRORS, OPT_SLAVE_ALLOW_BATCHING, OPT_DES_KEY_FILE, OPT_LOCAL_INFILE,
3286
  OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA,
3287
  OPT_SSL_CAPATH, OPT_SSL_CIPHER,
3288
  OPT_BACK_LOG, OPT_BINLOG_CACHE_SIZE,
3289
  OPT_CONNECT_TIMEOUT,
3290
  OPT_FLUSH_TIME, OPT_FT_MIN_WORD_LEN, OPT_FT_BOOLEAN_SYNTAX,
3291
  OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE,
3292
  OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_BLOCK_SIZE,
3293
  OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_AGE_THRESHOLD,
3294
  OPT_LONG_QUERY_TIME,
3295
  OPT_LOWER_CASE_TABLE_NAMES, OPT_MAX_ALLOWED_PACKET,
3296
  OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE,
3297
  OPT_MAX_CONNECTIONS, OPT_MAX_CONNECT_ERRORS,
3298
  OPT_MAX_HEP_TABLE_SIZE,
3299
  OPT_MAX_JOIN_SIZE, OPT_MAX_PREPARED_STMT_COUNT,
3300
  OPT_MAX_RELAY_LOG_SIZE, OPT_MAX_SORT_LENGTH,
3301
  OPT_MAX_SEEKS_FOR_KEY, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS,
3302
  OPT_MAX_LENGTH_FOR_SORT_DATA,
3303
  OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE,
3304
  OPT_MAX_ERROR_COUNT, OPT_MULTI_RANGE_COUNT, OPT_MYISAM_DATA_POINTER_SIZE,
3305
  OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
3306
  OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
3307
  OPT_MYISAM_USE_MMAP, OPT_MYISAM_REPAIR_THREADS,
3308
  OPT_MYISAM_STATS_METHOD,
3309
  OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT,
3310
  OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT,
3311
  OPT_OPEN_FILES_LIMIT,
3312
  OPT_PRELOAD_BUFFER_SIZE,
3313
  OPT_QUERY_CACHE_LIMIT, OPT_QUERY_CACHE_MIN_RES_UNIT, OPT_QUERY_CACHE_SIZE,
3314
  OPT_QUERY_CACHE_TYPE, OPT_QUERY_CACHE_WLOCK_INVALIDATE, OPT_RECORD_BUFFER,
3315
  OPT_RECORD_RND_BUFFER, OPT_DIV_PRECINCREMENT, OPT_RELAY_LOG_SPACE_LIMIT,
3316
  OPT_RELAY_LOG_PURGE,
3317
  OPT_SLAVE_NET_TIMEOUT, OPT_SLAVE_COMPRESSED_PROTOCOL, OPT_SLOW_LAUNCH_TIME,
3318
  OPT_SLAVE_TRANS_RETRIES, OPT_READONLY, OPT_DEBUGGING,
3319
  OPT_SORT_BUFFER, OPT_TABLE_OPEN_CACHE, OPT_TABLE_DEF_CACHE,
3320
  OPT_THREAD_CONCURRENCY, OPT_THREAD_CACHE_SIZE,
3321
  OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK,
3322
  OPT_WAIT_TIMEOUT,
3323
  OPT_ERROR_LOG_FILE,
3324
  OPT_DEFAULT_WEEK_FORMAT,
3325
  OPT_RANGE_ALLOC_BLOCK_SIZE, OPT_ALLOW_SUSPICIOUS_UDFS,
3326
  OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE,
3327
  OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE,
3328
  OPT_SYNC_FRM, OPT_SYNC_BINLOG,
3329
  OPT_SYNC_REPLICATION,
3330
  OPT_SYNC_REPLICATION_SLAVE_ID,
3331
  OPT_SYNC_REPLICATION_TIMEOUT,
3332
  OPT_ENABLE_SHARED_MEMORY,
3333
  OPT_SHARED_MEMORY_BASE_NAME,
3334
  OPT_OLD_PASSWORDS,
3335
  OPT_OLD_ALTER_TABLE,
3336
  OPT_EXPIRE_LOGS_DAYS,
3337
  OPT_GROUP_CONCAT_MAX_LEN,
3338
  OPT_DEFAULT_COLLATION,
3339
  OPT_CHARACTER_SET_CLIENT_HANDSHAKE,
3340
  OPT_CHARACTER_SET_FILESYSTEM,
3341
  OPT_LC_TIME_NAMES,
3342
  OPT_INIT_CONNECT,
3343
  OPT_INIT_SLAVE,
3344
  OPT_SECURE_AUTH,
3345
  OPT_DATE_FORMAT,
3346
  OPT_TIME_FORMAT,
3347
  OPT_DATETIME_FORMAT,
3348
  OPT_LOG_QUERIES_NOT_USING_INDEXES,
3349
  OPT_DEFAULT_TIME_ZONE,
3350
  OPT_SYSDATE_IS_NOW,
3351
  OPT_OPTIMIZER_SEARCH_DEPTH,
3352
  OPT_OPTIMIZER_PRUNE_LEVEL,
3353
  OPT_UPDATABLE_VIEWS_WITH_LIMIT,
3354
  OPT_AUTO_INCREMENT, OPT_AUTO_INCREMENT_OFFSET,
3355
  OPT_ENABLE_LARGE_PAGES,
3356
  OPT_TIMED_MUTEXES,
3357
  OPT_OLD_STYLE_USER_LIMITS,
3358
  OPT_LOG_SLOW_ADMIN_STATEMENTS,
3359
  OPT_TABLE_LOCK_WAIT_TIMEOUT,
3360
  OPT_PLUGIN_LOAD,
3361
  OPT_PLUGIN_DIR,
3362
  OPT_LOG_OUTPUT,
3363
  OPT_PORT_OPEN_TIMEOUT,
3364
  OPT_PROFILING,
3365
  OPT_KEEP_FILES_ON_CREATE,
3366
  OPT_GENERAL_LOG,
3367
  OPT_SLOW_LOG,
3368
  OPT_THREAD_HANDLING,
3369
  OPT_INNODB_ROLLBACK_ON_TIMEOUT,
3370
  OPT_SECURE_FILE_PRIV,
3371
  OPT_MIN_EXAMINED_ROW_LIMIT,
3372
  OPT_LOG_SLOW_SLAVE_STATEMENTS,
3373
  OPT_OLD_MODE,
3374
  OPT_POOL_OF_THREADS,
3375
  OPT_SLAVE_EXEC_MODE
3376
};
3377
3378
3379
#define LONG_TIMEOUT ((ulong) 3600L*24L*365L)
3380
3381
struct my_option my_long_options[] =
3382
{
3383
  {"help", '?', "Display this help and exit.", 
3384
   (uchar**) &opt_help, (uchar**) &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
3385
   0, 0},
3386
  {"abort-slave-event-count", OPT_ABORT_SLAVE_EVENT_COUNT,
3387
   "Option used by mysql-test for debugging and testing of replication.",
3388
   (uchar**) &abort_slave_event_count,  (uchar**) &abort_slave_event_count,
3389
   0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3390
  {"allow-suspicious-udfs", OPT_ALLOW_SUSPICIOUS_UDFS,
3391
   "Allows use of UDFs consisting of only one symbol xxx() "
3392
   "without corresponding xxx_init() or xxx_deinit(). That also means "
3393
   "that one can load any function from any library, for example exit() "
3394
   "from libc.so",
3395
   (uchar**) &opt_allow_suspicious_udfs, (uchar**) &opt_allow_suspicious_udfs,
3396
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3397
  {"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax. This mode will also set transaction isolation level 'serializable'.", 0, 0, 0,
3398
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
3399
  {"auto-increment-increment", OPT_AUTO_INCREMENT,
3400
   "Auto-increment columns are incremented by this",
3401
   (uchar**) &global_system_variables.auto_increment_increment,
3402
   (uchar**) &max_system_variables.auto_increment_increment, 0, GET_ULONG,
3403
   OPT_ARG, 1, 1, 65535, 0, 1, 0 },
3404
  {"auto-increment-offset", OPT_AUTO_INCREMENT_OFFSET,
3405
   "Offset added to Auto-increment columns. Used when auto-increment-increment != 1",
3406
   (uchar**) &global_system_variables.auto_increment_offset,
3407
   (uchar**) &max_system_variables.auto_increment_offset, 0, GET_ULONG, OPT_ARG,
3408
   1, 1, 65535, 0, 1, 0 },
3409
  {"basedir", 'b',
3410
   "Path to installation directory. All paths are usually resolved relative to this.",
3411
   (uchar**) &mysql_home_ptr, (uchar**) &mysql_home_ptr, 0, GET_STR, REQUIRED_ARG,
3412
   0, 0, 0, 0, 0, 0},
3413
  {"big-tables", OPT_BIG_TABLES,
3414
   "Allow big result sets by saving all temporary sets on file (Solves most 'table full' errors).",
3415
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
3416
  {"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
3417
   (uchar**) &my_bind_addr_str, (uchar**) &my_bind_addr_str, 0, GET_STR,
3418
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3419
  {"binlog_format", OPT_BINLOG_FORMAT,
3420
   "Does not have any effect without '--log-bin'. "
3421
   "Tell the master the form of binary logging to use: either 'row' for "
3422
   "row-based binary logging, or 'statement' for statement-based binary "
3423
   "logging, or 'mixed'. 'mixed' is statement-based binary logging except "
3424
   "for those statements where only row-based is correct: those which "
3425
   "involve user-defined functions (i.e. UDFs) or the UUID() function; for "
3426
   "those, row-based binary logging is automatically used. "
3427
   ,(uchar**) &opt_binlog_format, (uchar**) &opt_binlog_format,
3428
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3429
  {"binlog-do-db", OPT_BINLOG_DO_DB,
3430
   "Tells the master it should log updates for the specified database, and exclude all others not explicitly mentioned.",
3431
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3432
  {"binlog-ignore-db", OPT_BINLOG_IGNORE_DB,
3433
   "Tells the master that updates to the given database should not be logged tothe binary log.",
3434
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3435
  {"binlog-row-event-max-size", OPT_BINLOG_ROWS_EVENT_MAX_SIZE,
3436
   "The maximum size of a row-based binary log event in bytes. Rows will be "
3437
   "grouped into events smaller than this size if possible. "
3438
   "The value has to be a multiple of 256.",
3439
   (uchar**) &opt_binlog_rows_event_max_size, 
3440
   (uchar**) &opt_binlog_rows_event_max_size, 0, 
3441
   GET_ULONG, REQUIRED_ARG, 
3442
   /* def_value */ 1024, /* min_value */  256, /* max_value */ ULONG_MAX, 
3443
   /* sub_size */     0, /* block_size */ 256, 
3444
   /* app_type */ 0
3445
  },
3446
#ifndef DISABLE_GRANT_OPTIONS
3447
  {"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts.", 0, 0, 0,
3448
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
3449
#endif
3450
  {"character-set-client-handshake", OPT_CHARACTER_SET_CLIENT_HANDSHAKE,
3451
   "Don't ignore client side character set value sent during handshake.",
3452
   (uchar**) &opt_character_set_client_handshake,
3453
   (uchar**) &opt_character_set_client_handshake,
3454
    0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
3455
  {"character-set-filesystem", OPT_CHARACTER_SET_FILESYSTEM,
3456
   "Set the filesystem character set.",
3457
   (uchar**) &character_set_filesystem_name,
3458
   (uchar**) &character_set_filesystem_name,
3459
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
3460
  {"character-set-server", 'C', "Set the default character set.",
3461
   (uchar**) &default_character_set_name, (uchar**) &default_character_set_name,
3462
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
3463
  {"character-sets-dir", OPT_CHARSETS_DIR,
3464
   "Directory where character sets are.", (uchar**) &charsets_dir,
3465
   (uchar**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3466
  {"chroot", 'r', "Chroot mysqld daemon during startup.",
3467
   (uchar**) &mysqld_chroot, (uchar**) &mysqld_chroot, 0, GET_STR, REQUIRED_ARG,
3468
   0, 0, 0, 0, 0, 0},
3469
  {"collation-server", OPT_DEFAULT_COLLATION, "Set the default collation.",
3470
   (uchar**) &default_collation_name, (uchar**) &default_collation_name,
3471
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
3472
  {"completion-type", OPT_COMPLETION_TYPE, "Default completion type.",
3473
   (uchar**) &global_system_variables.completion_type,
3474
   (uchar**) &max_system_variables.completion_type, 0, GET_ULONG,
3475
   REQUIRED_ARG, 0, 0, 2, 0, 1, 0},
3476
  {"console", OPT_CONSOLE, "Write error output on screen; Don't remove the console window on windows.",
3477
   (uchar**) &opt_console, (uchar**) &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0,
3478
   0, 0, 0},
3479
  {"core-file", OPT_WANT_CORE, "Write core on errors.", 0, 0, 0, GET_NO_ARG,
3480
   NO_ARG, 0, 0, 0, 0, 0, 0},
3481
  {"datadir", 'h', "Path to the database root.", (uchar**) &mysql_data_home,
3482
   (uchar**) &mysql_data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3483
#ifndef DBUG_OFF
3484
  {"debug", '#', "Debug log.", (uchar**) &default_dbug_option,
3485
   (uchar**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
3486
#endif
3487
  {"default-character-set", 'C', "Set the default character set (deprecated option, use --character-set-server instead).",
3488
   (uchar**) &default_character_set_name, (uchar**) &default_character_set_name,
3489
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
3490
  {"default-collation", OPT_DEFAULT_COLLATION, "Set the default collation (deprecated option, use --collation-server instead).",
3491
   (uchar**) &default_collation_name, (uchar**) &default_collation_name,
3492
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
3493
  {"default-storage-engine", OPT_STORAGE_ENGINE,
3494
   "Set the default storage engine (table type) for tables.",
3495
   (uchar**)&default_storage_engine_str, (uchar**)&default_storage_engine_str,
3496
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3497
  {"default-table-type", OPT_STORAGE_ENGINE,
3498
   "(deprecated) Use --default-storage-engine.",
3499
   (uchar**)&default_storage_engine_str, (uchar**)&default_storage_engine_str,
3500
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3501
  {"default-time-zone", OPT_DEFAULT_TIME_ZONE, "Set the default time zone.",
3502
   (uchar**) &default_tz_name, (uchar**) &default_tz_name,
3503
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
3504
  {"delay-key-write", OPT_DELAY_KEY_WRITE, "Type of DELAY_KEY_WRITE.",
3505
   0,0,0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
3506
  {"delay-key-write-for-all-tables", OPT_DELAY_KEY_WRITE_ALL,
3507
   "Don't flush key buffers between writes for any MyISAM table (Deprecated option, use --delay-key-write=all instead).",
3508
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
3509
  {"disconnect-slave-event-count", OPT_DISCONNECT_SLAVE_EVENT_COUNT,
3510
   "Option used by mysql-test for debugging and testing of replication.",
3511
   (uchar**) &disconnect_slave_event_count,
3512
   (uchar**) &disconnect_slave_event_count, 0, GET_INT, REQUIRED_ARG, 0, 0, 0,
3513
   0, 0, 0},
3514
#ifdef HAVE_STACK_TRACE_ON_SEGV
3515
  {"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure.",
3516
   (uchar**) &opt_do_pstack, (uchar**) &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0,
3517
   0, 0, 0, 0},
3518
#endif /* HAVE_STACK_TRACE_ON_SEGV */
3519
  {"engine-condition-pushdown",
3520
   OPT_ENGINE_CONDITION_PUSHDOWN,
3521
   "Push supported query conditions to the storage engine.",
3522
   (uchar**) &global_system_variables.engine_condition_pushdown,
3523
   (uchar**) &global_system_variables.engine_condition_pushdown,
3524
   0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
3525
  /* See how it's handled in get_one_option() */
3526
  {"exit-info", 'T', "Used for debugging;  Use at your own risk!", 0, 0, 0,
3527
   GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
3528
  {"flush", OPT_FLUSH, "Flush tables to disk between SQL commands.", 0, 0, 0,
3529
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
3530
  /* We must always support the next option to make scripts like mysqltest
3531
     easier to do */
3532
  {"gdb", OPT_DEBUGGING,
3533
   "Set up signals usable for debugging",
3534
   (uchar**) &opt_debugging, (uchar**) &opt_debugging,
3535
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3536
  {"general-log", OPT_GENERAL_LOG,
3537
   "Enable|disable general log", (uchar**) &opt_log,
3538
   (uchar**) &opt_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
3539
  {"init-connect", OPT_INIT_CONNECT, "Command(s) that are executed for each new connection",
3540
   (uchar**) &opt_init_connect, (uchar**) &opt_init_connect, 0, GET_STR_ALLOC,
3541
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3542
  {"init-file", OPT_INIT_FILE, "Read SQL commands from this file at startup.",
3543
   (uchar**) &opt_init_file, (uchar**) &opt_init_file, 0, GET_STR, REQUIRED_ARG,
3544
   0, 0, 0, 0, 0, 0},
3545
  {"init-slave", OPT_INIT_SLAVE, "Command(s) that are executed when a slave connects to this master",
3546
   (uchar**) &opt_init_slave, (uchar**) &opt_init_slave, 0, GET_STR_ALLOC,
3547
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3548
  {"language", 'L',
3549
   "Client error messages in given language. May be given as a full path.",
3550
   (uchar**) &language_ptr, (uchar**) &language_ptr, 0, GET_STR, REQUIRED_ARG,
3551
   0, 0, 0, 0, 0, 0},
3552
  {"lc-time-names", OPT_LC_TIME_NAMES,
3553
   "Set the language used for the month names and the days of the week.",
3554
   (uchar**) &lc_time_names_name,
3555
   (uchar**) &lc_time_names_name,
3556
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
3557
  {"local-infile", OPT_LOCAL_INFILE,
3558
   "Enable/disable LOAD DATA LOCAL INFILE (takes values 1|0).",
3559
   (uchar**) &opt_local_infile,
3560
   (uchar**) &opt_local_infile, 0, GET_BOOL, OPT_ARG,
3561
   1, 0, 0, 0, 0, 0},
3562
  {"log", 'l', "Log connections and queries to file.", (uchar**) &opt_logname,
3563
   (uchar**) &opt_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
3564
  {"log-bin", OPT_BIN_LOG,
3565
   "Log update queries in binary format. Optional (but strongly recommended "
3566
   "to avoid replication problems if server's hostname changes) argument "
3567
   "should be the chosen location for the binary log files.",
3568
   (uchar**) &opt_bin_logname, (uchar**) &opt_bin_logname, 0, GET_STR_ALLOC,
3569
   OPT_ARG, 0, 0, 0, 0, 0, 0},
3570
  {"log-bin-index", OPT_BIN_LOG_INDEX,
3571
   "File that holds the names for last binary log files.",
3572
   (uchar**) &opt_binlog_index_name, (uchar**) &opt_binlog_index_name, 0, GET_STR,
3573
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3574
  /*
3575
    This option starts with "log-bin" to emphasize that it is specific of
3576
    binary logging.
3577
  */
3578
  {"log-bin-trust-function-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
3579
   "If equal to 0 (the default), then when --log-bin is used, creation of "
3580
   "a stored function (or trigger) is allowed only to users having the SUPER privilege "
3581
   "and only if this stored function (trigger) may not break binary logging."
3582
   "Note that if ALL connections to this server ALWAYS use row-based binary "
3583
   "logging, the security issues do not exist and the binary logging cannot "
3584
   "break, so you can safely set this to 1."
3585
   ,(uchar**) &trust_function_creators, (uchar**) &trust_function_creators, 0,
3586
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3587
  {"log-error", OPT_ERROR_LOG_FILE, "Error log file.",
3588
   (uchar**) &log_error_file_ptr, (uchar**) &log_error_file_ptr, 0, GET_STR,
3589
   OPT_ARG, 0, 0, 0, 0, 0, 0},
3590
  {"log-isam", OPT_ISAM_LOG, "Log all MyISAM changes to file.",
3591
   (uchar**) &myisam_log_filename, (uchar**) &myisam_log_filename, 0, GET_STR,
3592
   OPT_ARG, 0, 0, 0, 0, 0, 0},
3593
  {"log-long-format", '0',
3594
   "Log some extra information to update log. Please note that this option is deprecated; see --log-short-format option.", 
3595
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
3596
#ifdef WITH_CSV_STORAGE_ENGINE
3597
  {"log-output", OPT_LOG_OUTPUT,
3598
   "Syntax: log-output[=value[,value...]], where \"value\" could be TABLE, "
3599
   "FILE or NONE.",
3600
   (uchar**) &log_output_str, (uchar**) &log_output_str, 0,
3601
   GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
3602
#endif
3603
  {"log-queries-not-using-indexes", OPT_LOG_QUERIES_NOT_USING_INDEXES,
3604
   "Log queries that are executed without benefit of any index to the slow log if it is open.",
3605
   (uchar**) &opt_log_queries_not_using_indexes, (uchar**) &opt_log_queries_not_using_indexes,
3606
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3607
  {"log-short-format", OPT_SHORT_LOG_FORMAT,
3608
   "Don't log extra information to update and slow-query logs.",
3609
   (uchar**) &opt_short_log_format, (uchar**) &opt_short_log_format,
3610
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3611
  {"log-slave-updates", OPT_LOG_SLAVE_UPDATES,
3612
   "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.",
3613
   (uchar**) &opt_log_slave_updates, (uchar**) &opt_log_slave_updates, 0, GET_BOOL,
3614
   NO_ARG, 0, 0, 0, 0, 0, 0},
3615
  {"log-slow-admin-statements", OPT_LOG_SLOW_ADMIN_STATEMENTS,
3616
   "Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements to the slow log if it is open.",
3617
   (uchar**) &opt_log_slow_admin_statements,
3618
   (uchar**) &opt_log_slow_admin_statements,
3619
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3620
 {"log-slow-slave-statements", OPT_LOG_SLOW_SLAVE_STATEMENTS,
3621
  "Log slow statements executed by slave thread to the slow log if it is open.",
3622
  (uchar**) &opt_log_slow_slave_statements,
3623
  (uchar**) &opt_log_slow_slave_statements,
3624
  0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3625
  {"log-slow-queries", OPT_SLOW_QUERY_LOG,
3626
    "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.",
3627
   (uchar**) &opt_slow_logname, (uchar**) &opt_slow_logname, 0, GET_STR, OPT_ARG,
3628
   0, 0, 0, 0, 0, 0},
3629
  {"log-tc", OPT_LOG_TC,
3630
   "Path to transaction coordinator log (used for transactions that affect "
3631
   "more than one storage engine, when binary log is disabled)",
3632
   (uchar**) &opt_tc_log_file, (uchar**) &opt_tc_log_file, 0, GET_STR,
3633
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3634
#ifdef HAVE_MMAP
3635
  {"log-tc-size", OPT_LOG_TC_SIZE, "Size of transaction coordinator log.",
3636
   (uchar**) &opt_tc_log_size, (uchar**) &opt_tc_log_size, 0, GET_ULONG,
3637
   REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, ULONG_MAX, 0,
3638
   TC_LOG_PAGE_SIZE, 0},
3639
#endif
3640
  {"log-update", OPT_UPDATE_LOG,
3641
   "The update log is deprecated since version 5.0, is replaced by the binary \
3642
log and this option justs turns on --log-bin instead.",
3643
   (uchar**) &opt_update_logname, (uchar**) &opt_update_logname, 0, GET_STR,
3644
   OPT_ARG, 0, 0, 0, 0, 0, 0},
3645
  {"log-warnings", 'W', "Log some not critical warnings to the log file.",
3646
   (uchar**) &global_system_variables.log_warnings,
3647
   (uchar**) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0,
3648
   0, 0, 0},
3649
  {"low-priority-updates", OPT_LOW_PRIORITY_UPDATES,
3650
   "INSERT/DELETE/UPDATE has lower priority than selects.",
3651
   (uchar**) &global_system_variables.low_priority_updates,
3652
   (uchar**) &max_system_variables.low_priority_updates,
3653
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3654
  {"master-info-file", OPT_MASTER_INFO_FILE,
3655
   "The location and name of the file that remembers the master and where the I/O replication \
3656
thread is in the master's binlogs.",
3657
   (uchar**) &master_info_file, (uchar**) &master_info_file, 0, GET_STR,
3658
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3659
  {"master-retry-count", OPT_MASTER_RETRY_COUNT,
3660
   "The number of tries the slave will make to connect to the master before giving up.",
3661
   (uchar**) &master_retry_count, (uchar**) &master_retry_count, 0, GET_ULONG,
3662
   REQUIRED_ARG, 3600*24, 0, 0, 0, 0, 0},
3663
  {"max-binlog-dump-events", OPT_MAX_BINLOG_DUMP_EVENTS,
3664
   "Option used by mysql-test for debugging and testing of replication.",
3665
   (uchar**) &max_binlog_dump_events, (uchar**) &max_binlog_dump_events, 0,
3666
   GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3667
  {"memlock", OPT_MEMLOCK, "Lock mysqld in memory.", (uchar**) &locked_in_memory,
3668
   (uchar**) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3669
  {"myisam-recover", OPT_MYISAM_RECOVER,
3670
   "Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.",
3671
   (uchar**) &myisam_recover_options_str, (uchar**) &myisam_recover_options_str, 0,
3672
   GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
3673
  {"new", 'n', "Use very new possible 'unsafe' functions.",
3674
   (uchar**) &global_system_variables.new_mode,
3675
   (uchar**) &max_system_variables.new_mode,
3676
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3677
  {"old-alter-table", OPT_OLD_ALTER_TABLE,
3678
   "Use old, non-optimized alter table.",
3679
   (uchar**) &global_system_variables.old_alter_table,
3680
   (uchar**) &max_system_variables.old_alter_table, 0, GET_BOOL, NO_ARG,
3681
   0, 0, 0, 0, 0, 0},
3682
  {"old-passwords", OPT_OLD_PASSWORDS, "Use old password encryption method (needed for 4.0 and older clients).",
3683
   (uchar**) &global_system_variables.old_passwords,
3684
   (uchar**) &max_system_variables.old_passwords, 0, GET_BOOL, NO_ARG,
3685
   0, 0, 0, 0, 0, 0},
3686
  {"old-style-user-limits", OPT_OLD_STYLE_USER_LIMITS,
3687
   "Enable old-style user limits (before 5.0.3 user resources were counted per each user+host vs. per account)",
3688
   (uchar**) &opt_old_style_user_limits, (uchar**) &opt_old_style_user_limits,
3689
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3690
  {"pid-file", OPT_PID_FILE, "Pid file used by safe_mysqld.",
3691
   (uchar**) &pidfile_name_ptr, (uchar**) &pidfile_name_ptr, 0, GET_STR,
3692
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3693
  {"port", 'P', "Port number to use for connection or 0 for default to, in "
3694
   "order of preference, my.cnf, $MYSQL_TCP_PORT, "
3695
#if MYSQL_PORT_DEFAULT == 0
3696
   "/etc/services, "
3697
#endif
3698
   "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
3699
   (uchar**) &mysqld_port,
3700
   (uchar**) &mysqld_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3701
  {"port-open-timeout", OPT_PORT_OPEN_TIMEOUT,
3702
   "Maximum time in seconds to wait for the port to become free. "
3703
   "(Default: no wait)", (uchar**) &mysqld_port_timeout,
3704
   (uchar**) &mysqld_port_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3705
  {"relay-log", OPT_RELAY_LOG,
3706
   "The location and name to use for relay logs.",
3707
   (uchar**) &opt_relay_logname, (uchar**) &opt_relay_logname, 0,
3708
   GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3709
  {"relay-log-index", OPT_RELAY_LOG_INDEX,
3710
   "The location and name to use for the file that keeps a list of the last \
3711
relay logs.",
3712
   (uchar**) &opt_relaylog_index_name, (uchar**) &opt_relaylog_index_name, 0,
3713
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3714
  {"relay-log-info-file", OPT_RELAY_LOG_INFO_FILE,
3715
   "The location and name of the file that remembers where the SQL replication \
3716
thread is in the relay logs.",
3717
   (uchar**) &relay_log_info_file, (uchar**) &relay_log_info_file, 0, GET_STR,
3718
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3719
  {"replicate-do-db", OPT_REPLICATE_DO_DB,
3720
   "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.%.",
3721
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3722
  {"replicate-do-table", OPT_REPLICATE_DO_TABLE,
3723
   "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.",
3724
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3725
  {"replicate-ignore-db", OPT_REPLICATE_IGNORE_DB,
3726
   "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.%. ",
3727
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3728
  {"replicate-ignore-table", OPT_REPLICATE_IGNORE_TABLE,
3729
   "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.",
3730
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3731
  {"replicate-rewrite-db", OPT_REPLICATE_REWRITE_DB,
3732
   "Updates to a database with a different name than the original. Example: replicate-rewrite-db=master_db_name->slave_db_name.",
3733
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3734
  {"replicate-same-server-id", OPT_REPLICATE_SAME_SERVER_ID,
3735
   "In replication, if set to 1, do not skip events having our server id. \
3736
Default value is 0 (to break infinite loops in circular replication). \
3737
Can't be set to 1 if --log-slave-updates is used.",
3738
   (uchar**) &replicate_same_server_id,
3739
   (uchar**) &replicate_same_server_id,
3740
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3741
  {"replicate-wild-do-table", OPT_REPLICATE_WILD_DO_TABLE,
3742
   "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.",
3743
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3744
  {"replicate-wild-ignore-table", OPT_REPLICATE_WILD_IGNORE_TABLE,
3745
   "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.",
3746
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3747
  // In replication, we may need to tell the other servers how to connect
3748
  {"report-host", OPT_REPORT_HOST,
3749
   "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.",
3750
   (uchar**) &report_host, (uchar**) &report_host, 0, GET_STR, REQUIRED_ARG, 0, 0,
3751
   0, 0, 0, 0},
3752
  {"report-password", OPT_REPORT_PASSWORD, "Undocumented.",
3753
   (uchar**) &report_password, (uchar**) &report_password, 0, GET_STR,
3754
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3755
  {"report-port", OPT_REPORT_PORT,
3756
   "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.",
3757
   (uchar**) &report_port, (uchar**) &report_port, 0, GET_UINT, REQUIRED_ARG,
3758
   MYSQL_PORT, 0, 0, 0, 0, 0},
3759
  {"safe-mode", OPT_SAFE, "Skip some optimize stages (for testing).",
3760
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
3761
  {"secure-file-priv", OPT_SECURE_FILE_PRIV,
3762
   "Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files within specified directory",
3763
   (uchar**) &opt_secure_file_priv, (uchar**) &opt_secure_file_priv, 0,
3764
   GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3765
  {"server-id",	OPT_SERVER_ID,
3766
   "Uniquely identifies the server instance in the community of replication partners.",
3767
   (uchar**) &server_id, (uchar**) &server_id, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 0,
3768
   0, 0, 0},
3769
  {"set-variable", 'O',
3770
   "Change the value of a variable. Please note that this option is deprecated;you can set variables directly with --variable-name=value.",
3771
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3772
  {"skip-new", OPT_SKIP_NEW, "Don't use new, possible wrong routines.",
3773
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
3774
  {"skip-slave-start", OPT_SKIP_SLAVE_START,
3775
   "If set, slave is not autostarted.", (uchar**) &opt_skip_slave_start,
3776
   (uchar**) &opt_skip_slave_start, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3777
  {"skip-stack-trace", OPT_SKIP_STACK_TRACE,
3778
   "Don't print a stack trace on failure.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
3779
   0, 0, 0, 0},
3780
  {"skip-symlink", OPT_SKIP_SYMLINKS, "Don't allow symlinking of tables. Deprecated option.  Use --skip-symbolic-links instead.",
3781
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
3782
  {"skip-thread-priority", OPT_SKIP_PRIOR,
3783
   "Don't give threads different priorities.", 0, 0, 0, GET_NO_ARG, NO_ARG,
3784
   DEFAULT_SKIP_THREAD_PRIORITY, 0, 0, 0, 0, 0},
3785
  {"slave-load-tmpdir", OPT_SLAVE_LOAD_TMPDIR,
3786
   "The location where the slave should put its temporary files when \
3787
replicating a LOAD DATA INFILE command.",
3788
   (uchar**) &slave_load_tmpdir, (uchar**) &slave_load_tmpdir, 0, GET_STR_ALLOC,
3789
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3790
  {"slave-skip-errors", OPT_SLAVE_SKIP_ERRORS,
3791
   "Tells the slave thread to continue replication when a query event returns an error from the provided list.",
3792
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3793
  {"slave-exec-mode", OPT_SLAVE_EXEC_MODE,
3794
   "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.",
3795
   (uchar**) &slave_exec_mode_str, (uchar**) &slave_exec_mode_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3796
  {"slow-query-log", OPT_SLOW_LOG,
3797
   "Enable|disable slow query log", (uchar**) &opt_slow_log,
3798
   (uchar**) &opt_slow_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
3799
  {"sporadic-binlog-dump-fail", OPT_SPORADIC_BINLOG_DUMP_FAIL,
3800
   "Option used by mysql-test for debugging and testing of replication.",
3801
   (uchar**) &opt_sporadic_binlog_dump_fail,
3802
   (uchar**) &opt_sporadic_binlog_dump_fail, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
3803
   0},
3804
  {"sql-bin-update-same", OPT_SQL_BIN_UPDATE_SAME,
3805
   "The update log is deprecated since version 5.0, is replaced by the binary \
3806
log and this option does nothing anymore.",
3807
   0, 0, 0, GET_DISABLED, NO_ARG, 0, 0, 0, 0, 0, 0},
3808
  {"symbolic-links", 's', "Enable symbolic link support.",
3809
   (uchar**) &my_use_symdir, (uchar**) &my_use_symdir, 0, GET_BOOL, NO_ARG,
3810
   /*
3811
     The system call realpath() produces warnings under valgrind and
3812
     purify. These are not suppressed: instead we disable symlinks
3813
     option if compiled with valgrind support.
3814
   */
3815
   IF_PURIFY(0,1), 0, 0, 0, 0, 0},
3816
  {"sysdate-is-now", OPT_SYSDATE_IS_NOW,
3817
   "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.",
3818
   (uchar**) &global_system_variables.sysdate_is_now,
3819
   0, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
3820
  {"tc-heuristic-recover", OPT_TC_HEURISTIC_RECOVER,
3821
   "Decision to use in heuristic recover process. Possible values are COMMIT or ROLLBACK.",
3822
   (uchar**) &opt_tc_heuristic_recover, (uchar**) &opt_tc_heuristic_recover,
3823
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3824
  {"temp-pool", OPT_TEMP_POOL,
3825
   "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.",
3826
   (uchar**) &use_temp_pool, (uchar**) &use_temp_pool, 0, GET_BOOL, NO_ARG, 1,
3827
   0, 0, 0, 0, 0},
3828
  {"timed_mutexes", OPT_TIMED_MUTEXES,
3829
   "Specify whether to time mutexes (only InnoDB mutexes are currently supported)",
3830
   (uchar**) &timed_mutexes, (uchar**) &timed_mutexes, 0, GET_BOOL, NO_ARG, 0, 
3831
    0, 0, 0, 0, 0},
3832
  {"tmpdir", 't',
3833
   "Path for temporary files. Several paths may be specified, separated by a "
3834
   "colon (:)"
3835
   ", in this case they are used in a round-robin fashion.",
3836
   (uchar**) &opt_mysql_tmpdir,
3837
   (uchar**) &opt_mysql_tmpdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3838
  {"transaction-isolation", OPT_TX_ISOLATION,
3839
   "Default transaction isolation level.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0,
3840
   0, 0, 0, 0, 0},
3841
  {"use-symbolic-links", 's', "Enable symbolic link support. Deprecated option; use --symbolic-links instead.",
3842
   (uchar**) &my_use_symdir, (uchar**) &my_use_symdir, 0, GET_BOOL, NO_ARG,
3843
   IF_PURIFY(0,1), 0, 0, 0, 0, 0},
3844
  {"user", 'u', "Run mysqld daemon as user.", 0, 0, 0, GET_STR, REQUIRED_ARG,
3845
   0, 0, 0, 0, 0, 0},
3846
  {"verbose", 'v', "Used with --help option for detailed help",
3847
   (uchar**) &opt_verbose, (uchar**) &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
3848
   0, 0},
3849
  {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
3850
   NO_ARG, 0, 0, 0, 0, 0, 0},
3851
  {"warnings", 'W', "Deprecated; use --log-warnings instead.",
3852
   (uchar**) &global_system_variables.log_warnings,
3853
   (uchar**) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG,
3854
   1, 0, ULONG_MAX, 0, 0, 0},
3855
  { "back_log", OPT_BACK_LOG,
3856
    "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.",
3857
    (uchar**) &back_log, (uchar**) &back_log, 0, GET_ULONG,
3858
    REQUIRED_ARG, 50, 1, 65535, 0, 1, 0 },
3859
  {"binlog_cache_size", OPT_BINLOG_CACHE_SIZE,
3860
   "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.",
3861
   (uchar**) &binlog_cache_size, (uchar**) &binlog_cache_size, 0, GET_ULONG,
3862
   REQUIRED_ARG, 32*1024L, IO_SIZE, ULONG_MAX, 0, IO_SIZE, 0},
3863
  {"bulk_insert_buffer_size", OPT_BULK_INSERT_BUFFER_SIZE,
3864
   "Size of tree cache used in bulk insert optimisation. Note that this is a limit per thread!",
3865
   (uchar**) &global_system_variables.bulk_insert_buff_size,
3866
   (uchar**) &max_system_variables.bulk_insert_buff_size,
3867
   0, GET_ULONG, REQUIRED_ARG, 8192*1024, 0, ULONG_MAX, 0, 1, 0},
3868
  {"connect_timeout", OPT_CONNECT_TIMEOUT,
3869
   "The number of seconds the mysqld server is waiting for a connect packet before responding with 'Bad handshake'.",
3870
    (uchar**) &connect_timeout, (uchar**) &connect_timeout,
3871
   0, GET_ULONG, REQUIRED_ARG, CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1, 0 },
3872
  { "date_format", OPT_DATE_FORMAT,
3873
    "The DATE format (For future).",
3874
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_DATE],
3875
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_DATE],
3876
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3877
  { "datetime_format", OPT_DATETIME_FORMAT,
3878
    "The DATETIME/TIMESTAMP format (for future).",
3879
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME],
3880
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME],
3881
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3882
  { "default_week_format", OPT_DEFAULT_WEEK_FORMAT,
3883
    "The default week format used by WEEK() functions.",
3884
    (uchar**) &global_system_variables.default_week_format,
3885
    (uchar**) &max_system_variables.default_week_format,
3886
    0, GET_ULONG, REQUIRED_ARG, 0, 0, 7L, 0, 1, 0},
3887
  {"div_precision_increment", OPT_DIV_PRECINCREMENT,
3888
   "Precision of the result of '/' operator will be increased on that value.",
3889
   (uchar**) &global_system_variables.div_precincrement,
3890
   (uchar**) &max_system_variables.div_precincrement, 0, GET_ULONG,
3891
   REQUIRED_ARG, 4, 0, DECIMAL_MAX_SCALE, 0, 0, 0},
3892
  {"expire_logs_days", OPT_EXPIRE_LOGS_DAYS,
3893
   "If non-zero, binary logs will be purged after expire_logs_days "
3894
   "days; possible purges happen at startup and at binary log rotation.",
3895
   (uchar**) &expire_logs_days,
3896
   (uchar**) &expire_logs_days, 0, GET_ULONG,
3897
   REQUIRED_ARG, 0, 0, 99, 0, 1, 0},
3898
  { "flush_time", OPT_FLUSH_TIME,
3899
    "A dedicated thread is created to flush all tables at the given interval.",
3900
    (uchar**) &flush_time, (uchar**) &flush_time, 0, GET_ULONG, REQUIRED_ARG,
3901
    FLUSH_TIME, 0, LONG_TIMEOUT, 0, 1, 0},
3902
  { "group_concat_max_len", OPT_GROUP_CONCAT_MAX_LEN,
3903
    "The maximum length of the result of function  group_concat.",
3904
    (uchar**) &global_system_variables.group_concat_max_len,
3905
    (uchar**) &max_system_variables.group_concat_max_len, 0, GET_ULONG,
3906
    REQUIRED_ARG, 1024, 4, ULONG_MAX, 0, 1, 0},
3907
  {"interactive_timeout", OPT_INTERACTIVE_TIMEOUT,
3908
   "The number of seconds the server waits for activity on an interactive connection before closing it.",
3909
   (uchar**) &global_system_variables.net_interactive_timeout,
3910
   (uchar**) &max_system_variables.net_interactive_timeout, 0,
3911
   GET_ULONG, REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
3912
  {"join_buffer_size", OPT_JOIN_BUFF_SIZE,
3913
   "The size of the buffer that is used for full joins.",
3914
   (uchar**) &global_system_variables.join_buff_size,
3915
   (uchar**) &max_system_variables.join_buff_size, 0, GET_ULONG,
3916
   REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ULONG_MAX,
3917
   MALLOC_OVERHEAD, IO_SIZE, 0},
3918
  {"keep_files_on_create", OPT_KEEP_FILES_ON_CREATE,
3919
   "Don't overwrite stale .MYD and .MYI even if no directory is specified.",
3920
   (uchar**) &global_system_variables.keep_files_on_create,
3921
   (uchar**) &max_system_variables.keep_files_on_create,
3922
   0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
3923
  {"key_buffer_size", OPT_KEY_BUFFER_SIZE,
3924
   "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.",
3925
   (uchar**) &dflt_key_cache_var.param_buff_size,
3926
   (uchar**) 0,
3927
   0, (GET_ULL | GET_ASK_ADDR),
3928
   REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, SIZE_T_MAX, MALLOC_OVERHEAD,
3929
   IO_SIZE, 0},
3930
  {"key_cache_age_threshold", OPT_KEY_CACHE_AGE_THRESHOLD,
3931
   "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",
3932
   (uchar**) &dflt_key_cache_var.param_age_threshold,
3933
   (uchar**) 0,
3934
   0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG, 
3935
   300, 100, ULONG_MAX, 0, 100, 0},
3936
  {"key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE,
3937
   "The default size of key cache blocks",
3938
   (uchar**) &dflt_key_cache_var.param_block_size,
3939
   (uchar**) 0,
3940
   0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG,
3941
   KEY_CACHE_BLOCK_SIZE, 512, 1024 * 16, 0, 512, 0},
3942
  {"key_cache_division_limit", OPT_KEY_CACHE_DIVISION_LIMIT,
3943
   "The minimum percentage of warm blocks in key cache",
3944
   (uchar**) &dflt_key_cache_var.param_division_limit,
3945
   (uchar**) 0,
3946
   0, (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100,
3947
   1, 100, 0, 1, 0},
3948
  {"long_query_time", OPT_LONG_QUERY_TIME,
3949
   "Log all queries that have taken more than long_query_time seconds to execute to file. "
3950
   "The argument will be treated as a decimal value with microsecond precission.",
3951
   (uchar**) &long_query_time, (uchar**) &long_query_time, 0, GET_DOUBLE,
3952
   REQUIRED_ARG, 10, 0, LONG_TIMEOUT, 0, 0, 0},
3953
  {"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES,
3954
   "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",
3955
   (uchar**) &lower_case_table_names,
3956
   (uchar**) &lower_case_table_names, 0, GET_UINT, OPT_ARG,
3957
#ifdef FN_NO_CASE_SENCE
3958
    1
3959
#else
3960
    0
3961
#endif
3962
   , 0, 2, 0, 1, 0},
3963
  {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
3964
   "Max packetlength to send/receive from to server.",
3965
   (uchar**) &global_system_variables.max_allowed_packet,
3966
   (uchar**) &max_system_variables.max_allowed_packet, 0, GET_ULONG,
3967
   REQUIRED_ARG, 1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
3968
  {"max_binlog_cache_size", OPT_MAX_BINLOG_CACHE_SIZE,
3969
   "Can be used to restrict the total size used to cache a multi-transaction query.",
3970
   (uchar**) &max_binlog_cache_size, (uchar**) &max_binlog_cache_size, 0,
3971
   GET_ULONG, REQUIRED_ARG, ULONG_MAX, IO_SIZE, ULONG_MAX, 0, IO_SIZE, 0},
3972
  {"max_binlog_size", OPT_MAX_BINLOG_SIZE,
3973
   "Binary log will be rotated automatically when the size exceeds this \
3974
value. Will also apply to relay logs if max_relay_log_size is 0. \
3975
The minimum value for this variable is 4096.",
3976
   (uchar**) &max_binlog_size, (uchar**) &max_binlog_size, 0, GET_ULONG,
3977
   REQUIRED_ARG, 1024*1024L*1024L, IO_SIZE, 1024*1024L*1024L, 0, IO_SIZE, 0},
3978
  {"max_connect_errors", OPT_MAX_CONNECT_ERRORS,
3979
   "If there is more than this number of interrupted connections from a host this host will be blocked from further connections.",
3980
   (uchar**) &max_connect_errors, (uchar**) &max_connect_errors, 0, GET_ULONG,
3981
    REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ULONG_MAX, 0, 1, 0},
3982
  // Default max_connections of 151 is larger than Apache's default max
3983
  // children, to avoid "too many connections" error in a common setup
3984
  {"max_connections", OPT_MAX_CONNECTIONS,
3985
   "The number of simultaneous clients allowed.", (uchar**) &max_connections,
3986
   (uchar**) &max_connections, 0, GET_ULONG, REQUIRED_ARG, 151, 1, 100000, 0, 1,
3987
   0},
3988
  {"max_error_count", OPT_MAX_ERROR_COUNT,
3989
   "Max number of errors/warnings to store for a statement.",
3990
   (uchar**) &global_system_variables.max_error_count,
3991
   (uchar**) &max_system_variables.max_error_count,
3992
   0, GET_ULONG, REQUIRED_ARG, DEFAULT_ERROR_COUNT, 0, 65535, 0, 1, 0},
3993
  {"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE,
3994
   "Don't allow creation of heap tables bigger than this.",
3995
   (uchar**) &global_system_variables.max_heap_table_size,
3996
   (uchar**) &max_system_variables.max_heap_table_size, 0, GET_ULL,
3997
   REQUIRED_ARG, 16*1024*1024L, 16384, MAX_MEM_TABLE_SIZE,
3998
   MALLOC_OVERHEAD, 1024, 0},
3999
  {"max_join_size", OPT_MAX_JOIN_SIZE,
4000
   "Joins that are probably going to read more than max_join_size records return an error.",
4001
   (uchar**) &global_system_variables.max_join_size,
4002
   (uchar**) &max_system_variables.max_join_size, 0, GET_HA_ROWS, REQUIRED_ARG,
4003
   ~0L, 1, ~0L, 0, 1, 0},
4004
   {"max_length_for_sort_data", OPT_MAX_LENGTH_FOR_SORT_DATA,
4005
    "Max number of bytes in sorted records.",
4006
    (uchar**) &global_system_variables.max_length_for_sort_data,
4007
    (uchar**) &max_system_variables.max_length_for_sort_data, 0, GET_ULONG,
4008
    REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
4009
  {"max_relay_log_size", OPT_MAX_RELAY_LOG_SIZE,
4010
   "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.",
4011
   (uchar**) &max_relay_log_size, (uchar**) &max_relay_log_size, 0, GET_ULONG,
4012
   REQUIRED_ARG, 0L, 0L, 1024*1024L*1024L, 0, IO_SIZE, 0},
4013
  { "max_seeks_for_key", OPT_MAX_SEEKS_FOR_KEY,
4014
    "Limit assumed max number of seeks when looking up rows based on a key",
4015
    (uchar**) &global_system_variables.max_seeks_for_key,
4016
    (uchar**) &max_system_variables.max_seeks_for_key, 0, GET_ULONG,
4017
    REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0 },
4018
  {"max_sort_length", OPT_MAX_SORT_LENGTH,
4019
   "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).",
4020
   (uchar**) &global_system_variables.max_sort_length,
4021
   (uchar**) &max_system_variables.max_sort_length, 0, GET_ULONG,
4022
   REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
4023
  {"max_tmp_tables", OPT_MAX_TMP_TABLES,
4024
   "Maximum number of temporary tables a client can keep open at a time.",
4025
   (uchar**) &global_system_variables.max_tmp_tables,
4026
   (uchar**) &max_system_variables.max_tmp_tables, 0, GET_ULONG,
4027
   REQUIRED_ARG, 32, 1, ULONG_MAX, 0, 1, 0},
4028
  {"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
4029
   "After this many write locks, allow some read locks to run in between.",
4030
   (uchar**) &max_write_lock_count, (uchar**) &max_write_lock_count, 0, GET_ULONG,
4031
   REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0},
4032
  {"min_examined_row_limit", OPT_MIN_EXAMINED_ROW_LIMIT,
4033
   "Don't log queries which examine less than min_examined_row_limit rows to file.",
4034
   (uchar**) &global_system_variables.min_examined_row_limit,
4035
   (uchar**) &max_system_variables.min_examined_row_limit, 0, GET_ULONG,
4036
  REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1L, 0},
4037
  {"myisam_block_size", OPT_MYISAM_BLOCK_SIZE,
4038
   "Block size to be used for MyISAM index pages.",
4039
   (uchar**) &opt_myisam_block_size,
4040
   (uchar**) &opt_myisam_block_size, 0, GET_ULONG, REQUIRED_ARG,
4041
   MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, MI_MAX_KEY_BLOCK_LENGTH,
4042
   0, MI_MIN_KEY_BLOCK_LENGTH, 0},
4043
  {"myisam_data_pointer_size", OPT_MYISAM_DATA_POINTER_SIZE,
4044
   "Default pointer size to be used for MyISAM tables.",
4045
   (uchar**) &myisam_data_pointer_size,
4046
   (uchar**) &myisam_data_pointer_size, 0, GET_ULONG, REQUIRED_ARG,
4047
   6, 2, 7, 0, 1, 0},
4048
  {"myisam_max_extra_sort_file_size", OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
4049
   "Deprecated option",
4050
   (uchar**) &global_system_variables.myisam_max_extra_sort_file_size,
4051
   (uchar**) &max_system_variables.myisam_max_extra_sort_file_size,
4052
   0, GET_ULL, REQUIRED_ARG, (ulonglong) MI_MAX_TEMP_LENGTH,
4053
   0, (ulonglong) MAX_FILE_SIZE, 0, 1, 0},
4054
  {"myisam_max_sort_file_size", OPT_MYISAM_MAX_SORT_FILE_SIZE,
4055
   "Don't use the fast sort index method to created index if the temporary file would get bigger than this.",
4056
   (uchar**) &global_system_variables.myisam_max_sort_file_size,
4057
   (uchar**) &max_system_variables.myisam_max_sort_file_size, 0,
4058
   GET_ULL, REQUIRED_ARG, (longlong) LONG_MAX, 0, (ulonglong) MAX_FILE_SIZE,
4059
   0, 1024*1024, 0},
4060
  {"myisam_repair_threads", OPT_MYISAM_REPAIR_THREADS,
4061
   "Number of threads to use when repairing MyISAM tables. The value of 1 disables parallel repair.",
4062
   (uchar**) &global_system_variables.myisam_repair_threads,
4063
   (uchar**) &max_system_variables.myisam_repair_threads, 0,
4064
   GET_ULONG, REQUIRED_ARG, 1, 1, ULONG_MAX, 0, 1, 0},
4065
  {"myisam_sort_buffer_size", OPT_MYISAM_SORT_BUFFER_SIZE,
4066
   "The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE.",
4067
   (uchar**) &global_system_variables.myisam_sort_buff_size,
4068
   (uchar**) &max_system_variables.myisam_sort_buff_size, 0,
4069
   GET_ULONG, REQUIRED_ARG, 8192*1024, 4, ~0L, 0, 1, 0},
4070
  {"myisam_stats_method", OPT_MYISAM_STATS_METHOD,
4071
   "Specifies how MyISAM index statistics collection code should threat NULLs. "
4072
   "Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), "
4073
   "\"nulls_equal\" (emulate 4.0 behavior), and \"nulls_ignored\".",
4074
   (uchar**) &myisam_stats_method_str, (uchar**) &myisam_stats_method_str, 0,
4075
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4076
  {"net_buffer_length", OPT_NET_BUFFER_LENGTH,
4077
   "Buffer length for TCP/IP and socket communication.",
4078
   (uchar**) &global_system_variables.net_buffer_length,
4079
   (uchar**) &max_system_variables.net_buffer_length, 0, GET_ULONG,
4080
   REQUIRED_ARG, 16384, 1024, 1024*1024L, 0, 1024, 0},
4081
  {"net_read_timeout", OPT_NET_READ_TIMEOUT,
4082
   "Number of seconds to wait for more data from a connection before aborting the read.",
4083
   (uchar**) &global_system_variables.net_read_timeout,
4084
   (uchar**) &max_system_variables.net_read_timeout, 0, GET_ULONG,
4085
   REQUIRED_ARG, NET_READ_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
4086
  {"net_retry_count", OPT_NET_RETRY_COUNT,
4087
   "If a read on a communication port is interrupted, retry this many times before giving up.",
4088
   (uchar**) &global_system_variables.net_retry_count,
4089
   (uchar**) &max_system_variables.net_retry_count,0,
4090
   GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, ULONG_MAX, 0, 1, 0},
4091
  {"net_write_timeout", OPT_NET_WRITE_TIMEOUT,
4092
   "Number of seconds to wait for a block to be written to a connection  before aborting the write.",
4093
   (uchar**) &global_system_variables.net_write_timeout,
4094
   (uchar**) &max_system_variables.net_write_timeout, 0, GET_ULONG,
4095
   REQUIRED_ARG, NET_WRITE_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
4096
  { "old", OPT_OLD_MODE, "Use compatible behavior.", 
4097
    (uchar**) &global_system_variables.old_mode,
4098
    (uchar**) &max_system_variables.old_mode, 0, GET_BOOL, NO_ARG, 
4099
    0, 0, 0, 0, 0, 0},
4100
  {"open_files_limit", OPT_OPEN_FILES_LIMIT,
4101
   "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.",
4102
   (uchar**) &open_files_limit, (uchar**) &open_files_limit, 0, GET_ULONG,
4103
   REQUIRED_ARG, 0, 0, OS_FILE_LIMIT, 0, 1, 0},
4104
  {"optimizer_prune_level", OPT_OPTIMIZER_PRUNE_LEVEL,
4105
   "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.",
4106
   (uchar**) &global_system_variables.optimizer_prune_level,
4107
   (uchar**) &max_system_variables.optimizer_prune_level,
4108
   0, GET_ULONG, OPT_ARG, 1, 0, 1, 0, 1, 0},
4109
  {"optimizer_search_depth", OPT_OPTIMIZER_SEARCH_DEPTH,
4110
   "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).",
4111
   (uchar**) &global_system_variables.optimizer_search_depth,
4112
   (uchar**) &max_system_variables.optimizer_search_depth,
4113
   0, GET_ULONG, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0},
4114
  {"plugin_dir", OPT_PLUGIN_DIR,
4115
   "Directory for plugins.",
4116
   (uchar**) &opt_plugin_dir_ptr, (uchar**) &opt_plugin_dir_ptr, 0,
4117
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4118
  {"plugin_load", OPT_PLUGIN_LOAD,
4119
   "Optional colon separated list of plugins to load, where each plugin is "
4120
   "identified by name and path to library seperated by an equals.",
4121
   (uchar**) &opt_plugin_load, (uchar**) &opt_plugin_load, 0,
4122
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4123
  {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
4124
   "The size of the buffer that is allocated when preloading indexes",
4125
   (uchar**) &global_system_variables.preload_buff_size,
4126
   (uchar**) &max_system_variables.preload_buff_size, 0, GET_ULONG,
4127
   REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0},
4128
  {"query_alloc_block_size", OPT_QUERY_ALLOC_BLOCK_SIZE,
4129
   "Allocation block size for query parsing and execution",
4130
   (uchar**) &global_system_variables.query_alloc_block_size,
4131
   (uchar**) &max_system_variables.query_alloc_block_size, 0, GET_ULONG,
4132
   REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
4133
  {"query_prealloc_size", OPT_QUERY_PREALLOC_SIZE,
4134
   "Persistent buffer for query parsing and execution",
4135
   (uchar**) &global_system_variables.query_prealloc_size,
4136
   (uchar**) &max_system_variables.query_prealloc_size, 0, GET_ULONG,
4137
   REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, QUERY_ALLOC_PREALLOC_SIZE,
4138
   ULONG_MAX, 0, 1024, 0},
4139
  {"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE,
4140
   "Allocation block size for storing ranges during optimization",
4141
   (uchar**) &global_system_variables.range_alloc_block_size,
4142
   (uchar**) &max_system_variables.range_alloc_block_size, 0, GET_ULONG,
4143
   REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, ULONG_MAX,
4144
   0, 1024, 0},
4145
  {"read_buffer_size", OPT_RECORD_BUFFER,
4146
   "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.",
4147
   (uchar**) &global_system_variables.read_buff_size,
4148
   (uchar**) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
4149
   128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, INT_MAX32, MALLOC_OVERHEAD, IO_SIZE,
4150
   0},
4151
  {"read_only", OPT_READONLY,
4152
   "Make all non-temporary tables read-only, with the exception for replication (slave) threads and users with the SUPER privilege",
4153
   (uchar**) &opt_readonly,
4154
   (uchar**) &opt_readonly,
4155
   0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
4156
  {"read_rnd_buffer_size", OPT_RECORD_RND_BUFFER,
4157
   "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.",
4158
   (uchar**) &global_system_variables.read_rnd_buff_size,
4159
   (uchar**) &max_system_variables.read_rnd_buff_size, 0,
4160
   GET_ULONG, REQUIRED_ARG, 256*1024L, 64 /*IO_SIZE*2+MALLOC_OVERHEAD*/ ,
4161
   INT_MAX32, MALLOC_OVERHEAD, 1 /* Small lower limit to be able to test MRR */, 0},
4162
  {"record_buffer", OPT_RECORD_BUFFER,
4163
   "Alias for read_buffer_size",
4164
   (uchar**) &global_system_variables.read_buff_size,
4165
   (uchar**) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
4166
   128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, INT_MAX32, MALLOC_OVERHEAD, IO_SIZE, 0},
4167
  {"relay_log_purge", OPT_RELAY_LOG_PURGE,
4168
   "0 = do not purge relay logs. 1 = purge them as soon as they are no more needed.",
4169
   (uchar**) &relay_log_purge,
4170
   (uchar**) &relay_log_purge, 0, GET_BOOL, NO_ARG,
4171
   1, 0, 1, 0, 1, 0},
4172
  {"relay_log_space_limit", OPT_RELAY_LOG_SPACE_LIMIT,
4173
   "Maximum space to use for all relay logs.",
4174
   (uchar**) &relay_log_space_limit,
4175
   (uchar**) &relay_log_space_limit, 0, GET_ULL, REQUIRED_ARG, 0L, 0L,
4176
   (longlong) ULONG_MAX, 0, 1, 0},
4177
  {"slave_compressed_protocol", OPT_SLAVE_COMPRESSED_PROTOCOL,
4178
   "Use compression on master/slave protocol.",
4179
   (uchar**) &opt_slave_compressed_protocol,
4180
   (uchar**) &opt_slave_compressed_protocol,
4181
   0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
4182
  {"slave_net_timeout", OPT_SLAVE_NET_TIMEOUT,
4183
   "Number of seconds to wait for more data from a master/slave connection before aborting the read.",
4184
   (uchar**) &slave_net_timeout, (uchar**) &slave_net_timeout, 0,
4185
   GET_ULONG, REQUIRED_ARG, SLAVE_NET_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
4186
  {"slave_transaction_retries", OPT_SLAVE_TRANS_RETRIES,
4187
   "Number of times the slave SQL thread will retry a transaction in case "
4188
   "it failed with a deadlock or elapsed lock wait timeout, "
4189
   "before giving up and stopping.",
4190
   (uchar**) &slave_trans_retries, (uchar**) &slave_trans_retries, 0,
4191
   GET_ULONG, REQUIRED_ARG, 10L, 0L, (longlong) ULONG_MAX, 0, 1, 0},
4192
  {"slave-allow-batching", OPT_SLAVE_ALLOW_BATCHING,
4193
   "Allow slave to batch requests.",
4194
   (uchar**) &slave_allow_batching, (uchar**) &slave_allow_batching,
4195
   0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
4196
  {"slow_launch_time", OPT_SLOW_LAUNCH_TIME,
4197
   "If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented.",
4198
   (uchar**) &slow_launch_time, (uchar**) &slow_launch_time, 0, GET_ULONG,
4199
   REQUIRED_ARG, 2L, 0L, LONG_TIMEOUT, 0, 1, 0},
4200
  {"sort_buffer_size", OPT_SORT_BUFFER,
4201
   "Each thread that needs to do a sort allocates a buffer of this size.",
4202
   (uchar**) &global_system_variables.sortbuff_size,
4203
   (uchar**) &max_system_variables.sortbuff_size, 0, GET_ULONG, REQUIRED_ARG,
4204
   MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, ULONG_MAX,
4205
   MALLOC_OVERHEAD, 1, 0},
4206
  {"sync-binlog", OPT_SYNC_BINLOG,
4207
   "Synchronously flush binary log to disk after every #th event. "
4208
   "Use 0 (default) to disable synchronous flushing.",
4209
   (uchar**) &sync_binlog_period, (uchar**) &sync_binlog_period, 0, GET_ULONG,
4210
   REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1, 0},
4211
  {"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default.",
4212
   (uchar**) &opt_sync_frm, (uchar**) &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0,
4213
   0, 0, 0, 0},
4214
  {"table_cache", OPT_TABLE_OPEN_CACHE,
4215
   "Deprecated; use --table_open_cache instead.",
4216
   (uchar**) &table_cache_size, (uchar**) &table_cache_size, 0, GET_ULONG,
4217
   REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
4218
  {"table_definition_cache", OPT_TABLE_DEF_CACHE,
4219
   "The number of cached table definitions.",
4220
   (uchar**) &table_def_size, (uchar**) &table_def_size,
4221
   0, GET_ULONG, REQUIRED_ARG, 128, 1, 512*1024L, 0, 1, 0},
4222
  {"table_open_cache", OPT_TABLE_OPEN_CACHE,
4223
   "The number of cached open tables.",
4224
   (uchar**) &table_cache_size, (uchar**) &table_cache_size, 0, GET_ULONG,
4225
   REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
4226
  {"table_lock_wait_timeout", OPT_TABLE_LOCK_WAIT_TIMEOUT,
4227
   "Timeout in seconds to wait for a table level lock before returning an "
4228
   "error. Used only if the connection has active cursors.",
4229
   (uchar**) &table_lock_wait_timeout, (uchar**) &table_lock_wait_timeout,
4230
   0, GET_ULONG, REQUIRED_ARG, 50, 1, 1024 * 1024 * 1024, 0, 1, 0},
4231
  {"thread_cache_size", OPT_THREAD_CACHE_SIZE,
4232
   "How many threads we should keep in a cache for reuse.",
4233
   (uchar**) &thread_cache_size, (uchar**) &thread_cache_size, 0, GET_ULONG,
4234
   REQUIRED_ARG, 0, 0, 16384, 0, 1, 0},
4235
  {"thread_pool_size", OPT_THREAD_CACHE_SIZE,
4236
   "How many threads we should create to handle query requests in case of 'thread_handling=pool-of-threads'",
4237
   (uchar**) &thread_pool_size, (uchar**) &thread_pool_size, 0, GET_ULONG,
4238
   REQUIRED_ARG, 20, 1, 16384, 0, 1, 0},
4239
  {"thread_stack", OPT_THREAD_STACK,
4240
   "The stack size for each thread.", (uchar**) &my_thread_stack_size,
4241
   (uchar**) &my_thread_stack_size, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK,
4242
   1024L*128L, ULONG_MAX, 0, 1024, 0},
4243
  { "time_format", OPT_TIME_FORMAT,
4244
    "The TIME format (for future).",
4245
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_TIME],
4246
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_TIME],
4247
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4248
  {"tmp_table_size", OPT_TMP_TABLE_SIZE,
4249
   "If an internal in-memory temporary table exceeds this size, MySQL will"
4250
   " automatically convert it to an on-disk MyISAM table.",
4251
   (uchar**) &global_system_variables.tmp_table_size,
4252
   (uchar**) &max_system_variables.tmp_table_size, 0, GET_ULL,
4253
   REQUIRED_ARG, 16*1024*1024L, 1024, MAX_MEM_TABLE_SIZE, 0, 1, 0},
4254
  {"transaction_alloc_block_size", OPT_TRANS_ALLOC_BLOCK_SIZE,
4255
   "Allocation block size for transactions to be stored in binary log",
4256
   (uchar**) &global_system_variables.trans_alloc_block_size,
4257
   (uchar**) &max_system_variables.trans_alloc_block_size, 0, GET_ULONG,
4258
   REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
4259
  {"transaction_prealloc_size", OPT_TRANS_PREALLOC_SIZE,
4260
   "Persistent buffer for transactions to be stored in binary log",
4261
   (uchar**) &global_system_variables.trans_prealloc_size,
4262
   (uchar**) &max_system_variables.trans_prealloc_size, 0, GET_ULONG,
4263
   REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
4264
  {"wait_timeout", OPT_WAIT_TIMEOUT,
4265
   "The number of seconds the server waits for activity on a connection before closing it.",
4266
   (uchar**) &global_system_variables.net_wait_timeout,
4267
   (uchar**) &max_system_variables.net_wait_timeout, 0, GET_ULONG,
4268
   REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT),
4269
   0, 1, 0},
4270
  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
4271
};
4272
4273
static int show_net_compression(THD *thd, SHOW_VAR *var, char *buff)
4274
{
4275
  var->type= SHOW_MY_BOOL;
4276
  var->value= (char *)&thd->net.compress;
4277
  return 0;
4278
}
4279
4280
static int show_starttime(THD *thd, SHOW_VAR *var, char *buff)
4281
{
4282
  var->type= SHOW_LONG;
4283
  var->value= buff;
4284
  *((long *)buff)= (long) (thd->query_start() - server_start_time);
4285
  return 0;
4286
}
4287
4288
static int show_flushstatustime(THD *thd, SHOW_VAR *var, char *buff)
4289
{
4290
  var->type= SHOW_LONG;
4291
  var->value= buff;
4292
  *((long *)buff)= (long) (thd->query_start() - flush_status_time);
4293
  return 0;
4294
}
4295
4296
static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff)
4297
{
4298
  var->type= SHOW_MY_BOOL;
4299
  pthread_mutex_lock(&LOCK_active_mi);
4300
  var->value= buff;
4301
  *((my_bool *)buff)= (my_bool) (active_mi && active_mi->slave_running &&
4302
                                 active_mi->rli.slave_running);
4303
  pthread_mutex_unlock(&LOCK_active_mi);
4304
  return 0;
4305
}
4306
4307
static int show_slave_retried_trans(THD *thd, SHOW_VAR *var, char *buff)
4308
{
4309
  /*
4310
    TODO: with multimaster, have one such counter per line in
4311
    SHOW SLAVE STATUS, and have the sum over all lines here.
4312
  */
4313
  pthread_mutex_lock(&LOCK_active_mi);
4314
  if (active_mi)
4315
  {
4316
    var->type= SHOW_LONG;
4317
    var->value= buff;
4318
    pthread_mutex_lock(&active_mi->rli.data_lock);
4319
    *((long *)buff)= (long)active_mi->rli.retried_trans;
4320
    pthread_mutex_unlock(&active_mi->rli.data_lock);
4321
  }
4322
  else
4323
    var->type= SHOW_UNDEF;
4324
  pthread_mutex_unlock(&LOCK_active_mi);
4325
  return 0;
4326
}
4327
4328
static int show_slave_received_heartbeats(THD *thd, SHOW_VAR *var, char *buff)
4329
{
4330
  pthread_mutex_lock(&LOCK_active_mi);
4331
  if (active_mi)
4332
  {
4333
    var->type= SHOW_LONGLONG;
4334
    var->value= buff;
4335
    pthread_mutex_lock(&active_mi->rli.data_lock);
4336
    *((longlong *)buff)= active_mi->received_heartbeats;
4337
    pthread_mutex_unlock(&active_mi->rli.data_lock);
4338
  }
4339
  else
4340
    var->type= SHOW_UNDEF;
4341
  pthread_mutex_unlock(&LOCK_active_mi);
4342
  return 0;
4343
}
4344
4345
static int show_heartbeat_period(THD *thd, SHOW_VAR *var, char *buff)
4346
{
4347
  pthread_mutex_lock(&LOCK_active_mi);
4348
  if (active_mi)
4349
  {
4350
    var->type= SHOW_CHAR;
4351
    var->value= buff;
4352
    my_sprintf(buff, (buff, "%.3f",active_mi->heartbeat_period));
4353
  }
4354
  else
4355
    var->type= SHOW_UNDEF;
4356
  pthread_mutex_unlock(&LOCK_active_mi);
4357
  return 0;
4358
}
4359
4360
4361
static int show_open_tables(THD *thd, SHOW_VAR *var, char *buff)
4362
{
4363
  var->type= SHOW_LONG;
4364
  var->value= buff;
4365
  *((long *)buff)= (long)cached_open_tables();
4366
  return 0;
4367
}
4368
4369
static int show_table_definitions(THD *thd, SHOW_VAR *var, char *buff)
4370
{
4371
  var->type= SHOW_LONG;
4372
  var->value= buff;
4373
  *((long *)buff)= (long)cached_table_definitions();
4374
  return 0;
4375
}
4376
4377
/*
4378
  Variables shown by SHOW STATUS in alphabetical order
4379
*/
4380
4381
SHOW_VAR status_vars[]= {
4382
  {"Aborted_clients",          (char*) &aborted_threads,        SHOW_LONG},
4383
  {"Aborted_connects",         (char*) &aborted_connects,       SHOW_LONG},
4384
  {"Binlog_cache_disk_use",    (char*) &binlog_cache_disk_use,  SHOW_LONG},
4385
  {"Binlog_cache_use",         (char*) &binlog_cache_use,       SHOW_LONG},
4386
  {"Bytes_received",           (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONGLONG_STATUS},
4387
  {"Bytes_sent",               (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS},
4388
  {"Com",                      (char*) com_status_vars, SHOW_ARRAY},
4389
  {"Compression",              (char*) &show_net_compression, SHOW_FUNC},
4390
  {"Connections",              (char*) &thread_id,              SHOW_LONG_NOFLUSH},
4391
  {"Created_tmp_disk_tables",  (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS},
4392
  {"Created_tmp_files",	       (char*) &my_tmp_file_created,	SHOW_LONG},
4393
  {"Created_tmp_tables",       (char*) offsetof(STATUS_VAR, created_tmp_tables), SHOW_LONG_STATUS},
4394
  {"Flush_commands",           (char*) &refresh_version,        SHOW_LONG_NOFLUSH},
4395
  {"Handler_commit",           (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
4396
  {"Handler_delete",           (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS},
4397
  {"Handler_discover",         (char*) offsetof(STATUS_VAR, ha_discover_count), SHOW_LONG_STATUS},
4398
  {"Handler_prepare",          (char*) offsetof(STATUS_VAR, ha_prepare_count),  SHOW_LONG_STATUS},
4399
  {"Handler_read_first",       (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS},
4400
  {"Handler_read_key",         (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS},
4401
  {"Handler_read_next",        (char*) offsetof(STATUS_VAR, ha_read_next_count), SHOW_LONG_STATUS},
4402
  {"Handler_read_prev",        (char*) offsetof(STATUS_VAR, ha_read_prev_count), SHOW_LONG_STATUS},
4403
  {"Handler_read_rnd",         (char*) offsetof(STATUS_VAR, ha_read_rnd_count), SHOW_LONG_STATUS},
4404
  {"Handler_read_rnd_next",    (char*) offsetof(STATUS_VAR, ha_read_rnd_next_count), SHOW_LONG_STATUS},
4405
  {"Handler_rollback",         (char*) offsetof(STATUS_VAR, ha_rollback_count), SHOW_LONG_STATUS},
4406
  {"Handler_savepoint",        (char*) offsetof(STATUS_VAR, ha_savepoint_count), SHOW_LONG_STATUS},
4407
  {"Handler_savepoint_rollback",(char*) offsetof(STATUS_VAR, ha_savepoint_rollback_count), SHOW_LONG_STATUS},
4408
  {"Handler_update",           (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS},
4409
  {"Handler_write",            (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS},
4410
  {"Key_blocks_not_flushed",   (char*) offsetof(KEY_CACHE, global_blocks_changed), SHOW_KEY_CACHE_LONG},
4411
  {"Key_blocks_unused",        (char*) offsetof(KEY_CACHE, blocks_unused), SHOW_KEY_CACHE_LONG},
4412
  {"Key_blocks_used",          (char*) offsetof(KEY_CACHE, blocks_used), SHOW_KEY_CACHE_LONG},
4413
  {"Key_read_requests",        (char*) offsetof(KEY_CACHE, global_cache_r_requests), SHOW_KEY_CACHE_LONGLONG},
4414
  {"Key_reads",                (char*) offsetof(KEY_CACHE, global_cache_read), SHOW_KEY_CACHE_LONGLONG},
4415
  {"Key_write_requests",       (char*) offsetof(KEY_CACHE, global_cache_w_requests), SHOW_KEY_CACHE_LONGLONG},
4416
  {"Key_writes",               (char*) offsetof(KEY_CACHE, global_cache_write), SHOW_KEY_CACHE_LONGLONG},
4417
  {"Last_query_cost",          (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS},
4418
  {"Max_used_connections",     (char*) &max_used_connections,  SHOW_LONG},
4419
  {"Open_files",               (char*) &my_file_opened,         SHOW_LONG_NOFLUSH},
4420
  {"Open_streams",             (char*) &my_stream_opened,       SHOW_LONG_NOFLUSH},
4421
  {"Open_table_definitions",   (char*) &show_table_definitions, SHOW_FUNC},
4422
  {"Open_tables",              (char*) &show_open_tables,       SHOW_FUNC},
4423
  {"Opened_files",             (char*) &my_file_total_opened, SHOW_LONG_NOFLUSH},
4424
  {"Opened_tables",            (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS},
4425
  {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS},
4426
  {"Questions",                (char*) offsetof(STATUS_VAR, questions), SHOW_LONG_STATUS},
4427
  {"Select_full_join",         (char*) offsetof(STATUS_VAR, select_full_join_count), SHOW_LONG_STATUS},
4428
  {"Select_full_range_join",   (char*) offsetof(STATUS_VAR, select_full_range_join_count), SHOW_LONG_STATUS},
4429
  {"Select_range",             (char*) offsetof(STATUS_VAR, select_range_count), SHOW_LONG_STATUS},
4430
  {"Select_range_check",       (char*) offsetof(STATUS_VAR, select_range_check_count), SHOW_LONG_STATUS},
4431
  {"Select_scan",	       (char*) offsetof(STATUS_VAR, select_scan_count), SHOW_LONG_STATUS},
4432
  {"Slave_open_temp_tables",   (char*) &slave_open_temp_tables, SHOW_LONG},
4433
  {"Slave_retried_transactions",(char*) &show_slave_retried_trans, SHOW_FUNC},
4434
  {"Slave_heartbeat_period",   (char*) &show_heartbeat_period, SHOW_FUNC},
4435
  {"Slave_received_heartbeats",(char*) &show_slave_received_heartbeats, SHOW_FUNC},
4436
  {"Slave_running",            (char*) &show_slave_running,     SHOW_FUNC},
4437
  {"Slow_launch_threads",      (char*) &slow_launch_threads,    SHOW_LONG},
4438
  {"Slow_queries",             (char*) offsetof(STATUS_VAR, long_query_count), SHOW_LONG_STATUS},
4439
  {"Sort_merge_passes",	       (char*) offsetof(STATUS_VAR, filesort_merge_passes), SHOW_LONG_STATUS},
4440
  {"Sort_range",	       (char*) offsetof(STATUS_VAR, filesort_range_count), SHOW_LONG_STATUS},
4441
  {"Sort_rows",		       (char*) offsetof(STATUS_VAR, filesort_rows), SHOW_LONG_STATUS},
4442
  {"Sort_scan",		       (char*) offsetof(STATUS_VAR, filesort_scan_count), SHOW_LONG_STATUS},
4443
  {"Table_locks_immediate",    (char*) &locks_immediate,        SHOW_LONG},
4444
  {"Table_locks_waited",       (char*) &locks_waited,           SHOW_LONG},
4445
#ifdef HAVE_MMAP
4446
  {"Tc_log_max_pages_used",    (char*) &tc_log_max_pages_used,  SHOW_LONG},
4447
  {"Tc_log_page_size",         (char*) &tc_log_page_size,       SHOW_LONG},
4448
  {"Tc_log_page_waits",        (char*) &tc_log_page_waits,      SHOW_LONG},
4449
#endif
4450
  {"Threads_cached",           (char*) &cached_thread_count,    SHOW_LONG_NOFLUSH},
4451
  {"Threads_connected",        (char*) &connection_count,       SHOW_INT},
4452
  {"Threads_created",	       (char*) &thread_created,		SHOW_LONG_NOFLUSH},
4453
  {"Threads_running",          (char*) &thread_running,         SHOW_INT},
4454
  {"Uptime",                   (char*) &show_starttime,         SHOW_FUNC},
4455
  {"Uptime_since_flush_status",(char*) &show_flushstatustime,   SHOW_FUNC},
4456
  {NullS, NullS, SHOW_LONG}
4457
};
4458
4459
static void print_version(void)
4460
{
4461
  set_server_version();
4462
  /*
4463
    Note: the instance manager keys off the string 'Ver' so it can find the
4464
    version from the output of 'mysqld --version', so don't change it!
4465
  */
4466
  printf("%s  Ver %s for %s on %s (%s)\n",my_progname,
4467
	 server_version,SYSTEM_TYPE,MACHINE_TYPE, MYSQL_COMPILATION_COMMENT);
4468
}
4469
4470
static void usage(void)
4471
{
4472
  if (!(default_charset_info= get_charset_by_csname(default_character_set_name,
4473
					           MY_CS_PRIMARY,
4474
						   MYF(MY_WME))))
4475
    exit(1);
4476
  if (!default_collation_name)
4477
    default_collation_name= (char*) default_charset_info->name;
4478
  print_version();
4479
  puts("\
4480
Copyright (C) 2000 MySQL AB, by Monty and others\n\
4481
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
4482
and you are welcome to modify and redistribute it under the GPL license\n\n\
4483
Starts the MySQL database server\n");
4484
4485
  printf("Usage: %s [OPTIONS]\n", my_progname);
4486
  if (!opt_verbose)
4487
    puts("\nFor more help options (several pages), use mysqld --verbose --help");
4488
  else
4489
  {
4490
  print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
4491
  puts("");
4492
  set_ports();
4493
4494
  /* Print out all the options including plugin supplied options */
4495
  my_print_help_inc_plugins(my_long_options, sizeof(my_long_options)/sizeof(my_option));
4496
4497
  puts("\n\
4498
To see what values a running MySQL server is using, type\n\
4499
'mysqladmin variables' instead of 'mysqld --verbose --help'.");
4500
  }
4501
}
4502
4503
4504
/**
4505
  Initialize all MySQL global variables to default values.
4506
4507
  We don't need to set numeric variables refered to in my_long_options
4508
  as these are initialized by my_getopt.
4509
4510
  @note
4511
    The reason to set a lot of global variables to zero is to allow one to
4512
    restart the embedded server with a clean environment
4513
    It's also needed on some exotic platforms where global variables are
4514
    not set to 0 when a program starts.
4515
4516
    We don't need to set numeric variables refered to in my_long_options
4517
    as these are initialized by my_getopt.
4518
*/
4519
4520
static void mysql_init_variables(void)
4521
{
4522
  /* Things reset to zero */
4523
  opt_skip_slave_start= opt_reckless_slave = 0;
4524
  mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0;
4525
  opt_log= opt_slow_log= 0;
4526
  opt_update_log= 0;
4527
  log_output_options= find_bit_type(log_output_str, &log_output_typelib);
4528
  opt_bin_log= 0;
4529
  opt_disable_networking= opt_skip_show_db=0;
4530
  opt_logname= opt_update_logname= opt_binlog_index_name= opt_slow_logname= 0;
4531
  opt_tc_log_file= (char *)"tc.log";      // no hostname in tc_log file name !
4532
  opt_secure_auth= 0;
4533
  opt_secure_file_priv= 0;
4534
  opt_bootstrap= opt_myisam_log= 0;
4535
  mqh_used= 0;
4536
  segfaulted= kill_in_progress= 0;
4537
  cleanup_done= 0;
4538
  defaults_argc= 0;
4539
  defaults_argv= 0;
4540
  server_id_supplied= 0;
4541
  test_flags= select_errors= dropping_tables= ha_open_options=0;
4542
  thread_count= thread_running= kill_cached_threads= wake_thread=0;
4543
  slave_open_temp_tables= 0;
4544
  cached_thread_count= 0;
4545
  opt_endinfo= using_udf_functions= 0;
4546
  opt_using_transactions= using_update_log= 0;
4547
  abort_loop= select_thread_in_use= signal_thread_in_use= 0;
4548
  ready_to_exit= shutdown_in_progress= 0;
4549
  aborted_threads= aborted_connects= 0;
4550
  specialflag= 0;
4551
  binlog_cache_use=  binlog_cache_disk_use= 0;
4552
  max_used_connections= slow_launch_threads = 0;
4553
  mysqld_user= mysqld_chroot= opt_init_file= opt_bin_logname = 0;
4554
  errmesg= 0;
11 by Brian Aker
Removing old UNIX socket bits
4555
  opt_mysql_tmpdir= my_bind_addr_str= NullS;
1 by brian
clean slate
4556
  bzero((uchar*) &mysql_tmpdir_list, sizeof(mysql_tmpdir_list));
4557
  bzero((char *) &global_status_var, sizeof(global_status_var));
4558
  key_map_full.set_all();
4559
4560
  /* Character sets */
4561
  system_charset_info= &my_charset_utf8_general_ci;
4562
  files_charset_info= &my_charset_utf8_general_ci;
4563
  national_charset_info= &my_charset_utf8_general_ci;
4564
  table_alias_charset= &my_charset_bin;
4565
  character_set_filesystem= &my_charset_bin;
4566
4567
  opt_date_time_formats[0]= opt_date_time_formats[1]= opt_date_time_formats[2]= 0;
4568
4569
  /* Things with default values that are not zero */
4570
  delay_key_write_options= (uint) DELAY_KEY_WRITE_ON;
4571
  slave_exec_mode_options= 0;
4572
  slave_exec_mode_options= (uint)
4573
    find_bit_type_or_exit(slave_exec_mode_str, &slave_exec_mode_typelib, NULL);
4574
  opt_specialflag= SPECIAL_ENGLISH;
11 by Brian Aker
Removing old UNIX socket bits
4575
  ip_sock= INVALID_SOCKET;
1 by brian
clean slate
4576
  mysql_home_ptr= mysql_home;
4577
  pidfile_name_ptr= pidfile_name;
4578
  log_error_file_ptr= log_error_file;
4579
  language_ptr= language;
4580
  mysql_data_home= mysql_real_data_home;
4581
  thd_startup_options= (OPTION_AUTO_IS_NULL | OPTION_BIN_LOG |
4582
                        OPTION_QUOTE_SHOW_CREATE | OPTION_SQL_NOTES);
4583
  protocol_version= PROTOCOL_VERSION;
4584
  what_to_log= ~ (1L << (uint) COM_TIME);
4585
  refresh_version= 1L;	/* Increments on each reload */
4586
  global_query_id= thread_id= 1L;
4587
  strmov(server_version, MYSQL_SERVER_VERSION);
4588
  myisam_recover_options_str= "OFF";
4589
  myisam_stats_method_str= "nulls_unequal";
4590
  threads.empty();
4591
  thread_cache.empty();
4592
  key_caches.empty();
4593
  if (!(dflt_key_cache= get_or_create_key_cache(default_key_cache_base.str,
4594
                                                default_key_cache_base.length)))
4595
    exit(1);
4596
  /* set key_cache_hash.default_value = dflt_key_cache */
4597
  multi_keycache_init();
4598
4599
  /* Set directory paths */
4600
  strmake(language, LANGUAGE, sizeof(language)-1);
4601
  strmake(mysql_real_data_home, get_relative_path(DATADIR),
4602
	  sizeof(mysql_real_data_home)-1);
4603
  mysql_data_home_buff[0]=FN_CURLIB;	// all paths are relative from here
4604
  mysql_data_home_buff[1]=0;
4605
  mysql_data_home_len= 2;
4606
4607
  /* Replication parameters */
4608
  master_info_file= (char*) "master.info",
4609
    relay_log_info_file= (char*) "relay-log.info";
4610
  report_user= report_password = report_host= 0;	/* TO BE DELETED */
4611
  opt_relay_logname= opt_relaylog_index_name= 0;
4612
4613
  /* Variables in libraries */
4614
  charsets_dir= 0;
4615
  default_character_set_name= (char*) MYSQL_DEFAULT_CHARSET_NAME;
4616
  default_collation_name= compiled_default_collation_name;
10 by Brian Aker
Start of var cleanup (really.... looking at this code the entire thing needs
4617
  sys_charset_system.set((char*) system_charset_info->csname);
1 by brian
clean slate
4618
  character_set_filesystem_name= (char*) "binary";
4619
  lc_time_names_name= (char*) "en_US";
4620
  /* Set default values for some option variables */
4621
  default_storage_engine_str= (char*) "MyISAM";
4622
  global_system_variables.table_plugin= NULL;
4623
  global_system_variables.tx_isolation= ISO_REPEATABLE_READ;
4624
  global_system_variables.select_limit= (ulonglong) HA_POS_ERROR;
4625
  max_system_variables.select_limit=    (ulonglong) HA_POS_ERROR;
4626
  global_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
4627
  max_system_variables.max_join_size=   (ulonglong) HA_POS_ERROR;
4628
  global_system_variables.old_passwords= 0;
4629
  global_system_variables.old_alter_table= 0;
4630
  global_system_variables.binlog_format= BINLOG_FORMAT_UNSPEC;
4631
  /*
4632
    Default behavior for 4.1 and 5.0 is to treat NULL values as unequal
4633
    when collecting index statistics for MyISAM tables.
4634
  */
4635
  global_system_variables.myisam_stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
4636
4637
  /* Variables that depends on compile options */
4638
#ifndef DBUG_OFF
4639
  default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace",
4640
			     "d:t:i:o,/tmp/mysqld.trace");
4641
#endif
4642
  opt_error_log= IF_WIN(1,0);
4643
#ifdef HAVE_BROKEN_REALPATH
4644
  have_symlink=SHOW_OPTION_NO;
4645
#else
4646
  have_symlink=SHOW_OPTION_YES;
4647
#endif
4648
#ifdef HAVE_DLOPEN
4649
  have_dlopen=SHOW_OPTION_YES;
4650
#else
4651
  have_dlopen=SHOW_OPTION_NO;
4652
#endif
4653
#ifdef HAVE_CRYPT
4654
  have_crypt=SHOW_OPTION_YES;
4655
#else
4656
  have_crypt=SHOW_OPTION_NO;
4657
#endif
4658
#ifdef HAVE_COMPRESS
4659
  have_compress= SHOW_OPTION_YES;
4660
#else
4661
  have_compress= SHOW_OPTION_NO;
4662
#endif
4663
4664
  const char *tmpenv;
4665
  if (!(tmpenv = getenv("MY_BASEDIR_VERSION")))
4666
    tmpenv = DEFAULT_MYSQL_HOME;
4667
  (void) strmake(mysql_home, tmpenv, sizeof(mysql_home)-1);
4668
}
4669
4670
4671
my_bool
4672
mysqld_get_one_option(int optid,
4673
                      const struct my_option *opt __attribute__((unused)),
4674
                      char *argument)
4675
{
4676
  switch(optid) {
4677
  case '#':
4678
#ifndef DBUG_OFF
4679
    DBUG_SET_INITIAL(argument ? argument : default_dbug_option);
4680
#endif
4681
    opt_endinfo=1;				/* unireg: memory allocation */
4682
    break;
4683
  case 'a':
4684
    global_system_variables.tx_isolation= ISO_SERIALIZABLE;
4685
    break;
4686
  case 'b':
4687
    strmake(mysql_home,argument,sizeof(mysql_home)-1);
4688
    break;
4689
  case 'C':
4690
    if (default_collation_name == compiled_default_collation_name)
4691
      default_collation_name= 0;
4692
    break;
4693
  case 'l':
4694
    opt_log=1;
4695
    break;
4696
  case 'h':
4697
    strmake(mysql_real_data_home,argument, sizeof(mysql_real_data_home)-1);
4698
    /* Correct pointer set by my_getopt (for embedded library) */
4699
    mysql_data_home= mysql_real_data_home;
4700
    mysql_data_home_len= strlen(mysql_data_home);
4701
    break;
4702
  case 'u':
4703
    if (!mysqld_user || !strcmp(mysqld_user, argument))
4704
      mysqld_user= argument;
4705
    else
4706
      sql_print_warning("Ignoring user change to '%s' because the user was set to '%s' earlier on the command line\n", argument, mysqld_user);
4707
    break;
4708
  case 'L':
4709
    strmake(language, argument, sizeof(language)-1);
4710
    break;
4711
  case OPT_SLAVE_SKIP_ERRORS:
4712
    init_slave_skip_errors(argument);
4713
    break;
4714
  case OPT_SLAVE_EXEC_MODE:
4715
    slave_exec_mode_options= (uint)
4716
      find_bit_type_or_exit(argument, &slave_exec_mode_typelib, "");
4717
    break;
4718
  case 'V':
4719
    print_version();
4720
    exit(0);
4721
  case 'W':
4722
    if (!argument)
4723
      global_system_variables.log_warnings++;
4724
    else if (argument == disabled_my_option)
4725
      global_system_variables.log_warnings= 0L;
4726
    else
4727
      global_system_variables.log_warnings= atoi(argument);
4728
    break;
4729
  case 'T':
4730
    test_flags= argument ? (uint) atoi(argument) : 0;
4731
    opt_endinfo=1;
4732
    break;
4733
  case (int) OPT_BIG_TABLES:
4734
    thd_startup_options|=OPTION_BIG_TABLES;
4735
    break;
4736
  case (int) OPT_ISAM_LOG:
4737
    opt_myisam_log=1;
4738
    break;
4739
  case (int) OPT_UPDATE_LOG:
4740
    opt_update_log=1;
4741
    break;
4742
  case (int) OPT_BIN_LOG:
4743
    opt_bin_log= test(argument != disabled_my_option);
4744
    break;
4745
  case (int) OPT_ERROR_LOG_FILE:
4746
    opt_error_log= 1;
4747
    break;
4748
  case (int)OPT_REPLICATE_IGNORE_DB:
4749
  {
4750
    rpl_filter->add_ignore_db(argument);
4751
    break;
4752
  }
4753
  case (int)OPT_REPLICATE_DO_DB:
4754
  {
4755
    rpl_filter->add_do_db(argument);
4756
    break;
4757
  }
4758
  case (int)OPT_REPLICATE_REWRITE_DB:
4759
  {
4760
    char* key = argument,*p, *val;
4761
4762
    if (!(p= strstr(argument, "->")))
4763
    {
4764
      fprintf(stderr,
4765
	      "Bad syntax in replicate-rewrite-db - missing '->'!\n");
4766
      exit(1);
4767
    }
4768
    val= p--;
4769
    while (my_isspace(mysqld_charset, *p) && p > argument)
4770
      *p-- = 0;
4771
    if (p == argument)
4772
    {
4773
      fprintf(stderr,
4774
	      "Bad syntax in replicate-rewrite-db - empty FROM db!\n");
4775
      exit(1);
4776
    }
4777
    *val= 0;
4778
    val+= 2;
4779
    while (*val && my_isspace(mysqld_charset, *val))
4780
      *val++;
4781
    if (!*val)
4782
    {
4783
      fprintf(stderr,
4784
	      "Bad syntax in replicate-rewrite-db - empty TO db!\n");
4785
      exit(1);
4786
    }
4787
4788
    rpl_filter->add_db_rewrite(key, val);
4789
    break;
4790
  }
4791
4792
  case (int)OPT_BINLOG_IGNORE_DB:
4793
  {
4794
    binlog_filter->add_ignore_db(argument);
4795
    break;
4796
  }
4797
  case OPT_BINLOG_FORMAT:
4798
  {
4799
    int id;
4800
    id= find_type_or_exit(argument, &binlog_format_typelib, opt->name);
4801
    global_system_variables.binlog_format= opt_binlog_format_id= id - 1;
4802
    break;
4803
  }
4804
  case (int)OPT_BINLOG_DO_DB:
4805
  {
4806
    binlog_filter->add_do_db(argument);
4807
    break;
4808
  }
4809
  case (int)OPT_REPLICATE_DO_TABLE:
4810
  {
4811
    if (rpl_filter->add_do_table(argument))
4812
    {
4813
      fprintf(stderr, "Could not add do table rule '%s'!\n", argument);
4814
      exit(1);
4815
    }
4816
    break;
4817
  }
4818
  case (int)OPT_REPLICATE_WILD_DO_TABLE:
4819
  {
4820
    if (rpl_filter->add_wild_do_table(argument))
4821
    {
4822
      fprintf(stderr, "Could not add do table rule '%s'!\n", argument);
4823
      exit(1);
4824
    }
4825
    break;
4826
  }
4827
  case (int)OPT_REPLICATE_WILD_IGNORE_TABLE:
4828
  {
4829
    if (rpl_filter->add_wild_ignore_table(argument))
4830
    {
4831
      fprintf(stderr, "Could not add ignore table rule '%s'!\n", argument);
4832
      exit(1);
4833
    }
4834
    break;
4835
  }
4836
  case (int)OPT_REPLICATE_IGNORE_TABLE:
4837
  {
4838
    if (rpl_filter->add_ignore_table(argument))
4839
    {
4840
      fprintf(stderr, "Could not add ignore table rule '%s'!\n", argument);
4841
      exit(1);
4842
    }
4843
    break;
4844
  }
4845
  case (int) OPT_SLOW_QUERY_LOG:
4846
    opt_slow_log= 1;
4847
    break;
4848
#ifdef WITH_CSV_STORAGE_ENGINE
4849
  case  OPT_LOG_OUTPUT:
4850
  {
4851
    if (!argument || !argument[0])
4852
    {
4853
      log_output_options= LOG_FILE;
4854
      log_output_str= log_output_typelib.type_names[1];
4855
    }
4856
    else
4857
    {
4858
      log_output_str= argument;
4859
      log_output_options=
4860
        find_bit_type_or_exit(argument, &log_output_typelib, opt->name);
4861
  }
4862
    break;
4863
  }
4864
#endif
4865
  case (int) OPT_SKIP_NEW:
4866
    opt_specialflag|= SPECIAL_NO_NEW_FUNC;
4867
    delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
4868
    myisam_concurrent_insert=0;
4869
    myisam_recover_options= HA_RECOVER_NONE;
4870
    my_use_symdir=0;
4871
    ha_open_options&= ~(HA_OPEN_ABORT_IF_CRASHED | HA_OPEN_DELAY_KEY_WRITE);
4872
    break;
4873
  case (int) OPT_SAFE:
4874
    opt_specialflag|= SPECIAL_SAFE_MODE;
4875
    delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
4876
    myisam_recover_options= HA_RECOVER_DEFAULT;
4877
    ha_open_options&= ~(HA_OPEN_DELAY_KEY_WRITE);
4878
    break;
4879
  case (int) OPT_SKIP_PRIOR:
4880
    opt_specialflag|= SPECIAL_NO_PRIOR;
4881
    break;
4882
  case (int) OPT_SKIP_LOCK:
4883
    opt_external_locking=0;
4884
    break;
4885
  case (int) OPT_SKIP_SHOW_DB:
4886
    opt_skip_show_db=1;
4887
    opt_specialflag|=SPECIAL_SKIP_SHOW_DB;
4888
    break;
4889
  case (int) OPT_WANT_CORE:
4890
    test_flags |= TEST_CORE_ON_SIGNAL;
4891
    break;
4892
  case (int) OPT_SKIP_STACK_TRACE:
4893
    test_flags|=TEST_NO_STACKTRACE;
4894
    break;
4895
  case (int) OPT_SKIP_SYMLINKS:
4896
    my_use_symdir=0;
4897
    break;
4898
  case (int) OPT_BIND_ADDRESS:
4899
    {
4900
      struct addrinfo *res_lst, hints;    
4901
4902
      bzero(&hints, sizeof(struct addrinfo));
4903
      hints.ai_socktype= SOCK_STREAM;
4904
      hints.ai_protocol= IPPROTO_TCP;
4905
4906
      if (getaddrinfo(argument, NULL, &hints, &res_lst) != 0) 
4907
      {
4908
        sql_print_error("Can't start server: cannot resolve hostname!");
4909
        exit(1);
4910
      }
4911
4912
      if (res_lst->ai_next)
4913
      {
4914
        sql_print_error("Can't start server: bind-address refers to multiple interfaces!");
4915
        exit(1);
4916
      }
4917
      freeaddrinfo(res_lst);
4918
    }
4919
    break;
4920
  case (int) OPT_PID_FILE:
4921
    strmake(pidfile_name, argument, sizeof(pidfile_name)-1);
4922
    break;
4923
  case OPT_CONSOLE:
4924
    if (opt_console)
4925
      opt_error_log= 0;			// Force logs to stdout
4926
    break;
4927
  case (int) OPT_FLUSH:
4928
    myisam_flush=1;
4929
    flush_time=0;			// No auto flush
4930
    break;
4931
  case OPT_LOW_PRIORITY_UPDATES:
4932
    thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY;
4933
    global_system_variables.low_priority_updates=1;
4934
    break;
4935
  case OPT_BOOTSTRAP:
4936
    opt_noacl=opt_bootstrap=1;
4937
    break;
4938
  case OPT_SERVER_ID:
4939
    server_id_supplied = 1;
4940
    break;
4941
  case OPT_DELAY_KEY_WRITE_ALL:
4942
    if (argument != disabled_my_option)
4943
      argument= (char*) "ALL";
4944
    /* Fall through */
4945
  case OPT_DELAY_KEY_WRITE:
4946
    if (argument == disabled_my_option)
4947
      delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
4948
    else if (! argument)
4949
      delay_key_write_options= (uint) DELAY_KEY_WRITE_ON;
4950
    else
4951
    {
4952
      int type;
4953
      type= find_type_or_exit(argument, &delay_key_write_typelib, opt->name);
4954
      delay_key_write_options= (uint) type-1;
4955
    }
4956
    break;
4957
  case OPT_CHARSETS_DIR:
4958
    strmake(mysql_charsets_dir, argument, sizeof(mysql_charsets_dir)-1);
4959
    charsets_dir = mysql_charsets_dir;
4960
    break;
4961
  case OPT_TX_ISOLATION:
4962
  {
4963
    int type;
4964
    type= find_type_or_exit(argument, &tx_isolation_typelib, opt->name);
4965
    global_system_variables.tx_isolation= (type-1);
4966
    break;
4967
  }
4968
  case OPT_MYISAM_RECOVER:
4969
  {
4970
    if (!argument)
4971
    {
4972
      myisam_recover_options=    HA_RECOVER_DEFAULT;
4973
      myisam_recover_options_str= myisam_recover_typelib.type_names[0];
4974
    }
4975
    else if (!argument[0])
4976
    {
4977
      myisam_recover_options= HA_RECOVER_NONE;
4978
      myisam_recover_options_str= "OFF";
4979
    }
4980
    else
4981
    {
4982
      myisam_recover_options_str=argument;
4983
      myisam_recover_options=
4984
        find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name);
4985
    }
4986
    ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
4987
    break;
4988
  }
4989
  case OPT_TC_HEURISTIC_RECOVER:
4990
    tc_heuristic_recover= find_type_or_exit(argument,
4991
                                            &tc_heuristic_recover_typelib,
4992
                                            opt->name);
4993
    break;
4994
  case OPT_MYISAM_STATS_METHOD:
4995
  {
4996
    ulong method_conv;
4997
    int method;
4998
4999
    myisam_stats_method_str= argument;
5000
    method= find_type_or_exit(argument, &myisam_stats_method_typelib,
5001
                              opt->name);
5002
    switch (method-1) {
5003
    case 2:
5004
      method_conv= MI_STATS_METHOD_IGNORE_NULLS;
5005
      break;
5006
    case 1:
5007
      method_conv= MI_STATS_METHOD_NULLS_EQUAL;
5008
      break;
5009
    case 0:
5010
    default:
5011
      method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
5012
      break;
5013
    }
5014
    global_system_variables.myisam_stats_method= method_conv;
5015
    break;
5016
  }
5017
  case OPT_LOWER_CASE_TABLE_NAMES:
5018
    lower_case_table_names= argument ? atoi(argument) : 1;
5019
    lower_case_table_names_used= 1;
5020
    break;
5021
  }
5022
  return 0;
5023
}
5024
5025
5026
/** Handle arguments for multiple key caches. */
5027
5028
extern "C" uchar **mysql_getopt_value(const char *keyname, uint key_length,
5029
                                      const struct my_option *option);
5030
5031
uchar* *
5032
mysql_getopt_value(const char *keyname, uint key_length,
5033
		   const struct my_option *option)
5034
{
5035
  switch (option->id) {
5036
  case OPT_KEY_BUFFER_SIZE:
5037
  case OPT_KEY_CACHE_BLOCK_SIZE:
5038
  case OPT_KEY_CACHE_DIVISION_LIMIT:
5039
  case OPT_KEY_CACHE_AGE_THRESHOLD:
5040
  {
5041
    KEY_CACHE *key_cache;
5042
    if (!(key_cache= get_or_create_key_cache(keyname, key_length)))
5043
      exit(1);
5044
    switch (option->id) {
5045
    case OPT_KEY_BUFFER_SIZE:
5046
      return (uchar**) &key_cache->param_buff_size;
5047
    case OPT_KEY_CACHE_BLOCK_SIZE:
5048
      return (uchar**) &key_cache->param_block_size;
5049
    case OPT_KEY_CACHE_DIVISION_LIMIT:
5050
      return (uchar**) &key_cache->param_division_limit;
5051
    case OPT_KEY_CACHE_AGE_THRESHOLD:
5052
      return (uchar**) &key_cache->param_age_threshold;
5053
    }
5054
  }
5055
  }
5056
  return option->value;
5057
}
5058
5059
5060
extern "C" void option_error_reporter(enum loglevel level, const char *format, ...);
5061
5062
void option_error_reporter(enum loglevel level, const char *format, ...)
5063
{
5064
  va_list args;
5065
  va_start(args, format);
5066
5067
  /* Don't print warnings for --loose options during bootstrap */
5068
  if (level == ERROR_LEVEL || !opt_bootstrap ||
5069
      global_system_variables.log_warnings)
5070
  {
5071
    vprint_msg_to_log(level, format, args);
5072
  }
5073
  va_end(args);
5074
}
5075
5076
5077
/**
5078
  @todo
5079
  - FIXME add EXIT_TOO_MANY_ARGUMENTS to "mysys_err.h" and return that code?
5080
*/
5081
static void get_options(int *argc,char **argv)
5082
{
5083
  int ho_error;
5084
5085
  my_getopt_register_get_addr(mysql_getopt_value);
5086
  my_getopt_error_reporter= option_error_reporter;
5087
5088
  /* Skip unknown options so that they may be processed later by plugins */
5089
  my_getopt_skip_unknown= TRUE;
5090
5091
  if ((ho_error= handle_options(argc, &argv, my_long_options,
5092
                                mysqld_get_one_option)))
5093
    exit(ho_error);
5094
  (*argc)++; /* add back one for the progname handle_options removes */
5095
             /* no need to do this for argv as we are discarding it. */
5096
5097
  if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes ||
5098
       opt_log_slow_slave_statements) &&
5099
      !opt_slow_log)
5100
    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");
5101
5102
#if defined(HAVE_BROKEN_REALPATH)
5103
  my_use_symdir=0;
5104
  my_disable_symlinks=1;
5105
  have_symlink=SHOW_OPTION_NO;
5106
#else
5107
  if (!my_use_symdir)
5108
  {
5109
    my_disable_symlinks=1;
5110
    have_symlink=SHOW_OPTION_DISABLED;
5111
  }
5112
#endif
5113
  if (opt_debugging)
5114
  {
5115
    /* Allow break with SIGINT, no core or stack trace */
5116
    test_flags|= TEST_SIGINT | TEST_NO_STACKTRACE;
5117
    test_flags&= ~TEST_CORE_ON_SIGNAL;
5118
  }
5119
  /* Set global MyISAM variables from delay_key_write_options */
5120
  fix_delay_key_write((THD*) 0, OPT_GLOBAL);
5121
  /* Set global slave_exec_mode from its option */
5122
  fix_slave_exec_mode(OPT_GLOBAL);
5123
5124
  if (mysqld_chroot)
5125
    set_root(mysqld_chroot);
5126
  fix_paths();
5127
5128
  /*
5129
    Set some global variables from the global_system_variables
5130
    In most cases the global variables will not be used
5131
  */
5132
  my_disable_locking= myisam_single_user= test(opt_external_locking == 0);
5133
  my_default_record_cache_size=global_system_variables.read_buff_size;
5134
  myisam_max_temp_length=
5135
    (my_off_t) global_system_variables.myisam_max_sort_file_size;
5136
5137
  /* Set global variables based on startup options */
5138
  myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size);
5139
5140
  /* long_query_time is in microseconds */
5141
  global_system_variables.long_query_time= max_system_variables.long_query_time=
5142
    (longlong) (long_query_time * 1000000.0);
5143
5144
  if (opt_short_log_format)
5145
    opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT;
5146
5147
  if (init_global_datetime_format(MYSQL_TIMESTAMP_DATE,
5148
				  &global_system_variables.date_format) ||
5149
      init_global_datetime_format(MYSQL_TIMESTAMP_TIME,
5150
				  &global_system_variables.time_format) ||
5151
      init_global_datetime_format(MYSQL_TIMESTAMP_DATETIME,
5152
				  &global_system_variables.datetime_format))
5153
    exit(1);
5154
12.1.3 by Brian Aker
Removal of dead code/remove non-used Falcon tests.
5155
  pool_of_threads_scheduler(&thread_scheduler);  /* purecov: tested */
1 by brian
clean slate
5156
}
5157
5158
5159
/*
5160
  Create version name for running mysqld version
5161
  We automaticly add suffixes -debug, -embedded and -log to the version
5162
  name to make the version more descriptive.
5163
  (MYSQL_SERVER_SUFFIX is set by the compilation environment)
5164
*/
5165
5166
static void set_server_version(void)
5167
{
5168
  char *end= strxmov(server_version, MYSQL_SERVER_VERSION,
5169
                     MYSQL_SERVER_SUFFIX_STR, NullS);
5170
#ifndef DBUG_OFF
5171
  if (!strstr(MYSQL_SERVER_SUFFIX_STR, "-debug"))
5172
    end= strmov(end, "-debug");
5173
#endif
5174
  if (opt_log || opt_update_log || opt_slow_log || opt_bin_log)
5175
    strmov(end, "-log");                        // This may slow down system
5176
}
5177
5178
5179
static char *get_relative_path(const char *path)
5180
{
5181
  if (test_if_hard_path(path) &&
5182
      is_prefix(path,DEFAULT_MYSQL_HOME) &&
5183
      strcmp(DEFAULT_MYSQL_HOME,FN_ROOTDIR))
5184
  {
5185
    path+=(uint) strlen(DEFAULT_MYSQL_HOME);
5186
    while (*path == FN_LIBCHAR)
5187
      path++;
5188
  }
5189
  return (char*) path;
5190
}
5191
5192
5193
/**
5194
  Fix filename and replace extension where 'dir' is relative to
5195
  mysql_real_data_home.
5196
  @return
5197
    1 if len(path) > FN_REFLEN
5198
*/
5199
5200
bool
5201
fn_format_relative_to_data_home(char * to, const char *name,
5202
				const char *dir, const char *extension)
5203
{
5204
  char tmp_path[FN_REFLEN];
5205
  if (!test_if_hard_path(dir))
5206
  {
5207
    strxnmov(tmp_path,sizeof(tmp_path)-1, mysql_real_data_home,
5208
	     dir, NullS);
5209
    dir=tmp_path;
5210
  }
5211
  return !fn_format(to, name, dir, extension,
5212
		    MY_APPEND_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH);
5213
}
5214
5215
5216
static void fix_paths(void)
5217
{
5218
  char buff[FN_REFLEN],*pos;
5219
  convert_dirname(mysql_home,mysql_home,NullS);
5220
  /* Resolve symlinks to allow 'mysql_home' to be a relative symlink */
5221
  my_realpath(mysql_home,mysql_home,MYF(0));
5222
  /* Ensure that mysql_home ends in FN_LIBCHAR */
5223
  pos=strend(mysql_home);
5224
  if (pos[-1] != FN_LIBCHAR)
5225
  {
5226
    pos[0]= FN_LIBCHAR;
5227
    pos[1]= 0;
5228
  }
5229
  convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
5230
  (void) fn_format(buff, mysql_real_data_home, "", "",
5231
                   (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
5232
  (void) unpack_dirname(mysql_unpacked_real_data_home, buff);
5233
  convert_dirname(language,language,NullS);
5234
  (void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir
5235
  (void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home);
5236
  (void) my_load_path(pidfile_name,pidfile_name,mysql_real_data_home);
5237
  (void) my_load_path(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr :
5238
                                      get_relative_path(PLUGINDIR), mysql_home);
5239
  opt_plugin_dir_ptr= opt_plugin_dir;
5240
5241
  char *sharedir=get_relative_path(SHAREDIR);
5242
  if (test_if_hard_path(sharedir))
5243
    strmake(buff,sharedir,sizeof(buff)-1);		/* purecov: tested */
5244
  else
5245
    strxnmov(buff,sizeof(buff)-1,mysql_home,sharedir,NullS);
5246
  convert_dirname(buff,buff,NullS);
5247
  (void) my_load_path(language,language,buff);
5248
5249
  /* If --character-sets-dir isn't given, use shared library dir */
5250
  if (charsets_dir != mysql_charsets_dir)
5251
  {
5252
    strxnmov(mysql_charsets_dir, sizeof(mysql_charsets_dir)-1, buff,
5253
	     CHARSET_DIR, NullS);
5254
  }
5255
  (void) my_load_path(mysql_charsets_dir, mysql_charsets_dir, buff);
5256
  convert_dirname(mysql_charsets_dir, mysql_charsets_dir, NullS);
5257
  charsets_dir=mysql_charsets_dir;
5258
5259
  if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir))
5260
    exit(1);
5261
  if (!slave_load_tmpdir)
5262
  {
5263
    if (!(slave_load_tmpdir = (char*) my_strdup(mysql_tmpdir, MYF(MY_FAE))))
5264
      exit(1);
5265
  }
5266
  /*
5267
    Convert the secure-file-priv option to system format, allowing
5268
    a quick strcmp to check if read or write is in an allowed dir
5269
   */
5270
  if (opt_secure_file_priv)
5271
  {
5272
    convert_dirname(buff, opt_secure_file_priv, NullS);
5273
    my_free(opt_secure_file_priv, MYF(0));
5274
    opt_secure_file_priv= my_strdup(buff, MYF(MY_FAE));
5275
  }
5276
}
5277
5278
5279
static ulong find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
5280
                                   const char *option)
5281
{
5282
  ulong res;
5283
5284
  const char **ptr;
5285
  
5286
  if ((res= find_bit_type(x, bit_lib)) == ~(ulong) 0)
5287
  {
5288
    ptr= bit_lib->type_names;
5289
    if (!*x)
5290
      fprintf(stderr, "No option given to %s\n", option);
5291
    else
5292
      fprintf(stderr, "Wrong option to %s. Option(s) given: %s\n", option, x);
5293
    fprintf(stderr, "Alternatives are: '%s'", *ptr);
5294
    while (*++ptr)
5295
      fprintf(stderr, ",'%s'", *ptr);
5296
    fprintf(stderr, "\n");
5297
    exit(1);
5298
  }
5299
  return res;
5300
}
5301
5302
5303
/**
5304
  @return
5305
    a bitfield from a string of substrings separated by ','
5306
    or
5307
    ~(ulong) 0 on error.
5308
*/
5309
5310
static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
5311
{
5312
  bool found_end;
5313
  int  found_count;
5314
  const char *end,*i,*j;
5315
  const char **array, *pos;
5316
  ulong found,found_int,bit;
5317
  DBUG_ENTER("find_bit_type");
5318
  DBUG_PRINT("enter",("x: '%s'",x));
5319
5320
  found=0;
5321
  found_end= 0;
5322
  pos=(char *) x;
5323
  while (*pos == ' ') pos++;
5324
  found_end= *pos == 0;
5325
  while (!found_end)
5326
  {
5327
    if (!*(end=strcend(pos,',')))		/* Let end point at fieldend */
5328
    {
5329
      while (end > pos && end[-1] == ' ')
5330
	end--;					/* Skip end-space */
5331
      found_end=1;
5332
    }
5333
    found_int=0; found_count=0;
5334
    for (array=bit_lib->type_names, bit=1 ; (i= *array++) ; bit<<=1)
5335
    {
5336
      j=pos;
5337
      while (j != end)
5338
      {
5339
	if (my_toupper(mysqld_charset,*i++) !=
5340
            my_toupper(mysqld_charset,*j++))
5341
	  goto skip;
5342
      }
5343
      found_int=bit;
5344
      if (! *i)
5345
      {
5346
	found_count=1;
5347
	break;
5348
      }
5349
      else if (j != pos)			// Half field found
5350
      {
5351
	found_count++;				// Could be one of two values
5352
      }
5353
skip: ;
5354
    }
5355
    if (found_count != 1)
5356
      DBUG_RETURN(~(ulong) 0);				// No unique value
5357
    found|=found_int;
5358
    pos=end+1;
5359
  }
5360
5361
  DBUG_PRINT("exit",("bit-field: %ld",(ulong) found));
5362
  DBUG_RETURN(found);
5363
} /* find_bit_type */
5364
5365
5366
/**
5367
  Check if file system used for databases is case insensitive.
5368
5369
  @param dir_name			Directory to test
5370
5371
  @retval
5372
    -1  Don't know (Test failed)
5373
  @retval
5374
    0   File system is case sensitive
5375
  @retval
5376
    1   File system is case insensitive
5377
*/
5378
5379
static int test_if_case_insensitive(const char *dir_name)
5380
{
5381
  int result= 0;
5382
  File file;
5383
  char buff[FN_REFLEN], buff2[FN_REFLEN];
15 by brian
Fix for stat, NETWARE removal
5384
  struct stat stat_info;
1 by brian
clean slate
5385
  DBUG_ENTER("test_if_case_insensitive");
5386
5387
  fn_format(buff, glob_hostname, dir_name, ".lower-test",
5388
	    MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_REPLACE_DIR);
5389
  fn_format(buff2, glob_hostname, dir_name, ".LOWER-TEST",
5390
	    MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_REPLACE_DIR);
5391
  (void) my_delete(buff2, MYF(0));
5392
  if ((file= my_create(buff, 0666, O_RDWR, MYF(0))) < 0)
5393
  {
5394
    sql_print_warning("Can't create test file %s", buff);
5395
    DBUG_RETURN(-1);
5396
  }
5397
  my_close(file, MYF(0));
15 by brian
Fix for stat, NETWARE removal
5398
  if (!stat(buff2, &stat_info))
1 by brian
clean slate
5399
    result= 1;					// Can access file
5400
  (void) my_delete(buff, MYF(MY_WME));
5401
  DBUG_PRINT("exit", ("result: %d", result));
5402
  DBUG_RETURN(result);
5403
}
5404
5405
5406
/**
5407
  Create file to store pid number.
5408
*/
5409
static void create_pid_file()
5410
{
5411
  File file;
5412
  if ((file = my_create(pidfile_name,0664,
5413
			O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0)
5414
  {
5415
    char buff[21], *end;
5416
    end= int10_to_str((long) getpid(), buff, 10);
5417
    *end++= '\n';
5418
    if (!my_write(file, (uchar*) buff, (uint) (end-buff), MYF(MY_WME | MY_NABP)))
5419
    {
5420
      (void) my_close(file, MYF(0));
5421
      return;
5422
    }
5423
    (void) my_close(file, MYF(0));
5424
  }
5425
  sql_perror("Can't start server: can't create PID file");
5426
  exit(1);
5427
}
5428
5429
/** Clear most status variables. */
5430
void refresh_status(THD *thd)
5431
{
5432
  pthread_mutex_lock(&LOCK_status);
5433
5434
  /* Add thread's status variabes to global status */
5435
  add_to_status(&global_status_var, &thd->status_var);
5436
5437
  /* Reset thread's status variables */
5438
  bzero((uchar*) &thd->status_var, sizeof(thd->status_var));
5439
5440
  /* Reset some global variables */
5441
  reset_status_vars();
5442
5443
  /* Reset the counters of all key caches (default and named). */
5444
  process_key_caches(reset_key_cache_counters);
5445
  flush_status_time= time((time_t*) 0);
5446
  pthread_mutex_unlock(&LOCK_status);
5447
5448
  /*
5449
    Set max_used_connections to the number of currently open
5450
    connections.  Lock LOCK_thread_count out of LOCK_status to avoid
5451
    deadlocks.  Status reset becomes not atomic, but status data is
5452
    not exact anyway.
5453
  */
5454
  pthread_mutex_lock(&LOCK_thread_count);
5455
  max_used_connections= thread_count;
5456
  pthread_mutex_unlock(&LOCK_thread_count);
5457
}
5458
5459
5460
/*****************************************************************************
5461
  Instantiate templates
5462
*****************************************************************************/
5463
5464
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
5465
/* Used templates */
5466
template class I_List<THD>;
5467
template class I_List_iterator<THD>;
5468
template class I_List<i_string>;
5469
template class I_List<i_string_pair>;
5470
template class I_List<NAMED_LIST>;
5471
template class I_List<Statement>;
5472
template class I_List_iterator<Statement>;
5473
#endif