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