~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to sql/mysqld.cc

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
 
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 <my_stacktrace.h>
 
26
#include "mysqld_suffix.h"
 
27
#include "mysys_err.h"
 
28
#include "events.h"
 
29
#include "debug_sync.h"
 
30
 
 
31
#include "../storage/myisam/ha_myisam.h"
 
32
 
 
33
#include "rpl_injector.h"
 
34
 
 
35
#ifdef HAVE_SYS_PRCTL_H
 
36
#include <sys/prctl.h>
 
37
#endif
 
38
 
 
39
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
 
40
#if defined(NOT_ENOUGH_TESTED) \
 
41
  && defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000
 
42
#define OPT_NDB_SHM_DEFAULT 1
 
43
#else
 
44
#define OPT_NDB_SHM_DEFAULT 0
 
45
#endif
 
46
#endif
 
47
 
 
48
#ifndef DEFAULT_SKIP_THREAD_PRIORITY
 
49
#define DEFAULT_SKIP_THREAD_PRIORITY 0
 
50
#endif
 
51
 
 
52
#include <thr_alarm.h>
 
53
#include <ft_global.h>
 
54
#include <errmsg.h>
 
55
#include "sp_rcontext.h"
 
56
#include "sp_cache.h"
 
57
 
 
58
#define mysqld_charset &my_charset_latin1
 
59
 
 
60
#ifdef HAVE_purify
 
61
#define IF_PURIFY(A,B) (A)
 
62
#else
 
63
#define IF_PURIFY(A,B) (B)
 
64
#endif
 
65
 
 
66
#if SIZEOF_CHARP == 4
 
67
#define MAX_MEM_TABLE_SIZE ~(ulong) 0
 
68
#else
 
69
#define MAX_MEM_TABLE_SIZE ~(ulonglong) 0
 
70
#endif
 
71
 
 
72
/* stack traces are only supported on linux intel */
 
73
#if defined(__linux__)  && defined(__i386__) && defined(USE_PSTACK)
 
74
#define HAVE_STACK_TRACE_ON_SEGV
 
75
#include "../pstack/pstack.h"
 
76
char pstack_file_name[80];
 
77
#endif /* __linux__ */
 
78
 
 
79
/* We have HAVE_purify below as this speeds up the shutdown of MySQL */
 
80
 
 
81
#if defined(HAVE_DEC_3_2_THREADS) || defined(SIGNALS_DONT_BREAK_READ) || defined(HAVE_purify) && defined(__linux__)
 
82
#define HAVE_CLOSE_SERVER_SOCK 1
 
83
#endif
 
84
 
 
85
extern "C" {                                    // Because of SCO 3.2V4.2
 
86
#include <errno.h>
 
87
#include <sys/stat.h>
 
88
#ifndef __GNU_LIBRARY__
 
89
#define __GNU_LIBRARY__                         // Skip warnings in getopt.h
 
90
#endif
 
91
#include <my_getopt.h>
 
92
#ifdef HAVE_SYSENT_H
 
93
#include <sysent.h>
 
94
#endif
 
95
#ifdef HAVE_PWD_H
 
96
#include <pwd.h>                                // For getpwent
 
97
#endif
 
98
#ifdef HAVE_GRP_H
 
99
#include <grp.h>
 
100
#endif
 
101
#include <my_net.h>
 
102
 
 
103
#if !defined(__WIN__)
 
104
#  ifndef __NETWARE__
 
105
#include <sys/resource.h>
 
106
#  endif /* __NETWARE__ */
 
107
#ifdef HAVE_SYS_UN_H
 
108
#  include <sys/un.h>
 
109
#endif
 
110
#include <netdb.h>
 
111
#ifdef HAVE_SELECT_H
 
112
#  include <select.h>
 
113
#endif
 
114
#ifdef HAVE_SYS_SELECT_H
 
115
#include <sys/select.h>
 
116
#endif
 
117
#include <sys/utsname.h>
 
118
#endif /* __WIN__ */
 
119
 
 
120
#include <my_libwrap.h>
 
121
 
 
122
#ifdef HAVE_SYS_MMAN_H
 
123
#include <sys/mman.h>
 
124
#endif
 
125
 
 
126
#ifdef __WIN__ 
 
127
#include <crtdbg.h>
 
128
#define SIGNAL_FMT "exception 0x%x"
 
129
#else
 
130
#define SIGNAL_FMT "signal %d"
 
131
#endif
 
132
 
 
133
#ifdef __NETWARE__
 
134
#define zVOLSTATE_ACTIVE 6
 
135
#define zVOLSTATE_DEACTIVE 2
 
136
#define zVOLSTATE_MAINTENANCE 3
 
137
 
 
138
#undef __event_h__
 
139
#include <../include/event.h>
 
140
/*
 
141
  This #undef exists here because both libc of NetWare and MySQL have
 
142
  files named event.h which causes compilation errors.
 
143
*/
 
144
 
 
145
#include <nks/netware.h>
 
146
#include <nks/vm.h>
 
147
#include <library.h>
 
148
#include <monitor.h>
 
149
#include <zOmni.h>                              //For NEB
 
150
#include <neb.h>                                //For NEB
 
151
#include <nebpub.h>                             //For NEB
 
152
#include <zEvent.h>                             //For NSS event structures
 
153
#include <zPublics.h>
 
154
 
 
155
static void *neb_consumer_id= NULL;             //For storing NEB consumer id
 
156
static char datavolname[256]= {0};
 
157
static VolumeID_t datavolid;
 
158
static event_handle_t eh;
 
159
static Report_t ref;
 
160
static void *refneb= NULL;
 
161
my_bool event_flag= FALSE;
 
162
static int volumeid= -1;
 
163
 
 
164
  /* NEB event callback */
 
165
unsigned long neb_event_callback(struct EventBlock *eblock);
 
166
static void registerwithneb();
 
167
static void getvolumename();
 
168
static void getvolumeID(BYTE *volumeName);
 
169
#endif /* __NETWARE__ */
 
170
  
 
171
 
 
172
#ifdef _AIX41
 
173
int initgroups(const char *,unsigned int);
 
174
#endif
 
175
 
 
176
#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
 
177
#include <ieeefp.h>
 
178
#ifdef HAVE_FP_EXCEPT                           // Fix type conflict
 
179
typedef fp_except fp_except_t;
 
180
#endif
 
181
#endif /* __FreeBSD__ && HAVE_IEEEFP_H */
 
182
#ifdef HAVE_SYS_FPU_H
 
183
/* for IRIX to use set_fpc_csr() */
 
184
#include <sys/fpu.h>
 
185
#endif
 
186
 
 
187
inline void setup_fpu()
 
188
{
 
189
#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
 
190
  /* We can't handle floating point exceptions with threads, so disable
 
191
     this on freebsd
 
192
     Don't fall for overflow, underflow,divide-by-zero or loss of precision
 
193
  */
 
194
#if defined(__i386__)
 
195
  fpsetmask(~(FP_X_INV | FP_X_DNML | FP_X_OFL | FP_X_UFL | FP_X_DZ |
 
196
              FP_X_IMP));
 
197
#else
 
198
  fpsetmask(~(FP_X_INV |             FP_X_OFL | FP_X_UFL | FP_X_DZ |
 
199
              FP_X_IMP));
 
200
#endif /* __i386__ */
 
201
#endif /* __FreeBSD__ && HAVE_IEEEFP_H */
 
202
 
 
203
#ifdef HAVE_FESETROUND
 
204
    /* Set FPU rounding mode to "round-to-nearest" */
 
205
  fesetround(FE_TONEAREST);
 
206
#endif /* HAVE_FESETROUND */
 
207
    
 
208
#if defined(__sgi) && defined(HAVE_SYS_FPU_H)
 
209
  /* Enable denormalized DOUBLE values support for IRIX */
 
210
  union fpc_csr n;
 
211
  n.fc_word = get_fpc_csr();
 
212
  n.fc_struct.flush = 0;
 
213
  set_fpc_csr(n.fc_word);
 
214
#endif
 
215
}
 
216
 
 
217
} /* cplusplus */
 
218
 
 
219
#define MYSQL_KILL_SIGNAL SIGTERM
 
220
 
 
221
#ifdef HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R
 
222
#include <sys/types.h>
 
223
#else
 
224
#include <my_pthread.h>                 // For thr_setconcurency()
 
225
#endif
 
226
 
 
227
#ifdef SOLARIS
 
228
extern "C" int gethostname(char *name, int namelen);
 
229
#endif
 
230
 
 
231
extern "C" sig_handler handle_segfault(int sig);
 
232
 
 
233
#if defined(__linux__)
 
234
#define ENABLE_TEMP_POOL 1
 
235
#else
 
236
#define ENABLE_TEMP_POOL 0
 
237
#endif
 
238
 
 
239
/* Constants */
 
240
 
 
241
const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"};
 
242
/*
 
243
  WARNING: When adding new SQL modes don't forget to update the
 
244
           tables definitions that stores it's value.
 
245
           (ie: mysql.event, mysql.proc)
 
246
*/
 
247
static const char *sql_mode_names[]=
 
248
{
 
249
  "REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE",
 
250
  "?", "ONLY_FULL_GROUP_BY", "NO_UNSIGNED_SUBTRACTION",
 
251
  "NO_DIR_IN_CREATE",
 
252
  "POSTGRESQL", "ORACLE", "MSSQL", "DB2", "MAXDB", "NO_KEY_OPTIONS",
 
253
  "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", "MYSQL323", "MYSQL40", "ANSI",
 
254
  "NO_AUTO_VALUE_ON_ZERO", "NO_BACKSLASH_ESCAPES", "STRICT_TRANS_TABLES",
 
255
  "STRICT_ALL_TABLES",
 
256
  "NO_ZERO_IN_DATE", "NO_ZERO_DATE", "ALLOW_INVALID_DATES",
 
257
  "ERROR_FOR_DIVISION_BY_ZERO",
 
258
  "TRADITIONAL", "NO_AUTO_CREATE_USER", "HIGH_NOT_PRECEDENCE",
 
259
  "NO_ENGINE_SUBSTITUTION",
 
260
  "PAD_CHAR_TO_FULL_LENGTH",
 
261
  NullS
 
262
};
 
263
 
 
264
static const unsigned int sql_mode_names_len[]=
 
265
{
 
266
  /*REAL_AS_FLOAT*/               13,
 
267
  /*PIPES_AS_CONCAT*/             15,
 
268
  /*ANSI_QUOTES*/                 11,
 
269
  /*IGNORE_SPACE*/                12,
 
270
  /*?*/                           1,
 
271
  /*ONLY_FULL_GROUP_BY*/          18,
 
272
  /*NO_UNSIGNED_SUBTRACTION*/     23,
 
273
  /*NO_DIR_IN_CREATE*/            16,
 
274
  /*POSTGRESQL*/                  10,
 
275
  /*ORACLE*/                      6,
 
276
  /*MSSQL*/                       5,
 
277
  /*DB2*/                         3,
 
278
  /*MAXDB*/                       5,
 
279
  /*NO_KEY_OPTIONS*/              14,
 
280
  /*NO_TABLE_OPTIONS*/            16,
 
281
  /*NO_FIELD_OPTIONS*/            16,
 
282
  /*MYSQL323*/                    8,
 
283
  /*MYSQL40*/                     7,
 
284
  /*ANSI*/                        4,
 
285
  /*NO_AUTO_VALUE_ON_ZERO*/       21,
 
286
  /*NO_BACKSLASH_ESCAPES*/        20,
 
287
  /*STRICT_TRANS_TABLES*/         19,
 
288
  /*STRICT_ALL_TABLES*/           17,
 
289
  /*NO_ZERO_IN_DATE*/             15,
 
290
  /*NO_ZERO_DATE*/                12,
 
291
  /*ALLOW_INVALID_DATES*/         19,
 
292
  /*ERROR_FOR_DIVISION_BY_ZERO*/  26,
 
293
  /*TRADITIONAL*/                 11,
 
294
  /*NO_AUTO_CREATE_USER*/         19,
 
295
  /*HIGH_NOT_PRECEDENCE*/         19,
 
296
  /*NO_ENGINE_SUBSTITUTION*/      22,
 
297
  /*PAD_CHAR_TO_FULL_LENGTH*/     23
 
298
};
 
299
 
 
300
TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"",
 
301
                            sql_mode_names,
 
302
                            (unsigned int *)sql_mode_names_len };
 
303
 
 
304
static const char *optimizer_switch_names[]=
 
305
{
 
306
  "index_merge","index_merge_union","index_merge_sort_union", 
 
307
  "index_merge_intersection", "default", NullS
 
308
};
 
309
/* Corresponding defines are named OPTIMIZER_SWITCH_XXX */
 
310
static const unsigned int optimizer_switch_names_len[]=
 
311
{
 
312
  sizeof("index_merge") - 1,
 
313
  sizeof("index_merge_union") - 1,
 
314
  sizeof("index_merge_sort_union") - 1,
 
315
  sizeof("index_merge_intersection") - 1,
 
316
  sizeof("default") - 1
 
317
};
 
318
TYPELIB optimizer_switch_typelib= { array_elements(optimizer_switch_names)-1,"",
 
319
                                    optimizer_switch_names,
 
320
                                    (unsigned int *)optimizer_switch_names_len };
 
321
 
 
322
static const char *tc_heuristic_recover_names[]=
 
323
{
 
324
  "COMMIT", "ROLLBACK", NullS
 
325
};
 
326
static TYPELIB tc_heuristic_recover_typelib=
 
327
{
 
328
  array_elements(tc_heuristic_recover_names)-1,"",
 
329
  tc_heuristic_recover_names, NULL
 
330
};
 
331
 
 
332
static const char *thread_handling_names[]=
 
333
{ "one-thread-per-connection", "no-threads",
 
334
#if HAVE_POOL_OF_THREADS == 1
 
335
  "pool-of-threads",
 
336
#endif
 
337
  NullS};
 
338
 
 
339
TYPELIB thread_handling_typelib=
 
340
{
 
341
  array_elements(thread_handling_names) - 1, "",
 
342
  thread_handling_names, NULL
 
343
};
 
344
 
 
345
const char *first_keyword= "first", *binary_keyword= "BINARY";
 
346
const char *my_localhost= "localhost", *delayed_user= "DELAYED";
 
347
#if SIZEOF_OFF_T > 4 && defined(BIG_TABLES)
 
348
#define GET_HA_ROWS GET_ULL
 
349
#else
 
350
#define GET_HA_ROWS GET_ULONG
 
351
#endif
 
352
 
 
353
bool opt_large_files= sizeof(my_off_t) > 4;
 
354
 
 
355
/*
 
356
  Used with --help for detailed option
 
357
*/
 
358
static my_bool opt_help= 0, opt_verbose= 0;
 
359
 
 
360
arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
 
361
{{&Arg_comparator::compare_string,     &Arg_comparator::compare_e_string},
 
362
 {&Arg_comparator::compare_real,       &Arg_comparator::compare_e_real},
 
363
 {&Arg_comparator::compare_int_signed, &Arg_comparator::compare_e_int},
 
364
 {&Arg_comparator::compare_row,        &Arg_comparator::compare_e_row},
 
365
 {&Arg_comparator::compare_decimal,    &Arg_comparator::compare_e_decimal}};
 
366
 
 
367
const char *log_output_names[] = { "NONE", "FILE", "TABLE", NullS};
 
368
static const unsigned int log_output_names_len[]= { 4, 4, 5, 0 };
 
369
TYPELIB log_output_typelib= {array_elements(log_output_names)-1,"",
 
370
                             log_output_names, 
 
371
                             (unsigned int *) log_output_names_len};
 
372
 
 
373
/* static variables */
 
374
 
 
375
/* the default log output is log tables */
 
376
static bool lower_case_table_names_used= 0;
 
377
static bool volatile select_thread_in_use, signal_thread_in_use;
 
378
static bool volatile ready_to_exit;
 
379
static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0;
 
380
static my_bool opt_short_log_format= 0;
 
381
static uint kill_cached_threads, wake_thread;
 
382
static ulong killed_threads, thread_created;
 
383
static ulong max_used_connections;
 
384
static ulong my_bind_addr;                      /**< the address we bind to */
 
385
static volatile ulong cached_thread_count= 0;
 
386
static const char *sql_mode_str= "OFF";
 
387
/* Text representation for OPTIMIZER_SWITCH_DEFAULT */
 
388
static const char *optimizer_switch_str="index_merge=on,index_merge_union=on,"
 
389
                                        "index_merge_sort_union=on,"
 
390
                                        "index_merge_intersection=on";
 
391
static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr;
 
392
static char *opt_init_slave, *language_ptr, *opt_init_connect;
 
393
static char *default_character_set_name;
 
394
static char *character_set_filesystem_name;
 
395
static char *lc_time_names_name;
 
396
static char *my_bind_addr_str;
 
397
static char *default_collation_name; 
 
398
static char *default_storage_engine_str;
 
399
static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME;
 
400
static I_List<THD> thread_cache;
 
401
static double long_query_time;
 
402
 
 
403
static pthread_cond_t COND_thread_cache, COND_flush_thread_cache;
 
404
 
 
405
/* Global variables */
 
406
 
 
407
bool opt_update_log, opt_bin_log, opt_ignore_builtin_innodb= 0;
 
408
my_bool opt_log, opt_slow_log;
 
409
ulong log_output_options;
 
410
my_bool opt_log_queries_not_using_indexes= 0;
 
411
bool opt_error_log= IF_WIN(1,0);
 
412
bool opt_disable_networking=0, opt_skip_show_db=0;
 
413
my_bool opt_character_set_client_handshake= 1;
 
414
bool server_id_supplied = 0;
 
415
bool opt_endinfo, using_udf_functions;
 
416
my_bool locked_in_memory;
 
417
bool opt_using_transactions;
 
418
bool volatile abort_loop;
 
419
bool volatile shutdown_in_progress;
 
420
/*
 
421
  True if the bootstrap thread is running. Protected by LOCK_thread_count,
 
422
  just like thread_count.
 
423
  Used in bootstrap() function to determine if the bootstrap thread
 
424
  has completed. Note, that we can't use 'thread_count' instead,
 
425
  since in 5.1, in presence of the Event Scheduler, there may be
 
426
  event threads running in parallel, so it's impossible to know
 
427
  what value of 'thread_count' is a sign of completion of the
 
428
  bootstrap thread.
 
429
 
 
430
  At the same time, we can't start the event scheduler after
 
431
  bootstrap either, since we want to be able to process event-related
 
432
  SQL commands in the init file and in --bootstrap mode.
 
433
*/
 
434
bool in_bootstrap= FALSE;
 
435
/**
 
436
   @brief 'grant_option' is used to indicate if privileges needs
 
437
   to be checked, in which case the lock, LOCK_grant, is used
 
438
   to protect access to the grant table.
 
439
   @note This flag is dropped in 5.1 
 
440
   @see grant_init()
 
441
 */
 
442
bool volatile grant_option;
 
443
 
 
444
my_bool opt_skip_slave_start = 0; ///< If set, slave is not autostarted
 
445
my_bool opt_reckless_slave = 0;
 
446
my_bool opt_enable_named_pipe= 0;
 
447
my_bool opt_local_infile, opt_slave_compressed_protocol;
 
448
my_bool opt_safe_user_create = 0, opt_no_mix_types = 0;
 
449
my_bool opt_show_slave_auth_info, opt_sql_bin_update = 0;
 
450
my_bool opt_log_slave_updates= 0;
 
451
bool slave_warning_issued = false; 
 
452
 
 
453
/*
 
454
  Legacy global handlerton. These will be removed (please do not add more).
 
455
*/
 
456
handlerton *heap_hton;
 
457
handlerton *myisam_hton;
 
458
handlerton *partition_hton;
 
459
 
 
460
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
 
461
const char *opt_ndbcluster_connectstring= 0;
 
462
const char *opt_ndb_connectstring= 0;
 
463
char opt_ndb_constrbuf[1024]= {0};
 
464
unsigned opt_ndb_constrbuf_len= 0;
 
465
my_bool opt_ndb_shm, opt_ndb_optimized_node_selection;
 
466
ulong opt_ndb_cache_check_time;
 
467
const char *opt_ndb_mgmd;
 
468
ulong opt_ndb_nodeid;
 
469
ulong ndb_extra_logging;
 
470
#ifdef HAVE_NDB_BINLOG
 
471
ulong ndb_report_thresh_binlog_epoch_slip;
 
472
ulong ndb_report_thresh_binlog_mem_usage;
 
473
#endif
 
474
 
 
475
extern const char *ndb_distribution_names[];
 
476
extern TYPELIB ndb_distribution_typelib;
 
477
extern const char *opt_ndb_distribution;
 
478
extern enum ndb_distribution opt_ndb_distribution_id;
 
479
#endif
 
480
my_bool opt_readonly, use_temp_pool, relay_log_purge;
 
481
my_bool opt_sync_frm, opt_allow_suspicious_udfs;
 
482
my_bool opt_secure_auth= 0;
 
483
char* opt_secure_file_priv= 0;
 
484
my_bool opt_log_slow_admin_statements= 0;
 
485
my_bool opt_log_slow_slave_statements= 0;
 
486
my_bool lower_case_file_system= 0;
 
487
my_bool opt_large_pages= 0;
 
488
my_bool opt_myisam_use_mmap= 0;
 
489
uint    opt_large_page_size= 0;
 
490
#if defined(ENABLED_DEBUG_SYNC)
 
491
uint    opt_debug_sync_timeout= 0;
 
492
#endif /* defined(ENABLED_DEBUG_SYNC) */
 
493
my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
 
494
/*
 
495
  True if there is at least one per-hour limit for some user, so we should
 
496
  check them before each query (and possibly reset counters when hour is
 
497
  changed). False otherwise.
 
498
*/
 
499
volatile bool mqh_used = 0;
 
500
my_bool opt_noacl;
 
501
my_bool sp_automatic_privileges= 1;
 
502
 
 
503
ulong opt_binlog_rows_event_max_size;
 
504
const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS};
 
505
TYPELIB binlog_format_typelib=
 
506
  { array_elements(binlog_format_names) - 1, "",
 
507
    binlog_format_names, NULL };
 
508
ulong opt_binlog_format_id= (ulong) BINLOG_FORMAT_UNSPEC;
 
509
const char *opt_binlog_format= binlog_format_names[opt_binlog_format_id];
 
510
#ifdef HAVE_INITGROUPS
 
511
static bool calling_initgroups= FALSE; /**< Used in SIGSEGV handler. */
 
512
#endif
 
513
uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
 
514
uint mysqld_port_timeout;
 
515
uint delay_key_write_options, protocol_version;
 
516
uint lower_case_table_names;
 
517
uint tc_heuristic_recover= 0;
 
518
uint volatile thread_count, thread_running;
 
519
ulonglong thd_startup_options;
 
520
ulong back_log, connect_timeout, concurrency, server_id;
 
521
ulong table_cache_size, table_def_size;
 
522
ulong what_to_log;
 
523
ulong query_buff_size, slow_launch_time, slave_open_temp_tables;
 
524
ulong open_files_limit, max_binlog_size, max_relay_log_size;
 
525
ulong slave_net_timeout, slave_trans_retries;
 
526
ulong slave_exec_mode_options;
 
527
const char *slave_exec_mode_str= "STRICT";
 
528
ulong thread_cache_size=0, thread_pool_size= 0;
 
529
ulong binlog_cache_size=0;
 
530
ulonglong  max_binlog_cache_size=0;
 
531
ulong query_cache_size=0;
 
532
ulong refresh_version;  /* Increments on each reload */
 
533
query_id_t global_query_id;
 
534
ulong aborted_threads, aborted_connects;
 
535
ulong delayed_insert_timeout, delayed_insert_limit, delayed_queue_size;
 
536
ulong delayed_insert_threads, delayed_insert_writes, delayed_rows_in_use;
 
537
ulong delayed_insert_errors,flush_time;
 
538
ulong specialflag=0;
 
539
ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
 
540
ulong max_connections, max_connect_errors;
 
541
uint  max_user_connections= 0;
 
542
/**
 
543
  Limit of the total number of prepared statements in the server.
 
544
  Is necessary to protect the server against out-of-memory attacks.
 
545
*/
 
546
ulong max_prepared_stmt_count;
 
547
/**
 
548
  Current total number of prepared statements in the server. This number
 
549
  is exact, and therefore may not be equal to the difference between
 
550
  `com_stmt_prepare' and `com_stmt_close' (global status variables), as
 
551
  the latter ones account for all registered attempts to prepare
 
552
  a statement (including unsuccessful ones).  Prepared statements are
 
553
  currently connection-local: if the same SQL query text is prepared in
 
554
  two different connections, this counts as two distinct prepared
 
555
  statements.
 
556
*/
 
557
ulong prepared_stmt_count=0;
 
558
ulong thread_id=1L,current_pid;
 
559
ulong slow_launch_threads = 0, sync_binlog_period;
 
560
ulong expire_logs_days = 0;
 
561
ulong rpl_recovery_rank=0;
 
562
const char *log_output_str= "FILE";
 
563
 
 
564
time_t server_start_time, flush_status_time;
 
565
 
 
566
char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
 
567
char *default_tz_name;
 
568
char log_error_file[FN_REFLEN], glob_hostname[FN_REFLEN];
 
569
char mysql_real_data_home[FN_REFLEN],
 
570
     language[FN_REFLEN], reg_ext[FN_EXTLEN], mysql_charsets_dir[FN_REFLEN],
 
571
     *opt_init_file, *opt_tc_log_file,
 
572
     def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
 
573
char mysql_unpacked_real_data_home[FN_REFLEN];
 
574
int mysql_unpacked_real_data_home_len;
 
575
uint reg_ext_length;
 
576
const key_map key_map_empty(0);
 
577
key_map key_map_full(0);                        // Will be initialized later
 
578
 
 
579
const char *opt_date_time_formats[3];
 
580
 
 
581
uint mysql_data_home_len;
 
582
char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home;
 
583
char server_version[SERVER_VERSION_LENGTH];
 
584
char *mysqld_unix_port, *opt_mysql_tmpdir;
 
585
const char **errmesg;                   /**< Error messages */
 
586
const char *myisam_recover_options_str="OFF";
 
587
const char *myisam_stats_method_str="nulls_unequal";
 
588
 
 
589
/** name of reference on left espression in rewritten IN subquery */
 
590
const char *in_left_expr_name= "<left expr>";
 
591
/** name of additional condition */
 
592
const char *in_additional_cond= "<IN COND>";
 
593
const char *in_having_cond= "<IN HAVING>";
 
594
 
 
595
my_decimal decimal_zero;
 
596
/* classes for comparation parsing/processing */
 
597
Eq_creator eq_creator;
 
598
Ne_creator ne_creator;
 
599
Gt_creator gt_creator;
 
600
Lt_creator lt_creator;
 
601
Ge_creator ge_creator;
 
602
Le_creator le_creator;
 
603
 
 
604
FILE *bootstrap_file;
 
605
int bootstrap_error;
 
606
FILE *stderror_file=0;
 
607
 
 
608
I_List<THD> threads;
 
609
I_List<NAMED_LIST> key_caches;
 
610
Rpl_filter* rpl_filter;
 
611
Rpl_filter* binlog_filter;
 
612
 
 
613
struct system_variables global_system_variables;
 
614
struct system_variables max_system_variables;
 
615
struct system_status_var global_status_var;
 
616
 
 
617
MY_TMPDIR mysql_tmpdir_list;
 
618
MY_BITMAP temp_pool;
 
619
 
 
620
CHARSET_INFO *system_charset_info, *files_charset_info ;
 
621
CHARSET_INFO *national_charset_info, *table_alias_charset;
 
622
CHARSET_INFO *character_set_filesystem;
 
623
 
 
624
MY_LOCALE *my_default_lc_time_names;
 
625
 
 
626
SHOW_COMP_OPTION have_ssl, have_symlink, have_dlopen, have_query_cache;
 
627
SHOW_COMP_OPTION have_geometry, have_rtree_keys;
 
628
SHOW_COMP_OPTION have_crypt, have_compress;
 
629
SHOW_COMP_OPTION have_community_features;
 
630
 
 
631
/* Thread specific variables */
 
632
 
 
633
pthread_key(MEM_ROOT**,THR_MALLOC);
 
634
pthread_key(THD*, THR_THD);
 
635
pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
 
636
                LOCK_mapped_file, LOCK_status, LOCK_global_read_lock,
 
637
                LOCK_error_log, LOCK_uuid_generator,
 
638
                LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
 
639
                LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
 
640
                LOCK_global_system_variables,
 
641
                LOCK_user_conn, LOCK_slave_list, LOCK_active_mi,
 
642
                LOCK_connection_count;
 
643
/**
 
644
  The below lock protects access to two global server variables:
 
645
  max_prepared_stmt_count and prepared_stmt_count. These variables
 
646
  set the limit and hold the current total number of prepared statements
 
647
  in the server, respectively. As PREPARE/DEALLOCATE rate in a loaded
 
648
  server may be fairly high, we need a dedicated lock.
 
649
*/
 
650
pthread_mutex_t LOCK_prepared_stmt_count;
 
651
#ifdef HAVE_OPENSSL
 
652
pthread_mutex_t LOCK_des_key_file;
 
653
#endif
 
654
rw_lock_t       LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
 
655
rw_lock_t       LOCK_system_variables_hash;
 
656
pthread_cond_t COND_refresh, COND_thread_count, COND_global_read_lock;
 
657
pthread_t signal_thread;
 
658
pthread_attr_t connection_attrib;
 
659
pthread_mutex_t  LOCK_server_started;
 
660
pthread_cond_t  COND_server_started;
 
661
 
 
662
int mysqld_server_started= 0;
 
663
 
 
664
File_parser_dummy_hook file_parser_dummy_hook;
 
665
 
 
666
/* replication parameters, if master_host is not NULL, we are a slave */
 
667
uint master_port= MYSQL_PORT, master_connect_retry = 60;
 
668
uint report_port= MYSQL_PORT;
 
669
ulong master_retry_count=0;
 
670
char *master_user, *master_password, *master_host, *master_info_file;
 
671
char *relay_log_info_file, *report_user, *report_password, *report_host;
 
672
char *opt_relay_logname = 0, *opt_relaylog_index_name=0;
 
673
my_bool master_ssl;
 
674
char *master_ssl_key, *master_ssl_cert;
 
675
char *master_ssl_ca, *master_ssl_capath, *master_ssl_cipher;
 
676
char *opt_logname, *opt_slow_logname;
 
677
 
 
678
/* Static variables */
 
679
 
 
680
static bool kill_in_progress, segfaulted;
 
681
#ifdef HAVE_STACK_TRACE_ON_SEGV
 
682
static my_bool opt_do_pstack;
 
683
#endif /* HAVE_STACK_TRACE_ON_SEGV */
 
684
static my_bool opt_bootstrap, opt_myisam_log;
 
685
static int cleanup_done;
 
686
static ulong opt_specialflag, opt_myisam_block_size;
 
687
static char *opt_update_logname, *opt_binlog_index_name;
 
688
static char *opt_tc_heuristic_recover;
 
689
static char *mysql_home_ptr, *pidfile_name_ptr;
 
690
static int defaults_argc;
 
691
static char **defaults_argv;
 
692
static char *opt_bin_logname;
 
693
 
 
694
int orig_argc;
 
695
char **orig_argv;
 
696
 
 
697
static my_socket unix_sock,ip_sock;
 
698
struct rand_struct sql_rand; ///< used by sql_class.cc:THD::THD()
 
699
 
 
700
#ifndef EMBEDDED_LIBRARY
 
701
struct passwd *user_info;
 
702
static pthread_t select_thread;
 
703
static uint thr_kill_signal;
 
704
#endif
 
705
 
 
706
/* OS specific variables */
 
707
 
 
708
#ifdef __WIN__
 
709
#undef   getpid
 
710
#include <process.h>
 
711
 
 
712
static pthread_cond_t COND_handler_count;
 
713
static uint handler_count;
 
714
static bool start_mode=0, use_opt_args;
 
715
static int opt_argc;
 
716
static char **opt_argv;
 
717
 
 
718
#if !defined(EMBEDDED_LIBRARY)
 
719
static HANDLE hEventShutdown;
 
720
static char shutdown_event_name[40];
 
721
#include "nt_servc.h"
 
722
static   NTService  Service;          ///< Service object for WinNT
 
723
#endif /* EMBEDDED_LIBRARY */
 
724
#endif /* __WIN__ */
 
725
 
 
726
#ifdef __NT__
 
727
static char pipe_name[512];
 
728
static SECURITY_ATTRIBUTES saPipeSecurity;
 
729
static SECURITY_DESCRIPTOR sdPipeDescriptor;
 
730
static HANDLE hPipe = INVALID_HANDLE_VALUE;
 
731
#endif
 
732
 
 
733
#ifndef EMBEDDED_LIBRARY
 
734
bool mysqld_embedded=0;
 
735
#else
 
736
bool mysqld_embedded=1;
 
737
#endif
 
738
 
 
739
static my_bool plugins_are_initialized= FALSE;
 
740
 
 
741
#ifndef DBUG_OFF
 
742
static const char* default_dbug_option;
 
743
#endif
 
744
#ifdef HAVE_LIBWRAP
 
745
const char *libwrapName= NULL;
 
746
int allow_severity = LOG_INFO;
 
747
int deny_severity = LOG_WARNING;
 
748
#endif
 
749
#ifdef HAVE_QUERY_CACHE
 
750
static ulong query_cache_limit= 0;
 
751
ulong query_cache_min_res_unit= QUERY_CACHE_MIN_RESULT_DATA_SIZE;
 
752
Query_cache query_cache;
 
753
#endif
 
754
#ifdef HAVE_SMEM
 
755
char *shared_memory_base_name= default_shared_memory_base_name;
 
756
my_bool opt_enable_shared_memory;
 
757
HANDLE smem_event_connect_request= 0;
 
758
#endif
 
759
 
 
760
scheduler_functions thread_scheduler;
 
761
 
 
762
#define SSL_VARS_NOT_STATIC
 
763
#include "sslopt-vars.h"
 
764
#ifdef HAVE_OPENSSL
 
765
#include <openssl/crypto.h>
 
766
#ifndef HAVE_YASSL
 
767
typedef struct CRYPTO_dynlock_value
 
768
{
 
769
  rw_lock_t lock;
 
770
} openssl_lock_t;
 
771
 
 
772
static openssl_lock_t *openssl_stdlocks;
 
773
static openssl_lock_t *openssl_dynlock_create(const char *, int);
 
774
static void openssl_dynlock_destroy(openssl_lock_t *, const char *, int);
 
775
static void openssl_lock_function(int, int, const char *, int);
 
776
static void openssl_lock(int, openssl_lock_t *, const char *, int);
 
777
static unsigned long openssl_id_function();
 
778
#endif
 
779
char *des_key_file;
 
780
struct st_VioSSLFd *ssl_acceptor_fd;
 
781
#endif /* HAVE_OPENSSL */
 
782
 
 
783
/**
 
784
  Number of currently active user connections. The variable is protected by
 
785
  LOCK_connection_count.
 
786
*/
 
787
uint connection_count= 0;
 
788
 
 
789
/* Function declarations */
 
790
 
 
791
pthread_handler_t signal_hand(void *arg);
 
792
static int mysql_init_variables(void);
 
793
static int get_options(int *argc,char **argv);
 
794
extern "C" my_bool mysqld_get_one_option(int, const struct my_option *, char *);
 
795
static void set_server_version(void);
 
796
static int init_thread_environment();
 
797
static char *get_relative_path(const char *path);
 
798
static int fix_paths(void);
 
799
pthread_handler_t handle_connections_sockets(void *arg);
 
800
pthread_handler_t kill_server_thread(void *arg);
 
801
static void bootstrap(FILE *file);
 
802
static bool read_init_file(char *file_name);
 
803
#ifdef __NT__
 
804
pthread_handler_t handle_connections_namedpipes(void *arg);
 
805
#endif
 
806
#ifdef HAVE_SMEM
 
807
pthread_handler_t handle_connections_shared_memory(void *arg);
 
808
#endif
 
809
pthread_handler_t handle_slave(void *arg);
 
810
static ulong find_bit_type(const char *x, TYPELIB *bit_lib);
 
811
static ulong find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
 
812
                                   const char *option, int *error);
 
813
static void clean_up(bool print_message);
 
814
static int test_if_case_insensitive(const char *dir_name);
 
815
 
 
816
#ifndef EMBEDDED_LIBRARY
 
817
static void usage(void);
 
818
static void start_signal_handler(void);
 
819
static void close_server_sock();
 
820
static void clean_up_mutexes(void);
 
821
static void wait_for_signal_thread_to_end(void);
 
822
static void create_pid_file();
 
823
static void end_ssl();
 
824
#endif
 
825
 
 
826
 
 
827
#ifndef EMBEDDED_LIBRARY
 
828
/****************************************************************************
 
829
** Code to end mysqld
 
830
****************************************************************************/
 
831
 
 
832
static void close_connections(void)
 
833
{
 
834
#ifdef EXTRA_DEBUG
 
835
  int count=0;
 
836
#endif
 
837
  DBUG_ENTER("close_connections");
 
838
 
 
839
  /* Clear thread cache */
 
840
  kill_cached_threads++;
 
841
  flush_thread_cache();
 
842
 
 
843
  /* kill connection thread */
 
844
#if !defined(__WIN__) && !defined(__NETWARE__)
 
845
  DBUG_PRINT("quit", ("waiting for select thread: 0x%lx",
 
846
                      (ulong) select_thread));
 
847
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
848
 
 
849
  while (select_thread_in_use)
 
850
  {
 
851
    struct timespec abstime;
 
852
    int error;
 
853
    LINT_INIT(error);
 
854
    DBUG_PRINT("info",("Waiting for select thread"));
 
855
 
 
856
#ifndef DONT_USE_THR_ALARM
 
857
    if (pthread_kill(select_thread, thr_client_alarm))
 
858
      break;                                    // allready dead
 
859
#endif
 
860
    set_timespec(abstime, 2);
 
861
    for (uint tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
 
862
    {
 
863
      error=pthread_cond_timedwait(&COND_thread_count,&LOCK_thread_count,
 
864
                                   &abstime);
 
865
      if (error != EINTR)
 
866
        break;
 
867
    }
 
868
#ifdef EXTRA_DEBUG
 
869
    if (error != 0 && !count++)
 
870
      sql_print_error("Got error %d from pthread_cond_timedwait",error);
 
871
#endif
 
872
    close_server_sock();
 
873
  }
 
874
  (void) pthread_mutex_unlock(&LOCK_thread_count);
 
875
#endif /* __WIN__ */
 
876
 
 
877
 
 
878
  /* Abort listening to new connections */
 
879
  DBUG_PRINT("quit",("Closing sockets"));
 
880
  if (!opt_disable_networking )
 
881
  {
 
882
    if (ip_sock != INVALID_SOCKET)
 
883
    {
 
884
      (void) shutdown(ip_sock, SHUT_RDWR);
 
885
      (void) closesocket(ip_sock);
 
886
      ip_sock= INVALID_SOCKET;
 
887
    }
 
888
  }
 
889
#ifdef __NT__
 
890
  if (hPipe != INVALID_HANDLE_VALUE && opt_enable_named_pipe)
 
891
  {
 
892
    HANDLE temp;
 
893
    DBUG_PRINT("quit", ("Closing named pipes") );
 
894
 
 
895
    /* Create connection to the handle named pipe handler to break the loop */
 
896
    if ((temp = CreateFile(pipe_name,
 
897
                           GENERIC_READ | GENERIC_WRITE,
 
898
                           0,
 
899
                           NULL,
 
900
                           OPEN_EXISTING,
 
901
                           0,
 
902
                           NULL )) != INVALID_HANDLE_VALUE)
 
903
    {
 
904
      WaitNamedPipe(pipe_name, 1000);
 
905
      DWORD dwMode = PIPE_READMODE_BYTE | PIPE_WAIT;
 
906
      SetNamedPipeHandleState(temp, &dwMode, NULL, NULL);
 
907
      CancelIo(temp);
 
908
      DisconnectNamedPipe(temp);
 
909
      CloseHandle(temp);
 
910
    }
 
911
  }
 
912
#endif
 
913
#ifdef HAVE_SYS_UN_H
 
914
  if (unix_sock != INVALID_SOCKET)
 
915
  {
 
916
    (void) shutdown(unix_sock, SHUT_RDWR);
 
917
    (void) closesocket(unix_sock);
 
918
    (void) unlink(mysqld_unix_port);
 
919
    unix_sock= INVALID_SOCKET;
 
920
  }
 
921
#endif
 
922
  end_thr_alarm(0);                      // Abort old alarms.
 
923
 
 
924
  /*
 
925
    First signal all threads that it's time to die
 
926
    This will give the threads some time to gracefully abort their
 
927
    statements and inform their clients that the server is about to die.
 
928
  */
 
929
 
 
930
  THD *tmp;
 
931
  (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
 
932
 
 
933
  I_List_iterator<THD> it(threads);
 
934
  while ((tmp=it++))
 
935
  {
 
936
    DBUG_PRINT("quit",("Informing thread %ld that it's time to die",
 
937
                       tmp->thread_id));
 
938
    /* We skip slave threads & scheduler on this first loop through. */
 
939
    if (tmp->slave_thread)
 
940
      continue;
 
941
 
 
942
    tmp->killed= THD::KILL_CONNECTION;
 
943
    thread_scheduler.post_kill_notification(tmp);
 
944
    if (tmp->mysys_var)
 
945
    {
 
946
      tmp->mysys_var->abort=1;
 
947
      pthread_mutex_lock(&tmp->mysys_var->mutex);
 
948
      if (tmp->mysys_var->current_cond)
 
949
      {
 
950
        pthread_mutex_lock(tmp->mysys_var->current_mutex);
 
951
        pthread_cond_broadcast(tmp->mysys_var->current_cond);
 
952
        pthread_mutex_unlock(tmp->mysys_var->current_mutex);
 
953
      }
 
954
      pthread_mutex_unlock(&tmp->mysys_var->mutex);
 
955
    }
 
956
  }
 
957
  (void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list
 
958
 
 
959
  Events::deinit();
 
960
  end_slave();
 
961
 
 
962
  if (thread_count)
 
963
    sleep(2);                                   // Give threads time to die
 
964
 
 
965
  /*
 
966
    Force remaining threads to die by closing the connection to the client
 
967
    This will ensure that threads that are waiting for a command from the
 
968
    client on a blocking read call are aborted.
 
969
  */
 
970
 
 
971
  for (;;)
 
972
  {
 
973
    DBUG_PRINT("quit",("Locking LOCK_thread_count"));
 
974
    (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
 
975
    if (!(tmp=threads.get()))
 
976
    {
 
977
      DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
 
978
      (void) pthread_mutex_unlock(&LOCK_thread_count);
 
979
      break;
 
980
    }
 
981
#ifndef __bsdi__                                // Bug in BSDI kernel
 
982
    if (tmp->vio_ok())
 
983
    {
 
984
      if (global_system_variables.log_warnings)
 
985
        sql_print_warning(ER(ER_FORCING_CLOSE),my_progname,
 
986
                          tmp->thread_id,
 
987
                          (tmp->main_security_ctx.user ?
 
988
                           tmp->main_security_ctx.user : ""));
 
989
      close_connection(tmp,0,0);
 
990
    }
 
991
#endif
 
992
    DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
 
993
    (void) pthread_mutex_unlock(&LOCK_thread_count);
 
994
  }
 
995
  /* All threads has now been aborted */
 
996
  DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count));
 
997
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
998
  while (thread_count)
 
999
  {
 
1000
    (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
 
1001
    DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
 
1002
  }
 
1003
  (void) pthread_mutex_unlock(&LOCK_thread_count);
 
1004
 
 
1005
  close_active_mi();
 
1006
  DBUG_PRINT("quit",("close_connections thread"));
 
1007
  DBUG_VOID_RETURN;
 
1008
}
 
1009
 
 
1010
 
 
1011
static void close_server_sock()
 
1012
{
 
1013
#ifdef HAVE_CLOSE_SERVER_SOCK
 
1014
  DBUG_ENTER("close_server_sock");
 
1015
  my_socket tmp_sock;
 
1016
  tmp_sock=ip_sock;
 
1017
  if (tmp_sock != INVALID_SOCKET)
 
1018
  {
 
1019
    ip_sock=INVALID_SOCKET;
 
1020
    DBUG_PRINT("info",("calling shutdown on TCP/IP socket"));
 
1021
    VOID(shutdown(tmp_sock, SHUT_RDWR));
 
1022
#if defined(__NETWARE__)
 
1023
    /*
 
1024
      The following code is disabled for normal systems as it causes MySQL
 
1025
      to hang on AIX 4.3 during shutdown
 
1026
    */
 
1027
    DBUG_PRINT("info",("calling closesocket on TCP/IP socket"));
 
1028
    VOID(closesocket(tmp_sock));
 
1029
#endif
 
1030
  }
 
1031
  tmp_sock=unix_sock;
 
1032
  if (tmp_sock != INVALID_SOCKET)
 
1033
  {
 
1034
    unix_sock=INVALID_SOCKET;
 
1035
    DBUG_PRINT("info",("calling shutdown on unix socket"));
 
1036
    VOID(shutdown(tmp_sock, SHUT_RDWR));
 
1037
#if defined(__NETWARE__)
 
1038
    /*
 
1039
      The following code is disabled for normal systems as it may cause MySQL
 
1040
      to hang on AIX 4.3 during shutdown
 
1041
    */
 
1042
    DBUG_PRINT("info",("calling closesocket on unix/IP socket"));
 
1043
    VOID(closesocket(tmp_sock));
 
1044
#endif
 
1045
    VOID(unlink(mysqld_unix_port));
 
1046
  }
 
1047
  DBUG_VOID_RETURN;
 
1048
#endif
 
1049
}
 
1050
 
 
1051
#endif /*EMBEDDED_LIBRARY*/
 
1052
 
 
1053
 
 
1054
void kill_mysql(void)
 
1055
{
 
1056
  DBUG_ENTER("kill_mysql");
 
1057
 
 
1058
#if defined(SIGNALS_DONT_BREAK_READ) && !defined(EMBEDDED_LIBRARY)
 
1059
  abort_loop=1;                                 // Break connection loops
 
1060
  close_server_sock();                          // Force accept to wake up
 
1061
#endif
 
1062
 
 
1063
#if defined(__WIN__)
 
1064
#if !defined(EMBEDDED_LIBRARY)
 
1065
  {
 
1066
    if (!SetEvent(hEventShutdown))
 
1067
    {
 
1068
      DBUG_PRINT("error",("Got error: %ld from SetEvent",GetLastError()));
 
1069
    }
 
1070
    /*
 
1071
      or:
 
1072
      HANDLE hEvent=OpenEvent(0, FALSE, "MySqlShutdown");
 
1073
      SetEvent(hEventShutdown);
 
1074
      CloseHandle(hEvent);
 
1075
    */
 
1076
  }
 
1077
#endif
 
1078
#elif defined(HAVE_PTHREAD_KILL)
 
1079
  if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL))
 
1080
  {
 
1081
    DBUG_PRINT("error",("Got error %d from pthread_kill",errno)); /* purecov: inspected */
 
1082
  }
 
1083
#elif !defined(SIGNALS_DONT_BREAK_READ)
 
1084
  kill(current_pid, MYSQL_KILL_SIGNAL);
 
1085
#endif
 
1086
  DBUG_PRINT("quit",("After pthread_kill"));
 
1087
  shutdown_in_progress=1;                       // Safety if kill didn't work
 
1088
#ifdef SIGNALS_DONT_BREAK_READ
 
1089
  if (!kill_in_progress)
 
1090
  {
 
1091
    pthread_t tmp;
 
1092
    abort_loop=1;
 
1093
    if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
 
1094
                           (void*) 0))
 
1095
      sql_print_error("Can't create thread to kill server");
 
1096
  }
 
1097
#endif
 
1098
  DBUG_VOID_RETURN;
 
1099
}
 
1100
 
 
1101
/**
 
1102
  Force server down. Kill all connections and threads and exit.
 
1103
 
 
1104
  @param  sig_ptr       Signal number that caused kill_server to be called.
 
1105
 
 
1106
  @note
 
1107
    A signal number of 0 mean that the function was not called
 
1108
    from a signal handler and there is thus no signal to block
 
1109
    or stop, we just want to kill the server.
 
1110
*/
 
1111
 
 
1112
#if defined(__NETWARE__)
 
1113
extern "C" void kill_server(int sig_ptr)
 
1114
#define RETURN_FROM_KILL_SERVER return
 
1115
#elif !defined(__WIN__)
 
1116
static void *kill_server(void *sig_ptr)
 
1117
#define RETURN_FROM_KILL_SERVER return 0
 
1118
#else
 
1119
static void __cdecl kill_server(int sig_ptr)
 
1120
#define RETURN_FROM_KILL_SERVER return
 
1121
#endif
 
1122
{
 
1123
  DBUG_ENTER("kill_server");
 
1124
#ifndef EMBEDDED_LIBRARY
 
1125
  int sig=(int) (long) sig_ptr;                 // This is passed a int
 
1126
  // if there is a signal during the kill in progress, ignore the other
 
1127
  if (kill_in_progress)                         // Safety
 
1128
  {
 
1129
    DBUG_LEAVE;
 
1130
    RETURN_FROM_KILL_SERVER;
 
1131
  }
 
1132
  kill_in_progress=TRUE;
 
1133
  abort_loop=1;                                 // This should be set
 
1134
  if (sig != 0) // 0 is not a valid signal number
 
1135
    my_sigset(sig, SIG_IGN);                    /* purify inspected */
 
1136
  if (sig == MYSQL_KILL_SIGNAL || sig == 0)
 
1137
    sql_print_information(ER(ER_NORMAL_SHUTDOWN),my_progname);
 
1138
  else
 
1139
    sql_print_error(ER(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */
 
1140
 
 
1141
#if defined(HAVE_SMEM) && defined(__WIN__)    
 
1142
  /*    
 
1143
   Send event to smem_event_connect_request for aborting    
 
1144
   */    
 
1145
  if (!SetEvent(smem_event_connect_request))    
 
1146
  {      
 
1147
          DBUG_PRINT("error",
 
1148
                ("Got error: %ld from SetEvent of smem_event_connect_request",
 
1149
                 GetLastError()));    
 
1150
  }
 
1151
#endif  
 
1152
  
 
1153
  close_connections();
 
1154
  if (sig != MYSQL_KILL_SIGNAL &&
 
1155
      sig != 0)
 
1156
    unireg_abort(1);                            /* purecov: inspected */
 
1157
  else
 
1158
    unireg_end();
 
1159
 
 
1160
  /* purecov: begin deadcode */
 
1161
#ifdef __NETWARE__
 
1162
  if (!event_flag)
 
1163
    pthread_join(select_thread, NULL);          // wait for main thread
 
1164
#endif /* __NETWARE__ */
 
1165
 
 
1166
  DBUG_LEAVE;                                   // Must match DBUG_ENTER()
 
1167
  my_thread_end();
 
1168
  pthread_exit(0);
 
1169
  /* purecov: end */
 
1170
 
 
1171
  RETURN_FROM_KILL_SERVER;                      // Avoid compiler warnings
 
1172
 
 
1173
#else /* EMBEDDED_LIBRARY*/
 
1174
 
 
1175
  DBUG_LEAVE;
 
1176
  RETURN_FROM_KILL_SERVER;
 
1177
 
 
1178
#endif /* EMBEDDED_LIBRARY */
 
1179
}
 
1180
 
 
1181
 
 
1182
#if defined(USE_ONE_SIGNAL_HAND) || (defined(__NETWARE__) && defined(SIGNALS_DONT_BREAK_READ))
 
1183
pthread_handler_t kill_server_thread(void *arg __attribute__((unused)))
 
1184
{
 
1185
  my_thread_init();                             // Initialize new thread
 
1186
  kill_server(0);
 
1187
  /* purecov: begin deadcode */
 
1188
  my_thread_end();
 
1189
  pthread_exit(0);
 
1190
  return 0;
 
1191
  /* purecov: end */
 
1192
}
 
1193
#endif
 
1194
 
 
1195
 
 
1196
extern "C" sig_handler print_signal_warning(int sig)
 
1197
{
 
1198
  if (global_system_variables.log_warnings)
 
1199
    sql_print_warning("Got signal %d from thread %ld", sig,my_thread_id());
 
1200
#ifdef DONT_REMEMBER_SIGNAL
 
1201
  my_sigset(sig,print_signal_warning);          /* int. thread system calls */
 
1202
#endif
 
1203
#if !defined(__WIN__) && !defined(__NETWARE__)
 
1204
  if (sig == SIGALRM)
 
1205
    alarm(2);                                   /* reschedule alarm */
 
1206
#endif
 
1207
}
 
1208
 
 
1209
#ifndef EMBEDDED_LIBRARY
 
1210
 
 
1211
/**
 
1212
  cleanup all memory and end program nicely.
 
1213
 
 
1214
    If SIGNALS_DONT_BREAK_READ is defined, this function is called
 
1215
    by the main thread. To get MySQL to shut down nicely in this case
 
1216
    (Mac OS X) we have to call exit() instead if pthread_exit().
 
1217
 
 
1218
  @note
 
1219
    This function never returns.
 
1220
*/
 
1221
void unireg_end(void)
 
1222
{
 
1223
  clean_up(1);
 
1224
  my_thread_end();
 
1225
#if defined(SIGNALS_DONT_BREAK_READ) && !defined(__NETWARE__)
 
1226
  exit(0);
 
1227
#else
 
1228
  pthread_exit(0);                              // Exit is in main thread
 
1229
#endif
 
1230
}
 
1231
 
 
1232
extern "C" void unireg_abort(int exit_code)
 
1233
{
 
1234
  DBUG_ENTER("unireg_abort");
 
1235
 
 
1236
  if (opt_help)
 
1237
    usage();
 
1238
  if (exit_code)
 
1239
    sql_print_error("Aborting\n");
 
1240
  clean_up(!opt_help && (exit_code || !opt_bootstrap)); /* purecov: inspected */
 
1241
  DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
 
1242
  wait_for_signal_thread_to_end();
 
1243
  clean_up_mutexes();
 
1244
  my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
 
1245
  exit(exit_code); /* purecov: inspected */
 
1246
}
 
1247
 
 
1248
#endif /*EMBEDDED_LIBRARY*/
 
1249
 
 
1250
 
 
1251
void clean_up(bool print_message)
 
1252
{
 
1253
  DBUG_PRINT("exit",("clean_up"));
 
1254
  if (cleanup_done++)
 
1255
    return; /* purecov: inspected */
 
1256
 
 
1257
  stop_handle_manager();
 
1258
  release_ddl_log();
 
1259
 
 
1260
  /*
 
1261
    make sure that handlers finish up
 
1262
    what they have that is dependent on the binlog
 
1263
  */
 
1264
  ha_binlog_end(current_thd);
 
1265
 
 
1266
  logger.cleanup_base();
 
1267
 
 
1268
  injector::free_instance();
 
1269
  mysql_bin_log.cleanup();
 
1270
 
 
1271
#ifdef HAVE_REPLICATION
 
1272
  if (use_slave_mask)
 
1273
    bitmap_free(&slave_error_mask);
 
1274
#endif
 
1275
  my_tz_free();
 
1276
  my_database_names_free();
 
1277
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
1278
  servers_free(1);
 
1279
  acl_free(1);
 
1280
  grant_free();
 
1281
#endif
 
1282
  query_cache_destroy();
 
1283
  table_cache_free();
 
1284
  table_def_free();
 
1285
  hostname_cache_free();
 
1286
  item_user_lock_free();
 
1287
  lex_free();                           /* Free some memory */
 
1288
  item_create_cleanup();
 
1289
  set_var_free();
 
1290
  if (!opt_noacl)
 
1291
  {
 
1292
#ifdef HAVE_DLOPEN
 
1293
    udf_free();
 
1294
#endif
 
1295
  }
 
1296
  plugin_shutdown();
 
1297
  ha_end();
 
1298
  if (tc_log)
 
1299
    tc_log->close();
 
1300
  xid_cache_free();
 
1301
  delete_elements(&key_caches, (void (*)(const char*, uchar*)) free_key_cache);
 
1302
  multi_keycache_free();
 
1303
  free_status_vars();
 
1304
  end_thr_alarm(1);                     /* Free allocated memory */
 
1305
  my_free_open_file_info();
 
1306
  my_free((char*) global_system_variables.date_format,
 
1307
          MYF(MY_ALLOW_ZERO_PTR));
 
1308
  my_free((char*) global_system_variables.time_format,
 
1309
          MYF(MY_ALLOW_ZERO_PTR));
 
1310
  my_free((char*) global_system_variables.datetime_format,
 
1311
          MYF(MY_ALLOW_ZERO_PTR));
 
1312
  if (defaults_argv)
 
1313
    free_defaults(defaults_argv);
 
1314
  my_free(sys_init_connect.value, MYF(MY_ALLOW_ZERO_PTR));
 
1315
  my_free(sys_init_slave.value, MYF(MY_ALLOW_ZERO_PTR));
 
1316
  my_free(sys_var_general_log_path.value, MYF(MY_ALLOW_ZERO_PTR));
 
1317
  my_free(sys_var_slow_log_path.value, MYF(MY_ALLOW_ZERO_PTR));
 
1318
  free_tmpdir(&mysql_tmpdir_list);
 
1319
#ifdef HAVE_REPLICATION
 
1320
  my_free(slave_load_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
 
1321
#endif
 
1322
  x_free(opt_bin_logname);
 
1323
  x_free(opt_relay_logname);
 
1324
  x_free(opt_secure_file_priv);
 
1325
  bitmap_free(&temp_pool);
 
1326
  free_max_user_conn();
 
1327
#ifdef HAVE_REPLICATION
 
1328
  end_slave_list();
 
1329
#endif
 
1330
  delete binlog_filter;
 
1331
  delete rpl_filter;
 
1332
#ifndef EMBEDDED_LIBRARY
 
1333
  end_ssl();
 
1334
#endif
 
1335
  vio_end();
 
1336
#ifdef USE_REGEX
 
1337
  my_regex_end();
 
1338
#endif
 
1339
#if defined(ENABLED_DEBUG_SYNC)
 
1340
  /* End the debug sync facility. See debug_sync.cc. */
 
1341
  debug_sync_end();
 
1342
#endif /* defined(ENABLED_DEBUG_SYNC) */
 
1343
 
 
1344
#if !defined(EMBEDDED_LIBRARY)
 
1345
  if (!opt_bootstrap)
 
1346
    (void) my_delete(pidfile_name,MYF(0));      // This may not always exist
 
1347
#endif
 
1348
  if (print_message && errmesg && server_start_time)
 
1349
    sql_print_information(ER(ER_SHUTDOWN_COMPLETE),my_progname);
 
1350
  thread_scheduler.end();
 
1351
  finish_client_errs();
 
1352
  my_free((uchar*) my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST),
 
1353
          MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
 
1354
  DBUG_PRINT("quit", ("Error messages freed"));
 
1355
  /* Tell main we are ready */
 
1356
  logger.cleanup_end();
 
1357
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
1358
  DBUG_PRINT("quit", ("got thread count lock"));
 
1359
  ready_to_exit=1;
 
1360
  /* do the broadcast inside the lock to ensure that my_end() is not called */
 
1361
  (void) pthread_cond_broadcast(&COND_thread_count);
 
1362
  (void) pthread_mutex_unlock(&LOCK_thread_count);
 
1363
 
 
1364
  /*
 
1365
    The following lines may never be executed as the main thread may have
 
1366
    killed us
 
1367
  */
 
1368
  DBUG_PRINT("quit", ("done with cleanup"));
 
1369
} /* clean_up */
 
1370
 
 
1371
 
 
1372
#ifndef EMBEDDED_LIBRARY
 
1373
 
 
1374
/**
 
1375
  This is mainly needed when running with purify, but it's still nice to
 
1376
  know that all child threads have died when mysqld exits.
 
1377
*/
 
1378
static void wait_for_signal_thread_to_end()
 
1379
{
 
1380
#ifndef __NETWARE__
 
1381
  uint i;
 
1382
  /*
 
1383
    Wait up to 10 seconds for signal thread to die. We use this mainly to
 
1384
    avoid getting warnings that my_thread_end has not been called
 
1385
  */
 
1386
  for (i= 0 ; i < 100 && signal_thread_in_use; i++)
 
1387
  {
 
1388
    if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL) != ESRCH)
 
1389
      break;
 
1390
    my_sleep(100);                              // Give it time to die
 
1391
  }
 
1392
#endif
 
1393
}
 
1394
 
 
1395
 
 
1396
static void clean_up_mutexes()
 
1397
{
 
1398
  (void) pthread_mutex_destroy(&LOCK_mysql_create_db);
 
1399
  (void) pthread_mutex_destroy(&LOCK_lock_db);
 
1400
  (void) pthread_mutex_destroy(&LOCK_Acl);
 
1401
  (void) rwlock_destroy(&LOCK_grant);
 
1402
  (void) pthread_mutex_destroy(&LOCK_open);
 
1403
  (void) pthread_mutex_destroy(&LOCK_thread_count);
 
1404
  (void) pthread_mutex_destroy(&LOCK_mapped_file);
 
1405
  (void) pthread_mutex_destroy(&LOCK_status);
 
1406
  (void) pthread_mutex_destroy(&LOCK_error_log);
 
1407
  (void) pthread_mutex_destroy(&LOCK_delayed_insert);
 
1408
  (void) pthread_mutex_destroy(&LOCK_delayed_status);
 
1409
  (void) pthread_mutex_destroy(&LOCK_delayed_create);
 
1410
  (void) pthread_mutex_destroy(&LOCK_manager);
 
1411
  (void) pthread_mutex_destroy(&LOCK_crypt);
 
1412
  (void) pthread_mutex_destroy(&LOCK_bytes_sent);
 
1413
  (void) pthread_mutex_destroy(&LOCK_bytes_received);
 
1414
  (void) pthread_mutex_destroy(&LOCK_user_conn);
 
1415
  (void) pthread_mutex_destroy(&LOCK_connection_count);
 
1416
  Events::destroy_mutexes();
 
1417
#ifdef HAVE_OPENSSL
 
1418
  (void) pthread_mutex_destroy(&LOCK_des_key_file);
 
1419
#ifndef HAVE_YASSL
 
1420
  for (int i= 0; i < CRYPTO_num_locks(); ++i)
 
1421
    (void) rwlock_destroy(&openssl_stdlocks[i].lock);
 
1422
  OPENSSL_free(openssl_stdlocks);
 
1423
#endif
 
1424
#endif
 
1425
#ifdef HAVE_REPLICATION
 
1426
  (void) pthread_mutex_destroy(&LOCK_rpl_status);
 
1427
  (void) pthread_cond_destroy(&COND_rpl_status);
 
1428
#endif
 
1429
  (void) pthread_mutex_destroy(&LOCK_active_mi);
 
1430
  (void) rwlock_destroy(&LOCK_sys_init_connect);
 
1431
  (void) rwlock_destroy(&LOCK_sys_init_slave);
 
1432
  (void) pthread_mutex_destroy(&LOCK_global_system_variables);
 
1433
  (void) rwlock_destroy(&LOCK_system_variables_hash);
 
1434
  (void) pthread_mutex_destroy(&LOCK_global_read_lock);
 
1435
  (void) pthread_mutex_destroy(&LOCK_uuid_generator);
 
1436
  (void) pthread_mutex_destroy(&LOCK_prepared_stmt_count);
 
1437
  (void) pthread_cond_destroy(&COND_thread_count);
 
1438
  (void) pthread_cond_destroy(&COND_refresh);
 
1439
  (void) pthread_cond_destroy(&COND_global_read_lock);
 
1440
  (void) pthread_cond_destroy(&COND_thread_cache);
 
1441
  (void) pthread_cond_destroy(&COND_flush_thread_cache);
 
1442
  (void) pthread_cond_destroy(&COND_manager);
 
1443
}
 
1444
 
 
1445
#endif /*EMBEDDED_LIBRARY*/
 
1446
 
 
1447
 
 
1448
/****************************************************************************
 
1449
** Init IP and UNIX socket
 
1450
****************************************************************************/
 
1451
 
 
1452
#ifndef EMBEDDED_LIBRARY
 
1453
static void set_ports()
 
1454
{
 
1455
  char  *env;
 
1456
  if (!mysqld_port && !opt_disable_networking)
 
1457
  {                                     // Get port if not from commandline
 
1458
    mysqld_port= MYSQL_PORT;
 
1459
 
 
1460
    /*
 
1461
      if builder specifically requested a default port, use that
 
1462
      (even if it coincides with our factory default).
 
1463
      only if they didn't do we check /etc/services (and, failing
 
1464
      on that, fall back to the factory default of 3306).
 
1465
      either default can be overridden by the environment variable
 
1466
      MYSQL_TCP_PORT, which in turn can be overridden with command
 
1467
      line options.
 
1468
    */
 
1469
 
 
1470
#if MYSQL_PORT_DEFAULT == 0
 
1471
    struct  servent *serv_ptr;
 
1472
    if ((serv_ptr= getservbyname("mysql", "tcp")))
 
1473
      mysqld_port= ntohs((u_short) serv_ptr->s_port); /* purecov: inspected */
 
1474
#endif
 
1475
    if ((env = getenv("MYSQL_TCP_PORT")))
 
1476
      mysqld_port= (uint) atoi(env);            /* purecov: inspected */
 
1477
  }
 
1478
  if (!mysqld_unix_port)
 
1479
  {
 
1480
#ifdef __WIN__
 
1481
    mysqld_unix_port= (char*) MYSQL_NAMEDPIPE;
 
1482
#else
 
1483
    mysqld_unix_port= (char*) MYSQL_UNIX_ADDR;
 
1484
#endif
 
1485
    if ((env = getenv("MYSQL_UNIX_PORT")))
 
1486
      mysqld_unix_port= env;                    /* purecov: inspected */
 
1487
  }
 
1488
}
 
1489
 
 
1490
/* Change to run as another user if started with --user */
 
1491
 
 
1492
static struct passwd *check_user(const char *user)
 
1493
{
 
1494
#if !defined(__WIN__) && !defined(__NETWARE__)
 
1495
  struct passwd *tmp_user_info;
 
1496
  uid_t user_id= geteuid();
 
1497
 
 
1498
  // Don't bother if we aren't superuser
 
1499
  if (user_id)
 
1500
  {
 
1501
    if (user)
 
1502
    {
 
1503
      /* Don't give a warning, if real user is same as given with --user */
 
1504
      /* purecov: begin tested */
 
1505
      tmp_user_info= getpwnam(user);
 
1506
      if ((!tmp_user_info || user_id != tmp_user_info->pw_uid) &&
 
1507
          global_system_variables.log_warnings)
 
1508
        sql_print_warning(
 
1509
                    "One can only use the --user switch if running as root\n");
 
1510
      /* purecov: end */
 
1511
    }
 
1512
    return NULL;
 
1513
  }
 
1514
  if (!user)
 
1515
  {
 
1516
    if (!opt_bootstrap)
 
1517
    {
 
1518
      sql_print_error("Fatal error: Please read \"Security\" section of the manual to find out how to run mysqld as root!\n");
 
1519
      unireg_abort(1);
 
1520
    }
 
1521
    return NULL;
 
1522
  }
 
1523
  /* purecov: begin tested */
 
1524
  if (!strcmp(user,"root"))
 
1525
    return NULL;                        // Avoid problem with dynamic libraries
 
1526
 
 
1527
  if (!(tmp_user_info= getpwnam(user)))
 
1528
  {
 
1529
    // Allow a numeric uid to be used
 
1530
    const char *pos;
 
1531
    for (pos= user; my_isdigit(mysqld_charset,*pos); pos++) ;
 
1532
    if (*pos)                                   // Not numeric id
 
1533
      goto err;
 
1534
    if (!(tmp_user_info= getpwuid(atoi(user))))
 
1535
      goto err;
 
1536
  }
 
1537
  return tmp_user_info;
 
1538
  /* purecov: end */
 
1539
 
 
1540
err:
 
1541
  sql_print_error("Fatal error: Can't change to run as user '%s' ;  Please check that the user exists!\n",user);
 
1542
  unireg_abort(1);
 
1543
 
 
1544
#ifdef PR_SET_DUMPABLE
 
1545
  if (test_flags & TEST_CORE_ON_SIGNAL)
 
1546
  {
 
1547
    /* inform kernel that process is dumpable */
 
1548
    (void) prctl(PR_SET_DUMPABLE, 1);
 
1549
  }
 
1550
#endif
 
1551
 
 
1552
#endif
 
1553
  return NULL;
 
1554
}
 
1555
 
 
1556
static void set_user(const char *user, struct passwd *user_info_arg)
 
1557
{
 
1558
  /* purecov: begin tested */
 
1559
#if !defined(__WIN__) && !defined(__NETWARE__)
 
1560
  DBUG_ASSERT(user_info_arg != 0);
 
1561
#ifdef HAVE_INITGROUPS
 
1562
  /*
 
1563
    We can get a SIGSEGV when calling initgroups() on some systems when NSS
 
1564
    is configured to use LDAP and the server is statically linked.  We set
 
1565
    calling_initgroups as a flag to the SIGSEGV handler that is then used to
 
1566
    output a specific message to help the user resolve this problem.
 
1567
  */
 
1568
  calling_initgroups= TRUE;
 
1569
  initgroups((char*) user, user_info_arg->pw_gid);
 
1570
  calling_initgroups= FALSE;
 
1571
#endif
 
1572
  if (setgid(user_info_arg->pw_gid) == -1)
 
1573
  {
 
1574
    sql_perror("setgid");
 
1575
    unireg_abort(1);
 
1576
  }
 
1577
  if (setuid(user_info_arg->pw_uid) == -1)
 
1578
  {
 
1579
    sql_perror("setuid");
 
1580
    unireg_abort(1);
 
1581
  }
 
1582
#endif
 
1583
  /* purecov: end */
 
1584
}
 
1585
 
 
1586
 
 
1587
static void set_effective_user(struct passwd *user_info_arg)
 
1588
{
 
1589
#if !defined(__WIN__) && !defined(__NETWARE__)
 
1590
  DBUG_ASSERT(user_info_arg != 0);
 
1591
  if (setregid((gid_t)-1, user_info_arg->pw_gid) == -1)
 
1592
  {
 
1593
    sql_perror("setregid");
 
1594
    unireg_abort(1);
 
1595
  }
 
1596
  if (setreuid((uid_t)-1, user_info_arg->pw_uid) == -1)
 
1597
  {
 
1598
    sql_perror("setreuid");
 
1599
    unireg_abort(1);
 
1600
  }
 
1601
#endif
 
1602
}
 
1603
 
 
1604
 
 
1605
/** Change root user if started with @c --chroot . */
 
1606
static void set_root(const char *path)
 
1607
{
 
1608
#if !defined(__WIN__) && !defined(__NETWARE__)
 
1609
  if (chroot(path) == -1)
 
1610
  {
 
1611
    sql_perror("chroot");
 
1612
    unireg_abort(1);
 
1613
  }
 
1614
  my_setwd("/", MYF(0));
 
1615
#endif
 
1616
}
 
1617
 
 
1618
static void network_init(void)
 
1619
{
 
1620
  struct sockaddr_in    IPaddr;
 
1621
#ifdef HAVE_SYS_UN_H
 
1622
  struct sockaddr_un    UNIXaddr;
 
1623
#endif
 
1624
  int   arg=1;
 
1625
  int   ret;
 
1626
  uint  waited;
 
1627
  uint  this_wait;
 
1628
  uint  retry;
 
1629
  DBUG_ENTER("network_init");
 
1630
  LINT_INIT(ret);
 
1631
 
 
1632
  if (thread_scheduler.init())
 
1633
    unireg_abort(1);                    /* purecov: inspected */
 
1634
 
 
1635
  set_ports();
 
1636
 
 
1637
  if (mysqld_port != 0 && !opt_disable_networking && !opt_bootstrap)
 
1638
  {
 
1639
    DBUG_PRINT("general",("IP Socket is %d",mysqld_port));
 
1640
    ip_sock = socket(AF_INET, SOCK_STREAM, 0);
 
1641
    if (ip_sock == INVALID_SOCKET)
 
1642
    {
 
1643
      DBUG_PRINT("error",("Got error: %d from socket()",socket_errno));
 
1644
      sql_perror(ER(ER_IPSOCK_ERROR));          /* purecov: tested */
 
1645
      unireg_abort(1);                          /* purecov: tested */
 
1646
    }
 
1647
    bzero((char*) &IPaddr, sizeof(IPaddr));
 
1648
    IPaddr.sin_family = AF_INET;
 
1649
    IPaddr.sin_addr.s_addr = my_bind_addr;
 
1650
    IPaddr.sin_port = (unsigned short) htons((unsigned short) mysqld_port);
 
1651
 
 
1652
#ifndef __WIN__
 
1653
    /*
 
1654
      We should not use SO_REUSEADDR on windows as this would enable a
 
1655
      user to open two mysqld servers with the same TCP/IP port.
 
1656
    */
 
1657
    (void) setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,sizeof(arg));
 
1658
#endif /* __WIN__ */
 
1659
    /*
 
1660
      Sometimes the port is not released fast enough when stopping and
 
1661
      restarting the server. This happens quite often with the test suite
 
1662
      on busy Linux systems. Retry to bind the address at these intervals:
 
1663
      Sleep intervals: 1, 2, 4,  6,  9, 13, 17, 22, ...
 
1664
      Retry at second: 1, 3, 7, 13, 22, 35, 52, 74, ...
 
1665
      Limit the sequence by mysqld_port_timeout (set --port-open-timeout=#).
 
1666
    */
 
1667
    for (waited= 0, retry= 1; ; retry++, waited+= this_wait)
 
1668
    {
 
1669
      if (((ret= bind(ip_sock, my_reinterpret_cast(struct sockaddr *) (&IPaddr),
 
1670
                      sizeof(IPaddr))) >= 0) ||
 
1671
          (socket_errno != SOCKET_EADDRINUSE) ||
 
1672
          (waited >= mysqld_port_timeout))
 
1673
        break;
 
1674
      sql_print_information("Retrying bind on TCP/IP port %u", mysqld_port);
 
1675
      this_wait= retry * retry / 3 + 1;
 
1676
      sleep(this_wait);
 
1677
    }
 
1678
    if (ret < 0)
 
1679
    {
 
1680
      DBUG_PRINT("error",("Got error: %d from bind",socket_errno));
 
1681
      sql_perror("Can't start server: Bind on TCP/IP port");
 
1682
      sql_print_error("Do you already have another mysqld server running on port: %d ?",mysqld_port);
 
1683
      unireg_abort(1);
 
1684
    }
 
1685
    if (listen(ip_sock,(int) back_log) < 0)
 
1686
    {
 
1687
      sql_perror("Can't start server: listen() on TCP/IP port");
 
1688
      sql_print_error("listen() on TCP/IP failed with error %d",
 
1689
                      socket_errno);
 
1690
      unireg_abort(1);
 
1691
    }
 
1692
  }
 
1693
 
 
1694
#ifdef __NT__
 
1695
  /* create named pipe */
 
1696
  if (Service.IsNT() && mysqld_unix_port[0] && !opt_bootstrap &&
 
1697
      opt_enable_named_pipe)
 
1698
  {
 
1699
    
 
1700
    strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\.\\pipe\\",
 
1701
             mysqld_unix_port, NullS);
 
1702
    bzero((char*) &saPipeSecurity, sizeof(saPipeSecurity));
 
1703
    bzero((char*) &sdPipeDescriptor, sizeof(sdPipeDescriptor));
 
1704
    if (!InitializeSecurityDescriptor(&sdPipeDescriptor,
 
1705
                                      SECURITY_DESCRIPTOR_REVISION))
 
1706
    {
 
1707
      sql_perror("Can't start server : Initialize security descriptor");
 
1708
      unireg_abort(1);
 
1709
    }
 
1710
    if (!SetSecurityDescriptorDacl(&sdPipeDescriptor, TRUE, NULL, FALSE))
 
1711
    {
 
1712
      sql_perror("Can't start server : Set security descriptor");
 
1713
      unireg_abort(1);
 
1714
    }
 
1715
    saPipeSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
 
1716
    saPipeSecurity.lpSecurityDescriptor = &sdPipeDescriptor;
 
1717
    saPipeSecurity.bInheritHandle = FALSE;
 
1718
    if ((hPipe= CreateNamedPipe(pipe_name,
 
1719
                                PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
 
1720
                                PIPE_TYPE_BYTE |
 
1721
                                PIPE_READMODE_BYTE |
 
1722
                                PIPE_WAIT,
 
1723
                                PIPE_UNLIMITED_INSTANCES,
 
1724
                                (int) global_system_variables.net_buffer_length,
 
1725
                                (int) global_system_variables.net_buffer_length,
 
1726
                                NMPWAIT_USE_DEFAULT_WAIT,
 
1727
                                &saPipeSecurity)) == INVALID_HANDLE_VALUE)
 
1728
      {
 
1729
        LPVOID lpMsgBuf;
 
1730
        int error=GetLastError();
 
1731
        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
 
1732
                      FORMAT_MESSAGE_FROM_SYSTEM,
 
1733
                      NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
 
1734
                      (LPTSTR) &lpMsgBuf, 0, NULL );
 
1735
        sql_perror((char *)lpMsgBuf);
 
1736
        LocalFree(lpMsgBuf);
 
1737
        unireg_abort(1);
 
1738
      }
 
1739
  }
 
1740
#endif
 
1741
 
 
1742
#if defined(HAVE_SYS_UN_H)
 
1743
  /*
 
1744
  ** Create the UNIX socket
 
1745
  */
 
1746
  if (mysqld_unix_port[0] && !opt_bootstrap)
 
1747
  {
 
1748
    DBUG_PRINT("general",("UNIX Socket is %s",mysqld_unix_port));
 
1749
 
 
1750
    if (strlen(mysqld_unix_port) > (sizeof(UNIXaddr.sun_path) - 1))
 
1751
    {
 
1752
      sql_print_error("The socket file path is too long (> %u): %s",
 
1753
                      (uint) sizeof(UNIXaddr.sun_path) - 1, mysqld_unix_port);
 
1754
      unireg_abort(1);
 
1755
    }
 
1756
    if ((unix_sock= socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
 
1757
    {
 
1758
      sql_perror("Can't start server : UNIX Socket "); /* purecov: inspected */
 
1759
      unireg_abort(1);                          /* purecov: inspected */
 
1760
    }
 
1761
    bzero((char*) &UNIXaddr, sizeof(UNIXaddr));
 
1762
    UNIXaddr.sun_family = AF_UNIX;
 
1763
    strmov(UNIXaddr.sun_path, mysqld_unix_port);
 
1764
    (void) unlink(mysqld_unix_port);
 
1765
    (void) setsockopt(unix_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,
 
1766
                      sizeof(arg));
 
1767
    umask(0);
 
1768
    if (bind(unix_sock, my_reinterpret_cast(struct sockaddr *) (&UNIXaddr),
 
1769
             sizeof(UNIXaddr)) < 0)
 
1770
    {
 
1771
      sql_perror("Can't start server : Bind on unix socket"); /* purecov: tested */
 
1772
      sql_print_error("Do you already have another mysqld server running on socket: %s ?",mysqld_unix_port);
 
1773
      unireg_abort(1);                                  /* purecov: tested */
 
1774
    }
 
1775
    umask(((~my_umask) & 0666));
 
1776
#if defined(S_IFSOCK) && defined(SECURE_SOCKETS)
 
1777
    (void) chmod(mysqld_unix_port,S_IFSOCK);    /* Fix solaris 2.6 bug */
 
1778
#endif
 
1779
    if (listen(unix_sock,(int) back_log) < 0)
 
1780
      sql_print_warning("listen() on Unix socket failed with error %d",
 
1781
                      socket_errno);
 
1782
  }
 
1783
#endif
 
1784
  DBUG_PRINT("info",("server started"));
 
1785
  DBUG_VOID_RETURN;
 
1786
}
 
1787
 
 
1788
#endif /*!EMBEDDED_LIBRARY*/
 
1789
 
 
1790
 
 
1791
#ifndef EMBEDDED_LIBRARY
 
1792
/**
 
1793
  Close a connection.
 
1794
 
 
1795
  @param thd            Thread handle
 
1796
  @param errcode        Error code to print to console
 
1797
  @param lock           1 if we have have to lock LOCK_thread_count
 
1798
 
 
1799
  @note
 
1800
    For the connection that is doing shutdown, this is called twice
 
1801
*/
 
1802
void close_connection(THD *thd, uint errcode, bool lock)
 
1803
{
 
1804
  st_vio *vio;
 
1805
  DBUG_ENTER("close_connection");
 
1806
  DBUG_PRINT("enter",("fd: %s  error: '%s'",
 
1807
                      thd->net.vio ? vio_description(thd->net.vio) :
 
1808
                      "(not connected)",
 
1809
                      errcode ? ER(errcode) : ""));
 
1810
  if (lock)
 
1811
    (void) pthread_mutex_lock(&LOCK_thread_count);
 
1812
  thd->killed= THD::KILL_CONNECTION;
 
1813
  if ((vio= thd->net.vio) != 0)
 
1814
  {
 
1815
    if (errcode)
 
1816
      net_send_error(thd, errcode, ER(errcode)); /* purecov: inspected */
 
1817
    vio_close(vio);                     /* vio is freed in delete thd */
 
1818
  }
 
1819
  if (lock)
 
1820
    (void) pthread_mutex_unlock(&LOCK_thread_count);
 
1821
  DBUG_VOID_RETURN;
 
1822
}
 
1823
#endif /* EMBEDDED_LIBRARY */
 
1824
 
 
1825
 
 
1826
/** Called when a thread is aborted. */
 
1827
/* ARGSUSED */
 
1828
extern "C" sig_handler end_thread_signal(int sig __attribute__((unused)))
 
1829
{
 
1830
  THD *thd=current_thd;
 
1831
  DBUG_ENTER("end_thread_signal");
 
1832
  if (thd && ! thd->bootstrap)
 
1833
  {
 
1834
    statistic_increment(killed_threads, &LOCK_status);
 
1835
    thread_scheduler.end_thread(thd,0);         /* purecov: inspected */
 
1836
  }
 
1837
  DBUG_VOID_RETURN;                             /* purecov: deadcode */
 
1838
}
 
1839
 
 
1840
 
 
1841
/*
 
1842
  Unlink thd from global list of available connections and free thd
 
1843
 
 
1844
  SYNOPSIS
 
1845
    unlink_thd()
 
1846
    thd          Thread handler
 
1847
 
 
1848
  NOTES
 
1849
    LOCK_thread_count is locked and left locked
 
1850
*/
 
1851
 
 
1852
void unlink_thd(THD *thd)
 
1853
{
 
1854
  DBUG_ENTER("unlink_thd");
 
1855
  DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd));
 
1856
  thd->cleanup();
 
1857
 
 
1858
  pthread_mutex_lock(&LOCK_connection_count);
 
1859
  --connection_count;
 
1860
  pthread_mutex_unlock(&LOCK_connection_count);
 
1861
 
 
1862
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
1863
  thread_count--;
 
1864
  delete thd;
 
1865
  DBUG_VOID_RETURN;
 
1866
}
 
1867
 
 
1868
 
 
1869
/*
 
1870
  Store thread in cache for reuse by new connections
 
1871
 
 
1872
  SYNOPSIS
 
1873
    cache_thread()
 
1874
 
 
1875
  NOTES
 
1876
    LOCK_thread_count has to be locked
 
1877
 
 
1878
  RETURN
 
1879
    0  Thread was not put in cache
 
1880
    1  Thread is to be reused by new connection.
 
1881
       (ie, caller should return, not abort with pthread_exit())
 
1882
*/
 
1883
 
 
1884
 
 
1885
static bool cache_thread()
 
1886
{
 
1887
  safe_mutex_assert_owner(&LOCK_thread_count);
 
1888
  if (cached_thread_count < thread_cache_size &&
 
1889
      ! abort_loop && !kill_cached_threads)
 
1890
  {
 
1891
    /* Don't kill the thread, just put it in cache for reuse */
 
1892
    DBUG_PRINT("info", ("Adding thread to cache"));
 
1893
    cached_thread_count++;
 
1894
    while (!abort_loop && ! wake_thread && ! kill_cached_threads)
 
1895
      (void) pthread_cond_wait(&COND_thread_cache, &LOCK_thread_count);
 
1896
    cached_thread_count--;
 
1897
    if (kill_cached_threads)
 
1898
      pthread_cond_signal(&COND_flush_thread_cache);
 
1899
    if (wake_thread)
 
1900
    {
 
1901
      THD *thd;
 
1902
      wake_thread--;
 
1903
      thd= thread_cache.get();
 
1904
      thd->thread_stack= (char*) &thd;          // For store_globals
 
1905
      (void) thd->store_globals();
 
1906
      /*
 
1907
        THD::mysys_var::abort is associated with physical thread rather
 
1908
        than with THD object. So we need to reset this flag before using
 
1909
        this thread for handling of new THD object/connection.
 
1910
      */
 
1911
      thd->mysys_var->abort= 0;
 
1912
      thd->thr_create_utime= my_micro_time();
 
1913
      threads.append(thd);
 
1914
      return(1);
 
1915
    }
 
1916
  }
 
1917
  return(0);
 
1918
}
 
1919
 
 
1920
 
 
1921
/*
 
1922
  End thread for the current connection
 
1923
 
 
1924
  SYNOPSIS
 
1925
    one_thread_per_connection_end()
 
1926
    thd           Thread handler
 
1927
    put_in_cache  Store thread in cache, if there is room in it
 
1928
                  Normally this is true in all cases except when we got
 
1929
                  out of resources initializing the current thread
 
1930
 
 
1931
  NOTES
 
1932
    If thread is cached, we will wait until thread is scheduled to be
 
1933
    reused and then we will return.
 
1934
    If thread is not cached, we end the thread.
 
1935
 
 
1936
  RETURN
 
1937
    0    Signal to handle_one_connection to reuse connection
 
1938
*/
 
1939
 
 
1940
bool one_thread_per_connection_end(THD *thd, bool put_in_cache)
 
1941
{
 
1942
  DBUG_ENTER("one_thread_per_connection_end");
 
1943
  unlink_thd(thd);
 
1944
  if (put_in_cache)
 
1945
    put_in_cache= cache_thread();
 
1946
  pthread_mutex_unlock(&LOCK_thread_count);
 
1947
  if (put_in_cache)
 
1948
    DBUG_RETURN(0);                             // Thread is reused
 
1949
 
 
1950
  /* It's safe to broadcast outside a lock (COND... is not deleted here) */
 
1951
  DBUG_PRINT("signal", ("Broadcasting COND_thread_count"));
 
1952
  DBUG_LEAVE;                                   // Must match DBUG_ENTER()
 
1953
  my_thread_end();
 
1954
  (void) pthread_cond_broadcast(&COND_thread_count);
 
1955
 
 
1956
  pthread_exit(0);
 
1957
  return 0;                                     // Avoid compiler warnings
 
1958
}
 
1959
 
 
1960
 
 
1961
void flush_thread_cache()
 
1962
{
 
1963
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
1964
  kill_cached_threads++;
 
1965
  while (cached_thread_count)
 
1966
  {
 
1967
    pthread_cond_broadcast(&COND_thread_cache);
 
1968
    pthread_cond_wait(&COND_flush_thread_cache,&LOCK_thread_count);
 
1969
  }
 
1970
  kill_cached_threads--;
 
1971
  (void) pthread_mutex_unlock(&LOCK_thread_count);
 
1972
}
 
1973
 
 
1974
 
 
1975
#ifdef THREAD_SPECIFIC_SIGPIPE
 
1976
/**
 
1977
  Aborts a thread nicely. Comes here on SIGPIPE.
 
1978
 
 
1979
  @todo
 
1980
    One should have to fix that thr_alarm know about this thread too.
 
1981
*/
 
1982
extern "C" sig_handler abort_thread(int sig __attribute__((unused)))
 
1983
{
 
1984
  THD *thd=current_thd;
 
1985
  DBUG_ENTER("abort_thread");
 
1986
  if (thd)
 
1987
    thd->killed= THD::KILL_CONNECTION;
 
1988
  DBUG_VOID_RETURN;
 
1989
}
 
1990
#endif
 
1991
 
 
1992
 
 
1993
/******************************************************************************
 
1994
  Setup a signal thread with handles all signals.
 
1995
  Because Linux doesn't support schemas use a mutex to check that
 
1996
  the signal thread is ready before continuing
 
1997
******************************************************************************/
 
1998
 
 
1999
#if defined(__WIN__)
 
2000
 
 
2001
 
 
2002
/*
 
2003
  On Windows, we use native SetConsoleCtrlHandler for handle events like Ctrl-C
 
2004
  with graceful shutdown.
 
2005
  Also, we do not use signal(), but SetUnhandledExceptionFilter instead - as it
 
2006
  provides possibility to pass the exception to just-in-time debugger, collect
 
2007
  dumps and potentially also the exception and thread context used to output
 
2008
  callstack.
 
2009
*/
 
2010
 
 
2011
static BOOL WINAPI console_event_handler( DWORD type ) 
 
2012
{
 
2013
  DBUG_ENTER("console_event_handler");
 
2014
#ifndef EMBEDDED_LIBRARY
 
2015
  if(type == CTRL_C_EVENT)
 
2016
  {
 
2017
     /*
 
2018
       Do not shutdown before startup is finished and shutdown
 
2019
       thread is initialized. Otherwise there is a race condition 
 
2020
       between main thread doing initialization and CTRL-C thread doing
 
2021
       cleanup, which can result into crash.
 
2022
     */
 
2023
#ifndef EMBEDDED_LIBRARY
 
2024
     if(hEventShutdown)
 
2025
       kill_mysql();
 
2026
     else
 
2027
#endif
 
2028
       sql_print_warning("CTRL-C ignored during startup");
 
2029
     DBUG_RETURN(TRUE);
 
2030
  }
 
2031
#endif
 
2032
  DBUG_RETURN(FALSE);
 
2033
}
 
2034
 
 
2035
 
 
2036
/*
 
2037
  In Visual Studio 2005 and later, default SIGABRT handler will overwrite
 
2038
  any unhandled exception filter set by the application  and will try to
 
2039
  call JIT debugger. This is not what we want, this we calling __debugbreak
 
2040
  to stop in debugger, if process is being debugged or to generate 
 
2041
  EXCEPTION_BREAKPOINT and then handle_segfault will do its magic.
 
2042
*/
 
2043
 
 
2044
#if (_MSC_VER >= 1400)
 
2045
static void my_sigabrt_handler(int sig)
 
2046
{
 
2047
  __debugbreak();
 
2048
}
 
2049
#endif /*_MSC_VER >=1400 */
 
2050
 
 
2051
void win_install_sigabrt_handler(void)
 
2052
{
 
2053
#if (_MSC_VER >=1400)
 
2054
  /*abort() should not override our exception filter*/
 
2055
  _set_abort_behavior(0,_CALL_REPORTFAULT);
 
2056
  signal(SIGABRT,my_sigabrt_handler);
 
2057
#endif /* _MSC_VER >=1400 */
 
2058
}
 
2059
 
 
2060
#ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER
 
2061
#define DEBUGGER_ATTACH_TIMEOUT 120
 
2062
/*
 
2063
  Wait for debugger to attach and break into debugger. If debugger is not attached,
 
2064
  resume after timeout.
 
2065
*/
 
2066
static void wait_for_debugger(int timeout_sec)
 
2067
{
 
2068
   if(!IsDebuggerPresent())
 
2069
   {
 
2070
     int i;
 
2071
     printf("Waiting for debugger to attach, pid=%u\n",GetCurrentProcessId());
 
2072
     fflush(stdout);
 
2073
     for(i= 0; i < timeout_sec; i++)
 
2074
     {
 
2075
       Sleep(1000);
 
2076
       if(IsDebuggerPresent())
 
2077
       {
 
2078
         /* Break into debugger */
 
2079
         __debugbreak();
 
2080
         return;
 
2081
       }
 
2082
     }
 
2083
     printf("pid=%u, debugger not attached after %d seconds, resuming\n",GetCurrentProcessId(),
 
2084
       timeout_sec);
 
2085
     fflush(stdout);
 
2086
   }
 
2087
}
 
2088
#endif /* DEBUG_UNHANDLED_EXCEPTION_FILTER */
 
2089
 
 
2090
LONG WINAPI my_unhandler_exception_filter(EXCEPTION_POINTERS *ex_pointers)
 
2091
{
 
2092
   static BOOL first_time= TRUE;
 
2093
   if(!first_time)
 
2094
   {
 
2095
     /*
 
2096
       This routine can be called twice, typically
 
2097
       when detaching in JIT debugger.
 
2098
       Return EXCEPTION_EXECUTE_HANDLER to terminate process.
 
2099
     */
 
2100
     return EXCEPTION_EXECUTE_HANDLER;
 
2101
   }
 
2102
   first_time= FALSE;
 
2103
#ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER
 
2104
   /*
 
2105
    Unfortunately there is no clean way to debug unhandled exception filters,
 
2106
    as debugger does not stop there(also documented in MSDN) 
 
2107
    To overcome, one could put a MessageBox, but this will not work in service.
 
2108
    Better solution is to print error message and sleep some minutes 
 
2109
    until debugger is attached
 
2110
  */
 
2111
  wait_for_debugger(DEBUGGER_ATTACH_TIMEOUT);
 
2112
#endif /* DEBUG_UNHANDLED_EXCEPTION_FILTER */
 
2113
  __try
 
2114
  {
 
2115
    my_set_exception_pointers(ex_pointers);
 
2116
    handle_segfault(ex_pointers->ExceptionRecord->ExceptionCode);
 
2117
  }
 
2118
  __except(EXCEPTION_EXECUTE_HANDLER)
 
2119
  {
 
2120
    DWORD written;
 
2121
    const char msg[] = "Got exception in exception handler!\n";
 
2122
    WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),msg, sizeof(msg)-1, 
 
2123
      &written,NULL);
 
2124
  }
 
2125
  /*
 
2126
    Return EXCEPTION_CONTINUE_SEARCH to give JIT debugger
 
2127
    (drwtsn32 or vsjitdebugger) possibility to attach,
 
2128
    if JIT debugger is configured.
 
2129
    Windows Error reporting might generate a dump here.
 
2130
  */
 
2131
  return EXCEPTION_CONTINUE_SEARCH;
 
2132
}
 
2133
 
 
2134
 
 
2135
static void init_signals(void)
 
2136
{
 
2137
  win_install_sigabrt_handler();
 
2138
  if(opt_console)
 
2139
    SetConsoleCtrlHandler(console_event_handler,TRUE);
 
2140
 
 
2141
    /* Avoid MessageBox()es*/
 
2142
  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
 
2143
  _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
 
2144
  _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
 
2145
  _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
 
2146
  _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
 
2147
  _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
 
2148
 
 
2149
   /*
 
2150
     Do not use SEM_NOGPFAULTERRORBOX in the following SetErrorMode (),
 
2151
     because it would prevent JIT debugger and Windows error reporting
 
2152
     from working. We need WER or JIT-debugging, since our own unhandled
 
2153
     exception filter is not guaranteed to work in all situation
 
2154
     (like heap corruption or stack overflow)
 
2155
   */
 
2156
  SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS
 
2157
                               | SEM_NOOPENFILEERRORBOX);
 
2158
  SetUnhandledExceptionFilter(my_unhandler_exception_filter);
 
2159
}
 
2160
 
 
2161
 
 
2162
static void start_signal_handler(void)
 
2163
{
 
2164
#ifndef EMBEDDED_LIBRARY
 
2165
  // Save vm id of this process
 
2166
  if (!opt_bootstrap)
 
2167
    create_pid_file();
 
2168
#endif /* EMBEDDED_LIBRARY */
 
2169
}
 
2170
 
 
2171
 
 
2172
static void check_data_home(const char *path)
 
2173
{}
 
2174
 
 
2175
 
 
2176
#elif defined(__NETWARE__)
 
2177
 
 
2178
/// down server event callback.
 
2179
void mysql_down_server_cb(void *, void *)
 
2180
{
 
2181
  event_flag= TRUE;
 
2182
  kill_server(0);
 
2183
}
 
2184
 
 
2185
 
 
2186
/// destroy callback resources.
 
2187
void mysql_cb_destroy(void *)
 
2188
{
 
2189
  UnRegisterEventNotification(eh);  // cleanup down event notification
 
2190
  NX_UNWRAP_INTERFACE(ref);
 
2191
  /* Deregister NSS volume deactivation event */
 
2192
  NX_UNWRAP_INTERFACE(refneb);
 
2193
  if (neb_consumer_id)
 
2194
    UnRegisterConsumer(neb_consumer_id, NULL);
 
2195
}
 
2196
 
 
2197
 
 
2198
/// initialize callbacks.
 
2199
void mysql_cb_init()
 
2200
{
 
2201
  // register for down server event
 
2202
  void *handle = getnlmhandle();
 
2203
  rtag_t rt= AllocateResourceTag(handle, "MySQL Down Server Callback",
 
2204
                                 EventSignature);
 
2205
  NX_WRAP_INTERFACE((void *)mysql_down_server_cb, 2, (void **)&ref);
 
2206
  eh= RegisterForEventNotification(rt, EVENT_PRE_DOWN_SERVER,
 
2207
                                   EVENT_PRIORITY_APPLICATION,
 
2208
                                   NULL, ref, NULL);
 
2209
 
 
2210
  /*
 
2211
    Register for volume deactivation event
 
2212
    Wrap the callback function, as it is called by non-LibC thread
 
2213
  */
 
2214
  (void *) NX_WRAP_INTERFACE(neb_event_callback, 1, &refneb);
 
2215
  registerwithneb();
 
2216
 
 
2217
  NXVmRegisterExitHandler(mysql_cb_destroy, NULL);  // clean-up
 
2218
}
 
2219
 
 
2220
 
 
2221
/** To get the name of the NetWare volume having MySQL data folder. */
 
2222
static void getvolumename()
 
2223
{
 
2224
  char *p;
 
2225
  /*
 
2226
    We assume that data path is already set.
 
2227
    If not it won't come here. Terminate after volume name
 
2228
  */
 
2229
  if ((p= strchr(mysql_real_data_home, ':')))
 
2230
    strmake(datavolname, mysql_real_data_home,
 
2231
            (uint) (p - mysql_real_data_home));
 
2232
}
 
2233
 
 
2234
 
 
2235
/**
 
2236
  Registering with NEB for NSS Volume Deactivation event.
 
2237
*/
 
2238
 
 
2239
static void registerwithneb()
 
2240
{
 
2241
 
 
2242
  ConsumerRegistrationInfo reg_info;
 
2243
    
 
2244
  /* Clear NEB registration structure */
 
2245
  bzero((char*) &reg_info, sizeof(struct ConsumerRegistrationInfo));
 
2246
 
 
2247
  /* Fill the NEB consumer information structure */
 
2248
  reg_info.CRIVersion= 1;                   // NEB version
 
2249
  /* NEB Consumer name */
 
2250
  reg_info.CRIConsumerName= (BYTE *) "MySQL Database Server";
 
2251
  /* Event of interest */
 
2252
  reg_info.CRIEventName= (BYTE *) "NSS.ChangeVolState.Enter";
 
2253
  reg_info.CRIUserParameter= NULL;          // Consumer Info
 
2254
  reg_info.CRIEventFlags= 0;                // Event flags
 
2255
  /* Consumer NLM handle */
 
2256
  reg_info.CRIOwnerID= (LoadDefinitionStructure *)getnlmhandle();
 
2257
  reg_info.CRIConsumerESR= NULL;            // No consumer ESR required
 
2258
  reg_info.CRISecurityToken= 0;             // No security token for the event
 
2259
  reg_info.CRIConsumerFlags= 0;             // SMP_ENABLED_BIT; 
 
2260
  reg_info.CRIFilterName= 0;                // No event filtering
 
2261
  reg_info.CRIFilterDataLength= 0;          // No filtering data
 
2262
  reg_info.CRIFilterData= 0;                // No filtering data
 
2263
  /* Callback function for the event */
 
2264
  (void *)reg_info.CRIConsumerCallback= (void *) refneb;
 
2265
  reg_info.CRIOrder= 0;                     // Event callback order
 
2266
  reg_info.CRIConsumerType= CHECK_CONSUMER; // Consumer type
 
2267
 
 
2268
  /* Register for the event with NEB */
 
2269
  if (RegisterConsumer(&reg_info))
 
2270
  {
 
2271
    consoleprintf("Failed to register for NSS Volume Deactivation event \n");
 
2272
    return;
 
2273
  }
 
2274
  /* This ID is required for deregistration */
 
2275
  neb_consumer_id= reg_info.CRIConsumerID;
 
2276
 
 
2277
  /* Get MySQL data volume name, stored in global variable datavolname */
 
2278
  getvolumename();
 
2279
 
 
2280
  /*
 
2281
    Get the NSS volume ID of the MySQL Data volume.
 
2282
    Volume ID is stored in a global variable
 
2283
  */
 
2284
  getvolumeID((BYTE*) datavolname);     
 
2285
}
 
2286
 
 
2287
 
 
2288
/**
 
2289
  Callback for NSS Volume Deactivation event.
 
2290
*/
 
2291
 
 
2292
ulong neb_event_callback(struct EventBlock *eblock)
 
2293
{
 
2294
  EventChangeVolStateEnter_s *voldata;
 
2295
  extern bool nw_panic;
 
2296
 
 
2297
  voldata= (EventChangeVolStateEnter_s *)eblock->EBEventData;
 
2298
 
 
2299
  /* Deactivation of a volume */
 
2300
  if ((voldata->oldState == zVOLSTATE_ACTIVE &&
 
2301
       voldata->newState == zVOLSTATE_DEACTIVE ||
 
2302
       voldata->newState == zVOLSTATE_MAINTENANCE))
 
2303
  {
 
2304
    /*
 
2305
      Ensure that we bring down MySQL server only for MySQL data
 
2306
      volume deactivation
 
2307
    */
 
2308
    if (!memcmp(&voldata->volID, &datavolid, sizeof(VolumeID_t)))
 
2309
    {
 
2310
      consoleprintf("MySQL data volume is deactivated, shutting down MySQL Server \n");
 
2311
      event_flag= TRUE;
 
2312
      nw_panic = TRUE;
 
2313
      event_flag= TRUE;
 
2314
      kill_server(0);
 
2315
    }
 
2316
  }
 
2317
  return 0;
 
2318
}
 
2319
 
 
2320
 
 
2321
#define ADMIN_VOL_PATH                                  "_ADMIN:/Volumes/"
 
2322
 
 
2323
/**
 
2324
  Function to get NSS volume ID of the MySQL data.
 
2325
*/
 
2326
static void getvolumeID(BYTE *volumeName)
 
2327
{
 
2328
  char path[zMAX_FULL_NAME];
 
2329
  Key_t rootKey= 0, fileKey= 0;
 
2330
  QUAD getInfoMask;
 
2331
  zInfo_s info;
 
2332
  STATUS status;
 
2333
 
 
2334
  /* Get the root key */
 
2335
  if ((status= zRootKey(0, &rootKey)) != zOK)
 
2336
  {
 
2337
    consoleprintf("\nGetNSSVolumeProperties - Failed to get root key, status: %d\n.", (int) status);
 
2338
    goto exit;
 
2339
  }
 
2340
 
 
2341
  /*
 
2342
    Get the file key. This is the key to the volume object in the
 
2343
    NSS admin volumes directory.
 
2344
  */
 
2345
 
 
2346
  strxmov(path, (const char *) ADMIN_VOL_PATH, (const char *) volumeName,
 
2347
          NullS);
 
2348
  if ((status= zOpen(rootKey, zNSS_TASK, zNSPACE_LONG|zMODE_UTF8, 
 
2349
                     (BYTE *) path, zRR_READ_ACCESS, &fileKey)) != zOK)
 
2350
  {
 
2351
    consoleprintf("\nGetNSSVolumeProperties - Failed to get file, status: %d\n.", (int) status);
 
2352
    goto exit;
 
2353
  }
 
2354
 
 
2355
  getInfoMask= zGET_IDS | zGET_VOLUME_INFO ;
 
2356
  if ((status= zGetInfo(fileKey, getInfoMask, sizeof(info), 
 
2357
                        zINFO_VERSION_A, &info)) != zOK)
 
2358
  {
 
2359
    consoleprintf("\nGetNSSVolumeProperties - Failed in zGetInfo, status: %d\n.", (int) status);
 
2360
    goto exit;
 
2361
  }
 
2362
 
 
2363
  /* Copy the data to global variable */
 
2364
  datavolid.timeLow= info.vol.volumeID.timeLow;
 
2365
  datavolid.timeMid= info.vol.volumeID.timeMid;
 
2366
  datavolid.timeHighAndVersion= info.vol.volumeID.timeHighAndVersion;
 
2367
  datavolid.clockSeqHighAndReserved= info.vol.volumeID.clockSeqHighAndReserved;
 
2368
  datavolid.clockSeqLow= info.vol.volumeID.clockSeqLow;
 
2369
  /* This is guranteed to be 6-byte length (but sizeof() would be better) */
 
2370
  memcpy(datavolid.node, info.vol.volumeID.node, (unsigned int) 6);
 
2371
 
 
2372
exit:
 
2373
  if (rootKey)
 
2374
    zClose(rootKey);
 
2375
  if (fileKey)
 
2376
    zClose(fileKey);
 
2377
}
 
2378
 
 
2379
 
 
2380
static void init_signals(void)
 
2381
{
 
2382
  int signals[] = {SIGINT,SIGILL,SIGFPE,SIGSEGV,SIGTERM,SIGABRT};
 
2383
 
 
2384
  for (uint i=0 ; i < sizeof(signals)/sizeof(int) ; i++)
 
2385
    signal(signals[i], kill_server);
 
2386
  mysql_cb_init();  // initialize callbacks
 
2387
 
 
2388
}
 
2389
 
 
2390
 
 
2391
static void start_signal_handler(void)
 
2392
{
 
2393
  // Save vm id of this process
 
2394
  if (!opt_bootstrap)
 
2395
    create_pid_file();
 
2396
  // no signal handler
 
2397
}
 
2398
 
 
2399
 
 
2400
/**
 
2401
  Warn if the data is on a Traditional volume.
 
2402
 
 
2403
  @note
 
2404
    Already done by mysqld_safe
 
2405
*/
 
2406
 
 
2407
static void check_data_home(const char *path)
 
2408
{
 
2409
}
 
2410
 
 
2411
#endif /*__WIN__ || __NETWARE */
 
2412
 
 
2413
#ifdef HAVE_LINUXTHREADS
 
2414
#define UNSAFE_DEFAULT_LINUX_THREADS 200
 
2415
#endif
 
2416
 
 
2417
 
 
2418
#if BACKTRACE_DEMANGLE
 
2419
#include <cxxabi.h>
 
2420
extern "C" char *my_demangle(const char *mangled_name, int *status)
 
2421
{
 
2422
  return abi::__cxa_demangle(mangled_name, NULL, NULL, status);
 
2423
}
 
2424
#endif
 
2425
 
 
2426
 
 
2427
extern "C" sig_handler handle_segfault(int sig)
 
2428
{
 
2429
  time_t curr_time;
 
2430
  struct tm tm;
 
2431
  THD *thd=current_thd;
 
2432
 
 
2433
  /*
 
2434
    Strictly speaking, one needs a mutex here
 
2435
    but since we have got SIGSEGV already, things are a mess
 
2436
    so not having the mutex is not as bad as possibly using a buggy
 
2437
    mutex - so we keep things simple
 
2438
  */
 
2439
  if (segfaulted)
 
2440
  {
 
2441
    fprintf(stderr, "Fatal " SIGNAL_FMT " while backtracing\n", sig);
 
2442
    exit(1);
 
2443
  }
 
2444
 
 
2445
  segfaulted = 1;
 
2446
 
 
2447
  curr_time= my_time(0);
 
2448
  localtime_r(&curr_time, &tm);
 
2449
 
 
2450
  fprintf(stderr,"\
 
2451
%02d%02d%02d %2d:%02d:%02d - mysqld got " SIGNAL_FMT " ;\n\
 
2452
This could be because you hit a bug. It is also possible that this binary\n\
 
2453
or one of the libraries it was linked against is corrupt, improperly built,\n\
 
2454
or misconfigured. This error can also be caused by malfunctioning hardware.\n",
 
2455
          tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday,
 
2456
          tm.tm_hour, tm.tm_min, tm.tm_sec,
 
2457
          sig);
 
2458
  fprintf(stderr, "\
 
2459
We will try our best to scrape up some info that will hopefully help diagnose\n\
 
2460
the problem, but since we have already crashed, something is definitely wrong\n\
 
2461
and this may fail.\n\n");
 
2462
  fprintf(stderr, "key_buffer_size=%lu\n",
 
2463
          (ulong) dflt_key_cache->key_cache_mem_size);
 
2464
  fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
 
2465
  fprintf(stderr, "max_used_connections=%lu\n", max_used_connections);
 
2466
  fprintf(stderr, "max_threads=%u\n", thread_scheduler.max_threads);
 
2467
  fprintf(stderr, "threads_connected=%u\n", thread_count);
 
2468
  fprintf(stderr, "It is possible that mysqld could use up to \n\
 
2469
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = %lu K\n\
 
2470
bytes of memory\n", ((ulong) dflt_key_cache->key_cache_mem_size +
 
2471
                     (global_system_variables.read_buff_size +
 
2472
                      global_system_variables.sortbuff_size) *
 
2473
                     thread_scheduler.max_threads +
 
2474
                     max_connections * sizeof(THD)) / 1024);
 
2475
  fprintf(stderr, "Hope that's ok; if not, decrease some variables in the equation.\n\n");
 
2476
 
 
2477
#if defined(HAVE_LINUXTHREADS)
 
2478
  if (sizeof(char*) == 4 && thread_count > UNSAFE_DEFAULT_LINUX_THREADS)
 
2479
  {
 
2480
    fprintf(stderr, "\
 
2481
You seem to be running 32-bit Linux and have %d concurrent connections.\n\
 
2482
If you have not changed STACK_SIZE in LinuxThreads and built the binary \n\
 
2483
yourself, LinuxThreads is quite likely to steal a part of the global heap for\n\
 
2484
the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n",
 
2485
            thread_count);
 
2486
  }
 
2487
#endif /* HAVE_LINUXTHREADS */
 
2488
 
 
2489
#ifdef HAVE_STACKTRACE
 
2490
  if (!(test_flags & TEST_NO_STACKTRACE))
 
2491
  {
 
2492
    fprintf(stderr,"thd: 0x%lx\n",(long) thd);
 
2493
    fprintf(stderr,"\
 
2494
Attempting backtrace. You can use the following information to find out\n\
 
2495
where mysqld died. If you see no messages after this, something went\n\
 
2496
terribly wrong...\n");  
 
2497
    my_print_stacktrace(thd ? (uchar*) thd->thread_stack : NULL,
 
2498
                        my_thread_stack_size);
 
2499
  }
 
2500
  if (thd)
 
2501
  {
 
2502
    const char *kreason= "UNKNOWN";
 
2503
    switch (thd->killed) {
 
2504
    case THD::NOT_KILLED:
 
2505
      kreason= "NOT_KILLED";
 
2506
      break;
 
2507
    case THD::KILL_BAD_DATA:
 
2508
      kreason= "KILL_BAD_DATA";
 
2509
      break;
 
2510
    case THD::KILL_CONNECTION:
 
2511
      kreason= "KILL_CONNECTION";
 
2512
      break;
 
2513
    case THD::KILL_QUERY:
 
2514
      kreason= "KILL_QUERY";
 
2515
      break;
 
2516
    case THD::KILLED_NO_VALUE:
 
2517
      kreason= "KILLED_NO_VALUE";
 
2518
      break;
 
2519
    }
 
2520
    fprintf(stderr, "Trying to get some variables.\n\
 
2521
Some pointers may be invalid and cause the dump to abort...\n");
 
2522
    my_safe_print_str("thd->query", thd->query(), 1024);
 
2523
    fprintf(stderr, "thd->thread_id=%lu\n", (ulong) thd->thread_id);
 
2524
    fprintf(stderr, "thd->killed=%s\n", kreason);
 
2525
  }
 
2526
  fprintf(stderr, "\
 
2527
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains\n\
 
2528
information that should help you find out what is causing the crash.\n");
 
2529
  fflush(stderr);
 
2530
#endif /* HAVE_STACKTRACE */
 
2531
 
 
2532
#ifdef HAVE_INITGROUPS
 
2533
  if (calling_initgroups)
 
2534
    fprintf(stderr, "\n\
 
2535
This crash occured while the server was calling initgroups(). This is\n\
 
2536
often due to the use of a mysqld that is statically linked against glibc\n\
 
2537
and configured to use LDAP in /etc/nsswitch.conf. You will need to either\n\
 
2538
upgrade to a version of glibc that does not have this problem (2.3.4 or\n\
 
2539
later when used with nscd), disable LDAP in your nsswitch.conf, or use a\n\
 
2540
mysqld that is not statically linked.\n");
 
2541
#endif
 
2542
 
 
2543
#ifdef HAVE_NPTL
 
2544
  if (thd_lib_detected == THD_LIB_LT && !getenv("LD_ASSUME_KERNEL"))
 
2545
    fprintf(stderr,"\n\
 
2546
You are running a statically-linked LinuxThreads binary on an NPTL system.\n\
 
2547
This can result in crashes on some distributions due to LT/NPTL conflicts.\n\
 
2548
You should either build a dynamically-linked binary, or force LinuxThreads\n\
 
2549
to be used with the LD_ASSUME_KERNEL environment variable. Please consult\n\
 
2550
the documentation for your distribution on how to do that.\n");
 
2551
#endif
 
2552
  
 
2553
  if (locked_in_memory)
 
2554
  {
 
2555
    fprintf(stderr, "\n\
 
2556
The \"--memlock\" argument, which was enabled, uses system calls that are\n\
 
2557
unreliable and unstable on some operating systems and operating-system\n\
 
2558
versions (notably, some versions of Linux).  This crash could be due to use\n\
 
2559
of those buggy OS calls.  You should consider whether you really need the\n\
 
2560
\"--memlock\" parameter and/or consult the OS distributer about \"mlockall\"\n\
 
2561
bugs.\n");
 
2562
  }
 
2563
 
 
2564
#ifdef HAVE_WRITE_CORE
 
2565
  if (test_flags & TEST_CORE_ON_SIGNAL)
 
2566
  {
 
2567
    fprintf(stderr, "Writing a core file\n");
 
2568
    fflush(stderr);
 
2569
    my_write_core(sig);
 
2570
  }
 
2571
#endif
 
2572
 
 
2573
#ifndef __WIN__
 
2574
  /* On Windows, do not terminate, but pass control to exception filter */
 
2575
  exit(1);
 
2576
#endif
 
2577
}
 
2578
 
 
2579
#if !defined(__WIN__) && !defined(__NETWARE__)
 
2580
#ifndef SA_RESETHAND
 
2581
#define SA_RESETHAND 0
 
2582
#endif
 
2583
#ifndef SA_NODEFER
 
2584
#define SA_NODEFER 0
 
2585
#endif
 
2586
 
 
2587
#ifndef EMBEDDED_LIBRARY
 
2588
 
 
2589
static void init_signals(void)
 
2590
{
 
2591
  sigset_t set;
 
2592
  struct sigaction sa;
 
2593
  DBUG_ENTER("init_signals");
 
2594
 
 
2595
  my_sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called!
 
2596
 
 
2597
  if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL))
 
2598
  {
 
2599
    sa.sa_flags = SA_RESETHAND | SA_NODEFER;
 
2600
    sigemptyset(&sa.sa_mask);
 
2601
    sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
 
2602
 
 
2603
#ifdef HAVE_STACKTRACE
 
2604
    my_init_stacktrace();
 
2605
#endif
 
2606
#if defined(__amiga__)
 
2607
    sa.sa_handler=(void(*)())handle_segfault;
 
2608
#else
 
2609
    sa.sa_handler=handle_segfault;
 
2610
#endif
 
2611
    sigaction(SIGSEGV, &sa, NULL);
 
2612
    sigaction(SIGABRT, &sa, NULL);
 
2613
#ifdef SIGBUS
 
2614
    sigaction(SIGBUS, &sa, NULL);
 
2615
#endif
 
2616
    sigaction(SIGILL, &sa, NULL);
 
2617
    sigaction(SIGFPE, &sa, NULL);
 
2618
  }
 
2619
 
 
2620
#ifdef HAVE_GETRLIMIT
 
2621
  if (test_flags & TEST_CORE_ON_SIGNAL)
 
2622
  {
 
2623
    /* Change limits so that we will get a core file */
 
2624
    STRUCT_RLIMIT rl;
 
2625
    rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
 
2626
    if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
 
2627
      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");
 
2628
  }
 
2629
#endif
 
2630
  (void) sigemptyset(&set);
 
2631
  my_sigset(SIGPIPE,SIG_IGN);
 
2632
  sigaddset(&set,SIGPIPE);
 
2633
#ifndef IGNORE_SIGHUP_SIGQUIT
 
2634
  sigaddset(&set,SIGQUIT);
 
2635
  sigaddset(&set,SIGHUP);
 
2636
#endif
 
2637
  sigaddset(&set,SIGTERM);
 
2638
 
 
2639
  /* Fix signals if blocked by parents (can happen on Mac OS X) */
 
2640
  sigemptyset(&sa.sa_mask);
 
2641
  sa.sa_flags = 0;
 
2642
  sa.sa_handler = print_signal_warning;
 
2643
  sigaction(SIGTERM, &sa, (struct sigaction*) 0);
 
2644
  sa.sa_flags = 0;
 
2645
  sa.sa_handler = print_signal_warning;
 
2646
  sigaction(SIGHUP, &sa, (struct sigaction*) 0);
 
2647
#ifdef SIGTSTP
 
2648
  sigaddset(&set,SIGTSTP);
 
2649
#endif
 
2650
  if (thd_lib_detected != THD_LIB_LT)
 
2651
    sigaddset(&set,THR_SERVER_ALARM);
 
2652
  if (test_flags & TEST_SIGINT)
 
2653
  {
 
2654
    my_sigset(thr_kill_signal, end_thread_signal);
 
2655
    // May be SIGINT
 
2656
    sigdelset(&set, thr_kill_signal);
 
2657
  }
 
2658
  else
 
2659
    sigaddset(&set,SIGINT);
 
2660
  sigprocmask(SIG_SETMASK,&set,NULL);
 
2661
  pthread_sigmask(SIG_SETMASK,&set,NULL);
 
2662
  DBUG_VOID_RETURN;
 
2663
}
 
2664
 
 
2665
 
 
2666
static void start_signal_handler(void)
 
2667
{
 
2668
  int error;
 
2669
  pthread_attr_t thr_attr;
 
2670
  DBUG_ENTER("start_signal_handler");
 
2671
 
 
2672
  (void) pthread_attr_init(&thr_attr);
 
2673
#if !defined(HAVE_DEC_3_2_THREADS)
 
2674
  pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_SYSTEM);
 
2675
  (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
 
2676
  if (!(opt_specialflag & SPECIAL_NO_PRIOR))
 
2677
    my_pthread_attr_setprio(&thr_attr,INTERRUPT_PRIOR);
 
2678
#if defined(__ia64__) || defined(__ia64)
 
2679
  /*
 
2680
    Peculiar things with ia64 platforms - it seems we only have half the
 
2681
    stack size in reality, so we have to double it here
 
2682
  */
 
2683
  pthread_attr_setstacksize(&thr_attr,my_thread_stack_size*2);
 
2684
#else
 
2685
  pthread_attr_setstacksize(&thr_attr,my_thread_stack_size);
 
2686
#endif
 
2687
#endif
 
2688
 
 
2689
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
2690
  if ((error=pthread_create(&signal_thread,&thr_attr,signal_hand,0)))
 
2691
  {
 
2692
    sql_print_error("Can't create interrupt-thread (error %d, errno: %d)",
 
2693
                    error,errno);
 
2694
    exit(1);
 
2695
  }
 
2696
  (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
 
2697
  pthread_mutex_unlock(&LOCK_thread_count);
 
2698
 
 
2699
  (void) pthread_attr_destroy(&thr_attr);
 
2700
  DBUG_VOID_RETURN;
 
2701
}
 
2702
 
 
2703
 
 
2704
/** This threads handles all signals and alarms. */
 
2705
/* ARGSUSED */
 
2706
pthread_handler_t signal_hand(void *arg __attribute__((unused)))
 
2707
{
 
2708
  sigset_t set;
 
2709
  int sig;
 
2710
  my_thread_init();                             // Init new thread
 
2711
  DBUG_ENTER("signal_hand");
 
2712
  signal_thread_in_use= 1;
 
2713
 
 
2714
  /*
 
2715
    Setup alarm handler
 
2716
    This should actually be '+ max_number_of_slaves' instead of +10,
 
2717
    but the +10 should be quite safe.
 
2718
  */
 
2719
  init_thr_alarm(thread_scheduler.max_threads +
 
2720
                 global_system_variables.max_insert_delayed_threads + 10);
 
2721
  if (thd_lib_detected != THD_LIB_LT && (test_flags & TEST_SIGINT))
 
2722
  {
 
2723
    (void) sigemptyset(&set);                   // Setup up SIGINT for debug
 
2724
    (void) sigaddset(&set,SIGINT);              // For debugging
 
2725
    (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL);
 
2726
  }
 
2727
  (void) sigemptyset(&set);                     // Setup up SIGINT for debug
 
2728
#ifdef USE_ONE_SIGNAL_HAND
 
2729
  (void) sigaddset(&set,THR_SERVER_ALARM);      // For alarms
 
2730
#endif
 
2731
#ifndef IGNORE_SIGHUP_SIGQUIT
 
2732
  (void) sigaddset(&set,SIGQUIT);
 
2733
  (void) sigaddset(&set,SIGHUP);
 
2734
#endif
 
2735
  (void) sigaddset(&set,SIGTERM);
 
2736
  (void) sigaddset(&set,SIGTSTP);
 
2737
 
 
2738
  /* Save pid to this process (or thread on Linux) */
 
2739
  if (!opt_bootstrap)
 
2740
    create_pid_file();
 
2741
 
 
2742
#ifdef HAVE_STACK_TRACE_ON_SEGV
 
2743
  if (opt_do_pstack)
 
2744
  {
 
2745
    sprintf(pstack_file_name,"mysqld-%lu-%%d-%%d.backtrace", (ulong)getpid());
 
2746
    pstack_install_segv_action(pstack_file_name);
 
2747
  }
 
2748
#endif /* HAVE_STACK_TRACE_ON_SEGV */
 
2749
 
 
2750
  /*
 
2751
    signal to start_signal_handler that we are ready
 
2752
    This works by waiting for start_signal_handler to free mutex,
 
2753
    after which we signal it that we are ready.
 
2754
    At this pointer there is no other threads running, so there
 
2755
    should not be any other pthread_cond_signal() calls.
 
2756
  */
 
2757
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
2758
  (void) pthread_mutex_unlock(&LOCK_thread_count);
 
2759
  (void) pthread_cond_broadcast(&COND_thread_count);
 
2760
 
 
2761
  (void) pthread_sigmask(SIG_BLOCK,&set,NULL);
 
2762
  for (;;)
 
2763
  {
 
2764
    int error;                                  // Used when debugging
 
2765
    if (shutdown_in_progress && !abort_loop)
 
2766
    {
 
2767
      sig= SIGTERM;
 
2768
      error=0;
 
2769
    }
 
2770
    else
 
2771
      while ((error=my_sigwait(&set,&sig)) == EINTR) ;
 
2772
    if (cleanup_done)
 
2773
    {
 
2774
      DBUG_PRINT("quit",("signal_handler: calling my_thread_end()"));
 
2775
      my_thread_end();
 
2776
      signal_thread_in_use= 0;
 
2777
      DBUG_LEAVE;                               // Must match DBUG_ENTER()
 
2778
      pthread_exit(0);                          // Safety
 
2779
      return 0;                                 // Avoid compiler warnings
 
2780
    }
 
2781
    switch (sig) {
 
2782
    case SIGTERM:
 
2783
    case SIGQUIT:
 
2784
    case SIGKILL:
 
2785
#ifdef EXTRA_DEBUG
 
2786
      sql_print_information("Got signal %d to shutdown mysqld",sig);
 
2787
#endif
 
2788
      /* switch to the old log message processing */
 
2789
      logger.set_handlers(LOG_FILE, opt_slow_log ? LOG_FILE:LOG_NONE,
 
2790
                          opt_log ? LOG_FILE:LOG_NONE);
 
2791
      DBUG_PRINT("info",("Got signal: %d  abort_loop: %d",sig,abort_loop));
 
2792
      if (!abort_loop)
 
2793
      {
 
2794
        abort_loop=1;                           // mark abort for threads
 
2795
#ifdef USE_ONE_SIGNAL_HAND
 
2796
        pthread_t tmp;
 
2797
        if (!(opt_specialflag & SPECIAL_NO_PRIOR))
 
2798
          my_pthread_attr_setprio(&connection_attrib,INTERRUPT_PRIOR);
 
2799
        if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
 
2800
                           (void*) &sig))
 
2801
          sql_print_error("Can't create thread to kill server");
 
2802
#else
 
2803
        kill_server((void*) sig);       // MIT THREAD has a alarm thread
 
2804
#endif
 
2805
      }
 
2806
      break;
 
2807
    case SIGHUP:
 
2808
      if (!abort_loop)
 
2809
      {
 
2810
        bool not_used;
 
2811
        mysql_print_status();           // Print some debug info
 
2812
        reload_acl_and_cache((THD*) 0,
 
2813
                             (REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |
 
2814
                              REFRESH_GRANT |
 
2815
                              REFRESH_THREADS | REFRESH_HOSTS),
 
2816
                             (TABLE_LIST*) 0, &not_used); // Flush logs
 
2817
      }
 
2818
      /* reenable logs after the options were reloaded */
 
2819
      if (log_output_options & LOG_NONE)
 
2820
      {
 
2821
        logger.set_handlers(LOG_FILE,
 
2822
                            opt_slow_log ? LOG_TABLE : LOG_NONE,
 
2823
                            opt_log ? LOG_TABLE : LOG_NONE);
 
2824
      }
 
2825
      else
 
2826
      {
 
2827
        logger.set_handlers(LOG_FILE,
 
2828
                            opt_slow_log ? log_output_options : LOG_NONE,
 
2829
                            opt_log ? log_output_options : LOG_NONE);
 
2830
      }
 
2831
      break;
 
2832
#ifdef USE_ONE_SIGNAL_HAND
 
2833
    case THR_SERVER_ALARM:
 
2834
      process_alarm(sig);                       // Trigger alarms.
 
2835
      break;
 
2836
#endif
 
2837
    default:
 
2838
#ifdef EXTRA_DEBUG
 
2839
      sql_print_warning("Got signal: %d  error: %d",sig,error); /* purecov: tested */
 
2840
#endif
 
2841
      break;                                    /* purecov: tested */
 
2842
    }
 
2843
  }
 
2844
  return(0);                                    /* purecov: deadcode */
 
2845
}
 
2846
 
 
2847
static void check_data_home(const char *path)
 
2848
{}
 
2849
 
 
2850
#endif /*!EMBEDDED_LIBRARY*/
 
2851
#endif  /* __WIN__*/
 
2852
 
 
2853
 
 
2854
/**
 
2855
  All global error messages are sent here where the first one is stored
 
2856
  for the client.
 
2857
*/
 
2858
/* ARGSUSED */
 
2859
extern "C" int my_message_sql(uint error, const char *str, myf MyFlags);
 
2860
 
 
2861
int my_message_sql(uint error, const char *str, myf MyFlags)
 
2862
{
 
2863
  THD *thd;
 
2864
  DBUG_ENTER("my_message_sql");
 
2865
  DBUG_PRINT("error", ("error: %u  message: '%s'", error, str));
 
2866
 
 
2867
  DBUG_ASSERT(str != NULL);
 
2868
  /*
 
2869
    An error should have a valid error number (!= 0), so it can be caught
 
2870
    in stored procedures by SQL exception handlers.
 
2871
    Calling my_error() with error == 0 is a bug.
 
2872
    Remaining known places to fix:
 
2873
    - storage/myisam/mi_create.c, my_printf_error()
 
2874
    TODO:
 
2875
    DBUG_ASSERT(error != 0);
 
2876
  */
 
2877
 
 
2878
  if (error == 0)
 
2879
  {
 
2880
    /* At least, prevent new abuse ... */
 
2881
    DBUG_ASSERT(strncmp(str, "MyISAM table", 12) == 0);
 
2882
    error= ER_UNKNOWN_ERROR;
 
2883
  }
 
2884
 
 
2885
  if ((thd= current_thd))
 
2886
  {
 
2887
    /*
 
2888
      TODO: There are two exceptions mechanism (THD and sp_rcontext),
 
2889
      this could be improved by having a common stack of handlers.
 
2890
    */
 
2891
    if (thd->handle_error(error, str,
 
2892
                          MYSQL_ERROR::WARN_LEVEL_ERROR))
 
2893
      DBUG_RETURN(0);
 
2894
 
 
2895
    thd->is_slave_error=  1; // needed to catch query errors during replication
 
2896
 
 
2897
    /*
 
2898
      thd->lex->current_select == 0 if lex structure is not inited
 
2899
      (not query command (COM_QUERY))
 
2900
    */
 
2901
    if (thd->lex->current_select &&
 
2902
        thd->lex->current_select->no_error && !thd->is_fatal_error)
 
2903
    {
 
2904
      DBUG_PRINT("error",
 
2905
                 ("Error converted to warning: current_select: no_error %d  "
 
2906
                  "fatal_error: %d",
 
2907
                  (thd->lex->current_select ?
 
2908
                   thd->lex->current_select->no_error : 0),
 
2909
                  (int) thd->is_fatal_error));
 
2910
    }
 
2911
    else
 
2912
    {
 
2913
      if (! thd->main_da.is_error())            // Return only first message
 
2914
      {
 
2915
        thd->main_da.set_error_status(thd, error, str);
 
2916
      }
 
2917
      query_cache_abort(&thd->net);
 
2918
    }
 
2919
    /*
 
2920
      If a continue handler is found, the error message will be cleared
 
2921
      by the stored procedures code.
 
2922
    */
 
2923
    if (thd->spcont &&
 
2924
        ! (MyFlags & ME_NO_SP_HANDLER) &&
 
2925
        thd->spcont->handle_error(error, MYSQL_ERROR::WARN_LEVEL_ERROR, thd))
 
2926
    {
 
2927
      /*
 
2928
        Do not push any warnings, a handled error must be completely
 
2929
        silenced.
 
2930
      */
 
2931
      DBUG_RETURN(0);
 
2932
    }
 
2933
 
 
2934
    if (!thd->no_warnings_for_error &&
 
2935
        !(MyFlags & ME_NO_WARNING_FOR_ERROR))
 
2936
    {
 
2937
      /*
 
2938
        Suppress infinite recursion if there a memory allocation error
 
2939
        inside push_warning.
 
2940
      */
 
2941
      thd->no_warnings_for_error= TRUE;
 
2942
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str);
 
2943
      thd->no_warnings_for_error= FALSE;
 
2944
    }
 
2945
  }
 
2946
  if (!thd || MyFlags & ME_NOREFRESH)
 
2947
    sql_print_error("%s: %s",my_progname,str); /* purecov: inspected */
 
2948
  DBUG_RETURN(0);
 
2949
}
 
2950
 
 
2951
 
 
2952
#ifndef EMBEDDED_LIBRARY
 
2953
extern "C" void *my_str_malloc_mysqld(size_t size);
 
2954
extern "C" void my_str_free_mysqld(void *ptr);
 
2955
 
 
2956
void *my_str_malloc_mysqld(size_t size)
 
2957
{
 
2958
  return my_malloc(size, MYF(MY_FAE));
 
2959
}
 
2960
 
 
2961
 
 
2962
void my_str_free_mysqld(void *ptr)
 
2963
{
 
2964
  my_free((uchar*)ptr, MYF(MY_FAE));
 
2965
}
 
2966
#endif /* EMBEDDED_LIBRARY */
 
2967
 
 
2968
 
 
2969
#ifdef __WIN__
 
2970
 
 
2971
pthread_handler_t handle_shutdown(void *arg)
 
2972
{
 
2973
  MSG msg;
 
2974
  my_thread_init();
 
2975
 
 
2976
  /* this call should create the message queue for this thread */
 
2977
  PeekMessage(&msg, NULL, 1, 65534,PM_NOREMOVE);
 
2978
#if !defined(EMBEDDED_LIBRARY)
 
2979
  if (WaitForSingleObject(hEventShutdown,INFINITE)==WAIT_OBJECT_0)
 
2980
#endif /* EMBEDDED_LIBRARY */
 
2981
     kill_server(MYSQL_KILL_SIGNAL);
 
2982
  return 0;
 
2983
}
 
2984
#endif
 
2985
 
 
2986
const char *load_default_groups[]= {
 
2987
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
 
2988
"mysql_cluster",
 
2989
#endif
 
2990
"mysqld","server", MYSQL_BASE_VERSION, 0, 0};
 
2991
 
 
2992
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
 
2993
static const int load_default_groups_sz=
 
2994
sizeof(load_default_groups)/sizeof(load_default_groups[0]);
 
2995
#endif
 
2996
 
 
2997
 
 
2998
/**
 
2999
  Initialize one of the global date/time format variables.
 
3000
 
 
3001
  @param format_type            What kind of format should be supported
 
3002
  @param var_ptr                Pointer to variable that should be updated
 
3003
 
 
3004
  @note
 
3005
    The default value is taken from either opt_date_time_formats[] or
 
3006
    the ISO format (ANSI SQL)
 
3007
 
 
3008
  @retval
 
3009
    0 ok
 
3010
  @retval
 
3011
    1 error
 
3012
*/
 
3013
 
 
3014
static bool init_global_datetime_format(timestamp_type format_type,
 
3015
                                        DATE_TIME_FORMAT **var_ptr)
 
3016
{
 
3017
  /* Get command line option */
 
3018
  const char *str= opt_date_time_formats[format_type];
 
3019
 
 
3020
  if (!str)                                     // No specified format
 
3021
  {
 
3022
    str= get_date_time_format_str(&known_date_time_formats[ISO_FORMAT],
 
3023
                                  format_type);
 
3024
    /*
 
3025
      Set the "command line" option to point to the generated string so
 
3026
      that we can set global formats back to default
 
3027
    */
 
3028
    opt_date_time_formats[format_type]= str;
 
3029
  }
 
3030
  if (!(*var_ptr= date_time_format_make(format_type, str, strlen(str))))
 
3031
  {
 
3032
    fprintf(stderr, "Wrong date/time format specifier: %s\n", str);
 
3033
    return 1;
 
3034
  }
 
3035
  return 0;
 
3036
}
 
3037
 
 
3038
SHOW_VAR com_status_vars[]= {
 
3039
  {"admin_commands",       (char*) offsetof(STATUS_VAR, com_other), SHOW_LONG_STATUS},
 
3040
  {"assign_to_keycache",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ASSIGN_TO_KEYCACHE]), SHOW_LONG_STATUS},
 
3041
  {"alter_db",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_DB]), SHOW_LONG_STATUS},
 
3042
  {"alter_db_upgrade",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_DB_UPGRADE]), SHOW_LONG_STATUS},
 
3043
  {"alter_event",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_EVENT]), SHOW_LONG_STATUS},
 
3044
  {"alter_function",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_FUNCTION]), SHOW_LONG_STATUS},
 
3045
  {"alter_procedure",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_PROCEDURE]), SHOW_LONG_STATUS},
 
3046
  {"alter_server",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_SERVER]), SHOW_LONG_STATUS},
 
3047
  {"alter_table",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_TABLE]), SHOW_LONG_STATUS},
 
3048
  {"alter_tablespace",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_TABLESPACE]), SHOW_LONG_STATUS},
 
3049
  {"analyze",              (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ANALYZE]), SHOW_LONG_STATUS},
 
3050
  {"backup_table",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BACKUP_TABLE]), SHOW_LONG_STATUS},
 
3051
  {"begin",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BEGIN]), SHOW_LONG_STATUS},
 
3052
  {"binlog",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BINLOG_BASE64_EVENT]), SHOW_LONG_STATUS},
 
3053
  {"call_procedure",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CALL]), SHOW_LONG_STATUS},
 
3054
  {"change_db",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHANGE_DB]), SHOW_LONG_STATUS},
 
3055
  {"change_master",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHANGE_MASTER]), SHOW_LONG_STATUS},
 
3056
  {"check",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHECK]), SHOW_LONG_STATUS},
 
3057
  {"checksum",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHECKSUM]), SHOW_LONG_STATUS},
 
3058
  {"commit",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_COMMIT]), SHOW_LONG_STATUS},
 
3059
  {"create_db",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_DB]), SHOW_LONG_STATUS},
 
3060
  {"create_event",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_EVENT]), SHOW_LONG_STATUS},
 
3061
  {"create_function",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_SPFUNCTION]), SHOW_LONG_STATUS},
 
3062
  {"create_index",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_INDEX]), SHOW_LONG_STATUS},
 
3063
  {"create_procedure",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_PROCEDURE]), SHOW_LONG_STATUS},
 
3064
  {"create_server",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_SERVER]), SHOW_LONG_STATUS},
 
3065
  {"create_table",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_TABLE]), SHOW_LONG_STATUS},
 
3066
  {"create_trigger",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_TRIGGER]), SHOW_LONG_STATUS},
 
3067
  {"create_udf",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_FUNCTION]), SHOW_LONG_STATUS},
 
3068
  {"create_user",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_USER]), SHOW_LONG_STATUS},
 
3069
  {"create_view",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_VIEW]), SHOW_LONG_STATUS},
 
3070
  {"dealloc_sql",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DEALLOCATE_PREPARE]), SHOW_LONG_STATUS},
 
3071
  {"delete",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DELETE]), SHOW_LONG_STATUS},
 
3072
  {"delete_multi",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DELETE_MULTI]), SHOW_LONG_STATUS},
 
3073
  {"do",                   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DO]), SHOW_LONG_STATUS},
 
3074
  {"drop_db",              (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_DB]), SHOW_LONG_STATUS},
 
3075
  {"drop_event",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_EVENT]), SHOW_LONG_STATUS},
 
3076
  {"drop_function",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_FUNCTION]), SHOW_LONG_STATUS},
 
3077
  {"drop_index",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_INDEX]), SHOW_LONG_STATUS},
 
3078
  {"drop_procedure",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_PROCEDURE]), SHOW_LONG_STATUS},
 
3079
  {"drop_server",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_SERVER]), SHOW_LONG_STATUS},
 
3080
  {"drop_table",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_TABLE]), SHOW_LONG_STATUS},
 
3081
  {"drop_trigger",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_TRIGGER]), SHOW_LONG_STATUS},
 
3082
  {"drop_user",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_USER]), SHOW_LONG_STATUS},
 
3083
  {"drop_view",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_VIEW]), SHOW_LONG_STATUS},
 
3084
  {"empty_query",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EMPTY_QUERY]), SHOW_LONG_STATUS},
 
3085
  {"execute_sql",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EXECUTE]), SHOW_LONG_STATUS},
 
3086
  {"flush",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_FLUSH]), SHOW_LONG_STATUS},
 
3087
  {"grant",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_GRANT]), SHOW_LONG_STATUS},
 
3088
  {"ha_close",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_CLOSE]), SHOW_LONG_STATUS},
 
3089
  {"ha_open",              (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_OPEN]), SHOW_LONG_STATUS},
 
3090
  {"ha_read",              (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_READ]), SHOW_LONG_STATUS},
 
3091
  {"help",                 (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HELP]), SHOW_LONG_STATUS},
 
3092
  {"insert",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_INSERT]), SHOW_LONG_STATUS},
 
3093
  {"insert_select",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_INSERT_SELECT]), SHOW_LONG_STATUS},
 
3094
  {"install_plugin",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_INSTALL_PLUGIN]), SHOW_LONG_STATUS},
 
3095
  {"kill",                 (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_KILL]), SHOW_LONG_STATUS},
 
3096
  {"load",                 (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOAD]), SHOW_LONG_STATUS},
 
3097
  {"load_master_data",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOAD_MASTER_DATA]), SHOW_LONG_STATUS},
 
3098
  {"load_master_table",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOAD_MASTER_TABLE]), SHOW_LONG_STATUS},
 
3099
  {"lock_tables",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOCK_TABLES]), SHOW_LONG_STATUS},
 
3100
  {"optimize",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_OPTIMIZE]), SHOW_LONG_STATUS},
 
3101
  {"preload_keys",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PRELOAD_KEYS]), SHOW_LONG_STATUS},
 
3102
  {"prepare_sql",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PREPARE]), SHOW_LONG_STATUS},
 
3103
  {"purge",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PURGE]), SHOW_LONG_STATUS},
 
3104
  {"purge_before_date",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PURGE_BEFORE]), SHOW_LONG_STATUS},
 
3105
  {"release_savepoint",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RELEASE_SAVEPOINT]), SHOW_LONG_STATUS},
 
3106
  {"rename_table",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RENAME_TABLE]), SHOW_LONG_STATUS},
 
3107
  {"rename_user",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RENAME_USER]), SHOW_LONG_STATUS},
 
3108
  {"repair",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPAIR]), SHOW_LONG_STATUS},
 
3109
  {"replace",              (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPLACE]), SHOW_LONG_STATUS},
 
3110
  {"replace_select",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPLACE_SELECT]), SHOW_LONG_STATUS},
 
3111
  {"reset",                (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RESET]), SHOW_LONG_STATUS},
 
3112
  {"restore_table",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RESTORE_TABLE]), SHOW_LONG_STATUS},
 
3113
  {"revoke",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REVOKE]), SHOW_LONG_STATUS},
 
3114
  {"revoke_all",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REVOKE_ALL]), SHOW_LONG_STATUS},
 
3115
  {"rollback",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ROLLBACK]), SHOW_LONG_STATUS},
 
3116
  {"rollback_to_savepoint",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ROLLBACK_TO_SAVEPOINT]), SHOW_LONG_STATUS},
 
3117
  {"savepoint",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SAVEPOINT]), SHOW_LONG_STATUS},
 
3118
  {"select",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SELECT]), SHOW_LONG_STATUS},
 
3119
  {"set_option",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SET_OPTION]), SHOW_LONG_STATUS},
 
3120
  {"show_authors",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_AUTHORS]), SHOW_LONG_STATUS},
 
3121
  {"show_binlog_events",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOG_EVENTS]), SHOW_LONG_STATUS},
 
3122
  {"show_binlogs",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOGS]), SHOW_LONG_STATUS},
 
3123
  {"show_charsets",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CHARSETS]), SHOW_LONG_STATUS},
 
3124
  {"show_collations",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLLATIONS]), SHOW_LONG_STATUS},
 
3125
  {"show_column_types",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLUMN_TYPES]), SHOW_LONG_STATUS},
 
3126
  {"show_contributors",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CONTRIBUTORS]), SHOW_LONG_STATUS},
 
3127
  {"show_create_db",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_DB]), SHOW_LONG_STATUS},
 
3128
  {"show_create_event",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_EVENT]), SHOW_LONG_STATUS},
 
3129
  {"show_create_func",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_FUNC]), SHOW_LONG_STATUS},
 
3130
  {"show_create_proc",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_PROC]), SHOW_LONG_STATUS},
 
3131
  {"show_create_table",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE]), SHOW_LONG_STATUS},
 
3132
  {"show_create_trigger",  (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_TRIGGER]), SHOW_LONG_STATUS},
 
3133
  {"show_databases",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_DATABASES]), SHOW_LONG_STATUS},
 
3134
  {"show_engine_logs",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_LOGS]), SHOW_LONG_STATUS},
 
3135
  {"show_engine_mutex",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_MUTEX]), SHOW_LONG_STATUS},
 
3136
  {"show_engine_status",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_STATUS]), SHOW_LONG_STATUS},
 
3137
  {"show_events",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_EVENTS]), SHOW_LONG_STATUS},
 
3138
  {"show_errors",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ERRORS]), SHOW_LONG_STATUS},
 
3139
  {"show_fields",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_FIELDS]), SHOW_LONG_STATUS},
 
3140
#ifndef DBUG_OFF
 
3141
  {"show_function_code",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_FUNC_CODE]), SHOW_LONG_STATUS},
 
3142
#endif
 
3143
  {"show_function_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS_FUNC]), SHOW_LONG_STATUS},
 
3144
  {"show_grants",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_GRANTS]), SHOW_LONG_STATUS},
 
3145
  {"show_keys",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_KEYS]), SHOW_LONG_STATUS},
 
3146
  {"show_master_status",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_MASTER_STAT]), SHOW_LONG_STATUS},
 
3147
  {"show_new_master",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_NEW_MASTER]), SHOW_LONG_STATUS},
 
3148
  {"show_open_tables",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_OPEN_TABLES]), SHOW_LONG_STATUS},
 
3149
  {"show_plugins",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PLUGINS]), SHOW_LONG_STATUS},
 
3150
  {"show_privileges",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PRIVILEGES]), SHOW_LONG_STATUS},
 
3151
#ifndef DBUG_OFF
 
3152
  {"show_procedure_code",  (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROC_CODE]), SHOW_LONG_STATUS},
 
3153
#endif
 
3154
  {"show_procedure_status",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS_PROC]), SHOW_LONG_STATUS},
 
3155
  {"show_processlist",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROCESSLIST]), SHOW_LONG_STATUS},
 
3156
  {"show_profile",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROFILE]), SHOW_LONG_STATUS},
 
3157
  {"show_profiles",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROFILES]), SHOW_LONG_STATUS},
 
3158
  {"show_slave_hosts",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_HOSTS]), SHOW_LONG_STATUS},
 
3159
  {"show_slave_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_STAT]), SHOW_LONG_STATUS},
 
3160
  {"show_status",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS},
 
3161
  {"show_storage_engines", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STORAGE_ENGINES]), SHOW_LONG_STATUS},
 
3162
  {"show_table_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS},
 
3163
  {"show_tables",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLES]), SHOW_LONG_STATUS},
 
3164
  {"show_triggers",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TRIGGERS]), SHOW_LONG_STATUS},
 
3165
  {"show_variables",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS},
 
3166
  {"show_warnings",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
 
3167
  {"slave_start",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_START]), SHOW_LONG_STATUS},
 
3168
  {"slave_stop",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_STOP]), SHOW_LONG_STATUS},
 
3169
  {"stmt_close",           (char*) offsetof(STATUS_VAR, com_stmt_close), SHOW_LONG_STATUS},
 
3170
  {"stmt_execute",         (char*) offsetof(STATUS_VAR, com_stmt_execute), SHOW_LONG_STATUS},
 
3171
  {"stmt_fetch",           (char*) offsetof(STATUS_VAR, com_stmt_fetch), SHOW_LONG_STATUS},
 
3172
  {"stmt_prepare",         (char*) offsetof(STATUS_VAR, com_stmt_prepare), SHOW_LONG_STATUS},
 
3173
  {"stmt_reprepare",       (char*) offsetof(STATUS_VAR, com_stmt_reprepare), SHOW_LONG_STATUS},
 
3174
  {"stmt_reset",           (char*) offsetof(STATUS_VAR, com_stmt_reset), SHOW_LONG_STATUS},
 
3175
  {"stmt_send_long_data",  (char*) offsetof(STATUS_VAR, com_stmt_send_long_data), SHOW_LONG_STATUS},
 
3176
  {"truncate",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_TRUNCATE]), SHOW_LONG_STATUS},
 
3177
  {"uninstall_plugin",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNINSTALL_PLUGIN]), SHOW_LONG_STATUS},
 
3178
  {"unlock_tables",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNLOCK_TABLES]), SHOW_LONG_STATUS},
 
3179
  {"update",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UPDATE]), SHOW_LONG_STATUS},
 
3180
  {"update_multi",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UPDATE_MULTI]), SHOW_LONG_STATUS},
 
3181
  {"xa_commit",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_COMMIT]),SHOW_LONG_STATUS},
 
3182
  {"xa_end",               (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_END]),SHOW_LONG_STATUS},
 
3183
  {"xa_prepare",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_PREPARE]),SHOW_LONG_STATUS},
 
3184
  {"xa_recover",           (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_RECOVER]),SHOW_LONG_STATUS},
 
3185
  {"xa_rollback",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_ROLLBACK]),SHOW_LONG_STATUS},
 
3186
  {"xa_start",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_START]),SHOW_LONG_STATUS},
 
3187
  {NullS, NullS, SHOW_LONG}
 
3188
};
 
3189
 
 
3190
static int init_common_variables(const char *conf_file_name, int argc,
 
3191
                                 char **argv, const char **groups)
 
3192
{
 
3193
  char buff[FN_REFLEN], *s;
 
3194
  umask(((~my_umask) & 0666));
 
3195
  my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
 
3196
  tzset();                      // Set tzname
 
3197
 
 
3198
  max_system_variables.pseudo_thread_id= (ulong)~0;
 
3199
  server_start_time= flush_status_time= my_time(0);
 
3200
  rpl_filter= new Rpl_filter;
 
3201
  binlog_filter= new Rpl_filter;
 
3202
  if (!rpl_filter || !binlog_filter)
 
3203
  {
 
3204
    sql_perror("Could not allocate replication and binlog filters");
 
3205
    return 1;
 
3206
  }
 
3207
 
 
3208
  if (init_thread_environment() ||
 
3209
      mysql_init_variables())
 
3210
    return 1;
 
3211
 
 
3212
#ifdef HAVE_TZNAME
 
3213
  {
 
3214
    struct tm tm_tmp;
 
3215
    localtime_r(&server_start_time,&tm_tmp);
 
3216
    strmake(system_time_zone, tzname[tm_tmp.tm_isdst != 0 ? 1 : 0],
 
3217
            sizeof(system_time_zone)-1);
 
3218
 
 
3219
 }
 
3220
#endif
 
3221
  /*
 
3222
    We set SYSTEM time zone as reasonable default and
 
3223
    also for failure of my_tz_init() and bootstrap mode.
 
3224
    If user explicitly set time zone with --default-time-zone
 
3225
    option we will change this value in my_tz_init().
 
3226
  */
 
3227
  global_system_variables.time_zone= my_tz_SYSTEM;
 
3228
 
 
3229
  /*
 
3230
    Init mutexes for the global MYSQL_BIN_LOG objects.
 
3231
    As safe_mutex depends on what MY_INIT() does, we can't init the mutexes of
 
3232
    global MYSQL_BIN_LOGs in their constructors, because then they would be
 
3233
    inited before MY_INIT(). So we do it here.
 
3234
  */
 
3235
  mysql_bin_log.init_pthread_objects();
 
3236
 
 
3237
  if (gethostname(glob_hostname,sizeof(glob_hostname)) < 0)
 
3238
  {
 
3239
    strmake(glob_hostname, STRING_WITH_LEN("localhost"));
 
3240
    sql_print_warning("gethostname failed, using '%s' as hostname",
 
3241
                      glob_hostname);
 
3242
    strmake(pidfile_name, STRING_WITH_LEN("mysql"));
 
3243
  }
 
3244
  else
 
3245
  strmake(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
 
3246
  strmov(fn_ext(pidfile_name),".pid");          // Add proper extension
 
3247
 
 
3248
  /*
 
3249
    Add server status variables to the dynamic list of
 
3250
    status variables that is shown by SHOW STATUS.
 
3251
    Later, in plugin_init, and mysql_install_plugin
 
3252
    new entries could be added to that list.
 
3253
  */
 
3254
  if (add_status_vars(status_vars))
 
3255
    return 1; // an error was already reported
 
3256
 
 
3257
#ifndef DBUG_OFF
 
3258
  /*
 
3259
    We have few debug-only commands in com_status_vars, only visible in debug
 
3260
    builds. for simplicity we enable the assert only in debug builds
 
3261
 
 
3262
    There are 8 Com_ variables which don't have corresponding SQLCOM_ values:
 
3263
    (TODO strictly speaking they shouldn't be here, should not have Com_ prefix
 
3264
    that is. Perhaps Stmt_ ? Comstmt_ ? Prepstmt_ ?)
 
3265
 
 
3266
      Com_admin_commands       => com_other
 
3267
      Com_stmt_close           => com_stmt_close
 
3268
      Com_stmt_execute         => com_stmt_execute
 
3269
      Com_stmt_fetch           => com_stmt_fetch
 
3270
      Com_stmt_prepare         => com_stmt_prepare
 
3271
      Com_stmt_reprepare       => com_stmt_reprepare
 
3272
      Com_stmt_reset           => com_stmt_reset
 
3273
      Com_stmt_send_long_data  => com_stmt_send_long_data
 
3274
 
 
3275
    With this correction the number of Com_ variables (number of elements in
 
3276
    the array, excluding the last element - terminator) must match the number
 
3277
    of SQLCOM_ constants.
 
3278
  */
 
3279
  compile_time_assert(sizeof(com_status_vars)/sizeof(com_status_vars[0]) - 1 ==
 
3280
                     SQLCOM_END + 8);
 
3281
#endif
 
3282
 
 
3283
  orig_argc=argc;
 
3284
  orig_argv=argv;
 
3285
  load_defaults(conf_file_name, groups, &argc, &argv);
 
3286
  defaults_argv=argv;
 
3287
  defaults_argc=argc;
 
3288
  if (get_options(&defaults_argc, defaults_argv))
 
3289
    return 1;
 
3290
  set_server_version();
 
3291
 
 
3292
  DBUG_PRINT("info",("%s  Ver %s for %s on %s\n",my_progname,
 
3293
                     server_version, SYSTEM_TYPE,MACHINE_TYPE));
 
3294
 
 
3295
#ifdef HAVE_LARGE_PAGES
 
3296
  /* Initialize large page size */
 
3297
  if (opt_large_pages && (opt_large_page_size= my_get_large_page_size()))
 
3298
  {
 
3299
      my_use_large_pages= 1;
 
3300
      my_large_page_size= opt_large_page_size;
 
3301
  }
 
3302
#endif /* HAVE_LARGE_PAGES */
 
3303
 
 
3304
  /* connections and databases needs lots of files */
 
3305
  {
 
3306
    uint files, wanted_files, max_open_files;
 
3307
 
 
3308
    /* MyISAM requires two file handles per table. */
 
3309
    wanted_files= 10+max_connections+table_cache_size*2;
 
3310
    /*
 
3311
      We are trying to allocate no less than max_connections*5 file
 
3312
      handles (i.e. we are trying to set the limit so that they will
 
3313
      be available).  In addition, we allocate no less than how much
 
3314
      was already allocated.  However below we report a warning and
 
3315
      recompute values only if we got less file handles than were
 
3316
      explicitly requested.  No warning and re-computation occur if we
 
3317
      can't get max_connections*5 but still got no less than was
 
3318
      requested (value of wanted_files).
 
3319
    */
 
3320
    max_open_files= max(max(wanted_files, max_connections*5),
 
3321
                        open_files_limit);
 
3322
    files= my_set_max_open_files(max_open_files);
 
3323
 
 
3324
    if (files < wanted_files)
 
3325
    {
 
3326
      if (!open_files_limit)
 
3327
      {
 
3328
        /*
 
3329
          If we have requested too much file handles than we bring
 
3330
          max_connections in supported bounds.
 
3331
        */
 
3332
        max_connections= (ulong) min(files-10-TABLE_OPEN_CACHE_MIN*2,
 
3333
                                     max_connections);
 
3334
        /*
 
3335
          Decrease table_cache_size according to max_connections, but
 
3336
          not below TABLE_OPEN_CACHE_MIN.  Outer min() ensures that we
 
3337
          never increase table_cache_size automatically (that could
 
3338
          happen if max_connections is decreased above).
 
3339
        */
 
3340
        table_cache_size= (ulong) min(max((files-10-max_connections)/2,
 
3341
                                          TABLE_OPEN_CACHE_MIN),
 
3342
                                      table_cache_size);
 
3343
        DBUG_PRINT("warning",
 
3344
                   ("Changed limits: max_open_files: %u  max_connections: %ld  table_cache: %ld",
 
3345
                    files, max_connections, table_cache_size));
 
3346
        if (global_system_variables.log_warnings)
 
3347
          sql_print_warning("Changed limits: max_open_files: %u  max_connections: %ld  table_cache: %ld",
 
3348
                        files, max_connections, table_cache_size);
 
3349
      }
 
3350
      else if (global_system_variables.log_warnings)
 
3351
        sql_print_warning("Could not increase number of max_open_files to more than %u (request: %u)", files, wanted_files);
 
3352
    }
 
3353
    open_files_limit= files;
 
3354
  }
 
3355
  unireg_init(opt_specialflag); /* Set up extern variabels */
 
3356
  if (init_errmessage())        /* Read error messages from file */
 
3357
    return 1;
 
3358
  init_client_errs();
 
3359
  lex_init();
 
3360
  if (item_create_init())
 
3361
    return 1;
 
3362
  item_init();
 
3363
  if (set_var_init())
 
3364
    return 1;
 
3365
#ifdef HAVE_REPLICATION
 
3366
  if (init_replication_sys_vars())
 
3367
    return 1;
 
3368
#endif
 
3369
  mysys_uses_curses=0;
 
3370
#ifdef USE_REGEX
 
3371
  my_regex_init(&my_charset_latin1);
 
3372
#endif
 
3373
  /*
 
3374
    Process a comma-separated character set list and choose
 
3375
    the first available character set. This is mostly for
 
3376
    test purposes, to be able to start "mysqld" even if
 
3377
    the requested character set is not available (see bug#18743).
 
3378
  */
 
3379
  for (;;)
 
3380
  {
 
3381
    char *next_character_set_name= strchr(default_character_set_name, ',');
 
3382
    if (next_character_set_name)
 
3383
      *next_character_set_name++= '\0';
 
3384
    if (!(default_charset_info=
 
3385
          get_charset_by_csname(default_character_set_name,
 
3386
                                MY_CS_PRIMARY, MYF(MY_WME))))
 
3387
    {
 
3388
      if (next_character_set_name)
 
3389
      {
 
3390
        default_character_set_name= next_character_set_name;
 
3391
        default_collation_name= 0;          // Ignore collation
 
3392
      }
 
3393
      else
 
3394
        return 1;                           // Eof of the list
 
3395
    }
 
3396
    else
 
3397
      break;
 
3398
  }
 
3399
 
 
3400
  if (default_collation_name)
 
3401
  {
 
3402
    CHARSET_INFO *default_collation;
 
3403
    default_collation= get_charset_by_name(default_collation_name, MYF(0));
 
3404
    if (!default_collation)
 
3405
    {
 
3406
      sql_print_error(ER(ER_UNKNOWN_COLLATION), default_collation_name);
 
3407
      return 1;
 
3408
    }
 
3409
    if (!my_charset_same(default_charset_info, default_collation))
 
3410
    {
 
3411
      sql_print_error(ER(ER_COLLATION_CHARSET_MISMATCH),
 
3412
                      default_collation_name,
 
3413
                      default_charset_info->csname);
 
3414
      return 1;
 
3415
    }
 
3416
    default_charset_info= default_collation;
 
3417
  }
 
3418
  /* Set collactions that depends on the default collation */
 
3419
  global_system_variables.collation_server=      default_charset_info;
 
3420
  global_system_variables.collation_database=    default_charset_info;
 
3421
  global_system_variables.collation_connection=  default_charset_info;
 
3422
  global_system_variables.character_set_results= default_charset_info;
 
3423
  global_system_variables.character_set_client= default_charset_info;
 
3424
 
 
3425
  if (!(character_set_filesystem= 
 
3426
        get_charset_by_csname(character_set_filesystem_name,
 
3427
                              MY_CS_PRIMARY, MYF(MY_WME))))
 
3428
    return 1;
 
3429
  global_system_variables.character_set_filesystem= character_set_filesystem;
 
3430
 
 
3431
  if (!(my_default_lc_time_names=
 
3432
        my_locale_by_name(lc_time_names_name)))
 
3433
  {
 
3434
    sql_print_error("Unknown locale: '%s'", lc_time_names_name);
 
3435
    return 1;
 
3436
  }
 
3437
  global_system_variables.lc_time_names= my_default_lc_time_names;
 
3438
  
 
3439
  sys_init_connect.value_length= 0;
 
3440
  if ((sys_init_connect.value= opt_init_connect))
 
3441
    sys_init_connect.value_length= strlen(opt_init_connect);
 
3442
  else
 
3443
    sys_init_connect.value=my_strdup("",MYF(0));
 
3444
  sys_init_connect.is_os_charset= TRUE;
 
3445
 
 
3446
  sys_init_slave.value_length= 0;
 
3447
  if ((sys_init_slave.value= opt_init_slave))
 
3448
    sys_init_slave.value_length= strlen(opt_init_slave);
 
3449
  else
 
3450
    sys_init_slave.value=my_strdup("",MYF(0));
 
3451
  sys_init_slave.is_os_charset= TRUE;
 
3452
 
 
3453
  /* check log options and issue warnings if needed */
 
3454
  if (opt_log && opt_logname && !(log_output_options & LOG_FILE) &&
 
3455
      !(log_output_options & LOG_NONE))
 
3456
    sql_print_warning("Although a path was specified for the "
 
3457
                      "--log option, log tables are used. "
 
3458
                      "To enable logging to files use the --log-output option.");
 
3459
 
 
3460
  if (opt_slow_log && opt_slow_logname && !(log_output_options & LOG_FILE)
 
3461
      && !(log_output_options & LOG_NONE))
 
3462
    sql_print_warning("Although a path was specified for the "
 
3463
                      "--log_slow_queries option, log tables are used. "
 
3464
                      "To enable logging to files use the --log-output=file option.");
 
3465
 
 
3466
  s= opt_logname ? opt_logname : make_default_log_name(buff, ".log");
 
3467
  sys_var_general_log_path.value= my_strdup(s, MYF(0));
 
3468
  sys_var_general_log_path.value_length= strlen(s);
 
3469
 
 
3470
  s= opt_slow_logname ? opt_slow_logname : make_default_log_name(buff, "-slow.log");
 
3471
  sys_var_slow_log_path.value= my_strdup(s, MYF(0));
 
3472
  sys_var_slow_log_path.value_length= strlen(s);
 
3473
 
 
3474
#if defined(ENABLED_DEBUG_SYNC)
 
3475
  /* Initialize the debug sync facility. See debug_sync.cc. */
 
3476
  if (debug_sync_init())
 
3477
    return 1; /* purecov: tested */
 
3478
#endif /* defined(ENABLED_DEBUG_SYNC) */
 
3479
 
 
3480
#if (ENABLE_TEMP_POOL)
 
3481
  if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
 
3482
    return 1;
 
3483
#else
 
3484
  use_temp_pool= 0;
 
3485
#endif
 
3486
 
 
3487
  if (my_database_names_init())
 
3488
    return 1;
 
3489
 
 
3490
  /*
 
3491
    Ensure that lower_case_table_names is set on system where we have case
 
3492
    insensitive names.  If this is not done the users MyISAM tables will
 
3493
    get corrupted if accesses with names of different case.
 
3494
  */
 
3495
  DBUG_PRINT("info", ("lower_case_table_names: %d", lower_case_table_names));
 
3496
  lower_case_file_system= test_if_case_insensitive(mysql_real_data_home);
 
3497
  if (!lower_case_table_names && lower_case_file_system == 1)
 
3498
  {
 
3499
    if (lower_case_table_names_used)
 
3500
    {
 
3501
      if (global_system_variables.log_warnings)
 
3502
        sql_print_warning("\
 
3503
You have forced lower_case_table_names to 0 through a command-line \
 
3504
option, even though your file system '%s' is case insensitive.  This means \
 
3505
that you can corrupt a MyISAM table by accessing it with different cases. \
 
3506
You should consider changing lower_case_table_names to 1 or 2",
 
3507
                        mysql_real_data_home);
 
3508
    }
 
3509
    else
 
3510
    {
 
3511
      if (global_system_variables.log_warnings)
 
3512
        sql_print_warning("Setting lower_case_table_names=2 because file system for %s is case insensitive", mysql_real_data_home);
 
3513
      lower_case_table_names= 2;
 
3514
    }
 
3515
  }
 
3516
  else if (lower_case_table_names == 2 &&
 
3517
           !(lower_case_file_system=
 
3518
             (test_if_case_insensitive(mysql_real_data_home) == 1)))
 
3519
  {
 
3520
    if (global_system_variables.log_warnings)
 
3521
      sql_print_warning("lower_case_table_names was set to 2, even though your "
 
3522
                        "the file system '%s' is case sensitive.  Now setting "
 
3523
                        "lower_case_table_names to 0 to avoid future problems.",
 
3524
                        mysql_real_data_home);
 
3525
    lower_case_table_names= 0;
 
3526
  }
 
3527
  else
 
3528
  {
 
3529
    lower_case_file_system=
 
3530
      (test_if_case_insensitive(mysql_real_data_home) == 1);
 
3531
  }
 
3532
 
 
3533
  /* Reset table_alias_charset, now that lower_case_table_names is set. */
 
3534
  table_alias_charset= (lower_case_table_names ?
 
3535
                        files_charset_info :
 
3536
                        &my_charset_bin);
 
3537
 
 
3538
  return 0;
 
3539
}
 
3540
 
 
3541
 
 
3542
static int init_thread_environment()
 
3543
{
 
3544
  (void) pthread_mutex_init(&LOCK_mysql_create_db,MY_MUTEX_INIT_SLOW);
 
3545
  (void) pthread_mutex_init(&LOCK_lock_db,MY_MUTEX_INIT_SLOW);
 
3546
  (void) pthread_mutex_init(&LOCK_Acl,MY_MUTEX_INIT_SLOW);
 
3547
  (void) pthread_mutex_init(&LOCK_open, MY_MUTEX_INIT_FAST);
 
3548
  (void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
 
3549
  (void) pthread_mutex_init(&LOCK_mapped_file,MY_MUTEX_INIT_SLOW);
 
3550
  (void) pthread_mutex_init(&LOCK_status,MY_MUTEX_INIT_FAST);
 
3551
  (void) pthread_mutex_init(&LOCK_error_log,MY_MUTEX_INIT_FAST);
 
3552
  (void) pthread_mutex_init(&LOCK_delayed_insert,MY_MUTEX_INIT_FAST);
 
3553
  (void) pthread_mutex_init(&LOCK_delayed_status,MY_MUTEX_INIT_FAST);
 
3554
  (void) pthread_mutex_init(&LOCK_delayed_create,MY_MUTEX_INIT_SLOW);
 
3555
  (void) pthread_mutex_init(&LOCK_manager,MY_MUTEX_INIT_FAST);
 
3556
  (void) pthread_mutex_init(&LOCK_crypt,MY_MUTEX_INIT_FAST);
 
3557
  (void) pthread_mutex_init(&LOCK_bytes_sent,MY_MUTEX_INIT_FAST);
 
3558
  (void) pthread_mutex_init(&LOCK_bytes_received,MY_MUTEX_INIT_FAST);
 
3559
  (void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
 
3560
  (void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
 
3561
  (void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
 
3562
  (void) my_rwlock_init(&LOCK_system_variables_hash, NULL);
 
3563
  (void) pthread_mutex_init(&LOCK_global_read_lock, MY_MUTEX_INIT_FAST);
 
3564
  (void) pthread_mutex_init(&LOCK_prepared_stmt_count, MY_MUTEX_INIT_FAST);
 
3565
  (void) pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST);
 
3566
  (void) pthread_mutex_init(&LOCK_connection_count, MY_MUTEX_INIT_FAST);
 
3567
#ifdef HAVE_OPENSSL
 
3568
  (void) pthread_mutex_init(&LOCK_des_key_file,MY_MUTEX_INIT_FAST);
 
3569
#ifndef HAVE_YASSL
 
3570
  openssl_stdlocks= (openssl_lock_t*) OPENSSL_malloc(CRYPTO_num_locks() *
 
3571
                                                     sizeof(openssl_lock_t));
 
3572
  for (int i= 0; i < CRYPTO_num_locks(); ++i)
 
3573
    (void) my_rwlock_init(&openssl_stdlocks[i].lock, NULL); 
 
3574
  CRYPTO_set_dynlock_create_callback(openssl_dynlock_create);
 
3575
  CRYPTO_set_dynlock_destroy_callback(openssl_dynlock_destroy);
 
3576
  CRYPTO_set_dynlock_lock_callback(openssl_lock);
 
3577
  CRYPTO_set_locking_callback(openssl_lock_function);
 
3578
  CRYPTO_set_id_callback(openssl_id_function);
 
3579
#endif
 
3580
#endif
 
3581
  (void) my_rwlock_init(&LOCK_sys_init_connect, NULL);
 
3582
  (void) my_rwlock_init(&LOCK_sys_init_slave, NULL);
 
3583
  (void) my_rwlock_init(&LOCK_grant, NULL);
 
3584
  (void) pthread_cond_init(&COND_thread_count,NULL);
 
3585
  (void) pthread_cond_init(&COND_refresh,NULL);
 
3586
  (void) pthread_cond_init(&COND_global_read_lock,NULL);
 
3587
  (void) pthread_cond_init(&COND_thread_cache,NULL);
 
3588
  (void) pthread_cond_init(&COND_flush_thread_cache,NULL);
 
3589
  (void) pthread_cond_init(&COND_manager,NULL);
 
3590
#ifdef HAVE_REPLICATION
 
3591
  (void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST);
 
3592
  (void) pthread_cond_init(&COND_rpl_status, NULL);
 
3593
#endif
 
3594
  (void) pthread_mutex_init(&LOCK_server_started, MY_MUTEX_INIT_FAST);
 
3595
  (void) pthread_cond_init(&COND_server_started,NULL);
 
3596
  sp_cache_init();
 
3597
#ifdef HAVE_EVENT_SCHEDULER
 
3598
  Events::init_mutexes();
 
3599
#endif
 
3600
  /* Parameter for threads created for connections */
 
3601
  (void) pthread_attr_init(&connection_attrib);
 
3602
  (void) pthread_attr_setdetachstate(&connection_attrib,
 
3603
                                     PTHREAD_CREATE_DETACHED);
 
3604
  pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM);
 
3605
  if (!(opt_specialflag & SPECIAL_NO_PRIOR))
 
3606
    my_pthread_attr_setprio(&connection_attrib,WAIT_PRIOR);
 
3607
 
 
3608
  if (pthread_key_create(&THR_THD,NULL) ||
 
3609
      pthread_key_create(&THR_MALLOC,NULL))
 
3610
  {
 
3611
    sql_print_error("Can't create thread-keys");
 
3612
    return 1;
 
3613
  }
 
3614
  return 0;
 
3615
}
 
3616
 
 
3617
 
 
3618
#if defined(HAVE_OPENSSL) && !defined(HAVE_YASSL)
 
3619
static unsigned long openssl_id_function()
 
3620
 
3621
  return (unsigned long) pthread_self();
 
3622
 
3623
 
 
3624
 
 
3625
static openssl_lock_t *openssl_dynlock_create(const char *file, int line)
 
3626
 
3627
  openssl_lock_t *lock= new openssl_lock_t;
 
3628
  my_rwlock_init(&lock->lock, NULL);
 
3629
  return lock;
 
3630
}
 
3631
 
 
3632
 
 
3633
static void openssl_dynlock_destroy(openssl_lock_t *lock, const char *file, 
 
3634
                                    int line)
 
3635
{
 
3636
  rwlock_destroy(&lock->lock);
 
3637
  delete lock;
 
3638
}
 
3639
 
 
3640
 
 
3641
static void openssl_lock_function(int mode, int n, const char *file, int line)
 
3642
{
 
3643
  if (n < 0 || n > CRYPTO_num_locks())
 
3644
  {
 
3645
    /* Lock number out of bounds. */
 
3646
    sql_print_error("Fatal: OpenSSL interface problem (n = %d)", n);
 
3647
    abort();
 
3648
  }
 
3649
  openssl_lock(mode, &openssl_stdlocks[n], file, line);
 
3650
}
 
3651
 
 
3652
 
 
3653
static void openssl_lock(int mode, openssl_lock_t *lock, const char *file, 
 
3654
                         int line)
 
3655
{
 
3656
  int err;
 
3657
  char const *what;
 
3658
 
 
3659
  switch (mode) {
 
3660
  case CRYPTO_LOCK|CRYPTO_READ:
 
3661
    what = "read lock";
 
3662
    err = rw_rdlock(&lock->lock);
 
3663
    break;
 
3664
  case CRYPTO_LOCK|CRYPTO_WRITE:
 
3665
    what = "write lock";
 
3666
    err = rw_wrlock(&lock->lock);
 
3667
    break;
 
3668
  case CRYPTO_UNLOCK|CRYPTO_READ:
 
3669
  case CRYPTO_UNLOCK|CRYPTO_WRITE:
 
3670
    what = "unlock";
 
3671
    err = rw_unlock(&lock->lock);
 
3672
    break;
 
3673
  default:
 
3674
    /* Unknown locking mode. */
 
3675
    sql_print_error("Fatal: OpenSSL interface problem (mode=0x%x)", mode);
 
3676
    abort();
 
3677
  }
 
3678
  if (err) 
 
3679
  {
 
3680
    sql_print_error("Fatal: can't %s OpenSSL lock", what);
 
3681
    abort();
 
3682
  }
 
3683
}
 
3684
#endif /* HAVE_OPENSSL */
 
3685
 
 
3686
 
 
3687
#ifndef EMBEDDED_LIBRARY
 
3688
 
 
3689
static void init_ssl()
 
3690
{
 
3691
#ifdef HAVE_OPENSSL
 
3692
  if (opt_use_ssl)
 
3693
  {
 
3694
    enum enum_ssl_init_error error= SSL_INITERR_NOERROR;
 
3695
 
 
3696
    /* having ssl_acceptor_fd != 0 signals the use of SSL */
 
3697
    ssl_acceptor_fd= new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert,
 
3698
                                          opt_ssl_ca, opt_ssl_capath,
 
3699
                                          opt_ssl_cipher, &error);
 
3700
    DBUG_PRINT("info",("ssl_acceptor_fd: 0x%lx", (long) ssl_acceptor_fd));
 
3701
    if (!ssl_acceptor_fd)
 
3702
    {
 
3703
      sql_print_warning("Failed to setup SSL");
 
3704
      sql_print_warning("SSL error: %s", sslGetErrString(error));
 
3705
      opt_use_ssl = 0;
 
3706
      have_ssl= SHOW_OPTION_DISABLED;
 
3707
    }
 
3708
  }
 
3709
  else
 
3710
  {
 
3711
    have_ssl= SHOW_OPTION_DISABLED;
 
3712
  }
 
3713
  if (des_key_file)
 
3714
    load_des_key_file(des_key_file);
 
3715
#endif /* HAVE_OPENSSL */
 
3716
}
 
3717
 
 
3718
 
 
3719
static void end_ssl()
 
3720
{
 
3721
#ifdef HAVE_OPENSSL
 
3722
  if (ssl_acceptor_fd)
 
3723
  {
 
3724
    free_vio_ssl_acceptor_fd(ssl_acceptor_fd);
 
3725
    ssl_acceptor_fd= 0;
 
3726
  }
 
3727
#endif /* HAVE_OPENSSL */
 
3728
}
 
3729
 
 
3730
#endif /* EMBEDDED_LIBRARY */
 
3731
 
 
3732
 
 
3733
static int init_server_components()
 
3734
{
 
3735
  FILE* reopen;
 
3736
  DBUG_ENTER("init_server_components");
 
3737
  /*
 
3738
    We need to call each of these following functions to ensure that
 
3739
    all things are initialized so that unireg_abort() doesn't fail
 
3740
  */
 
3741
  if (table_cache_init() | table_def_init() | hostname_cache_init())
 
3742
    unireg_abort(1);
 
3743
 
 
3744
  query_cache_result_size_limit(query_cache_limit);
 
3745
  query_cache_set_min_res_unit(query_cache_min_res_unit);
 
3746
  query_cache_init();
 
3747
  query_cache_resize(query_cache_size);
 
3748
  randominit(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2);
 
3749
  setup_fpu();
 
3750
  init_thr_lock();
 
3751
#ifdef HAVE_REPLICATION
 
3752
  init_slave_list();
 
3753
#endif
 
3754
 
 
3755
  /* Setup logs */
 
3756
 
 
3757
  /*
 
3758
    Enable old-fashioned error log, except when the user has requested
 
3759
    help information. Since the implementation of plugin server
 
3760
    variables the help output is now written much later.
 
3761
  */
 
3762
  if (opt_error_log && !opt_help)
 
3763
  {
 
3764
    if (!log_error_file_ptr[0])
 
3765
      fn_format(log_error_file, pidfile_name, mysql_data_home, ".err",
 
3766
                MY_REPLACE_EXT); /* replace '.<domain>' by '.err', bug#4997 */
 
3767
    else
 
3768
      fn_format(log_error_file, log_error_file_ptr, mysql_data_home, ".err",
 
3769
                MY_UNPACK_FILENAME | MY_SAFE_PATH);
 
3770
    if (!log_error_file[0])
 
3771
      opt_error_log= 1;                         // Too long file name
 
3772
    else
 
3773
    {
 
3774
#ifndef EMBEDDED_LIBRARY
 
3775
      if (freopen(log_error_file, "a+", stdout))
 
3776
#endif
 
3777
      {
 
3778
        reopen= freopen(log_error_file, "a+", stderr);
 
3779
        setbuf(stderr, NULL);
 
3780
      }
 
3781
    }
 
3782
  }
 
3783
 
 
3784
  if (xid_cache_init())
 
3785
  {
 
3786
    sql_print_error("Out of memory");
 
3787
    unireg_abort(1);
 
3788
  }
 
3789
 
 
3790
  /* need to configure logging before initializing storage engines */
 
3791
  if (opt_update_log)
 
3792
  {
 
3793
    /*
 
3794
      Update log is removed since 5.0. But we still accept the option.
 
3795
      The idea is if the user already uses the binlog and the update log,
 
3796
      we completely ignore any option/variable related to the update log, like
 
3797
      if the update log did not exist. But if the user uses only the update
 
3798
      log, then we translate everything into binlog for him (with warnings).
 
3799
      Implementation of the above :
 
3800
      - If mysqld is started with --log-update and --log-bin,
 
3801
      ignore --log-update (print a warning), push a warning when SQL_LOG_UPDATE
 
3802
      is used, and turn off --sql-bin-update-same.
 
3803
      This will completely ignore SQL_LOG_UPDATE
 
3804
      - If mysqld is started with --log-update only,
 
3805
      change it to --log-bin (with the filename passed to log-update,
 
3806
      plus '-bin') (print a warning), push a warning when SQL_LOG_UPDATE is
 
3807
      used, and turn on --sql-bin-update-same.
 
3808
      This will translate SQL_LOG_UPDATE to SQL_LOG_BIN.
 
3809
 
 
3810
      Note that we tell the user that --sql-bin-update-same is deprecated and
 
3811
      does nothing, and we don't take into account if he used this option or
 
3812
      not; but internally we give this variable a value to have the behaviour
 
3813
      we want (i.e. have SQL_LOG_UPDATE influence SQL_LOG_BIN or not).
 
3814
      As sql-bin-update-same, log-update and log-bin cannot be changed by the
 
3815
      user after starting the server (they are not variables), the user will
 
3816
      not later interfere with the settings we do here.
 
3817
    */
 
3818
    if (opt_bin_log)
 
3819
    {
 
3820
      opt_sql_bin_update= 0;
 
3821
      sql_print_error("The update log is no longer supported by MySQL in \
 
3822
version 5.0 and above. It is replaced by the binary log.");
 
3823
    }
 
3824
    else
 
3825
    {
 
3826
      opt_sql_bin_update= 1;
 
3827
      opt_bin_log= 1;
 
3828
      if (opt_update_logname)
 
3829
      {
 
3830
        /* as opt_bin_log==0, no need to free opt_bin_logname */
 
3831
        if (!(opt_bin_logname= my_strdup(opt_update_logname, MYF(MY_WME))))
 
3832
        {
 
3833
          sql_print_error("Out of memory");
 
3834
          return EXIT_OUT_OF_MEMORY;
 
3835
        }
 
3836
        sql_print_error("The update log is no longer supported by MySQL in \
 
3837
version 5.0 and above. It is replaced by the binary log. Now starting MySQL \
 
3838
with --log-bin='%s' instead.",opt_bin_logname);
 
3839
      }
 
3840
      else
 
3841
        sql_print_error("The update log is no longer supported by MySQL in \
 
3842
version 5.0 and above. It is replaced by the binary log. Now starting MySQL \
 
3843
with --log-bin instead.");
 
3844
    }
 
3845
  }
 
3846
  if (opt_log_slave_updates && !opt_bin_log)
 
3847
  {
 
3848
    sql_print_error("You need to use --log-bin to make "
 
3849
                    "--log-slave-updates work.");
 
3850
    unireg_abort(1);
 
3851
  }
 
3852
  if (!opt_bin_log)
 
3853
  {
 
3854
    if (opt_binlog_format_id != BINLOG_FORMAT_UNSPEC)
 
3855
    {
 
3856
      sql_print_error("You need to use --log-bin to make "
 
3857
                      "--binlog-format work.");
 
3858
      unireg_abort(1);
 
3859
    }
 
3860
    else
 
3861
    {
 
3862
      global_system_variables.binlog_format= BINLOG_FORMAT_STMT;
 
3863
    }
 
3864
  }
 
3865
  else
 
3866
    if (opt_binlog_format_id == BINLOG_FORMAT_UNSPEC)
 
3867
      global_system_variables.binlog_format= BINLOG_FORMAT_STMT;
 
3868
    else
 
3869
    { 
 
3870
      DBUG_ASSERT(global_system_variables.binlog_format != BINLOG_FORMAT_UNSPEC);
 
3871
    }
 
3872
 
 
3873
  /* Check that we have not let the format to unspecified at this point */
 
3874
  DBUG_ASSERT((uint)global_system_variables.binlog_format <=
 
3875
              array_elements(binlog_format_names)-1);
 
3876
 
 
3877
#ifdef HAVE_REPLICATION
 
3878
  if (opt_log_slave_updates && replicate_same_server_id)
 
3879
  {
 
3880
    sql_print_error("\
 
3881
using --replicate-same-server-id in conjunction with \
 
3882
--log-slave-updates is impossible, it would lead to infinite loops in this \
 
3883
server.");
 
3884
    unireg_abort(1);
 
3885
  }
 
3886
#endif
 
3887
 
 
3888
  if (opt_bin_log)
 
3889
  {
 
3890
    /* Reports an error and aborts, if the --log-bin's path 
 
3891
       is a directory.*/
 
3892
    if (opt_bin_logname && 
 
3893
        opt_bin_logname[strlen(opt_bin_logname) - 1] == FN_LIBCHAR)
 
3894
    {
 
3895
      sql_print_error("Path '%s' is a directory name, please specify \
 
3896
a file name for --log-bin option", opt_bin_logname);
 
3897
      unireg_abort(1);
 
3898
    }
 
3899
 
 
3900
    /* Reports an error and aborts, if the --log-bin-index's path 
 
3901
       is a directory.*/
 
3902
    if (opt_binlog_index_name && 
 
3903
        opt_binlog_index_name[strlen(opt_binlog_index_name) - 1] 
 
3904
        == FN_LIBCHAR)
 
3905
    {
 
3906
      sql_print_error("Path '%s' is a directory name, please specify \
 
3907
a file name for --log-bin-index option", opt_binlog_index_name);
 
3908
      unireg_abort(1);
 
3909
    }
 
3910
 
 
3911
    char buf[FN_REFLEN];
 
3912
    const char *ln;
 
3913
    ln= mysql_bin_log.generate_name(opt_bin_logname, "-bin", 1, buf);
 
3914
    if (!opt_bin_logname && !opt_binlog_index_name)
 
3915
    {
 
3916
      /*
 
3917
        User didn't give us info to name the binlog index file.
 
3918
        Picking `hostname`-bin.index like did in 4.x, causes replication to
 
3919
        fail if the hostname is changed later. So, we would like to instead
 
3920
        require a name. But as we don't want to break many existing setups, we
 
3921
        only give warning, not error.
 
3922
      */
 
3923
      sql_print_warning("No argument was provided to --log-bin, and "
 
3924
                        "--log-bin-index was not used; so replication "
 
3925
                        "may break when this MySQL server acts as a "
 
3926
                        "master and has his hostname changed!! Please "
 
3927
                        "use '--log-bin=%s' to avoid this problem.", ln);
 
3928
    }
 
3929
    if (ln == buf)
 
3930
    {
 
3931
      my_free(opt_bin_logname, MYF(MY_ALLOW_ZERO_PTR));
 
3932
      opt_bin_logname=my_strdup(buf, MYF(0));
 
3933
    }
 
3934
    if (mysql_bin_log.open_index_file(opt_binlog_index_name, ln, TRUE))
 
3935
    {
 
3936
      unireg_abort(1);
 
3937
    }
 
3938
  }
 
3939
 
 
3940
  /* call ha_init_key_cache() on all key caches to init them */
 
3941
  process_key_caches(&ha_init_key_cache);
 
3942
 
 
3943
  /* Allow storage engine to give real error messages */
 
3944
  if (ha_init_errors())
 
3945
    DBUG_RETURN(1);
 
3946
 
 
3947
  { 
 
3948
    if (plugin_init(&defaults_argc, defaults_argv,
 
3949
                    (opt_noacl ? PLUGIN_INIT_SKIP_PLUGIN_TABLE : 0) |
 
3950
                    (opt_help ? PLUGIN_INIT_SKIP_INITIALIZATION : 0)))
 
3951
    {
 
3952
      sql_print_error("Failed to initialize plugins.");
 
3953
      unireg_abort(1);
 
3954
    }
 
3955
    plugins_are_initialized= TRUE;  /* Don't separate from init function */
 
3956
  }
 
3957
 
 
3958
  if (opt_help)
 
3959
    unireg_abort(0);
 
3960
 
 
3961
  /* we do want to exit if there are any other unknown options */
 
3962
  if (defaults_argc > 1)
 
3963
  {
 
3964
    int ho_error;
 
3965
    char **tmp_argv= defaults_argv;
 
3966
    struct my_option no_opts[]=
 
3967
    {
 
3968
      {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 
3969
    };
 
3970
    /*
 
3971
      We need to eat any 'loose' arguments first before we conclude
 
3972
      that there are unprocessed options.
 
3973
      But we need to preserve defaults_argv pointer intact for
 
3974
      free_defaults() to work. Thus we use a copy here.
 
3975
    */
 
3976
    my_getopt_skip_unknown= 0;
 
3977
 
 
3978
    if ((ho_error= handle_options(&defaults_argc, &tmp_argv, no_opts,
 
3979
                                  mysqld_get_one_option)))
 
3980
      unireg_abort(ho_error);
 
3981
    my_getopt_skip_unknown= TRUE;
 
3982
 
 
3983
    if (defaults_argc)
 
3984
    {
 
3985
      fprintf(stderr, "%s: Too many arguments (first extra is '%s').\n"
 
3986
              "Use --verbose --help to get a list of available options\n",
 
3987
              my_progname, *tmp_argv);
 
3988
      unireg_abort(1);
 
3989
    }
 
3990
  }
 
3991
 
 
3992
  /* if the errmsg.sys is not loaded, terminate to maintain behaviour */
 
3993
  if (!errmesg[0][0])
 
3994
    unireg_abort(1);
 
3995
 
 
3996
  /* We have to initialize the storage engines before CSV logging */
 
3997
  if (ha_init())
 
3998
  {
 
3999
    sql_print_error("Can't init databases");
 
4000
    unireg_abort(1);
 
4001
  }
 
4002
 
 
4003
#ifdef WITH_CSV_STORAGE_ENGINE
 
4004
  if (opt_bootstrap)
 
4005
    log_output_options= LOG_FILE;
 
4006
  else
 
4007
    logger.init_log_tables();
 
4008
 
 
4009
  if (log_output_options & LOG_NONE)
 
4010
  {
 
4011
    /*
 
4012
      Issue a warining if there were specified additional options to the
 
4013
      log-output along with NONE. Probably this wasn't what user wanted.
 
4014
    */
 
4015
    if ((log_output_options & LOG_NONE) && (log_output_options & ~LOG_NONE))
 
4016
      sql_print_warning("There were other values specified to "
 
4017
                        "log-output besides NONE. Disabling slow "
 
4018
                        "and general logs anyway.");
 
4019
    logger.set_handlers(LOG_FILE, LOG_NONE, LOG_NONE);
 
4020
  }
 
4021
  else
 
4022
  {
 
4023
    /* fall back to the log files if tables are not present */
 
4024
    LEX_STRING csv_name={C_STRING_WITH_LEN("csv")};
 
4025
    if (!plugin_is_ready(&csv_name, MYSQL_STORAGE_ENGINE_PLUGIN))
 
4026
    {
 
4027
      /* purecov: begin inspected */
 
4028
      sql_print_error("CSV engine is not present, falling back to the "
 
4029
                      "log files");
 
4030
      log_output_options= (log_output_options & ~LOG_TABLE) | LOG_FILE;
 
4031
      /* purecov: end */
 
4032
    }
 
4033
 
 
4034
    logger.set_handlers(LOG_FILE, opt_slow_log ? log_output_options:LOG_NONE,
 
4035
                        opt_log ? log_output_options:LOG_NONE);
 
4036
  }
 
4037
#else
 
4038
  logger.set_handlers(LOG_FILE, opt_slow_log ? LOG_FILE:LOG_NONE,
 
4039
                      opt_log ? LOG_FILE:LOG_NONE);
 
4040
#endif
 
4041
 
 
4042
  /*
 
4043
    Check that the default storage engine is actually available.
 
4044
  */
 
4045
  if (default_storage_engine_str)
 
4046
  {
 
4047
    LEX_STRING name= { default_storage_engine_str,
 
4048
                       strlen(default_storage_engine_str) };
 
4049
    plugin_ref plugin;
 
4050
    handlerton *hton;
 
4051
    
 
4052
    if ((plugin= ha_resolve_by_name(0, &name)))
 
4053
      hton= plugin_data(plugin, handlerton*);
 
4054
    else
 
4055
    {
 
4056
      sql_print_error("Unknown/unsupported table type: %s",
 
4057
                      default_storage_engine_str);
 
4058
      unireg_abort(1);
 
4059
    }
 
4060
    if (!ha_storage_engine_is_enabled(hton))
 
4061
    {
 
4062
      if (!opt_bootstrap)
 
4063
      {
 
4064
        sql_print_error("Default storage engine (%s) is not available",
 
4065
                        default_storage_engine_str);
 
4066
        unireg_abort(1);
 
4067
      }
 
4068
      DBUG_ASSERT(global_system_variables.table_plugin);
 
4069
    }
 
4070
    else
 
4071
    {
 
4072
      /*
 
4073
        Need to unlock as global_system_variables.table_plugin 
 
4074
        was acquired during plugin_init()
 
4075
      */
 
4076
      plugin_unlock(0, global_system_variables.table_plugin);
 
4077
      global_system_variables.table_plugin= plugin;
 
4078
    }
 
4079
  }
 
4080
 
 
4081
  tc_log= (total_ha_2pc > 1 ? (opt_bin_log  ?
 
4082
                               (TC_LOG *) &mysql_bin_log :
 
4083
                               (TC_LOG *) &tc_log_mmap) :
 
4084
           (TC_LOG *) &tc_log_dummy);
 
4085
 
 
4086
  if (tc_log->open(opt_bin_log ? opt_bin_logname : opt_tc_log_file))
 
4087
  {
 
4088
    sql_print_error("Can't init tc log");
 
4089
    unireg_abort(1);
 
4090
  }
 
4091
 
 
4092
  if (ha_recover(0))
 
4093
  {
 
4094
    unireg_abort(1);
 
4095
  }
 
4096
 
 
4097
  if (opt_bin_log && mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0,
 
4098
                                        WRITE_CACHE, 0, max_binlog_size, 0, TRUE))
 
4099
    unireg_abort(1);
 
4100
 
 
4101
#ifdef HAVE_REPLICATION
 
4102
  if (opt_bin_log && expire_logs_days)
 
4103
  {
 
4104
    time_t purge_time= server_start_time - expire_logs_days*24*60*60;
 
4105
    if (purge_time >= 0)
 
4106
      mysql_bin_log.purge_logs_before_date(purge_time);
 
4107
  }
 
4108
#endif
 
4109
#ifdef __NETWARE__
 
4110
  /* Increasing stacksize of threads on NetWare */
 
4111
  pthread_attr_setstacksize(&connection_attrib, NW_THD_STACKSIZE);
 
4112
#endif
 
4113
 
 
4114
  if (opt_myisam_log)
 
4115
    (void) mi_log(1);
 
4116
 
 
4117
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && !defined(EMBEDDED_LIBRARY)
 
4118
  if (locked_in_memory && !getuid())
 
4119
  {
 
4120
    if (setreuid((uid_t)-1, 0) == -1)
 
4121
    {                        // this should never happen
 
4122
      sql_perror("setreuid");
 
4123
      unireg_abort(1);
 
4124
    }
 
4125
    if (mlockall(MCL_CURRENT))
 
4126
    {
 
4127
      if (global_system_variables.log_warnings)
 
4128
        sql_print_warning("Failed to lock memory. Errno: %d\n",errno);
 
4129
      locked_in_memory= 0;
 
4130
    }
 
4131
    if (user_info)
 
4132
      set_user(mysqld_user, user_info);
 
4133
  }
 
4134
  else
 
4135
#endif
 
4136
    locked_in_memory=0;
 
4137
 
 
4138
  ft_init_stopwords();
 
4139
 
 
4140
  init_max_user_conn();
 
4141
  init_update_queries();
 
4142
  DBUG_RETURN(0);
 
4143
}
 
4144
 
 
4145
 
 
4146
#ifndef EMBEDDED_LIBRARY
 
4147
 
 
4148
static void create_shutdown_thread()
 
4149
{
 
4150
#ifdef __WIN__
 
4151
  hEventShutdown=CreateEvent(0, FALSE, FALSE, shutdown_event_name);
 
4152
  pthread_t hThread;
 
4153
  if (pthread_create(&hThread,&connection_attrib,handle_shutdown,0))
 
4154
    sql_print_warning("Can't create thread to handle shutdown requests");
 
4155
 
 
4156
  // On "Stop Service" we have to do regular shutdown
 
4157
  Service.SetShutdownEvent(hEventShutdown);
 
4158
#endif /* __WIN__ */
 
4159
}
 
4160
 
 
4161
#endif /* EMBEDDED_LIBRARY */
 
4162
 
 
4163
 
 
4164
#if (defined(__NT__) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY)
 
4165
static void handle_connections_methods()
 
4166
{
 
4167
  pthread_t hThread;
 
4168
  DBUG_ENTER("handle_connections_methods");
 
4169
#ifdef __NT__
 
4170
  if (hPipe == INVALID_HANDLE_VALUE &&
 
4171
      (!have_tcpip || opt_disable_networking) &&
 
4172
      !opt_enable_shared_memory)
 
4173
  {
 
4174
    sql_print_error("TCP/IP, --shared-memory, or --named-pipe should be configured on NT OS");
 
4175
    unireg_abort(1);                            // Will not return
 
4176
  }
 
4177
#endif
 
4178
 
 
4179
  pthread_mutex_lock(&LOCK_thread_count);
 
4180
  (void) pthread_cond_init(&COND_handler_count,NULL);
 
4181
  handler_count=0;
 
4182
#ifdef __NT__
 
4183
  if (hPipe != INVALID_HANDLE_VALUE)
 
4184
  {
 
4185
    handler_count++;
 
4186
    if (pthread_create(&hThread,&connection_attrib,
 
4187
                       handle_connections_namedpipes, 0))
 
4188
    {
 
4189
      sql_print_warning("Can't create thread to handle named pipes");
 
4190
      handler_count--;
 
4191
    }
 
4192
  }
 
4193
#endif /* __NT__ */
 
4194
  if (have_tcpip && !opt_disable_networking)
 
4195
  {
 
4196
    handler_count++;
 
4197
    if (pthread_create(&hThread,&connection_attrib,
 
4198
                       handle_connections_sockets, 0))
 
4199
    {
 
4200
      sql_print_warning("Can't create thread to handle TCP/IP");
 
4201
      handler_count--;
 
4202
    }
 
4203
  }
 
4204
#ifdef HAVE_SMEM
 
4205
  if (opt_enable_shared_memory)
 
4206
  {
 
4207
    handler_count++;
 
4208
    if (pthread_create(&hThread,&connection_attrib,
 
4209
                       handle_connections_shared_memory, 0))
 
4210
    {
 
4211
      sql_print_warning("Can't create thread to handle shared memory");
 
4212
      handler_count--;
 
4213
    }
 
4214
  }
 
4215
#endif 
 
4216
 
 
4217
  while (handler_count > 0)
 
4218
    pthread_cond_wait(&COND_handler_count,&LOCK_thread_count);
 
4219
  pthread_mutex_unlock(&LOCK_thread_count);
 
4220
  DBUG_VOID_RETURN;
 
4221
}
 
4222
 
 
4223
void decrement_handler_count()
 
4224
{
 
4225
  pthread_mutex_lock(&LOCK_thread_count);
 
4226
  handler_count--;
 
4227
  pthread_cond_signal(&COND_handler_count);
 
4228
  pthread_mutex_unlock(&LOCK_thread_count);  
 
4229
  my_thread_end();
 
4230
}
 
4231
#else
 
4232
#define decrement_handler_count()
 
4233
#endif /* defined(__NT__) || defined(HAVE_SMEM) */
 
4234
 
 
4235
 
 
4236
#ifndef EMBEDDED_LIBRARY
 
4237
#ifndef DBUG_OFF
 
4238
/*
 
4239
  Debugging helper function to keep the locale database
 
4240
  (see sql_locale.cc) and max_month_name_length and
 
4241
  max_day_name_length variable values in consistent state.
 
4242
*/
 
4243
static void test_lc_time_sz()
 
4244
{
 
4245
  DBUG_ENTER("test_lc_time_sz");
 
4246
  for (MY_LOCALE **loc= my_locales; *loc; loc++)
 
4247
  {
 
4248
    uint max_month_len= 0;
 
4249
    uint max_day_len = 0;
 
4250
    for (const char **month= (*loc)->month_names->type_names; *month; month++)
 
4251
    {
 
4252
      set_if_bigger(max_month_len,
 
4253
                    my_numchars_mb(&my_charset_utf8_general_ci,
 
4254
                                   *month, *month + strlen(*month)));
 
4255
    }
 
4256
    for (const char **day= (*loc)->day_names->type_names; *day; day++)
 
4257
    {
 
4258
      set_if_bigger(max_day_len,
 
4259
                    my_numchars_mb(&my_charset_utf8_general_ci,
 
4260
                                   *day, *day + strlen(*day)));
 
4261
    }
 
4262
    if ((*loc)->max_month_name_length != max_month_len ||
 
4263
        (*loc)->max_day_name_length != max_day_len)
 
4264
    {
 
4265
      DBUG_PRINT("Wrong max day name(or month name) length for locale:",
 
4266
                 ("%s", (*loc)->name));
 
4267
      DBUG_ASSERT(0);
 
4268
    }
 
4269
  }
 
4270
  DBUG_VOID_RETURN;
 
4271
}
 
4272
#endif//DBUG_OFF
 
4273
 
 
4274
 
 
4275
#ifdef __WIN__
 
4276
int win_main(int argc, char **argv)
 
4277
#else
 
4278
int main(int argc, char **argv)
 
4279
#endif
 
4280
{
 
4281
  MY_INIT(argv[0]);             // init my_sys library & pthreads
 
4282
  /* nothing should come before this line ^^^ */
 
4283
 
 
4284
  /* Set signal used to kill MySQL */
 
4285
#if defined(SIGUSR2)
 
4286
  thr_kill_signal= thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2;
 
4287
#else
 
4288
  thr_kill_signal= SIGINT;
 
4289
#endif
 
4290
 
 
4291
  /*
 
4292
    Perform basic logger initialization logger. Should be called after
 
4293
    MY_INIT, as it initializes mutexes. Log tables are inited later.
 
4294
  */
 
4295
  logger.init_base();
 
4296
 
 
4297
#ifdef _CUSTOMSTARTUPCONFIG_
 
4298
  if (_cust_check_startup())
 
4299
  {
 
4300
    / * _cust_check_startup will report startup failure error * /
 
4301
    exit(1);
 
4302
  }
 
4303
#endif
 
4304
 
 
4305
#ifdef  __WIN__
 
4306
  /*
 
4307
    Before performing any socket operation (like retrieving hostname
 
4308
    in init_common_variables we have to call WSAStartup
 
4309
  */
 
4310
  {
 
4311
    WSADATA WsaData;
 
4312
    if (SOCKET_ERROR == WSAStartup (0x0101, &WsaData))
 
4313
    {
 
4314
      /* errors are not read yet, so we use english text here */
 
4315
      my_message(ER_WSAS_FAILED, "WSAStartup Failed", MYF(0));
 
4316
      unireg_abort(1);
 
4317
    }
 
4318
  }
 
4319
#endif /* __WIN__ */
 
4320
 
 
4321
  if (init_common_variables(MYSQL_CONFIG_NAME,
 
4322
                            argc, argv, load_default_groups))
 
4323
    unireg_abort(1);                            // Will do exit
 
4324
 
 
4325
  init_signals();
 
4326
  if (!(opt_specialflag & SPECIAL_NO_PRIOR))
 
4327
    my_pthread_setprio(pthread_self(),CONNECT_PRIOR);
 
4328
#if defined(__ia64__) || defined(__ia64)
 
4329
  /*
 
4330
    Peculiar things with ia64 platforms - it seems we only have half the
 
4331
    stack size in reality, so we have to double it here
 
4332
  */
 
4333
  pthread_attr_setstacksize(&connection_attrib,my_thread_stack_size*2);
 
4334
#else
 
4335
  pthread_attr_setstacksize(&connection_attrib,my_thread_stack_size);
 
4336
#endif
 
4337
#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
 
4338
  {
 
4339
    /* Retrieve used stack size;  Needed for checking stack overflows */
 
4340
    size_t stack_size= 0;
 
4341
    pthread_attr_getstacksize(&connection_attrib, &stack_size);
 
4342
#if defined(__ia64__) || defined(__ia64)
 
4343
    stack_size/= 2;
 
4344
#endif
 
4345
    /* We must check if stack_size = 0 as Solaris 2.9 can return 0 here */
 
4346
    if (stack_size && stack_size < my_thread_stack_size)
 
4347
    {
 
4348
      if (global_system_variables.log_warnings)
 
4349
        sql_print_warning("Asked for %lu thread stack, but got %ld",
 
4350
                          my_thread_stack_size, (long) stack_size);
 
4351
#if defined(__ia64__) || defined(__ia64)
 
4352
      my_thread_stack_size= stack_size*2;
 
4353
#else
 
4354
      my_thread_stack_size= stack_size;
 
4355
#endif
 
4356
    }
 
4357
  }
 
4358
#endif
 
4359
#ifdef __NETWARE__
 
4360
  /* Increasing stacksize of threads on NetWare */
 
4361
  pthread_attr_setstacksize(&connection_attrib, NW_THD_STACKSIZE);
 
4362
#endif
 
4363
 
 
4364
  (void) thr_setconcurrency(concurrency);       // 10 by default
 
4365
 
 
4366
  select_thread=pthread_self();
 
4367
  select_thread_in_use=1;
 
4368
 
 
4369
#ifdef HAVE_LIBWRAP
 
4370
  libwrapName= my_progname+dirname_length(my_progname);
 
4371
  openlog(libwrapName, LOG_PID, LOG_AUTH);
 
4372
#endif
 
4373
 
 
4374
#ifndef DBUG_OFF
 
4375
  test_lc_time_sz();
 
4376
#endif
 
4377
 
 
4378
  /*
 
4379
    We have enough space for fiddling with the argv, continue
 
4380
  */
 
4381
  check_data_home(mysql_real_data_home);
 
4382
  if (my_setwd(mysql_real_data_home,MYF(MY_WME)) && !opt_help)
 
4383
    unireg_abort(1);                            /* purecov: inspected */
 
4384
  mysql_data_home= mysql_data_home_buff;
 
4385
  mysql_data_home[0]=FN_CURLIB;         // all paths are relative from here
 
4386
  mysql_data_home[1]=0;
 
4387
  mysql_data_home_len= 2;
 
4388
 
 
4389
  if ((user_info= check_user(mysqld_user)))
 
4390
  {
 
4391
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
 
4392
    if (locked_in_memory) // getuid() == 0 here
 
4393
      set_effective_user(user_info);
 
4394
    else
 
4395
#endif
 
4396
      set_user(mysqld_user, user_info);
 
4397
  }
 
4398
 
 
4399
  if (opt_bin_log && !server_id)
 
4400
  {
 
4401
    server_id= !master_host ? 1 : 2;
 
4402
#ifdef EXTRA_DEBUG
 
4403
    switch (server_id) {
 
4404
    case 1:
 
4405
      sql_print_warning("\
 
4406
You have enabled the binary log, but you haven't set server-id to \
 
4407
a non-zero value: we force server id to 1; updates will be logged to the \
 
4408
binary log, but connections from slaves will not be accepted.");
 
4409
      break;
 
4410
    case 2:
 
4411
      sql_print_warning("\
 
4412
You should set server-id to a non-0 value if master_host is set; \
 
4413
we force server id to 2, but this MySQL server will not act as a slave.");
 
4414
      break;
 
4415
    }
 
4416
#endif
 
4417
  }
 
4418
 
 
4419
  if (init_server_components())
 
4420
    unireg_abort(1);
 
4421
 
 
4422
  init_ssl();
 
4423
  network_init();
 
4424
 
 
4425
#ifdef __WIN__
 
4426
  if (!opt_console)
 
4427
  {
 
4428
    freopen(log_error_file,"a+",stdout);
 
4429
    freopen(log_error_file,"a+",stderr);
 
4430
    setbuf(stderr, NULL);
 
4431
    FreeConsole();                              // Remove window
 
4432
  }
 
4433
#endif
 
4434
 
 
4435
  /*
 
4436
   Initialize my_str_malloc() and my_str_free()
 
4437
  */
 
4438
  my_str_malloc= &my_str_malloc_mysqld;
 
4439
  my_str_free= &my_str_free_mysqld;
 
4440
 
 
4441
  /*
 
4442
    init signals & alarm
 
4443
    After this we can't quit by a simple unireg_abort
 
4444
  */
 
4445
  error_handler_hook= my_message_sql;
 
4446
  start_signal_handler();                               // Creates pidfile
 
4447
 
 
4448
  if (mysql_rm_tmp_tables() || acl_init(opt_noacl) ||
 
4449
      my_tz_init((THD *)0, default_tz_name, opt_bootstrap))
 
4450
  {
 
4451
    abort_loop=1;
 
4452
    select_thread_in_use=0;
 
4453
#ifndef __NETWARE__
 
4454
    (void) pthread_kill(signal_thread, MYSQL_KILL_SIGNAL);
 
4455
#endif /* __NETWARE__ */
 
4456
 
 
4457
    if (!opt_bootstrap)
 
4458
      (void) my_delete(pidfile_name,MYF(MY_WME));       // Not needed anymore
 
4459
 
 
4460
    if (unix_sock != INVALID_SOCKET)
 
4461
      unlink(mysqld_unix_port);
 
4462
    exit(1);
 
4463
  }
 
4464
  if (!opt_noacl)
 
4465
    (void) grant_init();
 
4466
 
 
4467
  if (!opt_bootstrap)
 
4468
    servers_init(0);
 
4469
 
 
4470
  if (!opt_noacl)
 
4471
  {
 
4472
#ifdef HAVE_DLOPEN
 
4473
    udf_init();
 
4474
#endif
 
4475
  }
 
4476
 
 
4477
  init_status_vars();
 
4478
  if (opt_bootstrap) /* If running with bootstrap, do not start replication. */
 
4479
    opt_skip_slave_start= 1;
 
4480
  /*
 
4481
    init_slave() must be called after the thread keys are created.
 
4482
    Some parts of the code (e.g. SHOW STATUS LIKE 'slave_running' and other
 
4483
    places) assume that active_mi != 0, so let's fail if it's 0 (out of
 
4484
    memory); a message has already been printed.
 
4485
  */
 
4486
  if (init_slave() && !active_mi)
 
4487
  {
 
4488
    unireg_abort(1);
 
4489
  }
 
4490
 
 
4491
  execute_ddl_log_recovery();
 
4492
 
 
4493
  if (Events::init(opt_noacl || opt_bootstrap))
 
4494
    unireg_abort(1);
 
4495
 
 
4496
  if (opt_bootstrap)
 
4497
  {
 
4498
    select_thread_in_use= 0;                    // Allow 'kill' to work
 
4499
    bootstrap(stdin);
 
4500
    unireg_abort(bootstrap_error ? 1 : 0);
 
4501
  }
 
4502
  if (opt_init_file)
 
4503
  {
 
4504
    if (read_init_file(opt_init_file))
 
4505
      unireg_abort(1);
 
4506
  }
 
4507
 
 
4508
  create_shutdown_thread();
 
4509
  start_handle_manager();
 
4510
 
 
4511
  sql_print_information(ER(ER_STARTUP),my_progname,server_version,
 
4512
                        ((unix_sock == INVALID_SOCKET) ? (char*) ""
 
4513
                                                       : mysqld_unix_port),
 
4514
                         mysqld_port,
 
4515
                         MYSQL_COMPILATION_COMMENT);
 
4516
#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
 
4517
  Service.SetRunning();
 
4518
#endif
 
4519
 
 
4520
 
 
4521
  /* Signal threads waiting for server to be started */
 
4522
  pthread_mutex_lock(&LOCK_server_started);
 
4523
  mysqld_server_started= 1;
 
4524
  pthread_cond_signal(&COND_server_started);
 
4525
  pthread_mutex_unlock(&LOCK_server_started);
 
4526
 
 
4527
#if defined(__NT__) || defined(HAVE_SMEM)
 
4528
  handle_connections_methods();
 
4529
#else
 
4530
#ifdef __WIN__
 
4531
  if (!have_tcpip || opt_disable_networking)
 
4532
  {
 
4533
    sql_print_error("TCP/IP unavailable or disabled with --skip-networking; no available interfaces");
 
4534
    unireg_abort(1);
 
4535
  }
 
4536
#endif
 
4537
  handle_connections_sockets(0);
 
4538
#endif /* __NT__ */
 
4539
 
 
4540
  /* (void) pthread_attr_destroy(&connection_attrib); */
 
4541
  
 
4542
  DBUG_PRINT("quit",("Exiting main thread"));
 
4543
 
 
4544
#ifndef __WIN__
 
4545
#ifdef EXTRA_DEBUG2
 
4546
  sql_print_error("Before Lock_thread_count");
 
4547
#endif
 
4548
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
4549
  DBUG_PRINT("quit", ("Got thread_count mutex"));
 
4550
  select_thread_in_use=0;                       // For close_connections
 
4551
  (void) pthread_mutex_unlock(&LOCK_thread_count);
 
4552
  (void) pthread_cond_broadcast(&COND_thread_count);
 
4553
#ifdef EXTRA_DEBUG2
 
4554
  sql_print_error("After lock_thread_count");
 
4555
#endif
 
4556
#endif /* __WIN__ */
 
4557
 
 
4558
  /* Wait until cleanup is done */
 
4559
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
4560
  while (!ready_to_exit)
 
4561
    pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
 
4562
  (void) pthread_mutex_unlock(&LOCK_thread_count);
 
4563
 
 
4564
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
 
4565
  if (Service.IsNT() && start_mode)
 
4566
    Service.Stop();
 
4567
  else
 
4568
  {
 
4569
    Service.SetShutdownEvent(0);
 
4570
    if (hEventShutdown)
 
4571
      CloseHandle(hEventShutdown);
 
4572
  }
 
4573
#endif
 
4574
  clean_up(1);
 
4575
  wait_for_signal_thread_to_end();
 
4576
  clean_up_mutexes();
 
4577
  my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
 
4578
 
 
4579
  exit(0);
 
4580
  return(0);                                    /* purecov: deadcode */
 
4581
}
 
4582
 
 
4583
#endif /* EMBEDDED_LIBRARY */
 
4584
 
 
4585
 
 
4586
/****************************************************************************
 
4587
  Main and thread entry function for Win32
 
4588
  (all this is needed only to run mysqld as a service on WinNT)
 
4589
****************************************************************************/
 
4590
 
 
4591
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
 
4592
int mysql_service(void *p)
 
4593
{
 
4594
  if (use_opt_args)
 
4595
    win_main(opt_argc, opt_argv);
 
4596
  else
 
4597
    win_main(Service.my_argc, Service.my_argv);
 
4598
  return 0;
 
4599
}
 
4600
 
 
4601
 
 
4602
/* Quote string if it contains space, else copy */
 
4603
 
 
4604
static char *add_quoted_string(char *to, const char *from, char *to_end)
 
4605
{
 
4606
  uint length= (uint) (to_end-to);
 
4607
 
 
4608
  if (!strchr(from, ' '))
 
4609
    return strmake(to, from, length-1);
 
4610
  return strxnmov(to, length-1, "\"", from, "\"", NullS);
 
4611
}
 
4612
 
 
4613
 
 
4614
/**
 
4615
  Handle basic handling of services, like installation and removal.
 
4616
 
 
4617
  @param argv                   Pointer to argument list
 
4618
  @param servicename            Internal name of service
 
4619
  @param displayname            Display name of service (in taskbar ?)
 
4620
  @param file_path              Path to this program
 
4621
  @param startup_option Startup option to mysqld
 
4622
 
 
4623
  @retval
 
4624
    0           option handled
 
4625
  @retval
 
4626
    1           Could not handle option
 
4627
*/
 
4628
 
 
4629
static bool
 
4630
default_service_handling(char **argv,
 
4631
                         const char *servicename,
 
4632
                         const char *displayname,
 
4633
                         const char *file_path,
 
4634
                         const char *extra_opt,
 
4635
                         const char *account_name)
 
4636
{
 
4637
  char path_and_service[FN_REFLEN+FN_REFLEN+32], *pos, *end;
 
4638
  const char *opt_delim;
 
4639
  end= path_and_service + sizeof(path_and_service)-3;
 
4640
 
 
4641
  /* We have to quote filename if it contains spaces */
 
4642
  pos= add_quoted_string(path_and_service, file_path, end);
 
4643
  if (*extra_opt)
 
4644
  {
 
4645
    /* 
 
4646
     Add option after file_path. There will be zero or one extra option.  It's 
 
4647
     assumed to be --defaults-file=file but isn't checked.  The variable (not
 
4648
     the option name) should be quoted if it contains a string.  
 
4649
    */
 
4650
    *pos++= ' ';
 
4651
    if (opt_delim= strchr(extra_opt, '='))
 
4652
    {
 
4653
      size_t length= ++opt_delim - extra_opt;
 
4654
      pos= strnmov(pos, extra_opt, length);
 
4655
    }
 
4656
    else
 
4657
      opt_delim= extra_opt;
 
4658
    
 
4659
    pos= add_quoted_string(pos, opt_delim, end);
 
4660
  }
 
4661
  /* We must have servicename last */
 
4662
  *pos++= ' ';
 
4663
  (void) add_quoted_string(pos, servicename, end);
 
4664
 
 
4665
  if (Service.got_service_option(argv, "install"))
 
4666
  {
 
4667
    Service.Install(1, servicename, displayname, path_and_service,
 
4668
                    account_name);
 
4669
    return 0;
 
4670
  }
 
4671
  if (Service.got_service_option(argv, "install-manual"))
 
4672
  {
 
4673
    Service.Install(0, servicename, displayname, path_and_service,
 
4674
                    account_name);
 
4675
    return 0;
 
4676
  }
 
4677
  if (Service.got_service_option(argv, "remove"))
 
4678
  {
 
4679
    Service.Remove(servicename);
 
4680
    return 0;
 
4681
  }
 
4682
  return 1;
 
4683
}
 
4684
 
 
4685
 
 
4686
int main(int argc, char **argv)
 
4687
{
 
4688
  /*
 
4689
    When several instances are running on the same machine, we
 
4690
    need to have an  unique  named  hEventShudown  through the
 
4691
    application PID e.g.: MySQLShutdown1890; MySQLShutdown2342
 
4692
  */
 
4693
  int10_to_str((int) GetCurrentProcessId(),strmov(shutdown_event_name,
 
4694
                                                  "MySQLShutdown"), 10);
 
4695
 
 
4696
  /* Must be initialized early for comparison of service name */
 
4697
  system_charset_info= &my_charset_utf8_general_ci;
 
4698
 
 
4699
  if (Service.GetOS())  /* true NT family */
 
4700
  {
 
4701
    char file_path[FN_REFLEN];
 
4702
    my_path(file_path, argv[0], "");                  /* Find name in path */
 
4703
    fn_format(file_path,argv[0],file_path,"",
 
4704
              MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_RESOLVE_SYMLINKS);
 
4705
 
 
4706
    if (argc == 2)
 
4707
    {
 
4708
      if (!default_service_handling(argv, MYSQL_SERVICENAME, MYSQL_SERVICENAME,
 
4709
                                   file_path, "", NULL))
 
4710
        return 0;
 
4711
      if (Service.IsService(argv[1]))        /* Start an optional service */
 
4712
      {
 
4713
        /*
 
4714
          Only add the service name to the groups read from the config file
 
4715
          if it's not "MySQL". (The default service name should be 'mysqld'
 
4716
          but we started a bad tradition by calling it MySQL from the start
 
4717
          and we are now stuck with it.
 
4718
        */
 
4719
        if (my_strcasecmp(system_charset_info, argv[1],"mysql"))
 
4720
          load_default_groups[load_default_groups_sz-2]= argv[1];
 
4721
        start_mode= 1;
 
4722
        Service.Init(argv[1], mysql_service);
 
4723
        return 0;
 
4724
      }
 
4725
    }
 
4726
    else if (argc == 3) /* install or remove any optional service */
 
4727
    {
 
4728
      if (!default_service_handling(argv, argv[2], argv[2], file_path, "",
 
4729
                                    NULL))
 
4730
        return 0;
 
4731
      if (Service.IsService(argv[2]))
 
4732
      {
 
4733
        /*
 
4734
          mysqld was started as
 
4735
          mysqld --defaults-file=my_path\my.ini service-name
 
4736
        */
 
4737
        use_opt_args=1;
 
4738
        opt_argc= 2;                            // Skip service-name
 
4739
        opt_argv=argv;
 
4740
        start_mode= 1;
 
4741
        if (my_strcasecmp(system_charset_info, argv[2],"mysql"))
 
4742
          load_default_groups[load_default_groups_sz-2]= argv[2];
 
4743
        Service.Init(argv[2], mysql_service);
 
4744
        return 0;
 
4745
      }
 
4746
    }
 
4747
    else if (argc == 4 || argc == 5)
 
4748
    {
 
4749
      /*
 
4750
        This may seem strange, because we handle --local-service while
 
4751
        preserving 4.1's behavior of allowing any one other argument that is
 
4752
        passed to the service on startup. (The assumption is that this is
 
4753
        --defaults-file=file, but that was not enforced in 4.1, so we don't
 
4754
        enforce it here.)
 
4755
      */
 
4756
      const char *extra_opt= NullS;
 
4757
      const char *account_name = NullS;
 
4758
      int index;
 
4759
      for (index = 3; index < argc; index++)
 
4760
      {
 
4761
        if (!strcmp(argv[index], "--local-service"))
 
4762
          account_name= "NT AUTHORITY\\LocalService";
 
4763
        else
 
4764
          extra_opt= argv[index];
 
4765
      }
 
4766
 
 
4767
      if (argc == 4 || account_name)
 
4768
        if (!default_service_handling(argv, argv[2], argv[2], file_path,
 
4769
                                      extra_opt, account_name))
 
4770
          return 0;
 
4771
    }
 
4772
    else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME))
 
4773
    {
 
4774
      /* start the default service */
 
4775
      start_mode= 1;
 
4776
      Service.Init(MYSQL_SERVICENAME, mysql_service);
 
4777
      return 0;
 
4778
    }
 
4779
  }
 
4780
  /* Start as standalone server */
 
4781
  Service.my_argc=argc;
 
4782
  Service.my_argv=argv;
 
4783
  mysql_service(NULL);
 
4784
  return 0;
 
4785
}
 
4786
#endif
 
4787
 
 
4788
 
 
4789
/**
 
4790
  Execute all commands from a file. Used by the mysql_install_db script to
 
4791
  create MySQL privilege tables without having to start a full MySQL server.
 
4792
*/
 
4793
 
 
4794
static void bootstrap(FILE *file)
 
4795
{
 
4796
  DBUG_ENTER("bootstrap");
 
4797
 
 
4798
  THD *thd= new THD;
 
4799
  thd->bootstrap=1;
 
4800
  my_net_init(&thd->net,(st_vio*) 0);
 
4801
  thd->max_client_packet_length= thd->net.max_packet;
 
4802
  thd->security_ctx->master_access= ~(ulong)0;
 
4803
  thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
 
4804
  thread_count++;
 
4805
  in_bootstrap= TRUE;
 
4806
 
 
4807
  bootstrap_file=file;
 
4808
#ifndef EMBEDDED_LIBRARY                        // TODO:  Enable this
 
4809
  if (pthread_create(&thd->real_id,&connection_attrib,handle_bootstrap,
 
4810
                     (void*) thd))
 
4811
  {
 
4812
    sql_print_warning("Can't create thread to handle bootstrap");
 
4813
    bootstrap_error=-1;
 
4814
    DBUG_VOID_RETURN;
 
4815
  }
 
4816
  /* Wait for thread to die */
 
4817
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
4818
  while (in_bootstrap)
 
4819
  {
 
4820
    (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
 
4821
    DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
 
4822
  }
 
4823
  (void) pthread_mutex_unlock(&LOCK_thread_count);
 
4824
#else
 
4825
  thd->mysql= 0;
 
4826
  handle_bootstrap((void *)thd);
 
4827
#endif
 
4828
 
 
4829
  DBUG_VOID_RETURN;
 
4830
}
 
4831
 
 
4832
 
 
4833
static bool read_init_file(char *file_name)
 
4834
{
 
4835
  FILE *file;
 
4836
  DBUG_ENTER("read_init_file");
 
4837
  DBUG_PRINT("enter",("name: %s",file_name));
 
4838
  if (!(file=my_fopen(file_name,O_RDONLY,MYF(MY_WME))))
 
4839
    DBUG_RETURN(TRUE);
 
4840
  bootstrap(file);
 
4841
  (void) my_fclose(file,MYF(MY_WME));
 
4842
  DBUG_RETURN(FALSE);
 
4843
}
 
4844
 
 
4845
 
 
4846
#ifndef EMBEDDED_LIBRARY
 
4847
 
 
4848
/*
 
4849
   Simple scheduler that use the main thread to handle the request
 
4850
 
 
4851
   NOTES
 
4852
     This is only used for debugging, when starting mysqld with
 
4853
     --thread-handling=no-threads or --one-thread
 
4854
 
 
4855
     When we enter this function, LOCK_thread_count is hold!
 
4856
*/
 
4857
   
 
4858
void handle_connection_in_main_thread(THD *thd)
 
4859
{
 
4860
  safe_mutex_assert_owner(&LOCK_thread_count);
 
4861
  thread_cache_size=0;                  // Safety
 
4862
  threads.append(thd);
 
4863
  pthread_mutex_unlock(&LOCK_thread_count);
 
4864
  thd->start_utime= my_micro_time();
 
4865
  handle_one_connection(thd);
 
4866
}
 
4867
 
 
4868
 
 
4869
/*
 
4870
  Scheduler that uses one thread per connection
 
4871
*/
 
4872
 
 
4873
void create_thread_to_handle_connection(THD *thd)
 
4874
{
 
4875
  if (cached_thread_count > wake_thread)
 
4876
  {
 
4877
    /* Get thread from cache */
 
4878
    thread_cache.append(thd);
 
4879
    wake_thread++;
 
4880
    pthread_cond_signal(&COND_thread_cache);
 
4881
  }
 
4882
  else
 
4883
  {
 
4884
    char error_message_buff[MYSQL_ERRMSG_SIZE];
 
4885
    /* Create new thread to handle connection */
 
4886
    int error;
 
4887
    thread_created++;
 
4888
    threads.append(thd);
 
4889
    DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id));
 
4890
    thd->prior_thr_create_utime= thd->start_utime= my_micro_time();
 
4891
    if ((error=pthread_create(&thd->real_id,&connection_attrib,
 
4892
                              handle_one_connection,
 
4893
                              (void*) thd)))
 
4894
    {
 
4895
      /* purecov: begin inspected */
 
4896
      DBUG_PRINT("error",
 
4897
                 ("Can't create thread to handle request (error %d)",
 
4898
                  error));
 
4899
      thread_count--;
 
4900
      thd->killed= THD::KILL_CONNECTION;                        // Safety
 
4901
      (void) pthread_mutex_unlock(&LOCK_thread_count);
 
4902
 
 
4903
      pthread_mutex_lock(&LOCK_connection_count);
 
4904
      --connection_count;
 
4905
      pthread_mutex_unlock(&LOCK_connection_count);
 
4906
 
 
4907
      statistic_increment(aborted_connects,&LOCK_status);
 
4908
      /* Can't use my_error() since store_globals has not been called. */
 
4909
      my_snprintf(error_message_buff, sizeof(error_message_buff),
 
4910
                  ER(ER_CANT_CREATE_THREAD), error);
 
4911
      net_send_error(thd, ER_CANT_CREATE_THREAD, error_message_buff);
 
4912
      (void) pthread_mutex_lock(&LOCK_thread_count);
 
4913
      close_connection(thd,0,0);
 
4914
      delete thd;
 
4915
      (void) pthread_mutex_unlock(&LOCK_thread_count);
 
4916
      return;
 
4917
      /* purecov: end */
 
4918
    }
 
4919
  }
 
4920
  (void) pthread_mutex_unlock(&LOCK_thread_count);
 
4921
  DBUG_PRINT("info",("Thread created"));
 
4922
}
 
4923
 
 
4924
 
 
4925
/**
 
4926
  Create new thread to handle incoming connection.
 
4927
 
 
4928
    This function will create new thread to handle the incoming
 
4929
    connection.  If there are idle cached threads one will be used.
 
4930
    'thd' will be pushed into 'threads'.
 
4931
 
 
4932
    In single-threaded mode (\#define ONE_THREAD) connection will be
 
4933
    handled inside this function.
 
4934
 
 
4935
  @param[in,out] thd    Thread handle of future thread.
 
4936
*/
 
4937
 
 
4938
static void create_new_thread(THD *thd)
 
4939
{
 
4940
  NET *net=&thd->net;
 
4941
  DBUG_ENTER("create_new_thread");
 
4942
 
 
4943
  if (protocol_version > 9)
 
4944
    net->return_errno=1;
 
4945
 
 
4946
  /*
 
4947
    Don't allow too many connections. We roughly check here that we allow
 
4948
    only (max_connections + 1) connections.
 
4949
  */
 
4950
 
 
4951
  pthread_mutex_lock(&LOCK_connection_count);
 
4952
 
 
4953
  if (connection_count >= max_connections + 1 || abort_loop)
 
4954
  {
 
4955
    pthread_mutex_unlock(&LOCK_connection_count);
 
4956
 
 
4957
    DBUG_PRINT("error",("Too many connections"));
 
4958
    close_connection(thd, ER_CON_COUNT_ERROR, 1);
 
4959
    delete thd;
 
4960
    DBUG_VOID_RETURN;
 
4961
  }
 
4962
 
 
4963
  ++connection_count;
 
4964
 
 
4965
  if (connection_count > max_used_connections)
 
4966
    max_used_connections= connection_count;
 
4967
 
 
4968
  pthread_mutex_unlock(&LOCK_connection_count);
 
4969
 
 
4970
  /* Start a new thread to handle connection. */
 
4971
 
 
4972
  pthread_mutex_lock(&LOCK_thread_count);
 
4973
 
 
4974
  /*
 
4975
    The initialization of thread_id is done in create_embedded_thd() for
 
4976
    the embedded library.
 
4977
    TODO: refactor this to avoid code duplication there
 
4978
  */
 
4979
  thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
 
4980
 
 
4981
  thread_count++;
 
4982
 
 
4983
  thread_scheduler.add_connection(thd);
 
4984
 
 
4985
  DBUG_VOID_RETURN;
 
4986
}
 
4987
#endif /* EMBEDDED_LIBRARY */
 
4988
 
 
4989
 
 
4990
#ifdef SIGNALS_DONT_BREAK_READ
 
4991
inline void kill_broken_server()
 
4992
{
 
4993
  /* hack to get around signals ignored in syscalls for problem OS's */
 
4994
  if (
 
4995
#if !defined(__NETWARE__)
 
4996
      unix_sock == INVALID_SOCKET ||
 
4997
#endif
 
4998
      (!opt_disable_networking && ip_sock == INVALID_SOCKET))
 
4999
  {
 
5000
    select_thread_in_use = 0;
 
5001
    /* The following call will never return */
 
5002
    kill_server(IF_NETWARE(MYSQL_KILL_SIGNAL, (void*) MYSQL_KILL_SIGNAL));
 
5003
  }
 
5004
}
 
5005
#define MAYBE_BROKEN_SYSCALL kill_broken_server();
 
5006
#else
 
5007
#define MAYBE_BROKEN_SYSCALL
 
5008
#endif
 
5009
 
 
5010
        /* Handle new connections and spawn new process to handle them */
 
5011
 
 
5012
#ifndef EMBEDDED_LIBRARY
 
5013
pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused)))
 
5014
{
 
5015
  my_socket sock,new_sock;
 
5016
  uint error_count=0;
 
5017
  uint max_used_connection= (uint) (max(ip_sock,unix_sock)+1);
 
5018
  fd_set readFDs,clientFDs;
 
5019
  THD *thd;
 
5020
  struct sockaddr_in cAddr;
 
5021
  int ip_flags=0,socket_flags=0,flags;
 
5022
  st_vio *vio_tmp;
 
5023
  DBUG_ENTER("handle_connections_sockets");
 
5024
 
 
5025
  LINT_INIT(new_sock);
 
5026
 
 
5027
  (void) my_pthread_getprio(pthread_self());            // For debugging
 
5028
 
 
5029
  FD_ZERO(&clientFDs);
 
5030
  if (ip_sock != INVALID_SOCKET)
 
5031
  {
 
5032
    FD_SET(ip_sock,&clientFDs);
 
5033
#ifdef HAVE_FCNTL
 
5034
    ip_flags = fcntl(ip_sock, F_GETFL, 0);
 
5035
#endif
 
5036
  }
 
5037
#ifdef HAVE_SYS_UN_H
 
5038
  FD_SET(unix_sock,&clientFDs);
 
5039
#ifdef HAVE_FCNTL
 
5040
  socket_flags=fcntl(unix_sock, F_GETFL, 0);
 
5041
#endif
 
5042
#endif
 
5043
 
 
5044
  DBUG_PRINT("general",("Waiting for connections."));
 
5045
  MAYBE_BROKEN_SYSCALL;
 
5046
  while (!abort_loop)
 
5047
  {
 
5048
    readFDs=clientFDs;
 
5049
#ifdef HPUX10
 
5050
    if (select(max_used_connection,(int*) &readFDs,0,0,0) < 0)
 
5051
      continue;
 
5052
#else
 
5053
    if (select((int) max_used_connection,&readFDs,0,0,0) < 0)
 
5054
    {
 
5055
      if (socket_errno != SOCKET_EINTR)
 
5056
      {
 
5057
        if (!select_errors++ && !abort_loop)    /* purecov: inspected */
 
5058
          sql_print_error("mysqld: Got error %d from select",socket_errno); /* purecov: inspected */
 
5059
      }
 
5060
      MAYBE_BROKEN_SYSCALL
 
5061
      continue;
 
5062
    }
 
5063
#endif  /* HPUX10 */
 
5064
    if (abort_loop)
 
5065
    {
 
5066
      MAYBE_BROKEN_SYSCALL;
 
5067
      break;
 
5068
    }
 
5069
 
 
5070
    /* Is this a new connection request ? */
 
5071
#ifdef HAVE_SYS_UN_H
 
5072
    if (FD_ISSET(unix_sock,&readFDs))
 
5073
    {
 
5074
      sock = unix_sock;
 
5075
      flags= socket_flags;
 
5076
    }
 
5077
    else
 
5078
#endif
 
5079
    {
 
5080
      sock = ip_sock;
 
5081
      flags= ip_flags;
 
5082
    }
 
5083
 
 
5084
#if !defined(NO_FCNTL_NONBLOCK)
 
5085
    if (!(test_flags & TEST_BLOCKING))
 
5086
    {
 
5087
#if defined(O_NONBLOCK)
 
5088
      fcntl(sock, F_SETFL, flags | O_NONBLOCK);
 
5089
#elif defined(O_NDELAY)
 
5090
      fcntl(sock, F_SETFL, flags | O_NDELAY);
 
5091
#endif
 
5092
    }
 
5093
#endif /* NO_FCNTL_NONBLOCK */
 
5094
    for (uint retry=0; retry < MAX_ACCEPT_RETRY; retry++)
 
5095
    {
 
5096
      size_socket length=sizeof(struct sockaddr_in);
 
5097
      new_sock = accept(sock, my_reinterpret_cast(struct sockaddr *) (&cAddr),
 
5098
                        &length);
 
5099
#ifdef __NETWARE__ 
 
5100
      // TODO: temporary fix, waiting for TCP/IP fix - DEFECT000303149
 
5101
      if ((new_sock == INVALID_SOCKET) && (socket_errno == EINVAL))
 
5102
      {
 
5103
        kill_server(SIGTERM);
 
5104
      }
 
5105
#endif
 
5106
      if (new_sock != INVALID_SOCKET ||
 
5107
          (socket_errno != SOCKET_EINTR && socket_errno != SOCKET_EAGAIN))
 
5108
        break;
 
5109
      MAYBE_BROKEN_SYSCALL;
 
5110
#if !defined(NO_FCNTL_NONBLOCK)
 
5111
      if (!(test_flags & TEST_BLOCKING))
 
5112
      {
 
5113
        if (retry == MAX_ACCEPT_RETRY - 1)
 
5114
          fcntl(sock, F_SETFL, flags);          // Try without O_NONBLOCK
 
5115
      }
 
5116
#endif
 
5117
    }
 
5118
#if !defined(NO_FCNTL_NONBLOCK)
 
5119
    if (!(test_flags & TEST_BLOCKING))
 
5120
      fcntl(sock, F_SETFL, flags);
 
5121
#endif
 
5122
    if (new_sock == INVALID_SOCKET)
 
5123
    {
 
5124
      if ((error_count++ & 255) == 0)           // This can happen often
 
5125
        sql_perror("Error in accept");
 
5126
      MAYBE_BROKEN_SYSCALL;
 
5127
      if (socket_errno == SOCKET_ENFILE || socket_errno == SOCKET_EMFILE)
 
5128
        sleep(1);                               // Give other threads some time
 
5129
      continue;
 
5130
    }
 
5131
 
 
5132
#ifdef HAVE_LIBWRAP
 
5133
    {
 
5134
      if (sock == ip_sock)
 
5135
      {
 
5136
        struct request_info req;
 
5137
        signal(SIGCHLD, SIG_DFL);
 
5138
        request_init(&req, RQ_DAEMON, libwrapName, RQ_FILE, new_sock, NULL);
 
5139
        my_fromhost(&req);
 
5140
        if (!my_hosts_access(&req))
 
5141
        {
 
5142
          /*
 
5143
            This may be stupid but refuse() includes an exit(0)
 
5144
            which we surely don't want...
 
5145
            clean_exit() - same stupid thing ...
 
5146
          */
 
5147
          syslog(deny_severity, "refused connect from %s",
 
5148
                 my_eval_client(&req));
 
5149
 
 
5150
          /*
 
5151
            C++ sucks (the gibberish in front just translates the supplied
 
5152
            sink function pointer in the req structure from a void (*sink)();
 
5153
            to a void(*sink)(int) if you omit the cast, the C++ compiler
 
5154
            will cry...
 
5155
          */
 
5156
          if (req.sink)
 
5157
            ((void (*)(int))req.sink)(req.fd);
 
5158
 
 
5159
          (void) shutdown(new_sock, SHUT_RDWR);
 
5160
          (void) closesocket(new_sock);
 
5161
          continue;
 
5162
        }
 
5163
      }
 
5164
    }
 
5165
#endif /* HAVE_LIBWRAP */
 
5166
 
 
5167
    {
 
5168
      size_socket dummyLen;
 
5169
      struct sockaddr dummy;
 
5170
      dummyLen = sizeof(struct sockaddr);
 
5171
      if (getsockname(new_sock,&dummy, &dummyLen) < 0)
 
5172
      {
 
5173
        sql_perror("Error on new connection socket");
 
5174
        (void) shutdown(new_sock, SHUT_RDWR);
 
5175
        (void) closesocket(new_sock);
 
5176
        continue;
 
5177
      }
 
5178
    }
 
5179
 
 
5180
    /*
 
5181
    ** Don't allow too many connections
 
5182
    */
 
5183
 
 
5184
    if (!(thd= new THD))
 
5185
    {
 
5186
      (void) shutdown(new_sock, SHUT_RDWR);
 
5187
      VOID(closesocket(new_sock));
 
5188
      continue;
 
5189
    }
 
5190
    if (!(vio_tmp=vio_new(new_sock,
 
5191
                          sock == unix_sock ? VIO_TYPE_SOCKET :
 
5192
                          VIO_TYPE_TCPIP,
 
5193
                          sock == unix_sock ? VIO_LOCALHOST: 0)) ||
 
5194
        my_net_init(&thd->net,vio_tmp))
 
5195
    {
 
5196
      /*
 
5197
        Only delete the temporary vio if we didn't already attach it to the
 
5198
        NET object. The destructor in THD will delete any initialized net
 
5199
        structure.
 
5200
      */
 
5201
      if (vio_tmp && thd->net.vio != vio_tmp)
 
5202
        vio_delete(vio_tmp);
 
5203
      else
 
5204
      {
 
5205
        (void) shutdown(new_sock, SHUT_RDWR);
 
5206
        (void) closesocket(new_sock);
 
5207
      }
 
5208
      delete thd;
 
5209
      continue;
 
5210
    }
 
5211
    if (sock == unix_sock)
 
5212
      thd->security_ctx->host=(char*) my_localhost;
 
5213
 
 
5214
    create_new_thread(thd);
 
5215
  }
 
5216
  DBUG_LEAVE;
 
5217
  decrement_handler_count();
 
5218
  return 0;
 
5219
}
 
5220
 
 
5221
 
 
5222
#ifdef __NT__
 
5223
pthread_handler_t handle_connections_namedpipes(void *arg)
 
5224
{
 
5225
  HANDLE hConnectedPipe;
 
5226
  OVERLAPPED connectOverlapped= {0};
 
5227
  THD *thd;
 
5228
  my_thread_init();
 
5229
  DBUG_ENTER("handle_connections_namedpipes");
 
5230
  connectOverlapped.hEvent= CreateEvent(NULL, TRUE, FALSE, NULL);
 
5231
  if (!connectOverlapped.hEvent)
 
5232
  {
 
5233
    sql_print_error("Can't create event, last error=%u", GetLastError());
 
5234
    unireg_abort(1);
 
5235
  }
 
5236
  DBUG_PRINT("general",("Waiting for named pipe connections."));
 
5237
  while (!abort_loop)
 
5238
  {
 
5239
    /* wait for named pipe connection */
 
5240
    BOOL fConnected= ConnectNamedPipe(hPipe, &connectOverlapped);
 
5241
    if (!fConnected && (GetLastError() == ERROR_IO_PENDING))
 
5242
    {
 
5243
        /*
 
5244
          ERROR_IO_PENDING says async IO has started but not yet finished.
 
5245
          GetOverlappedResult will wait for completion.
 
5246
        */
 
5247
        DWORD bytes;
 
5248
        fConnected= GetOverlappedResult(hPipe, &connectOverlapped,&bytes, TRUE);
 
5249
    }
 
5250
    if (abort_loop)
 
5251
      break;
 
5252
    if (!fConnected)
 
5253
      fConnected = GetLastError() == ERROR_PIPE_CONNECTED;
 
5254
    if (!fConnected)
 
5255
    {
 
5256
      CloseHandle(hPipe);
 
5257
      if ((hPipe= CreateNamedPipe(pipe_name,
 
5258
                                  PIPE_ACCESS_DUPLEX |
 
5259
                                  FILE_FLAG_OVERLAPPED,
 
5260
                                  PIPE_TYPE_BYTE |
 
5261
                                  PIPE_READMODE_BYTE |
 
5262
                                  PIPE_WAIT,
 
5263
                                  PIPE_UNLIMITED_INSTANCES,
 
5264
                                  (int) global_system_variables.
 
5265
                                  net_buffer_length,
 
5266
                                  (int) global_system_variables.
 
5267
                                  net_buffer_length,
 
5268
                                  NMPWAIT_USE_DEFAULT_WAIT,
 
5269
                                  &saPipeSecurity)) ==
 
5270
          INVALID_HANDLE_VALUE)
 
5271
      {
 
5272
        sql_perror("Can't create new named pipe!");
 
5273
        break;                                  // Abort
 
5274
      }
 
5275
    }
 
5276
    hConnectedPipe = hPipe;
 
5277
    /* create new pipe for new connection */
 
5278
    if ((hPipe = CreateNamedPipe(pipe_name,
 
5279
                 PIPE_ACCESS_DUPLEX |
 
5280
                 FILE_FLAG_OVERLAPPED,
 
5281
                                 PIPE_TYPE_BYTE |
 
5282
                                 PIPE_READMODE_BYTE |
 
5283
                                 PIPE_WAIT,
 
5284
                                 PIPE_UNLIMITED_INSTANCES,
 
5285
                                 (int) global_system_variables.net_buffer_length,
 
5286
                                 (int) global_system_variables.net_buffer_length,
 
5287
                                 NMPWAIT_USE_DEFAULT_WAIT,
 
5288
                                 &saPipeSecurity)) ==
 
5289
        INVALID_HANDLE_VALUE)
 
5290
    {
 
5291
      sql_perror("Can't create new named pipe!");
 
5292
      hPipe=hConnectedPipe;
 
5293
      continue;                                 // We have to try again
 
5294
    }
 
5295
 
 
5296
    if (!(thd = new THD))
 
5297
    {
 
5298
      DisconnectNamedPipe(hConnectedPipe);
 
5299
      CloseHandle(hConnectedPipe);
 
5300
      continue;
 
5301
    }
 
5302
    if (!(thd->net.vio= vio_new_win32pipe(hConnectedPipe)) ||
 
5303
        my_net_init(&thd->net, thd->net.vio))
 
5304
    {
 
5305
      close_connection(thd, ER_OUT_OF_RESOURCES, 1);
 
5306
      delete thd;
 
5307
      continue;
 
5308
    }
 
5309
    /* Host is unknown */
 
5310
    thd->security_ctx->host= my_strdup(my_localhost, MYF(0));
 
5311
    create_new_thread(thd);
 
5312
  }
 
5313
  CloseHandle(connectOverlapped.hEvent);
 
5314
  DBUG_LEAVE;
 
5315
  decrement_handler_count();
 
5316
  return 0;
 
5317
}
 
5318
#endif /* __NT__ */
 
5319
 
 
5320
 
 
5321
#ifdef HAVE_SMEM
 
5322
 
 
5323
/**
 
5324
  Thread of shared memory's service.
 
5325
 
 
5326
  @param arg                              Arguments of thread
 
5327
*/
 
5328
pthread_handler_t handle_connections_shared_memory(void *arg)
 
5329
{
 
5330
  /* file-mapping object, use for create shared memory */
 
5331
  HANDLE handle_connect_file_map= 0;
 
5332
  char  *handle_connect_map= 0;                 // pointer on shared memory
 
5333
  HANDLE event_connect_answer= 0;
 
5334
  ulong smem_buffer_length= shared_memory_buffer_length + 4;
 
5335
  ulong connect_number= 1;
 
5336
  char *tmp= NULL;
 
5337
  char *suffix_pos;
 
5338
  char connect_number_char[22], *p;
 
5339
  const char *errmsg= 0;
 
5340
  SECURITY_ATTRIBUTES *sa_event= 0, *sa_mapping= 0;
 
5341
  my_thread_init();
 
5342
  DBUG_ENTER("handle_connections_shared_memorys");
 
5343
  DBUG_PRINT("general",("Waiting for allocated shared memory."));
 
5344
 
 
5345
  /*
 
5346
     get enough space base-name + '_' + longest suffix we might ever send
 
5347
   */
 
5348
  if (!(tmp= (char *)my_malloc(strlen(shared_memory_base_name) + 32L, MYF(MY_FAE))))
 
5349
    goto error;
 
5350
 
 
5351
  if (my_security_attr_create(&sa_event, &errmsg,
 
5352
                              GENERIC_ALL, SYNCHRONIZE | EVENT_MODIFY_STATE))
 
5353
    goto error;
 
5354
 
 
5355
  if (my_security_attr_create(&sa_mapping, &errmsg,
 
5356
                             GENERIC_ALL, FILE_MAP_READ | FILE_MAP_WRITE))
 
5357
    goto error;
 
5358
 
 
5359
  /*
 
5360
    The name of event and file-mapping events create agree next rule:
 
5361
      shared_memory_base_name+unique_part
 
5362
    Where:
 
5363
      shared_memory_base_name is unique value for each server
 
5364
      unique_part is unique value for each object (events and file-mapping)
 
5365
  */
 
5366
  suffix_pos= strxmov(tmp,shared_memory_base_name,"_",NullS);
 
5367
  strmov(suffix_pos, "CONNECT_REQUEST");
 
5368
  if ((smem_event_connect_request= CreateEvent(sa_event,
 
5369
                                               FALSE, FALSE, tmp)) == 0)
 
5370
  {
 
5371
    errmsg= "Could not create request event";
 
5372
    goto error;
 
5373
  }
 
5374
  strmov(suffix_pos, "CONNECT_ANSWER");
 
5375
  if ((event_connect_answer= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
 
5376
  {
 
5377
    errmsg="Could not create answer event";
 
5378
    goto error;
 
5379
  }
 
5380
  strmov(suffix_pos, "CONNECT_DATA");
 
5381
  if ((handle_connect_file_map=
 
5382
       CreateFileMapping(INVALID_HANDLE_VALUE, sa_mapping,
 
5383
                         PAGE_READWRITE, 0, sizeof(connect_number), tmp)) == 0)
 
5384
  {
 
5385
    errmsg= "Could not create file mapping";
 
5386
    goto error;
 
5387
  }
 
5388
  if ((handle_connect_map= (char *)MapViewOfFile(handle_connect_file_map,
 
5389
                                                  FILE_MAP_WRITE,0,0,
 
5390
                                                  sizeof(DWORD))) == 0)
 
5391
  {
 
5392
    errmsg= "Could not create shared memory service";
 
5393
    goto error;
 
5394
  }
 
5395
 
 
5396
  while (!abort_loop)
 
5397
  {
 
5398
    /* Wait a request from client */
 
5399
    WaitForSingleObject(smem_event_connect_request,INFINITE);
 
5400
 
 
5401
    /*
 
5402
       it can be after shutdown command
 
5403
    */
 
5404
    if (abort_loop)
 
5405
      goto error;
 
5406
 
 
5407
    HANDLE handle_client_file_map= 0;
 
5408
    char  *handle_client_map= 0;
 
5409
    HANDLE event_client_wrote= 0;
 
5410
    HANDLE event_client_read= 0;    // for transfer data server <-> client
 
5411
    HANDLE event_server_wrote= 0;
 
5412
    HANDLE event_server_read= 0;
 
5413
    HANDLE event_conn_closed= 0;
 
5414
    THD *thd= 0;
 
5415
 
 
5416
    p= int10_to_str(connect_number, connect_number_char, 10);
 
5417
    /*
 
5418
      The name of event and file-mapping events create agree next rule:
 
5419
        shared_memory_base_name+unique_part+number_of_connection
 
5420
        Where:
 
5421
          shared_memory_base_name is uniquel value for each server
 
5422
          unique_part is unique value for each object (events and file-mapping)
 
5423
          number_of_connection is connection-number between server and client
 
5424
    */
 
5425
    suffix_pos= strxmov(tmp,shared_memory_base_name,"_",connect_number_char,
 
5426
                         "_",NullS);
 
5427
    strmov(suffix_pos, "DATA");
 
5428
    if ((handle_client_file_map=
 
5429
         CreateFileMapping(INVALID_HANDLE_VALUE, sa_mapping,
 
5430
                           PAGE_READWRITE, 0, smem_buffer_length, tmp)) == 0)
 
5431
    {
 
5432
      errmsg= "Could not create file mapping";
 
5433
      goto errorconn;
 
5434
    }
 
5435
    if ((handle_client_map= (char*)MapViewOfFile(handle_client_file_map,
 
5436
                                                  FILE_MAP_WRITE,0,0,
 
5437
                                                  smem_buffer_length)) == 0)
 
5438
    {
 
5439
      errmsg= "Could not create memory map";
 
5440
      goto errorconn;
 
5441
    }
 
5442
    strmov(suffix_pos, "CLIENT_WROTE");
 
5443
    if ((event_client_wrote= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
 
5444
    {
 
5445
      errmsg= "Could not create client write event";
 
5446
      goto errorconn;
 
5447
    }
 
5448
    strmov(suffix_pos, "CLIENT_READ");
 
5449
    if ((event_client_read= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
 
5450
    {
 
5451
      errmsg= "Could not create client read event";
 
5452
      goto errorconn;
 
5453
    }
 
5454
    strmov(suffix_pos, "SERVER_READ");
 
5455
    if ((event_server_read= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
 
5456
    {
 
5457
      errmsg= "Could not create server read event";
 
5458
      goto errorconn;
 
5459
    }
 
5460
    strmov(suffix_pos, "SERVER_WROTE");
 
5461
    if ((event_server_wrote= CreateEvent(sa_event,
 
5462
                                         FALSE, FALSE, tmp)) == 0)
 
5463
    {
 
5464
      errmsg= "Could not create server write event";
 
5465
      goto errorconn;
 
5466
    }
 
5467
    strmov(suffix_pos, "CONNECTION_CLOSED");
 
5468
    if ((event_conn_closed= CreateEvent(sa_event,
 
5469
                                        TRUE, FALSE, tmp)) == 0)
 
5470
    {
 
5471
      errmsg= "Could not create closed connection event";
 
5472
      goto errorconn;
 
5473
    }
 
5474
    if (abort_loop)
 
5475
      goto errorconn;
 
5476
    if (!(thd= new THD))
 
5477
      goto errorconn;
 
5478
    /* Send number of connection to client */
 
5479
    int4store(handle_connect_map, connect_number);
 
5480
    if (!SetEvent(event_connect_answer))
 
5481
    {
 
5482
      errmsg= "Could not send answer event";
 
5483
      goto errorconn;
 
5484
    }
 
5485
    /* Set event that client should receive data */
 
5486
    if (!SetEvent(event_client_read))
 
5487
    {
 
5488
      errmsg= "Could not set client to read mode";
 
5489
      goto errorconn;
 
5490
    }
 
5491
    if (!(thd->net.vio= vio_new_win32shared_memory(handle_client_file_map,
 
5492
                                                   handle_client_map,
 
5493
                                                   event_client_wrote,
 
5494
                                                   event_client_read,
 
5495
                                                   event_server_wrote,
 
5496
                                                   event_server_read,
 
5497
                                                   event_conn_closed)) ||
 
5498
                        my_net_init(&thd->net, thd->net.vio))
 
5499
    {
 
5500
      close_connection(thd, ER_OUT_OF_RESOURCES, 1);
 
5501
      errmsg= 0;
 
5502
      goto errorconn;
 
5503
    }
 
5504
    thd->security_ctx->host= my_strdup(my_localhost, MYF(0)); /* Host is unknown */
 
5505
    create_new_thread(thd);
 
5506
    connect_number++;
 
5507
    continue;
 
5508
 
 
5509
errorconn:
 
5510
    /* Could not form connection;  Free used handlers/memort and retry */
 
5511
    if (errmsg)
 
5512
    {
 
5513
      char buff[180];
 
5514
      strxmov(buff, "Can't create shared memory connection: ", errmsg, ".",
 
5515
              NullS);
 
5516
      sql_perror(buff);
 
5517
    }
 
5518
    if (handle_client_file_map) 
 
5519
      CloseHandle(handle_client_file_map);
 
5520
    if (handle_client_map)
 
5521
      UnmapViewOfFile(handle_client_map);
 
5522
    if (event_server_wrote)
 
5523
      CloseHandle(event_server_wrote);
 
5524
    if (event_server_read)
 
5525
      CloseHandle(event_server_read);
 
5526
    if (event_client_wrote)
 
5527
      CloseHandle(event_client_wrote);
 
5528
    if (event_client_read)
 
5529
      CloseHandle(event_client_read);
 
5530
    if (event_conn_closed)
 
5531
      CloseHandle(event_conn_closed);
 
5532
    delete thd;
 
5533
  }
 
5534
 
 
5535
  /* End shared memory handling */
 
5536
error:
 
5537
  if (tmp)
 
5538
    my_free(tmp, MYF(0));
 
5539
 
 
5540
  if (errmsg)
 
5541
  {
 
5542
    char buff[180];
 
5543
    strxmov(buff, "Can't create shared memory service: ", errmsg, ".", NullS);
 
5544
    sql_perror(buff);
 
5545
  }
 
5546
  my_security_attr_free(sa_event);
 
5547
  my_security_attr_free(sa_mapping);
 
5548
  if (handle_connect_map)       UnmapViewOfFile(handle_connect_map);
 
5549
  if (handle_connect_file_map)  CloseHandle(handle_connect_file_map);
 
5550
  if (event_connect_answer)     CloseHandle(event_connect_answer);
 
5551
  if (smem_event_connect_request) CloseHandle(smem_event_connect_request);
 
5552
  DBUG_LEAVE;
 
5553
  decrement_handler_count();
 
5554
  return 0;
 
5555
}
 
5556
#endif /* HAVE_SMEM */
 
5557
#endif /* EMBEDDED_LIBRARY */
 
5558
 
 
5559
 
 
5560
/****************************************************************************
 
5561
  Handle start options
 
5562
******************************************************************************/
 
5563
 
 
5564
enum options_mysqld
 
5565
{
 
5566
  OPT_ISAM_LOG=256,            OPT_SKIP_NEW, 
 
5567
  OPT_SKIP_GRANT,              OPT_SKIP_LOCK, 
 
5568
  OPT_ENABLE_LOCK,             OPT_USE_LOCKING,
 
5569
  OPT_SOCKET,                  OPT_UPDATE_LOG,
 
5570
  OPT_BIN_LOG,                 OPT_SKIP_RESOLVE,
 
5571
  OPT_SKIP_NETWORKING,         OPT_BIN_LOG_INDEX,
 
5572
  OPT_BIND_ADDRESS,            OPT_PID_FILE,
 
5573
  OPT_SKIP_PRIOR,              OPT_BIG_TABLES,
 
5574
  OPT_STANDALONE,              OPT_ONE_THREAD,
 
5575
  OPT_CONSOLE,                 OPT_LOW_PRIORITY_UPDATES,
 
5576
  OPT_SKIP_HOST_CACHE,         OPT_SHORT_LOG_FORMAT,
 
5577
  OPT_FLUSH,                   OPT_SAFE,
 
5578
  OPT_BOOTSTRAP,               OPT_SKIP_SHOW_DB,
 
5579
  OPT_STORAGE_ENGINE,          OPT_INIT_FILE,
 
5580
  OPT_DELAY_KEY_WRITE_ALL,     OPT_SLOW_QUERY_LOG,
 
5581
  OPT_DELAY_KEY_WRITE,         OPT_CHARSETS_DIR,
 
5582
  OPT_MASTER_HOST,             OPT_MASTER_USER,
 
5583
  OPT_MASTER_PASSWORD,         OPT_MASTER_PORT,
 
5584
  OPT_MASTER_INFO_FILE,        OPT_MASTER_CONNECT_RETRY,
 
5585
  OPT_MASTER_RETRY_COUNT,      OPT_LOG_TC, OPT_LOG_TC_SIZE,
 
5586
  OPT_MASTER_SSL,              OPT_MASTER_SSL_KEY,
 
5587
  OPT_MASTER_SSL_CERT,         OPT_MASTER_SSL_CAPATH,
 
5588
  OPT_MASTER_SSL_CIPHER,       OPT_MASTER_SSL_CA,
 
5589
  OPT_SQL_BIN_UPDATE_SAME,     OPT_REPLICATE_DO_DB,
 
5590
  OPT_REPLICATE_IGNORE_DB,     OPT_LOG_SLAVE_UPDATES,
 
5591
  OPT_BINLOG_DO_DB,            OPT_BINLOG_IGNORE_DB,
 
5592
  OPT_BINLOG_FORMAT,
 
5593
#ifndef DBUG_OFF
 
5594
  OPT_BINLOG_SHOW_XID,
 
5595
#endif
 
5596
  OPT_BINLOG_ROWS_EVENT_MAX_SIZE, 
 
5597
  OPT_WANT_CORE,               OPT_CONCURRENT_INSERT,
 
5598
  OPT_MEMLOCK,                 OPT_MYISAM_RECOVER,
 
5599
  OPT_REPLICATE_REWRITE_DB,    OPT_SERVER_ID,
 
5600
  OPT_SKIP_SLAVE_START,        OPT_SAFE_SHOW_DB, 
 
5601
  OPT_SAFEMALLOC_MEM_LIMIT,    OPT_REPLICATE_DO_TABLE,
 
5602
  OPT_REPLICATE_IGNORE_TABLE,  OPT_REPLICATE_WILD_DO_TABLE,
 
5603
  OPT_REPLICATE_WILD_IGNORE_TABLE, OPT_REPLICATE_SAME_SERVER_ID,
 
5604
  OPT_DISCONNECT_SLAVE_EVENT_COUNT, OPT_TC_HEURISTIC_RECOVER,
 
5605
  OPT_ABORT_SLAVE_EVENT_COUNT,
 
5606
  OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
 
5607
  OPT_LOG_BIN_TRUST_FUNCTION_CREATORS_OLD,
 
5608
  OPT_ENGINE_CONDITION_PUSHDOWN, OPT_NDB_CONNECTSTRING, 
 
5609
  OPT_NDB_USE_EXACT_COUNT, OPT_NDB_USE_TRANSACTIONS,
 
5610
  OPT_NDB_FORCE_SEND, OPT_NDB_AUTOINCREMENT_PREFETCH_SZ,
 
5611
  OPT_NDB_SHM, OPT_NDB_OPTIMIZED_NODE_SELECTION, OPT_NDB_CACHE_CHECK_TIME,
 
5612
  OPT_NDB_MGMD, OPT_NDB_NODEID,
 
5613
  OPT_NDB_DISTRIBUTION,
 
5614
  OPT_NDB_INDEX_STAT_ENABLE,
 
5615
  OPT_NDB_EXTRA_LOGGING,
 
5616
  OPT_NDB_REPORT_THRESH_BINLOG_EPOCH_SLIP,
 
5617
  OPT_NDB_REPORT_THRESH_BINLOG_MEM_USAGE,
 
5618
  OPT_NDB_USE_COPYING_ALTER_TABLE,
 
5619
  OPT_SKIP_SAFEMALLOC,
 
5620
  OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE,
 
5621
  OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
 
5622
  OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL,
 
5623
  OPT_SAFE_USER_CREATE, OPT_SQL_MODE,
 
5624
  OPT_HAVE_NAMED_PIPE,
 
5625
  OPT_DO_PSTACK, OPT_EVENT_SCHEDULER, OPT_REPORT_HOST,
 
5626
  OPT_REPORT_USER, OPT_REPORT_PASSWORD, OPT_REPORT_PORT,
 
5627
  OPT_SHOW_SLAVE_AUTH_INFO,
 
5628
  OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE,
 
5629
  OPT_RPL_RECOVERY_RANK,OPT_INIT_RPL_ROLE,
 
5630
  OPT_RELAY_LOG, OPT_RELAY_LOG_INDEX, OPT_RELAY_LOG_INFO_FILE,
 
5631
  OPT_SLAVE_SKIP_ERRORS, OPT_DES_KEY_FILE, OPT_LOCAL_INFILE,
 
5632
  OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA,
 
5633
  OPT_SSL_CAPATH, OPT_SSL_CIPHER,
 
5634
  OPT_BACK_LOG, OPT_BINLOG_CACHE_SIZE,
 
5635
  OPT_CONNECT_TIMEOUT, OPT_DELAYED_INSERT_TIMEOUT,
 
5636
  OPT_DELAYED_INSERT_LIMIT, OPT_DELAYED_QUEUE_SIZE,
 
5637
  OPT_FLUSH_TIME, OPT_FT_MIN_WORD_LEN, OPT_FT_BOOLEAN_SYNTAX,
 
5638
  OPT_FT_MAX_WORD_LEN, OPT_FT_QUERY_EXPANSION_LIMIT, OPT_FT_STOPWORD_FILE,
 
5639
  OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE,
 
5640
  OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_BLOCK_SIZE,
 
5641
  OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_AGE_THRESHOLD,
 
5642
  OPT_LONG_QUERY_TIME,
 
5643
  OPT_LOWER_CASE_TABLE_NAMES, OPT_MAX_ALLOWED_PACKET,
 
5644
  OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE,
 
5645
  OPT_MAX_CONNECTIONS, OPT_MAX_CONNECT_ERRORS,
 
5646
  OPT_MAX_DELAYED_THREADS, OPT_MAX_HEP_TABLE_SIZE,
 
5647
  OPT_MAX_JOIN_SIZE, OPT_MAX_PREPARED_STMT_COUNT,
 
5648
  OPT_MAX_RELAY_LOG_SIZE, OPT_MAX_SORT_LENGTH,
 
5649
  OPT_MAX_SEEKS_FOR_KEY, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS,
 
5650
  OPT_MAX_LENGTH_FOR_SORT_DATA,
 
5651
  OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE,
 
5652
  OPT_MAX_ERROR_COUNT, OPT_MULTI_RANGE_COUNT, OPT_MYISAM_DATA_POINTER_SIZE,
 
5653
  OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
 
5654
  OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
 
5655
  OPT_MYISAM_USE_MMAP, OPT_MYISAM_REPAIR_THREADS,
 
5656
  OPT_MYISAM_MMAP_SIZE,
 
5657
  OPT_MYISAM_STATS_METHOD,
 
5658
  OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT,
 
5659
  OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT,
 
5660
  OPT_OPEN_FILES_LIMIT,
 
5661
  OPT_PRELOAD_BUFFER_SIZE,
 
5662
  OPT_QUERY_CACHE_LIMIT, OPT_QUERY_CACHE_MIN_RES_UNIT, OPT_QUERY_CACHE_SIZE,
 
5663
  OPT_QUERY_CACHE_TYPE, OPT_QUERY_CACHE_WLOCK_INVALIDATE, OPT_RECORD_BUFFER,
 
5664
  OPT_RECORD_RND_BUFFER, OPT_DIV_PRECINCREMENT, OPT_RELAY_LOG_SPACE_LIMIT,
 
5665
  OPT_RELAY_LOG_PURGE,
 
5666
  OPT_SLAVE_NET_TIMEOUT, OPT_SLAVE_COMPRESSED_PROTOCOL, OPT_SLOW_LAUNCH_TIME,
 
5667
  OPT_SLAVE_TRANS_RETRIES, OPT_READONLY, OPT_DEBUGGING,
 
5668
  OPT_SORT_BUFFER, OPT_TABLE_OPEN_CACHE, OPT_TABLE_DEF_CACHE,
 
5669
  OPT_THREAD_CONCURRENCY, OPT_THREAD_CACHE_SIZE,
 
5670
  OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK,
 
5671
  OPT_WAIT_TIMEOUT,
 
5672
  OPT_ERROR_LOG_FILE,
 
5673
  OPT_DEFAULT_WEEK_FORMAT,
 
5674
  OPT_RANGE_ALLOC_BLOCK_SIZE, OPT_ALLOW_SUSPICIOUS_UDFS,
 
5675
  OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE,
 
5676
  OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE,
 
5677
  OPT_SYNC_FRM, OPT_SYNC_BINLOG,
 
5678
  OPT_SYNC_REPLICATION,
 
5679
  OPT_SYNC_REPLICATION_SLAVE_ID,
 
5680
  OPT_SYNC_REPLICATION_TIMEOUT,
 
5681
  OPT_ENABLE_SHARED_MEMORY,
 
5682
  OPT_SHARED_MEMORY_BASE_NAME,
 
5683
  OPT_OLD_PASSWORDS,
 
5684
  OPT_OLD_ALTER_TABLE,
 
5685
  OPT_EXPIRE_LOGS_DAYS,
 
5686
  OPT_GROUP_CONCAT_MAX_LEN,
 
5687
  OPT_DEFAULT_COLLATION,
 
5688
  OPT_DEFAULT_COLLATION_OLD,
 
5689
  OPT_CHARACTER_SET_CLIENT_HANDSHAKE,
 
5690
  OPT_CHARACTER_SET_FILESYSTEM,
 
5691
  OPT_LC_TIME_NAMES,
 
5692
  OPT_INIT_CONNECT,
 
5693
  OPT_INIT_SLAVE,
 
5694
  OPT_SECURE_AUTH,
 
5695
  OPT_DATE_FORMAT,
 
5696
  OPT_TIME_FORMAT,
 
5697
  OPT_DATETIME_FORMAT,
 
5698
  OPT_LOG_QUERIES_NOT_USING_INDEXES,
 
5699
  OPT_DEFAULT_TIME_ZONE,
 
5700
  OPT_SYSDATE_IS_NOW,
 
5701
  OPT_OPTIMIZER_SEARCH_DEPTH,
 
5702
  OPT_OPTIMIZER_PRUNE_LEVEL,
 
5703
  OPT_OPTIMIZER_SWITCH,
 
5704
  OPT_UPDATABLE_VIEWS_WITH_LIMIT,
 
5705
  OPT_SP_AUTOMATIC_PRIVILEGES,
 
5706
  OPT_MAX_SP_RECURSION_DEPTH,
 
5707
  OPT_AUTO_INCREMENT, OPT_AUTO_INCREMENT_OFFSET,
 
5708
  OPT_ENABLE_LARGE_PAGES,
 
5709
  OPT_TIMED_MUTEXES,
 
5710
  OPT_OLD_STYLE_USER_LIMITS,
 
5711
  OPT_LOG_SLOW_ADMIN_STATEMENTS,
 
5712
  OPT_TABLE_LOCK_WAIT_TIMEOUT,
 
5713
  OPT_PLUGIN_LOAD,
 
5714
  OPT_PLUGIN_DIR,
 
5715
  OPT_SYMBOLIC_LINKS,
 
5716
  OPT_WARNINGS,
 
5717
  OPT_RECORD_BUFFER_OLD,
 
5718
  OPT_LOG_OUTPUT,
 
5719
  OPT_PORT_OPEN_TIMEOUT,
 
5720
  OPT_PROFILING,
 
5721
  OPT_KEEP_FILES_ON_CREATE,
 
5722
  OPT_GENERAL_LOG,
 
5723
  OPT_SLOW_LOG,
 
5724
  OPT_THREAD_HANDLING,
 
5725
  OPT_INNODB_ROLLBACK_ON_TIMEOUT,
 
5726
  OPT_SECURE_FILE_PRIV,
 
5727
  OPT_MIN_EXAMINED_ROW_LIMIT,
 
5728
  OPT_LOG_SLOW_SLAVE_STATEMENTS,
 
5729
#if defined(ENABLED_DEBUG_SYNC)
 
5730
  OPT_DEBUG_SYNC_TIMEOUT,
 
5731
#endif /* defined(ENABLED_DEBUG_SYNC) */
 
5732
  OPT_OLD_MODE,
 
5733
  OPT_SLAVE_EXEC_MODE,
 
5734
  OPT_GENERAL_LOG_FILE,
 
5735
  OPT_SLOW_QUERY_LOG_FILE,
 
5736
  OPT_IGNORE_BUILTIN_INNODB,
 
5737
  OPT_BINLOG_DIRECT_NON_TRANS_UPDATE,
 
5738
  OPT_DEFAULT_CHARACTER_SET_OLD
 
5739
};
 
5740
 
 
5741
 
 
5742
#define LONG_TIMEOUT ((ulong) 3600L*24L*365L)
 
5743
 
 
5744
struct my_option my_long_options[] =
 
5745
{
 
5746
  {"help", '?', "Display this help and exit.", 
 
5747
   (uchar**) &opt_help, (uchar**) &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
 
5748
   0, 0},
 
5749
#ifdef HAVE_REPLICATION
 
5750
  {"abort-slave-event-count", OPT_ABORT_SLAVE_EVENT_COUNT,
 
5751
   "Option used by mysql-test for debugging and testing of replication.",
 
5752
   (uchar**) &abort_slave_event_count,  (uchar**) &abort_slave_event_count,
 
5753
   0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
5754
#endif /* HAVE_REPLICATION */
 
5755
  {"allow-suspicious-udfs", OPT_ALLOW_SUSPICIOUS_UDFS,
 
5756
   "Allows use of UDFs consisting of only one symbol xxx() "
 
5757
   "without corresponding xxx_init() or xxx_deinit(). That also means "
 
5758
   "that one can load any function from any library, for example exit() "
 
5759
   "from libc.so",
 
5760
   (uchar**) &opt_allow_suspicious_udfs, (uchar**) &opt_allow_suspicious_udfs,
 
5761
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
5762
  {"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax. This mode will also set transaction isolation level 'serializable'.", 0, 0, 0,
 
5763
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
5764
  {"auto-increment-increment", OPT_AUTO_INCREMENT,
 
5765
   "Auto-increment columns are incremented by this.",
 
5766
   (uchar**) &global_system_variables.auto_increment_increment,
 
5767
   (uchar**) &max_system_variables.auto_increment_increment, 0, GET_ULONG,
 
5768
   OPT_ARG, 1, 1, 65535, 0, 1, 0 },
 
5769
  {"auto-increment-offset", OPT_AUTO_INCREMENT_OFFSET,
 
5770
   "Offset added to Auto-increment columns. Used when auto-increment-increment != 1.",
 
5771
   (uchar**) &global_system_variables.auto_increment_offset,
 
5772
   (uchar**) &max_system_variables.auto_increment_offset, 0, GET_ULONG, OPT_ARG,
 
5773
   1, 1, 65535, 0, 1, 0 },
 
5774
  {"automatic-sp-privileges", OPT_SP_AUTOMATIC_PRIVILEGES,
 
5775
   "Creating and dropping stored procedures alters ACLs. Disable with --skip-automatic-sp-privileges.",
 
5776
   (uchar**) &sp_automatic_privileges, (uchar**) &sp_automatic_privileges,
 
5777
   0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
 
5778
  {"basedir", 'b',
 
5779
   "Path to installation directory. All paths are usually resolved relative to this.",
 
5780
   (uchar**) &mysql_home_ptr, (uchar**) &mysql_home_ptr, 0, GET_STR, REQUIRED_ARG,
 
5781
   0, 0, 0, 0, 0, 0},
 
5782
  {"big-tables", OPT_BIG_TABLES,
 
5783
   "Allow big result sets by saving all temporary sets on file (solves most 'table full' errors).",
 
5784
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
5785
  {"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
 
5786
   (uchar**) &my_bind_addr_str, (uchar**) &my_bind_addr_str, 0, GET_STR,
 
5787
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
5788
  {"binlog_format", OPT_BINLOG_FORMAT,
 
5789
   "Does not have any effect without '--log-bin'. "
 
5790
   "Tell the master the form of binary logging to use: either 'row' for "
 
5791
   "row-based binary logging, 'statement' for statement-based binary "
 
5792
   "logging, or 'mixed'. 'mixed' is statement-based binary logging except "
 
5793
   "for statements where only row-based is correct: Statements that involve "
 
5794
   "user-defined functions (i.e., UDFs) or the UUID() function."
 
5795
#ifdef HAVE_NDB_BINLOG
 
5796
   "If ndbcluster is enabled and binlog_format is `mixed', the format switches"
 
5797
   " to 'row' and back implicitly per each query accessing a NDB table."
 
5798
#endif
 
5799
   ,(uchar**) &opt_binlog_format, (uchar**) &opt_binlog_format,
 
5800
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
5801
  {"binlog-do-db", OPT_BINLOG_DO_DB,
 
5802
   "Tells the master it should log updates for the specified database, and exclude all others not explicitly mentioned.",
 
5803
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
5804
  {"binlog-ignore-db", OPT_BINLOG_IGNORE_DB,
 
5805
   "Tells the master that updates to the given database should not be logged to the binary log.",
 
5806
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
5807
  {"binlog-row-event-max-size", OPT_BINLOG_ROWS_EVENT_MAX_SIZE,
 
5808
   "The maximum size of a row-based binary log event in bytes. Rows will be "
 
5809
   "grouped into events smaller than this size if possible. "
 
5810
   "The value has to be a multiple of 256.",
 
5811
   (uchar**) &opt_binlog_rows_event_max_size, 
 
5812
   (uchar**) &opt_binlog_rows_event_max_size, 0, 
 
5813
   GET_ULONG, REQUIRED_ARG, 
 
5814
   /* def_value */ 1024, /* min_value */  256, /* max_value */ ULONG_MAX, 
 
5815
   /* sub_size */     0, /* block_size */ 256, 
 
5816
   /* app_type */ 0
 
5817
  },
 
5818
#ifndef DISABLE_GRANT_OPTIONS
 
5819
  {"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts.", 0, 0, 0,
 
5820
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
5821
#endif
 
5822
  {"character-set-client-handshake", OPT_CHARACTER_SET_CLIENT_HANDSHAKE,
 
5823
   "Don't ignore client side character set value sent during handshake.",
 
5824
   (uchar**) &opt_character_set_client_handshake,
 
5825
   (uchar**) &opt_character_set_client_handshake,
 
5826
    0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
 
5827
  {"character-set-filesystem", OPT_CHARACTER_SET_FILESYSTEM,
 
5828
   "Set the filesystem character set.",
 
5829
   (uchar**) &character_set_filesystem_name,
 
5830
   (uchar**) &character_set_filesystem_name,
 
5831
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
 
5832
  {"character-set-server", 'C', "Set the default character set.",
 
5833
   (uchar**) &default_character_set_name, (uchar**) &default_character_set_name,
 
5834
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
 
5835
  {"character-sets-dir", OPT_CHARSETS_DIR,
 
5836
   "Directory where character sets are.", (uchar**) &charsets_dir,
 
5837
   (uchar**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
5838
  {"chroot", 'r', "Chroot mysqld daemon during startup.",
 
5839
   (uchar**) &mysqld_chroot, (uchar**) &mysqld_chroot, 0, GET_STR, REQUIRED_ARG,
 
5840
   0, 0, 0, 0, 0, 0},
 
5841
  {"collation-server", OPT_DEFAULT_COLLATION, "Set the default collation.",
 
5842
   (uchar**) &default_collation_name, (uchar**) &default_collation_name,
 
5843
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
 
5844
  {"completion-type", OPT_COMPLETION_TYPE, "Default completion type.",
 
5845
   (uchar**) &global_system_variables.completion_type,
 
5846
   (uchar**) &max_system_variables.completion_type, 0, GET_ULONG,
 
5847
   REQUIRED_ARG, 0, 0, 2, 0, 1, 0},
 
5848
  {"concurrent-insert", OPT_CONCURRENT_INSERT,
 
5849
   "Use concurrent insert with MyISAM. Disable with --concurrent-insert=0.",
 
5850
   (uchar**) &myisam_concurrent_insert, (uchar**) &myisam_concurrent_insert,
 
5851
   0, GET_ULONG, OPT_ARG, 1, 0, 2, 0, 0, 0},
 
5852
  {"console", OPT_CONSOLE, "Write error output on screen; don't remove the console window on windows.",
 
5853
   (uchar**) &opt_console, (uchar**) &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
5854
   0, 0, 0},
 
5855
  {"core-file", OPT_WANT_CORE, "Write core on errors.", 0, 0, 0, GET_NO_ARG,
 
5856
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
5857
  {"datadir", 'h', "Path to the database root.", (uchar**) &mysql_data_home,
 
5858
   (uchar**) &mysql_data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
5859
#ifndef DBUG_OFF
 
5860
  {"debug", '#', "Debug log.", (uchar**) &default_dbug_option,
 
5861
   (uchar**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
5862
#endif
 
5863
  {"default-character-set", OPT_DEFAULT_CHARACTER_SET_OLD, 
 
5864
   "Set the default character set (deprecated option, use --character-set-server instead).",
 
5865
   (uchar**) &default_character_set_name, (uchar**) &default_character_set_name,
 
5866
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
 
5867
  {"default-collation", OPT_DEFAULT_COLLATION_OLD, "Set the default collation (deprecated option, use --collation-server instead).",
 
5868
   (uchar**) &default_collation_name, (uchar**) &default_collation_name,
 
5869
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
 
5870
  {"default-storage-engine", OPT_STORAGE_ENGINE,
 
5871
   "Set the default storage engine (table type) for tables.",
 
5872
   (uchar**)&default_storage_engine_str, (uchar**)&default_storage_engine_str,
 
5873
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
5874
  {"default-table-type", OPT_STORAGE_ENGINE,
 
5875
   "(deprecated) Use --default-storage-engine.",
 
5876
   (uchar**)&default_storage_engine_str, (uchar**)&default_storage_engine_str,
 
5877
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
5878
  {"default-time-zone", OPT_DEFAULT_TIME_ZONE, "Set the default time zone.",
 
5879
   (uchar**) &default_tz_name, (uchar**) &default_tz_name,
 
5880
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
 
5881
  {"delay-key-write", OPT_DELAY_KEY_WRITE, "Type of DELAY_KEY_WRITE.",
 
5882
   0,0,0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
5883
  {"delay-key-write-for-all-tables", OPT_DELAY_KEY_WRITE_ALL,
 
5884
   "Don't flush key buffers between writes for any MyISAM table. (Deprecated option, use --delay-key-write=all instead.)",
 
5885
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
5886
#ifdef HAVE_OPENSSL
 
5887
  {"des-key-file", OPT_DES_KEY_FILE,
 
5888
   "Load keys for des_encrypt() and des_encrypt from given file.",
 
5889
   (uchar**) &des_key_file, (uchar**) &des_key_file, 0, GET_STR, REQUIRED_ARG,
 
5890
   0, 0, 0, 0, 0, 0},
 
5891
#endif /* HAVE_OPENSSL */
 
5892
#ifdef HAVE_REPLICATION
 
5893
  {"disconnect-slave-event-count", OPT_DISCONNECT_SLAVE_EVENT_COUNT,
 
5894
   "Option used by mysql-test for debugging and testing of replication.",
 
5895
   (uchar**) &disconnect_slave_event_count,
 
5896
   (uchar**) &disconnect_slave_event_count, 0, GET_INT, REQUIRED_ARG, 0, 0, 0,
 
5897
   0, 0, 0},
 
5898
#endif /* HAVE_REPLICATION */
 
5899
  {"enable-locking", OPT_ENABLE_LOCK,
 
5900
   "Deprecated option, use --external-locking instead.",
 
5901
   (uchar**) &opt_external_locking, (uchar**) &opt_external_locking,
 
5902
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
5903
#ifdef __NT__
 
5904
  {"enable-named-pipe", OPT_HAVE_NAMED_PIPE, "Enable the named pipe (NT).",
 
5905
   (uchar**) &opt_enable_named_pipe, (uchar**) &opt_enable_named_pipe, 0, GET_BOOL,
 
5906
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
5907
#endif
 
5908
#ifdef HAVE_STACK_TRACE_ON_SEGV
 
5909
  {"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure.",
 
5910
   (uchar**) &opt_do_pstack, (uchar**) &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0,
 
5911
   0, 0, 0, 0},
 
5912
#endif /* HAVE_STACK_TRACE_ON_SEGV */
 
5913
  {"engine-condition-pushdown",
 
5914
   OPT_ENGINE_CONDITION_PUSHDOWN,
 
5915
   "Push supported query conditions to the storage engine.",
 
5916
   (uchar**) &global_system_variables.engine_condition_pushdown,
 
5917
   (uchar**) &global_system_variables.engine_condition_pushdown,
 
5918
   0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
 
5919
  /* See how it's handled in get_one_option() */
 
5920
  {"event-scheduler", OPT_EVENT_SCHEDULER, "Enable/disable the event scheduler.",
 
5921
   NULL,  NULL, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
5922
  {"exit-info", 'T', "Used for debugging. Use at your own risk.", 0, 0, 0,
 
5923
   GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
5924
  {"external-locking", OPT_USE_LOCKING, "Use system (external) locking (disabled by default).  With this option enabled you can run myisamchk to test (not repair) tables while the MySQL server is running. Disable with --skip-external-locking.",
 
5925
   (uchar**) &opt_external_locking, (uchar**) &opt_external_locking,
 
5926
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
5927
  {"flush", OPT_FLUSH, "Flush tables to disk between SQL commands.", 0, 0, 0,
 
5928
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
5929
  /* We must always support the next option to make scripts like mysqltest
 
5930
     easier to do */
 
5931
  {"gdb", OPT_DEBUGGING,
 
5932
   "Set up signals usable for debugging.",
 
5933
   (uchar**) &opt_debugging, (uchar**) &opt_debugging,
 
5934
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
5935
  {"general_log", OPT_GENERAL_LOG,
 
5936
   "Enable/disable general log.", (uchar**) &opt_log,
 
5937
   (uchar**) &opt_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
5938
#ifdef HAVE_LARGE_PAGES
 
5939
  {"large-pages", OPT_ENABLE_LARGE_PAGES, "Enable support for large pages. \
 
5940
Disable with --skip-large-pages.",
 
5941
   (uchar**) &opt_large_pages, (uchar**) &opt_large_pages, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
5942
   0, 0, 0},
 
5943
#endif
 
5944
  {"ignore-builtin-innodb", OPT_IGNORE_BUILTIN_INNODB ,
 
5945
   "Disable initialization of builtin InnoDB plugin.",
 
5946
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
5947
  {"init-connect", OPT_INIT_CONNECT, 
 
5948
   "Command(s) that are executed for each new connection.",
 
5949
   (uchar**) &opt_init_connect, (uchar**) &opt_init_connect, 0, GET_STR_ALLOC,
 
5950
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
5951
#ifndef DISABLE_GRANT_OPTIONS
 
5952
  {"init-file", OPT_INIT_FILE, "Read SQL commands from this file at startup.",
 
5953
   (uchar**) &opt_init_file, (uchar**) &opt_init_file, 0, GET_STR, REQUIRED_ARG,
 
5954
   0, 0, 0, 0, 0, 0},
 
5955
#endif
 
5956
  {"init-rpl-role", OPT_INIT_RPL_ROLE, "Set the replication role.", 0, 0, 0,
 
5957
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
5958
  {"init-slave", OPT_INIT_SLAVE, "Command(s) that are executed by a slave server \
 
5959
each time the SQL thread starts.",
 
5960
   (uchar**) &opt_init_slave, (uchar**) &opt_init_slave, 0, GET_STR_ALLOC,
 
5961
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
5962
  {"language", 'L',
 
5963
   "Client error messages in given language. May be given as a full path.",
 
5964
   (uchar**) &language_ptr, (uchar**) &language_ptr, 0, GET_STR, REQUIRED_ARG,
 
5965
   0, 0, 0, 0, 0, 0},
 
5966
  {"lc-time-names", OPT_LC_TIME_NAMES,
 
5967
   "Set the language used for the month names and the days of the week.",
 
5968
   (uchar**) &lc_time_names_name,
 
5969
   (uchar**) &lc_time_names_name,
 
5970
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
 
5971
  {"local-infile", OPT_LOCAL_INFILE,
 
5972
   "Enable/disable LOAD DATA LOCAL INFILE (takes values 1 or 0).",
 
5973
   (uchar**) &opt_local_infile,
 
5974
   (uchar**) &opt_local_infile, 0, GET_BOOL, OPT_ARG,
 
5975
   1, 0, 0, 0, 0, 0},
 
5976
  {"log", 'l', "Log connections and queries to file (deprecated option, use "
 
5977
   "--general_log/--general_log_file instead).", (uchar**) &opt_logname,
 
5978
   (uchar**) &opt_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
5979
  {"general_log_file", OPT_GENERAL_LOG_FILE,
 
5980
   "Log connections and queries to given file.", (uchar**) &opt_logname,
 
5981
   (uchar**) &opt_logname, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
5982
  {"log-bin", OPT_BIN_LOG,
 
5983
   "Log update queries in binary format. Optional (but strongly recommended "
 
5984
   "to avoid replication problems if server's hostname changes) argument "
 
5985
   "should be the chosen location for the binary log files.",
 
5986
   (uchar**) &opt_bin_logname, (uchar**) &opt_bin_logname, 0, GET_STR_ALLOC,
 
5987
   OPT_ARG, 0, 0, 0, 0, 0, 0},
 
5988
  {"log-bin-index", OPT_BIN_LOG_INDEX,
 
5989
   "File that holds the names for last binary log files.",
 
5990
   (uchar**) &opt_binlog_index_name, (uchar**) &opt_binlog_index_name, 0, GET_STR,
 
5991
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
5992
#ifndef TO_BE_REMOVED_IN_5_1_OR_6_0
 
5993
  /*
 
5994
    In 5.0.6 we introduced the below option, then in 5.0.16 we renamed it to
 
5995
    log-bin-trust-function-creators but kept also the old name for
 
5996
    compatibility; the behaviour was also changed to apply only to functions
 
5997
    (and triggers). In a future release this old name could be removed.
 
5998
  */
 
5999
  {"log-bin-trust-routine-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS_OLD,
 
6000
   "(deprecated) Use log-bin-trust-function-creators.",
 
6001
   (uchar**) &trust_function_creators, (uchar**) &trust_function_creators, 0,
 
6002
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6003
#endif
 
6004
  /*
 
6005
    This option starts with "log-bin" to emphasize that it is specific of
 
6006
    binary logging.
 
6007
  */
 
6008
  {"log-bin-trust-function-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
 
6009
   "If equal to 0 (the default), then when --log-bin is used, creation of "
 
6010
   "a stored function (or trigger) is allowed only to users having the SUPER "
 
6011
   "privilege, and only if this stored function (trigger) may not break "
 
6012
   "binary logging."
 
6013
   "Note that if ALL connections to this server ALWAYS use row-based binary "
 
6014
   "logging, the security issues do not exist and the binary logging cannot "
 
6015
   "break, so you can safely set this to 1."
 
6016
   ,(uchar**) &trust_function_creators, (uchar**) &trust_function_creators, 0,
 
6017
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6018
  {"log-error", OPT_ERROR_LOG_FILE, "Error log file.",
 
6019
   (uchar**) &log_error_file_ptr, (uchar**) &log_error_file_ptr, 0, GET_STR,
 
6020
   OPT_ARG, 0, 0, 0, 0, 0, 0},
 
6021
  {"log-isam", OPT_ISAM_LOG, "Log all MyISAM changes to file.",
 
6022
   (uchar**) &myisam_log_filename, (uchar**) &myisam_log_filename, 0, GET_STR,
 
6023
   OPT_ARG, 0, 0, 0, 0, 0, 0},
 
6024
  {"log-long-format", '0',
 
6025
   "Log some extra information to update log. Please note that this option is deprecated; see --log-short-format option.", 
 
6026
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6027
#ifdef WITH_CSV_STORAGE_ENGINE
 
6028
  {"log-output", OPT_LOG_OUTPUT,
 
6029
   "Syntax: log-output[=value[,value...]], where \"value\" could be TABLE, "
 
6030
   "FILE or NONE.",
 
6031
   (uchar**) &log_output_str, (uchar**) &log_output_str, 0,
 
6032
   GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
6033
#endif
 
6034
  {"log-queries-not-using-indexes", OPT_LOG_QUERIES_NOT_USING_INDEXES,
 
6035
   "Log queries that are executed without benefit of any index to the slow log if it is open.",
 
6036
   (uchar**) &opt_log_queries_not_using_indexes, (uchar**) &opt_log_queries_not_using_indexes,
 
6037
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6038
  {"log-short-format", OPT_SHORT_LOG_FORMAT,
 
6039
   "Don't log extra information to update and slow-query logs.",
 
6040
   (uchar**) &opt_short_log_format, (uchar**) &opt_short_log_format,
 
6041
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6042
  {"log-slave-updates", OPT_LOG_SLAVE_UPDATES,
 
6043
   "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.",
 
6044
   (uchar**) &opt_log_slave_updates, (uchar**) &opt_log_slave_updates, 0, GET_BOOL,
 
6045
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
6046
  {"log-slow-admin-statements", OPT_LOG_SLOW_ADMIN_STATEMENTS,
 
6047
   "Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements to the slow log if it is open.",
 
6048
   (uchar**) &opt_log_slow_admin_statements,
 
6049
   (uchar**) &opt_log_slow_admin_statements,
 
6050
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6051
 {"log-slow-slave-statements", OPT_LOG_SLOW_SLAVE_STATEMENTS,
 
6052
  "Log slow statements executed by slave thread to the slow log if it is open.",
 
6053
  (uchar**) &opt_log_slow_slave_statements,
 
6054
  (uchar**) &opt_log_slow_slave_statements,
 
6055
  0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6056
  {"log_slow_queries", OPT_SLOW_QUERY_LOG,
 
6057
    "Log slow queries to a table or log file. Defaults logging to table "
 
6058
    "mysql.slow_log or hostname-slow.log if --log-output=file is used. "
 
6059
    "Must be enabled to activate other slow log options. "
 
6060
    "(deprecated option, use --slow_query_log/--slow_query_log_file instead)",
 
6061
   (uchar**) &opt_slow_logname, (uchar**) &opt_slow_logname, 0, GET_STR, OPT_ARG,
 
6062
   0, 0, 0, 0, 0, 0},
 
6063
  {"slow_query_log_file", OPT_SLOW_QUERY_LOG_FILE,
 
6064
    "Log slow queries to given log file. Defaults logging to hostname-slow.log. Must be enabled to activate other slow log options.",
 
6065
   (uchar**) &opt_slow_logname, (uchar**) &opt_slow_logname, 0, GET_STR,
 
6066
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6067
  {"log-tc", OPT_LOG_TC,
 
6068
   "Path to transaction coordinator log (used for transactions that affect "
 
6069
   "more than one storage engine, when binary log is disabled).",
 
6070
   (uchar**) &opt_tc_log_file, (uchar**) &opt_tc_log_file, 0, GET_STR,
 
6071
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6072
#ifdef HAVE_MMAP
 
6073
  {"log-tc-size", OPT_LOG_TC_SIZE, "Size of transaction coordinator log.",
 
6074
   (uchar**) &opt_tc_log_size, (uchar**) &opt_tc_log_size, 0, GET_ULONG,
 
6075
   REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, ULONG_MAX, 0,
 
6076
   TC_LOG_PAGE_SIZE, 0},
 
6077
#endif
 
6078
  {"log-update", OPT_UPDATE_LOG,
 
6079
   "The update log is deprecated since version 5.0, is replaced by the binary \
 
6080
log and this option justs turns on --log-bin instead.",
 
6081
   (uchar**) &opt_update_logname, (uchar**) &opt_update_logname, 0, GET_STR,
 
6082
   OPT_ARG, 0, 0, 0, 0, 0, 0},
 
6083
  {"log-warnings", 'W', "Log some not critical warnings to the log file.",
 
6084
   (uchar**) &global_system_variables.log_warnings,
 
6085
   (uchar**) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0,
 
6086
   0, 0, 0},
 
6087
  {"low-priority-updates", OPT_LOW_PRIORITY_UPDATES,
 
6088
   "INSERT/DELETE/UPDATE has lower priority than selects.",
 
6089
   (uchar**) &global_system_variables.low_priority_updates,
 
6090
   (uchar**) &max_system_variables.low_priority_updates,
 
6091
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6092
  {"master-connect-retry", OPT_MASTER_CONNECT_RETRY,
 
6093
   "The number of seconds the slave thread will sleep before retrying to "
 
6094
   "connect to the master, in case the master goes down or the connection "
 
6095
   "is lost.",
 
6096
   (uchar**) &master_connect_retry, (uchar**) &master_connect_retry, 0, GET_UINT,
 
6097
   REQUIRED_ARG, 60, 0, 0, 0, 0, 0},
 
6098
  {"master-host", OPT_MASTER_HOST,
 
6099
   "Master hostname or IP address for replication. If not set, the slave thread will not be started. Note that the setting of master-host will be ignored if there exists a valid master.info file.",
 
6100
   (uchar**) &master_host, (uchar**) &master_host, 0, GET_STR, REQUIRED_ARG, 0, 0,
 
6101
   0, 0, 0, 0},
 
6102
  {"master-info-file", OPT_MASTER_INFO_FILE,
 
6103
   "The location and name of the file that remembers the master and where the I/O replication \
 
6104
thread is in the master's binlogs.",
 
6105
   (uchar**) &master_info_file, (uchar**) &master_info_file, 0, GET_STR,
 
6106
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6107
  {"master-password", OPT_MASTER_PASSWORD,
 
6108
   "The password the slave thread will authenticate with when connecting to "
 
6109
   "the master. If not set, an empty password is assumed. The value in "
 
6110
   "master.info will take precedence if it can be read.",
 
6111
   (uchar**)&master_password, (uchar**)&master_password, 0,
 
6112
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6113
  {"master-port", OPT_MASTER_PORT,
 
6114
   "The port the master is listening on. If not set, the compiled setting of MYSQL_PORT is assumed. If you have not tinkered with configure options, this should be 3306. The value in master.info will take precedence if it can be read.",
 
6115
   (uchar**) &master_port, (uchar**) &master_port, 0, GET_UINT, REQUIRED_ARG,
 
6116
   MYSQL_PORT, 0, 0, 0, 0, 0},
 
6117
  {"master-retry-count", OPT_MASTER_RETRY_COUNT,
 
6118
   "The number of tries the slave will make to connect to the master before giving up.",
 
6119
   (uchar**) &master_retry_count, (uchar**) &master_retry_count, 0, GET_ULONG,
 
6120
   REQUIRED_ARG, 3600*24, 0, 0, 0, 0, 0},
 
6121
  {"master-ssl", OPT_MASTER_SSL,
 
6122
   "Enable the slave to connect to the master using SSL.",
 
6123
   (uchar**) &master_ssl, (uchar**) &master_ssl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
 
6124
   0, 0},
 
6125
  {"master-ssl-ca", OPT_MASTER_SSL_CA,
 
6126
   "Master SSL CA file. Only applies if you have enabled master-ssl.",
 
6127
   (uchar**) &master_ssl_ca, (uchar**) &master_ssl_ca, 0, GET_STR, OPT_ARG,
 
6128
   0, 0, 0, 0, 0, 0},
 
6129
  {"master-ssl-capath", OPT_MASTER_SSL_CAPATH,
 
6130
   "Master SSL CA path. Only applies if you have enabled master-ssl.",
 
6131
   (uchar**) &master_ssl_capath, (uchar**) &master_ssl_capath, 0, GET_STR, OPT_ARG,
 
6132
   0, 0, 0, 0, 0, 0},
 
6133
  {"master-ssl-cert", OPT_MASTER_SSL_CERT,
 
6134
   "Master SSL certificate file name. Only applies if you have enabled "
 
6135
   "master-ssl.",
 
6136
   (uchar**) &master_ssl_cert, (uchar**) &master_ssl_cert, 0, GET_STR, OPT_ARG,
 
6137
   0, 0, 0, 0, 0, 0},
 
6138
  {"master-ssl-cipher", OPT_MASTER_SSL_CIPHER,
 
6139
   "Master SSL cipher. Only applies if you have enabled master-ssl.",
 
6140
   (uchar**) &master_ssl_cipher, (uchar**) &master_ssl_capath, 0, GET_STR, OPT_ARG,
 
6141
   0, 0, 0, 0, 0, 0},
 
6142
  {"master-ssl-key", OPT_MASTER_SSL_KEY,
 
6143
   "Master SSL keyfile name. Only applies if you have enabled master-ssl.",
 
6144
   (uchar**) &master_ssl_key, (uchar**) &master_ssl_key, 0, GET_STR, OPT_ARG,
 
6145
   0, 0, 0, 0, 0, 0},
 
6146
  {"master-user", OPT_MASTER_USER,
 
6147
   "The username the slave thread will use for authentication when connecting to the master. The user must have FILE privilege. If the master user is not set, user test is assumed. The value in master.info will take precedence if it can be read.",
 
6148
   (uchar**) &master_user, (uchar**) &master_user, 0, GET_STR, REQUIRED_ARG, 0, 0,
 
6149
   0, 0, 0, 0},
 
6150
#ifdef HAVE_REPLICATION
 
6151
  {"max-binlog-dump-events", OPT_MAX_BINLOG_DUMP_EVENTS,
 
6152
   "Option used by mysql-test for debugging and testing of replication.",
 
6153
   (uchar**) &max_binlog_dump_events, (uchar**) &max_binlog_dump_events, 0,
 
6154
   GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6155
#endif /* HAVE_REPLICATION */
 
6156
  {"memlock", OPT_MEMLOCK, "Lock mysqld in memory.", (uchar**) &locked_in_memory,
 
6157
   (uchar**) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6158
  {"myisam-recover", OPT_MYISAM_RECOVER,
 
6159
   "Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.",
 
6160
   (uchar**) &myisam_recover_options_str, (uchar**) &myisam_recover_options_str, 0,
 
6161
   GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
6162
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
 
6163
  {"ndb-connectstring", OPT_NDB_CONNECTSTRING,
 
6164
   "Connect string for ndbcluster.",
 
6165
   (uchar**) &opt_ndb_connectstring,
 
6166
   (uchar**) &opt_ndb_connectstring,
 
6167
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6168
  {"ndb-mgmd-host", OPT_NDB_MGMD,
 
6169
   "Set host and port for ndb_mgmd. Syntax: hostname[:port]",
 
6170
   (uchar**) &opt_ndb_mgmd,
 
6171
   (uchar**) &opt_ndb_mgmd,
 
6172
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6173
  {"ndb-nodeid", OPT_NDB_NODEID,
 
6174
   "Nodeid for this mysqlserver in the cluster.",
 
6175
   (uchar**) &opt_ndb_nodeid,
 
6176
   (uchar**) &opt_ndb_nodeid,
 
6177
   0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6178
  {"ndb-autoincrement-prefetch-sz", OPT_NDB_AUTOINCREMENT_PREFETCH_SZ,
 
6179
   "Specify number of autoincrement values that are prefetched.",
 
6180
   (uchar**) &global_system_variables.ndb_autoincrement_prefetch_sz,
 
6181
   (uchar**) &max_system_variables.ndb_autoincrement_prefetch_sz,
 
6182
   0, GET_ULONG, REQUIRED_ARG, 1, 1, 256, 0, 0, 0},
 
6183
  {"ndb-force-send", OPT_NDB_FORCE_SEND,
 
6184
   "Force send of buffers to ndb immediately without waiting for "
 
6185
   "other threads.",
 
6186
   (uchar**) &global_system_variables.ndb_force_send,
 
6187
   (uchar**) &global_system_variables.ndb_force_send,
 
6188
   0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
 
6189
  {"ndb_force_send", OPT_NDB_FORCE_SEND,
 
6190
   "same as --ndb-force-send.",
 
6191
   (uchar**) &global_system_variables.ndb_force_send,
 
6192
   (uchar**) &global_system_variables.ndb_force_send,
 
6193
   0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
 
6194
  {"ndb-extra-logging", OPT_NDB_EXTRA_LOGGING,
 
6195
   "Turn on more logging in the error log.",
 
6196
   (uchar**) &ndb_extra_logging,
 
6197
   (uchar**) &ndb_extra_logging,
 
6198
   0, GET_INT, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
6199
#ifdef HAVE_NDB_BINLOG
 
6200
  {"ndb-report-thresh-binlog-epoch-slip", OPT_NDB_REPORT_THRESH_BINLOG_EPOCH_SLIP,
 
6201
   "Threshold on number of epochs to be behind before reporting binlog status. "
 
6202
   "E.g., 3 means that if the difference between what epoch has been received "
 
6203
   "from the storage nodes and what has been applied to the binlog is 3 or more, "
 
6204
   "a status message will be sent to the cluster log.",
 
6205
   (uchar**) &ndb_report_thresh_binlog_epoch_slip,
 
6206
   (uchar**) &ndb_report_thresh_binlog_epoch_slip,
 
6207
   0, GET_ULONG, REQUIRED_ARG, 3, 0, 256, 0, 0, 0},
 
6208
  {"ndb-report-thresh-binlog-mem-usage", OPT_NDB_REPORT_THRESH_BINLOG_MEM_USAGE,
 
6209
   "Threshold on percentage of free memory before reporting binlog status. E.g., "
 
6210
   "10 means that if amount of available memory for receiving binlog data from "
 
6211
   "the storage nodes goes below 10%, "
 
6212
   "a status message will be sent to the cluster log.",
 
6213
   (uchar**) &ndb_report_thresh_binlog_mem_usage,
 
6214
   (uchar**) &ndb_report_thresh_binlog_mem_usage,
 
6215
   0, GET_ULONG, REQUIRED_ARG, 10, 0, 100, 0, 0, 0},
 
6216
#endif
 
6217
  {"ndb-use-exact-count", OPT_NDB_USE_EXACT_COUNT,
 
6218
   "Use exact records count during query planning and for fast "
 
6219
   "select count(*), disable for faster queries.",
 
6220
   (uchar**) &global_system_variables.ndb_use_exact_count,
 
6221
   (uchar**) &global_system_variables.ndb_use_exact_count,
 
6222
   0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
 
6223
  {"ndb_use_exact_count", OPT_NDB_USE_EXACT_COUNT,
 
6224
   "Same as --ndb-use-exact-count.",
 
6225
   (uchar**) &global_system_variables.ndb_use_exact_count,
 
6226
   (uchar**) &global_system_variables.ndb_use_exact_count,
 
6227
   0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
 
6228
  {"ndb-use-transactions", OPT_NDB_USE_TRANSACTIONS,
 
6229
   "Use transactions for large inserts, if enabled then large "
 
6230
   "inserts will be split into several smaller transactions",
 
6231
   (uchar**) &global_system_variables.ndb_use_transactions,
 
6232
   (uchar**) &global_system_variables.ndb_use_transactions,
 
6233
   0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
 
6234
  {"ndb_use_transactions", OPT_NDB_USE_TRANSACTIONS,
 
6235
   "Same as --ndb-use-transactions.",
 
6236
   (uchar**) &global_system_variables.ndb_use_transactions,
 
6237
   (uchar**) &global_system_variables.ndb_use_transactions,
 
6238
   0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
 
6239
  {"ndb-shm", OPT_NDB_SHM,
 
6240
   "Use shared memory connections when available.",
 
6241
   (uchar**) &opt_ndb_shm,
 
6242
   (uchar**) &opt_ndb_shm,
 
6243
   0, GET_BOOL, OPT_ARG, OPT_NDB_SHM_DEFAULT, 0, 0, 0, 0, 0},
 
6244
  {"ndb-optimized-node-selection", OPT_NDB_OPTIMIZED_NODE_SELECTION,
 
6245
   "Select nodes for transactions in a more optimal way.",
 
6246
   (uchar**) &opt_ndb_optimized_node_selection,
 
6247
   (uchar**) &opt_ndb_optimized_node_selection,
 
6248
   0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
 
6249
  { "ndb-cache-check-time", OPT_NDB_CACHE_CHECK_TIME,
 
6250
    "A dedicated thread is created to, at the given milliseconds interval, "
 
6251
    "invalidate the query cache if another MySQL server in the cluster has "
 
6252
    "changed the data in the database.",
 
6253
    (uchar**) &opt_ndb_cache_check_time, (uchar**) &opt_ndb_cache_check_time, 0, GET_ULONG, REQUIRED_ARG,
 
6254
    0, 0, LONG_TIMEOUT, 0, 1, 0},
 
6255
  {"ndb-index-stat-enable", OPT_NDB_INDEX_STAT_ENABLE,
 
6256
   "Use ndb index statistics in query optimization.",
 
6257
   (uchar**) &global_system_variables.ndb_index_stat_enable,
 
6258
   (uchar**) &max_system_variables.ndb_index_stat_enable,
 
6259
   0, GET_BOOL, OPT_ARG, 0, 0, 1, 0, 0, 0},
 
6260
#endif
 
6261
  {"ndb-use-copying-alter-table",
 
6262
   OPT_NDB_USE_COPYING_ALTER_TABLE,
 
6263
   "Force ndbcluster to always copy tables at alter table (should only be used if on-line alter table fails).",
 
6264
   (uchar**) &global_system_variables.ndb_use_copying_alter_table,
 
6265
   (uchar**) &global_system_variables.ndb_use_copying_alter_table,
 
6266
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},  
 
6267
  {"new", 'n', "Use very new, possibly 'unsafe', functions.",
 
6268
   (uchar**) &global_system_variables.new_mode,
 
6269
   (uchar**) &max_system_variables.new_mode,
 
6270
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6271
#ifdef NOT_YET
 
6272
  {"no-mix-table-types", OPT_NO_MIX_TYPE, 
 
6273
   "Don't allow commands that use two different table types.",
 
6274
   (uchar**) &opt_no_mix_types, (uchar**) &opt_no_mix_types, 0, GET_BOOL, NO_ARG,
 
6275
   0, 0, 0, 0, 0, 0},
 
6276
#endif
 
6277
  {"old-alter-table", OPT_OLD_ALTER_TABLE,
 
6278
   "Use old, non-optimized alter table.",
 
6279
   (uchar**) &global_system_variables.old_alter_table,
 
6280
   (uchar**) &max_system_variables.old_alter_table, 0, GET_BOOL, NO_ARG,
 
6281
   0, 0, 0, 0, 0, 0},
 
6282
  {"old-passwords", OPT_OLD_PASSWORDS, "Use old password encryption method (needed for 4.0 and older clients).",
 
6283
   (uchar**) &global_system_variables.old_passwords,
 
6284
   (uchar**) &max_system_variables.old_passwords, 0, GET_BOOL, NO_ARG,
 
6285
   0, 0, 0, 0, 0, 0},
 
6286
  {"one-thread", OPT_ONE_THREAD,
 
6287
   "(Deprecated): Only use one thread (for debugging under Linux). Use "
 
6288
   "thread-handling=no-threads instead.",
 
6289
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6290
  {"old-style-user-limits", OPT_OLD_STYLE_USER_LIMITS,
 
6291
   "Enable old-style user limits (before 5.0.3, user resources were counted "
 
6292
   "per each user+host vs. per account).",
 
6293
   (uchar**) &opt_old_style_user_limits, (uchar**) &opt_old_style_user_limits,
 
6294
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6295
  {"pid-file", OPT_PID_FILE, "Pid file used by safe_mysqld.",
 
6296
   (uchar**) &pidfile_name_ptr, (uchar**) &pidfile_name_ptr, 0, GET_STR,
 
6297
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6298
  {"port", 'P', "Port number to use for connection or 0 for default to, in "
 
6299
   "order of preference, my.cnf, $MYSQL_TCP_PORT, "
 
6300
#if MYSQL_PORT_DEFAULT == 0
 
6301
   "/etc/services, "
 
6302
#endif
 
6303
   "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
 
6304
   (uchar**) &mysqld_port,
 
6305
   (uchar**) &mysqld_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6306
  {"port-open-timeout", OPT_PORT_OPEN_TIMEOUT,
 
6307
   "Maximum time in seconds to wait for the port to become free. "
 
6308
   "(Default: No wait).", (uchar**) &mysqld_port_timeout,
 
6309
   (uchar**) &mysqld_port_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6310
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
 
6311
  {"profiling_history_size", OPT_PROFILING, "Limit of query profiling memory.",
 
6312
   (uchar**) &global_system_variables.profiling_history_size,
 
6313
   (uchar**) &max_system_variables.profiling_history_size,
 
6314
   0, GET_ULONG, REQUIRED_ARG, 15, 0, 100, 0, 0, 0},
 
6315
#endif
 
6316
  {"relay-log", OPT_RELAY_LOG,
 
6317
   "The location and name to use for relay logs.",
 
6318
   (uchar**) &opt_relay_logname, (uchar**) &opt_relay_logname, 0,
 
6319
   GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6320
  {"relay-log-index", OPT_RELAY_LOG_INDEX,
 
6321
   "The location and name to use for the file that keeps a list of the last \
 
6322
relay logs.",
 
6323
   (uchar**) &opt_relaylog_index_name, (uchar**) &opt_relaylog_index_name, 0,
 
6324
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6325
  {"relay-log-info-file", OPT_RELAY_LOG_INFO_FILE,
 
6326
   "The location and name of the file that remembers where the SQL replication \
 
6327
thread is in the relay logs.",
 
6328
   (uchar**) &relay_log_info_file, (uchar**) &relay_log_info_file, 0, GET_STR,
 
6329
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6330
  {"replicate-do-db", OPT_REPLICATE_DO_DB,
 
6331
   "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.%.",
 
6332
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6333
  {"replicate-do-table", OPT_REPLICATE_DO_TABLE,
 
6334
   "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.",
 
6335
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6336
  {"replicate-ignore-db", OPT_REPLICATE_IGNORE_DB,
 
6337
   "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.%. ",
 
6338
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6339
  {"replicate-ignore-table", OPT_REPLICATE_IGNORE_TABLE,
 
6340
   "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.",
 
6341
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6342
  {"replicate-rewrite-db", OPT_REPLICATE_REWRITE_DB,
 
6343
   "Updates to a database with a different name than the original. Example: replicate-rewrite-db=master_db_name->slave_db_name.",
 
6344
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6345
#ifdef HAVE_REPLICATION
 
6346
  {"replicate-same-server-id", OPT_REPLICATE_SAME_SERVER_ID,
 
6347
   "In replication, if set to 1, do not skip events having our server id. \
 
6348
Default value is 0 (to break infinite loops in circular replication). \
 
6349
Can't be set to 1 if --log-slave-updates is used.",
 
6350
   (uchar**) &replicate_same_server_id,
 
6351
   (uchar**) &replicate_same_server_id,
 
6352
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6353
#endif
 
6354
  {"replicate-wild-do-table", OPT_REPLICATE_WILD_DO_TABLE,
 
6355
   "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.",
 
6356
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6357
  {"replicate-wild-ignore-table", OPT_REPLICATE_WILD_IGNORE_TABLE,
 
6358
   "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.",
 
6359
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6360
  // In replication, we may need to tell the other servers how to connect
 
6361
  {"report-host", OPT_REPORT_HOST,
 
6362
   "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.",
 
6363
   (uchar**) &report_host, (uchar**) &report_host, 0, GET_STR, REQUIRED_ARG, 0, 0,
 
6364
   0, 0, 0, 0},
 
6365
  {"report-password", OPT_REPORT_PASSWORD, "Undocumented.",
 
6366
   (uchar**) &report_password, (uchar**) &report_password, 0, GET_STR,
 
6367
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6368
  {"report-port", OPT_REPORT_PORT,
 
6369
   "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.",
 
6370
   (uchar**) &report_port, (uchar**) &report_port, 0, GET_UINT, REQUIRED_ARG,
 
6371
   MYSQL_PORT, 0, 0, 0, 0, 0},
 
6372
  {"report-user", OPT_REPORT_USER, "Undocumented.", (uchar**) &report_user,
 
6373
   (uchar**) &report_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6374
  {"rpl-recovery-rank", OPT_RPL_RECOVERY_RANK, "Undocumented.",
 
6375
   (uchar**) &rpl_recovery_rank, (uchar**) &rpl_recovery_rank, 0, GET_ULONG,
 
6376
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6377
  {"safe-mode", OPT_SAFE, "Skip some optimize stages (for testing).",
 
6378
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6379
#ifndef TO_BE_DELETED
 
6380
  {"safe-show-database", OPT_SAFE_SHOW_DB,
 
6381
   "Deprecated option; use GRANT SHOW DATABASES instead.",
 
6382
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6383
#endif
 
6384
  {"safe-user-create", OPT_SAFE_USER_CREATE,
 
6385
   "Don't allow new user creation by the user who has no write privileges to the mysql.user table.",
 
6386
   (uchar**) &opt_safe_user_create, (uchar**) &opt_safe_user_create, 0, GET_BOOL,
 
6387
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
6388
  {"safemalloc-mem-limit", OPT_SAFEMALLOC_MEM_LIMIT,
 
6389
   "Simulate memory shortage when compiled with the --with-debug=full option.",
 
6390
   0, 0, 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6391
  {"secure-auth", OPT_SECURE_AUTH, "Disallow authentication for accounts that have old (pre-4.1) passwords.",
 
6392
   (uchar**) &opt_secure_auth, (uchar**) &opt_secure_auth, 0, GET_BOOL, NO_ARG,
 
6393
   my_bool(0), 0, 0, 0, 0, 0},
 
6394
  {"secure-file-priv", OPT_SECURE_FILE_PRIV,
 
6395
   "Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files within specified directory.",
 
6396
   (uchar**) &opt_secure_file_priv, (uchar**) &opt_secure_file_priv, 0,
 
6397
   GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6398
  {"server-id", OPT_SERVER_ID,
 
6399
   "Uniquely identifies the server instance in the community of replication partners.",
 
6400
   (uchar**) &server_id, (uchar**) &server_id, 0, GET_ULONG, REQUIRED_ARG, 0, 0, UINT_MAX32,
 
6401
   0, 0, 0},
 
6402
  {"set-variable", 'O',
 
6403
   "Change the value of a variable. Please note that this option is deprecated; "
 
6404
   "you can set variables directly with --variable-name=value.",
 
6405
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6406
#ifdef HAVE_SMEM
 
6407
  {"shared-memory", OPT_ENABLE_SHARED_MEMORY,
 
6408
   "Enable the shared memory.",(uchar**) &opt_enable_shared_memory, (uchar**) &opt_enable_shared_memory,
 
6409
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6410
#endif
 
6411
#ifdef HAVE_SMEM
 
6412
  {"shared-memory-base-name",OPT_SHARED_MEMORY_BASE_NAME,
 
6413
   "Base name of shared memory.", (uchar**) &shared_memory_base_name, (uchar**) &shared_memory_base_name,
 
6414
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6415
#endif
 
6416
  {"show-slave-auth-info", OPT_SHOW_SLAVE_AUTH_INFO,
 
6417
   "Show user and password in SHOW SLAVE HOSTS on this master.",
 
6418
   (uchar**) &opt_show_slave_auth_info, (uchar**) &opt_show_slave_auth_info, 0,
 
6419
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6420
#ifndef DISABLE_GRANT_OPTIONS
 
6421
  {"skip-grant-tables", OPT_SKIP_GRANT,
 
6422
   "Start without grant tables. This gives all users FULL ACCESS to all tables.",
 
6423
   (uchar**) &opt_noacl, (uchar**) &opt_noacl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
 
6424
   0},
 
6425
#endif
 
6426
  {"skip-host-cache", OPT_SKIP_HOST_CACHE, "Don't cache host names.", 0, 0, 0,
 
6427
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6428
  {"skip-locking", OPT_SKIP_LOCK,
 
6429
   "Deprecated option, use --skip-external-locking instead.",
 
6430
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6431
  {"skip-name-resolve", OPT_SKIP_RESOLVE,
 
6432
   "Don't resolve hostnames. All hostnames are IP's or 'localhost'.",
 
6433
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6434
  {"skip-networking", OPT_SKIP_NETWORKING,
 
6435
   "Don't allow connection with TCP/IP.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0,
 
6436
   0, 0, 0},
 
6437
  {"skip-new", OPT_SKIP_NEW, "Don't use new, possibly wrong routines.",
 
6438
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6439
#ifndef DBUG_OFF
 
6440
#ifdef SAFEMALLOC
 
6441
  {"skip-safemalloc", OPT_SKIP_SAFEMALLOC,
 
6442
   "Don't use the memory allocation checking.", 0, 0, 0, GET_NO_ARG, NO_ARG,
 
6443
   0, 0, 0, 0, 0, 0},
 
6444
#endif
 
6445
#endif
 
6446
  {"skip-show-database", OPT_SKIP_SHOW_DB,
 
6447
   "Don't allow 'SHOW DATABASE' commands.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
 
6448
   0, 0, 0, 0},
 
6449
  {"skip-slave-start", OPT_SKIP_SLAVE_START,
 
6450
   "If set, slave is not autostarted.", (uchar**) &opt_skip_slave_start,
 
6451
   (uchar**) &opt_skip_slave_start, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6452
  {"skip-stack-trace", OPT_SKIP_STACK_TRACE,
 
6453
   "Don't print a stack trace on failure.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
 
6454
   0, 0, 0, 0},
 
6455
  {"skip-symlink", OPT_SKIP_SYMLINKS, "Don't allow symlinking of tables. Deprecated option. Use --skip-symbolic-links instead.",
 
6456
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6457
  {"skip-thread-priority", OPT_SKIP_PRIOR,
 
6458
   "Don't give threads different priorities. Deprecated option.", 0, 0, 0, GET_NO_ARG, NO_ARG,
 
6459
   DEFAULT_SKIP_THREAD_PRIORITY, 0, 0, 0, 0, 0},
 
6460
#ifdef HAVE_REPLICATION
 
6461
  {"slave-load-tmpdir", OPT_SLAVE_LOAD_TMPDIR,
 
6462
   "The location where the slave should put its temporary files when \
 
6463
replicating a LOAD DATA INFILE command.",
 
6464
   (uchar**) &slave_load_tmpdir, (uchar**) &slave_load_tmpdir, 0, GET_STR_ALLOC,
 
6465
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6466
  {"slave-skip-errors", OPT_SLAVE_SKIP_ERRORS,
 
6467
   "Tells the slave thread to continue replication when a query event returns an error from the provided list.",
 
6468
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6469
  {"slave-exec-mode", OPT_SLAVE_EXEC_MODE,
 
6470
   "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.",
 
6471
   (uchar**) &slave_exec_mode_str, (uchar**) &slave_exec_mode_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6472
#endif
 
6473
  {"slow-query-log", OPT_SLOW_LOG,
 
6474
   "Enable/disable slow query log.", (uchar**) &opt_slow_log,
 
6475
   (uchar**) &opt_slow_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
6476
  {"socket", OPT_SOCKET, "Socket file to use for connection.",
 
6477
   (uchar**) &mysqld_unix_port, (uchar**) &mysqld_unix_port, 0, GET_STR,
 
6478
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6479
#ifdef HAVE_REPLICATION
 
6480
  {"sporadic-binlog-dump-fail", OPT_SPORADIC_BINLOG_DUMP_FAIL,
 
6481
   "Option used by mysql-test for debugging and testing of replication.",
 
6482
   (uchar**) &opt_sporadic_binlog_dump_fail,
 
6483
   (uchar**) &opt_sporadic_binlog_dump_fail, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
 
6484
   0},
 
6485
#endif /* HAVE_REPLICATION */
 
6486
  {"sql-bin-update-same", OPT_SQL_BIN_UPDATE_SAME,
 
6487
   "The update log is deprecated since version 5.0, is replaced by the binary \
 
6488
log and this option does nothing anymore.",
 
6489
   0, 0, 0, GET_DISABLED, NO_ARG, 0, 0, 0, 0, 0, 0},
 
6490
  {"sql-mode", OPT_SQL_MODE,
 
6491
   "Syntax: sql-mode=option[,option[,option...]] where option can be one of: REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, ONLY_FULL_GROUP_BY, NO_UNSIGNED_SUBTRACTION.",
 
6492
   (uchar**) &sql_mode_str, (uchar**) &sql_mode_str, 0, GET_STR, REQUIRED_ARG, 0,
 
6493
   0, 0, 0, 0, 0},
 
6494
#ifdef HAVE_OPENSSL
 
6495
#include "sslopt-longopts.h"
 
6496
#endif
 
6497
#ifdef __WIN__
 
6498
  {"standalone", OPT_STANDALONE,
 
6499
  "Dummy option to start as a standalone program (NT).", 0, 0, 0, GET_NO_ARG,
 
6500
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
6501
#endif
 
6502
  {"symbolic-links", 's', "Enable symbolic link support.",
 
6503
   (uchar**) &my_use_symdir, (uchar**) &my_use_symdir, 0, GET_BOOL, NO_ARG,
 
6504
   /*
 
6505
     The system call realpath() produces warnings under valgrind and
 
6506
     purify. These are not suppressed: instead we disable symlinks
 
6507
     option if compiled with valgrind support.
 
6508
   */
 
6509
   IF_PURIFY(0,1), 0, 0, 0, 0, 0},
 
6510
  {"sysdate-is-now", OPT_SYSDATE_IS_NOW,
 
6511
   "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.",
 
6512
   (uchar**) &global_system_variables.sysdate_is_now,
 
6513
   0, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
 
6514
  {"tc-heuristic-recover", OPT_TC_HEURISTIC_RECOVER,
 
6515
   "Decision to use in heuristic recover process. Possible values are COMMIT or ROLLBACK.",
 
6516
   (uchar**) &opt_tc_heuristic_recover, (uchar**) &opt_tc_heuristic_recover,
 
6517
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6518
#if defined(ENABLED_DEBUG_SYNC)
 
6519
  {"debug-sync-timeout", OPT_DEBUG_SYNC_TIMEOUT,
 
6520
   "Enable the debug sync facility "
 
6521
   "and optionally specify a default wait timeout in seconds. "
 
6522
   "A zero value keeps the facility disabled.",
 
6523
   (uchar**) &opt_debug_sync_timeout, 0,
 
6524
   0, GET_UINT, OPT_ARG, 0, 0, UINT_MAX, 0, 0, 0},
 
6525
#endif /* defined(ENABLED_DEBUG_SYNC) */
 
6526
  {"temp-pool", OPT_TEMP_POOL,
 
6527
#if (ENABLE_TEMP_POOL)
 
6528
   "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.",
 
6529
#else
 
6530
   "This option is ignored on this OS.",
 
6531
#endif
 
6532
   (uchar**) &use_temp_pool, (uchar**) &use_temp_pool, 0, GET_BOOL, NO_ARG, 1,
 
6533
   0, 0, 0, 0, 0},
 
6534
 
 
6535
  {"timed_mutexes", OPT_TIMED_MUTEXES,
 
6536
   "Specify whether to time mutexes (only InnoDB mutexes are currently supported).",
 
6537
   (uchar**) &timed_mutexes, (uchar**) &timed_mutexes, 0, GET_BOOL, NO_ARG, 0, 
 
6538
    0, 0, 0, 0, 0},
 
6539
  {"tmpdir", 't',
 
6540
   "Path for temporary files. Several paths may be specified, separated by a "
 
6541
#if defined(__WIN__) || defined(__NETWARE__)
 
6542
   "semicolon (;)"
 
6543
#else
 
6544
   "colon (:)"
 
6545
#endif
 
6546
   ", in this case they are used in a round-robin fashion.",
 
6547
   (uchar**) &opt_mysql_tmpdir,
 
6548
   (uchar**) &opt_mysql_tmpdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6549
  {"transaction-isolation", OPT_TX_ISOLATION,
 
6550
   "Default transaction isolation level.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0,
 
6551
   0, 0, 0, 0, 0},
 
6552
  {"use-symbolic-links", OPT_SYMBOLIC_LINKS, "Enable symbolic link support. Deprecated option; use --symbolic-links instead.",
 
6553
   (uchar**) &my_use_symdir, (uchar**) &my_use_symdir, 0, GET_BOOL, NO_ARG,
 
6554
   IF_PURIFY(0,1), 0, 0, 0, 0, 0},
 
6555
  {"user", 'u', "Run mysqld daemon as user.", 0, 0, 0, GET_STR, REQUIRED_ARG,
 
6556
   0, 0, 0, 0, 0, 0},
 
6557
  {"verbose", 'v', "Used with --help option for detailed help.",
 
6558
   (uchar**) &opt_verbose, (uchar**) &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
 
6559
   0, 0},
 
6560
  {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
 
6561
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
6562
  {"warnings", OPT_WARNINGS, "Deprecated; use --log-warnings instead.",
 
6563
   (uchar**) &global_system_variables.log_warnings,
 
6564
   (uchar**) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG,
 
6565
   1, 0, ULONG_MAX, 0, 0, 0},
 
6566
  { "back_log", OPT_BACK_LOG,
 
6567
    "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.",
 
6568
    (uchar**) &back_log, (uchar**) &back_log, 0, GET_ULONG,
 
6569
    REQUIRED_ARG, 50, 1, 65535, 0, 1, 0 },
 
6570
  {"binlog_cache_size", OPT_BINLOG_CACHE_SIZE,
 
6571
   "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.",
 
6572
   (uchar**) &binlog_cache_size, (uchar**) &binlog_cache_size, 0, GET_ULONG,
 
6573
   REQUIRED_ARG, 32*1024L, IO_SIZE, ULONG_MAX, 0, IO_SIZE, 0},
 
6574
  {"bulk_insert_buffer_size", OPT_BULK_INSERT_BUFFER_SIZE,
 
6575
   "Size of tree cache used in bulk insert optimization. Note that this is a limit per thread.",
 
6576
   (uchar**) &global_system_variables.bulk_insert_buff_size,
 
6577
   (uchar**) &max_system_variables.bulk_insert_buff_size,
 
6578
   0, GET_ULONG, REQUIRED_ARG, 8192*1024, 0, ULONG_MAX, 0, 1, 0},
 
6579
  {"connect_timeout", OPT_CONNECT_TIMEOUT,
 
6580
   "The number of seconds the mysqld server is waiting for a connect packet before responding with 'Bad handshake'.",
 
6581
    (uchar**) &connect_timeout, (uchar**) &connect_timeout,
 
6582
   0, GET_ULONG, REQUIRED_ARG, CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1, 0 },
 
6583
  { "date_format", OPT_DATE_FORMAT,
 
6584
    "The DATE format (for future).",
 
6585
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_DATE],
 
6586
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_DATE],
 
6587
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6588
  { "datetime_format", OPT_DATETIME_FORMAT,
 
6589
    "The DATETIME/TIMESTAMP format (for future).",
 
6590
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME],
 
6591
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME],
 
6592
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6593
  { "default_week_format", OPT_DEFAULT_WEEK_FORMAT,
 
6594
    "The default week format used by WEEK() functions.",
 
6595
    (uchar**) &global_system_variables.default_week_format,
 
6596
    (uchar**) &max_system_variables.default_week_format,
 
6597
    0, GET_ULONG, REQUIRED_ARG, 0, 0, 7L, 0, 1, 0},
 
6598
  {"delayed_insert_limit", OPT_DELAYED_INSERT_LIMIT,
 
6599
   "After inserting delayed_insert_limit rows, the INSERT DELAYED handler will check if there are any SELECT statements pending. If so, it allows these to execute before continuing.",
 
6600
    (uchar**) &delayed_insert_limit, (uchar**) &delayed_insert_limit, 0, GET_ULONG,
 
6601
    REQUIRED_ARG, DELAYED_LIMIT, 1, ULONG_MAX, 0, 1, 0},
 
6602
  {"delayed_insert_timeout", OPT_DELAYED_INSERT_TIMEOUT,
 
6603
   "How long a INSERT DELAYED thread should wait for INSERT statements before terminating.",
 
6604
   (uchar**) &delayed_insert_timeout, (uchar**) &delayed_insert_timeout, 0,
 
6605
   GET_ULONG, REQUIRED_ARG, DELAYED_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
 
6606
  { "delayed_queue_size", OPT_DELAYED_QUEUE_SIZE,
 
6607
    "What size queue (in rows) should be allocated for handling INSERT DELAYED. If the queue becomes full, any client that does INSERT DELAYED will wait until there is room in the queue again.",
 
6608
    (uchar**) &delayed_queue_size, (uchar**) &delayed_queue_size, 0, GET_ULONG,
 
6609
    REQUIRED_ARG, DELAYED_QUEUE_SIZE, 1, ULONG_MAX, 0, 1, 0},
 
6610
  {"div_precision_increment", OPT_DIV_PRECINCREMENT,
 
6611
   "Precision of the result of '/' operator will be increased on that value.",
 
6612
   (uchar**) &global_system_variables.div_precincrement,
 
6613
   (uchar**) &max_system_variables.div_precincrement, 0, GET_ULONG,
 
6614
   REQUIRED_ARG, 4, 0, DECIMAL_MAX_SCALE, 0, 0, 0},
 
6615
  {"expire_logs_days", OPT_EXPIRE_LOGS_DAYS,
 
6616
   "If non-zero, binary logs will be purged after expire_logs_days "
 
6617
   "days; possible purges happen at startup and at binary log rotation.",
 
6618
   (uchar**) &expire_logs_days,
 
6619
   (uchar**) &expire_logs_days, 0, GET_ULONG,
 
6620
   REQUIRED_ARG, 0, 0, 99, 0, 1, 0},
 
6621
  { "flush_time", OPT_FLUSH_TIME,
 
6622
    "A dedicated thread is created to flush all tables at the given interval.",
 
6623
    (uchar**) &flush_time, (uchar**) &flush_time, 0, GET_ULONG, REQUIRED_ARG,
 
6624
    FLUSH_TIME, 0, LONG_TIMEOUT, 0, 1, 0},
 
6625
  { "ft_boolean_syntax", OPT_FT_BOOLEAN_SYNTAX,
 
6626
    "List of operators for MATCH ... AGAINST ( ... IN BOOLEAN MODE).",
 
6627
    0, 0, 0, GET_STR,
 
6628
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6629
  { "ft_max_word_len", OPT_FT_MAX_WORD_LEN,
 
6630
    "The maximum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable.",
 
6631
    (uchar**) &ft_max_word_len, (uchar**) &ft_max_word_len, 0, GET_ULONG,
 
6632
    REQUIRED_ARG, HA_FT_MAXCHARLEN, 10, HA_FT_MAXCHARLEN, 0, 1, 0},
 
6633
  { "ft_min_word_len", OPT_FT_MIN_WORD_LEN,
 
6634
    "The minimum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable.",
 
6635
    (uchar**) &ft_min_word_len, (uchar**) &ft_min_word_len, 0, GET_ULONG,
 
6636
    REQUIRED_ARG, 4, 1, HA_FT_MAXCHARLEN, 0, 1, 0},
 
6637
  { "ft_query_expansion_limit", OPT_FT_QUERY_EXPANSION_LIMIT,
 
6638
    "Number of best matches to use for query expansion.",
 
6639
    (uchar**) &ft_query_expansion_limit, (uchar**) &ft_query_expansion_limit, 0, GET_ULONG,
 
6640
    REQUIRED_ARG, 20, 0, 1000, 0, 1, 0},
 
6641
  { "ft_stopword_file", OPT_FT_STOPWORD_FILE,
 
6642
    "Use stopwords from this file instead of built-in list.",
 
6643
    (uchar**) &ft_stopword_file, (uchar**) &ft_stopword_file, 0, GET_STR,
 
6644
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6645
  { "group_concat_max_len", OPT_GROUP_CONCAT_MAX_LEN,
 
6646
    "The maximum length of the result of function group_concat.",
 
6647
    (uchar**) &global_system_variables.group_concat_max_len,
 
6648
    (uchar**) &max_system_variables.group_concat_max_len, 0, GET_ULONG,
 
6649
    REQUIRED_ARG, 1024, 4, ULONG_MAX, 0, 1, 0},
 
6650
  {"interactive_timeout", OPT_INTERACTIVE_TIMEOUT,
 
6651
   "The number of seconds the server waits for activity on an interactive connection before closing it.",
 
6652
   (uchar**) &global_system_variables.net_interactive_timeout,
 
6653
   (uchar**) &max_system_variables.net_interactive_timeout, 0,
 
6654
   GET_ULONG, REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
 
6655
  {"join_buffer_size", OPT_JOIN_BUFF_SIZE,
 
6656
   "The size of the buffer that is used for full joins.",
 
6657
   (uchar**) &global_system_variables.join_buff_size,
 
6658
   (uchar**) &max_system_variables.join_buff_size, 0, GET_ULONG,
 
6659
   REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ULONG_MAX,
 
6660
   MALLOC_OVERHEAD, IO_SIZE, 0},
 
6661
  {"keep_files_on_create", OPT_KEEP_FILES_ON_CREATE,
 
6662
   "Don't overwrite stale .MYD and .MYI even if no directory is specified.",
 
6663
   (uchar**) &global_system_variables.keep_files_on_create,
 
6664
   (uchar**) &max_system_variables.keep_files_on_create,
 
6665
   0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
6666
  {"key_buffer_size", OPT_KEY_BUFFER_SIZE,
 
6667
   "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.",
 
6668
   (uchar**) &dflt_key_cache_var.param_buff_size,
 
6669
   (uchar**) 0,
 
6670
   0, (GET_ULL | GET_ASK_ADDR),
 
6671
   REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, SIZE_T_MAX, MALLOC_OVERHEAD,
 
6672
   IO_SIZE, 0},
 
6673
  {"key_cache_age_threshold", OPT_KEY_CACHE_AGE_THRESHOLD,
 
6674
   "This characterizes the number of hits a hot block has to be untouched "
 
6675
   "until it is considered aged enough to be downgraded to a warm block. "
 
6676
   "This specifies the percentage ratio of that number of hits to the total "
 
6677
   "number of blocks in key cache.",
 
6678
   (uchar**) &dflt_key_cache_var.param_age_threshold,
 
6679
   (uchar**) 0,
 
6680
   0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG, 
 
6681
   300, 100, ULONG_MAX, 0, 100, 0},
 
6682
  {"key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE,
 
6683
   "The default size of key cache blocks.",
 
6684
   (uchar**) &dflt_key_cache_var.param_block_size,
 
6685
   (uchar**) 0,
 
6686
   0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG,
 
6687
   KEY_CACHE_BLOCK_SIZE, 512, 1024 * 16, 0, 512, 0},
 
6688
  {"key_cache_division_limit", OPT_KEY_CACHE_DIVISION_LIMIT,
 
6689
   "The minimum percentage of warm blocks in key cache.",
 
6690
   (uchar**) &dflt_key_cache_var.param_division_limit,
 
6691
   (uchar**) 0,
 
6692
   0, (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100,
 
6693
   1, 100, 0, 1, 0},
 
6694
  {"long_query_time", OPT_LONG_QUERY_TIME,
 
6695
   "Log all queries that have taken more than long_query_time seconds to "
 
6696
   "execute. The argument will be treated as a decimal value with "
 
6697
   "microsecond precision.",
 
6698
   (uchar**) &long_query_time, (uchar**) &long_query_time, 0, GET_DOUBLE,
 
6699
   REQUIRED_ARG, 10, 0, LONG_TIMEOUT, 0, 0, 0},
 
6700
  {"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES,
 
6701
   "If set to 1, table names are stored in lowercase on disk and table names "
 
6702
   "will be case-insensitive.  Should be set to 2 if you are using a case-"
 
6703
   "insensitive file system.",
 
6704
   (uchar**) &lower_case_table_names,
 
6705
   (uchar**) &lower_case_table_names, 0, GET_UINT, OPT_ARG,
 
6706
#ifdef FN_NO_CASE_SENCE
 
6707
    1
 
6708
#else
 
6709
    0
 
6710
#endif
 
6711
   , 0, 2, 0, 1, 0},
 
6712
  {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
 
6713
   "The maximum packet length to send to or receive from server.",
 
6714
   (uchar**) &global_system_variables.max_allowed_packet,
 
6715
   (uchar**) &max_system_variables.max_allowed_packet, 0, GET_ULONG,
 
6716
   REQUIRED_ARG, 1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
 
6717
  {"max_binlog_cache_size", OPT_MAX_BINLOG_CACHE_SIZE,
 
6718
   "Can be used to restrict the total size used to cache a multi-transaction query.",
 
6719
   (uchar**) &max_binlog_cache_size, (uchar**) &max_binlog_cache_size, 0,
 
6720
   GET_ULL, REQUIRED_ARG, ULONG_MAX, IO_SIZE, ULONGLONG_MAX, 0, IO_SIZE, 0},
 
6721
  {"max_binlog_size", OPT_MAX_BINLOG_SIZE,
 
6722
   "Binary log will be rotated automatically when the size exceeds this \
 
6723
value. Will also apply to relay logs if max_relay_log_size is 0. \
 
6724
The minimum value for this variable is 4096.",
 
6725
   (uchar**) &max_binlog_size, (uchar**) &max_binlog_size, 0, GET_ULONG,
 
6726
   REQUIRED_ARG, 1024*1024L*1024L, IO_SIZE, 1024*1024L*1024L, 0, IO_SIZE, 0},
 
6727
  {"max_connect_errors", OPT_MAX_CONNECT_ERRORS,
 
6728
   "If there is more than this number of interrupted connections from a host this host will be blocked from further connections.",
 
6729
   (uchar**) &max_connect_errors, (uchar**) &max_connect_errors, 0, GET_ULONG,
 
6730
    REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ULONG_MAX, 0, 1, 0},
 
6731
  // Default max_connections of 151 is larger than Apache's default max
 
6732
  // children, to avoid "too many connections" error in a common setup
 
6733
  {"max_connections", OPT_MAX_CONNECTIONS,
 
6734
   "The number of simultaneous clients allowed.", (uchar**) &max_connections,
 
6735
   (uchar**) &max_connections, 0, GET_ULONG, REQUIRED_ARG, 151, 1, 100000, 0, 1,
 
6736
   0},
 
6737
  {"max_delayed_threads", OPT_MAX_DELAYED_THREADS,
 
6738
   "Don't start more than this number of threads to handle INSERT DELAYED statements. If set to zero, which means INSERT DELAYED is not used.",
 
6739
   (uchar**) &global_system_variables.max_insert_delayed_threads,
 
6740
   (uchar**) &max_system_variables.max_insert_delayed_threads,
 
6741
   0, GET_ULONG, REQUIRED_ARG, 20, 0, 16384, 0, 1, 0},
 
6742
  {"max_error_count", OPT_MAX_ERROR_COUNT,
 
6743
   "Max number of errors/warnings to store for a statement.",
 
6744
   (uchar**) &global_system_variables.max_error_count,
 
6745
   (uchar**) &max_system_variables.max_error_count,
 
6746
   0, GET_ULONG, REQUIRED_ARG, DEFAULT_ERROR_COUNT, 0, 65535, 0, 1, 0},
 
6747
  {"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE,
 
6748
   "Don't allow creation of heap tables bigger than this.",
 
6749
   (uchar**) &global_system_variables.max_heap_table_size,
 
6750
   (uchar**) &max_system_variables.max_heap_table_size, 0, GET_ULL,
 
6751
   REQUIRED_ARG, 16*1024*1024L, 16384, MAX_MEM_TABLE_SIZE,
 
6752
   MALLOC_OVERHEAD, 1024, 0},
 
6753
  {"max_join_size", OPT_MAX_JOIN_SIZE,
 
6754
   "Joins that are probably going to read more than max_join_size records return an error.",
 
6755
   (uchar**) &global_system_variables.max_join_size,
 
6756
   (uchar**) &max_system_variables.max_join_size, 0, GET_HA_ROWS, REQUIRED_ARG,
 
6757
   HA_POS_ERROR, 1, HA_POS_ERROR, 0, 1, 0},
 
6758
   {"max_length_for_sort_data", OPT_MAX_LENGTH_FOR_SORT_DATA,
 
6759
    "Max number of bytes in sorted records.",
 
6760
    (uchar**) &global_system_variables.max_length_for_sort_data,
 
6761
    (uchar**) &max_system_variables.max_length_for_sort_data, 0, GET_ULONG,
 
6762
    REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
 
6763
  {"max_prepared_stmt_count", OPT_MAX_PREPARED_STMT_COUNT,
 
6764
   "Maximum number of prepared statements in the server.",
 
6765
   (uchar**) &max_prepared_stmt_count, (uchar**) &max_prepared_stmt_count,
 
6766
   0, GET_ULONG, REQUIRED_ARG, 16382, 0, 1*1024*1024, 0, 1, 0},
 
6767
  {"max_relay_log_size", OPT_MAX_RELAY_LOG_SIZE,
 
6768
   "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.",
 
6769
   (uchar**) &max_relay_log_size, (uchar**) &max_relay_log_size, 0, GET_ULONG,
 
6770
   REQUIRED_ARG, 0L, 0L, 1024*1024L*1024L, 0, IO_SIZE, 0},
 
6771
  { "max_seeks_for_key", OPT_MAX_SEEKS_FOR_KEY,
 
6772
    "Limit assumed max number of seeks when looking up rows based on a key.",
 
6773
    (uchar**) &global_system_variables.max_seeks_for_key,
 
6774
    (uchar**) &max_system_variables.max_seeks_for_key, 0, GET_ULONG,
 
6775
    REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0 },
 
6776
  {"max_sort_length", OPT_MAX_SORT_LENGTH,
 
6777
   "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).",
 
6778
   (uchar**) &global_system_variables.max_sort_length,
 
6779
   (uchar**) &max_system_variables.max_sort_length, 0, GET_ULONG,
 
6780
   REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
 
6781
  {"max_sp_recursion_depth", OPT_MAX_SP_RECURSION_DEPTH,
 
6782
   "Maximum stored procedure recursion depth. (discussed with docs).",
 
6783
   (uchar**) &global_system_variables.max_sp_recursion_depth,
 
6784
   (uchar**) &max_system_variables.max_sp_recursion_depth, 0, GET_ULONG,
 
6785
   OPT_ARG, 0, 0, 255, 0, 1, 0 },
 
6786
  {"max_tmp_tables", OPT_MAX_TMP_TABLES,
 
6787
   "Maximum number of temporary tables a client can keep open at a time.",
 
6788
   (uchar**) &global_system_variables.max_tmp_tables,
 
6789
   (uchar**) &max_system_variables.max_tmp_tables, 0, GET_ULONG,
 
6790
   REQUIRED_ARG, 32, 1, ULONG_MAX, 0, 1, 0},
 
6791
  {"max_user_connections", OPT_MAX_USER_CONNECTIONS,
 
6792
   "The maximum number of active connections for a single user (0 = no limit).",
 
6793
   (uchar**) &max_user_connections, (uchar**) &max_user_connections, 0, GET_UINT,
 
6794
   REQUIRED_ARG, 0, 0, UINT_MAX, 0, 1, 0},
 
6795
  {"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
 
6796
   "After this many write locks, allow some read locks to run in between.",
 
6797
   (uchar**) &max_write_lock_count, (uchar**) &max_write_lock_count, 0, GET_ULONG,
 
6798
   REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0},
 
6799
  {"min_examined_row_limit", OPT_MIN_EXAMINED_ROW_LIMIT,
 
6800
   "Don't log queries which examine less than min_examined_row_limit rows to file.",
 
6801
   (uchar**) &global_system_variables.min_examined_row_limit,
 
6802
   (uchar**) &max_system_variables.min_examined_row_limit, 0, GET_ULONG,
 
6803
  REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1L, 0},
 
6804
  {"multi_range_count", OPT_MULTI_RANGE_COUNT,
 
6805
   "Number of key ranges to request at once.",
 
6806
   (uchar**) &global_system_variables.multi_range_count,
 
6807
   (uchar**) &max_system_variables.multi_range_count, 0,
 
6808
   GET_ULONG, REQUIRED_ARG, 256, 1, ULONG_MAX, 0, 1, 0},
 
6809
  {"myisam_block_size", OPT_MYISAM_BLOCK_SIZE,
 
6810
   "Block size to be used for MyISAM index pages.",
 
6811
   (uchar**) &opt_myisam_block_size,
 
6812
   (uchar**) &opt_myisam_block_size, 0, GET_ULONG, REQUIRED_ARG,
 
6813
   MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, MI_MAX_KEY_BLOCK_LENGTH,
 
6814
   0, MI_MIN_KEY_BLOCK_LENGTH, 0},
 
6815
  {"myisam_data_pointer_size", OPT_MYISAM_DATA_POINTER_SIZE,
 
6816
   "Default pointer size to be used for MyISAM tables.",
 
6817
   (uchar**) &myisam_data_pointer_size,
 
6818
   (uchar**) &myisam_data_pointer_size, 0, GET_ULONG, REQUIRED_ARG,
 
6819
   6, 2, 7, 0, 1, 0},
 
6820
  {"myisam_max_extra_sort_file_size", OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
 
6821
   "This is a deprecated option that does nothing anymore.  It will be removed in MySQL " 
 
6822
   VER_CELOSIA,
 
6823
   (uchar**) &global_system_variables.myisam_max_extra_sort_file_size,
 
6824
   (uchar**) &max_system_variables.myisam_max_extra_sort_file_size,
 
6825
   0, GET_ULL, REQUIRED_ARG, (ulonglong) MI_MAX_TEMP_LENGTH,
 
6826
   0, (ulonglong) MAX_FILE_SIZE, 0, 1, 0},
 
6827
  {"myisam_max_sort_file_size", OPT_MYISAM_MAX_SORT_FILE_SIZE,
 
6828
   "Don't use the fast sort index method to created index if the temporary file would get bigger than this.",
 
6829
   (uchar**) &global_system_variables.myisam_max_sort_file_size,
 
6830
   (uchar**) &max_system_variables.myisam_max_sort_file_size, 0,
 
6831
   GET_ULL, REQUIRED_ARG, (longlong) LONG_MAX, 0, (ulonglong) MAX_FILE_SIZE,
 
6832
   0, 1024*1024, 0},
 
6833
  {"myisam_mmap_size", OPT_MYISAM_MMAP_SIZE,
 
6834
   "Can be used to restrict the total memory used for memory mmaping of myisam files",
 
6835
   (uchar**) &myisam_mmap_size, (uchar**) &myisam_mmap_size, 0,
 
6836
   GET_ULL, REQUIRED_ARG, SIZE_T_MAX, MEMMAP_EXTRA_MARGIN, SIZE_T_MAX, 0, 1, 0},
 
6837
  {"myisam_repair_threads", OPT_MYISAM_REPAIR_THREADS,
 
6838
   "Number of threads to use when repairing MyISAM tables. The value of 1 disables parallel repair.",
 
6839
   (uchar**) &global_system_variables.myisam_repair_threads,
 
6840
   (uchar**) &max_system_variables.myisam_repair_threads, 0,
 
6841
   GET_ULONG, REQUIRED_ARG, 1, 1, ULONG_MAX, 0, 1, 0},
 
6842
  {"myisam_sort_buffer_size", OPT_MYISAM_SORT_BUFFER_SIZE,
 
6843
   "The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE.",
 
6844
   (uchar**) &global_system_variables.myisam_sort_buff_size,
 
6845
   (uchar**) &max_system_variables.myisam_sort_buff_size, 0,
 
6846
   GET_ULONG, REQUIRED_ARG, 8192*1024, 4, ~0L, 0, 1, 0},
 
6847
  {"myisam_use_mmap", OPT_MYISAM_USE_MMAP,
 
6848
   "Use memory mapping for reading and writing MyISAM tables.",
 
6849
   (uchar**) &opt_myisam_use_mmap,
 
6850
   (uchar**) &opt_myisam_use_mmap, 0, GET_BOOL, NO_ARG, 0, 
 
6851
    0, 0, 0, 0, 0},
 
6852
  {"myisam_stats_method", OPT_MYISAM_STATS_METHOD,
 
6853
   "Specifies how MyISAM index statistics collection code should threat NULLs. "
 
6854
   "Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), "
 
6855
   "\"nulls_equal\" (emulate 4.0 behavior), and \"nulls_ignored\".",
 
6856
   (uchar**) &myisam_stats_method_str, (uchar**) &myisam_stats_method_str, 0,
 
6857
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6858
  {"net_buffer_length", OPT_NET_BUFFER_LENGTH,
 
6859
   "Buffer length for TCP/IP and socket communication.",
 
6860
   (uchar**) &global_system_variables.net_buffer_length,
 
6861
   (uchar**) &max_system_variables.net_buffer_length, 0, GET_ULONG,
 
6862
   REQUIRED_ARG, 16384, 1024, 1024*1024L, 0, 1024, 0},
 
6863
  {"net_read_timeout", OPT_NET_READ_TIMEOUT,
 
6864
   "Number of seconds to wait for more data from a connection before aborting the read.",
 
6865
   (uchar**) &global_system_variables.net_read_timeout,
 
6866
   (uchar**) &max_system_variables.net_read_timeout, 0, GET_ULONG,
 
6867
   REQUIRED_ARG, NET_READ_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
 
6868
  {"net_retry_count", OPT_NET_RETRY_COUNT,
 
6869
   "If a read on a communication port is interrupted, retry this many times before giving up.",
 
6870
   (uchar**) &global_system_variables.net_retry_count,
 
6871
   (uchar**) &max_system_variables.net_retry_count,0,
 
6872
   GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, ULONG_MAX, 0, 1, 0},
 
6873
  {"net_write_timeout", OPT_NET_WRITE_TIMEOUT,
 
6874
   "Number of seconds to wait for a block to be written to a connection before "
 
6875
   "aborting the write.",
 
6876
   (uchar**) &global_system_variables.net_write_timeout,
 
6877
   (uchar**) &max_system_variables.net_write_timeout, 0, GET_ULONG,
 
6878
   REQUIRED_ARG, NET_WRITE_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
 
6879
  { "old", OPT_OLD_MODE, "Use compatible behavior.", 
 
6880
    (uchar**) &global_system_variables.old_mode,
 
6881
    (uchar**) &max_system_variables.old_mode, 0, GET_BOOL, NO_ARG, 
 
6882
    0, 0, 0, 0, 0, 0},
 
6883
  {"open_files_limit", OPT_OPEN_FILES_LIMIT,
 
6884
   "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.",
 
6885
   (uchar**) &open_files_limit, (uchar**) &open_files_limit, 0, GET_ULONG,
 
6886
   REQUIRED_ARG, 0, 0, OS_FILE_LIMIT, 0, 1, 0},
 
6887
  {"optimizer_prune_level", OPT_OPTIMIZER_PRUNE_LEVEL,
 
6888
   "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.",
 
6889
   (uchar**) &global_system_variables.optimizer_prune_level,
 
6890
   (uchar**) &max_system_variables.optimizer_prune_level,
 
6891
   0, GET_ULONG, OPT_ARG, 1, 0, 1, 0, 1, 0},
 
6892
  {"optimizer_search_depth", OPT_OPTIMIZER_SEARCH_DEPTH,
 
6893
   "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).",
 
6894
   (uchar**) &global_system_variables.optimizer_search_depth,
 
6895
   (uchar**) &max_system_variables.optimizer_search_depth,
 
6896
   0, GET_ULONG, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0},
 
6897
  {"optimizer_switch", OPT_OPTIMIZER_SWITCH,
 
6898
   "optimizer_switch=option=val[,option=val...], where option={index_merge, "
 
6899
   "index_merge_union, index_merge_sort_union, index_merge_intersection} and "
 
6900
   "val={on, off, default}.",
 
6901
   (uchar**) &optimizer_switch_str, (uchar**) &optimizer_switch_str, 0, GET_STR, REQUIRED_ARG, 
 
6902
   /*OPTIMIZER_SWITCH_DEFAULT*/0,
 
6903
   0, 0, 0, 0, 0},
 
6904
  {"plugin_dir", OPT_PLUGIN_DIR,
 
6905
   "Directory for plugins.",
 
6906
   (uchar**) &opt_plugin_dir_ptr, (uchar**) &opt_plugin_dir_ptr, 0,
 
6907
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6908
  {"plugin-load", OPT_PLUGIN_LOAD,
 
6909
   "Optional semicolon-separated list of plugins to load, where each plugin is "
 
6910
   "identified as name=library, where name is the plugin name and library "
 
6911
   "is the plugin library in plugin_dir.",
 
6912
   (uchar**) &opt_plugin_load, (uchar**) &opt_plugin_load, 0,
 
6913
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
6914
  {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
 
6915
   "The size of the buffer that is allocated when preloading indexes.",
 
6916
   (uchar**) &global_system_variables.preload_buff_size,
 
6917
   (uchar**) &max_system_variables.preload_buff_size, 0, GET_ULONG,
 
6918
   REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0},
 
6919
  {"query_alloc_block_size", OPT_QUERY_ALLOC_BLOCK_SIZE,
 
6920
   "Allocation block size for query parsing and execution.",
 
6921
   (uchar**) &global_system_variables.query_alloc_block_size,
 
6922
   (uchar**) &max_system_variables.query_alloc_block_size, 0, GET_ULONG,
 
6923
   REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
 
6924
#ifdef HAVE_QUERY_CACHE
 
6925
  {"query_cache_limit", OPT_QUERY_CACHE_LIMIT,
 
6926
   "Don't cache results that are bigger than this.",
 
6927
   (uchar**) &query_cache_limit, (uchar**) &query_cache_limit, 0, GET_ULONG,
 
6928
   REQUIRED_ARG, 1024*1024L, 0, ULONG_MAX, 0, 1, 0},
 
6929
  {"query_cache_min_res_unit", OPT_QUERY_CACHE_MIN_RES_UNIT,
 
6930
   "Minimal size of unit in which space for results is allocated (last unit "
 
6931
   "will be trimmed after writing all result data).",
 
6932
   (uchar**) &query_cache_min_res_unit, (uchar**) &query_cache_min_res_unit,
 
6933
   0, GET_ULONG, REQUIRED_ARG, QUERY_CACHE_MIN_RESULT_DATA_SIZE,
 
6934
   0, ULONG_MAX, 0, 1, 0},
 
6935
#endif /*HAVE_QUERY_CACHE*/
 
6936
  {"query_cache_size", OPT_QUERY_CACHE_SIZE,
 
6937
   "The memory allocated to store results from old queries.",
 
6938
   (uchar**) &query_cache_size, (uchar**) &query_cache_size, 0, GET_ULONG,
 
6939
   REQUIRED_ARG, 0, 0, (longlong) ULONG_MAX, 0, 1024, 0},
 
6940
#ifdef HAVE_QUERY_CACHE
 
6941
  {"query_cache_type", OPT_QUERY_CACHE_TYPE,
 
6942
   "0 = OFF = Don't cache or retrieve results. 1 = ON = Cache all results except SELECT SQL_NO_CACHE ... queries. 2 = DEMAND = Cache only SELECT SQL_CACHE ... queries.",
 
6943
   (uchar**) &global_system_variables.query_cache_type,
 
6944
   (uchar**) &max_system_variables.query_cache_type,
 
6945
   0, GET_ULONG, REQUIRED_ARG, 1, 0, 2, 0, 1, 0},
 
6946
  {"query_cache_wlock_invalidate", OPT_QUERY_CACHE_WLOCK_INVALIDATE,
 
6947
   "Invalidate queries in query cache on LOCK for write.",
 
6948
   (uchar**) &global_system_variables.query_cache_wlock_invalidate,
 
6949
   (uchar**) &max_system_variables.query_cache_wlock_invalidate,
 
6950
   0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
 
6951
#endif /*HAVE_QUERY_CACHE*/
 
6952
  {"query_prealloc_size", OPT_QUERY_PREALLOC_SIZE,
 
6953
   "Persistent buffer for query parsing and execution.",
 
6954
   (uchar**) &global_system_variables.query_prealloc_size,
 
6955
   (uchar**) &max_system_variables.query_prealloc_size, 0, GET_ULONG,
 
6956
   REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, QUERY_ALLOC_PREALLOC_SIZE,
 
6957
   ULONG_MAX, 0, 1024, 0},
 
6958
  {"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE,
 
6959
   "Allocation block size for storing ranges during optimization.",
 
6960
   (uchar**) &global_system_variables.range_alloc_block_size,
 
6961
   (uchar**) &max_system_variables.range_alloc_block_size, 0, GET_ULONG,
 
6962
   REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, ULONG_MAX,
 
6963
   0, 1024, 0},
 
6964
  {"read_buffer_size", OPT_RECORD_BUFFER,
 
6965
   "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.",
 
6966
   (uchar**) &global_system_variables.read_buff_size,
 
6967
   (uchar**) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
 
6968
   128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, INT_MAX32, MALLOC_OVERHEAD, IO_SIZE,
 
6969
   0},
 
6970
  {"read_only", OPT_READONLY,
 
6971
   "Make all non-temporary tables read-only, with the exception of replication "
 
6972
   "(slave) threads and users with the SUPER privilege.",
 
6973
   (uchar**) &opt_readonly,
 
6974
   (uchar**) &opt_readonly,
 
6975
   0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
 
6976
  {"read_rnd_buffer_size", OPT_RECORD_RND_BUFFER,
 
6977
   "When reading rows in sorted order after a sort, the rows are read through "
 
6978
   "this buffer to avoid disk seeks. If not set, then it's set to the value of "
 
6979
   "record_buffer.",
 
6980
   (uchar**) &global_system_variables.read_rnd_buff_size,
 
6981
   (uchar**) &max_system_variables.read_rnd_buff_size, 0,
 
6982
   GET_ULONG, REQUIRED_ARG, 256*1024L, IO_SIZE*2+MALLOC_OVERHEAD,
 
6983
   INT_MAX32, MALLOC_OVERHEAD, IO_SIZE, 0},
 
6984
  {"record_buffer", OPT_RECORD_BUFFER_OLD,
 
6985
   "Alias for read_buffer_size. This variable is deprecated and will be removed in a future release.",
 
6986
   (uchar**) &global_system_variables.read_buff_size,
 
6987
   (uchar**) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
 
6988
   128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, INT_MAX32, MALLOC_OVERHEAD, IO_SIZE, 0},
 
6989
#ifdef HAVE_REPLICATION
 
6990
  {"relay_log_purge", OPT_RELAY_LOG_PURGE,
 
6991
   "0 = do not purge relay logs. 1 = purge them as soon as they are no more needed.",
 
6992
   (uchar**) &relay_log_purge,
 
6993
   (uchar**) &relay_log_purge, 0, GET_BOOL, NO_ARG,
 
6994
   1, 0, 1, 0, 1, 0},
 
6995
  {"relay_log_space_limit", OPT_RELAY_LOG_SPACE_LIMIT,
 
6996
   "Maximum space to use for all relay logs.",
 
6997
   (uchar**) &relay_log_space_limit,
 
6998
   (uchar**) &relay_log_space_limit, 0, GET_ULL, REQUIRED_ARG, 0L, 0L,
 
6999
   (longlong) ULONG_MAX, 0, 1, 0},
 
7000
  {"slave_compressed_protocol", OPT_SLAVE_COMPRESSED_PROTOCOL,
 
7001
   "Use compression on master/slave protocol.",
 
7002
   (uchar**) &opt_slave_compressed_protocol,
 
7003
   (uchar**) &opt_slave_compressed_protocol,
 
7004
   0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
 
7005
  {"slave_net_timeout", OPT_SLAVE_NET_TIMEOUT,
 
7006
   "Number of seconds to wait for more data from a master/slave connection before aborting the read.",
 
7007
   (uchar**) &slave_net_timeout, (uchar**) &slave_net_timeout, 0,
 
7008
   GET_ULONG, REQUIRED_ARG, SLAVE_NET_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
 
7009
  {"slave_transaction_retries", OPT_SLAVE_TRANS_RETRIES,
 
7010
   "Number of times the slave SQL thread will retry a transaction in case "
 
7011
   "it failed with a deadlock or elapsed lock wait timeout, "
 
7012
   "before giving up and stopping.",
 
7013
   (uchar**) &slave_trans_retries, (uchar**) &slave_trans_retries, 0,
 
7014
   GET_ULONG, REQUIRED_ARG, 10L, 0L, (longlong) ULONG_MAX, 0, 1, 0},
 
7015
#endif /* HAVE_REPLICATION */
 
7016
  {"slow_launch_time", OPT_SLOW_LAUNCH_TIME,
 
7017
   "If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented.",
 
7018
   (uchar**) &slow_launch_time, (uchar**) &slow_launch_time, 0, GET_ULONG,
 
7019
   REQUIRED_ARG, 2L, 0L, LONG_TIMEOUT, 0, 1, 0},
 
7020
  {"sort_buffer_size", OPT_SORT_BUFFER,
 
7021
   "Each thread that needs to do a sort allocates a buffer of this size.",
 
7022
   (uchar**) &global_system_variables.sortbuff_size,
 
7023
   (uchar**) &max_system_variables.sortbuff_size, 0, GET_ULONG, REQUIRED_ARG,
 
7024
   MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, ~0L, MALLOC_OVERHEAD,
 
7025
   1, 0},
 
7026
  {"sync-binlog", OPT_SYNC_BINLOG,
 
7027
   "Synchronously flush binary log to disk after every #th event. "
 
7028
   "Use 0 (default) to disable synchronous flushing.",
 
7029
   (uchar**) &sync_binlog_period, (uchar**) &sync_binlog_period, 0, GET_ULONG,
 
7030
   REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1, 0},
 
7031
  {"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default.",
 
7032
   (uchar**) &opt_sync_frm, (uchar**) &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0,
 
7033
   0, 0, 0, 0},
 
7034
  {"table_cache", OPT_TABLE_OPEN_CACHE,
 
7035
   "Deprecated; use --table_open_cache instead.",
 
7036
   (uchar**) &table_cache_size, (uchar**) &table_cache_size, 0, GET_ULONG,
 
7037
   REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
 
7038
  {"table_definition_cache", OPT_TABLE_DEF_CACHE,
 
7039
   "The number of cached table definitions.",
 
7040
   (uchar**) &table_def_size, (uchar**) &table_def_size,
 
7041
   0, GET_ULONG, REQUIRED_ARG, TABLE_DEF_CACHE_DEFAULT, TABLE_DEF_CACHE_MIN,
 
7042
   512*1024L, 0, 1, 0},
 
7043
  {"table_open_cache", OPT_TABLE_OPEN_CACHE,
 
7044
   "The number of cached open tables.",
 
7045
   (uchar**) &table_cache_size, (uchar**) &table_cache_size, 0, GET_ULONG,
 
7046
   REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
 
7047
  {"table_lock_wait_timeout", OPT_TABLE_LOCK_WAIT_TIMEOUT,
 
7048
   "Timeout in seconds to wait for a table level lock before returning an "
 
7049
   "error. Used only if the connection has active cursors.",
 
7050
   (uchar**) &table_lock_wait_timeout, (uchar**) &table_lock_wait_timeout,
 
7051
   0, GET_ULONG, REQUIRED_ARG, 50, 1, 1024 * 1024 * 1024, 0, 1, 0},
 
7052
  {"thread_cache_size", OPT_THREAD_CACHE_SIZE,
 
7053
   "How many threads we should keep in a cache for reuse.",
 
7054
   (uchar**) &thread_cache_size, (uchar**) &thread_cache_size, 0, GET_ULONG,
 
7055
   REQUIRED_ARG, 0, 0, 16384, 0, 1, 0},
 
7056
  {"thread_concurrency", OPT_THREAD_CONCURRENCY,
 
7057
   "Permits the application to give the threads system a hint for the desired number of threads that should be run at the same time.",
 
7058
   (uchar**) &concurrency, (uchar**) &concurrency, 0, GET_ULONG, REQUIRED_ARG,
 
7059
   DEFAULT_CONCURRENCY, 1, 512, 0, 1, 0},
 
7060
#if HAVE_POOL_OF_THREADS == 1
 
7061
  {"thread_pool_size", OPT_THREAD_CACHE_SIZE,
 
7062
   "How many threads we should create to handle query requests in case of "
 
7063
   "'thread_handling=pool-of-threads'.",
 
7064
   (uchar**) &thread_pool_size, (uchar**) &thread_pool_size, 0, GET_ULONG,
 
7065
   REQUIRED_ARG, 20, 1, 16384, 0, 1, 0},
 
7066
#endif
 
7067
  {"thread_stack", OPT_THREAD_STACK,
 
7068
   "The stack size for each thread.", (uchar**) &my_thread_stack_size,
 
7069
   (uchar**) &my_thread_stack_size, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK,
 
7070
   1024L*128L, ULONG_MAX, 0, 1024, 0},
 
7071
  { "time_format", OPT_TIME_FORMAT,
 
7072
    "The TIME format (for future).",
 
7073
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_TIME],
 
7074
    (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_TIME],
 
7075
    0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
7076
  {"tmp_table_size", OPT_TMP_TABLE_SIZE,
 
7077
   "If an internal in-memory temporary table exceeds this size, MySQL will"
 
7078
   " automatically convert it to an on-disk MyISAM table.",
 
7079
   (uchar**) &global_system_variables.tmp_table_size,
 
7080
   (uchar**) &max_system_variables.tmp_table_size, 0, GET_ULL,
 
7081
   REQUIRED_ARG, 16*1024*1024L, 1024, MAX_MEM_TABLE_SIZE, 0, 1, 0},
 
7082
  {"transaction_alloc_block_size", OPT_TRANS_ALLOC_BLOCK_SIZE,
 
7083
   "Allocation block size for transactions to be stored in binary log.",
 
7084
   (uchar**) &global_system_variables.trans_alloc_block_size,
 
7085
   (uchar**) &max_system_variables.trans_alloc_block_size, 0, GET_ULONG,
 
7086
   REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
 
7087
  {"transaction_prealloc_size", OPT_TRANS_PREALLOC_SIZE,
 
7088
   "Persistent buffer for transactions to be stored in binary log.",
 
7089
   (uchar**) &global_system_variables.trans_prealloc_size,
 
7090
   (uchar**) &max_system_variables.trans_prealloc_size, 0, GET_ULONG,
 
7091
   REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
 
7092
  {"thread_handling", OPT_THREAD_HANDLING,
 
7093
   "Define threads usage for handling queries: "
 
7094
   "one-thread-per-connection or no-threads.", 0, 0,
 
7095
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
7096
  {"updatable_views_with_limit", OPT_UPDATABLE_VIEWS_WITH_LIMIT,
 
7097
   "1 = YES = Don't issue an error message (warning only) if a VIEW without presence of a key of the underlying table is used in queries with a LIMIT clause for updating. 0 = NO = Prohibit update of a VIEW, which does not contain a key of the underlying table and the query uses a LIMIT clause (usually get from GUI tools).",
 
7098
   (uchar**) &global_system_variables.updatable_views_with_limit,
 
7099
   (uchar**) &max_system_variables.updatable_views_with_limit,
 
7100
   0, GET_ULONG, REQUIRED_ARG, 1, 0, 1, 0, 1, 0},
 
7101
  {"wait_timeout", OPT_WAIT_TIMEOUT,
 
7102
   "The number of seconds the server waits for activity on a connection before closing it.",
 
7103
   (uchar**) &global_system_variables.net_wait_timeout,
 
7104
   (uchar**) &max_system_variables.net_wait_timeout, 0, GET_ULONG,
 
7105
   REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT),
 
7106
   0, 1, 0},
 
7107
  {"binlog-direct-non-transactional-updates", OPT_BINLOG_DIRECT_NON_TRANS_UPDATE,
 
7108
   "Causes updates to non-transactional engines using statement format to be "
 
7109
   "written directly to binary log. Before using this option, make sure that "
 
7110
   "there are no dependencies between transactional and non-transactional "
 
7111
   "tables such as in the statement INSERT INTO t_myisam SELECT * FROM "
 
7112
   "t_innodb; otherwise, slaves may diverge from the master.",
 
7113
   (uchar**) &global_system_variables.binlog_direct_non_trans_update, (uchar**) &max_system_variables.binlog_direct_non_trans_update, 0, GET_BOOL, NO_ARG, 0,
 
7114
    0, 0, 0, 0, 0},
 
7115
  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 
7116
};
 
7117
 
 
7118
 
 
7119
static int show_queries(THD *thd, SHOW_VAR *var, char *buff)
 
7120
{
 
7121
  var->type= SHOW_LONGLONG;
 
7122
  var->value= (char *)&thd->query_id;
 
7123
  return 0;
 
7124
}
 
7125
 
 
7126
 
 
7127
static int show_net_compression(THD *thd, SHOW_VAR *var, char *buff)
 
7128
{
 
7129
  var->type= SHOW_MY_BOOL;
 
7130
  var->value= (char *)&thd->net.compress;
 
7131
  return 0;
 
7132
}
 
7133
 
 
7134
static int show_starttime(THD *thd, SHOW_VAR *var, char *buff)
 
7135
{
 
7136
  var->type= SHOW_LONG;
 
7137
  var->value= buff;
 
7138
  *((long *)buff)= (long) (thd->query_start() - server_start_time);
 
7139
  return 0;
 
7140
}
 
7141
 
 
7142
#ifdef COMMUNITY_SERVER
 
7143
static int show_flushstatustime(THD *thd, SHOW_VAR *var, char *buff)
 
7144
{
 
7145
  var->type= SHOW_LONG;
 
7146
  var->value= buff;
 
7147
  *((long *)buff)= (long) (thd->query_start() - flush_status_time);
 
7148
  return 0;
 
7149
}
 
7150
#endif
 
7151
 
 
7152
#ifdef HAVE_REPLICATION
 
7153
static int show_rpl_status(THD *thd, SHOW_VAR *var, char *buff)
 
7154
{
 
7155
  var->type= SHOW_CHAR;
 
7156
  var->value= const_cast<char*>(rpl_status_type[(int)rpl_status]);
 
7157
  return 0;
 
7158
}
 
7159
 
 
7160
static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff)
 
7161
{
 
7162
  var->type= SHOW_MY_BOOL;
 
7163
  pthread_mutex_lock(&LOCK_active_mi);
 
7164
  var->value= buff;
 
7165
  *((my_bool *)buff)= (my_bool) (active_mi && active_mi->slave_running &&
 
7166
                                 active_mi->rli.slave_running);
 
7167
  pthread_mutex_unlock(&LOCK_active_mi);
 
7168
  return 0;
 
7169
}
 
7170
 
 
7171
static int show_slave_retried_trans(THD *thd, SHOW_VAR *var, char *buff)
 
7172
{
 
7173
  /*
 
7174
    TODO: with multimaster, have one such counter per line in
 
7175
    SHOW SLAVE STATUS, and have the sum over all lines here.
 
7176
  */
 
7177
  pthread_mutex_lock(&LOCK_active_mi);
 
7178
  if (active_mi)
 
7179
  {
 
7180
    var->type= SHOW_LONG;
 
7181
    var->value= buff;
 
7182
    pthread_mutex_lock(&active_mi->rli.data_lock);
 
7183
    *((long *)buff)= (long)active_mi->rli.retried_trans;
 
7184
    pthread_mutex_unlock(&active_mi->rli.data_lock);
 
7185
  }
 
7186
  else
 
7187
    var->type= SHOW_UNDEF;
 
7188
  pthread_mutex_unlock(&LOCK_active_mi);
 
7189
  return 0;
 
7190
}
 
7191
#endif /* HAVE_REPLICATION */
 
7192
 
 
7193
static int show_open_tables(THD *thd, SHOW_VAR *var, char *buff)
 
7194
{
 
7195
  var->type= SHOW_LONG;
 
7196
  var->value= buff;
 
7197
  *((long *)buff)= (long)cached_open_tables();
 
7198
  return 0;
 
7199
}
 
7200
 
 
7201
static int show_prepared_stmt_count(THD *thd, SHOW_VAR *var, char *buff)
 
7202
{
 
7203
  var->type= SHOW_LONG;
 
7204
  var->value= buff;
 
7205
  pthread_mutex_lock(&LOCK_prepared_stmt_count);
 
7206
  *((long *)buff)= (long)prepared_stmt_count;
 
7207
  pthread_mutex_unlock(&LOCK_prepared_stmt_count);
 
7208
  return 0;
 
7209
}
 
7210
 
 
7211
static int show_table_definitions(THD *thd, SHOW_VAR *var, char *buff)
 
7212
{
 
7213
  var->type= SHOW_LONG;
 
7214
  var->value= buff;
 
7215
  *((long *)buff)= (long)cached_table_definitions();
 
7216
  return 0;
 
7217
}
 
7218
 
 
7219
#ifdef HAVE_OPENSSL
 
7220
/* Functions relying on CTX */
 
7221
static int show_ssl_ctx_sess_accept(THD *thd, SHOW_VAR *var, char *buff)
 
7222
{
 
7223
  var->type= SHOW_LONG;
 
7224
  var->value= buff;
 
7225
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
 
7226
                     SSL_CTX_sess_accept(ssl_acceptor_fd->ssl_context));
 
7227
  return 0;
 
7228
}
 
7229
 
 
7230
static int show_ssl_ctx_sess_accept_good(THD *thd, SHOW_VAR *var, char *buff)
 
7231
{
 
7232
  var->type= SHOW_LONG;
 
7233
  var->value= buff;
 
7234
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
 
7235
                     SSL_CTX_sess_accept_good(ssl_acceptor_fd->ssl_context));
 
7236
  return 0;
 
7237
}
 
7238
 
 
7239
static int show_ssl_ctx_sess_connect_good(THD *thd, SHOW_VAR *var, char *buff)
 
7240
{
 
7241
  var->type= SHOW_LONG;
 
7242
  var->value= buff;
 
7243
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
 
7244
                     SSL_CTX_sess_connect_good(ssl_acceptor_fd->ssl_context));
 
7245
  return 0;
 
7246
}
 
7247
 
 
7248
static int show_ssl_ctx_sess_accept_renegotiate(THD *thd, SHOW_VAR *var, char *buff)
 
7249
{
 
7250
  var->type= SHOW_LONG;
 
7251
  var->value= buff;
 
7252
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
 
7253
                     SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context));
 
7254
  return 0;
 
7255
}
 
7256
 
 
7257
static int show_ssl_ctx_sess_connect_renegotiate(THD *thd, SHOW_VAR *var, char *buff)
 
7258
{
 
7259
  var->type= SHOW_LONG;
 
7260
  var->value= buff;
 
7261
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
 
7262
                     SSL_CTX_sess_connect_renegotiate(ssl_acceptor_fd->ssl_context));
 
7263
  return 0;
 
7264
}
 
7265
 
 
7266
static int show_ssl_ctx_sess_cb_hits(THD *thd, SHOW_VAR *var, char *buff)
 
7267
{
 
7268
  var->type= SHOW_LONG;
 
7269
  var->value= buff;
 
7270
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
 
7271
                     SSL_CTX_sess_cb_hits(ssl_acceptor_fd->ssl_context));
 
7272
  return 0;
 
7273
}
 
7274
 
 
7275
static int show_ssl_ctx_sess_hits(THD *thd, SHOW_VAR *var, char *buff)
 
7276
{
 
7277
  var->type= SHOW_LONG;
 
7278
  var->value= buff;
 
7279
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
 
7280
                     SSL_CTX_sess_hits(ssl_acceptor_fd->ssl_context));
 
7281
  return 0;
 
7282
}
 
7283
 
 
7284
static int show_ssl_ctx_sess_cache_full(THD *thd, SHOW_VAR *var, char *buff)
 
7285
{
 
7286
  var->type= SHOW_LONG;
 
7287
  var->value= buff;
 
7288
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
 
7289
                     SSL_CTX_sess_cache_full(ssl_acceptor_fd->ssl_context));
 
7290
  return 0;
 
7291
}
 
7292
 
 
7293
static int show_ssl_ctx_sess_misses(THD *thd, SHOW_VAR *var, char *buff)
 
7294
{
 
7295
  var->type= SHOW_LONG;
 
7296
  var->value= buff;
 
7297
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
 
7298
                     SSL_CTX_sess_misses(ssl_acceptor_fd->ssl_context));
 
7299
  return 0;
 
7300
}
 
7301
 
 
7302
static int show_ssl_ctx_sess_timeouts(THD *thd, SHOW_VAR *var, char *buff)
 
7303
{
 
7304
  var->type= SHOW_LONG;
 
7305
  var->value= buff;
 
7306
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
 
7307
                     SSL_CTX_sess_timeouts(ssl_acceptor_fd->ssl_context));
 
7308
  return 0;
 
7309
}
 
7310
 
 
7311
static int show_ssl_ctx_sess_number(THD *thd, SHOW_VAR *var, char *buff)
 
7312
{
 
7313
  var->type= SHOW_LONG;
 
7314
  var->value= buff;
 
7315
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
 
7316
                     SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context));
 
7317
  return 0;
 
7318
}
 
7319
 
 
7320
static int show_ssl_ctx_sess_connect(THD *thd, SHOW_VAR *var, char *buff)
 
7321
{
 
7322
  var->type= SHOW_LONG;
 
7323
  var->value= buff;
 
7324
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
 
7325
                     SSL_CTX_sess_connect(ssl_acceptor_fd->ssl_context));
 
7326
  return 0;
 
7327
}
 
7328
 
 
7329
static int show_ssl_ctx_sess_get_cache_size(THD *thd, SHOW_VAR *var, char *buff)
 
7330
{
 
7331
  var->type= SHOW_LONG;
 
7332
  var->value= buff;
 
7333
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
 
7334
                     SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context));
 
7335
  return 0;
 
7336
}
 
7337
 
 
7338
static int show_ssl_ctx_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff)
 
7339
{
 
7340
  var->type= SHOW_LONG;
 
7341
  var->value= buff;
 
7342
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
 
7343
                     SSL_CTX_get_verify_mode(ssl_acceptor_fd->ssl_context));
 
7344
  return 0;
 
7345
}
 
7346
 
 
7347
static int show_ssl_ctx_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff)
 
7348
{
 
7349
  var->type= SHOW_LONG;
 
7350
  var->value= buff;
 
7351
  *((long *)buff)= (!ssl_acceptor_fd ? 0 :
 
7352
                     SSL_CTX_get_verify_depth(ssl_acceptor_fd->ssl_context));
 
7353
  return 0;
 
7354
}
 
7355
 
 
7356
static int show_ssl_ctx_get_session_cache_mode(THD *thd, SHOW_VAR *var, char *buff)
 
7357
{
 
7358
  var->type= SHOW_CHAR;
 
7359
  if (!ssl_acceptor_fd)
 
7360
    var->value= const_cast<char*>("NONE");
 
7361
  else
 
7362
    switch (SSL_CTX_get_session_cache_mode(ssl_acceptor_fd->ssl_context))
 
7363
    {
 
7364
    case SSL_SESS_CACHE_OFF:
 
7365
      var->value= const_cast<char*>("OFF"); break;
 
7366
    case SSL_SESS_CACHE_CLIENT:
 
7367
      var->value= const_cast<char*>("CLIENT"); break;
 
7368
    case SSL_SESS_CACHE_SERVER:
 
7369
      var->value= const_cast<char*>("SERVER"); break;
 
7370
    case SSL_SESS_CACHE_BOTH:
 
7371
      var->value= const_cast<char*>("BOTH"); break;
 
7372
    case SSL_SESS_CACHE_NO_AUTO_CLEAR:
 
7373
      var->value= const_cast<char*>("NO_AUTO_CLEAR"); break;
 
7374
    case SSL_SESS_CACHE_NO_INTERNAL_LOOKUP:
 
7375
      var->value= const_cast<char*>("NO_INTERNAL_LOOKUP"); break;
 
7376
    default:
 
7377
      var->value= const_cast<char*>("Unknown"); break;
 
7378
    }
 
7379
  return 0;
 
7380
}
 
7381
 
 
7382
/*
 
7383
   Functions relying on SSL 
 
7384
   Note: In the show_ssl_* functions, we need to check if we have a
 
7385
         valid vio-object since this isn't always true, specifically
 
7386
         when session_status or global_status is requested from
 
7387
         inside an Event.
 
7388
 */
 
7389
static int show_ssl_get_version(THD *thd, SHOW_VAR *var, char *buff)
 
7390
{
 
7391
  var->type= SHOW_CHAR;
 
7392
  if( thd->vio_ok() && thd->net.vio->ssl_arg )
 
7393
    var->value= const_cast<char*>(SSL_get_version((SSL*) thd->net.vio->ssl_arg));
 
7394
  else
 
7395
    var->value= (char *)"";
 
7396
  return 0;
 
7397
}
 
7398
 
 
7399
static int show_ssl_session_reused(THD *thd, SHOW_VAR *var, char *buff)
 
7400
{
 
7401
  var->type= SHOW_LONG;
 
7402
  var->value= buff;
 
7403
  if( thd->vio_ok() && thd->net.vio->ssl_arg )
 
7404
    *((long *)buff)= (long)SSL_session_reused((SSL*) thd->net.vio->ssl_arg);
 
7405
  else
 
7406
    *((long *)buff)= 0;
 
7407
  return 0;
 
7408
}
 
7409
 
 
7410
static int show_ssl_get_default_timeout(THD *thd, SHOW_VAR *var, char *buff)
 
7411
{
 
7412
  var->type= SHOW_LONG;
 
7413
  var->value= buff;
 
7414
  if( thd->vio_ok() && thd->net.vio->ssl_arg )
 
7415
    *((long *)buff)= (long)SSL_get_default_timeout((SSL*)thd->net.vio->ssl_arg);
 
7416
  else
 
7417
    *((long *)buff)= 0;
 
7418
  return 0;
 
7419
}
 
7420
 
 
7421
static int show_ssl_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff)
 
7422
{
 
7423
  var->type= SHOW_LONG;
 
7424
  var->value= buff;
 
7425
  if( thd->net.vio && thd->net.vio->ssl_arg )
 
7426
    *((long *)buff)= (long)SSL_get_verify_mode((SSL*)thd->net.vio->ssl_arg);
 
7427
  else
 
7428
    *((long *)buff)= 0;
 
7429
  return 0;
 
7430
}
 
7431
 
 
7432
static int show_ssl_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff)
 
7433
{
 
7434
  var->type= SHOW_LONG;
 
7435
  var->value= buff;
 
7436
  if( thd->vio_ok() && thd->net.vio->ssl_arg )
 
7437
    *((long *)buff)= (long)SSL_get_verify_depth((SSL*)thd->net.vio->ssl_arg);
 
7438
  else
 
7439
    *((long *)buff)= 0;
 
7440
  return 0;
 
7441
}
 
7442
 
 
7443
static int show_ssl_get_cipher(THD *thd, SHOW_VAR *var, char *buff)
 
7444
{
 
7445
  var->type= SHOW_CHAR;
 
7446
  if( thd->vio_ok() && thd->net.vio->ssl_arg )
 
7447
    var->value= const_cast<char*>(SSL_get_cipher((SSL*) thd->net.vio->ssl_arg));
 
7448
  else
 
7449
    var->value= (char *)"";
 
7450
  return 0;
 
7451
}
 
7452
 
 
7453
static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff)
 
7454
{
 
7455
  var->type= SHOW_CHAR;
 
7456
  var->value= buff;
 
7457
  if (thd->vio_ok() && thd->net.vio->ssl_arg)
 
7458
  {
 
7459
    int i;
 
7460
    const char *p;
 
7461
    char *end= buff + SHOW_VAR_FUNC_BUFF_SIZE;
 
7462
    for (i=0; (p= SSL_get_cipher_list((SSL*) thd->net.vio->ssl_arg,i)) &&
 
7463
               buff < end; i++)
 
7464
    {
 
7465
      buff= strnmov(buff, p, end-buff-1);
 
7466
      *buff++= ':';
 
7467
    }
 
7468
    if (i)
 
7469
      buff--;
 
7470
  }
 
7471
  *buff=0;
 
7472
  return 0;
 
7473
}
 
7474
 
 
7475
#endif /* HAVE_OPENSSL */
 
7476
 
 
7477
 
 
7478
/*
 
7479
  Variables shown by SHOW STATUS in alphabetical order
 
7480
*/
 
7481
 
 
7482
SHOW_VAR status_vars[]= {
 
7483
  {"Aborted_clients",          (char*) &aborted_threads,        SHOW_LONG},
 
7484
  {"Aborted_connects",         (char*) &aborted_connects,       SHOW_LONG},
 
7485
  {"Binlog_cache_disk_use",    (char*) &binlog_cache_disk_use,  SHOW_LONG},
 
7486
  {"Binlog_cache_use",         (char*) &binlog_cache_use,       SHOW_LONG},
 
7487
  {"Bytes_received",           (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONGLONG_STATUS},
 
7488
  {"Bytes_sent",               (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS},
 
7489
  {"Com",                      (char*) com_status_vars, SHOW_ARRAY},
 
7490
  {"Compression",              (char*) &show_net_compression, SHOW_FUNC},
 
7491
  {"Connections",              (char*) &thread_id,              SHOW_LONG_NOFLUSH},
 
7492
  {"Created_tmp_disk_tables",  (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS},
 
7493
  {"Created_tmp_files",        (char*) &my_tmp_file_created,    SHOW_LONG},
 
7494
  {"Created_tmp_tables",       (char*) offsetof(STATUS_VAR, created_tmp_tables), SHOW_LONG_STATUS},
 
7495
  {"Delayed_errors",           (char*) &delayed_insert_errors,  SHOW_LONG},
 
7496
  {"Delayed_insert_threads",   (char*) &delayed_insert_threads, SHOW_LONG_NOFLUSH},
 
7497
  {"Delayed_writes",           (char*) &delayed_insert_writes,  SHOW_LONG},
 
7498
  {"Flush_commands",           (char*) &refresh_version,        SHOW_LONG_NOFLUSH},
 
7499
  {"Handler_commit",           (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
 
7500
  {"Handler_delete",           (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS},
 
7501
  {"Handler_discover",         (char*) offsetof(STATUS_VAR, ha_discover_count), SHOW_LONG_STATUS},
 
7502
  {"Handler_prepare",          (char*) offsetof(STATUS_VAR, ha_prepare_count),  SHOW_LONG_STATUS},
 
7503
  {"Handler_read_first",       (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS},
 
7504
  {"Handler_read_key",         (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS},
 
7505
  {"Handler_read_next",        (char*) offsetof(STATUS_VAR, ha_read_next_count), SHOW_LONG_STATUS},
 
7506
  {"Handler_read_prev",        (char*) offsetof(STATUS_VAR, ha_read_prev_count), SHOW_LONG_STATUS},
 
7507
  {"Handler_read_rnd",         (char*) offsetof(STATUS_VAR, ha_read_rnd_count), SHOW_LONG_STATUS},
 
7508
  {"Handler_read_rnd_next",    (char*) offsetof(STATUS_VAR, ha_read_rnd_next_count), SHOW_LONG_STATUS},
 
7509
  {"Handler_rollback",         (char*) offsetof(STATUS_VAR, ha_rollback_count), SHOW_LONG_STATUS},
 
7510
  {"Handler_savepoint",        (char*) offsetof(STATUS_VAR, ha_savepoint_count), SHOW_LONG_STATUS},
 
7511
  {"Handler_savepoint_rollback",(char*) offsetof(STATUS_VAR, ha_savepoint_rollback_count), SHOW_LONG_STATUS},
 
7512
  {"Handler_update",           (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS},
 
7513
  {"Handler_write",            (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS},
 
7514
  {"Key_blocks_not_flushed",   (char*) offsetof(KEY_CACHE, global_blocks_changed), SHOW_KEY_CACHE_LONG},
 
7515
  {"Key_blocks_unused",        (char*) offsetof(KEY_CACHE, blocks_unused), SHOW_KEY_CACHE_LONG},
 
7516
  {"Key_blocks_used",          (char*) offsetof(KEY_CACHE, blocks_used), SHOW_KEY_CACHE_LONG},
 
7517
  {"Key_read_requests",        (char*) offsetof(KEY_CACHE, global_cache_r_requests), SHOW_KEY_CACHE_LONGLONG},
 
7518
  {"Key_reads",                (char*) offsetof(KEY_CACHE, global_cache_read), SHOW_KEY_CACHE_LONGLONG},
 
7519
  {"Key_write_requests",       (char*) offsetof(KEY_CACHE, global_cache_w_requests), SHOW_KEY_CACHE_LONGLONG},
 
7520
  {"Key_writes",               (char*) offsetof(KEY_CACHE, global_cache_write), SHOW_KEY_CACHE_LONGLONG},
 
7521
  {"Last_query_cost",          (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS},
 
7522
  {"Max_used_connections",     (char*) &max_used_connections,  SHOW_LONG},
 
7523
  {"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use,    SHOW_LONG_NOFLUSH},
 
7524
  {"Open_files",               (char*) &my_file_opened,         SHOW_LONG_NOFLUSH},
 
7525
  {"Open_streams",             (char*) &my_stream_opened,       SHOW_LONG_NOFLUSH},
 
7526
  {"Open_table_definitions",   (char*) &show_table_definitions, SHOW_FUNC},
 
7527
  {"Open_tables",              (char*) &show_open_tables,       SHOW_FUNC},
 
7528
  {"Opened_files",             (char*) &my_file_total_opened, SHOW_LONG_NOFLUSH},
 
7529
  {"Opened_tables",            (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS},
 
7530
  {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS},
 
7531
  {"Prepared_stmt_count",      (char*) &show_prepared_stmt_count, SHOW_FUNC},
 
7532
#ifdef HAVE_QUERY_CACHE
 
7533
  {"Qcache_free_blocks",       (char*) &query_cache.free_memory_blocks, SHOW_LONG_NOFLUSH},
 
7534
  {"Qcache_free_memory",       (char*) &query_cache.free_memory, SHOW_LONG_NOFLUSH},
 
7535
  {"Qcache_hits",              (char*) &query_cache.hits,       SHOW_LONG},
 
7536
  {"Qcache_inserts",           (char*) &query_cache.inserts,    SHOW_LONG},
 
7537
  {"Qcache_lowmem_prunes",     (char*) &query_cache.lowmem_prunes, SHOW_LONG},
 
7538
  {"Qcache_not_cached",        (char*) &query_cache.refused,    SHOW_LONG},
 
7539
  {"Qcache_queries_in_cache",  (char*) &query_cache.queries_in_cache, SHOW_LONG_NOFLUSH},
 
7540
  {"Qcache_total_blocks",      (char*) &query_cache.total_blocks, SHOW_LONG_NOFLUSH},
 
7541
#endif /*HAVE_QUERY_CACHE*/
 
7542
  {"Queries",                  (char*) &show_queries,            SHOW_FUNC},
 
7543
  {"Questions",                (char*) offsetof(STATUS_VAR, questions), SHOW_LONG_STATUS},
 
7544
#ifdef HAVE_REPLICATION
 
7545
  {"Rpl_status",               (char*) &show_rpl_status,          SHOW_FUNC},
 
7546
#endif
 
7547
  {"Select_full_join",         (char*) offsetof(STATUS_VAR, select_full_join_count), SHOW_LONG_STATUS},
 
7548
  {"Select_full_range_join",   (char*) offsetof(STATUS_VAR, select_full_range_join_count), SHOW_LONG_STATUS},
 
7549
  {"Select_range",             (char*) offsetof(STATUS_VAR, select_range_count), SHOW_LONG_STATUS},
 
7550
  {"Select_range_check",       (char*) offsetof(STATUS_VAR, select_range_check_count), SHOW_LONG_STATUS},
 
7551
  {"Select_scan",              (char*) offsetof(STATUS_VAR, select_scan_count), SHOW_LONG_STATUS},
 
7552
  {"Slave_open_temp_tables",   (char*) &slave_open_temp_tables, SHOW_LONG},
 
7553
#ifdef HAVE_REPLICATION
 
7554
  {"Slave_retried_transactions",(char*) &show_slave_retried_trans, SHOW_FUNC},
 
7555
  {"Slave_running",            (char*) &show_slave_running,     SHOW_FUNC},
 
7556
#endif
 
7557
  {"Slow_launch_threads",      (char*) &slow_launch_threads,    SHOW_LONG},
 
7558
  {"Slow_queries",             (char*) offsetof(STATUS_VAR, long_query_count), SHOW_LONG_STATUS},
 
7559
  {"Sort_merge_passes",        (char*) offsetof(STATUS_VAR, filesort_merge_passes), SHOW_LONG_STATUS},
 
7560
  {"Sort_range",               (char*) offsetof(STATUS_VAR, filesort_range_count), SHOW_LONG_STATUS},
 
7561
  {"Sort_rows",                (char*) offsetof(STATUS_VAR, filesort_rows), SHOW_LONG_STATUS},
 
7562
  {"Sort_scan",                (char*) offsetof(STATUS_VAR, filesort_scan_count), SHOW_LONG_STATUS},
 
7563
#ifdef HAVE_OPENSSL
 
7564
  {"Ssl_accept_renegotiates",  (char*) &show_ssl_ctx_sess_accept_renegotiate, SHOW_FUNC},
 
7565
  {"Ssl_accepts",              (char*) &show_ssl_ctx_sess_accept, SHOW_FUNC},
 
7566
  {"Ssl_callback_cache_hits",  (char*) &show_ssl_ctx_sess_cb_hits, SHOW_FUNC},
 
7567
  {"Ssl_cipher",               (char*) &show_ssl_get_cipher, SHOW_FUNC},
 
7568
  {"Ssl_cipher_list",          (char*) &show_ssl_get_cipher_list, SHOW_FUNC},
 
7569
  {"Ssl_client_connects",      (char*) &show_ssl_ctx_sess_connect, SHOW_FUNC},
 
7570
  {"Ssl_connect_renegotiates", (char*) &show_ssl_ctx_sess_connect_renegotiate, SHOW_FUNC},
 
7571
  {"Ssl_ctx_verify_depth",     (char*) &show_ssl_ctx_get_verify_depth, SHOW_FUNC},
 
7572
  {"Ssl_ctx_verify_mode",      (char*) &show_ssl_ctx_get_verify_mode, SHOW_FUNC},
 
7573
  {"Ssl_default_timeout",      (char*) &show_ssl_get_default_timeout, SHOW_FUNC},
 
7574
  {"Ssl_finished_accepts",     (char*) &show_ssl_ctx_sess_accept_good, SHOW_FUNC},
 
7575
  {"Ssl_finished_connects",    (char*) &show_ssl_ctx_sess_connect_good, SHOW_FUNC},
 
7576
  {"Ssl_session_cache_hits",   (char*) &show_ssl_ctx_sess_hits, SHOW_FUNC},
 
7577
  {"Ssl_session_cache_misses", (char*) &show_ssl_ctx_sess_misses, SHOW_FUNC},
 
7578
  {"Ssl_session_cache_mode",   (char*) &show_ssl_ctx_get_session_cache_mode, SHOW_FUNC},
 
7579
  {"Ssl_session_cache_overflows", (char*) &show_ssl_ctx_sess_cache_full, SHOW_FUNC},
 
7580
  {"Ssl_session_cache_size",   (char*) &show_ssl_ctx_sess_get_cache_size, SHOW_FUNC},
 
7581
  {"Ssl_session_cache_timeouts", (char*) &show_ssl_ctx_sess_timeouts, SHOW_FUNC},
 
7582
  {"Ssl_sessions_reused",      (char*) &show_ssl_session_reused, SHOW_FUNC},
 
7583
  {"Ssl_used_session_cache_entries",(char*) &show_ssl_ctx_sess_number, SHOW_FUNC},
 
7584
  {"Ssl_verify_depth",         (char*) &show_ssl_get_verify_depth, SHOW_FUNC},
 
7585
  {"Ssl_verify_mode",          (char*) &show_ssl_get_verify_mode, SHOW_FUNC},
 
7586
  {"Ssl_version",              (char*) &show_ssl_get_version, SHOW_FUNC},
 
7587
#endif /* HAVE_OPENSSL */
 
7588
  {"Table_locks_immediate",    (char*) &locks_immediate,        SHOW_LONG},
 
7589
  {"Table_locks_waited",       (char*) &locks_waited,           SHOW_LONG},
 
7590
#ifdef HAVE_MMAP
 
7591
  {"Tc_log_max_pages_used",    (char*) &tc_log_max_pages_used,  SHOW_LONG},
 
7592
  {"Tc_log_page_size",         (char*) &tc_log_page_size,       SHOW_LONG},
 
7593
  {"Tc_log_page_waits",        (char*) &tc_log_page_waits,      SHOW_LONG},
 
7594
#endif
 
7595
  {"Threads_cached",           (char*) &cached_thread_count,    SHOW_LONG_NOFLUSH},
 
7596
  {"Threads_connected",        (char*) &thread_count,           SHOW_INT},
 
7597
  {"Threads_created",          (char*) &thread_created,         SHOW_LONG_NOFLUSH},
 
7598
  {"Threads_running",          (char*) &thread_running,         SHOW_INT},
 
7599
  {"Uptime",                   (char*) &show_starttime,         SHOW_FUNC},
 
7600
#ifdef COMMUNITY_SERVER
 
7601
  {"Uptime_since_flush_status",(char*) &show_flushstatustime,   SHOW_FUNC},
 
7602
#endif
 
7603
  {NullS, NullS, SHOW_LONG}
 
7604
};
 
7605
 
 
7606
#ifndef EMBEDDED_LIBRARY
 
7607
static void print_version(void)
 
7608
{
 
7609
  set_server_version();
 
7610
  /*
 
7611
    Note: the instance manager keys off the string 'Ver' so it can find the
 
7612
    version from the output of 'mysqld --version', so don't change it!
 
7613
  */
 
7614
  printf("%s  Ver %s for %s on %s (%s)\n",my_progname,
 
7615
         server_version,SYSTEM_TYPE,MACHINE_TYPE, MYSQL_COMPILATION_COMMENT);
 
7616
}
 
7617
 
 
7618
static void usage(void)
 
7619
{
 
7620
  if (!(default_charset_info= get_charset_by_csname(default_character_set_name,
 
7621
                                                   MY_CS_PRIMARY,
 
7622
                                                   MYF(MY_WME))))
 
7623
    exit(1);
 
7624
  if (!default_collation_name)
 
7625
    default_collation_name= (char*) default_charset_info->name;
 
7626
  print_version();
 
7627
  puts("\
 
7628
Copyright (C) 2000-2008 MySQL AB, by Monty and others.\n\
 
7629
Copyright (C) 2008 Sun Microsystems, Inc.\n\
 
7630
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
 
7631
and you are welcome to modify and redistribute it under the GPL license\n\n\
 
7632
Starts the MySQL database server.\n");
 
7633
 
 
7634
  printf("Usage: %s [OPTIONS]\n", my_progname);
 
7635
  if (!opt_verbose)
 
7636
    puts("\nFor more help options (several pages), use mysqld --verbose --help.");
 
7637
  else
 
7638
  {
 
7639
#ifdef __WIN__
 
7640
  puts("NT and Win32 specific options:\n\
 
7641
  --install                     Install the default service (NT).\n\
 
7642
  --install-manual              Install the default service started manually (NT).\n\
 
7643
  --install service_name        Install an optional service (NT).\n\
 
7644
  --install-manual service_name Install an optional service started manually (NT).\n\
 
7645
  --remove                      Remove the default service from the service list (NT).\n\
 
7646
  --remove service_name         Remove the service_name from the service list (NT).\n\
 
7647
  --enable-named-pipe           Only to be used for the default server (NT).\n\
 
7648
  --standalone                  Dummy option to start as a standalone server (NT).\
 
7649
");
 
7650
  puts("");
 
7651
#endif
 
7652
  print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
 
7653
  puts("");
 
7654
  set_ports();
 
7655
 
 
7656
  /* Print out all the options including plugin supplied options */
 
7657
  my_print_help_inc_plugins(my_long_options, sizeof(my_long_options)/sizeof(my_option));
 
7658
 
 
7659
  if (! plugins_are_initialized)
 
7660
  {
 
7661
    puts("\n\
 
7662
Plugins have parameters that are not reflected in this list\n\
 
7663
because execution stopped before plugins were initialized.");
 
7664
  }
 
7665
 
 
7666
  puts("\n\
 
7667
To see what values a running MySQL server is using, type\n\
 
7668
'mysqladmin variables' instead of 'mysqld --verbose --help'.");
 
7669
  }
 
7670
}
 
7671
#endif /*!EMBEDDED_LIBRARY*/
 
7672
 
 
7673
 
 
7674
/**
 
7675
  Initialize all MySQL global variables to default values.
 
7676
 
 
7677
  We don't need to set numeric variables refered to in my_long_options
 
7678
  as these are initialized by my_getopt.
 
7679
 
 
7680
  @note
 
7681
    The reason to set a lot of global variables to zero is to allow one to
 
7682
    restart the embedded server with a clean environment
 
7683
    It's also needed on some exotic platforms where global variables are
 
7684
    not set to 0 when a program starts.
 
7685
 
 
7686
    We don't need to set numeric variables refered to in my_long_options
 
7687
    as these are initialized by my_getopt.
 
7688
*/
 
7689
 
 
7690
static int mysql_init_variables(void)
 
7691
{
 
7692
  int error;
 
7693
  /* Things reset to zero */
 
7694
  opt_skip_slave_start= opt_reckless_slave = 0;
 
7695
  mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0;
 
7696
  myisam_test_invalid_symlink= test_if_data_home_dir;
 
7697
  opt_log= opt_slow_log= 0;
 
7698
  opt_update_log= 0;
 
7699
  log_output_options= find_bit_type(log_output_str, &log_output_typelib);
 
7700
  opt_bin_log= 0;
 
7701
  opt_disable_networking= opt_skip_show_db=0;
 
7702
  opt_ignore_builtin_innodb= 0;
 
7703
  opt_logname= opt_update_logname= opt_binlog_index_name= opt_slow_logname= 0;
 
7704
  opt_tc_log_file= (char *)"tc.log";      // no hostname in tc_log file name !
 
7705
  opt_secure_auth= 0;
 
7706
  opt_secure_file_priv= 0;
 
7707
  opt_bootstrap= opt_myisam_log= 0;
 
7708
  mqh_used= 0;
 
7709
  segfaulted= kill_in_progress= 0;
 
7710
  cleanup_done= 0;
 
7711
  defaults_argc= 0;
 
7712
  defaults_argv= 0;
 
7713
  server_id_supplied= 0;
 
7714
  test_flags= select_errors= dropping_tables= ha_open_options=0;
 
7715
  thread_count= thread_running= kill_cached_threads= wake_thread=0;
 
7716
  slave_open_temp_tables= 0;
 
7717
  cached_thread_count= 0;
 
7718
  opt_endinfo= using_udf_functions= 0;
 
7719
  opt_using_transactions= 0;
 
7720
  abort_loop= select_thread_in_use= signal_thread_in_use= 0;
 
7721
  ready_to_exit= shutdown_in_progress= grant_option= 0;
 
7722
  aborted_threads= aborted_connects= 0;
 
7723
  delayed_insert_threads= delayed_insert_writes= delayed_rows_in_use= 0;
 
7724
  delayed_insert_errors= thread_created= 0;
 
7725
  specialflag= 0;
 
7726
  binlog_cache_use=  binlog_cache_disk_use= 0;
 
7727
  max_used_connections= slow_launch_threads = 0;
 
7728
  mysqld_user= mysqld_chroot= opt_init_file= opt_bin_logname = 0;
 
7729
  prepared_stmt_count= 0;
 
7730
  errmesg= 0;
 
7731
  mysqld_unix_port= opt_mysql_tmpdir= my_bind_addr_str= NullS;
 
7732
  bzero((uchar*) &mysql_tmpdir_list, sizeof(mysql_tmpdir_list));
 
7733
  bzero((char *) &global_status_var, sizeof(global_status_var));
 
7734
  opt_large_pages= 0;
 
7735
#if defined(ENABLED_DEBUG_SYNC)
 
7736
  opt_debug_sync_timeout= 0;
 
7737
#endif /* defined(ENABLED_DEBUG_SYNC) */
 
7738
  key_map_full.set_all();
 
7739
 
 
7740
  /* Character sets */
 
7741
  system_charset_info= &my_charset_utf8_general_ci;
 
7742
  files_charset_info= &my_charset_utf8_general_ci;
 
7743
  national_charset_info= &my_charset_utf8_general_ci;
 
7744
  table_alias_charset= &my_charset_bin;
 
7745
  character_set_filesystem= &my_charset_bin;
 
7746
 
 
7747
  opt_date_time_formats[0]= opt_date_time_formats[1]= opt_date_time_formats[2]= 0;
 
7748
 
 
7749
  /* Things with default values that are not zero */
 
7750
  delay_key_write_options= (uint) DELAY_KEY_WRITE_ON;
 
7751
  slave_exec_mode_options= 0;
 
7752
  slave_exec_mode_options= (uint)
 
7753
    find_bit_type_or_exit(slave_exec_mode_str, &slave_exec_mode_typelib, NULL,
 
7754
                          &error);
 
7755
  if (error)
 
7756
    return 1;
 
7757
  opt_specialflag= SPECIAL_ENGLISH;
 
7758
  unix_sock= ip_sock= INVALID_SOCKET;
 
7759
  mysql_home_ptr= mysql_home;
 
7760
  pidfile_name_ptr= pidfile_name;
 
7761
  log_error_file_ptr= log_error_file;
 
7762
  language_ptr= language;
 
7763
  mysql_data_home= mysql_real_data_home;
 
7764
  thd_startup_options= (OPTION_AUTO_IS_NULL | OPTION_BIN_LOG |
 
7765
                        OPTION_QUOTE_SHOW_CREATE | OPTION_SQL_NOTES);
 
7766
  protocol_version= PROTOCOL_VERSION;
 
7767
  what_to_log= ~ (1L << (uint) COM_TIME);
 
7768
  refresh_version= 1L;  /* Increments on each reload */
 
7769
  global_query_id= thread_id= 1L;
 
7770
  strmov(server_version, MYSQL_SERVER_VERSION);
 
7771
  myisam_recover_options_str= sql_mode_str= "OFF";
 
7772
  myisam_stats_method_str= "nulls_unequal";
 
7773
  my_bind_addr = htonl(INADDR_ANY);
 
7774
  threads.empty();
 
7775
  thread_cache.empty();
 
7776
  key_caches.empty();
 
7777
  if (!(dflt_key_cache= get_or_create_key_cache(default_key_cache_base.str,
 
7778
                                                default_key_cache_base.length)))
 
7779
  {
 
7780
    sql_print_error("Cannot allocate the keycache");
 
7781
    return 1;
 
7782
  }
 
7783
  /* set key_cache_hash.default_value = dflt_key_cache */
 
7784
  multi_keycache_init();
 
7785
 
 
7786
  /* Set directory paths */
 
7787
  strmake(language, LANGUAGE, sizeof(language)-1);
 
7788
  strmake(mysql_real_data_home, get_relative_path(MYSQL_DATADIR),
 
7789
          sizeof(mysql_real_data_home)-1);
 
7790
  mysql_data_home_buff[0]=FN_CURLIB;    // all paths are relative from here
 
7791
  mysql_data_home_buff[1]=0;
 
7792
  mysql_data_home_len= 2;
 
7793
 
 
7794
  /* Replication parameters */
 
7795
  master_user= (char*) "test";
 
7796
  master_password= master_host= 0;
 
7797
  master_info_file= (char*) "master.info",
 
7798
    relay_log_info_file= (char*) "relay-log.info";
 
7799
  master_ssl_key= master_ssl_cert= master_ssl_ca=
 
7800
    master_ssl_capath= master_ssl_cipher= 0;
 
7801
  report_user= report_password = report_host= 0;        /* TO BE DELETED */
 
7802
  opt_relay_logname= opt_relaylog_index_name= 0;
 
7803
 
 
7804
  /* Variables in libraries */
 
7805
  charsets_dir= 0;
 
7806
  default_character_set_name= (char*) MYSQL_DEFAULT_CHARSET_NAME;
 
7807
  default_collation_name= compiled_default_collation_name;
 
7808
  sys_charset_system.value= (char*) system_charset_info->csname;
 
7809
  character_set_filesystem_name= (char*) "binary";
 
7810
  lc_time_names_name= (char*) "en_US";
 
7811
  /* Set default values for some option variables */
 
7812
  default_storage_engine_str= (char*) "MyISAM";
 
7813
  global_system_variables.table_plugin= NULL;
 
7814
  global_system_variables.tx_isolation= ISO_REPEATABLE_READ;
 
7815
  global_system_variables.select_limit= (ulonglong) HA_POS_ERROR;
 
7816
  max_system_variables.select_limit=    (ulonglong) HA_POS_ERROR;
 
7817
  global_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
 
7818
  max_system_variables.max_join_size=   (ulonglong) HA_POS_ERROR;
 
7819
  global_system_variables.old_passwords= 0;
 
7820
  global_system_variables.old_alter_table= 0;
 
7821
  global_system_variables.binlog_format= BINLOG_FORMAT_UNSPEC;
 
7822
  /*
 
7823
    Default behavior for 4.1 and 5.0 is to treat NULL values as unequal
 
7824
    when collecting index statistics for MyISAM tables.
 
7825
  */
 
7826
  global_system_variables.myisam_stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
 
7827
  
 
7828
  global_system_variables.optimizer_switch= OPTIMIZER_SWITCH_DEFAULT;
 
7829
  /* Variables that depends on compile options */
 
7830
#ifndef DBUG_OFF
 
7831
  default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace",
 
7832
                             "d:t:i:o,/tmp/mysqld.trace");
 
7833
#endif
 
7834
  opt_error_log= IF_WIN(1,0);
 
7835
#ifdef COMMUNITY_SERVER
 
7836
    have_community_features = SHOW_OPTION_YES;
 
7837
#else
 
7838
    have_community_features = SHOW_OPTION_NO;
 
7839
#endif
 
7840
  global_system_variables.ndb_index_stat_enable=FALSE;
 
7841
  max_system_variables.ndb_index_stat_enable=TRUE;
 
7842
  global_system_variables.ndb_index_stat_cache_entries=32;
 
7843
  max_system_variables.ndb_index_stat_cache_entries=~0L;
 
7844
  global_system_variables.ndb_index_stat_update_freq=20;
 
7845
  max_system_variables.ndb_index_stat_update_freq=~0L;
 
7846
#ifdef HAVE_OPENSSL
 
7847
  have_ssl=SHOW_OPTION_YES;
 
7848
#else
 
7849
  have_ssl=SHOW_OPTION_NO;
 
7850
#endif
 
7851
#ifdef HAVE_BROKEN_REALPATH
 
7852
  have_symlink=SHOW_OPTION_NO;
 
7853
#else
 
7854
  have_symlink=SHOW_OPTION_YES;
 
7855
#endif
 
7856
#ifdef HAVE_DLOPEN
 
7857
  have_dlopen=SHOW_OPTION_YES;
 
7858
#else
 
7859
  have_dlopen=SHOW_OPTION_NO;
 
7860
#endif
 
7861
#ifdef HAVE_QUERY_CACHE
 
7862
  have_query_cache=SHOW_OPTION_YES;
 
7863
#else
 
7864
  have_query_cache=SHOW_OPTION_NO;
 
7865
#endif
 
7866
#ifdef HAVE_SPATIAL
 
7867
  have_geometry=SHOW_OPTION_YES;
 
7868
#else
 
7869
  have_geometry=SHOW_OPTION_NO;
 
7870
#endif
 
7871
#ifdef HAVE_RTREE_KEYS
 
7872
  have_rtree_keys=SHOW_OPTION_YES;
 
7873
#else
 
7874
  have_rtree_keys=SHOW_OPTION_NO;
 
7875
#endif
 
7876
#ifdef HAVE_CRYPT
 
7877
  have_crypt=SHOW_OPTION_YES;
 
7878
#else
 
7879
  have_crypt=SHOW_OPTION_NO;
 
7880
#endif
 
7881
#ifdef HAVE_COMPRESS
 
7882
  have_compress= SHOW_OPTION_YES;
 
7883
#else
 
7884
  have_compress= SHOW_OPTION_NO;
 
7885
#endif
 
7886
#ifdef HAVE_LIBWRAP
 
7887
  libwrapName= NullS;
 
7888
#endif
 
7889
#ifdef HAVE_OPENSSL
 
7890
  des_key_file = 0;
 
7891
  ssl_acceptor_fd= 0;
 
7892
#endif
 
7893
#ifdef HAVE_SMEM
 
7894
  shared_memory_base_name= default_shared_memory_base_name;
 
7895
#endif
 
7896
#if !defined(my_pthread_setprio) && !defined(HAVE_PTHREAD_SETSCHEDPARAM)
 
7897
  opt_specialflag |= SPECIAL_NO_PRIOR;
 
7898
#endif
 
7899
 
 
7900
#if defined(__WIN__) || defined(__NETWARE__)
 
7901
  /* Allow Win32 and NetWare users to move MySQL anywhere */
 
7902
  {
 
7903
    char prg_dev[LIBLEN];
 
7904
#if defined __WIN__
 
7905
        char executing_path_name[LIBLEN];
 
7906
        if (!test_if_hard_path(my_progname))
 
7907
        {
 
7908
                // we don't want to use GetModuleFileName inside of my_path since
 
7909
                // my_path is a generic path dereferencing function and here we care
 
7910
                // only about the executing binary.
 
7911
                GetModuleFileName(NULL, executing_path_name, sizeof(executing_path_name));
 
7912
                my_path(prg_dev, executing_path_name, NULL);
 
7913
        }
 
7914
        else
 
7915
#endif
 
7916
    my_path(prg_dev,my_progname,"mysql/bin");
 
7917
    strcat(prg_dev,"/../");                     // Remove 'bin' to get base dir
 
7918
    cleanup_dirname(mysql_home,prg_dev);
 
7919
  }
 
7920
#else
 
7921
  const char *tmpenv;
 
7922
  if (!(tmpenv = getenv("MY_BASEDIR_VERSION")))
 
7923
    tmpenv = DEFAULT_MYSQL_HOME;
 
7924
  (void) strmake(mysql_home, tmpenv, sizeof(mysql_home)-1);
 
7925
#endif
 
7926
  return 0;
 
7927
}
 
7928
 
 
7929
 
 
7930
my_bool
 
7931
mysqld_get_one_option(int optid,
 
7932
                      const struct my_option *opt __attribute__((unused)),
 
7933
                      char *argument)
 
7934
{
 
7935
  int error;
 
7936
 
 
7937
  switch(optid) {
 
7938
  case '#':
 
7939
#ifndef DBUG_OFF
 
7940
    DBUG_SET_INITIAL(argument ? argument : default_dbug_option);
 
7941
#endif
 
7942
    opt_endinfo=1;                              /* unireg: memory allocation */
 
7943
    break;
 
7944
  case '0':
 
7945
    WARN_DEPRECATED(NULL, VER_CELOSIA, "--log-long-format", "--log-short-format");
 
7946
    break;
 
7947
  case 'a':
 
7948
    global_system_variables.sql_mode= fix_sql_mode(MODE_ANSI);
 
7949
    global_system_variables.tx_isolation= ISO_SERIALIZABLE;
 
7950
    break;
 
7951
  case 'b':
 
7952
    strmake(mysql_home,argument,sizeof(mysql_home)-1);
 
7953
    break;
 
7954
  case OPT_DEFAULT_CHARACTER_SET_OLD: // --default-character-set
 
7955
    WARN_DEPRECATED(NULL, VER_CELOSIA, 
 
7956
                    "--default-character-set",
 
7957
                    "--character-set-server");
 
7958
    /* Fall through */
 
7959
  case 'C':
 
7960
    if (default_collation_name == compiled_default_collation_name)
 
7961
      default_collation_name= 0;
 
7962
    break;
 
7963
  case 'l':
 
7964
    WARN_DEPRECATED(NULL, "7.0", "--log", "'--general_log'/'--general_log_file'");
 
7965
    opt_log=1;
 
7966
    break;
 
7967
  case 'h':
 
7968
    strmake(mysql_real_data_home,argument, sizeof(mysql_real_data_home)-1);
 
7969
    /* Correct pointer set by my_getopt (for embedded library) */
 
7970
    mysql_data_home= mysql_real_data_home;
 
7971
    mysql_data_home_len= strlen(mysql_data_home);
 
7972
    break;
 
7973
  case 'u':
 
7974
    if (!mysqld_user || !strcmp(mysqld_user, argument))
 
7975
      mysqld_user= argument;
 
7976
    else
 
7977
      sql_print_warning("Ignoring user change to '%s' because the user was set to '%s' earlier on the command line\n", argument, mysqld_user);
 
7978
    break;
 
7979
  case 'L':
 
7980
    strmake(language, argument, sizeof(language)-1);
 
7981
    break;
 
7982
  case 'O':
 
7983
    WARN_DEPRECATED(NULL, VER_CELOSIA, "--set-variable", "--variable-name=value");
 
7984
    break;
 
7985
#ifdef HAVE_REPLICATION
 
7986
  case OPT_SLAVE_SKIP_ERRORS:
 
7987
    init_slave_skip_errors(argument);
 
7988
    break;
 
7989
  case OPT_SLAVE_EXEC_MODE:
 
7990
    slave_exec_mode_options= (uint)
 
7991
      find_bit_type_or_exit(argument, &slave_exec_mode_typelib, "", &error);
 
7992
    if (error)
 
7993
      return 1;
 
7994
    break;
 
7995
#endif
 
7996
  case OPT_SAFEMALLOC_MEM_LIMIT:
 
7997
#if !defined(DBUG_OFF) && defined(SAFEMALLOC)
 
7998
    sf_malloc_mem_limit = atoi(argument);
 
7999
#endif
 
8000
    break;
 
8001
#include <sslopt-case.h>
 
8002
#ifndef EMBEDDED_LIBRARY
 
8003
  case 'V':
 
8004
    print_version();
 
8005
    exit(0);
 
8006
#endif /*EMBEDDED_LIBRARY*/
 
8007
  case OPT_WARNINGS:
 
8008
    WARN_DEPRECATED(NULL, VER_CELOSIA, "--warnings", "--log-warnings");
 
8009
    /* Note: fall-through to 'W' */
 
8010
  case 'W':
 
8011
    if (!argument)
 
8012
      global_system_variables.log_warnings++;
 
8013
    else if (argument == disabled_my_option)
 
8014
      global_system_variables.log_warnings= 0L;
 
8015
    else
 
8016
      global_system_variables.log_warnings= atoi(argument);
 
8017
    break;
 
8018
  case 'T':
 
8019
    test_flags= argument ? (uint) atoi(argument) : 0;
 
8020
    opt_endinfo=1;
 
8021
    break;
 
8022
  case (int) OPT_DEFAULT_COLLATION_OLD:
 
8023
    WARN_DEPRECATED(NULL, VER_CELOSIA, "--default-collation", "--collation-server");
 
8024
    break;
 
8025
  case (int) OPT_SAFE_SHOW_DB:
 
8026
    WARN_DEPRECATED(NULL, VER_CELOSIA, "--safe-show-database", "GRANT SHOW DATABASES");
 
8027
    break;
 
8028
  case (int) OPT_LOG_BIN_TRUST_FUNCTION_CREATORS_OLD:
 
8029
    WARN_DEPRECATED(NULL, VER_CELOSIA, "--log-bin-trust-routine-creators", "--log-bin-trust-function-creators");
 
8030
    break;
 
8031
  case (int) OPT_ENABLE_LOCK:
 
8032
    WARN_DEPRECATED(NULL, VER_CELOSIA, "--enable-locking", "--external-locking");
 
8033
    break;
 
8034
  case (int) OPT_BIG_TABLES:
 
8035
    thd_startup_options|=OPTION_BIG_TABLES;
 
8036
    break;
 
8037
  case (int) OPT_IGNORE_BUILTIN_INNODB:
 
8038
    opt_ignore_builtin_innodb= 1;
 
8039
    break;
 
8040
  case (int) OPT_ISAM_LOG:
 
8041
    opt_myisam_log=1;
 
8042
    break;
 
8043
  case (int) OPT_UPDATE_LOG:
 
8044
    WARN_DEPRECATED(NULL, VER_CELOSIA, "--log-update", "--log-bin");
 
8045
    opt_update_log=1;
 
8046
    break;
 
8047
  case (int) OPT_BIN_LOG:
 
8048
    opt_bin_log= test(argument != disabled_my_option);
 
8049
    break;
 
8050
  case (int) OPT_ERROR_LOG_FILE:
 
8051
    opt_error_log= 1;
 
8052
    break;
 
8053
#ifdef HAVE_REPLICATION
 
8054
  case (int) OPT_INIT_RPL_ROLE:
 
8055
  {
 
8056
    int role;
 
8057
    role= find_type_or_exit(argument, &rpl_role_typelib, opt->name);
 
8058
    rpl_status = (role == 1) ?  RPL_AUTH_MASTER : RPL_IDLE_SLAVE;
 
8059
    break;
 
8060
  }
 
8061
  case (int)OPT_REPLICATE_IGNORE_DB:
 
8062
  {
 
8063
    rpl_filter->add_ignore_db(argument);
 
8064
    break;
 
8065
  }
 
8066
  case (int)OPT_REPLICATE_DO_DB:
 
8067
  {
 
8068
    rpl_filter->add_do_db(argument);
 
8069
    break;
 
8070
  }
 
8071
  case (int)OPT_REPLICATE_REWRITE_DB:
 
8072
  {
 
8073
    char* key = argument,*p, *val;
 
8074
 
 
8075
    if (!(p= strstr(argument, "->")))
 
8076
    {
 
8077
      sql_print_error("Bad syntax in replicate-rewrite-db - missing '->'!\n");
 
8078
      return 1;
 
8079
    }
 
8080
    val= p--;
 
8081
    while (my_isspace(mysqld_charset, *p) && p > argument)
 
8082
      *p-- = 0;
 
8083
    if (p == argument)
 
8084
    {
 
8085
      sql_print_error("Bad syntax in replicate-rewrite-db - empty FROM db!\n");
 
8086
      return 1;
 
8087
    }
 
8088
    *val= 0;
 
8089
    val+= 2;
 
8090
    while (*val && my_isspace(mysqld_charset, *val))
 
8091
      *val++;
 
8092
    if (!*val)
 
8093
    {
 
8094
      sql_print_error("Bad syntax in replicate-rewrite-db - empty TO db!\n");
 
8095
      return 1;
 
8096
    }
 
8097
 
 
8098
    rpl_filter->add_db_rewrite(key, val);
 
8099
    break;
 
8100
  }
 
8101
 
 
8102
  case (int)OPT_BINLOG_IGNORE_DB:
 
8103
  {
 
8104
    binlog_filter->add_ignore_db(argument);
 
8105
    break;
 
8106
  }
 
8107
  case OPT_BINLOG_FORMAT:
 
8108
  {
 
8109
    int id;
 
8110
    id= find_type_or_exit(argument, &binlog_format_typelib, opt->name);
 
8111
    global_system_variables.binlog_format= opt_binlog_format_id= id - 1;
 
8112
    break;
 
8113
  }
 
8114
  case (int)OPT_BINLOG_DO_DB:
 
8115
  {
 
8116
    binlog_filter->add_do_db(argument);
 
8117
    break;
 
8118
  }
 
8119
  case (int)OPT_REPLICATE_DO_TABLE:
 
8120
  {
 
8121
    if (rpl_filter->add_do_table(argument))
 
8122
    {
 
8123
      sql_print_error("Could not add do table rule '%s'!\n", argument);
 
8124
      return 1;
 
8125
    }
 
8126
    break;
 
8127
  }
 
8128
  case (int)OPT_REPLICATE_WILD_DO_TABLE:
 
8129
  {
 
8130
    if (rpl_filter->add_wild_do_table(argument))
 
8131
    {
 
8132
      sql_print_error("Could not add do table rule '%s'!\n", argument);
 
8133
      return 1;
 
8134
    }
 
8135
    break;
 
8136
  }
 
8137
  case (int)OPT_REPLICATE_WILD_IGNORE_TABLE:
 
8138
  {
 
8139
    if (rpl_filter->add_wild_ignore_table(argument))
 
8140
    {
 
8141
      sql_print_error("Could not add ignore table rule '%s'!\n", argument);
 
8142
      return 1;
 
8143
    }
 
8144
    break;
 
8145
  }
 
8146
  case (int)OPT_REPLICATE_IGNORE_TABLE:
 
8147
  {
 
8148
    if (rpl_filter->add_ignore_table(argument))
 
8149
    {
 
8150
      sql_print_error("Could not add ignore table rule '%s'!\n", argument);
 
8151
      return 1;
 
8152
    }
 
8153
    break;
 
8154
  }
 
8155
#endif /* HAVE_REPLICATION */
 
8156
  case (int) OPT_SLOW_QUERY_LOG:
 
8157
    WARN_DEPRECATED(NULL, "7.0", "--log_slow_queries", "'--slow_query_log'/'--slow_query_log_file'");
 
8158
    opt_slow_log= 1;
 
8159
    break;
 
8160
#ifdef WITH_CSV_STORAGE_ENGINE
 
8161
  case  OPT_LOG_OUTPUT:
 
8162
  {
 
8163
    if (!argument || !argument[0])
 
8164
    {
 
8165
      log_output_options= LOG_FILE;
 
8166
      log_output_str= log_output_typelib.type_names[1];
 
8167
    }
 
8168
    else
 
8169
    {
 
8170
      log_output_str= argument;
 
8171
      log_output_options=
 
8172
        find_bit_type_or_exit(argument, &log_output_typelib, opt->name, &error);
 
8173
      if (error)
 
8174
        return 1;
 
8175
  }
 
8176
    break;
 
8177
  }
 
8178
#endif
 
8179
  case OPT_EVENT_SCHEDULER:
 
8180
#ifndef HAVE_EVENT_SCHEDULER
 
8181
    sql_perror("Event scheduler is not supported in embedded build.");
 
8182
#else
 
8183
    if (Events::set_opt_event_scheduler(argument))
 
8184
      return 1;
 
8185
#endif
 
8186
    break;
 
8187
  case (int) OPT_SKIP_NEW:
 
8188
    opt_specialflag|= SPECIAL_NO_NEW_FUNC;
 
8189
    delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
 
8190
    myisam_concurrent_insert=0;
 
8191
    myisam_recover_options= HA_RECOVER_NONE;
 
8192
    sp_automatic_privileges=0;
 
8193
    my_use_symdir=0;
 
8194
    ha_open_options&= ~(HA_OPEN_ABORT_IF_CRASHED | HA_OPEN_DELAY_KEY_WRITE);
 
8195
#ifdef HAVE_QUERY_CACHE
 
8196
    query_cache_size=0;
 
8197
#endif
 
8198
    break;
 
8199
  case (int) OPT_SAFE:
 
8200
    opt_specialflag|= SPECIAL_SAFE_MODE;
 
8201
    delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
 
8202
    myisam_recover_options= HA_RECOVER_DEFAULT;
 
8203
    ha_open_options&= ~(HA_OPEN_DELAY_KEY_WRITE);
 
8204
    break;
 
8205
  case (int) OPT_SKIP_PRIOR:
 
8206
    opt_specialflag|= SPECIAL_NO_PRIOR;
 
8207
    sql_print_warning("The --skip-thread-priority startup option is deprecated "
 
8208
                      "and will be removed in MySQL 7.0. MySQL 6.0 and up do not "
 
8209
                      "give threads different priorities.");
 
8210
    break;
 
8211
  case (int) OPT_SKIP_LOCK:
 
8212
    WARN_DEPRECATED(NULL, VER_CELOSIA, "--skip-locking", "--skip-external-locking");
 
8213
    opt_external_locking=0;
 
8214
    break;
 
8215
  case (int) OPT_SQL_BIN_UPDATE_SAME:
 
8216
    WARN_DEPRECATED(NULL, VER_CELOSIA, "--sql-bin-update-same", "the binary log");
 
8217
    break;
 
8218
  case (int) OPT_RECORD_BUFFER_OLD:
 
8219
    WARN_DEPRECATED(NULL, VER_CELOSIA, "record_buffer", "read_buffer_size");
 
8220
    break;
 
8221
  case (int) OPT_SYMBOLIC_LINKS:
 
8222
    WARN_DEPRECATED(NULL, VER_CELOSIA, "--use-symbolic-links", "--symbolic-links");
 
8223
    break;
 
8224
  case (int) OPT_SKIP_HOST_CACHE:
 
8225
    opt_specialflag|= SPECIAL_NO_HOST_CACHE;
 
8226
    break;
 
8227
  case (int) OPT_SKIP_RESOLVE:
 
8228
    opt_specialflag|=SPECIAL_NO_RESOLVE;
 
8229
    break;
 
8230
  case (int) OPT_SKIP_NETWORKING:
 
8231
#if defined(__NETWARE__)
 
8232
    sql_perror("Can't start server: skip-networking option is currently not supported on NetWare");
 
8233
    return 1;
 
8234
#endif
 
8235
    opt_disable_networking=1;
 
8236
    mysqld_port=0;
 
8237
    break;
 
8238
  case (int) OPT_SKIP_SHOW_DB:
 
8239
    opt_skip_show_db=1;
 
8240
    opt_specialflag|=SPECIAL_SKIP_SHOW_DB;
 
8241
    break;
 
8242
  case (int) OPT_WANT_CORE:
 
8243
    test_flags |= TEST_CORE_ON_SIGNAL;
 
8244
    break;
 
8245
  case (int) OPT_SKIP_STACK_TRACE:
 
8246
    test_flags|=TEST_NO_STACKTRACE;
 
8247
    break;
 
8248
  case (int) OPT_SKIP_SYMLINKS:
 
8249
    WARN_DEPRECATED(NULL, VER_CELOSIA, "--skip-symlink", "--skip-symbolic-links");
 
8250
    my_use_symdir=0;
 
8251
    break;
 
8252
  case (int) OPT_BIND_ADDRESS:
 
8253
    if ((my_bind_addr= (ulong) inet_addr(argument)) == INADDR_NONE)
 
8254
    {
 
8255
      struct hostent *ent;
 
8256
      if (argument[0])
 
8257
        ent=gethostbyname(argument);
 
8258
      else
 
8259
      {
 
8260
        char myhostname[255];
 
8261
        if (gethostname(myhostname,sizeof(myhostname)) < 0)
 
8262
        {
 
8263
          sql_perror("Can't start server: cannot get my own hostname!");
 
8264
          return 1;
 
8265
        }
 
8266
        ent=gethostbyname(myhostname);
 
8267
      }
 
8268
      if (!ent)
 
8269
      {
 
8270
        sql_perror("Can't start server: cannot resolve hostname!");
 
8271
        return 1;
 
8272
      }
 
8273
      my_bind_addr = (ulong) ((in_addr*)ent->h_addr_list[0])->s_addr;
 
8274
    }
 
8275
    break;
 
8276
  case (int) OPT_PID_FILE:
 
8277
    strmake(pidfile_name, argument, sizeof(pidfile_name)-1);
 
8278
    break;
 
8279
#ifdef __WIN__
 
8280
  case (int) OPT_STANDALONE:            /* Dummy option for NT */
 
8281
    break;
 
8282
#endif
 
8283
  /*
 
8284
    The following change issues a deprecation warning if the slave
 
8285
    configuration is specified either in the my.cnf file or on
 
8286
    the command-line. See BUG#21490.
 
8287
  */
 
8288
  case OPT_MASTER_HOST:
 
8289
  case OPT_MASTER_USER:
 
8290
  case OPT_MASTER_PASSWORD:
 
8291
  case OPT_MASTER_PORT:
 
8292
  case OPT_MASTER_CONNECT_RETRY:
 
8293
  case OPT_MASTER_SSL:          
 
8294
  case OPT_MASTER_SSL_KEY:
 
8295
  case OPT_MASTER_SSL_CERT:       
 
8296
  case OPT_MASTER_SSL_CAPATH:
 
8297
  case OPT_MASTER_SSL_CIPHER:
 
8298
  case OPT_MASTER_SSL_CA:
 
8299
    if (!slave_warning_issued)                 //only show the warning once
 
8300
    {
 
8301
      slave_warning_issued = true;   
 
8302
      WARN_DEPRECATED(NULL, "6.0", "for replication startup options", 
 
8303
        "'CHANGE MASTER'");
 
8304
    }
 
8305
    break;
 
8306
  case OPT_CONSOLE:
 
8307
    if (opt_console)
 
8308
      opt_error_log= 0;                 // Force logs to stdout
 
8309
    break;
 
8310
  case (int) OPT_FLUSH:
 
8311
    myisam_flush=1;
 
8312
    flush_time=0;                       // No auto flush
 
8313
    break;
 
8314
  case OPT_LOW_PRIORITY_UPDATES:
 
8315
    thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY;
 
8316
    global_system_variables.low_priority_updates=1;
 
8317
    break;
 
8318
  case OPT_BOOTSTRAP:
 
8319
    opt_noacl=opt_bootstrap=1;
 
8320
    break;
 
8321
  case OPT_SERVER_ID:
 
8322
    server_id_supplied = 1;
 
8323
    break;
 
8324
  case OPT_DELAY_KEY_WRITE_ALL:
 
8325
    WARN_DEPRECATED(NULL, VER_CELOSIA, 
 
8326
                    "--delay-key-write-for-all-tables",
 
8327
                    "--delay-key-write=ALL");
 
8328
    if (argument != disabled_my_option)
 
8329
      argument= (char*) "ALL";
 
8330
    /* Fall through */
 
8331
  case OPT_DELAY_KEY_WRITE:
 
8332
    if (argument == disabled_my_option)
 
8333
      delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
 
8334
    else if (! argument)
 
8335
      delay_key_write_options= (uint) DELAY_KEY_WRITE_ON;
 
8336
    else
 
8337
    {
 
8338
      int type;
 
8339
      type= find_type_or_exit(argument, &delay_key_write_typelib, opt->name);
 
8340
      delay_key_write_options= (uint) type-1;
 
8341
    }
 
8342
    break;
 
8343
  case OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE:
 
8344
    sql_print_warning("--myisam_max_extra_sort_file_size is deprecated and "
 
8345
                      "does nothing in this version.  It will be removed in "
 
8346
                      "a future release.");
 
8347
    break;
 
8348
  case OPT_CHARSETS_DIR:
 
8349
    strmake(mysql_charsets_dir, argument, sizeof(mysql_charsets_dir)-1);
 
8350
    charsets_dir = mysql_charsets_dir;
 
8351
    break;
 
8352
  case OPT_TX_ISOLATION:
 
8353
  {
 
8354
    int type;
 
8355
    type= find_type_or_exit(argument, &tx_isolation_typelib, opt->name);
 
8356
    global_system_variables.tx_isolation= (type-1);
 
8357
    break;
 
8358
  }
 
8359
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
 
8360
  case OPT_NDB_MGMD:
 
8361
  case OPT_NDB_NODEID:
 
8362
  {
 
8363
    int len= my_snprintf(opt_ndb_constrbuf+opt_ndb_constrbuf_len,
 
8364
                         sizeof(opt_ndb_constrbuf)-opt_ndb_constrbuf_len,
 
8365
                         "%s%s%s",opt_ndb_constrbuf_len > 0 ? ",":"",
 
8366
                         optid == OPT_NDB_NODEID ? "nodeid=" : "",
 
8367
                         argument);
 
8368
    opt_ndb_constrbuf_len+= len;
 
8369
  }
 
8370
  /* fall through to add the connectstring to the end
 
8371
   * and set opt_ndbcluster_connectstring
 
8372
   */
 
8373
  case OPT_NDB_CONNECTSTRING:
 
8374
    if (opt_ndb_connectstring && opt_ndb_connectstring[0])
 
8375
      my_snprintf(opt_ndb_constrbuf+opt_ndb_constrbuf_len,
 
8376
                  sizeof(opt_ndb_constrbuf)-opt_ndb_constrbuf_len,
 
8377
                  "%s%s", opt_ndb_constrbuf_len > 0 ? ",":"",
 
8378
                  opt_ndb_connectstring);
 
8379
    else
 
8380
      opt_ndb_constrbuf[opt_ndb_constrbuf_len]= 0;
 
8381
    opt_ndbcluster_connectstring= opt_ndb_constrbuf;
 
8382
    break;
 
8383
  case OPT_NDB_DISTRIBUTION:
 
8384
    int id;
 
8385
    id= find_type_or_exit(argument, &ndb_distribution_typelib, opt->name);
 
8386
    opt_ndb_distribution_id= (enum ndb_distribution)(id-1);
 
8387
    break;
 
8388
  case OPT_NDB_EXTRA_LOGGING:
 
8389
    if (!argument)
 
8390
      ndb_extra_logging++;
 
8391
    else if (argument == disabled_my_option)
 
8392
      ndb_extra_logging= 0L;
 
8393
    else
 
8394
      ndb_extra_logging= atoi(argument);
 
8395
    break;
 
8396
#endif
 
8397
  case OPT_MYISAM_RECOVER:
 
8398
  {
 
8399
    if (!argument)
 
8400
    {
 
8401
      myisam_recover_options=    HA_RECOVER_DEFAULT;
 
8402
      myisam_recover_options_str= myisam_recover_typelib.type_names[0];
 
8403
    }
 
8404
    else if (!argument[0])
 
8405
    {
 
8406
      myisam_recover_options= HA_RECOVER_NONE;
 
8407
      myisam_recover_options_str= "OFF";
 
8408
    }
 
8409
    else
 
8410
    {
 
8411
      myisam_recover_options_str=argument;
 
8412
      myisam_recover_options=
 
8413
        find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name,
 
8414
                              &error);
 
8415
      if (error)
 
8416
        return 1;
 
8417
    }
 
8418
    ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
 
8419
    break;
 
8420
  }
 
8421
  case OPT_CONCURRENT_INSERT:
 
8422
    /* The following code is mainly here to emulate old behavior */
 
8423
    if (!argument)                      /* --concurrent-insert */
 
8424
      myisam_concurrent_insert= 1;
 
8425
    else if (argument == disabled_my_option)
 
8426
      myisam_concurrent_insert= 0;      /* --skip-concurrent-insert */
 
8427
    break;
 
8428
  case OPT_TC_HEURISTIC_RECOVER:
 
8429
    tc_heuristic_recover= find_type_or_exit(argument,
 
8430
                                            &tc_heuristic_recover_typelib,
 
8431
                                            opt->name);
 
8432
    break;
 
8433
  case OPT_MYISAM_STATS_METHOD:
 
8434
  {
 
8435
    ulong method_conv;
 
8436
    int method;
 
8437
    LINT_INIT(method_conv);
 
8438
 
 
8439
    myisam_stats_method_str= argument;
 
8440
    method= find_type_or_exit(argument, &myisam_stats_method_typelib,
 
8441
                              opt->name);
 
8442
    switch (method-1) {
 
8443
    case 2:
 
8444
      method_conv= MI_STATS_METHOD_IGNORE_NULLS;
 
8445
      break;
 
8446
    case 1:
 
8447
      method_conv= MI_STATS_METHOD_NULLS_EQUAL;
 
8448
      break;
 
8449
    case 0:
 
8450
    default:
 
8451
      method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
 
8452
      break;
 
8453
    }
 
8454
    global_system_variables.myisam_stats_method= method_conv;
 
8455
    break;
 
8456
  }
 
8457
  case OPT_SQL_MODE:
 
8458
  {
 
8459
    sql_mode_str= argument;
 
8460
    global_system_variables.sql_mode=
 
8461
      find_bit_type_or_exit(argument, &sql_mode_typelib, opt->name, &error);
 
8462
    if (error)
 
8463
      return 1;
 
8464
    global_system_variables.sql_mode= fix_sql_mode(global_system_variables.
 
8465
                                                   sql_mode);
 
8466
    break;
 
8467
  }
 
8468
  case OPT_OPTIMIZER_SWITCH:
 
8469
  {
 
8470
    bool not_used;
 
8471
    char *error= 0;
 
8472
    uint error_len= 0;
 
8473
    optimizer_switch_str= argument;
 
8474
    global_system_variables.optimizer_switch=
 
8475
      (ulong)find_set_from_flags(&optimizer_switch_typelib, 
 
8476
                                 optimizer_switch_typelib.count, 
 
8477
                                 global_system_variables.optimizer_switch,
 
8478
                                 global_system_variables.optimizer_switch,
 
8479
                                 argument, strlen(argument), NULL,
 
8480
                                 &error, &error_len, &not_used);
 
8481
     if (error)
 
8482
     {
 
8483
       char buf[512];
 
8484
       char *cbuf= buf;
 
8485
       cbuf += my_snprintf(buf, 512, "Error in parsing optimizer_switch setting near %*s\n", error_len, error);
 
8486
       sql_perror(buf);
 
8487
       return 1;
 
8488
     }
 
8489
    break;
 
8490
  }
 
8491
  case OPT_ONE_THREAD:
 
8492
    global_system_variables.thread_handling=
 
8493
      SCHEDULER_ONE_THREAD_PER_CONNECTION;
 
8494
    break;
 
8495
  case OPT_THREAD_HANDLING:
 
8496
  {
 
8497
    global_system_variables.thread_handling=
 
8498
      find_type_or_exit(argument, &thread_handling_typelib, opt->name)-1;
 
8499
    break;
 
8500
  }
 
8501
  case OPT_FT_BOOLEAN_SYNTAX:
 
8502
    if (ft_boolean_check_syntax_string((uchar*) argument))
 
8503
    {
 
8504
      sql_print_error("Invalid ft-boolean-syntax string: %s\n", argument);
 
8505
      return 1;
 
8506
    }
 
8507
    strmake(ft_boolean_syntax, argument, sizeof(ft_boolean_syntax)-1);
 
8508
    break;
 
8509
  case OPT_SKIP_SAFEMALLOC:
 
8510
#ifdef SAFEMALLOC
 
8511
    sf_malloc_quick=1;
 
8512
#endif
 
8513
    break;
 
8514
  case OPT_LOWER_CASE_TABLE_NAMES:
 
8515
    lower_case_table_names= argument ? atoi(argument) : 1;
 
8516
    lower_case_table_names_used= 1;
 
8517
    break;
 
8518
#if defined(ENABLED_DEBUG_SYNC)
 
8519
  case OPT_DEBUG_SYNC_TIMEOUT:
 
8520
    /*
 
8521
      Debug Sync Facility. See debug_sync.cc.
 
8522
      Default timeout for WAIT_FOR action.
 
8523
      Default value is zero (facility disabled).
 
8524
      If option is given without an argument, supply a non-zero value.
 
8525
    */
 
8526
    if (!argument)
 
8527
    {
 
8528
      /* purecov: begin tested */
 
8529
      opt_debug_sync_timeout= DEBUG_SYNC_DEFAULT_WAIT_TIMEOUT;
 
8530
      /* purecov: end */
 
8531
    }
 
8532
    break;
 
8533
#endif /* defined(ENABLED_DEBUG_SYNC) */
 
8534
  }
 
8535
  return 0;
 
8536
}
 
8537
 
 
8538
 
 
8539
/** Handle arguments for multiple key caches. */
 
8540
 
 
8541
extern "C" int mysql_getopt_value(uchar **value,
 
8542
                                  const char *keyname, uint key_length,
 
8543
                                  const struct my_option *option,
 
8544
                                  int *error);
 
8545
 
 
8546
static uchar* *
 
8547
mysql_getopt_value(const char *keyname, uint key_length,
 
8548
                   const struct my_option *option, int *error)
 
8549
{
 
8550
  if (error)
 
8551
    *error= 0;
 
8552
  switch (option->id) {
 
8553
  case OPT_KEY_BUFFER_SIZE:
 
8554
  case OPT_KEY_CACHE_BLOCK_SIZE:
 
8555
  case OPT_KEY_CACHE_DIVISION_LIMIT:
 
8556
  case OPT_KEY_CACHE_AGE_THRESHOLD:
 
8557
  {
 
8558
    KEY_CACHE *key_cache;
 
8559
    if (!(key_cache= get_or_create_key_cache(keyname, key_length)))
 
8560
    {
 
8561
      if (error)
 
8562
        *error= EXIT_OUT_OF_MEMORY;
 
8563
      return 0;
 
8564
    }
 
8565
    switch (option->id) {
 
8566
    case OPT_KEY_BUFFER_SIZE:
 
8567
      return (uchar**) &key_cache->param_buff_size;
 
8568
    case OPT_KEY_CACHE_BLOCK_SIZE:
 
8569
      return (uchar**) &key_cache->param_block_size;
 
8570
    case OPT_KEY_CACHE_DIVISION_LIMIT:
 
8571
      return (uchar**) &key_cache->param_division_limit;
 
8572
    case OPT_KEY_CACHE_AGE_THRESHOLD:
 
8573
      return (uchar**) &key_cache->param_age_threshold;
 
8574
    }
 
8575
  }
 
8576
  }
 
8577
  return option->value;
 
8578
}
 
8579
 
 
8580
 
 
8581
extern "C" void option_error_reporter(enum loglevel level, const char *format, ...);
 
8582
 
 
8583
void option_error_reporter(enum loglevel level, const char *format, ...)
 
8584
{
 
8585
  va_list args;
 
8586
  va_start(args, format);
 
8587
 
 
8588
  /* Don't print warnings for --loose options during bootstrap */
 
8589
  if (level == ERROR_LEVEL || !opt_bootstrap ||
 
8590
      global_system_variables.log_warnings)
 
8591
  {
 
8592
    vprint_msg_to_log(level, format, args);
 
8593
  }
 
8594
  va_end(args);
 
8595
}
 
8596
 
 
8597
 
 
8598
/**
 
8599
  @todo
 
8600
  - FIXME add EXIT_TOO_MANY_ARGUMENTS to "mysys_err.h" and return that code?
 
8601
*/
 
8602
static int get_options(int *argc,char **argv)
 
8603
{
 
8604
  int ho_error;
 
8605
 
 
8606
  my_getopt_register_get_addr(mysql_getopt_value);
 
8607
  strmake(def_ft_boolean_syntax, ft_boolean_syntax,
 
8608
          sizeof(ft_boolean_syntax)-1);
 
8609
  my_getopt_error_reporter= option_error_reporter;
 
8610
 
 
8611
  /* Skip unknown options so that they may be processed later by plugins */
 
8612
  my_getopt_skip_unknown= TRUE;
 
8613
 
 
8614
  if ((ho_error= handle_options(argc, &argv, my_long_options,
 
8615
                                mysqld_get_one_option)))
 
8616
    return ho_error;
 
8617
  (*argc)++; /* add back one for the progname handle_options removes */
 
8618
             /* no need to do this for argv as we are discarding it. */
 
8619
 
 
8620
  if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes ||
 
8621
       opt_log_slow_slave_statements) &&
 
8622
      !opt_slow_log)
 
8623
    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");
 
8624
 
 
8625
#if defined(HAVE_BROKEN_REALPATH)
 
8626
  my_use_symdir=0;
 
8627
  my_disable_symlinks=1;
 
8628
  have_symlink=SHOW_OPTION_NO;
 
8629
#else
 
8630
  if (!my_use_symdir)
 
8631
  {
 
8632
    my_disable_symlinks=1;
 
8633
    have_symlink=SHOW_OPTION_DISABLED;
 
8634
  }
 
8635
#endif
 
8636
  if (opt_debugging)
 
8637
  {
 
8638
    /* Allow break with SIGINT, no core or stack trace */
 
8639
    test_flags|= TEST_SIGINT | TEST_NO_STACKTRACE;
 
8640
    test_flags&= ~TEST_CORE_ON_SIGNAL;
 
8641
  }
 
8642
  /* Set global MyISAM variables from delay_key_write_options */
 
8643
  fix_delay_key_write((THD*) 0, OPT_GLOBAL);
 
8644
  /* Set global slave_exec_mode from its option */
 
8645
  fix_slave_exec_mode(OPT_GLOBAL);
 
8646
 
 
8647
#ifndef EMBEDDED_LIBRARY
 
8648
  if (mysqld_chroot)
 
8649
    set_root(mysqld_chroot);
 
8650
#else
 
8651
  global_system_variables.thread_handling = SCHEDULER_NO_THREADS;
 
8652
  max_allowed_packet= global_system_variables.max_allowed_packet;
 
8653
  net_buffer_length= global_system_variables.net_buffer_length;
 
8654
#endif
 
8655
  if (fix_paths())
 
8656
    return 1;
 
8657
 
 
8658
  /*
 
8659
    Set some global variables from the global_system_variables
 
8660
    In most cases the global variables will not be used
 
8661
  */
 
8662
  my_disable_locking= myisam_single_user= test(opt_external_locking == 0);
 
8663
  my_default_record_cache_size=global_system_variables.read_buff_size;
 
8664
  myisam_max_temp_length=
 
8665
    (my_off_t) global_system_variables.myisam_max_sort_file_size;
 
8666
 
 
8667
  /* Set global variables based on startup options */
 
8668
  myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size);
 
8669
 
 
8670
  /* long_query_time is in microseconds */
 
8671
  global_system_variables.long_query_time= max_system_variables.long_query_time=
 
8672
    (longlong) (long_query_time * 1000000.0);
 
8673
 
 
8674
  if (opt_short_log_format)
 
8675
    opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT;
 
8676
 
 
8677
  if (init_global_datetime_format(MYSQL_TIMESTAMP_DATE,
 
8678
                                  &global_system_variables.date_format) ||
 
8679
      init_global_datetime_format(MYSQL_TIMESTAMP_TIME,
 
8680
                                  &global_system_variables.time_format) ||
 
8681
      init_global_datetime_format(MYSQL_TIMESTAMP_DATETIME,
 
8682
                                  &global_system_variables.datetime_format))
 
8683
    return 1;
 
8684
 
 
8685
#ifdef EMBEDDED_LIBRARY
 
8686
  one_thread_scheduler(&thread_scheduler);
 
8687
#else
 
8688
  if (global_system_variables.thread_handling <=
 
8689
      SCHEDULER_ONE_THREAD_PER_CONNECTION)
 
8690
    one_thread_per_connection_scheduler(&thread_scheduler);
 
8691
  else if (global_system_variables.thread_handling == SCHEDULER_NO_THREADS)
 
8692
    one_thread_scheduler(&thread_scheduler);
 
8693
  else
 
8694
    pool_of_threads_scheduler(&thread_scheduler);  /* purecov: tested */
 
8695
#endif
 
8696
  return 0;
 
8697
}
 
8698
 
 
8699
 
 
8700
/*
 
8701
  Create version name for running mysqld version
 
8702
  We automaticly add suffixes -debug, -embedded and -log to the version
 
8703
  name to make the version more descriptive.
 
8704
  (MYSQL_SERVER_SUFFIX is set by the compilation environment)
 
8705
*/
 
8706
 
 
8707
static void set_server_version(void)
 
8708
{
 
8709
  char *end= strxmov(server_version, MYSQL_SERVER_VERSION,
 
8710
                     MYSQL_SERVER_SUFFIX_STR, NullS);
 
8711
#ifdef EMBEDDED_LIBRARY
 
8712
  end= strmov(end, "-embedded");
 
8713
#endif
 
8714
#ifndef DBUG_OFF
 
8715
  if (!strstr(MYSQL_SERVER_SUFFIX_STR, "-debug"))
 
8716
    end= strmov(end, "-debug");
 
8717
#endif
 
8718
  if (opt_log || opt_update_log || opt_slow_log || opt_bin_log)
 
8719
    strmov(end, "-log");                        // This may slow down system
 
8720
}
 
8721
 
 
8722
 
 
8723
static char *get_relative_path(const char *path)
 
8724
{
 
8725
  if (test_if_hard_path(path) &&
 
8726
      is_prefix(path,DEFAULT_MYSQL_HOME) &&
 
8727
      strcmp(DEFAULT_MYSQL_HOME,FN_ROOTDIR))
 
8728
  {
 
8729
    path+=(uint) strlen(DEFAULT_MYSQL_HOME);
 
8730
    while (*path == FN_LIBCHAR)
 
8731
      path++;
 
8732
  }
 
8733
  return (char*) path;
 
8734
}
 
8735
 
 
8736
 
 
8737
/**
 
8738
  Fix filename and replace extension where 'dir' is relative to
 
8739
  mysql_real_data_home.
 
8740
  @return
 
8741
    1 if len(path) > FN_REFLEN
 
8742
*/
 
8743
 
 
8744
bool
 
8745
fn_format_relative_to_data_home(char * to, const char *name,
 
8746
                                const char *dir, const char *extension)
 
8747
{
 
8748
  char tmp_path[FN_REFLEN];
 
8749
  if (!test_if_hard_path(dir))
 
8750
  {
 
8751
    strxnmov(tmp_path,sizeof(tmp_path)-1, mysql_real_data_home,
 
8752
             dir, NullS);
 
8753
    dir=tmp_path;
 
8754
  }
 
8755
  return !fn_format(to, name, dir, extension,
 
8756
                    MY_APPEND_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH);
 
8757
}
 
8758
 
 
8759
 
 
8760
static int fix_paths(void)
 
8761
{
 
8762
  char buff[FN_REFLEN],*pos;
 
8763
  convert_dirname(mysql_home,mysql_home,NullS);
 
8764
  /* Resolve symlinks to allow 'mysql_home' to be a relative symlink */
 
8765
  my_realpath(mysql_home,mysql_home,MYF(0));
 
8766
  /* Ensure that mysql_home ends in FN_LIBCHAR */
 
8767
  pos=strend(mysql_home);
 
8768
  if (pos[-1] != FN_LIBCHAR)
 
8769
  {
 
8770
    pos[0]= FN_LIBCHAR;
 
8771
    pos[1]= 0;
 
8772
  }
 
8773
  convert_dirname(language,language,NullS);
 
8774
  convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
 
8775
  (void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir
 
8776
  (void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home);
 
8777
  (void) my_load_path(pidfile_name,pidfile_name,mysql_real_data_home);
 
8778
  (void) my_load_path(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr :
 
8779
                                      get_relative_path(PLUGINDIR), mysql_home);
 
8780
  opt_plugin_dir_ptr= opt_plugin_dir;
 
8781
 
 
8782
  my_realpath(mysql_unpacked_real_data_home, mysql_real_data_home, MYF(0));
 
8783
  mysql_unpacked_real_data_home_len= 
 
8784
    (int) strlen(mysql_unpacked_real_data_home);
 
8785
  if (mysql_unpacked_real_data_home[mysql_unpacked_real_data_home_len-1] == FN_LIBCHAR)
 
8786
    --mysql_unpacked_real_data_home_len;
 
8787
 
 
8788
  char *sharedir=get_relative_path(SHAREDIR);
 
8789
  if (test_if_hard_path(sharedir))
 
8790
    strmake(buff,sharedir,sizeof(buff)-1);              /* purecov: tested */
 
8791
  else
 
8792
    strxnmov(buff,sizeof(buff)-1,mysql_home,sharedir,NullS);
 
8793
  convert_dirname(buff,buff,NullS);
 
8794
  (void) my_load_path(language,language,buff);
 
8795
 
 
8796
  /* If --character-sets-dir isn't given, use shared library dir */
 
8797
  if (charsets_dir != mysql_charsets_dir)
 
8798
  {
 
8799
    strxnmov(mysql_charsets_dir, sizeof(mysql_charsets_dir)-1, buff,
 
8800
             CHARSET_DIR, NullS);
 
8801
  }
 
8802
  (void) my_load_path(mysql_charsets_dir, mysql_charsets_dir, buff);
 
8803
  convert_dirname(mysql_charsets_dir, mysql_charsets_dir, NullS);
 
8804
  charsets_dir=mysql_charsets_dir;
 
8805
 
 
8806
  if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir))
 
8807
    return 1;
 
8808
#ifdef HAVE_REPLICATION
 
8809
  if (!slave_load_tmpdir)
 
8810
  {
 
8811
    if (!(slave_load_tmpdir = (char*) my_strdup(mysql_tmpdir, MYF(MY_FAE))))
 
8812
      return 1;
 
8813
  }
 
8814
#endif /* HAVE_REPLICATION */
 
8815
  /*
 
8816
    Convert the secure-file-priv option to system format, allowing
 
8817
    a quick strcmp to check if read or write is in an allowed dir
 
8818
   */
 
8819
  if (opt_secure_file_priv)
 
8820
  {
 
8821
    convert_dirname(buff, opt_secure_file_priv, NullS);
 
8822
    my_free(opt_secure_file_priv, MYF(0));
 
8823
    opt_secure_file_priv= my_strdup(buff, MYF(MY_FAE));
 
8824
  }
 
8825
  return 0;
 
8826
}
 
8827
 
 
8828
 
 
8829
static ulong find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
 
8830
                                   const char *option, int *error)
 
8831
{
 
8832
  ulong result;
 
8833
  const char **ptr;
 
8834
  
 
8835
  *error= 0;
 
8836
  if ((result= find_bit_type(x, bit_lib)) == ~(ulong) 0)
 
8837
  {
 
8838
    char *buff= (char *) my_alloca(2048);
 
8839
    char *cbuf;
 
8840
    ptr= bit_lib->type_names;
 
8841
    cbuf= buff + ((!*x) ?
 
8842
      my_snprintf(buff, 2048, "No option given to %s\n", option) :
 
8843
      my_snprintf(buff, 2048, "Wrong option to %s. Option(s) given: %s\n",
 
8844
                  option, x));
 
8845
    cbuf+= my_snprintf(cbuf, 2048 - (cbuf-buff), "Alternatives are: '%s'", *ptr);
 
8846
    while (*++ptr)
 
8847
      cbuf+= my_snprintf(cbuf, 2048 - (cbuf-buff), ",'%s'", *ptr);
 
8848
    my_snprintf(cbuf, 2048 - (cbuf-buff), "\n");
 
8849
    sql_perror(buff);
 
8850
    *error= 1;
 
8851
    my_afree(buff);
 
8852
    return 0;
 
8853
  }
 
8854
 
 
8855
  return result;
 
8856
}
 
8857
 
 
8858
 
 
8859
/**
 
8860
  @return
 
8861
    a bitfield from a string of substrings separated by ','
 
8862
    or
 
8863
    ~(ulong) 0 on error.
 
8864
*/
 
8865
 
 
8866
static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
 
8867
{
 
8868
  bool found_end;
 
8869
  int  found_count;
 
8870
  const char *end,*i,*j;
 
8871
  const char **array, *pos;
 
8872
  ulong found,found_int,bit;
 
8873
  DBUG_ENTER("find_bit_type");
 
8874
  DBUG_PRINT("enter",("x: '%s'",x));
 
8875
 
 
8876
  found=0;
 
8877
  found_end= 0;
 
8878
  pos=(char *) x;
 
8879
  while (*pos == ' ') pos++;
 
8880
  found_end= *pos == 0;
 
8881
  while (!found_end)
 
8882
  {
 
8883
    if (!*(end=strcend(pos,',')))               /* Let end point at fieldend */
 
8884
    {
 
8885
      while (end > pos && end[-1] == ' ')
 
8886
        end--;                                  /* Skip end-space */
 
8887
      found_end=1;
 
8888
    }
 
8889
    found_int=0; found_count=0;
 
8890
    for (array=bit_lib->type_names, bit=1 ; (i= *array++) ; bit<<=1)
 
8891
    {
 
8892
      j=pos;
 
8893
      while (j != end)
 
8894
      {
 
8895
        if (my_toupper(mysqld_charset,*i++) !=
 
8896
            my_toupper(mysqld_charset,*j++))
 
8897
          goto skip;
 
8898
      }
 
8899
      found_int=bit;
 
8900
      if (! *i)
 
8901
      {
 
8902
        found_count=1;
 
8903
        break;
 
8904
      }
 
8905
      else if (j != pos)                        // Half field found
 
8906
      {
 
8907
        found_count++;                          // Could be one of two values
 
8908
      }
 
8909
skip: ;
 
8910
    }
 
8911
    if (found_count != 1)
 
8912
      DBUG_RETURN(~(ulong) 0);                          // No unique value
 
8913
    found|=found_int;
 
8914
    pos=end+1;
 
8915
  }
 
8916
 
 
8917
  DBUG_PRINT("exit",("bit-field: %ld",(ulong) found));
 
8918
  DBUG_RETURN(found);
 
8919
} /* find_bit_type */
 
8920
 
 
8921
 
 
8922
/**
 
8923
  Check if file system used for databases is case insensitive.
 
8924
 
 
8925
  @param dir_name                       Directory to test
 
8926
 
 
8927
  @retval
 
8928
    -1  Don't know (Test failed)
 
8929
  @retval
 
8930
    0   File system is case sensitive
 
8931
  @retval
 
8932
    1   File system is case insensitive
 
8933
*/
 
8934
 
 
8935
static int test_if_case_insensitive(const char *dir_name)
 
8936
{
 
8937
  int result= 0;
 
8938
  File file;
 
8939
  char buff[FN_REFLEN], buff2[FN_REFLEN];
 
8940
  MY_STAT stat_info;
 
8941
  DBUG_ENTER("test_if_case_insensitive");
 
8942
 
 
8943
  fn_format(buff, glob_hostname, dir_name, ".lower-test",
 
8944
            MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_REPLACE_DIR);
 
8945
  fn_format(buff2, glob_hostname, dir_name, ".LOWER-TEST",
 
8946
            MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_REPLACE_DIR);
 
8947
  (void) my_delete(buff2, MYF(0));
 
8948
  if ((file= my_create(buff, 0666, O_RDWR, MYF(0))) < 0)
 
8949
  {
 
8950
    sql_print_warning("Can't create test file %s", buff);
 
8951
    DBUG_RETURN(-1);
 
8952
  }
 
8953
  my_close(file, MYF(0));
 
8954
  if (my_stat(buff2, &stat_info, MYF(0)))
 
8955
    result= 1;                                  // Can access file
 
8956
  (void) my_delete(buff, MYF(MY_WME));
 
8957
  DBUG_PRINT("exit", ("result: %d", result));
 
8958
  DBUG_RETURN(result);
 
8959
}
 
8960
 
 
8961
 
 
8962
#ifndef EMBEDDED_LIBRARY
 
8963
 
 
8964
/**
 
8965
  Create file to store pid number.
 
8966
*/
 
8967
static void create_pid_file()
 
8968
{
 
8969
  File file;
 
8970
  if ((file = my_create(pidfile_name,0664,
 
8971
                        O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0)
 
8972
  {
 
8973
    char buff[21], *end;
 
8974
    end= int10_to_str((long) getpid(), buff, 10);
 
8975
    *end++= '\n';
 
8976
    if (!my_write(file, (uchar*) buff, (uint) (end-buff), MYF(MY_WME | MY_NABP)))
 
8977
    {
 
8978
      (void) my_close(file, MYF(0));
 
8979
      return;
 
8980
    }
 
8981
    (void) my_close(file, MYF(0));
 
8982
  }
 
8983
  sql_perror("Can't start server: can't create PID file");
 
8984
  exit(1);
 
8985
}
 
8986
#endif /* EMBEDDED_LIBRARY */
 
8987
 
 
8988
/** Clear most status variables. */
 
8989
void refresh_status(THD *thd)
 
8990
{
 
8991
  pthread_mutex_lock(&LOCK_status);
 
8992
 
 
8993
  /* Add thread's status variabes to global status */
 
8994
  add_to_status(&global_status_var, &thd->status_var);
 
8995
 
 
8996
  /* Reset thread's status variables */
 
8997
  bzero((uchar*) &thd->status_var, sizeof(thd->status_var));
 
8998
 
 
8999
  /* Reset some global variables */
 
9000
  reset_status_vars();
 
9001
 
 
9002
  /* Reset the counters of all key caches (default and named). */
 
9003
  process_key_caches(reset_key_cache_counters);
 
9004
#ifdef COMMUNITY_SERVER
 
9005
  flush_status_time= time((time_t*) 0);
 
9006
#endif
 
9007
  pthread_mutex_unlock(&LOCK_status);
 
9008
 
 
9009
  /*
 
9010
    Set max_used_connections to the number of currently open
 
9011
    connections.  Lock LOCK_thread_count out of LOCK_status to avoid
 
9012
    deadlocks.  Status reset becomes not atomic, but status data is
 
9013
    not exact anyway.
 
9014
  */
 
9015
  pthread_mutex_lock(&LOCK_thread_count);
 
9016
  max_used_connections= thread_count-delayed_insert_threads;
 
9017
  pthread_mutex_unlock(&LOCK_thread_count);
 
9018
}
 
9019
 
 
9020
 
 
9021
/*****************************************************************************
 
9022
  Instantiate variables for missing storage engines
 
9023
  This section should go away soon
 
9024
*****************************************************************************/
 
9025
 
 
9026
#ifndef WITH_NDBCLUSTER_STORAGE_ENGINE
 
9027
ulong ndb_cache_check_time;
 
9028
ulong ndb_extra_logging;
 
9029
#endif
 
9030
 
 
9031
/*****************************************************************************
 
9032
  Instantiate templates
 
9033
*****************************************************************************/
 
9034
 
 
9035
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
 
9036
/* Used templates */
 
9037
template class I_List<THD>;
 
9038
template class I_List_iterator<THD>;
 
9039
template class I_List<i_string>;
 
9040
template class I_List<i_string_pair>;
 
9041
template class I_List<NAMED_LIST>;
 
9042
template class I_List<Statement>;
 
9043
template class I_List_iterator<Statement>;
 
9044
#endif