~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/drizzled.cc

  • Committer: Jay Pipes
  • Date: 2008-12-18 15:55:03 UTC
  • mto: This revision was merged to the branch mainline in revision 717.
  • Revision ID: jpipes@serialcoder-20081218155503-u45ygyunrdyyvquq
Fix for Bug#308457.  Gave UTF8 enclosure and escape character on LOAD DATA INFILE and changed the error message to be more descriptive

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