~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/drizzled.cc

  • Committer: Monty Taylor
  • Date: 2008-11-16 05:36:13 UTC
  • mto: (584.1.9 devel)
  • mto: This revision was merged to the branch mainline in revision 589.
  • Revision ID: monty@inaugust.com-20081116053613-bld4rqxhlkb49c02
Split out cache_row and type_holder.

Show diffs side-by-side

added added

removed removed

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