~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
  {"stmt_close",           (char*) offsetof(STATUS_VAR, com_stmt_close), SHOW_LONG_STATUS},
2059
  {"truncate",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_TRUNCATE]), SHOW_LONG_STATUS},
2060
  {"unlock_tables",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNLOCK_TABLES]), SHOW_LONG_STATUS},
2061
  {"update",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UPDATE]), SHOW_LONG_STATUS},
2062
  {"update_multi",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UPDATE_MULTI]), SHOW_LONG_STATUS},
2063
  {NullS, NullS, SHOW_LONG}
2064
};
2065
2066
static int init_common_variables(const char *conf_file_name, int argc,
2067
				 char **argv, const char **groups)
2068
{
2069
  char buff[FN_REFLEN], *s;
2070
  umask(((~my_umask) & 0666));
2071
  my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
2072
  tzset();			// Set tzname
2073
2074
  max_system_variables.pseudo_thread_id= (ulong)~0;
2075
  server_start_time= flush_status_time= my_time(0);
2076
  rpl_filter= new Rpl_filter;
2077
  binlog_filter= new Rpl_filter;
2078
  if (!rpl_filter || !binlog_filter) 
2079
  {
2080
    sql_perror("Could not allocate replication and binlog filters");
2081
    exit(1);
2082
  }
2083
2084
  if (init_thread_environment())
2085
    return 1;
2086
  mysql_init_variables();
2087
2088
#ifdef HAVE_TZNAME
2089
  {
2090
    struct tm tm_tmp;
2091
    localtime_r(&server_start_time,&tm_tmp);
2092
    strmake(system_time_zone, tzname[tm_tmp.tm_isdst != 0 ? 1 : 0],
2093
            sizeof(system_time_zone)-1);
2094
2095
 }
2096
#endif
2097
  /*
2098
    We set SYSTEM time zone as reasonable default and
2099
    also for failure of my_tz_init() and bootstrap mode.
2100
    If user explicitly set time zone with --default-time-zone
2101
    option we will change this value in my_tz_init().
2102
  */
2103
  global_system_variables.time_zone= my_tz_SYSTEM;
2104
2105
  /*
2106
    Init mutexes for the global MYSQL_BIN_LOG objects.
2107
    As safe_mutex depends on what MY_INIT() does, we can't init the mutexes of
2108
    global MYSQL_BIN_LOGs in their constructors, because then they would be
2109
    inited before MY_INIT(). So we do it here.
2110
  */
2111
  mysql_bin_log.init_pthread_objects();
2112
2113
  if (gethostname(glob_hostname,sizeof(glob_hostname)) < 0)
2114
  {
2115
    strmake(glob_hostname, STRING_WITH_LEN("localhost"));
2116
    sql_print_warning("gethostname failed, using '%s' as hostname",
2117
                      glob_hostname);
2118
    strmake(pidfile_name, STRING_WITH_LEN("mysql"));
2119
  }
2120
  else
2121
  strmake(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
2122
  strmov(fn_ext(pidfile_name),".pid");		// Add proper extension
2123
2124
  /*
2125
    Add server status variables to the dynamic list of
2126
    status variables that is shown by SHOW STATUS.
2127
    Later, in plugin_init, and mysql_install_plugin
2128
    new entries could be added to that list.
2129
  */
2130
  if (add_status_vars(status_vars))
2131
    return 1; // an error was already reported
2132
2133
#ifndef DBUG_OFF
2134
  /*
2135
    We have few debug-only commands in com_status_vars, only visible in debug
2136
    builds. for simplicity we enable the assert only in debug builds
2137
2138
    There are 7 Com_ variables which don't have corresponding SQLCOM_ values:
2139
    (TODO strictly speaking they shouldn't be here, should not have Com_ prefix
2140
    that is. Perhaps Stmt_ ? Comstmt_ ? Prepstmt_ ?)
2141
2142
      Com_admin_commands       => com_other
2143
      Com_stmt_close           => com_stmt_close
2144
      Com_stmt_execute         => com_stmt_execute
2145
      Com_stmt_fetch           => com_stmt_fetch
2146
      Com_stmt_prepare         => com_stmt_prepare
2147
      Com_stmt_reset           => com_stmt_reset
2148
      Com_stmt_send_long_data  => com_stmt_send_long_data
2149
2150
    With this correction the number of Com_ variables (number of elements in
2151
    the array, excluding the last element - terminator) must match the number
2152
    of SQLCOM_ constants.
2153
  */
2154
  compile_time_assert(sizeof(com_status_vars)/sizeof(com_status_vars[0]) - 1 ==
2155
                     SQLCOM_END + 7);
2156
#endif
2157
2158
  load_defaults(conf_file_name, groups, &argc, &argv);
2159
  defaults_argv=argv;
2160
  defaults_argc=argc;
2161
  get_options(&defaults_argc, defaults_argv);
2162
  set_server_version();
2163
2164
  DBUG_PRINT("info",("%s  Ver %s for %s on %s\n",my_progname,
2165
		     server_version, SYSTEM_TYPE,MACHINE_TYPE));
2166
2167
  /* connections and databases needs lots of files */
2168
  {
2169
    uint files, wanted_files, max_open_files;
2170
2171
    /* MyISAM requires two file handles per table. */
2172
    wanted_files= 10+max_connections+table_cache_size*2;
2173
    /*
2174
      We are trying to allocate no less than max_connections*5 file
2175
      handles (i.e. we are trying to set the limit so that they will
2176
      be available).  In addition, we allocate no less than how much
2177
      was already allocated.  However below we report a warning and
2178
      recompute values only if we got less file handles than were
2179
      explicitly requested.  No warning and re-computation occur if we
2180
      can't get max_connections*5 but still got no less than was
2181
      requested (value of wanted_files).
2182
    */
2183
    max_open_files= max(max(wanted_files, max_connections*5),
2184
                        open_files_limit);
2185
    files= my_set_max_open_files(max_open_files);
2186
2187
    if (files < wanted_files)
2188
    {
2189
      if (!open_files_limit)
2190
      {
2191
        /*
2192
          If we have requested too much file handles than we bring
2193
          max_connections in supported bounds.
2194
        */
2195
        max_connections= (ulong) min(files-10-TABLE_OPEN_CACHE_MIN*2,
2196
                                     max_connections);
2197
        /*
2198
          Decrease table_cache_size according to max_connections, but
2199
          not below TABLE_OPEN_CACHE_MIN.  Outer min() ensures that we
2200
          never increase table_cache_size automatically (that could
2201
          happen if max_connections is decreased above).
2202
        */
2203
        table_cache_size= (ulong) min(max((files-10-max_connections)/2,
2204
                                          TABLE_OPEN_CACHE_MIN),
2205
                                      table_cache_size);
2206
	DBUG_PRINT("warning",
2207
		   ("Changed limits: max_open_files: %u  max_connections: %ld  table_cache: %ld",
2208
		    files, max_connections, table_cache_size));
2209
	if (global_system_variables.log_warnings)
2210
	  sql_print_warning("Changed limits: max_open_files: %u  max_connections: %ld  table_cache: %ld",
2211
			files, max_connections, table_cache_size);
2212
      }
2213
      else if (global_system_variables.log_warnings)
2214
	sql_print_warning("Could not increase number of max_open_files to more than %u (request: %u)", files, wanted_files);
2215
    }
2216
    open_files_limit= files;
2217
  }
2218
  unireg_init(opt_specialflag); /* Set up extern variabels */
2219
  if (init_errmessage())	/* Read error messages from file */
2220
    return 1;
2221
  init_client_errs();
2222
  lex_init();
2223
  if (item_create_init())
2224
    return 1;
2225
  item_init();
2226
  if (set_var_init())
2227
    return 1;
2228
  if (init_replication_sys_vars())
2229
    return 1;
2230
  mysys_uses_curses=0;
2231
  /*
2232
    Process a comma-separated character set list and choose
2233
    the first available character set. This is mostly for
2234
    test purposes, to be able to start "mysqld" even if
2235
    the requested character set is not available (see bug#18743).
2236
  */
2237
  for (;;)
2238
  {
2239
    char *next_character_set_name= strchr(default_character_set_name, ',');
2240
    if (next_character_set_name)
2241
      *next_character_set_name++= '\0';
2242
    if (!(default_charset_info=
2243
          get_charset_by_csname(default_character_set_name,
2244
                                MY_CS_PRIMARY, MYF(MY_WME))))
2245
    {
2246
      if (next_character_set_name)
2247
      {
2248
        default_character_set_name= next_character_set_name;
2249
        default_collation_name= 0;          // Ignore collation
2250
      }
2251
      else
2252
        return 1;                           // Eof of the list
2253
    }
2254
    else
2255
      break;
2256
  }
2257
2258
  if (default_collation_name)
2259
  {
2260
    CHARSET_INFO *default_collation;
2261
    default_collation= get_charset_by_name(default_collation_name, MYF(0));
2262
    if (!default_collation)
2263
    {
2264
      sql_print_error(ER(ER_UNKNOWN_COLLATION), default_collation_name);
2265
      return 1;
2266
    }
2267
    if (!my_charset_same(default_charset_info, default_collation))
2268
    {
2269
      sql_print_error(ER(ER_COLLATION_CHARSET_MISMATCH),
2270
		      default_collation_name,
2271
		      default_charset_info->csname);
2272
      return 1;
2273
    }
2274
    default_charset_info= default_collation;
2275
  }
2276
  /* Set collactions that depends on the default collation */
2277
  global_system_variables.collation_server=	 default_charset_info;
2278
  global_system_variables.collation_database=	 default_charset_info;
2279
  global_system_variables.collation_connection=  default_charset_info;
2280
  global_system_variables.character_set_results= default_charset_info;
2281
  global_system_variables.character_set_client= default_charset_info;
2282
2283
  global_system_variables.optimizer_use_mrr= 1;
2284
  global_system_variables.optimizer_switch= 0;
2285
2286
  if (!(character_set_filesystem= 
2287
        get_charset_by_csname(character_set_filesystem_name,
2288
                              MY_CS_PRIMARY, MYF(MY_WME))))
2289
    return 1;
2290
  global_system_variables.character_set_filesystem= character_set_filesystem;
2291
2292
  if (!(my_default_lc_time_names=
2293
        my_locale_by_name(lc_time_names_name)))
2294
  {
2295
    sql_print_error("Unknown locale: '%s'", lc_time_names_name);
2296
    return 1;
2297
  }
2298
  global_system_variables.lc_time_names= my_default_lc_time_names;
2299
  
2300
  sys_init_connect.value_length= 0;
2301
  if ((sys_init_connect.value= opt_init_connect))
2302
    sys_init_connect.value_length= strlen(opt_init_connect);
2303
  else
2304
    sys_init_connect.value=my_strdup("",MYF(0));
2305
2306
  sys_init_slave.value_length= 0;
2307
  if ((sys_init_slave.value= opt_init_slave))
2308
    sys_init_slave.value_length= strlen(opt_init_slave);
2309
  else
2310
    sys_init_slave.value=my_strdup("",MYF(0));
2311
2312
  /* check log options and issue warnings if needed */
2313
  if (opt_log && opt_logname && !(log_output_options & LOG_FILE) &&
2314
      !(log_output_options & LOG_NONE))
2315
    sql_print_warning("Although a path was specified for the "
2316
                      "--log option, log tables are used. "
2317
                      "To enable logging to files use the --log-output option.");
2318
2319
  if (opt_slow_log && opt_slow_logname && !(log_output_options & LOG_FILE)
2320
      && !(log_output_options & LOG_NONE))
2321
    sql_print_warning("Although a path was specified for the "
2322
                      "--log-slow-queries option, log tables are used. "
2323
                      "To enable logging to files use the --log-output=file option.");
2324
2325
  s= opt_logname ? opt_logname : make_default_log_name(buff, ".log");
2326
  sys_var_general_log_path.value= my_strdup(s, MYF(0));
2327
  sys_var_general_log_path.value_length= strlen(s);
2328
2329
  s= opt_slow_logname ? opt_slow_logname : make_default_log_name(buff, "-slow.log");
2330
  sys_var_slow_log_path.value= my_strdup(s, MYF(0));
2331
  sys_var_slow_log_path.value_length= strlen(s);
2332
2333
  if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
2334
    return 1;
2335
  if (my_database_names_init())
2336
    return 1;
2337
2338
  /*
2339
    Ensure that lower_case_table_names is set on system where we have case
2340
    insensitive names.  If this is not done the users MyISAM tables will
2341
    get corrupted if accesses with names of different case.
2342
  */
2343
  DBUG_PRINT("info", ("lower_case_table_names: %d", lower_case_table_names));
2344
  lower_case_file_system= test_if_case_insensitive(mysql_real_data_home);
2345
  if (!lower_case_table_names && lower_case_file_system == 1)
2346
  {
2347
    if (lower_case_table_names_used)
2348
    {
2349
      if (global_system_variables.log_warnings)
2350
	sql_print_warning("\
2351
You have forced lower_case_table_names to 0 through a command-line \
2352
option, even though your file system '%s' is case insensitive.  This means \
2353
that you can corrupt a MyISAM table by accessing it with different cases. \
2354
You should consider changing lower_case_table_names to 1 or 2",
2355
			mysql_real_data_home);
2356
    }
2357
    else
2358
    {
2359
      if (global_system_variables.log_warnings)
2360
	sql_print_warning("Setting lower_case_table_names=2 because file system for %s is case insensitive", mysql_real_data_home);
2361
      lower_case_table_names= 2;
2362
    }
2363
  }
2364
  else if (lower_case_table_names == 2 &&
2365
           !(lower_case_file_system=
2366
             (test_if_case_insensitive(mysql_real_data_home) == 1)))
2367
  {
2368
    if (global_system_variables.log_warnings)
2369
      sql_print_warning("lower_case_table_names was set to 2, even though your "
2370
                        "the file system '%s' is case sensitive.  Now setting "
2371
                        "lower_case_table_names to 0 to avoid future problems.",
2372
			mysql_real_data_home);
2373
    lower_case_table_names= 0;
2374
  }
2375
  else
2376
  {
2377
    lower_case_file_system=
2378
      (test_if_case_insensitive(mysql_real_data_home) == 1);
2379
  }
2380
2381
  /* Reset table_alias_charset, now that lower_case_table_names is set. */
2382
  table_alias_charset= (lower_case_table_names ?
2383
			files_charset_info :
2384
			&my_charset_bin);
2385
2386
  return 0;
2387
}
2388
2389
2390
static int init_thread_environment()
2391
{
2392
  (void) pthread_mutex_init(&LOCK_mysql_create_db,MY_MUTEX_INIT_SLOW);
2393
  (void) pthread_mutex_init(&LOCK_lock_db,MY_MUTEX_INIT_SLOW);
2394
  (void) pthread_mutex_init(&LOCK_open, NULL);
2395
  (void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
2396
  (void) pthread_mutex_init(&LOCK_mapped_file,MY_MUTEX_INIT_SLOW);
2397
  (void) pthread_mutex_init(&LOCK_status,MY_MUTEX_INIT_FAST);
2398
  (void) pthread_mutex_init(&LOCK_error_log,MY_MUTEX_INIT_FAST);
2399
  (void) pthread_mutex_init(&LOCK_manager,MY_MUTEX_INIT_FAST);
2400
  (void) pthread_mutex_init(&LOCK_crypt,MY_MUTEX_INIT_FAST);
2401
  (void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
2402
  (void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
2403
  (void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
2404
  (void) my_rwlock_init(&LOCK_system_variables_hash, NULL);
2405
  (void) pthread_mutex_init(&LOCK_global_read_lock, MY_MUTEX_INIT_FAST);
2406
  (void) pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST);
2407
  (void) pthread_mutex_init(&LOCK_connection_count, MY_MUTEX_INIT_FAST);
2408
  (void) my_rwlock_init(&LOCK_sys_init_connect, NULL);
2409
  (void) my_rwlock_init(&LOCK_sys_init_slave, NULL);
2410
  (void) pthread_cond_init(&COND_thread_count,NULL);
2411
  (void) pthread_cond_init(&COND_refresh,NULL);
2412
  (void) pthread_cond_init(&COND_global_read_lock,NULL);
2413
  (void) pthread_cond_init(&COND_thread_cache,NULL);
2414
  (void) pthread_cond_init(&COND_flush_thread_cache,NULL);
2415
  (void) pthread_cond_init(&COND_manager,NULL);
2416
  (void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST);
2417
  (void) pthread_cond_init(&COND_rpl_status, NULL);
2418
2419
  /* Parameter for threads created for connections */
2420
  (void) pthread_attr_init(&connection_attrib);
2421
  (void) pthread_attr_setdetachstate(&connection_attrib,
2422
				     PTHREAD_CREATE_DETACHED);
2423
  pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM);
2424
  if (!(opt_specialflag & SPECIAL_NO_PRIOR))
6 by Brian Aker
Second pass on pthread cleanup
2425
  {
2426
    struct sched_param tmp_sched_param;
2427
2428
    memset(&tmp_sched_param, 0, sizeof(tmp_sched_param));
2429
    tmp_sched_param.sched_priority= WAIT_PRIOR;
2430
    (void)pthread_attr_setschedparam(&connection_attrib, &tmp_sched_param);
2431
  }
1 by brian
clean slate
2432
2433
  if (pthread_key_create(&THR_THD,NULL) ||
2434
      pthread_key_create(&THR_MALLOC,NULL))
2435
  {
2436
    sql_print_error("Can't create thread-keys");
2437
    return 1;
2438
  }
2439
  return 0;
2440
}
2441
2442
2443
static int init_server_components()
2444
{
2445
  DBUG_ENTER("init_server_components");
2446
  /*
2447
    We need to call each of these following functions to ensure that
2448
    all things are initialized so that unireg_abort() doesn't fail
2449
  */
2450
  if (table_cache_init() | table_def_init())
2451
    unireg_abort(1);
2452
2453
  randominit(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2);
2454
  setup_fpu();
2455
  init_thr_lock();
2456
  init_slave_list();
2457
2458
  /* Setup logs */
2459
2460
  /*
2461
    Enable old-fashioned error log, except when the user has requested
2462
    help information. Since the implementation of plugin server
2463
    variables the help output is now written much later.
2464
  */
2465
  if (opt_error_log && !opt_help)
2466
  {
2467
    if (!log_error_file_ptr[0])
2468
      fn_format(log_error_file, pidfile_name, mysql_data_home, ".err",
2469
                MY_REPLACE_EXT); /* replace '.<domain>' by '.err', bug#4997 */
2470
    else
2471
      fn_format(log_error_file, log_error_file_ptr, mysql_data_home, ".err",
2472
                MY_UNPACK_FILENAME | MY_SAFE_PATH);
2473
    if (!log_error_file[0])
2474
      opt_error_log= 1;				// Too long file name
2475
    else
2476
    {
2477
      if (freopen(log_error_file, "a+", stdout))
2478
        freopen(log_error_file, "a+", stderr);
2479
    }
2480
  }
2481
2482
  if (xid_cache_init())
2483
  {
2484
    sql_print_error("Out of memory");
2485
    unireg_abort(1);
2486
  }
2487
2488
  /* need to configure logging before initializing storage engines */
2489
  if (opt_update_log)
2490
  {
2491
    /*
2492
      Update log is removed since 5.0. But we still accept the option.
2493
      The idea is if the user already uses the binlog and the update log,
2494
      we completely ignore any option/variable related to the update log, like
2495
      if the update log did not exist. But if the user uses only the update
2496
      log, then we translate everything into binlog for him (with warnings).
2497
      Implementation of the above :
2498
      - If mysqld is started with --log-update and --log-bin,
2499
      ignore --log-update (print a warning), push a warning when SQL_LOG_UPDATE
2500
      is used, and turn off --sql-bin-update-same.
2501
      This will completely ignore SQL_LOG_UPDATE
2502
      - If mysqld is started with --log-update only,
2503
      change it to --log-bin (with the filename passed to log-update,
2504
      plus '-bin') (print a warning), push a warning when SQL_LOG_UPDATE is
2505
      used, and turn on --sql-bin-update-same.
2506
      This will translate SQL_LOG_UPDATE to SQL_LOG_BIN.
2507
2508
      Note that we tell the user that --sql-bin-update-same is deprecated and
2509
      does nothing, and we don't take into account if he used this option or
2510
      not; but internally we give this variable a value to have the behaviour
2511
      we want (i.e. have SQL_LOG_UPDATE influence SQL_LOG_BIN or not).
2512
      As sql-bin-update-same, log-update and log-bin cannot be changed by the
2513
      user after starting the server (they are not variables), the user will
2514
      not later interfere with the settings we do here.
2515
    */
2516
    if (opt_bin_log)
2517
    {
2518
      opt_sql_bin_update= 0;
2519
      sql_print_error("The update log is no longer supported by MySQL in \
2520
version 5.0 and above. It is replaced by the binary log.");
2521
    }
2522
    else
2523
    {
2524
      opt_sql_bin_update= 1;
2525
      opt_bin_log= 1;
2526
      if (opt_update_logname)
2527
      {
2528
        /* as opt_bin_log==0, no need to free opt_bin_logname */
2529
        if (!(opt_bin_logname= my_strdup(opt_update_logname, MYF(MY_WME))))
2530
          exit(EXIT_OUT_OF_MEMORY);
2531
        sql_print_error("The update log is no longer supported by MySQL in \
2532
version 5.0 and above. It is replaced by the binary log. Now starting MySQL \
2533
with --log-bin='%s' instead.",opt_bin_logname);
2534
      }
2535
      else
2536
        sql_print_error("The update log is no longer supported by MySQL in \
2537
version 5.0 and above. It is replaced by the binary log. Now starting MySQL \
2538
with --log-bin instead.");
2539
    }
2540
  }
2541
  if (opt_log_slave_updates && !opt_bin_log)
2542
  {
2543
    sql_print_error("You need to use --log-bin to make "
2544
                    "--log-slave-updates work.");
2545
    unireg_abort(1);
2546
  }
2547
  if (!opt_bin_log)
2548
    if (opt_binlog_format_id != BINLOG_FORMAT_UNSPEC)
2549
  {
2550
    sql_print_error("You need to use --log-bin to make "
2551
                    "--binlog-format work.");
2552
    unireg_abort(1);
2553
  }
2554
    else
2555
  {
2556
      global_system_variables.binlog_format= BINLOG_FORMAT_MIXED;
2557
    }
2558
  else
2559
    if (opt_binlog_format_id == BINLOG_FORMAT_UNSPEC)
2560
      global_system_variables.binlog_format= BINLOG_FORMAT_MIXED;
2561
    else
2562
    { 
2563
      DBUG_ASSERT(global_system_variables.binlog_format != BINLOG_FORMAT_UNSPEC);
2564
  }
2565
2566
  /* Check that we have not let the format to unspecified at this point */
2567
  DBUG_ASSERT((uint)global_system_variables.binlog_format <=
2568
              array_elements(binlog_format_names)-1);
2569
2570
  if (opt_log_slave_updates && replicate_same_server_id)
2571
  {
2572
    sql_print_error("\
2573
using --replicate-same-server-id in conjunction with \
2574
--log-slave-updates is impossible, it would lead to infinite loops in this \
2575
server.");
2576
    unireg_abort(1);
2577
  }
2578
2579
  if (opt_bin_log)
2580
  {
2581
    char buf[FN_REFLEN];
2582
    const char *ln;
2583
    ln= mysql_bin_log.generate_name(opt_bin_logname, "-bin", 1, buf);
2584
    if (!opt_bin_logname && !opt_binlog_index_name)
2585
    {
2586
      /*
2587
        User didn't give us info to name the binlog index file.
2588
        Picking `hostname`-bin.index like did in 4.x, causes replication to
2589
        fail if the hostname is changed later. So, we would like to instead
2590
        require a name. But as we don't want to break many existing setups, we
2591
        only give warning, not error.
2592
      */
2593
      sql_print_warning("No argument was provided to --log-bin, and "
2594
                        "--log-bin-index was not used; so replication "
2595
                        "may break when this MySQL server acts as a "
2596
                        "master and has his hostname changed!! Please "
2597
                        "use '--log-bin=%s' to avoid this problem.", ln);
2598
    }
2599
    if (ln == buf)
2600
    {
2601
      my_free(opt_bin_logname, MYF(MY_ALLOW_ZERO_PTR));
2602
      opt_bin_logname=my_strdup(buf, MYF(0));
2603
    }
2604
    if (mysql_bin_log.open_index_file(opt_binlog_index_name, ln))
2605
    {
2606
      unireg_abort(1);
2607
    }
2608
2609
    /*
2610
      Used to specify which type of lock we need to use for queries of type
2611
      INSERT ... SELECT. This will change when we have row level logging.
2612
    */
2613
    using_update_log=1;
2614
  }
2615
2616
  /* call ha_init_key_cache() on all key caches to init them */
2617
  process_key_caches(&ha_init_key_cache);
2618
2619
  /* Allow storage engine to give real error messages */
2620
  if (ha_init_errors())
2621
    DBUG_RETURN(1);
2622
2623
  if (plugin_init(&defaults_argc, defaults_argv,
2624
                  (opt_noacl ? PLUGIN_INIT_SKIP_PLUGIN_TABLE : 0) |
2625
                  (opt_help ? PLUGIN_INIT_SKIP_INITIALIZATION : 0)))
2626
  {
2627
    sql_print_error("Failed to initialize plugins.");
2628
    unireg_abort(1);
2629
  }
2630
2631
  if (opt_help)
2632
    unireg_abort(0);
2633
2634
  /* we do want to exit if there are any other unknown options */
2635
  if (defaults_argc > 1)
2636
  {
2637
    int ho_error;
2638
    char **tmp_argv= defaults_argv;
2639
    struct my_option no_opts[]=
2640
    {
2641
      {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
2642
    };
2643
    /*
2644
      We need to eat any 'loose' arguments first before we conclude
2645
      that there are unprocessed options.
2646
      But we need to preserve defaults_argv pointer intact for
2647
      free_defaults() to work. Thus we use a copy here.
2648
    */
2649
    my_getopt_skip_unknown= 0;
2650
2651
    if ((ho_error= handle_options(&defaults_argc, &tmp_argv, no_opts,
2652
                                  mysqld_get_one_option)))
2653
      unireg_abort(ho_error);
2654
2655
    if (defaults_argc)
2656
    {
2657
      fprintf(stderr, "%s: Too many arguments (first extra is '%s').\n"
2658
              "Use --verbose --help to get a list of available options\n",
2659
              my_progname, *tmp_argv);
2660
      unireg_abort(1);
2661
    }
2662
  }
2663
2664
  /* if the errmsg.sys is not loaded, terminate to maintain behaviour */
2665
  if (!errmesg[0][0])
2666
    unireg_abort(1);
2667
2668
  /* We have to initialize the storage engines before CSV logging */
2669
  if (ha_init())
2670
  {
2671
    sql_print_error("Can't init databases");
2672
    unireg_abort(1);
2673
  }
2674
2675
  logger.set_handlers(LOG_FILE, opt_slow_log ? LOG_FILE:LOG_NONE,
2676
                      opt_log ? LOG_FILE:LOG_NONE);
2677
2678
  /*
2679
    Check that the default storage engine is actually available.
2680
  */
2681
  if (default_storage_engine_str)
2682
  {
2683
    LEX_STRING name= { default_storage_engine_str,
2684
                       strlen(default_storage_engine_str) };
2685
    plugin_ref plugin;
2686
    handlerton *hton;
2687
    
2688
    if ((plugin= ha_resolve_by_name(0, &name)))
2689
      hton= plugin_data(plugin, handlerton*);
2690
    else
2691
    {
2692
      sql_print_error("Unknown/unsupported table type: %s",
2693
                      default_storage_engine_str);
2694
      unireg_abort(1);
2695
    }
2696
    if (!ha_storage_engine_is_enabled(hton))
2697
    {
2698
      if (!opt_bootstrap)
2699
      {
2700
        sql_print_error("Default storage engine (%s) is not available",
2701
                        default_storage_engine_str);
2702
        unireg_abort(1);
2703
      }
2704
      DBUG_ASSERT(global_system_variables.table_plugin);
2705
    }
2706
    else
2707
    {
2708
      /*
2709
        Need to unlock as global_system_variables.table_plugin 
2710
        was acquired during plugin_init()
2711
      */
2712
      plugin_unlock(0, global_system_variables.table_plugin);
2713
      global_system_variables.table_plugin= plugin;
2714
    }
2715
  }
2716
2717
  tc_log= (total_ha_2pc > 1 ? (opt_bin_log  ?
2718
                               (TC_LOG *) &mysql_bin_log :
2719
                               (TC_LOG *) &tc_log_mmap) :
2720
           (TC_LOG *) &tc_log_dummy);
2721
2722
  if (tc_log->open(opt_bin_log ? opt_bin_logname : opt_tc_log_file))
2723
  {
2724
    sql_print_error("Can't init tc log");
2725
    unireg_abort(1);
2726
  }
2727
2728
  if (ha_recover(0))
2729
  {
2730
    unireg_abort(1);
2731
  }
2732
2733
  if (opt_bin_log && mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0,
2734
                                        WRITE_CACHE, 0, max_binlog_size, 0))
2735
    unireg_abort(1);
2736
2737
  if (opt_bin_log && expire_logs_days)
2738
  {
2739
    time_t purge_time= server_start_time - expire_logs_days*24*60*60;
2740
    if (purge_time >= 0)
2741
      mysql_bin_log.purge_logs_before_date(purge_time);
2742
  }
2743
2744
  if (opt_myisam_log)
2745
    (void) mi_log(1);
2746
2747
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
2748
  if (locked_in_memory && !getuid())
2749
  {
2750
    if (setreuid((uid_t)-1, 0) == -1)
2751
    {                        // this should never happen
2752
      sql_perror("setreuid");
2753
      unireg_abort(1);
2754
    }
2755
    if (mlockall(MCL_CURRENT))
2756
    {
2757
      if (global_system_variables.log_warnings)
2758
	sql_print_warning("Failed to lock memory. Errno: %d\n",errno);
2759
      locked_in_memory= 0;
2760
    }
2761
    if (user_info)
2762
      set_user(mysqld_user, user_info);
2763
  }
2764
  else
2765
#endif
2766
    locked_in_memory=0;
2767
2768
  ft_init_stopwords();
2769
2770
  init_update_queries();
2771
  DBUG_RETURN(0);
2772
}
2773
2774
2775
static void create_maintenance_thread()
2776
{
2777
  if (flush_time && flush_time != ~(ulong) 0L)
2778
  {
2779
    pthread_t hThread;
2780
    if (pthread_create(&hThread,&connection_attrib,handle_manager,0))
2781
      sql_print_warning("Can't create thread to manage maintenance");
2782
  }
2783
}
2784
2785
2786
int main(int argc, char **argv)
2787
{
2788
  MY_INIT(argv[0]);		// init my_sys library & pthreads
2789
  /* nothing should come before this line ^^^ */
2790
2791
  /* Set signal used to kill MySQL */
2792
#if defined(SIGUSR2)
2793
  thr_kill_signal= thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2;
2794
#else
2795
  thr_kill_signal= SIGINT;
2796
#endif
2797
2798
  /*
2799
    Perform basic logger initialization logger. Should be called after
2800
    MY_INIT, as it initializes mutexes. Log tables are inited later.
2801
  */
2802
  logger.init_base();
2803
2804
#ifdef _CUSTOMSTARTUPCONFIG_
2805
  if (_cust_check_startup())
2806
  {
2807
    / * _cust_check_startup will report startup failure error * /
2808
    exit(1);
2809
  }
2810
#endif
2811
2812
  if (init_common_variables(MYSQL_CONFIG_NAME,
2813
			    argc, argv, load_default_groups))
2814
    unireg_abort(1);				// Will do exit
2815
2816
  init_signals();
2817
  if (!(opt_specialflag & SPECIAL_NO_PRIOR))
5 by Brian Aker
Removed my_pthread_setprio()
2818
  {
2819
    struct sched_param tmp_sched_param;
2820
2821
    memset(&tmp_sched_param, 0, sizeof(tmp_sched_param));
2822
    tmp_sched_param.sched_priority= my_thread_stack_size*2;
2823
    (void)pthread_setschedparam(pthread_self(), SCHED_OTHER, &tmp_sched_param);
2824
  }
1 by brian
clean slate
2825
  pthread_attr_setstacksize(&connection_attrib,my_thread_stack_size);
2826
#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
2827
  {
2828
    /* Retrieve used stack size;  Needed for checking stack overflows */
2829
    size_t stack_size= 0;
2830
    pthread_attr_getstacksize(&connection_attrib, &stack_size);
2831
    /* We must check if stack_size = 0 as Solaris 2.9 can return 0 here */
2832
    if (stack_size && stack_size < my_thread_stack_size)
2833
    {
2834
      if (global_system_variables.log_warnings)
2835
	sql_print_warning("Asked for %lu thread stack, but got %ld",
2836
			  my_thread_stack_size, (long) stack_size);
2837
      my_thread_stack_size= stack_size;
2838
    }
2839
  }
2840
#endif
2841
2842
  select_thread=pthread_self();
2843
  select_thread_in_use=1;
2844
2845
  /*
2846
    We have enough space for fiddling with the argv, continue
2847
  */
2848
  check_data_home(mysql_real_data_home);
2849
  if (my_setwd(mysql_real_data_home,MYF(MY_WME)) && !opt_help)
2850
    unireg_abort(1);				/* purecov: inspected */
2851
  mysql_data_home= mysql_data_home_buff;
2852
  mysql_data_home[0]=FN_CURLIB;		// all paths are relative from here
2853
  mysql_data_home[1]=0;
2854
  mysql_data_home_len= 2;
2855
2856
  if ((user_info= check_user(mysqld_user)))
2857
  {
2858
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
2859
    if (locked_in_memory) // getuid() == 0 here
2860
      set_effective_user(user_info);
2861
    else
2862
#endif
2863
      set_user(mysqld_user, user_info);
2864
  }
2865
2866
  if (opt_bin_log && !server_id)
2867
  {
2868
    server_id= 1;
2869
#ifdef EXTRA_DEBUG
2870
    sql_print_warning("You have enabled the binary log, but you haven't set "
2871
                      "server-id to a non-zero value: we force server id to 1; "
2872
                      "updates will be logged to the binary log, but "
2873
                      "connections from slaves will not be accepted.");
2874
#endif
2875
  }
2876
2877
  if (init_server_components())
2878
    unireg_abort(1);
2879
2880
  network_init();
2881
2882
  /*
2883
   Initialize my_str_malloc() and my_str_free()
2884
  */
2885
  my_str_malloc= &my_str_malloc_mysqld;
2886
  my_str_free= &my_str_free_mysqld;
2887
2888
  /*
2889
    init signals & alarm
2890
    After this we can't quit by a simple unireg_abort
2891
  */
2892
  error_handler_hook= my_message_sql;
2893
  start_signal_handler();				// Creates pidfile
2894
2895
  if (mysql_rm_tmp_tables() || my_tz_init((THD *)0, default_tz_name, opt_bootstrap))
2896
  {
2897
    abort_loop=1;
2898
    select_thread_in_use=0;
2899
    (void) pthread_kill(signal_thread, MYSQL_KILL_SIGNAL);
2900
2901
    if (!opt_bootstrap)
2902
      (void) my_delete(pidfile_name,MYF(MY_WME));	// Not needed anymore
2903
2904
    exit(1);
2905
  }
2906
2907
  udf_init();
2908
2909
  init_status_vars();
2910
  if (opt_bootstrap) /* If running with bootstrap, do not start replication. */
2911
    opt_skip_slave_start= 1;
2912
  /*
2913
    init_slave() must be called after the thread keys are created.
2914
    Some parts of the code (e.g. SHOW STATUS LIKE 'slave_running' and other
2915
    places) assume that active_mi != 0, so let's fail if it's 0 (out of
2916
    memory); a message has already been printed.
2917
  */
2918
  if (init_slave() && !active_mi)
2919
  {
2920
    unireg_abort(1);
2921
  }
2922
2923
  if (opt_bootstrap)
2924
  {
2925
    select_thread_in_use= 0;                    // Allow 'kill' to work
2926
    bootstrap(stdin);
2927
    unireg_abort(bootstrap_error ? 1 : 0);
2928
  }
2929
  if (opt_init_file)
2930
  {
2931
    if (read_init_file(opt_init_file))
2932
      unireg_abort(1);
2933
  }
2934
2935
  create_maintenance_thread();
2936
2937
  sql_print_information(ER(ER_STARTUP),my_progname,server_version,
11 by Brian Aker
Removing old UNIX socket bits
2938
                        "", mysqld_port, MYSQL_COMPILATION_COMMENT);
2939
2940
2941
  handle_connections_sockets();
1 by brian
clean slate
2942
2943
  /* (void) pthread_attr_destroy(&connection_attrib); */
2944
  
2945
  DBUG_PRINT("quit",("Exiting main thread"));
2946
2947
#ifdef EXTRA_DEBUG2
2948
  sql_print_error("Before Lock_thread_count");
2949
#endif
2950
  (void) pthread_mutex_lock(&LOCK_thread_count);
2951
  DBUG_PRINT("quit", ("Got thread_count mutex"));
2952
  select_thread_in_use=0;			// For close_connections
2953
  (void) pthread_mutex_unlock(&LOCK_thread_count);
2954
  (void) pthread_cond_broadcast(&COND_thread_count);
2955
#ifdef EXTRA_DEBUG2
2956
  sql_print_error("After lock_thread_count");
2957
#endif
2958
2959
  /* Wait until cleanup is done */
2960
  (void) pthread_mutex_lock(&LOCK_thread_count);
2961
  while (!ready_to_exit)
2962
    pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
2963
  (void) pthread_mutex_unlock(&LOCK_thread_count);
2964
2965
  clean_up(1);
2966
  mysqld_exit(0);
2967
}
2968
2969
2970
/**
2971
  Execute all commands from a file. Used by the mysql_install_db script to
2972
  create MySQL privilege tables without having to start a full MySQL server.
2973
*/
2974
2975
static void bootstrap(FILE *file)
2976
{
2977
  DBUG_ENTER("bootstrap");
2978
2979
  THD *thd= new THD;
2980
  thd->bootstrap=1;
2981
  my_net_init(&thd->net,(st_vio*) 0);
2982
  thd->max_client_packet_length= thd->net.max_packet;
2983
  thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
2984
  thread_count++;
2985
2986
  bootstrap_file=file;
2987
  if (pthread_create(&thd->real_id,&connection_attrib,handle_bootstrap,
2988
		     (void*) thd))
2989
  {
2990
    sql_print_warning("Can't create thread to handle bootstrap");
2991
    bootstrap_error=-1;
2992
    DBUG_VOID_RETURN;
2993
  }
2994
  /* Wait for thread to die */
2995
  (void) pthread_mutex_lock(&LOCK_thread_count);
2996
  while (thread_count)
2997
  {
2998
    (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
2999
    DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
3000
  }
3001
  (void) pthread_mutex_unlock(&LOCK_thread_count);
3002
3003
  DBUG_VOID_RETURN;
3004
}
3005
3006
3007
static bool read_init_file(char *file_name)
3008
{
3009
  FILE *file;
3010
  DBUG_ENTER("read_init_file");
3011
  DBUG_PRINT("enter",("name: %s",file_name));
3012
  if (!(file=my_fopen(file_name,O_RDONLY,MYF(MY_WME))))
3013
    return(1);
3014
  bootstrap(file);
3015
  (void) my_fclose(file,MYF(MY_WME));
3016
  return 0;
3017
}
3018
3019
3020
/**
3021
  Create new thread to handle incoming connection.
3022
3023
    This function will create new thread to handle the incoming
3024
    connection.  If there are idle cached threads one will be used.
3025
    'thd' will be pushed into 'threads'.
3026
3027
    In single-threaded mode (\#define ONE_THREAD) connection will be
3028
    handled inside this function.
3029
3030
  @param[in,out] thd    Thread handle of future thread.
3031
*/
3032
3033
static void create_new_thread(THD *thd)
3034
{
3035
  DBUG_ENTER("create_new_thread");
3036
3037
  /*
3038
    Don't allow too many connections. We roughly check here that we allow
3039
    only (max_connections + 1) connections.
3040
  */
3041
3042
  pthread_mutex_lock(&LOCK_connection_count);
3043
3044
  if (connection_count >= max_connections + 1 || abort_loop)
3045
  {
3046
    pthread_mutex_unlock(&LOCK_connection_count);
3047
3048
    DBUG_PRINT("error",("Too many connections"));
3049
    close_connection(thd, ER_CON_COUNT_ERROR, 1);
3050
    delete thd;
3051
    DBUG_VOID_RETURN;
3052
  }
3053
3054
  ++connection_count;
3055
3056
  if (connection_count > max_used_connections)
3057
    max_used_connections= connection_count;
3058
3059
  pthread_mutex_unlock(&LOCK_connection_count);
3060
3061
  /* Start a new thread to handle connection. */
3062
3063
  pthread_mutex_lock(&LOCK_thread_count);
3064
3065
  /*
3066
    The initialization of thread_id is done in create_embedded_thd() for
3067
    the embedded library.
3068
    TODO: refactor this to avoid code duplication there
3069
  */
3070
  thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
3071
3072
  thread_count++;
3073
3074
  thread_scheduler.add_connection(thd);
3075
3076
  DBUG_VOID_RETURN;
3077
}
3078
3079
3080
#ifdef SIGNALS_DONT_BREAK_READ
3081
inline void kill_broken_server()
3082
{
3083
  /* hack to get around signals ignored in syscalls for problem OS's */
3084
  if ((!opt_disable_networking && ip_sock == INVALID_SOCKET))
3085
  {
3086
    select_thread_in_use = 0;
3087
    /* The following call will never return */
3088
    kill_server((void*) MYSQL_KILL_SIGNAL);
3089
  }
3090
}
3091
#define MAYBE_BROKEN_SYSCALL kill_broken_server();
3092
#else
3093
#define MAYBE_BROKEN_SYSCALL
3094
#endif
3095
3096
	/* Handle new connections and spawn new process to handle them */
3097
11 by Brian Aker
Removing old UNIX socket bits
3098
void handle_connections_sockets()
1 by brian
clean slate
3099
{
3100
  my_socket sock,new_sock;
3101
  uint error_count=0;
11 by Brian Aker
Removing old UNIX socket bits
3102
  uint max_used_connection= (uint)ip_sock+1;
1 by brian
clean slate
3103
  fd_set readFDs,clientFDs;
3104
  THD *thd;
3105
  struct sockaddr_storage cAddr;
3106
  int ip_flags=0, flags;
3107
  st_vio *vio_tmp;
3108
3109
  FD_ZERO(&clientFDs);
3110
  if (ip_sock != INVALID_SOCKET)
3111
  {
3112
    FD_SET(ip_sock,&clientFDs);
3113
#ifdef HAVE_FCNTL
3114
    ip_flags = fcntl(ip_sock, F_GETFL, 0);
3115
#endif
3116
  }
3117
  DBUG_PRINT("general",("Waiting for connections."));
3118
  MAYBE_BROKEN_SYSCALL;
3119
  while (!abort_loop)
3120
  {
3121
    readFDs=clientFDs;
3122
    if (select((int) max_used_connection,&readFDs,0,0,0) < 0)
3123
    {
3124
      if (socket_errno != SOCKET_EINTR)
3125
      {
3126
	if (!select_errors++ && !abort_loop)	/* purecov: inspected */
3127
	  sql_print_error("mysqld: Got error %d from select",socket_errno); /* purecov: inspected */
3128
      }
3129
      MAYBE_BROKEN_SYSCALL
3130
      continue;
3131
    }
3132
    if (abort_loop)
3133
    {
3134
      MAYBE_BROKEN_SYSCALL;
3135
      break;
3136
    }
3137
3138
    /* Is this a new connection request ? */
3139
    {
3140
      sock = ip_sock;
3141
      flags= ip_flags;
3142
    }
3143
3144
#if !defined(NO_FCNTL_NONBLOCK)
3145
    if (!(test_flags & TEST_BLOCKING))
3146
    {
3147
#if defined(O_NONBLOCK)
3148
      fcntl(sock, F_SETFL, flags | O_NONBLOCK);
3149
#elif defined(O_NDELAY)
3150
      fcntl(sock, F_SETFL, flags | O_NDELAY);
3151
#endif
3152
    }
3153
#endif /* NO_FCNTL_NONBLOCK */
3154
    for (uint retry=0; retry < MAX_ACCEPT_RETRY; retry++)
3155
    {
3156
      size_socket length= sizeof(struct sockaddr_storage);
3157
      new_sock= accept(sock, (struct sockaddr *)(&cAddr),
3158
                       &length);
3159
      if (new_sock != INVALID_SOCKET ||
3160
	  (socket_errno != SOCKET_EINTR && socket_errno != SOCKET_EAGAIN))
3161
	break;
3162
      MAYBE_BROKEN_SYSCALL;
3163
#if !defined(NO_FCNTL_NONBLOCK)
3164
      if (!(test_flags & TEST_BLOCKING))
3165
      {
3166
	if (retry == MAX_ACCEPT_RETRY - 1)
3167
	  fcntl(sock, F_SETFL, flags);		// Try without O_NONBLOCK
3168
      }
3169
#endif
3170
    }
3171
#if !defined(NO_FCNTL_NONBLOCK)
3172
    if (!(test_flags & TEST_BLOCKING))
3173
      fcntl(sock, F_SETFL, flags);
3174
#endif
3175
    if (new_sock == INVALID_SOCKET)
3176
    {
3177
      if ((error_count++ & 255) == 0)		// This can happen often
3178
	sql_perror("Error in accept");
3179
      MAYBE_BROKEN_SYSCALL;
3180
      if (socket_errno == SOCKET_ENFILE || socket_errno == SOCKET_EMFILE)
3181
	sleep(1);				// Give other threads some time
3182
      continue;
3183
    }
3184
3185
    {
3186
      size_socket dummyLen;
3187
      struct sockaddr_storage dummy;
3188
      dummyLen = sizeof(dummy);
3189
      if (  getsockname(new_sock,(struct sockaddr *)&dummy, 
3190
                  (socklen_t *)&dummyLen) < 0  )
3191
      {
3192
	sql_perror("Error on new connection socket");
3193
	(void) shutdown(new_sock, SHUT_RDWR);
3194
	(void) closesocket(new_sock);
3195
	continue;
3196
      }
3197
    }
3198
3199
    /*
3200
    ** Don't allow too many connections
3201
    */
3202
3203
    if (!(thd= new THD))
3204
    {
3205
      (void) shutdown(new_sock, SHUT_RDWR);
3206
      VOID(closesocket(new_sock));
3207
      continue;
3208
    }
11 by Brian Aker
Removing old UNIX socket bits
3209
    if (!(vio_tmp=vio_new(new_sock, VIO_TYPE_TCPIP, sock == 0)) ||
1 by brian
clean slate
3210
	my_net_init(&thd->net,vio_tmp))
3211
    {
3212
      /*
3213
        Only delete the temporary vio if we didn't already attach it to the
3214
        NET object. The destructor in THD will delete any initialized net
3215
        structure.
3216
      */
3217
      if (vio_tmp && thd->net.vio != vio_tmp)
3218
        vio_delete(vio_tmp);
3219
      else
3220
      {
3221
	(void) shutdown(new_sock, SHUT_RDWR);
3222
	(void) closesocket(new_sock);
3223
      }
3224
      delete thd;
3225
      continue;
3226
    }
3227
3228
    create_new_thread(thd);
3229
  }
3230
}
3231
3232
3233
/****************************************************************************
3234
  Handle start options
3235
******************************************************************************/
3236
3237
enum options_mysqld
3238
{
3239
  OPT_ISAM_LOG=256,            OPT_SKIP_NEW, 
3240
  OPT_SKIP_GRANT,              OPT_SKIP_LOCK, 
3241
  OPT_ENABLE_LOCK,             OPT_USE_LOCKING,
3242
  OPT_SOCKET,                  OPT_UPDATE_LOG,
3243
  OPT_BIN_LOG,                 
3244
  OPT_BIN_LOG_INDEX,
3245
  OPT_BIND_ADDRESS,            OPT_PID_FILE,
3246
  OPT_SKIP_PRIOR,              OPT_BIG_TABLES,
12.1.3 by Brian Aker
Removal of dead code/remove non-used Falcon tests.
3247
  OPT_STANDALONE,
1 by brian
clean slate
3248
  OPT_CONSOLE,                 OPT_LOW_PRIORITY_UPDATES,
3249
  OPT_SHORT_LOG_FORMAT,
3250
  OPT_FLUSH,                   OPT_SAFE,
3251
  OPT_BOOTSTRAP,               OPT_SKIP_SHOW_DB,
3252
  OPT_STORAGE_ENGINE,          OPT_INIT_FILE,
3253
  OPT_DELAY_KEY_WRITE_ALL,     OPT_SLOW_QUERY_LOG,
3254
  OPT_DELAY_KEY_WRITE,	       OPT_CHARSETS_DIR,
3255
  OPT_MASTER_INFO_FILE,
3256
  OPT_MASTER_RETRY_COUNT,      OPT_LOG_TC, OPT_LOG_TC_SIZE,
3257
  OPT_SQL_BIN_UPDATE_SAME,     OPT_REPLICATE_DO_DB,
3258
  OPT_REPLICATE_IGNORE_DB,     OPT_LOG_SLAVE_UPDATES,
3259
  OPT_BINLOG_DO_DB,            OPT_BINLOG_IGNORE_DB,
3260
  OPT_BINLOG_FORMAT,
3261
#ifndef DBUG_OFF
3262
  OPT_BINLOG_SHOW_XID,
3263
#endif
3264
  OPT_BINLOG_ROWS_EVENT_MAX_SIZE, 
3265
  OPT_WANT_CORE,
3266
  OPT_MEMLOCK,                 OPT_MYISAM_RECOVER,
3267
  OPT_REPLICATE_REWRITE_DB,    OPT_SERVER_ID,
3268
  OPT_SKIP_SLAVE_START,
3269
  OPT_REPLICATE_DO_TABLE,
3270
  OPT_REPLICATE_IGNORE_TABLE,  OPT_REPLICATE_WILD_DO_TABLE,
3271
  OPT_REPLICATE_WILD_IGNORE_TABLE, OPT_REPLICATE_SAME_SERVER_ID,
3272
  OPT_DISCONNECT_SLAVE_EVENT_COUNT, OPT_TC_HEURISTIC_RECOVER,
3273
  OPT_ABORT_SLAVE_EVENT_COUNT,
3274
  OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
3275
  OPT_ENGINE_CONDITION_PUSHDOWN, 
3276
  OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE,
3277
  OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
3278
  OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL,
3279
  OPT_SAFE_USER_CREATE,
3280
  OPT_DO_PSTACK, OPT_REPORT_HOST,
3281
  OPT_REPORT_USER, OPT_REPORT_PASSWORD, OPT_REPORT_PORT,
3282
  OPT_SHOW_SLAVE_AUTH_INFO,
3283
  OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE,
3284
  OPT_RPL_RECOVERY_RANK,
3285
  OPT_RELAY_LOG, OPT_RELAY_LOG_INDEX, OPT_RELAY_LOG_INFO_FILE,
3286
  OPT_SLAVE_SKIP_ERRORS, OPT_SLAVE_ALLOW_BATCHING, OPT_DES_KEY_FILE, OPT_LOCAL_INFILE,
3287
  OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA,
3288
  OPT_SSL_CAPATH, OPT_SSL_CIPHER,
3289
  OPT_BACK_LOG, OPT_BINLOG_CACHE_SIZE,
3290
  OPT_CONNECT_TIMEOUT,
3291
  OPT_FLUSH_TIME, OPT_FT_MIN_WORD_LEN, OPT_FT_BOOLEAN_SYNTAX,
3292
  OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE,
3293
  OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_BLOCK_SIZE,
3294
  OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_AGE_THRESHOLD,
3295
  OPT_LONG_QUERY_TIME,
3296
  OPT_LOWER_CASE_TABLE_NAMES, OPT_MAX_ALLOWED_PACKET,
3297
  OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE,
3298
  OPT_MAX_CONNECTIONS, OPT_MAX_CONNECT_ERRORS,
3299
  OPT_MAX_HEP_TABLE_SIZE,
3300
  OPT_MAX_JOIN_SIZE, OPT_MAX_PREPARED_STMT_COUNT,
3301
  OPT_MAX_RELAY_LOG_SIZE, OPT_MAX_SORT_LENGTH,
3302
  OPT_MAX_SEEKS_FOR_KEY, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS,
3303
  OPT_MAX_LENGTH_FOR_SORT_DATA,
3304
  OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE,
3305
  OPT_MAX_ERROR_COUNT, OPT_MULTI_RANGE_COUNT, OPT_MYISAM_DATA_POINTER_SIZE,
3306
  OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
3307
  OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
3308
  OPT_MYISAM_USE_MMAP, OPT_MYISAM_REPAIR_THREADS,
3309
  OPT_MYISAM_STATS_METHOD,
3310
  OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT,
3311
  OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT,
3312
  OPT_OPEN_FILES_LIMIT,
3313
  OPT_PRELOAD_BUFFER_SIZE,
3314
  OPT_QUERY_CACHE_LIMIT, OPT_QUERY_CACHE_MIN_RES_UNIT, OPT_QUERY_CACHE_SIZE,
3315
  OPT_QUERY_CACHE_TYPE, OPT_QUERY_CACHE_WLOCK_INVALIDATE, OPT_RECORD_BUFFER,
3316
  OPT_RECORD_RND_BUFFER, OPT_DIV_PRECINCREMENT, OPT_RELAY_LOG_SPACE_LIMIT,
3317
  OPT_RELAY_LOG_PURGE,
3318
  OPT_SLAVE_NET_TIMEOUT, OPT_SLAVE_COMPRESSED_PROTOCOL, OPT_SLOW_LAUNCH_TIME,
3319
  OPT_SLAVE_TRANS_RETRIES, OPT_READONLY, OPT_DEBUGGING,
3320
  OPT_SORT_BUFFER, OPT_TABLE_OPEN_CACHE, OPT_TABLE_DEF_CACHE,
3321
  OPT_THREAD_CONCURRENCY, OPT_THREAD_CACHE_SIZE,
3322
  OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK,
3323
  OPT_WAIT_TIMEOUT,
3324
  OPT_ERROR_LOG_FILE,
3325
  OPT_DEFAULT_WEEK_FORMAT,
3326
  OPT_RANGE_ALLOC_BLOCK_SIZE, OPT_ALLOW_SUSPICIOUS_UDFS,
3327
  OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE,
3328
  OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE,
3329
  OPT_SYNC_FRM, OPT_SYNC_BINLOG,
3330
  OPT_SYNC_REPLICATION,
3331
  OPT_SYNC_REPLICATION_SLAVE_ID,
3332
  OPT_SYNC_REPLICATION_TIMEOUT,
3333
  OPT_ENABLE_SHARED_MEMORY,
3334
  OPT_SHARED_MEMORY_BASE_NAME,
3335
  OPT_OLD_PASSWORDS,
3336
  OPT_OLD_ALTER_TABLE,
3337
  OPT_EXPIRE_LOGS_DAYS,
3338
  OPT_GROUP_CONCAT_MAX_LEN,
3339
  OPT_DEFAULT_COLLATION,
3340
  OPT_CHARACTER_SET_CLIENT_HANDSHAKE,
3341
  OPT_CHARACTER_SET_FILESYSTEM,
3342
  OPT_LC_TIME_NAMES,
3343
  OPT_INIT_CONNECT,
3344
  OPT_INIT_SLAVE,
3345
  OPT_SECURE_AUTH,
3346
  OPT_DATE_FORMAT,
3347
  OPT_TIME_FORMAT,
3348
  OPT_DATETIME_FORMAT,
3349
  OPT_LOG_QUERIES_NOT_USING_INDEXES,
3350
  OPT_DEFAULT_TIME_ZONE,
3351
  OPT_SYSDATE_IS_NOW,
3352
  OPT_OPTIMIZER_SEARCH_DEPTH,
3353
  OPT_OPTIMIZER_PRUNE_LEVEL,
3354
  OPT_UPDATABLE_VIEWS_WITH_LIMIT,
3355
  OPT_AUTO_INCREMENT, OPT_AUTO_INCREMENT_OFFSET,
3356
  OPT_ENABLE_LARGE_PAGES,
3357
  OPT_TIMED_MUTEXES,
3358
  OPT_OLD_STYLE_USER_LIMITS,
3359
  OPT_LOG_SLOW_ADMIN_STATEMENTS,
3360
  OPT_TABLE_LOCK_WAIT_TIMEOUT,
3361
  OPT_PLUGIN_LOAD,
3362
  OPT_PLUGIN_DIR,
3363
  OPT_LOG_OUTPUT,
3364
  OPT_PORT_OPEN_TIMEOUT,
3365
  OPT_PROFILING,
3366
  OPT_KEEP_FILES_ON_CREATE,
3367
  OPT_GENERAL_LOG,
3368
  OPT_SLOW_LOG,
3369
  OPT_THREAD_HANDLING,
3370
  OPT_INNODB_ROLLBACK_ON_TIMEOUT,
3371
  OPT_SECURE_FILE_PRIV,
3372
  OPT_MIN_EXAMINED_ROW_LIMIT,
3373
  OPT_LOG_SLOW_SLAVE_STATEMENTS,
3374
  OPT_OLD_MODE,
3375
  OPT_POOL_OF_THREADS,
3376
  OPT_SLAVE_EXEC_MODE
3377
};
3378
3379
3380
#define LONG_TIMEOUT ((ulong) 3600L*24L*365L)
3381
3382
struct my_option my_long_options[] =
3383
{
3384
  {"help", '?', "Display this help and exit.", 
3385
   (uchar**) &opt_help, (uchar**) &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
3386
   0, 0},
3387
  {"abort-slave-event-count", OPT_ABORT_SLAVE_EVENT_COUNT,
3388
   "Option used by mysql-test for debugging and testing of replication.",
3389
   (uchar**) &abort_slave_event_count,  (uchar**) &abort_slave_event_count,
3390
   0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3391
  {"allow-suspicious-udfs", OPT_ALLOW_SUSPICIOUS_UDFS,
3392
   "Allows use of UDFs consisting of only one symbol xxx() "
3393
   "without corresponding xxx_init() or xxx_deinit(). That also means "
3394
   "that one can load any function from any library, for example exit() "
3395
   "from libc.so",
3396
   (uchar**) &opt_allow_suspicious_udfs, (uchar**) &opt_allow_suspicious_udfs,
3397
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3398
  {"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax. This mode will also set transaction isolation level 'serializable'.", 0, 0, 0,
3399
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
3400
  {"auto-increment-increment", OPT_AUTO_INCREMENT,
3401
   "Auto-increment columns are incremented by this",
3402
   (uchar**) &global_system_variables.auto_increment_increment,
3403
   (uchar**) &max_system_variables.auto_increment_increment, 0, GET_ULONG,
3404
   OPT_ARG, 1, 1, 65535, 0, 1, 0 },
3405
  {"auto-increment-offset", OPT_AUTO_INCREMENT_OFFSET,
3406
   "Offset added to Auto-increment columns. Used when auto-increment-increment != 1",
3407
   (uchar**) &global_system_variables.auto_increment_offset,
3408
   (uchar**) &max_system_variables.auto_increment_offset, 0, GET_ULONG, OPT_ARG,
3409
   1, 1, 65535, 0, 1, 0 },
3410
  {"basedir", 'b',
3411
   "Path to installation directory. All paths are usually resolved relative to this.",
3412
   (uchar**) &mysql_home_ptr, (uchar**) &mysql_home_ptr, 0, GET_STR, REQUIRED_ARG,
3413
   0, 0, 0, 0, 0, 0},
3414
  {"big-tables", OPT_BIG_TABLES,
3415
   "Allow big result sets by saving all temporary sets on file (Solves most 'table full' errors).",
3416
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
3417
  {"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
3418
   (uchar**) &my_bind_addr_str, (uchar**) &my_bind_addr_str, 0, GET_STR,
3419
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3420
  {"binlog_format", OPT_BINLOG_FORMAT,
3421
   "Does not have any effect without '--log-bin'. "
3422
   "Tell the master the form of binary logging to use: either 'row' for "
3423
   "row-based binary logging, or 'statement' for statement-based binary "
3424
   "logging, or 'mixed'. 'mixed' is statement-based binary logging except "
3425
   "for those statements where only row-based is correct: those which "
3426
   "involve user-defined functions (i.e. UDFs) or the UUID() function; for "
3427
   "those, row-based binary logging is automatically used. "
3428
   ,(uchar**) &opt_binlog_format, (uchar**) &opt_binlog_format,
3429
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3430
  {"binlog-do-db", OPT_BINLOG_DO_DB,
3431
   "Tells the master it should log updates for the specified database, and exclude all others not explicitly mentioned.",
3432
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3433
  {"binlog-ignore-db", OPT_BINLOG_IGNORE_DB,
3434
   "Tells the master that updates to the given database should not be logged tothe binary log.",
3435
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3436
  {"binlog-row-event-max-size", OPT_BINLOG_ROWS_EVENT_MAX_SIZE,
3437
   "The maximum size of a row-based binary log event in bytes. Rows will be "
3438
   "grouped into events smaller than this size if possible. "
3439
   "The value has to be a multiple of 256.",
3440
   (uchar**) &opt_binlog_rows_event_max_size, 
3441
   (uchar**) &opt_binlog_rows_event_max_size, 0, 
3442
   GET_ULONG, REQUIRED_ARG, 
3443
   /* def_value */ 1024, /* min_value */  256, /* max_value */ ULONG_MAX, 
3444
   /* sub_size */     0, /* block_size */ 256, 
3445
   /* app_type */ 0
3446
  },
3447
#ifndef DISABLE_GRANT_OPTIONS
3448
  {"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts.", 0, 0, 0,
3449
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
3450
#endif
3451
  {"character-set-client-handshake", OPT_CHARACTER_SET_CLIENT_HANDSHAKE,
3452
   "Don't ignore client side character set value sent during handshake.",
3453
   (uchar**) &opt_character_set_client_handshake,
3454
   (uchar**) &opt_character_set_client_handshake,
3455
    0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
3456
  {"character-set-filesystem", OPT_CHARACTER_SET_FILESYSTEM,
3457
   "Set the filesystem character set.",
3458
   (uchar**) &character_set_filesystem_name,
3459
   (uchar**) &character_set_filesystem_name,
3460
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
3461
  {"character-set-server", 'C', "Set the default character set.",
3462
   (uchar**) &default_character_set_name, (uchar**) &default_character_set_name,
3463
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
3464
  {"character-sets-dir", OPT_CHARSETS_DIR,
3465
   "Directory where character sets are.", (uchar**) &charsets_dir,
3466
   (uchar**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3467
  {"chroot", 'r', "Chroot mysqld daemon during startup.",
3468
   (uchar**) &mysqld_chroot, (uchar**) &mysqld_chroot, 0, GET_STR, REQUIRED_ARG,
3469
   0, 0, 0, 0, 0, 0},
3470
  {"collation-server", OPT_DEFAULT_COLLATION, "Set the default collation.",
3471
   (uchar**) &default_collation_name, (uchar**) &default_collation_name,
3472
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
3473
  {"completion-type", OPT_COMPLETION_TYPE, "Default completion type.",
3474
   (uchar**) &global_system_variables.completion_type,
3475
   (uchar**) &max_system_variables.completion_type, 0, GET_ULONG,
3476
   REQUIRED_ARG, 0, 0, 2, 0, 1, 0},
3477
  {"console", OPT_CONSOLE, "Write error output on screen; Don't remove the console window on windows.",
3478
   (uchar**) &opt_console, (uchar**) &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0,
3479
   0, 0, 0},
3480
  {"core-file", OPT_WANT_CORE, "Write core on errors.", 0, 0, 0, GET_NO_ARG,
3481
   NO_ARG, 0, 0, 0, 0, 0, 0},
3482
  {"datadir", 'h', "Path to the database root.", (uchar**) &mysql_data_home,
3483
   (uchar**) &mysql_data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3484
#ifndef DBUG_OFF
3485
  {"debug", '#', "Debug log.", (uchar**) &default_dbug_option,
3486
   (uchar**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
3487
#endif
3488
  {"default-character-set", 'C', "Set the default character set (deprecated option, use --character-set-server instead).",
3489
   (uchar**) &default_character_set_name, (uchar**) &default_character_set_name,
3490
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
3491
  {"default-collation", OPT_DEFAULT_COLLATION, "Set the default collation (deprecated option, use --collation-server instead).",
3492
   (uchar**) &default_collation_name, (uchar**) &default_collation_name,
3493
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
3494
  {"default-storage-engine", OPT_STORAGE_ENGINE,
3495
   "Set the default storage engine (table type) for tables.",
3496
   (uchar**)&default_storage_engine_str, (uchar**)&default_storage_engine_str,
3497
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3498
  {"default-table-type", OPT_STORAGE_ENGINE,
3499
   "(deprecated) Use --default-storage-engine.",
3500
   (uchar**)&default_storage_engine_str, (uchar**)&default_storage_engine_str,
3501
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3502
  {"default-time-zone", OPT_DEFAULT_TIME_ZONE, "Set the default time zone.",
3503
   (uchar**) &default_tz_name, (uchar**) &default_tz_name,
3504
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
3505
  {"delay-key-write", OPT_DELAY_KEY_WRITE, "Type of DELAY_KEY_WRITE.",
3506
   0,0,0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
3507
  {"delay-key-write-for-all-tables", OPT_DELAY_KEY_WRITE_ALL,
3508
   "Don't flush key buffers between writes for any MyISAM table (Deprecated option, use --delay-key-write=all instead).",
3509
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
3510
  {"disconnect-slave-event-count", OPT_DISCONNECT_SLAVE_EVENT_COUNT,
3511
   "Option used by mysql-test for debugging and testing of replication.",
3512
   (uchar**) &disconnect_slave_event_count,
3513
   (uchar**) &disconnect_slave_event_count, 0, GET_INT, REQUIRED_ARG, 0, 0, 0,
3514
   0, 0, 0},
3515
#ifdef HAVE_STACK_TRACE_ON_SEGV
3516
  {"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure.",
3517
   (uchar**) &opt_do_pstack, (uchar**) &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0,
3518
   0, 0, 0, 0},
3519
#endif /* HAVE_STACK_TRACE_ON_SEGV */
3520
  {"engine-condition-pushdown",
3521
   OPT_ENGINE_CONDITION_PUSHDOWN,
3522
   "Push supported query conditions to the storage engine.",
3523
   (uchar**) &global_system_variables.engine_condition_pushdown,
3524
   (uchar**) &global_system_variables.engine_condition_pushdown,
3525
   0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
3526
  /* See how it's handled in get_one_option() */
3527
  {"exit-info", 'T', "Used for debugging;  Use at your own risk!", 0, 0, 0,
3528
   GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
3529
  {"flush", OPT_FLUSH, "Flush tables to disk between SQL commands.", 0, 0, 0,
3530
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
3531
  /* We must always support the next option to make scripts like mysqltest
3532
     easier to do */
3533
  {"gdb", OPT_DEBUGGING,
3534
   "Set up signals usable for debugging",
3535
   (uchar**) &opt_debugging, (uchar**) &opt_debugging,
3536
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3537
  {"general-log", OPT_GENERAL_LOG,
3538
   "Enable|disable general log", (uchar**) &opt_log,
3539
   (uchar**) &opt_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
3540
  {"init-connect", OPT_INIT_CONNECT, "Command(s) that are executed for each new connection",
3541
   (uchar**) &opt_init_connect, (uchar**) &opt_init_connect, 0, GET_STR_ALLOC,
3542
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3543
  {"init-file", OPT_INIT_FILE, "Read SQL commands from this file at startup.",
3544
   (uchar**) &opt_init_file, (uchar**) &opt_init_file, 0, GET_STR, REQUIRED_ARG,
3545
   0, 0, 0, 0, 0, 0},
3546
  {"init-slave", OPT_INIT_SLAVE, "Command(s) that are executed when a slave connects to this master",
3547
   (uchar**) &opt_init_slave, (uchar**) &opt_init_slave, 0, GET_STR_ALLOC,
3548
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3549
  {"language", 'L',
3550
   "Client error messages in given language. May be given as a full path.",
3551
   (uchar**) &language_ptr, (uchar**) &language_ptr, 0, GET_STR, REQUIRED_ARG,
3552
   0, 0, 0, 0, 0, 0},
3553
  {"lc-time-names", OPT_LC_TIME_NAMES,
3554
   "Set the language used for the month names and the days of the week.",
3555
   (uchar**) &lc_time_names_name,
3556
   (uchar**) &lc_time_names_name,
3557
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
3558
  {"local-infile", OPT_LOCAL_INFILE,
3559
   "Enable/disable LOAD DATA LOCAL INFILE (takes values 1|0).",
3560
   (uchar**) &opt_local_infile,
3561
   (uchar**) &opt_local_infile, 0, GET_BOOL, OPT_ARG,
3562
   1, 0, 0, 0, 0, 0},
3563
  {"log", 'l', "Log connections and queries to file.", (uchar**) &opt_logname,
3564
   (uchar**) &opt_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
3565
  {"log-bin", OPT_BIN_LOG,
3566
   "Log update queries in binary format. Optional (but strongly recommended "
3567
   "to avoid replication problems if server's hostname changes) argument "
3568
   "should be the chosen location for the binary log files.",
3569
   (uchar**) &opt_bin_logname, (uchar**) &opt_bin_logname, 0, GET_STR_ALLOC,
3570
   OPT_ARG, 0, 0, 0, 0, 0, 0},
3571
  {"log-bin-index", OPT_BIN_LOG_INDEX,
3572
   "File that holds the names for last binary log files.",
3573
   (uchar**) &opt_binlog_index_name, (uchar**) &opt_binlog_index_name, 0, GET_STR,
3574
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3575
  /*
3576
    This option starts with "log-bin" to emphasize that it is specific of
3577
    binary logging.
3578
  */
3579
  {"log-bin-trust-function-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
3580
   "If equal to 0 (the default), then when --log-bin is used, creation of "
3581
   "a stored function (or trigger) is allowed only to users having the SUPER privilege "
3582
   "and only if this stored function (trigger) may not break binary logging."
3583
   "Note that if ALL connections to this server ALWAYS use row-based binary "
3584
   "logging, the security issues do not exist and the binary logging cannot "
3585
   "break, so you can safely set this to 1."
3586
   ,(uchar**) &trust_function_creators, (uchar**) &trust_function_creators, 0,
3587
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3588
  {"log-error", OPT_ERROR_LOG_FILE, "Error log file.",
3589
   (uchar**) &log_error_file_ptr, (uchar**) &log_error_file_ptr, 0, GET_STR,
3590
   OPT_ARG, 0, 0, 0, 0, 0, 0},
3591
  {"log-isam", OPT_ISAM_LOG, "Log all MyISAM changes to file.",
3592
   (uchar**) &myisam_log_filename, (uchar**) &myisam_log_filename, 0, GET_STR,
3593
   OPT_ARG, 0, 0, 0, 0, 0, 0},
3594
  {"log-long-format", '0',
3595
   "Log some extra information to update log. Please note that this option is deprecated; see --log-short-format option.", 
3596
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
3597
#ifdef WITH_CSV_STORAGE_ENGINE
3598
  {"log-output", OPT_LOG_OUTPUT,
3599
   "Syntax: log-output[=value[,value...]], where \"value\" could be TABLE, "
3600
   "FILE or NONE.",
3601
   (uchar**) &log_output_str, (uchar**) &log_output_str, 0,
3602
   GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
3603
#endif
3604
  {"log-queries-not-using-indexes", OPT_LOG_QUERIES_NOT_USING_INDEXES,
3605
   "Log queries that are executed without benefit of any index to the slow log if it is open.",
3606
   (uchar**) &opt_log_queries_not_using_indexes, (uchar**) &opt_log_queries_not_using_indexes,
3607
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3608
  {"log-short-format", OPT_SHORT_LOG_FORMAT,
3609
   "Don't log extra information to update and slow-query logs.",
3610
   (uchar**) &opt_short_log_format, (uchar**) &opt_short_log_format,
3611
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3612
  {"log-slave-updates", OPT_LOG_SLAVE_UPDATES,
3613
   "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.",
3614
   (uchar**) &opt_log_slave_updates, (uchar**) &opt_log_slave_updates, 0, GET_BOOL,
3615
   NO_ARG, 0, 0, 0, 0, 0, 0},
3616
  {"log-slow-admin-statements", OPT_LOG_SLOW_ADMIN_STATEMENTS,
3617
   "Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements to the slow log if it is open.",
3618
   (uchar**) &opt_log_slow_admin_statements,
3619
   (uchar**) &opt_log_slow_admin_statements,
3620
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3621
 {"log-slow-slave-statements", OPT_LOG_SLOW_SLAVE_STATEMENTS,
3622
  "Log slow statements executed by slave thread to the slow log if it is open.",
3623
  (uchar**) &opt_log_slow_slave_statements,
3624
  (uchar**) &opt_log_slow_slave_statements,
3625
  0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3626
  {"log-slow-queries", OPT_SLOW_QUERY_LOG,
3627
    "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.",
3628
   (uchar**) &opt_slow_logname, (uchar**) &opt_slow_logname, 0, GET_STR, OPT_ARG,
3629
   0, 0, 0, 0, 0, 0},
3630
  {"log-tc", OPT_LOG_TC,
3631
   "Path to transaction coordinator log (used for transactions that affect "
3632
   "more than one storage engine, when binary log is disabled)",
3633
   (uchar**) &opt_tc_log_file, (uchar**) &opt_tc_log_file, 0, GET_STR,
3634
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3635
#ifdef HAVE_MMAP
3636
  {"log-tc-size", OPT_LOG_TC_SIZE, "Size of transaction coordinator log.",
3637
   (uchar**) &opt_tc_log_size, (uchar**) &opt_tc_log_size, 0, GET_ULONG,
3638
   REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, ULONG_MAX, 0,
3639
   TC_LOG_PAGE_SIZE, 0},
3640
#endif
3641
  {"log-update", OPT_UPDATE_LOG,
3642
   "The update log is deprecated since version 5.0, is replaced by the binary \
3643
log and this option justs turns on --log-bin instead.",
3644
   (uchar**) &opt_update_logname, (uchar**) &opt_update_logname, 0, GET_STR,
3645
   OPT_ARG, 0, 0, 0, 0, 0, 0},
3646
  {"log-warnings", 'W', "Log some not critical warnings to the log file.",
3647
   (uchar**) &global_system_variables.log_warnings,
3648
   (uchar**) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0,
3649
   0, 0, 0},
3650
  {"low-priority-updates", OPT_LOW_PRIORITY_UPDATES,
3651
   "INSERT/DELETE/UPDATE has lower priority than selects.",
3652
   (uchar**) &global_system_variables.low_priority_updates,
3653
   (uchar**) &max_system_variables.low_priority_updates,
3654
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3655
  {"master-info-file", OPT_MASTER_INFO_FILE,
3656
   "The location and name of the file that remembers the master and where the I/O replication \
3657
thread is in the master's binlogs.",
3658
   (uchar**) &master_info_file, (uchar**) &master_info_file, 0, GET_STR,
3659
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3660
  {"master-retry-count", OPT_MASTER_RETRY_COUNT,
3661
   "The number of tries the slave will make to connect to the master before giving up.",
3662
   (uchar**) &master_retry_count, (uchar**) &master_retry_count, 0, GET_ULONG,
3663
   REQUIRED_ARG, 3600*24, 0, 0, 0, 0, 0},
3664
  {"max-binlog-dump-events", OPT_MAX_BINLOG_DUMP_EVENTS,
3665
   "Option used by mysql-test for debugging and testing of replication.",
3666
   (uchar**) &max_binlog_dump_events, (uchar**) &max_binlog_dump_events, 0,
3667
   GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3668
  {"memlock", OPT_MEMLOCK, "Lock mysqld in memory.", (uchar**) &locked_in_memory,
3669
   (uchar**) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3670
  {"myisam-recover", OPT_MYISAM_RECOVER,
3671
   "Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.",
3672
   (uchar**) &myisam_recover_options_str, (uchar**) &myisam_recover_options_str, 0,
3673
   GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
3674
  {"new", 'n', "Use very new possible 'unsafe' functions.",
3675
   (uchar**) &global_system_variables.new_mode,
3676
   (uchar**) &max_system_variables.new_mode,
3677
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3678
  {"old-alter-table", OPT_OLD_ALTER_TABLE,
3679
   "Use old, non-optimized alter table.",
3680
   (uchar**) &global_system_variables.old_alter_table,
3681
   (uchar**) &max_system_variables.old_alter_table, 0, GET_BOOL, NO_ARG,
3682
   0, 0, 0, 0, 0, 0},
3683
  {"old-passwords", OPT_OLD_PASSWORDS, "Use old password encryption method (needed for 4.0 and older clients).",
3684
   (uchar**) &global_system_variables.old_passwords,
3685
   (uchar**) &max_system_variables.old_passwords, 0, GET_BOOL, NO_ARG,
3686
   0, 0, 0, 0, 0, 0},
3687
  {"old-style-user-limits", OPT_OLD_STYLE_USER_LIMITS,
3688
   "Enable old-style user limits (before 5.0.3 user resources were counted per each user+host vs. per account)",
3689
   (uchar**) &opt_old_style_user_limits, (uchar**) &opt_old_style_user_limits,
3690
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3691
  {"pid-file", OPT_PID_FILE, "Pid file used by safe_mysqld.",
3692
   (uchar**) &pidfile_name_ptr, (uchar**) &pidfile_name_ptr, 0, GET_STR,
3693
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3694
  {"port", 'P', "Port number to use for connection or 0 for default to, in "
3695
   "order of preference, my.cnf, $MYSQL_TCP_PORT, "
3696
#if MYSQL_PORT_DEFAULT == 0
3697
   "/etc/services, "
3698
#endif
3699
   "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
3700
   (uchar**) &mysqld_port,
3701
   (uchar**) &mysqld_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3702
  {"port-open-timeout", OPT_PORT_OPEN_TIMEOUT,
3703
   "Maximum time in seconds to wait for the port to become free. "
3704
   "(Default: no wait)", (uchar**) &mysqld_port_timeout,
3705
   (uchar**) &mysqld_port_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3706
  {"relay-log", OPT_RELAY_LOG,
3707
   "The location and name to use for relay logs.",
3708
   (uchar**) &opt_relay_logname, (uchar**) &opt_relay_logname, 0,
3709
   GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3710
  {"relay-log-index", OPT_RELAY_LOG_INDEX,
3711
   "The location and name to use for the file that keeps a list of the last \
3712
relay logs.",
3713
   (uchar**) &opt_relaylog_index_name, (uchar**) &opt_relaylog_index_name, 0,
3714
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3715
  {"relay-log-info-file", OPT_RELAY_LOG_INFO_FILE,
3716
   "The location and name of the file that remembers where the SQL replication \
3717
thread is in the relay logs.",
3718
   (uchar**) &relay_log_info_file, (uchar**) &relay_log_info_file, 0, GET_STR,
3719
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3720
  {"replicate-do-db", OPT_REPLICATE_DO_DB,
3721
   "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.%.",
3722
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3723
  {"replicate-do-table", OPT_REPLICATE_DO_TABLE,
3724
   "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.",
3725
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3726
  {"replicate-ignore-db", OPT_REPLICATE_IGNORE_DB,
3727
   "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.%. ",
3728
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3729
  {"replicate-ignore-table", OPT_REPLICATE_IGNORE_TABLE,
3730
   "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.",
3731
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3732
  {"replicate-rewrite-db", OPT_REPLICATE_REWRITE_DB,
3733
   "Updates to a database with a different name than the original. Example: replicate-rewrite-db=master_db_name->slave_db_name.",
3734
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3735
  {"replicate-same-server-id", OPT_REPLICATE_SAME_SERVER_ID,
3736
   "In replication, if set to 1, do not skip events having our server id. \
3737
Default value is 0 (to break infinite loops in circular replication). \
3738
Can't be set to 1 if --log-slave-updates is used.",
3739
   (uchar**) &replicate_same_server_id,
3740
   (uchar**) &replicate_same_server_id,
3741
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3742
  {"replicate-wild-do-table", OPT_REPLICATE_WILD_DO_TABLE,
3743
   "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.",
3744
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3745
  {"replicate-wild-ignore-table", OPT_REPLICATE_WILD_IGNORE_TABLE,
3746
   "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.",
3747
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3748
  // In replication, we may need to tell the other servers how to connect
3749
  {"report-host", OPT_REPORT_HOST,
3750
   "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.",
3751
   (uchar**) &report_host, (uchar**) &report_host, 0, GET_STR, REQUIRED_ARG, 0, 0,
3752
   0, 0, 0, 0},
3753
  {"report-password", OPT_REPORT_PASSWORD, "Undocumented.",
3754
   (uchar**) &report_password, (uchar**) &report_password, 0, GET_STR,
3755
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3756
  {"report-port", OPT_REPORT_PORT,
3757
   "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.",
3758
   (uchar**) &report_port, (uchar**) &report_port, 0, GET_UINT, REQUIRED_ARG,
3759
   MYSQL_PORT, 0, 0, 0, 0, 0},
3760
  {"safe-mode", OPT_SAFE, "Skip some optimize stages (for testing).",
3761
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
3762
  {"secure-file-priv", OPT_SECURE_FILE_PRIV,
3763
   "Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files within specified directory",
3764
   (uchar**) &opt_secure_file_priv, (uchar**) &opt_secure_file_priv, 0,
3765
   GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3766
  {"server-id",	OPT_SERVER_ID,
3767
   "Uniquely identifies the server instance in the community of replication partners.",
3768
   (uchar**) &server_id, (uchar**) &server_id, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 0,
3769
   0, 0, 0},
3770
  {"set-variable", 'O',
3771
   "Change the value of a variable. Please note that this option is deprecated;you can set variables directly with --variable-name=value.",
3772
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3773
  {"skip-new", OPT_SKIP_NEW, "Don't use new, possible wrong routines.",
3774
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
3775
  {"skip-slave-start", OPT_SKIP_SLAVE_START,
3776
   "If set, slave is not autostarted.", (uchar**) &opt_skip_slave_start,
3777
   (uchar**) &opt_skip_slave_start, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
3778
  {"skip-stack-trace", OPT_SKIP_STACK_TRACE,
3779
   "Don't print a stack trace on failure.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
3780
   0, 0, 0, 0},
3781
  {"skip-symlink", OPT_SKIP_SYMLINKS, "Don't allow symlinking of tables. Deprecated option.  Use --skip-symbolic-links instead.",
3782
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
3783
  {"skip-thread-priority", OPT_SKIP_PRIOR,
3784
   "Don't give threads different priorities.", 0, 0, 0, GET_NO_ARG, NO_ARG,
3785
   DEFAULT_SKIP_THREAD_PRIORITY, 0, 0, 0, 0, 0},
3786
  {"slave-load-tmpdir", OPT_SLAVE_LOAD_TMPDIR,
3787
   "The location where the slave should put its temporary files when \
3788
replicating a LOAD DATA INFILE command.",
3789
   (uchar**) &slave_load_tmpdir, (uchar**) &slave_load_tmpdir, 0, GET_STR_ALLOC,
3790
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3791
  {"slave-skip-errors", OPT_SLAVE_SKIP_ERRORS,
3792
   "Tells the slave thread to continue replication when a query event returns an error from the provided list.",
3793
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3794
  {"slave-exec-mode", OPT_SLAVE_EXEC_MODE,
3795
   "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.",
3796
   (uchar**) &slave_exec_mode_str, (uchar**) &slave_exec_mode_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3797
  {"slow-query-log", OPT_SLOW_LOG,
3798
   "Enable|disable slow query log", (uchar**) &opt_slow_log,
3799
   (uchar**) &opt_slow_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
3800
  {"sporadic-binlog-dump-fail", OPT_SPORADIC_BINLOG_DUMP_FAIL,
3801
   "Option used by mysql-test for debugging and testing of replication.",
3802
   (uchar**) &opt_sporadic_binlog_dump_fail,
3803
   (uchar**) &opt_sporadic_binlog_dump_fail, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
3804
   0},
3805
  {"sql-bin-update-same", OPT_SQL_BIN_UPDATE_SAME,
3806
   "The update log is deprecated since version 5.0, is replaced by the binary \
3807
log and this option does nothing anymore.",
3808
   0, 0, 0, GET_DISABLED, NO_ARG, 0, 0, 0, 0, 0, 0},
3809
  {"symbolic-links", 's', "Enable symbolic link support.",
3810
   (uchar**) &my_use_symdir, (uchar**) &my_use_symdir, 0, GET_BOOL, NO_ARG,
3811
   /*
3812
     The system call realpath() produces warnings under valgrind and
3813
     purify. These are not suppressed: instead we disable symlinks
3814
     option if compiled with valgrind support.
3815
   */
3816
   IF_PURIFY(0,1), 0, 0, 0, 0, 0},
3817
  {"sysdate-is-now", OPT_SYSDATE_IS_NOW,
3818
   "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.",
3819
   (uchar**) &global_system_variables.sysdate_is_now,
3820
   0, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
3821
  {"tc-heuristic-recover", OPT_TC_HEURISTIC_RECOVER,
3822
   "Decision to use in heuristic recover process. Possible values are COMMIT or ROLLBACK.",
3823
   (uchar**) &opt_tc_heuristic_recover, (uchar**) &opt_tc_heuristic_recover,
3824
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3825
  {"temp-pool", OPT_TEMP_POOL,
3826
   "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.",
3827
   (uchar**) &use_temp_pool, (uchar**) &use_temp_pool, 0, GET_BOOL, NO_ARG, 1,
3828
   0, 0, 0, 0, 0},
3829
  {"timed_mutexes", OPT_TIMED_MUTEXES,
3830
   "Specify whether to time mutexes (only InnoDB mutexes are currently supported)",
3831
   (uchar**) &timed_mutexes, (uchar**) &timed_mutexes, 0, GET_BOOL, NO_ARG, 0, 
3832
    0, 0, 0, 0, 0},
3833
  {"tmpdir", 't',
3834
   "Path for temporary files. Several paths may be specified, separated by a "
3835
   "colon (:)"
3836
   ", in this case they are used in a round-robin fashion.",
3837
   (uchar**) &opt_mysql_tmpdir,
3838
   (uchar**) &opt_mysql_tmpdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3839
  {"transaction-isolation", OPT_TX_ISOLATION,
3840
   "Default transaction isolation level.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0,
3841
   0, 0, 0, 0, 0},
3842
  {"use-symbolic-links", 's', "Enable symbolic link support. Deprecated option; use --symbolic-links instead.",
3843
   (uchar**) &my_use_symdir, (uchar**) &my_use_symdir, 0, GET_BOOL, NO_ARG,
3844
   IF_PURIFY(0,1), 0, 0, 0, 0, 0},
3845
  {"user", 'u', "Run mysqld daemon as user.", 0, 0, 0, GET_STR, REQUIRED_ARG,
3846
   0, 0, 0, 0, 0, 0},
3847
  {"verbose", 'v', "Used with --help option for detailed help",
3848
   (uchar**) &opt_verbose, (uchar**) &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
3849
   0, 0},
3850
  {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
3851
   NO_ARG, 0, 0, 0, 0, 0, 0},
3852
  {"warnings", 'W', "Deprecated; use --log-warnings instead.",
3853
   (uchar**) &global_system_variables.log_warnings,
3854
   (uchar**) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG,
3855
   1, 0, ULONG_MAX, 0, 0, 0},
3856
  { "back_log", OPT_BACK_LOG,
3857
    "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.",
3858
    (uchar**) &back_log, (uchar**) &back_log, 0, GET_ULONG,
3859
    REQUIRED_ARG, 50, 1, 65535, 0, 1, 0 },
3860
  {"binlog_cache_size", OPT_BINLOG_CACHE_SIZE,
3861
   "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.",
3862
   (uchar**) &binlog_cache_size, (uchar**) &binlog_cache_size, 0, GET_ULONG,
3863
   REQUIRED_ARG, 32*1024L, IO_SIZE, ULONG_MAX, 0, IO_SIZE, 0},
3864
  {"bulk_insert_buffer_size", OPT_BULK_INSERT_BUFFER_SIZE,
3865
   "Size of tree cache used in bulk insert optimisation. Note that this is a limit per thread!",
3866
   (uchar**) &global_system_variables.bulk_insert_buff_size,
3867
   (uchar**) &max_system_variables.bulk_insert_buff_size,
3868
   0, GET_ULONG, REQUIRED_ARG, 8192*1024, 0, ULONG_MAX, 0, 1, 0},
3869
  {"connect_timeout", OPT_CONNECT_TIMEOUT,
3870
   "The number of seconds the mysqld server is waiting for a connect packet before responding with 'Bad handshake'.",
3871
    (uchar**) &connect_timeout, (uchar**) &connect_timeout,
3872
   0, GET_ULONG, REQUIRED_ARG, CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1, 0 },
3873
  { "date_format", OPT_DATE_FORMAT,
3874
    "The DATE format (For future).",
3875
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_DATE],
3876
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_DATE],
3877
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3878
  { "datetime_format", OPT_DATETIME_FORMAT,
3879
    "The DATETIME/TIMESTAMP format (for future).",
3880
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME],
3881
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME],
3882
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
3883
  { "default_week_format", OPT_DEFAULT_WEEK_FORMAT,
3884
    "The default week format used by WEEK() functions.",
3885
    (uchar**) &global_system_variables.default_week_format,
3886
    (uchar**) &max_system_variables.default_week_format,
3887
    0, GET_ULONG, REQUIRED_ARG, 0, 0, 7L, 0, 1, 0},
3888
  {"div_precision_increment", OPT_DIV_PRECINCREMENT,
3889
   "Precision of the result of '/' operator will be increased on that value.",
3890
   (uchar**) &global_system_variables.div_precincrement,
3891
   (uchar**) &max_system_variables.div_precincrement, 0, GET_ULONG,
3892
   REQUIRED_ARG, 4, 0, DECIMAL_MAX_SCALE, 0, 0, 0},
3893
  {"expire_logs_days", OPT_EXPIRE_LOGS_DAYS,
3894
   "If non-zero, binary logs will be purged after expire_logs_days "
3895
   "days; possible purges happen at startup and at binary log rotation.",
3896
   (uchar**) &expire_logs_days,
3897
   (uchar**) &expire_logs_days, 0, GET_ULONG,
3898
   REQUIRED_ARG, 0, 0, 99, 0, 1, 0},
3899
  { "flush_time", OPT_FLUSH_TIME,
3900
    "A dedicated thread is created to flush all tables at the given interval.",
3901
    (uchar**) &flush_time, (uchar**) &flush_time, 0, GET_ULONG, REQUIRED_ARG,
3902
    FLUSH_TIME, 0, LONG_TIMEOUT, 0, 1, 0},
3903
  { "group_concat_max_len", OPT_GROUP_CONCAT_MAX_LEN,
3904
    "The maximum length of the result of function  group_concat.",
3905
    (uchar**) &global_system_variables.group_concat_max_len,
3906
    (uchar**) &max_system_variables.group_concat_max_len, 0, GET_ULONG,
3907
    REQUIRED_ARG, 1024, 4, ULONG_MAX, 0, 1, 0},
3908
  {"interactive_timeout", OPT_INTERACTIVE_TIMEOUT,
3909
   "The number of seconds the server waits for activity on an interactive connection before closing it.",
3910
   (uchar**) &global_system_variables.net_interactive_timeout,
3911
   (uchar**) &max_system_variables.net_interactive_timeout, 0,
3912
   GET_ULONG, REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
3913
  {"join_buffer_size", OPT_JOIN_BUFF_SIZE,
3914
   "The size of the buffer that is used for full joins.",
3915
   (uchar**) &global_system_variables.join_buff_size,
3916
   (uchar**) &max_system_variables.join_buff_size, 0, GET_ULONG,
3917
   REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ULONG_MAX,
3918
   MALLOC_OVERHEAD, IO_SIZE, 0},
3919
  {"keep_files_on_create", OPT_KEEP_FILES_ON_CREATE,
3920
   "Don't overwrite stale .MYD and .MYI even if no directory is specified.",
3921
   (uchar**) &global_system_variables.keep_files_on_create,
3922
   (uchar**) &max_system_variables.keep_files_on_create,
3923
   0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
3924
  {"key_buffer_size", OPT_KEY_BUFFER_SIZE,
3925
   "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.",
3926
   (uchar**) &dflt_key_cache_var.param_buff_size,
3927
   (uchar**) 0,
3928
   0, (GET_ULL | GET_ASK_ADDR),
3929
   REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, SIZE_T_MAX, MALLOC_OVERHEAD,
3930
   IO_SIZE, 0},
3931
  {"key_cache_age_threshold", OPT_KEY_CACHE_AGE_THRESHOLD,
3932
   "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",
3933
   (uchar**) &dflt_key_cache_var.param_age_threshold,
3934
   (uchar**) 0,
3935
   0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG, 
3936
   300, 100, ULONG_MAX, 0, 100, 0},
3937
  {"key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE,
3938
   "The default size of key cache blocks",
3939
   (uchar**) &dflt_key_cache_var.param_block_size,
3940
   (uchar**) 0,
3941
   0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG,
3942
   KEY_CACHE_BLOCK_SIZE, 512, 1024 * 16, 0, 512, 0},
3943
  {"key_cache_division_limit", OPT_KEY_CACHE_DIVISION_LIMIT,
3944
   "The minimum percentage of warm blocks in key cache",
3945
   (uchar**) &dflt_key_cache_var.param_division_limit,
3946
   (uchar**) 0,
3947
   0, (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100,
3948
   1, 100, 0, 1, 0},
3949
  {"long_query_time", OPT_LONG_QUERY_TIME,
3950
   "Log all queries that have taken more than long_query_time seconds to execute to file. "
3951
   "The argument will be treated as a decimal value with microsecond precission.",
3952
   (uchar**) &long_query_time, (uchar**) &long_query_time, 0, GET_DOUBLE,
3953
   REQUIRED_ARG, 10, 0, LONG_TIMEOUT, 0, 0, 0},
3954
  {"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES,
3955
   "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",
3956
   (uchar**) &lower_case_table_names,
3957
   (uchar**) &lower_case_table_names, 0, GET_UINT, OPT_ARG,
3958
#ifdef FN_NO_CASE_SENCE
3959
    1
3960
#else
3961
    0
3962
#endif
3963
   , 0, 2, 0, 1, 0},
3964
  {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
3965
   "Max packetlength to send/receive from to server.",
3966
   (uchar**) &global_system_variables.max_allowed_packet,
3967
   (uchar**) &max_system_variables.max_allowed_packet, 0, GET_ULONG,
3968
   REQUIRED_ARG, 1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
3969
  {"max_binlog_cache_size", OPT_MAX_BINLOG_CACHE_SIZE,
3970
   "Can be used to restrict the total size used to cache a multi-transaction query.",
3971
   (uchar**) &max_binlog_cache_size, (uchar**) &max_binlog_cache_size, 0,
3972
   GET_ULONG, REQUIRED_ARG, ULONG_MAX, IO_SIZE, ULONG_MAX, 0, IO_SIZE, 0},
3973
  {"max_binlog_size", OPT_MAX_BINLOG_SIZE,
3974
   "Binary log will be rotated automatically when the size exceeds this \
3975
value. Will also apply to relay logs if max_relay_log_size is 0. \
3976
The minimum value for this variable is 4096.",
3977
   (uchar**) &max_binlog_size, (uchar**) &max_binlog_size, 0, GET_ULONG,
3978
   REQUIRED_ARG, 1024*1024L*1024L, IO_SIZE, 1024*1024L*1024L, 0, IO_SIZE, 0},
3979
  {"max_connect_errors", OPT_MAX_CONNECT_ERRORS,
3980
   "If there is more than this number of interrupted connections from a host this host will be blocked from further connections.",
3981
   (uchar**) &max_connect_errors, (uchar**) &max_connect_errors, 0, GET_ULONG,
3982
    REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ULONG_MAX, 0, 1, 0},
3983
  // Default max_connections of 151 is larger than Apache's default max
3984
  // children, to avoid "too many connections" error in a common setup
3985
  {"max_connections", OPT_MAX_CONNECTIONS,
3986
   "The number of simultaneous clients allowed.", (uchar**) &max_connections,
3987
   (uchar**) &max_connections, 0, GET_ULONG, REQUIRED_ARG, 151, 1, 100000, 0, 1,
3988
   0},
3989
  {"max_error_count", OPT_MAX_ERROR_COUNT,
3990
   "Max number of errors/warnings to store for a statement.",
3991
   (uchar**) &global_system_variables.max_error_count,
3992
   (uchar**) &max_system_variables.max_error_count,
3993
   0, GET_ULONG, REQUIRED_ARG, DEFAULT_ERROR_COUNT, 0, 65535, 0, 1, 0},
3994
  {"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE,
3995
   "Don't allow creation of heap tables bigger than this.",
3996
   (uchar**) &global_system_variables.max_heap_table_size,
3997
   (uchar**) &max_system_variables.max_heap_table_size, 0, GET_ULL,
3998
   REQUIRED_ARG, 16*1024*1024L, 16384, MAX_MEM_TABLE_SIZE,
3999
   MALLOC_OVERHEAD, 1024, 0},
4000
  {"max_join_size", OPT_MAX_JOIN_SIZE,
4001
   "Joins that are probably going to read more than max_join_size records return an error.",
4002
   (uchar**) &global_system_variables.max_join_size,
4003
   (uchar**) &max_system_variables.max_join_size, 0, GET_HA_ROWS, REQUIRED_ARG,
4004
   ~0L, 1, ~0L, 0, 1, 0},
4005
   {"max_length_for_sort_data", OPT_MAX_LENGTH_FOR_SORT_DATA,
4006
    "Max number of bytes in sorted records.",
4007
    (uchar**) &global_system_variables.max_length_for_sort_data,
4008
    (uchar**) &max_system_variables.max_length_for_sort_data, 0, GET_ULONG,
4009
    REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
4010
  {"max_relay_log_size", OPT_MAX_RELAY_LOG_SIZE,
4011
   "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.",
4012
   (uchar**) &max_relay_log_size, (uchar**) &max_relay_log_size, 0, GET_ULONG,
4013
   REQUIRED_ARG, 0L, 0L, 1024*1024L*1024L, 0, IO_SIZE, 0},
4014
  { "max_seeks_for_key", OPT_MAX_SEEKS_FOR_KEY,
4015
    "Limit assumed max number of seeks when looking up rows based on a key",
4016
    (uchar**) &global_system_variables.max_seeks_for_key,
4017
    (uchar**) &max_system_variables.max_seeks_for_key, 0, GET_ULONG,
4018
    REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0 },
4019
  {"max_sort_length", OPT_MAX_SORT_LENGTH,
4020
   "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).",
4021
   (uchar**) &global_system_variables.max_sort_length,
4022
   (uchar**) &max_system_variables.max_sort_length, 0, GET_ULONG,
4023
   REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
4024
  {"max_tmp_tables", OPT_MAX_TMP_TABLES,
4025
   "Maximum number of temporary tables a client can keep open at a time.",
4026
   (uchar**) &global_system_variables.max_tmp_tables,
4027
   (uchar**) &max_system_variables.max_tmp_tables, 0, GET_ULONG,
4028
   REQUIRED_ARG, 32, 1, ULONG_MAX, 0, 1, 0},
4029
  {"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
4030
   "After this many write locks, allow some read locks to run in between.",
4031
   (uchar**) &max_write_lock_count, (uchar**) &max_write_lock_count, 0, GET_ULONG,
4032
   REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0},
4033
  {"min_examined_row_limit", OPT_MIN_EXAMINED_ROW_LIMIT,
4034
   "Don't log queries which examine less than min_examined_row_limit rows to file.",
4035
   (uchar**) &global_system_variables.min_examined_row_limit,
4036
   (uchar**) &max_system_variables.min_examined_row_limit, 0, GET_ULONG,
4037
  REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1L, 0},
4038
  {"myisam_block_size", OPT_MYISAM_BLOCK_SIZE,
4039
   "Block size to be used for MyISAM index pages.",
4040
   (uchar**) &opt_myisam_block_size,
4041
   (uchar**) &opt_myisam_block_size, 0, GET_ULONG, REQUIRED_ARG,
4042
   MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, MI_MAX_KEY_BLOCK_LENGTH,
4043
   0, MI_MIN_KEY_BLOCK_LENGTH, 0},
4044
  {"myisam_data_pointer_size", OPT_MYISAM_DATA_POINTER_SIZE,
4045
   "Default pointer size to be used for MyISAM tables.",
4046
   (uchar**) &myisam_data_pointer_size,
4047
   (uchar**) &myisam_data_pointer_size, 0, GET_ULONG, REQUIRED_ARG,
4048
   6, 2, 7, 0, 1, 0},
4049
  {"myisam_max_extra_sort_file_size", OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
4050
   "Deprecated option",
4051
   (uchar**) &global_system_variables.myisam_max_extra_sort_file_size,
4052
   (uchar**) &max_system_variables.myisam_max_extra_sort_file_size,
4053
   0, GET_ULL, REQUIRED_ARG, (ulonglong) MI_MAX_TEMP_LENGTH,
4054
   0, (ulonglong) MAX_FILE_SIZE, 0, 1, 0},
4055
  {"myisam_max_sort_file_size", OPT_MYISAM_MAX_SORT_FILE_SIZE,
4056
   "Don't use the fast sort index method to created index if the temporary file would get bigger than this.",
4057
   (uchar**) &global_system_variables.myisam_max_sort_file_size,
4058
   (uchar**) &max_system_variables.myisam_max_sort_file_size, 0,
4059
   GET_ULL, REQUIRED_ARG, (longlong) LONG_MAX, 0, (ulonglong) MAX_FILE_SIZE,
4060
   0, 1024*1024, 0},
4061
  {"myisam_repair_threads", OPT_MYISAM_REPAIR_THREADS,
4062
   "Number of threads to use when repairing MyISAM tables. The value of 1 disables parallel repair.",
4063
   (uchar**) &global_system_variables.myisam_repair_threads,
4064
   (uchar**) &max_system_variables.myisam_repair_threads, 0,
4065
   GET_ULONG, REQUIRED_ARG, 1, 1, ULONG_MAX, 0, 1, 0},
4066
  {"myisam_sort_buffer_size", OPT_MYISAM_SORT_BUFFER_SIZE,
4067
   "The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE.",
4068
   (uchar**) &global_system_variables.myisam_sort_buff_size,
4069
   (uchar**) &max_system_variables.myisam_sort_buff_size, 0,
4070
   GET_ULONG, REQUIRED_ARG, 8192*1024, 4, ~0L, 0, 1, 0},
4071
  {"myisam_stats_method", OPT_MYISAM_STATS_METHOD,
4072
   "Specifies how MyISAM index statistics collection code should threat NULLs. "
4073
   "Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), "
4074
   "\"nulls_equal\" (emulate 4.0 behavior), and \"nulls_ignored\".",
4075
   (uchar**) &myisam_stats_method_str, (uchar**) &myisam_stats_method_str, 0,
4076
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4077
  {"net_buffer_length", OPT_NET_BUFFER_LENGTH,
4078
   "Buffer length for TCP/IP and socket communication.",
4079
   (uchar**) &global_system_variables.net_buffer_length,
4080
   (uchar**) &max_system_variables.net_buffer_length, 0, GET_ULONG,
4081
   REQUIRED_ARG, 16384, 1024, 1024*1024L, 0, 1024, 0},
4082
  {"net_read_timeout", OPT_NET_READ_TIMEOUT,
4083
   "Number of seconds to wait for more data from a connection before aborting the read.",
4084
   (uchar**) &global_system_variables.net_read_timeout,
4085
   (uchar**) &max_system_variables.net_read_timeout, 0, GET_ULONG,
4086
   REQUIRED_ARG, NET_READ_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
4087
  {"net_retry_count", OPT_NET_RETRY_COUNT,
4088
   "If a read on a communication port is interrupted, retry this many times before giving up.",
4089
   (uchar**) &global_system_variables.net_retry_count,
4090
   (uchar**) &max_system_variables.net_retry_count,0,
4091
   GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, ULONG_MAX, 0, 1, 0},
4092
  {"net_write_timeout", OPT_NET_WRITE_TIMEOUT,
4093
   "Number of seconds to wait for a block to be written to a connection  before aborting the write.",
4094
   (uchar**) &global_system_variables.net_write_timeout,
4095
   (uchar**) &max_system_variables.net_write_timeout, 0, GET_ULONG,
4096
   REQUIRED_ARG, NET_WRITE_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
4097
  { "old", OPT_OLD_MODE, "Use compatible behavior.", 
4098
    (uchar**) &global_system_variables.old_mode,
4099
    (uchar**) &max_system_variables.old_mode, 0, GET_BOOL, NO_ARG, 
4100
    0, 0, 0, 0, 0, 0},
4101
  {"open_files_limit", OPT_OPEN_FILES_LIMIT,
4102
   "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.",
4103
   (uchar**) &open_files_limit, (uchar**) &open_files_limit, 0, GET_ULONG,
4104
   REQUIRED_ARG, 0, 0, OS_FILE_LIMIT, 0, 1, 0},
4105
  {"optimizer_prune_level", OPT_OPTIMIZER_PRUNE_LEVEL,
4106
   "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.",
4107
   (uchar**) &global_system_variables.optimizer_prune_level,
4108
   (uchar**) &max_system_variables.optimizer_prune_level,
4109
   0, GET_ULONG, OPT_ARG, 1, 0, 1, 0, 1, 0},
4110
  {"optimizer_search_depth", OPT_OPTIMIZER_SEARCH_DEPTH,
4111
   "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).",
4112
   (uchar**) &global_system_variables.optimizer_search_depth,
4113
   (uchar**) &max_system_variables.optimizer_search_depth,
4114
   0, GET_ULONG, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0},
4115
  {"plugin_dir", OPT_PLUGIN_DIR,
4116
   "Directory for plugins.",
4117
   (uchar**) &opt_plugin_dir_ptr, (uchar**) &opt_plugin_dir_ptr, 0,
4118
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4119
  {"plugin_load", OPT_PLUGIN_LOAD,
4120
   "Optional colon separated list of plugins to load, where each plugin is "
4121
   "identified by name and path to library seperated by an equals.",
4122
   (uchar**) &opt_plugin_load, (uchar**) &opt_plugin_load, 0,
4123
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4124
  {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
4125
   "The size of the buffer that is allocated when preloading indexes",
4126
   (uchar**) &global_system_variables.preload_buff_size,
4127
   (uchar**) &max_system_variables.preload_buff_size, 0, GET_ULONG,
4128
   REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0},
4129
  {"query_alloc_block_size", OPT_QUERY_ALLOC_BLOCK_SIZE,
4130
   "Allocation block size for query parsing and execution",
4131
   (uchar**) &global_system_variables.query_alloc_block_size,
4132
   (uchar**) &max_system_variables.query_alloc_block_size, 0, GET_ULONG,
4133
   REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
4134
  {"query_prealloc_size", OPT_QUERY_PREALLOC_SIZE,
4135
   "Persistent buffer for query parsing and execution",
4136
   (uchar**) &global_system_variables.query_prealloc_size,
4137
   (uchar**) &max_system_variables.query_prealloc_size, 0, GET_ULONG,
4138
   REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, QUERY_ALLOC_PREALLOC_SIZE,
4139
   ULONG_MAX, 0, 1024, 0},
4140
  {"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE,
4141
   "Allocation block size for storing ranges during optimization",
4142
   (uchar**) &global_system_variables.range_alloc_block_size,
4143
   (uchar**) &max_system_variables.range_alloc_block_size, 0, GET_ULONG,
4144
   REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, ULONG_MAX,
4145
   0, 1024, 0},
4146
  {"read_buffer_size", OPT_RECORD_BUFFER,
4147
   "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.",
4148
   (uchar**) &global_system_variables.read_buff_size,
4149
   (uchar**) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
4150
   128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, INT_MAX32, MALLOC_OVERHEAD, IO_SIZE,
4151
   0},
4152
  {"read_only", OPT_READONLY,
4153
   "Make all non-temporary tables read-only, with the exception for replication (slave) threads and users with the SUPER privilege",
4154
   (uchar**) &opt_readonly,
4155
   (uchar**) &opt_readonly,
4156
   0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
4157
  {"read_rnd_buffer_size", OPT_RECORD_RND_BUFFER,
4158
   "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.",
4159
   (uchar**) &global_system_variables.read_rnd_buff_size,
4160
   (uchar**) &max_system_variables.read_rnd_buff_size, 0,
4161
   GET_ULONG, REQUIRED_ARG, 256*1024L, 64 /*IO_SIZE*2+MALLOC_OVERHEAD*/ ,
4162
   INT_MAX32, MALLOC_OVERHEAD, 1 /* Small lower limit to be able to test MRR */, 0},
4163
  {"record_buffer", OPT_RECORD_BUFFER,
4164
   "Alias for read_buffer_size",
4165
   (uchar**) &global_system_variables.read_buff_size,
4166
   (uchar**) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
4167
   128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, INT_MAX32, MALLOC_OVERHEAD, IO_SIZE, 0},
4168
  {"relay_log_purge", OPT_RELAY_LOG_PURGE,
4169
   "0 = do not purge relay logs. 1 = purge them as soon as they are no more needed.",
4170
   (uchar**) &relay_log_purge,
4171
   (uchar**) &relay_log_purge, 0, GET_BOOL, NO_ARG,
4172
   1, 0, 1, 0, 1, 0},
4173
  {"relay_log_space_limit", OPT_RELAY_LOG_SPACE_LIMIT,
4174
   "Maximum space to use for all relay logs.",
4175
   (uchar**) &relay_log_space_limit,
4176
   (uchar**) &relay_log_space_limit, 0, GET_ULL, REQUIRED_ARG, 0L, 0L,
4177
   (longlong) ULONG_MAX, 0, 1, 0},
4178
  {"slave_compressed_protocol", OPT_SLAVE_COMPRESSED_PROTOCOL,
4179
   "Use compression on master/slave protocol.",
4180
   (uchar**) &opt_slave_compressed_protocol,
4181
   (uchar**) &opt_slave_compressed_protocol,
4182
   0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
4183
  {"slave_net_timeout", OPT_SLAVE_NET_TIMEOUT,
4184
   "Number of seconds to wait for more data from a master/slave connection before aborting the read.",
4185
   (uchar**) &slave_net_timeout, (uchar**) &slave_net_timeout, 0,
4186
   GET_ULONG, REQUIRED_ARG, SLAVE_NET_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
4187
  {"slave_transaction_retries", OPT_SLAVE_TRANS_RETRIES,
4188
   "Number of times the slave SQL thread will retry a transaction in case "
4189
   "it failed with a deadlock or elapsed lock wait timeout, "
4190
   "before giving up and stopping.",
4191
   (uchar**) &slave_trans_retries, (uchar**) &slave_trans_retries, 0,
4192
   GET_ULONG, REQUIRED_ARG, 10L, 0L, (longlong) ULONG_MAX, 0, 1, 0},
4193
  {"slave-allow-batching", OPT_SLAVE_ALLOW_BATCHING,
4194
   "Allow slave to batch requests.",
4195
   (uchar**) &slave_allow_batching, (uchar**) &slave_allow_batching,
4196
   0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
4197
  {"slow_launch_time", OPT_SLOW_LAUNCH_TIME,
4198
   "If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented.",
4199
   (uchar**) &slow_launch_time, (uchar**) &slow_launch_time, 0, GET_ULONG,
4200
   REQUIRED_ARG, 2L, 0L, LONG_TIMEOUT, 0, 1, 0},
4201
  {"sort_buffer_size", OPT_SORT_BUFFER,
4202
   "Each thread that needs to do a sort allocates a buffer of this size.",
4203
   (uchar**) &global_system_variables.sortbuff_size,
4204
   (uchar**) &max_system_variables.sortbuff_size, 0, GET_ULONG, REQUIRED_ARG,
4205
   MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, ULONG_MAX,
4206
   MALLOC_OVERHEAD, 1, 0},
4207
  {"sync-binlog", OPT_SYNC_BINLOG,
4208
   "Synchronously flush binary log to disk after every #th event. "
4209
   "Use 0 (default) to disable synchronous flushing.",
4210
   (uchar**) &sync_binlog_period, (uchar**) &sync_binlog_period, 0, GET_ULONG,
4211
   REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1, 0},
4212
  {"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default.",
4213
   (uchar**) &opt_sync_frm, (uchar**) &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0,
4214
   0, 0, 0, 0},
4215
  {"table_cache", OPT_TABLE_OPEN_CACHE,
4216
   "Deprecated; use --table_open_cache instead.",
4217
   (uchar**) &table_cache_size, (uchar**) &table_cache_size, 0, GET_ULONG,
4218
   REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
4219
  {"table_definition_cache", OPT_TABLE_DEF_CACHE,
4220
   "The number of cached table definitions.",
4221
   (uchar**) &table_def_size, (uchar**) &table_def_size,
4222
   0, GET_ULONG, REQUIRED_ARG, 128, 1, 512*1024L, 0, 1, 0},
4223
  {"table_open_cache", OPT_TABLE_OPEN_CACHE,
4224
   "The number of cached open tables.",
4225
   (uchar**) &table_cache_size, (uchar**) &table_cache_size, 0, GET_ULONG,
4226
   REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
4227
  {"table_lock_wait_timeout", OPT_TABLE_LOCK_WAIT_TIMEOUT,
4228
   "Timeout in seconds to wait for a table level lock before returning an "
4229
   "error. Used only if the connection has active cursors.",
4230
   (uchar**) &table_lock_wait_timeout, (uchar**) &table_lock_wait_timeout,
4231
   0, GET_ULONG, REQUIRED_ARG, 50, 1, 1024 * 1024 * 1024, 0, 1, 0},
4232
  {"thread_cache_size", OPT_THREAD_CACHE_SIZE,
4233
   "How many threads we should keep in a cache for reuse.",
4234
   (uchar**) &thread_cache_size, (uchar**) &thread_cache_size, 0, GET_ULONG,
4235
   REQUIRED_ARG, 0, 0, 16384, 0, 1, 0},
4236
  {"thread_pool_size", OPT_THREAD_CACHE_SIZE,
4237
   "How many threads we should create to handle query requests in case of 'thread_handling=pool-of-threads'",
4238
   (uchar**) &thread_pool_size, (uchar**) &thread_pool_size, 0, GET_ULONG,
4239
   REQUIRED_ARG, 20, 1, 16384, 0, 1, 0},
4240
  {"thread_stack", OPT_THREAD_STACK,
4241
   "The stack size for each thread.", (uchar**) &my_thread_stack_size,
4242
   (uchar**) &my_thread_stack_size, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK,
4243
   1024L*128L, ULONG_MAX, 0, 1024, 0},
4244
  { "time_format", OPT_TIME_FORMAT,
4245
    "The TIME format (for future).",
4246
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_TIME],
4247
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_TIME],
4248
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4249
  {"tmp_table_size", OPT_TMP_TABLE_SIZE,
4250
   "If an internal in-memory temporary table exceeds this size, MySQL will"
4251
   " automatically convert it to an on-disk MyISAM table.",
4252
   (uchar**) &global_system_variables.tmp_table_size,
4253
   (uchar**) &max_system_variables.tmp_table_size, 0, GET_ULL,
4254
   REQUIRED_ARG, 16*1024*1024L, 1024, MAX_MEM_TABLE_SIZE, 0, 1, 0},
4255
  {"transaction_alloc_block_size", OPT_TRANS_ALLOC_BLOCK_SIZE,
4256
   "Allocation block size for transactions to be stored in binary log",
4257
   (uchar**) &global_system_variables.trans_alloc_block_size,
4258
   (uchar**) &max_system_variables.trans_alloc_block_size, 0, GET_ULONG,
4259
   REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
4260
  {"transaction_prealloc_size", OPT_TRANS_PREALLOC_SIZE,
4261
   "Persistent buffer for transactions to be stored in binary log",
4262
   (uchar**) &global_system_variables.trans_prealloc_size,
4263
   (uchar**) &max_system_variables.trans_prealloc_size, 0, GET_ULONG,
4264
   REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
4265
  {"wait_timeout", OPT_WAIT_TIMEOUT,
4266
   "The number of seconds the server waits for activity on a connection before closing it.",
4267
   (uchar**) &global_system_variables.net_wait_timeout,
4268
   (uchar**) &max_system_variables.net_wait_timeout, 0, GET_ULONG,
4269
   REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT),
4270
   0, 1, 0},
4271
  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
4272
};
4273
4274
static int show_net_compression(THD *thd, SHOW_VAR *var, char *buff)
4275
{
4276
  var->type= SHOW_MY_BOOL;
4277
  var->value= (char *)&thd->net.compress;
4278
  return 0;
4279
}
4280
4281
static int show_starttime(THD *thd, SHOW_VAR *var, char *buff)
4282
{
4283
  var->type= SHOW_LONG;
4284
  var->value= buff;
4285
  *((long *)buff)= (long) (thd->query_start() - server_start_time);
4286
  return 0;
4287
}
4288
4289
static int show_flushstatustime(THD *thd, SHOW_VAR *var, char *buff)
4290
{
4291
  var->type= SHOW_LONG;
4292
  var->value= buff;
4293
  *((long *)buff)= (long) (thd->query_start() - flush_status_time);
4294
  return 0;
4295
}
4296
4297
static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff)
4298
{
4299
  var->type= SHOW_MY_BOOL;
4300
  pthread_mutex_lock(&LOCK_active_mi);
4301
  var->value= buff;
4302
  *((my_bool *)buff)= (my_bool) (active_mi && active_mi->slave_running &&
4303
                                 active_mi->rli.slave_running);
4304
  pthread_mutex_unlock(&LOCK_active_mi);
4305
  return 0;
4306
}
4307
4308
static int show_slave_retried_trans(THD *thd, SHOW_VAR *var, char *buff)
4309
{
4310
  /*
4311
    TODO: with multimaster, have one such counter per line in
4312
    SHOW SLAVE STATUS, and have the sum over all lines here.
4313
  */
4314
  pthread_mutex_lock(&LOCK_active_mi);
4315
  if (active_mi)
4316
  {
4317
    var->type= SHOW_LONG;
4318
    var->value= buff;
4319
    pthread_mutex_lock(&active_mi->rli.data_lock);
4320
    *((long *)buff)= (long)active_mi->rli.retried_trans;
4321
    pthread_mutex_unlock(&active_mi->rli.data_lock);
4322
  }
4323
  else
4324
    var->type= SHOW_UNDEF;
4325
  pthread_mutex_unlock(&LOCK_active_mi);
4326
  return 0;
4327
}
4328
4329
static int show_slave_received_heartbeats(THD *thd, SHOW_VAR *var, char *buff)
4330
{
4331
  pthread_mutex_lock(&LOCK_active_mi);
4332
  if (active_mi)
4333
  {
4334
    var->type= SHOW_LONGLONG;
4335
    var->value= buff;
4336
    pthread_mutex_lock(&active_mi->rli.data_lock);
4337
    *((longlong *)buff)= active_mi->received_heartbeats;
4338
    pthread_mutex_unlock(&active_mi->rli.data_lock);
4339
  }
4340
  else
4341
    var->type= SHOW_UNDEF;
4342
  pthread_mutex_unlock(&LOCK_active_mi);
4343
  return 0;
4344
}
4345
4346
static int show_heartbeat_period(THD *thd, SHOW_VAR *var, char *buff)
4347
{
4348
  pthread_mutex_lock(&LOCK_active_mi);
4349
  if (active_mi)
4350
  {
4351
    var->type= SHOW_CHAR;
4352
    var->value= buff;
4353
    my_sprintf(buff, (buff, "%.3f",active_mi->heartbeat_period));
4354
  }
4355
  else
4356
    var->type= SHOW_UNDEF;
4357
  pthread_mutex_unlock(&LOCK_active_mi);
4358
  return 0;
4359
}
4360
4361
4362
static int show_open_tables(THD *thd, SHOW_VAR *var, char *buff)
4363
{
4364
  var->type= SHOW_LONG;
4365
  var->value= buff;
4366
  *((long *)buff)= (long)cached_open_tables();
4367
  return 0;
4368
}
4369
4370
static int show_table_definitions(THD *thd, SHOW_VAR *var, char *buff)
4371
{
4372
  var->type= SHOW_LONG;
4373
  var->value= buff;
4374
  *((long *)buff)= (long)cached_table_definitions();
4375
  return 0;
4376
}
4377
4378
/*
4379
  Variables shown by SHOW STATUS in alphabetical order
4380
*/
4381
4382
SHOW_VAR status_vars[]= {
4383
  {"Aborted_clients",          (char*) &aborted_threads,        SHOW_LONG},
4384
  {"Aborted_connects",         (char*) &aborted_connects,       SHOW_LONG},
4385
  {"Binlog_cache_disk_use",    (char*) &binlog_cache_disk_use,  SHOW_LONG},
4386
  {"Binlog_cache_use",         (char*) &binlog_cache_use,       SHOW_LONG},
4387
  {"Bytes_received",           (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONGLONG_STATUS},
4388
  {"Bytes_sent",               (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS},
4389
  {"Com",                      (char*) com_status_vars, SHOW_ARRAY},
4390
  {"Compression",              (char*) &show_net_compression, SHOW_FUNC},
4391
  {"Connections",              (char*) &thread_id,              SHOW_LONG_NOFLUSH},
4392
  {"Created_tmp_disk_tables",  (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS},
4393
  {"Created_tmp_files",	       (char*) &my_tmp_file_created,	SHOW_LONG},
4394
  {"Created_tmp_tables",       (char*) offsetof(STATUS_VAR, created_tmp_tables), SHOW_LONG_STATUS},
4395
  {"Flush_commands",           (char*) &refresh_version,        SHOW_LONG_NOFLUSH},
4396
  {"Handler_commit",           (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
4397
  {"Handler_delete",           (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS},
4398
  {"Handler_discover",         (char*) offsetof(STATUS_VAR, ha_discover_count), SHOW_LONG_STATUS},
4399
  {"Handler_prepare",          (char*) offsetof(STATUS_VAR, ha_prepare_count),  SHOW_LONG_STATUS},
4400
  {"Handler_read_first",       (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS},
4401
  {"Handler_read_key",         (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS},
4402
  {"Handler_read_next",        (char*) offsetof(STATUS_VAR, ha_read_next_count), SHOW_LONG_STATUS},
4403
  {"Handler_read_prev",        (char*) offsetof(STATUS_VAR, ha_read_prev_count), SHOW_LONG_STATUS},
4404
  {"Handler_read_rnd",         (char*) offsetof(STATUS_VAR, ha_read_rnd_count), SHOW_LONG_STATUS},
4405
  {"Handler_read_rnd_next",    (char*) offsetof(STATUS_VAR, ha_read_rnd_next_count), SHOW_LONG_STATUS},
4406
  {"Handler_rollback",         (char*) offsetof(STATUS_VAR, ha_rollback_count), SHOW_LONG_STATUS},
4407
  {"Handler_savepoint",        (char*) offsetof(STATUS_VAR, ha_savepoint_count), SHOW_LONG_STATUS},
4408
  {"Handler_savepoint_rollback",(char*) offsetof(STATUS_VAR, ha_savepoint_rollback_count), SHOW_LONG_STATUS},
4409
  {"Handler_update",           (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS},
4410
  {"Handler_write",            (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS},
4411
  {"Key_blocks_not_flushed",   (char*) offsetof(KEY_CACHE, global_blocks_changed), SHOW_KEY_CACHE_LONG},
4412
  {"Key_blocks_unused",        (char*) offsetof(KEY_CACHE, blocks_unused), SHOW_KEY_CACHE_LONG},
4413
  {"Key_blocks_used",          (char*) offsetof(KEY_CACHE, blocks_used), SHOW_KEY_CACHE_LONG},
4414
  {"Key_read_requests",        (char*) offsetof(KEY_CACHE, global_cache_r_requests), SHOW_KEY_CACHE_LONGLONG},
4415
  {"Key_reads",                (char*) offsetof(KEY_CACHE, global_cache_read), SHOW_KEY_CACHE_LONGLONG},
4416
  {"Key_write_requests",       (char*) offsetof(KEY_CACHE, global_cache_w_requests), SHOW_KEY_CACHE_LONGLONG},
4417
  {"Key_writes",               (char*) offsetof(KEY_CACHE, global_cache_write), SHOW_KEY_CACHE_LONGLONG},
4418
  {"Last_query_cost",          (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS},
4419
  {"Max_used_connections",     (char*) &max_used_connections,  SHOW_LONG},
4420
  {"Open_files",               (char*) &my_file_opened,         SHOW_LONG_NOFLUSH},
4421
  {"Open_streams",             (char*) &my_stream_opened,       SHOW_LONG_NOFLUSH},
4422
  {"Open_table_definitions",   (char*) &show_table_definitions, SHOW_FUNC},
4423
  {"Open_tables",              (char*) &show_open_tables,       SHOW_FUNC},
4424
  {"Opened_files",             (char*) &my_file_total_opened, SHOW_LONG_NOFLUSH},
4425
  {"Opened_tables",            (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS},
4426
  {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS},
4427
  {"Questions",                (char*) offsetof(STATUS_VAR, questions), SHOW_LONG_STATUS},
4428
  {"Select_full_join",         (char*) offsetof(STATUS_VAR, select_full_join_count), SHOW_LONG_STATUS},
4429
  {"Select_full_range_join",   (char*) offsetof(STATUS_VAR, select_full_range_join_count), SHOW_LONG_STATUS},
4430
  {"Select_range",             (char*) offsetof(STATUS_VAR, select_range_count), SHOW_LONG_STATUS},
4431
  {"Select_range_check",       (char*) offsetof(STATUS_VAR, select_range_check_count), SHOW_LONG_STATUS},
4432
  {"Select_scan",	       (char*) offsetof(STATUS_VAR, select_scan_count), SHOW_LONG_STATUS},
4433
  {"Slave_open_temp_tables",   (char*) &slave_open_temp_tables, SHOW_LONG},
4434
  {"Slave_retried_transactions",(char*) &show_slave_retried_trans, SHOW_FUNC},
4435
  {"Slave_heartbeat_period",   (char*) &show_heartbeat_period, SHOW_FUNC},
4436
  {"Slave_received_heartbeats",(char*) &show_slave_received_heartbeats, SHOW_FUNC},
4437
  {"Slave_running",            (char*) &show_slave_running,     SHOW_FUNC},
4438
  {"Slow_launch_threads",      (char*) &slow_launch_threads,    SHOW_LONG},
4439
  {"Slow_queries",             (char*) offsetof(STATUS_VAR, long_query_count), SHOW_LONG_STATUS},
4440
  {"Sort_merge_passes",	       (char*) offsetof(STATUS_VAR, filesort_merge_passes), SHOW_LONG_STATUS},
4441
  {"Sort_range",	       (char*) offsetof(STATUS_VAR, filesort_range_count), SHOW_LONG_STATUS},
4442
  {"Sort_rows",		       (char*) offsetof(STATUS_VAR, filesort_rows), SHOW_LONG_STATUS},
4443
  {"Sort_scan",		       (char*) offsetof(STATUS_VAR, filesort_scan_count), SHOW_LONG_STATUS},
4444
  {"Table_locks_immediate",    (char*) &locks_immediate,        SHOW_LONG},
4445
  {"Table_locks_waited",       (char*) &locks_waited,           SHOW_LONG},
4446
#ifdef HAVE_MMAP
4447
  {"Tc_log_max_pages_used",    (char*) &tc_log_max_pages_used,  SHOW_LONG},
4448
  {"Tc_log_page_size",         (char*) &tc_log_page_size,       SHOW_LONG},
4449
  {"Tc_log_page_waits",        (char*) &tc_log_page_waits,      SHOW_LONG},
4450
#endif
4451
  {"Threads_cached",           (char*) &cached_thread_count,    SHOW_LONG_NOFLUSH},
4452
  {"Threads_connected",        (char*) &connection_count,       SHOW_INT},
4453
  {"Threads_created",	       (char*) &thread_created,		SHOW_LONG_NOFLUSH},
4454
  {"Threads_running",          (char*) &thread_running,         SHOW_INT},
4455
  {"Uptime",                   (char*) &show_starttime,         SHOW_FUNC},
4456
  {"Uptime_since_flush_status",(char*) &show_flushstatustime,   SHOW_FUNC},
4457
  {NullS, NullS, SHOW_LONG}
4458
};
4459
4460
static void print_version(void)
4461
{
4462
  set_server_version();
4463
  /*
4464
    Note: the instance manager keys off the string 'Ver' so it can find the
4465
    version from the output of 'mysqld --version', so don't change it!
4466
  */
4467
  printf("%s  Ver %s for %s on %s (%s)\n",my_progname,
4468
	 server_version,SYSTEM_TYPE,MACHINE_TYPE, MYSQL_COMPILATION_COMMENT);
4469
}
4470
4471
static void usage(void)
4472
{
4473
  if (!(default_charset_info= get_charset_by_csname(default_character_set_name,
4474
					           MY_CS_PRIMARY,
4475
						   MYF(MY_WME))))
4476
    exit(1);
4477
  if (!default_collation_name)
4478
    default_collation_name= (char*) default_charset_info->name;
4479
  print_version();
4480
  puts("\
4481
Copyright (C) 2000 MySQL AB, by Monty and others\n\
4482
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
4483
and you are welcome to modify and redistribute it under the GPL license\n\n\
4484
Starts the MySQL database server\n");
4485
4486
  printf("Usage: %s [OPTIONS]\n", my_progname);
4487
  if (!opt_verbose)
4488
    puts("\nFor more help options (several pages), use mysqld --verbose --help");
4489
  else
4490
  {
4491
  print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
4492
  puts("");
4493
  set_ports();
4494
4495
  /* Print out all the options including plugin supplied options */
4496
  my_print_help_inc_plugins(my_long_options, sizeof(my_long_options)/sizeof(my_option));
4497
4498
  puts("\n\
4499
To see what values a running MySQL server is using, type\n\
4500
'mysqladmin variables' instead of 'mysqld --verbose --help'.");
4501
  }
4502
}
4503
4504
4505
/**
4506
  Initialize all MySQL global variables to default values.
4507
4508
  We don't need to set numeric variables refered to in my_long_options
4509
  as these are initialized by my_getopt.
4510
4511
  @note
4512
    The reason to set a lot of global variables to zero is to allow one to
4513
    restart the embedded server with a clean environment
4514
    It's also needed on some exotic platforms where global variables are
4515
    not set to 0 when a program starts.
4516
4517
    We don't need to set numeric variables refered to in my_long_options
4518
    as these are initialized by my_getopt.
4519
*/
4520
4521
static void mysql_init_variables(void)
4522
{
4523
  /* Things reset to zero */
4524
  opt_skip_slave_start= opt_reckless_slave = 0;
4525
  mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0;
4526
  opt_log= opt_slow_log= 0;
4527
  opt_update_log= 0;
4528
  log_output_options= find_bit_type(log_output_str, &log_output_typelib);
4529
  opt_bin_log= 0;
4530
  opt_disable_networking= opt_skip_show_db=0;
4531
  opt_logname= opt_update_logname= opt_binlog_index_name= opt_slow_logname= 0;
4532
  opt_tc_log_file= (char *)"tc.log";      // no hostname in tc_log file name !
4533
  opt_secure_auth= 0;
4534
  opt_secure_file_priv= 0;
4535
  opt_bootstrap= opt_myisam_log= 0;
4536
  mqh_used= 0;
4537
  segfaulted= kill_in_progress= 0;
4538
  cleanup_done= 0;
4539
  defaults_argc= 0;
4540
  defaults_argv= 0;
4541
  server_id_supplied= 0;
4542
  test_flags= select_errors= dropping_tables= ha_open_options=0;
4543
  thread_count= thread_running= kill_cached_threads= wake_thread=0;
4544
  slave_open_temp_tables= 0;
4545
  cached_thread_count= 0;
4546
  opt_endinfo= using_udf_functions= 0;
4547
  opt_using_transactions= using_update_log= 0;
4548
  abort_loop= select_thread_in_use= signal_thread_in_use= 0;
4549
  ready_to_exit= shutdown_in_progress= 0;
4550
  aborted_threads= aborted_connects= 0;
4551
  specialflag= 0;
4552
  binlog_cache_use=  binlog_cache_disk_use= 0;
4553
  max_used_connections= slow_launch_threads = 0;
4554
  mysqld_user= mysqld_chroot= opt_init_file= opt_bin_logname = 0;
4555
  errmesg= 0;
11 by Brian Aker
Removing old UNIX socket bits
4556
  opt_mysql_tmpdir= my_bind_addr_str= NullS;
1 by brian
clean slate
4557
  bzero((uchar*) &mysql_tmpdir_list, sizeof(mysql_tmpdir_list));
4558
  bzero((char *) &global_status_var, sizeof(global_status_var));
4559
  key_map_full.set_all();
4560
4561
  /* Character sets */
4562
  system_charset_info= &my_charset_utf8_general_ci;
4563
  files_charset_info= &my_charset_utf8_general_ci;
4564
  national_charset_info= &my_charset_utf8_general_ci;
4565
  table_alias_charset= &my_charset_bin;
4566
  character_set_filesystem= &my_charset_bin;
4567
4568
  opt_date_time_formats[0]= opt_date_time_formats[1]= opt_date_time_formats[2]= 0;
4569
4570
  /* Things with default values that are not zero */
4571
  delay_key_write_options= (uint) DELAY_KEY_WRITE_ON;
4572
  slave_exec_mode_options= 0;
4573
  slave_exec_mode_options= (uint)
4574
    find_bit_type_or_exit(slave_exec_mode_str, &slave_exec_mode_typelib, NULL);
4575
  opt_specialflag= SPECIAL_ENGLISH;
11 by Brian Aker
Removing old UNIX socket bits
4576
  ip_sock= INVALID_SOCKET;
1 by brian
clean slate
4577
  mysql_home_ptr= mysql_home;
4578
  pidfile_name_ptr= pidfile_name;
4579
  log_error_file_ptr= log_error_file;
4580
  language_ptr= language;
4581
  mysql_data_home= mysql_real_data_home;
4582
  thd_startup_options= (OPTION_AUTO_IS_NULL | OPTION_BIN_LOG |
4583
                        OPTION_QUOTE_SHOW_CREATE | OPTION_SQL_NOTES);
4584
  protocol_version= PROTOCOL_VERSION;
4585
  what_to_log= ~ (1L << (uint) COM_TIME);
4586
  refresh_version= 1L;	/* Increments on each reload */
4587
  global_query_id= thread_id= 1L;
4588
  strmov(server_version, MYSQL_SERVER_VERSION);
4589
  myisam_recover_options_str= "OFF";
4590
  myisam_stats_method_str= "nulls_unequal";
4591
  threads.empty();
4592
  thread_cache.empty();
4593
  key_caches.empty();
4594
  if (!(dflt_key_cache= get_or_create_key_cache(default_key_cache_base.str,
4595
                                                default_key_cache_base.length)))
4596
    exit(1);
4597
  /* set key_cache_hash.default_value = dflt_key_cache */
4598
  multi_keycache_init();
4599
4600
  /* Set directory paths */
4601
  strmake(language, LANGUAGE, sizeof(language)-1);
4602
  strmake(mysql_real_data_home, get_relative_path(DATADIR),
4603
	  sizeof(mysql_real_data_home)-1);
4604
  mysql_data_home_buff[0]=FN_CURLIB;	// all paths are relative from here
4605
  mysql_data_home_buff[1]=0;
4606
  mysql_data_home_len= 2;
4607
4608
  /* Replication parameters */
4609
  master_info_file= (char*) "master.info",
4610
    relay_log_info_file= (char*) "relay-log.info";
4611
  report_user= report_password = report_host= 0;	/* TO BE DELETED */
4612
  opt_relay_logname= opt_relaylog_index_name= 0;
4613
4614
  /* Variables in libraries */
4615
  charsets_dir= 0;
4616
  default_character_set_name= (char*) MYSQL_DEFAULT_CHARSET_NAME;
4617
  default_collation_name= compiled_default_collation_name;
10 by Brian Aker
Start of var cleanup (really.... looking at this code the entire thing needs
4618
  sys_charset_system.set((char*) system_charset_info->csname);
1 by brian
clean slate
4619
  character_set_filesystem_name= (char*) "binary";
4620
  lc_time_names_name= (char*) "en_US";
4621
  /* Set default values for some option variables */
4622
  default_storage_engine_str= (char*) "MyISAM";
4623
  global_system_variables.table_plugin= NULL;
4624
  global_system_variables.tx_isolation= ISO_REPEATABLE_READ;
4625
  global_system_variables.select_limit= (ulonglong) HA_POS_ERROR;
4626
  max_system_variables.select_limit=    (ulonglong) HA_POS_ERROR;
4627
  global_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
4628
  max_system_variables.max_join_size=   (ulonglong) HA_POS_ERROR;
4629
  global_system_variables.old_passwords= 0;
4630
  global_system_variables.old_alter_table= 0;
4631
  global_system_variables.binlog_format= BINLOG_FORMAT_UNSPEC;
4632
  /*
4633
    Default behavior for 4.1 and 5.0 is to treat NULL values as unequal
4634
    when collecting index statistics for MyISAM tables.
4635
  */
4636
  global_system_variables.myisam_stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
4637
4638
  /* Variables that depends on compile options */
4639
#ifndef DBUG_OFF
4640
  default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace",
4641
			     "d:t:i:o,/tmp/mysqld.trace");
4642
#endif
4643
  opt_error_log= IF_WIN(1,0);
4644
#ifdef HAVE_BROKEN_REALPATH
4645
  have_symlink=SHOW_OPTION_NO;
4646
#else
4647
  have_symlink=SHOW_OPTION_YES;
4648
#endif
4649
#ifdef HAVE_DLOPEN
4650
  have_dlopen=SHOW_OPTION_YES;
4651
#else
4652
  have_dlopen=SHOW_OPTION_NO;
4653
#endif
4654
#ifdef HAVE_CRYPT
4655
  have_crypt=SHOW_OPTION_YES;
4656
#else
4657
  have_crypt=SHOW_OPTION_NO;
4658
#endif
4659
#ifdef HAVE_COMPRESS
4660
  have_compress= SHOW_OPTION_YES;
4661
#else
4662
  have_compress= SHOW_OPTION_NO;
4663
#endif
4664
4665
  const char *tmpenv;
4666
  if (!(tmpenv = getenv("MY_BASEDIR_VERSION")))
4667
    tmpenv = DEFAULT_MYSQL_HOME;
4668
  (void) strmake(mysql_home, tmpenv, sizeof(mysql_home)-1);
4669
}
4670
4671
4672
my_bool
4673
mysqld_get_one_option(int optid,
4674
                      const struct my_option *opt __attribute__((unused)),
4675
                      char *argument)
4676
{
4677
  switch(optid) {
4678
  case '#':
4679
#ifndef DBUG_OFF
4680
    DBUG_SET_INITIAL(argument ? argument : default_dbug_option);
4681
#endif
4682
    opt_endinfo=1;				/* unireg: memory allocation */
4683
    break;
4684
  case 'a':
4685
    global_system_variables.tx_isolation= ISO_SERIALIZABLE;
4686
    break;
4687
  case 'b':
4688
    strmake(mysql_home,argument,sizeof(mysql_home)-1);
4689
    break;
4690
  case 'C':
4691
    if (default_collation_name == compiled_default_collation_name)
4692
      default_collation_name= 0;
4693
    break;
4694
  case 'l':
4695
    opt_log=1;
4696
    break;
4697
  case 'h':
4698
    strmake(mysql_real_data_home,argument, sizeof(mysql_real_data_home)-1);
4699
    /* Correct pointer set by my_getopt (for embedded library) */
4700
    mysql_data_home= mysql_real_data_home;
4701
    mysql_data_home_len= strlen(mysql_data_home);
4702
    break;
4703
  case 'u':
4704
    if (!mysqld_user || !strcmp(mysqld_user, argument))
4705
      mysqld_user= argument;
4706
    else
4707
      sql_print_warning("Ignoring user change to '%s' because the user was set to '%s' earlier on the command line\n", argument, mysqld_user);
4708
    break;
4709
  case 'L':
4710
    strmake(language, argument, sizeof(language)-1);
4711
    break;
4712
  case OPT_SLAVE_SKIP_ERRORS:
4713
    init_slave_skip_errors(argument);
4714
    break;
4715
  case OPT_SLAVE_EXEC_MODE:
4716
    slave_exec_mode_options= (uint)
4717
      find_bit_type_or_exit(argument, &slave_exec_mode_typelib, "");
4718
    break;
4719
  case 'V':
4720
    print_version();
4721
    exit(0);
4722
  case 'W':
4723
    if (!argument)
4724
      global_system_variables.log_warnings++;
4725
    else if (argument == disabled_my_option)
4726
      global_system_variables.log_warnings= 0L;
4727
    else
4728
      global_system_variables.log_warnings= atoi(argument);
4729
    break;
4730
  case 'T':
4731
    test_flags= argument ? (uint) atoi(argument) : 0;
4732
    opt_endinfo=1;
4733
    break;
4734
  case (int) OPT_BIG_TABLES:
4735
    thd_startup_options|=OPTION_BIG_TABLES;
4736
    break;
4737
  case (int) OPT_ISAM_LOG:
4738
    opt_myisam_log=1;
4739
    break;
4740
  case (int) OPT_UPDATE_LOG:
4741
    opt_update_log=1;
4742
    break;
4743
  case (int) OPT_BIN_LOG:
4744
    opt_bin_log= test(argument != disabled_my_option);
4745
    break;
4746
  case (int) OPT_ERROR_LOG_FILE:
4747
    opt_error_log= 1;
4748
    break;
4749
  case (int)OPT_REPLICATE_IGNORE_DB:
4750
  {
4751
    rpl_filter->add_ignore_db(argument);
4752
    break;
4753
  }
4754
  case (int)OPT_REPLICATE_DO_DB:
4755
  {
4756
    rpl_filter->add_do_db(argument);
4757
    break;
4758
  }
4759
  case (int)OPT_REPLICATE_REWRITE_DB:
4760
  {
4761
    char* key = argument,*p, *val;
4762
4763
    if (!(p= strstr(argument, "->")))
4764
    {
4765
      fprintf(stderr,
4766
	      "Bad syntax in replicate-rewrite-db - missing '->'!\n");
4767
      exit(1);
4768
    }
4769
    val= p--;
4770
    while (my_isspace(mysqld_charset, *p) && p > argument)
4771
      *p-- = 0;
4772
    if (p == argument)
4773
    {
4774
      fprintf(stderr,
4775
	      "Bad syntax in replicate-rewrite-db - empty FROM db!\n");
4776
      exit(1);
4777
    }
4778
    *val= 0;
4779
    val+= 2;
4780
    while (*val && my_isspace(mysqld_charset, *val))
4781
      *val++;
4782
    if (!*val)
4783
    {
4784
      fprintf(stderr,
4785
	      "Bad syntax in replicate-rewrite-db - empty TO db!\n");
4786
      exit(1);
4787
    }
4788
4789
    rpl_filter->add_db_rewrite(key, val);
4790
    break;
4791
  }
4792
4793
  case (int)OPT_BINLOG_IGNORE_DB:
4794
  {
4795
    binlog_filter->add_ignore_db(argument);
4796
    break;
4797
  }
4798
  case OPT_BINLOG_FORMAT:
4799
  {
4800
    int id;
4801
    id= find_type_or_exit(argument, &binlog_format_typelib, opt->name);
4802
    global_system_variables.binlog_format= opt_binlog_format_id= id - 1;
4803
    break;
4804
  }
4805
  case (int)OPT_BINLOG_DO_DB:
4806
  {
4807
    binlog_filter->add_do_db(argument);
4808
    break;
4809
  }
4810
  case (int)OPT_REPLICATE_DO_TABLE:
4811
  {
4812
    if (rpl_filter->add_do_table(argument))
4813
    {
4814
      fprintf(stderr, "Could not add do table rule '%s'!\n", argument);
4815
      exit(1);
4816
    }
4817
    break;
4818
  }
4819
  case (int)OPT_REPLICATE_WILD_DO_TABLE:
4820
  {
4821
    if (rpl_filter->add_wild_do_table(argument))
4822
    {
4823
      fprintf(stderr, "Could not add do table rule '%s'!\n", argument);
4824
      exit(1);
4825
    }
4826
    break;
4827
  }
4828
  case (int)OPT_REPLICATE_WILD_IGNORE_TABLE:
4829
  {
4830
    if (rpl_filter->add_wild_ignore_table(argument))
4831
    {
4832
      fprintf(stderr, "Could not add ignore table rule '%s'!\n", argument);
4833
      exit(1);
4834
    }
4835
    break;
4836
  }
4837
  case (int)OPT_REPLICATE_IGNORE_TABLE:
4838
  {
4839
    if (rpl_filter->add_ignore_table(argument))
4840
    {
4841
      fprintf(stderr, "Could not add ignore table rule '%s'!\n", argument);
4842
      exit(1);
4843
    }
4844
    break;
4845
  }
4846
  case (int) OPT_SLOW_QUERY_LOG:
4847
    opt_slow_log= 1;
4848
    break;
4849
#ifdef WITH_CSV_STORAGE_ENGINE
4850
  case  OPT_LOG_OUTPUT:
4851
  {
4852
    if (!argument || !argument[0])
4853
    {
4854
      log_output_options= LOG_FILE;
4855
      log_output_str= log_output_typelib.type_names[1];
4856
    }
4857
    else
4858
    {
4859
      log_output_str= argument;
4860
      log_output_options=
4861
        find_bit_type_or_exit(argument, &log_output_typelib, opt->name);
4862
  }
4863
    break;
4864
  }
4865
#endif
4866
  case (int) OPT_SKIP_NEW:
4867
    opt_specialflag|= SPECIAL_NO_NEW_FUNC;
4868
    delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
4869
    myisam_concurrent_insert=0;
4870
    myisam_recover_options= HA_RECOVER_NONE;
4871
    my_use_symdir=0;
4872
    ha_open_options&= ~(HA_OPEN_ABORT_IF_CRASHED | HA_OPEN_DELAY_KEY_WRITE);
4873
    break;
4874
  case (int) OPT_SAFE:
4875
    opt_specialflag|= SPECIAL_SAFE_MODE;
4876
    delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
4877
    myisam_recover_options= HA_RECOVER_DEFAULT;
4878
    ha_open_options&= ~(HA_OPEN_DELAY_KEY_WRITE);
4879
    break;
4880
  case (int) OPT_SKIP_PRIOR:
4881
    opt_specialflag|= SPECIAL_NO_PRIOR;
4882
    break;
4883
  case (int) OPT_SKIP_LOCK:
4884
    opt_external_locking=0;
4885
    break;
4886
  case (int) OPT_SKIP_SHOW_DB:
4887
    opt_skip_show_db=1;
4888
    opt_specialflag|=SPECIAL_SKIP_SHOW_DB;
4889
    break;
4890
  case (int) OPT_WANT_CORE:
4891
    test_flags |= TEST_CORE_ON_SIGNAL;
4892
    break;
4893
  case (int) OPT_SKIP_STACK_TRACE:
4894
    test_flags|=TEST_NO_STACKTRACE;
4895
    break;
4896
  case (int) OPT_SKIP_SYMLINKS:
4897
    my_use_symdir=0;
4898
    break;
4899
  case (int) OPT_BIND_ADDRESS:
4900
    {
4901
      struct addrinfo *res_lst, hints;    
4902
4903
      bzero(&hints, sizeof(struct addrinfo));
4904
      hints.ai_socktype= SOCK_STREAM;
4905
      hints.ai_protocol= IPPROTO_TCP;
4906
4907
      if (getaddrinfo(argument, NULL, &hints, &res_lst) != 0) 
4908
      {
4909
        sql_print_error("Can't start server: cannot resolve hostname!");
4910
        exit(1);
4911
      }
4912
4913
      if (res_lst->ai_next)
4914
      {
4915
        sql_print_error("Can't start server: bind-address refers to multiple interfaces!");
4916
        exit(1);
4917
      }
4918
      freeaddrinfo(res_lst);
4919
    }
4920
    break;
4921
  case (int) OPT_PID_FILE:
4922
    strmake(pidfile_name, argument, sizeof(pidfile_name)-1);
4923
    break;
4924
  case OPT_CONSOLE:
4925
    if (opt_console)
4926
      opt_error_log= 0;			// Force logs to stdout
4927
    break;
4928
  case (int) OPT_FLUSH:
4929
    myisam_flush=1;
4930
    flush_time=0;			// No auto flush
4931
    break;
4932
  case OPT_LOW_PRIORITY_UPDATES:
4933
    thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY;
4934
    global_system_variables.low_priority_updates=1;
4935
    break;
4936
  case OPT_BOOTSTRAP:
4937
    opt_noacl=opt_bootstrap=1;
4938
    break;
4939
  case OPT_SERVER_ID:
4940
    server_id_supplied = 1;
4941
    break;
4942
  case OPT_DELAY_KEY_WRITE_ALL:
4943
    if (argument != disabled_my_option)
4944
      argument= (char*) "ALL";
4945
    /* Fall through */
4946
  case OPT_DELAY_KEY_WRITE:
4947
    if (argument == disabled_my_option)
4948
      delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
4949
    else if (! argument)
4950
      delay_key_write_options= (uint) DELAY_KEY_WRITE_ON;
4951
    else
4952
    {
4953
      int type;
4954
      type= find_type_or_exit(argument, &delay_key_write_typelib, opt->name);
4955
      delay_key_write_options= (uint) type-1;
4956
    }
4957
    break;
4958
  case OPT_CHARSETS_DIR:
4959
    strmake(mysql_charsets_dir, argument, sizeof(mysql_charsets_dir)-1);
4960
    charsets_dir = mysql_charsets_dir;
4961
    break;
4962
  case OPT_TX_ISOLATION:
4963
  {
4964
    int type;
4965
    type= find_type_or_exit(argument, &tx_isolation_typelib, opt->name);
4966
    global_system_variables.tx_isolation= (type-1);
4967
    break;
4968
  }
4969
  case OPT_MYISAM_RECOVER:
4970
  {
4971
    if (!argument)
4972
    {
4973
      myisam_recover_options=    HA_RECOVER_DEFAULT;
4974
      myisam_recover_options_str= myisam_recover_typelib.type_names[0];
4975
    }
4976
    else if (!argument[0])
4977
    {
4978
      myisam_recover_options= HA_RECOVER_NONE;
4979
      myisam_recover_options_str= "OFF";
4980
    }
4981
    else
4982
    {
4983
      myisam_recover_options_str=argument;
4984
      myisam_recover_options=
4985
        find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name);
4986
    }
4987
    ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
4988
    break;
4989
  }
4990
  case OPT_TC_HEURISTIC_RECOVER:
4991
    tc_heuristic_recover= find_type_or_exit(argument,
4992
                                            &tc_heuristic_recover_typelib,
4993
                                            opt->name);
4994
    break;
4995
  case OPT_MYISAM_STATS_METHOD:
4996
  {
4997
    ulong method_conv;
4998
    int method;
4999
5000
    myisam_stats_method_str= argument;
5001
    method= find_type_or_exit(argument, &myisam_stats_method_typelib,
5002
                              opt->name);
5003
    switch (method-1) {
5004
    case 2:
5005
      method_conv= MI_STATS_METHOD_IGNORE_NULLS;
5006
      break;
5007
    case 1:
5008
      method_conv= MI_STATS_METHOD_NULLS_EQUAL;
5009
      break;
5010
    case 0:
5011
    default:
5012
      method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
5013
      break;
5014
    }
5015
    global_system_variables.myisam_stats_method= method_conv;
5016
    break;
5017
  }
5018
  case OPT_LOWER_CASE_TABLE_NAMES:
5019
    lower_case_table_names= argument ? atoi(argument) : 1;
5020
    lower_case_table_names_used= 1;
5021
    break;
5022
  }
5023
  return 0;
5024
}
5025
5026
5027
/** Handle arguments for multiple key caches. */
5028
5029
extern "C" uchar **mysql_getopt_value(const char *keyname, uint key_length,
5030
                                      const struct my_option *option);
5031
5032
uchar* *
5033
mysql_getopt_value(const char *keyname, uint key_length,
5034
		   const struct my_option *option)
5035
{
5036
  switch (option->id) {
5037
  case OPT_KEY_BUFFER_SIZE:
5038
  case OPT_KEY_CACHE_BLOCK_SIZE:
5039
  case OPT_KEY_CACHE_DIVISION_LIMIT:
5040
  case OPT_KEY_CACHE_AGE_THRESHOLD:
5041
  {
5042
    KEY_CACHE *key_cache;
5043
    if (!(key_cache= get_or_create_key_cache(keyname, key_length)))
5044
      exit(1);
5045
    switch (option->id) {
5046
    case OPT_KEY_BUFFER_SIZE:
5047
      return (uchar**) &key_cache->param_buff_size;
5048
    case OPT_KEY_CACHE_BLOCK_SIZE:
5049
      return (uchar**) &key_cache->param_block_size;
5050
    case OPT_KEY_CACHE_DIVISION_LIMIT:
5051
      return (uchar**) &key_cache->param_division_limit;
5052
    case OPT_KEY_CACHE_AGE_THRESHOLD:
5053
      return (uchar**) &key_cache->param_age_threshold;
5054
    }
5055
  }
5056
  }
5057
  return option->value;
5058
}
5059
5060
5061
extern "C" void option_error_reporter(enum loglevel level, const char *format, ...);
5062
5063
void option_error_reporter(enum loglevel level, const char *format, ...)
5064
{
5065
  va_list args;
5066
  va_start(args, format);
5067
5068
  /* Don't print warnings for --loose options during bootstrap */
5069
  if (level == ERROR_LEVEL || !opt_bootstrap ||
5070
      global_system_variables.log_warnings)
5071
  {
5072
    vprint_msg_to_log(level, format, args);
5073
  }
5074
  va_end(args);
5075
}
5076
5077
5078
/**
5079
  @todo
5080
  - FIXME add EXIT_TOO_MANY_ARGUMENTS to "mysys_err.h" and return that code?
5081
*/
5082
static void get_options(int *argc,char **argv)
5083
{
5084
  int ho_error;
5085
5086
  my_getopt_register_get_addr(mysql_getopt_value);
5087
  my_getopt_error_reporter= option_error_reporter;
5088
5089
  /* Skip unknown options so that they may be processed later by plugins */
5090
  my_getopt_skip_unknown= TRUE;
5091
5092
  if ((ho_error= handle_options(argc, &argv, my_long_options,
5093
                                mysqld_get_one_option)))
5094
    exit(ho_error);
5095
  (*argc)++; /* add back one for the progname handle_options removes */
5096
             /* no need to do this for argv as we are discarding it. */
5097
5098
  if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes ||
5099
       opt_log_slow_slave_statements) &&
5100
      !opt_slow_log)
5101
    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");
5102
5103
#if defined(HAVE_BROKEN_REALPATH)
5104
  my_use_symdir=0;
5105
  my_disable_symlinks=1;
5106
  have_symlink=SHOW_OPTION_NO;
5107
#else
5108
  if (!my_use_symdir)
5109
  {
5110
    my_disable_symlinks=1;
5111
    have_symlink=SHOW_OPTION_DISABLED;
5112
  }
5113
#endif
5114
  if (opt_debugging)
5115
  {
5116
    /* Allow break with SIGINT, no core or stack trace */
5117
    test_flags|= TEST_SIGINT | TEST_NO_STACKTRACE;
5118
    test_flags&= ~TEST_CORE_ON_SIGNAL;
5119
  }
5120
  /* Set global MyISAM variables from delay_key_write_options */
5121
  fix_delay_key_write((THD*) 0, OPT_GLOBAL);
5122
  /* Set global slave_exec_mode from its option */
5123
  fix_slave_exec_mode(OPT_GLOBAL);
5124
5125
  if (mysqld_chroot)
5126
    set_root(mysqld_chroot);
5127
  fix_paths();
5128
5129
  /*
5130
    Set some global variables from the global_system_variables
5131
    In most cases the global variables will not be used
5132
  */
5133
  my_disable_locking= myisam_single_user= test(opt_external_locking == 0);
5134
  my_default_record_cache_size=global_system_variables.read_buff_size;
5135
  myisam_max_temp_length=
5136
    (my_off_t) global_system_variables.myisam_max_sort_file_size;
5137
5138
  /* Set global variables based on startup options */
5139
  myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size);
5140
5141
  /* long_query_time is in microseconds */
5142
  global_system_variables.long_query_time= max_system_variables.long_query_time=
5143
    (longlong) (long_query_time * 1000000.0);
5144
5145
  if (opt_short_log_format)
5146
    opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT;
5147
5148
  if (init_global_datetime_format(MYSQL_TIMESTAMP_DATE,
5149
				  &global_system_variables.date_format) ||
5150
      init_global_datetime_format(MYSQL_TIMESTAMP_TIME,
5151
				  &global_system_variables.time_format) ||
5152
      init_global_datetime_format(MYSQL_TIMESTAMP_DATETIME,
5153
				  &global_system_variables.datetime_format))
5154
    exit(1);
5155
12.1.3 by Brian Aker
Removal of dead code/remove non-used Falcon tests.
5156
  pool_of_threads_scheduler(&thread_scheduler);  /* purecov: tested */
1 by brian
clean slate
5157
}
5158
5159
5160
/*
5161
  Create version name for running mysqld version
5162
  We automaticly add suffixes -debug, -embedded and -log to the version
5163
  name to make the version more descriptive.
5164
  (MYSQL_SERVER_SUFFIX is set by the compilation environment)
5165
*/
5166
5167
static void set_server_version(void)
5168
{
5169
  char *end= strxmov(server_version, MYSQL_SERVER_VERSION,
5170
                     MYSQL_SERVER_SUFFIX_STR, NullS);
5171
#ifndef DBUG_OFF
5172
  if (!strstr(MYSQL_SERVER_SUFFIX_STR, "-debug"))
5173
    end= strmov(end, "-debug");
5174
#endif
5175
  if (opt_log || opt_update_log || opt_slow_log || opt_bin_log)
5176
    strmov(end, "-log");                        // This may slow down system
5177
}
5178
5179
5180
static char *get_relative_path(const char *path)
5181
{
5182
  if (test_if_hard_path(path) &&
5183
      is_prefix(path,DEFAULT_MYSQL_HOME) &&
5184
      strcmp(DEFAULT_MYSQL_HOME,FN_ROOTDIR))
5185
  {
5186
    path+=(uint) strlen(DEFAULT_MYSQL_HOME);
5187
    while (*path == FN_LIBCHAR)
5188
      path++;
5189
  }
5190
  return (char*) path;
5191
}
5192
5193
5194
/**
5195
  Fix filename and replace extension where 'dir' is relative to
5196
  mysql_real_data_home.
5197
  @return
5198
    1 if len(path) > FN_REFLEN
5199
*/
5200
5201
bool
5202
fn_format_relative_to_data_home(char * to, const char *name,
5203
				const char *dir, const char *extension)
5204
{
5205
  char tmp_path[FN_REFLEN];
5206
  if (!test_if_hard_path(dir))
5207
  {
5208
    strxnmov(tmp_path,sizeof(tmp_path)-1, mysql_real_data_home,
5209
	     dir, NullS);
5210
    dir=tmp_path;
5211
  }
5212
  return !fn_format(to, name, dir, extension,
5213
		    MY_APPEND_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH);
5214
}
5215
5216
5217
static void fix_paths(void)
5218
{
5219
  char buff[FN_REFLEN],*pos;
5220
  convert_dirname(mysql_home,mysql_home,NullS);
5221
  /* Resolve symlinks to allow 'mysql_home' to be a relative symlink */
5222
  my_realpath(mysql_home,mysql_home,MYF(0));
5223
  /* Ensure that mysql_home ends in FN_LIBCHAR */
5224
  pos=strend(mysql_home);
5225
  if (pos[-1] != FN_LIBCHAR)
5226
  {
5227
    pos[0]= FN_LIBCHAR;
5228
    pos[1]= 0;
5229
  }
5230
  convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
5231
  (void) fn_format(buff, mysql_real_data_home, "", "",
5232
                   (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
5233
  (void) unpack_dirname(mysql_unpacked_real_data_home, buff);
5234
  convert_dirname(language,language,NullS);
5235
  (void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir
5236
  (void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home);
5237
  (void) my_load_path(pidfile_name,pidfile_name,mysql_real_data_home);
5238
  (void) my_load_path(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr :
5239
                                      get_relative_path(PLUGINDIR), mysql_home);
5240
  opt_plugin_dir_ptr= opt_plugin_dir;
5241
5242
  char *sharedir=get_relative_path(SHAREDIR);
5243
  if (test_if_hard_path(sharedir))
5244
    strmake(buff,sharedir,sizeof(buff)-1);		/* purecov: tested */
5245
  else
5246
    strxnmov(buff,sizeof(buff)-1,mysql_home,sharedir,NullS);
5247
  convert_dirname(buff,buff,NullS);
5248
  (void) my_load_path(language,language,buff);
5249
5250
  /* If --character-sets-dir isn't given, use shared library dir */
5251
  if (charsets_dir != mysql_charsets_dir)
5252
  {
5253
    strxnmov(mysql_charsets_dir, sizeof(mysql_charsets_dir)-1, buff,
5254
	     CHARSET_DIR, NullS);
5255
  }
5256
  (void) my_load_path(mysql_charsets_dir, mysql_charsets_dir, buff);
5257
  convert_dirname(mysql_charsets_dir, mysql_charsets_dir, NullS);
5258
  charsets_dir=mysql_charsets_dir;
5259
5260
  if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir))
5261
    exit(1);
5262
  if (!slave_load_tmpdir)
5263
  {
5264
    if (!(slave_load_tmpdir = (char*) my_strdup(mysql_tmpdir, MYF(MY_FAE))))
5265
      exit(1);
5266
  }
5267
  /*
5268
    Convert the secure-file-priv option to system format, allowing
5269
    a quick strcmp to check if read or write is in an allowed dir
5270
   */
5271
  if (opt_secure_file_priv)
5272
  {
5273
    convert_dirname(buff, opt_secure_file_priv, NullS);
5274
    my_free(opt_secure_file_priv, MYF(0));
5275
    opt_secure_file_priv= my_strdup(buff, MYF(MY_FAE));
5276
  }
5277
}
5278
5279
5280
static ulong find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
5281
                                   const char *option)
5282
{
5283
  ulong res;
5284
5285
  const char **ptr;
5286
  
5287
  if ((res= find_bit_type(x, bit_lib)) == ~(ulong) 0)
5288
  {
5289
    ptr= bit_lib->type_names;
5290
    if (!*x)
5291
      fprintf(stderr, "No option given to %s\n", option);
5292
    else
5293
      fprintf(stderr, "Wrong option to %s. Option(s) given: %s\n", option, x);
5294
    fprintf(stderr, "Alternatives are: '%s'", *ptr);
5295
    while (*++ptr)
5296
      fprintf(stderr, ",'%s'", *ptr);
5297
    fprintf(stderr, "\n");
5298
    exit(1);
5299
  }
5300
  return res;
5301
}
5302
5303
5304
/**
5305
  @return
5306
    a bitfield from a string of substrings separated by ','
5307
    or
5308
    ~(ulong) 0 on error.
5309
*/
5310
5311
static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
5312
{
5313
  bool found_end;
5314
  int  found_count;
5315
  const char *end,*i,*j;
5316
  const char **array, *pos;
5317
  ulong found,found_int,bit;
5318
  DBUG_ENTER("find_bit_type");
5319
  DBUG_PRINT("enter",("x: '%s'",x));
5320
5321
  found=0;
5322
  found_end= 0;
5323
  pos=(char *) x;
5324
  while (*pos == ' ') pos++;
5325
  found_end= *pos == 0;
5326
  while (!found_end)
5327
  {
5328
    if (!*(end=strcend(pos,',')))		/* Let end point at fieldend */
5329
    {
5330
      while (end > pos && end[-1] == ' ')
5331
	end--;					/* Skip end-space */
5332
      found_end=1;
5333
    }
5334
    found_int=0; found_count=0;
5335
    for (array=bit_lib->type_names, bit=1 ; (i= *array++) ; bit<<=1)
5336
    {
5337
      j=pos;
5338
      while (j != end)
5339
      {
5340
	if (my_toupper(mysqld_charset,*i++) !=
5341
            my_toupper(mysqld_charset,*j++))
5342
	  goto skip;
5343
      }
5344
      found_int=bit;
5345
      if (! *i)
5346
      {
5347
	found_count=1;
5348
	break;
5349
      }
5350
      else if (j != pos)			// Half field found
5351
      {
5352
	found_count++;				// Could be one of two values
5353
      }
5354
skip: ;
5355
    }
5356
    if (found_count != 1)
5357
      DBUG_RETURN(~(ulong) 0);				// No unique value
5358
    found|=found_int;
5359
    pos=end+1;
5360
  }
5361
5362
  DBUG_PRINT("exit",("bit-field: %ld",(ulong) found));
5363
  DBUG_RETURN(found);
5364
} /* find_bit_type */
5365
5366
5367
/**
5368
  Check if file system used for databases is case insensitive.
5369
5370
  @param dir_name			Directory to test
5371
5372
  @retval
5373
    -1  Don't know (Test failed)
5374
  @retval
5375
    0   File system is case sensitive
5376
  @retval
5377
    1   File system is case insensitive
5378
*/
5379
5380
static int test_if_case_insensitive(const char *dir_name)
5381
{
5382
  int result= 0;
5383
  File file;
5384
  char buff[FN_REFLEN], buff2[FN_REFLEN];
15 by brian
Fix for stat, NETWARE removal
5385
  struct stat stat_info;
1 by brian
clean slate
5386
  DBUG_ENTER("test_if_case_insensitive");
5387
5388
  fn_format(buff, glob_hostname, dir_name, ".lower-test",
5389
	    MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_REPLACE_DIR);
5390
  fn_format(buff2, glob_hostname, dir_name, ".LOWER-TEST",
5391
	    MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_REPLACE_DIR);
5392
  (void) my_delete(buff2, MYF(0));
5393
  if ((file= my_create(buff, 0666, O_RDWR, MYF(0))) < 0)
5394
  {
5395
    sql_print_warning("Can't create test file %s", buff);
5396
    DBUG_RETURN(-1);
5397
  }
5398
  my_close(file, MYF(0));
15 by brian
Fix for stat, NETWARE removal
5399
  if (!stat(buff2, &stat_info))
1 by brian
clean slate
5400
    result= 1;					// Can access file
5401
  (void) my_delete(buff, MYF(MY_WME));
5402
  DBUG_PRINT("exit", ("result: %d", result));
5403
  DBUG_RETURN(result);
5404
}
5405
5406
5407
/**
5408
  Create file to store pid number.
5409
*/
5410
static void create_pid_file()
5411
{
5412
  File file;
5413
  if ((file = my_create(pidfile_name,0664,
5414
			O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0)
5415
  {
5416
    char buff[21], *end;
5417
    end= int10_to_str((long) getpid(), buff, 10);
5418
    *end++= '\n';
5419
    if (!my_write(file, (uchar*) buff, (uint) (end-buff), MYF(MY_WME | MY_NABP)))
5420
    {
5421
      (void) my_close(file, MYF(0));
5422
      return;
5423
    }
5424
    (void) my_close(file, MYF(0));
5425
  }
5426
  sql_perror("Can't start server: can't create PID file");
5427
  exit(1);
5428
}
5429
5430
/** Clear most status variables. */
5431
void refresh_status(THD *thd)
5432
{
5433
  pthread_mutex_lock(&LOCK_status);
5434
5435
  /* Add thread's status variabes to global status */
5436
  add_to_status(&global_status_var, &thd->status_var);
5437
5438
  /* Reset thread's status variables */
5439
  bzero((uchar*) &thd->status_var, sizeof(thd->status_var));
5440
5441
  /* Reset some global variables */
5442
  reset_status_vars();
5443
5444
  /* Reset the counters of all key caches (default and named). */
5445
  process_key_caches(reset_key_cache_counters);
5446
  flush_status_time= time((time_t*) 0);
5447
  pthread_mutex_unlock(&LOCK_status);
5448
5449
  /*
5450
    Set max_used_connections to the number of currently open
5451
    connections.  Lock LOCK_thread_count out of LOCK_status to avoid
5452
    deadlocks.  Status reset becomes not atomic, but status data is
5453
    not exact anyway.
5454
  */
5455
  pthread_mutex_lock(&LOCK_thread_count);
5456
  max_used_connections= thread_count;
5457
  pthread_mutex_unlock(&LOCK_thread_count);
5458
}
5459
5460
5461
/*****************************************************************************
5462
  Instantiate templates
5463
*****************************************************************************/
5464
5465
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
5466
/* Used templates */
5467
template class I_List<THD>;
5468
template class I_List_iterator<THD>;
5469
template class I_List<i_string>;
5470
template class I_List<i_string_pair>;
5471
template class I_List<NAMED_LIST>;
5472
template class I_List<Statement>;
5473
template class I_List_iterator<Statement>;
5474
#endif