~stewart/drizzle/embedded-innodb-create-select-transaction-arrgh

« back to all changes in this revision

Viewing changes to sql/mysqld.cc

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

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