~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/drizzled.cc

Renamed strings to mystrings, for include/lib naming consistency.

Show diffs side-by-side

added added

removed removed

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