~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/drizzled.cc

  • Committer: Monty Taylor
  • Date: 2008-10-23 00:05:28 UTC
  • Revision ID: monty@inaugust.com-20081023000528-grdvrd8c4058nutm
Moved my_handler to myisam, which is where it actually belongs.

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