1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
#include <drizzled/configmake.h>
22
#include <drizzled/atomics.h>
25
#include <sys/types.h>
26
#include <netinet/tcp.h>
27
#include <netinet/in.h>
31
#include "drizzled/internal/my_sys.h"
32
#include "drizzled/internal/my_bit.h"
33
#include <drizzled/my_hash.h>
34
#include <drizzled/stacktrace.h>
35
#include <drizzled/error.h>
36
#include <drizzled/errmsg_print.h>
37
#include <drizzled/tztime.h>
38
#include <drizzled/sql_base.h>
39
#include <drizzled/show.h>
40
#include <drizzled/sql_parse.h>
41
#include <drizzled/item/cmpfunc.h>
42
#include <drizzled/session.h>
43
#include <drizzled/item/create.h>
44
#include <drizzled/unireg.h>
45
#include "drizzled/temporal_format.h" /* For init_temporal_formats() */
46
#include "drizzled/plugin/listen.h"
47
#include "drizzled/plugin/error_message.h"
48
#include "drizzled/plugin/client.h"
49
#include "drizzled/plugin/scheduler.h"
50
#include "drizzled/plugin/xa_resource_manager.h"
51
#include "drizzled/plugin/monitored_in_transaction.h"
52
#include "drizzled/probes.h"
53
#include "drizzled/session_list.h"
54
#include "drizzled/charset.h"
55
#include "plugin/myisam/myisam.h"
57
#include <google/protobuf/stubs/common.h>
59
#if TIME_WITH_SYS_TIME
60
# include <sys/time.h>
64
# include <sys/time.h>
70
#ifdef HAVE_SYS_PRCTL_H
71
#include <sys/prctl.h>
73
#include <sys/socket.h>
80
#include "drizzled/my_getopt.h"
84
#include <pwd.h> // For getpwent
87
#include <sys/resource.h>
93
#ifdef HAVE_SYS_SELECT_H
94
#include <sys/select.h>
97
#include <sys/utsname.h>
99
#ifdef HAVE_SYS_MMAN_H
100
#include <sys/mman.h>
103
#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
105
#endif /* __FreeBSD__ && HAVE_IEEEFP_H */
107
#ifdef HAVE_FPU_CONTROL_H
108
#include <fpu_control.h>
111
#ifdef HAVE_SYS_FPU_H
112
/* for IRIX to use set_fpc_csr() */
116
#include "drizzled/internal/my_pthread.h" // For thr_setconcurency()
118
#include <drizzled/gettext.h>
122
#define IF_PURIFY(A,B) (A)
124
#define IF_PURIFY(A,B) (B)
127
#define MAX_MEM_TABLE_SIZE SIZE_MAX
134
#define mysqld_charset &my_charset_utf8_general_ci
135
inline void setup_fpu()
137
#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
139
We can't handle floating point exceptions with threads, so disable
141
Don't fall for overflow, underflow,divide-by-zero or loss of precision
143
#if defined(__i386__)
144
fpsetmask(~(FP_X_INV | FP_X_DNML | FP_X_OFL | FP_X_UFL | FP_X_DZ |
147
fpsetmask(~(FP_X_INV | FP_X_OFL | FP_X_UFL | FP_X_DZ |
149
#endif /* __i386__ */
150
#endif /* __FreeBSD__ && HAVE_IEEEFP_H */
153
x86 (32-bit) requires FPU precision to be explicitly set to 64 bit for
154
portable results of floating point operations
156
#if defined(__i386__) && defined(HAVE_FPU_CONTROL_H) && defined(_FPU_DOUBLE)
159
cw= (cw & ~_FPU_EXTENDED) | _FPU_DOUBLE;
161
#endif /* __i386__ && HAVE_FPU_CONTROL_H && _FPU_DOUBLE */
165
extern "C" int gethostname(char *name, int namelen);
169
static const char *tc_heuristic_recover_names[]=
171
"COMMIT", "ROLLBACK", NULL
173
static TYPELIB tc_heuristic_recover_typelib=
175
array_elements(tc_heuristic_recover_names)-1,"",
176
tc_heuristic_recover_names, NULL
179
const char *first_keyword= "first";
180
const char * const DRIZZLE_CONFIG_NAME= "drizzled";
181
#define GET_HA_ROWS GET_ULL
183
const char *tx_isolation_names[] =
184
{ "READ-UNCOMMITTED", "READ-COMMITTED", "REPEATABLE-READ", "SERIALIZABLE",
187
TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"",
188
tx_isolation_names, NULL};
191
Used with --help for detailed option
193
static bool opt_help= false;
194
static bool opt_help_extended= false;
196
arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
197
{{&Arg_comparator::compare_string, &Arg_comparator::compare_e_string},
198
{&Arg_comparator::compare_real, &Arg_comparator::compare_e_real},
199
{&Arg_comparator::compare_int_signed, &Arg_comparator::compare_e_int},
200
{&Arg_comparator::compare_row, &Arg_comparator::compare_e_row},
201
{&Arg_comparator::compare_decimal, &Arg_comparator::compare_e_decimal}};
203
/* static variables */
205
static bool volatile select_thread_in_use;
206
static bool volatile ready_to_exit;
207
static bool opt_debugging= 0;
208
static uint32_t wake_thread;
209
static uint32_t killed_threads;
210
static char *drizzled_user, *drizzled_chroot;
211
static char *language_ptr;
212
static const char *default_character_set_name;
213
static const char *character_set_filesystem_name;
214
static char *lc_time_names_name;
215
static char *default_collation_name;
216
static char *default_storage_engine_str;
217
static const char *compiled_default_collation_name= "utf8_general_ci";
219
/* Global variables */
221
bool volatile abort_loop;
222
bool volatile shutdown_in_progress;
223
uint32_t max_used_connections;
224
const string opt_scheduler_default("multi_thread");
225
char *opt_scheduler= NULL;
227
size_t my_thread_stack_size= 65536;
230
Legacy global plugin::StorageEngine. These will be removed (please do not add more).
232
plugin::StorageEngine *heap_engine;
233
plugin::StorageEngine *myisam_engine;
235
char* opt_secure_file_priv= 0;
237
static bool calling_initgroups= false; /**< Used in SIGSEGV handler. */
239
uint32_t drizzled_bind_timeout;
240
std::bitset<12> test_flags;
241
uint32_t dropping_tables, ha_open_options;
242
uint32_t tc_heuristic_recover= 0;
243
uint64_t session_startup_options;
246
uint64_t table_cache_size;
247
size_t table_def_size;
248
uint64_t aborted_threads;
249
uint64_t aborted_connects;
250
uint64_t max_connect_errors;
251
uint32_t global_thread_id= 1UL;
254
extern const double log_10[309];
256
const double log_10[] = {
257
1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007, 1e008, 1e009,
258
1e010, 1e011, 1e012, 1e013, 1e014, 1e015, 1e016, 1e017, 1e018, 1e019,
259
1e020, 1e021, 1e022, 1e023, 1e024, 1e025, 1e026, 1e027, 1e028, 1e029,
260
1e030, 1e031, 1e032, 1e033, 1e034, 1e035, 1e036, 1e037, 1e038, 1e039,
261
1e040, 1e041, 1e042, 1e043, 1e044, 1e045, 1e046, 1e047, 1e048, 1e049,
262
1e050, 1e051, 1e052, 1e053, 1e054, 1e055, 1e056, 1e057, 1e058, 1e059,
263
1e060, 1e061, 1e062, 1e063, 1e064, 1e065, 1e066, 1e067, 1e068, 1e069,
264
1e070, 1e071, 1e072, 1e073, 1e074, 1e075, 1e076, 1e077, 1e078, 1e079,
265
1e080, 1e081, 1e082, 1e083, 1e084, 1e085, 1e086, 1e087, 1e088, 1e089,
266
1e090, 1e091, 1e092, 1e093, 1e094, 1e095, 1e096, 1e097, 1e098, 1e099,
267
1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109,
268
1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119,
269
1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129,
270
1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139,
271
1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149,
272
1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159,
273
1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169,
274
1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179,
275
1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189,
276
1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199,
277
1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209,
278
1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219,
279
1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229,
280
1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239,
281
1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249,
282
1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259,
283
1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269,
284
1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279,
285
1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289,
286
1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299,
287
1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308
290
time_t server_start_time;
291
time_t flush_status_time;
293
char drizzle_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
294
char *default_tz_name;
295
char glob_hostname[FN_REFLEN];
296
char drizzle_real_data_home[FN_REFLEN],
299
char drizzle_unpacked_real_data_home[FN_REFLEN];
300
const key_map key_map_empty(0);
301
key_map key_map_full(0); // Will be initialized later
303
uint32_t drizzle_data_home_len;
304
char drizzle_data_home_buff[2], *drizzle_data_home=drizzle_real_data_home;
305
char *drizzle_tmpdir= NULL;
306
char *opt_drizzle_tmpdir= NULL;
308
/** name of reference on left espression in rewritten IN subquery */
309
const char *in_left_expr_name= "<left expr>";
310
/** name of additional condition */
311
const char *in_additional_cond= "<IN COND>";
312
const char *in_having_cond= "<IN HAVING>";
314
my_decimal decimal_zero;
315
/* classes for comparation parsing/processing */
317
FILE *stderror_file=0;
319
struct system_variables global_system_variables;
320
struct system_variables max_system_variables;
321
struct system_status_var global_status_var;
323
const CHARSET_INFO *system_charset_info, *files_charset_info ;
324
const CHARSET_INFO *table_alias_charset;
325
const CHARSET_INFO *character_set_filesystem;
327
MY_LOCALE *my_default_lc_time_names;
329
SHOW_COMP_OPTION have_symlink;
331
/* Thread specific variables */
333
pthread_key_t THR_Mem_root;
334
pthread_key_t THR_Session;
335
pthread_mutex_t LOCK_create_db;
336
pthread_mutex_t LOCK_open;
337
pthread_mutex_t LOCK_thread_count;
338
pthread_mutex_t LOCK_status;
339
pthread_mutex_t LOCK_global_read_lock;
340
pthread_mutex_t LOCK_global_system_variables;
342
pthread_rwlock_t LOCK_system_variables_hash;
343
pthread_cond_t COND_refresh, COND_thread_count, COND_global_read_lock;
344
pthread_t signal_thread;
345
pthread_cond_t COND_server_end;
347
/* Static variables */
349
static bool segfaulted;
350
#ifdef HAVE_STACK_TRACE_ON_SEGV
351
static bool opt_do_pstack;
352
#endif /* HAVE_STACK_TRACE_ON_SEGV */
354
static char *drizzle_home_ptr, *pidfile_name_ptr;
355
static int defaults_argc;
356
static char **defaults_argv;
358
struct passwd *user_info;
359
static pthread_t select_thread;
360
static uint32_t thr_kill_signal;
363
Number of currently active user connections. The variable is protected by
366
atomic<uint32_t> connection_count;
369
Refresh value. We use to test this to find out if a refresh even has happened recently.
371
uint64_t refresh_version; /* Increments on each reload */
373
/* Function declarations */
374
bool drizzle_rm_tmp_tables();
376
extern "C" pthread_handler_t signal_hand(void *arg);
377
static void drizzle_init_variables(void);
378
static void get_options(int *argc,char **argv);
379
bool drizzled_get_one_option(int, const struct my_option *, char *);
380
static int init_thread_environment();
381
static const char *get_relative_path(const char *path);
382
static void fix_paths(string &progname);
383
extern "C" pthread_handler_t handle_slave(void *arg);
384
static void clean_up(bool print_message);
386
static void usage(void);
387
static void clean_up_mutexes(void);
388
void close_connections(void);
390
/****************************************************************************
391
** Code to end drizzled
392
****************************************************************************/
394
void close_connections(void)
396
/* Abort listening to new connections */
397
plugin::Listen::shutdown();
399
/* kill connection thread */
400
(void) pthread_mutex_lock(&LOCK_thread_count);
402
while (select_thread_in_use)
404
struct timespec abstime;
407
set_timespec(abstime, 2);
408
for (uint32_t tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
410
error=pthread_cond_timedwait(&COND_thread_count,&LOCK_thread_count, &abstime);
415
(void) pthread_mutex_unlock(&LOCK_thread_count);
419
First signal all threads that it's time to die
420
This will give the threads some time to gracefully abort their
421
statements and inform their clients that the server is about to die.
426
(void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
428
for( SessionList::iterator it= getSessionList().begin(); it != getSessionList().end(); ++it )
431
tmp->killed= Session::KILL_CONNECTION;
432
tmp->scheduler->killSession(tmp);
433
DRIZZLE_CONNECTION_DONE(tmp->thread_id);
436
tmp->mysys_var->abort=1;
437
pthread_mutex_lock(&tmp->mysys_var->mutex);
438
if (tmp->mysys_var->current_cond)
440
pthread_mutex_lock(tmp->mysys_var->current_mutex);
441
pthread_cond_broadcast(tmp->mysys_var->current_cond);
442
pthread_mutex_unlock(tmp->mysys_var->current_mutex);
444
pthread_mutex_unlock(&tmp->mysys_var->mutex);
447
(void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list
449
if (connection_count)
450
sleep(2); // Give threads time to die
453
Force remaining threads to die by closing the connection to the client
454
This will ensure that threads that are waiting for a command from the
455
client on a blocking read call are aborted.
459
(void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
460
if (getSessionList().empty())
462
(void) pthread_mutex_unlock(&LOCK_thread_count);
465
tmp= getSessionList().front();
466
/* Close before unlock, avoiding crash. See LP bug#436685 */
467
tmp->client->close();
468
(void) pthread_mutex_unlock(&LOCK_thread_count);
472
extern "C" void print_signal_warning(int sig);
474
extern "C" void print_signal_warning(int sig)
476
if (global_system_variables.log_warnings)
477
errmsg_printf(ERRMSG_LVL_WARN, _("Got signal %d from thread %"PRIu64),
478
sig, global_thread_id);
479
#ifndef HAVE_BSD_SIGNALS
480
my_sigset(sig,print_signal_warning); /* int. thread system calls */
483
alarm(2); /* reschedule alarm */
487
cleanup all memory and end program nicely.
489
If SIGNALS_DONT_BREAK_READ is defined, this function is called
490
by the main thread. To get Drizzle to shut down nicely in this case
491
(Mac OS X) we have to call exit() instead if pthread_exit().
494
This function never returns.
496
void unireg_end(void)
499
internal::my_thread_end();
500
#if defined(SIGNALS_DONT_BREAK_READ)
503
pthread_exit(0); // Exit is in main thread
508
void unireg_abort(int exit_code)
512
errmsg_printf(ERRMSG_LVL_ERROR, _("Aborting\n"));
513
else if (opt_help || opt_help_extended)
515
clean_up(!opt_help && (exit_code));
522
static void clean_up(bool print_message)
528
TableShare::cacheStop();
532
plugin::Registry &plugins= plugin::Registry::singleton();
533
plugin_shutdown(plugins);
537
internal::free_defaults(defaults_argv);
538
free(drizzle_tmpdir);
539
if (opt_secure_file_priv)
540
free(opt_secure_file_priv);
542
deinit_temporal_formats();
544
#if GOOGLE_PROTOBUF_VERSION >= 2001000
545
google::protobuf::ShutdownProtobufLibrary();
548
(void) unlink(pidfile_name); // This may not always exist
550
if (print_message && server_start_time)
551
errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_SHUTDOWN_COMPLETE)),internal::my_progname);
552
/* Returns NULL on globerrs, we don't want to try to free that */
554
(void *)my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST);
555
// TODO!!!! EPIC FAIL!!!! This sefaults if uncommented.
556
/* if (freeme != NULL)
558
(void) pthread_mutex_lock(&LOCK_thread_count);
560
/* do the broadcast inside the lock to ensure that my_end() is not called */
561
(void) pthread_cond_broadcast(&COND_server_end);
562
(void) pthread_mutex_unlock(&LOCK_thread_count);
565
The following lines may never be executed as the main thread may have
571
static void clean_up_mutexes()
573
(void) pthread_mutex_destroy(&LOCK_create_db);
574
(void) pthread_mutex_destroy(&LOCK_open);
575
(void) pthread_mutex_destroy(&LOCK_thread_count);
576
(void) pthread_mutex_destroy(&LOCK_status);
577
(void) pthread_mutex_destroy(&LOCK_global_system_variables);
578
(void) pthread_rwlock_destroy(&LOCK_system_variables_hash);
579
(void) pthread_mutex_destroy(&LOCK_global_read_lock);
580
(void) pthread_cond_destroy(&COND_thread_count);
581
(void) pthread_cond_destroy(&COND_server_end);
582
(void) pthread_cond_destroy(&COND_refresh);
583
(void) pthread_cond_destroy(&COND_global_read_lock);
587
/* Change to run as another user if started with --user */
589
static struct passwd *check_user(const char *user)
591
struct passwd *tmp_user_info;
592
uid_t user_id= geteuid();
594
// Don't bother if we aren't superuser
599
/* Don't give a warning, if real user is same as given with --user */
600
tmp_user_info= getpwnam(user);
601
if ((!tmp_user_info || user_id != tmp_user_info->pw_uid) &&
602
global_system_variables.log_warnings)
603
errmsg_printf(ERRMSG_LVL_WARN, _("One can only use the --user switch "
604
"if running as root\n"));
610
errmsg_printf(ERRMSG_LVL_ERROR, _("Fatal error: Please read \"Security\" section of "
611
"the manual to find out how to run drizzled as root!\n"));
614
if (!strcmp(user,"root"))
615
return NULL; // Avoid problem with dynamic libraries
617
if (!(tmp_user_info= getpwnam(user)))
619
// Allow a numeric uid to be used
621
for (pos= user; my_isdigit(mysqld_charset,*pos); pos++) ;
622
if (*pos) // Not numeric id
624
if (!(tmp_user_info= getpwuid(atoi(user))))
627
return tmp_user_info;
630
errmsg_printf(ERRMSG_LVL_ERROR, _("Fatal error: Can't change to run as user '%s' ; "
631
"Please check that the user exists!\n"),user);
634
#ifdef PR_SET_DUMPABLE
635
if (test_flags.test(TEST_CORE_ON_SIGNAL))
637
/* inform kernel that process is dumpable */
638
(void) prctl(PR_SET_DUMPABLE, 1);
642
/* Sun Studio 5.10 doesn't like this line. 5.9 requires it */
643
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x590)
649
static void set_user(const char *user, struct passwd *user_info_arg)
651
assert(user_info_arg != 0);
653
We can get a SIGSEGV when calling initgroups() on some systems when NSS
654
is configured to use LDAP and the server is statically linked. We set
655
calling_initgroups as a flag to the SIGSEGV handler that is then used to
656
output a specific message to help the user resolve this problem.
658
calling_initgroups= true;
659
initgroups((char*) user, user_info_arg->pw_gid);
660
calling_initgroups= false;
661
if (setgid(user_info_arg->pw_gid) == -1)
663
sql_perror("setgid");
666
if (setuid(user_info_arg->pw_uid) == -1)
668
sql_perror("setuid");
674
/** Change root user if started with @c --chroot . */
675
static void set_root(const char *path)
677
if ((chroot(path) == -1) || !chdir("/"))
679
sql_perror("chroot");
684
extern "C" void end_thread_signal(int );
686
/** Called when a thread is aborted. */
687
extern "C" void end_thread_signal(int )
689
Session *session=current_session;
692
statistic_increment(killed_threads, &LOCK_status);
693
session->scheduler->killSessionNow(session);
694
DRIZZLE_CONNECTION_DONE(session->thread_id);
701
Unlink session from global list of available connections and free session
705
session Thread handler
708
LOCK_thread_count is locked and left locked
711
void Session::unlink(Session *session)
713
connection_count.decrement();
717
(void) pthread_mutex_lock(&LOCK_thread_count);
718
pthread_mutex_lock(&session->LOCK_delete);
720
getSessionList().erase(remove(getSessionList().begin(),
721
getSessionList().end(),
725
(void) pthread_mutex_unlock(&LOCK_thread_count);
731
#ifdef THREAD_SPECIFIC_SIGPIPE
735
One should have to fix that thr_alarm know about this thread too.
737
extern "C" void abort_thread(int )
739
Session *session=current_session;
741
session->killed= Session::KILL_CONNECTION;
746
#if defined(BACKTRACE_DEMANGLE)
748
extern "C" char *my_demangle(const char *mangled_name, int *status)
750
return abi::__cxa_demangle(mangled_name, NULL, NULL, status);
754
extern "C" void handle_segfault(int sig);
756
extern "C" void handle_segfault(int sig)
762
Strictly speaking, one needs a mutex here
763
but since we have got SIGSEGV already, things are a mess
764
so not having the mutex is not as bad as possibly using a buggy
765
mutex - so we keep things simple
769
fprintf(stderr, _("Fatal signal %d while backtracing\n"), sig);
775
curr_time= time(NULL);
776
if(curr_time == (time_t)-1)
778
fprintf(stderr, "Fetal: time() call failed\n");
782
localtime_r(&curr_time, &tm);
784
fprintf(stderr,"%02d%02d%02d %2d:%02d:%02d - drizzled got signal %d;\n"
785
"This could be because you hit a bug. It is also possible that "
786
"this binary\n or one of the libraries it was linked against is "
787
"corrupt, improperly built,\n or misconfigured. This error can "
788
"also be caused by malfunctioning hardware.\n",
789
tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday,
790
tm.tm_hour, tm.tm_min, tm.tm_sec,
792
fprintf(stderr, _("We will try our best to scrape up some info that "
793
"will hopefully help diagnose\n"
794
"the problem, but since we have already crashed, "
795
"something is definitely wrong\nand this may fail.\n\n"));
796
fprintf(stderr, "key_buffer_size=%u\n",
797
(uint32_t) dflt_key_cache->key_cache_mem_size);
798
fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
799
fprintf(stderr, "max_used_connections=%u\n", max_used_connections);
800
fprintf(stderr, "connection_count=%u\n", uint32_t(connection_count));
801
fprintf(stderr, _("It is possible that drizzled could use up to \n"
802
"key_buffer_size + (read_buffer_size + "
803
"sort_buffer_size)*thread_count\n"
805
"Hope that's ok; if not, decrease some variables in the "
808
#ifdef HAVE_STACKTRACE
809
Session *session= current_session;
811
if (! (test_flags.test(TEST_NO_STACKTRACE)))
813
fprintf(stderr,"session: 0x%lx\n",(long) session);
814
fprintf(stderr,_("Attempting backtrace. You can use the following "
815
"information to find out\n"
816
"where drizzled died. If you see no messages after this, "
818
"terribly wrong...\n"));
819
print_stacktrace(session ? (unsigned char*) session->thread_stack : (unsigned char*) 0,
820
my_thread_stack_size);
824
const char *kreason= "UNKNOWN";
825
switch (session->killed) {
826
case Session::NOT_KILLED:
827
kreason= "NOT_KILLED";
829
case Session::KILL_BAD_DATA:
830
kreason= "KILL_BAD_DATA";
832
case Session::KILL_CONNECTION:
833
kreason= "KILL_CONNECTION";
835
case Session::KILL_QUERY:
836
kreason= "KILL_QUERY";
838
case Session::KILLED_NO_VALUE:
839
kreason= "KILLED_NO_VALUE";
842
fprintf(stderr, _("Trying to get some variables.\n"
843
"Some pointers may be invalid and cause the "
844
"dump to abort...\n"));
845
safe_print_str("session->query", session->query.c_str(), 1024);
846
fprintf(stderr, "session->thread_id=%"PRIu32"\n", (uint32_t) session->thread_id);
847
fprintf(stderr, "session->killed=%s\n", kreason);
850
#endif /* HAVE_STACKTRACE */
852
if (calling_initgroups)
853
fprintf(stderr, _("\nThis crash occurred while the server was calling "
854
"initgroups(). This is\n"
855
"often due to the use of a drizzled that is statically "
856
"linked against glibc\n"
857
"and configured to use LDAP in /etc/nsswitch.conf. "
858
"You will need to either\n"
859
"upgrade to a version of glibc that does not have this "
860
"problem (2.3.4 or\n"
861
"later when used with nscd), disable LDAP in your "
862
"nsswitch.conf, or use a\n"
863
"drizzled that is not statically linked.\n"));
865
if (internal::thd_lib_detected == THD_LIB_LT && !getenv("LD_ASSUME_KERNEL"))
867
_("\nYou are running a statically-linked LinuxThreads binary "
868
"on an NPTL system.\n"
869
"This can result in crashes on some distributions due "
870
"to LT/NPTL conflicts.\n"
871
"You should either build a dynamically-linked binary, or force "
873
"to be used with the LD_ASSUME_KERNEL environment variable. "
875
"the documentation for your distribution on how to do that.\n"));
877
#ifdef HAVE_WRITE_CORE
878
if (test_flags.test(TEST_CORE_ON_SIGNAL))
880
fprintf(stderr, _("Writing a core file\n"));
890
#define SA_RESETHAND 0
898
All global error messages are sent here where the first one is stored
901
static void my_message_sql(uint32_t error, const char *str, myf MyFlags)
905
Put here following assertion when situation with EE_* error codes
908
if ((session= current_session))
910
if (MyFlags & ME_FATALERROR)
911
session->is_fatal_error= 1;
914
TODO: There are two exceptions mechanism (Session and sp_rcontext),
915
this could be improved by having a common stack of handlers.
917
if (session->handle_error(error, str,
918
DRIZZLE_ERROR::WARN_LEVEL_ERROR))
922
session->lex->current_select == 0 if lex structure is not inited
923
(not query command (COM_QUERY))
925
if (! (session->lex->current_select &&
926
session->lex->current_select->no_error && !session->is_fatal_error))
928
if (! session->main_da.is_error()) // Return only first message
931
error= ER_UNKNOWN_ERROR;
934
session->main_da.set_error_status(error, str);
938
if (!session->no_warnings_for_error && !session->is_fatal_error)
941
Suppress infinite recursion if there a memory allocation error
944
session->no_warnings_for_error= true;
945
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error, str);
946
session->no_warnings_for_error= false;
949
if (!session || MyFlags & ME_NOREFRESH)
950
errmsg_printf(ERRMSG_LVL_ERROR, "%s: %s",internal::my_progname,str);
954
static const char *load_default_groups[]= {
955
DRIZZLE_CONFIG_NAME, "server", 0, 0};
957
static int show_starttime(drizzle_show_var *var, char *buff)
959
var->type= SHOW_LONG;
961
*((long *)buff)= (long) (time(NULL) - server_start_time);
965
static int show_flushstatustime(drizzle_show_var *var, char *buff)
967
var->type= SHOW_LONG;
969
*((long *)buff)= (long) (time(NULL) - flush_status_time);
973
static st_show_var_func_container show_starttime_cont= { &show_starttime };
975
static st_show_var_func_container show_flushstatustime_cont= { &show_flushstatustime };
978
Variables shown by SHOW STATUS in alphabetical order
980
static drizzle_show_var com_status_vars[]= {
981
{"admin_commands", (char*) offsetof(system_status_var, com_other), SHOW_LONG_STATUS},
982
{"alter_db", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_ALTER_DB]), SHOW_LONG_STATUS},
983
{"alter_table", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_ALTER_TABLE]), SHOW_LONG_STATUS},
984
{"analyze", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_ANALYZE]), SHOW_LONG_STATUS},
985
{"begin", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_BEGIN]), SHOW_LONG_STATUS},
986
{"change_db", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CHANGE_DB]), SHOW_LONG_STATUS},
987
{"check", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CHECK]), SHOW_LONG_STATUS},
988
{"checksum", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CHECKSUM]), SHOW_LONG_STATUS},
989
{"commit", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_COMMIT]), SHOW_LONG_STATUS},
990
{"create_db", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CREATE_DB]), SHOW_LONG_STATUS},
991
{"create_index", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CREATE_INDEX]), SHOW_LONG_STATUS},
992
{"create_table", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CREATE_TABLE]), SHOW_LONG_STATUS},
993
{"delete", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_DELETE]), SHOW_LONG_STATUS},
994
{"drop_db", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_DROP_DB]), SHOW_LONG_STATUS},
995
{"drop_index", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_DROP_INDEX]), SHOW_LONG_STATUS},
996
{"drop_table", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_DROP_TABLE]), SHOW_LONG_STATUS},
997
{"empty_query", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_EMPTY_QUERY]), SHOW_LONG_STATUS},
998
{"flush", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_FLUSH]), SHOW_LONG_STATUS},
999
{"insert", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_INSERT]), SHOW_LONG_STATUS},
1000
{"insert_select", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_INSERT_SELECT]), SHOW_LONG_STATUS},
1001
{"kill", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_KILL]), SHOW_LONG_STATUS},
1002
{"load", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_LOAD]), SHOW_LONG_STATUS},
1003
{"release_savepoint", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_RELEASE_SAVEPOINT]), SHOW_LONG_STATUS},
1004
{"rename_table", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_RENAME_TABLE]), SHOW_LONG_STATUS},
1005
{"replace", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_REPLACE]), SHOW_LONG_STATUS},
1006
{"replace_select", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_REPLACE_SELECT]), SHOW_LONG_STATUS},
1007
{"rollback", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_ROLLBACK]), SHOW_LONG_STATUS},
1008
{"rollback_to_savepoint",(char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_ROLLBACK_TO_SAVEPOINT]), SHOW_LONG_STATUS},
1009
{"savepoint", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SAVEPOINT]), SHOW_LONG_STATUS},
1010
{"select", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SELECT]), SHOW_LONG_STATUS},
1011
{"set_option", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SET_OPTION]), SHOW_LONG_STATUS},
1012
{"show_create_db", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SHOW_CREATE_DB]), SHOW_LONG_STATUS},
1013
{"show_create_table", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SHOW_CREATE]), SHOW_LONG_STATUS},
1014
{"show_errors", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SHOW_ERRORS]), SHOW_LONG_STATUS},
1015
{"show_warnings", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
1016
{"truncate", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_TRUNCATE]), SHOW_LONG_STATUS},
1017
{"unlock_tables", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_UNLOCK_TABLES]), SHOW_LONG_STATUS},
1018
{"update", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_UPDATE]), SHOW_LONG_STATUS},
1019
{NULL, NULL, SHOW_LONGLONG}
1022
static drizzle_show_var status_vars[]= {
1023
{"Aborted_clients", (char*) &aborted_threads, SHOW_LONGLONG},
1024
{"Aborted_connects", (char*) &aborted_connects, SHOW_LONGLONG},
1025
{"Bytes_received", (char*) offsetof(system_status_var, bytes_received), SHOW_LONGLONG_STATUS},
1026
{"Bytes_sent", (char*) offsetof(system_status_var, bytes_sent), SHOW_LONGLONG_STATUS},
1027
{"Connections", (char*) &global_thread_id, SHOW_INT_NOFLUSH},
1028
{"Created_tmp_disk_tables", (char*) offsetof(system_status_var, created_tmp_disk_tables), SHOW_LONG_STATUS},
1029
{"Created_tmp_tables", (char*) offsetof(system_status_var, created_tmp_tables), SHOW_LONG_STATUS},
1030
{"Flush_commands", (char*) &refresh_version, SHOW_INT_NOFLUSH},
1031
{"Handler_commit", (char*) offsetof(system_status_var, ha_commit_count), SHOW_LONG_STATUS},
1032
{"Handler_delete", (char*) offsetof(system_status_var, ha_delete_count), SHOW_LONG_STATUS},
1033
{"Handler_prepare", (char*) offsetof(system_status_var, ha_prepare_count), SHOW_LONG_STATUS},
1034
{"Handler_read_first", (char*) offsetof(system_status_var, ha_read_first_count), SHOW_LONG_STATUS},
1035
{"Handler_read_key", (char*) offsetof(system_status_var, ha_read_key_count), SHOW_LONG_STATUS},
1036
{"Handler_read_next", (char*) offsetof(system_status_var, ha_read_next_count), SHOW_LONG_STATUS},
1037
{"Handler_read_prev", (char*) offsetof(system_status_var, ha_read_prev_count), SHOW_LONG_STATUS},
1038
{"Handler_read_rnd", (char*) offsetof(system_status_var, ha_read_rnd_count), SHOW_LONG_STATUS},
1039
{"Handler_read_rnd_next", (char*) offsetof(system_status_var, ha_read_rnd_next_count), SHOW_LONG_STATUS},
1040
{"Handler_rollback", (char*) offsetof(system_status_var, ha_rollback_count), SHOW_LONG_STATUS},
1041
{"Handler_savepoint", (char*) offsetof(system_status_var, ha_savepoint_count), SHOW_LONG_STATUS},
1042
{"Handler_savepoint_rollback",(char*) offsetof(system_status_var, ha_savepoint_rollback_count), SHOW_LONG_STATUS},
1043
{"Handler_update", (char*) offsetof(system_status_var, ha_update_count), SHOW_LONG_STATUS},
1044
{"Handler_write", (char*) offsetof(system_status_var, ha_write_count), SHOW_LONG_STATUS},
1045
{"Key_blocks_not_flushed", (char*) offsetof(KEY_CACHE, global_blocks_changed), SHOW_KEY_CACHE_LONG},
1046
{"Key_blocks_unused", (char*) offsetof(KEY_CACHE, blocks_unused), SHOW_KEY_CACHE_LONG},
1047
{"Key_blocks_used", (char*) offsetof(KEY_CACHE, blocks_used), SHOW_KEY_CACHE_LONG},
1048
{"Key_read_requests", (char*) offsetof(KEY_CACHE, global_cache_r_requests), SHOW_KEY_CACHE_LONGLONG},
1049
{"Key_reads", (char*) offsetof(KEY_CACHE, global_cache_read), SHOW_KEY_CACHE_LONGLONG},
1050
{"Key_write_requests", (char*) offsetof(KEY_CACHE, global_cache_w_requests), SHOW_KEY_CACHE_LONGLONG},
1051
{"Key_writes", (char*) offsetof(KEY_CACHE, global_cache_write), SHOW_KEY_CACHE_LONGLONG},
1052
{"Last_query_cost", (char*) offsetof(system_status_var, last_query_cost), SHOW_DOUBLE_STATUS},
1053
{"Max_used_connections", (char*) &max_used_connections, SHOW_INT},
1054
{"Questions", (char*) offsetof(system_status_var, questions), SHOW_LONG_STATUS},
1055
{"Select_full_join", (char*) offsetof(system_status_var, select_full_join_count), SHOW_LONG_STATUS},
1056
{"Select_full_range_join", (char*) offsetof(system_status_var, select_full_range_join_count), SHOW_LONG_STATUS},
1057
{"Select_range", (char*) offsetof(system_status_var, select_range_count), SHOW_LONG_STATUS},
1058
{"Select_range_check", (char*) offsetof(system_status_var, select_range_check_count), SHOW_LONG_STATUS},
1059
{"Select_scan", (char*) offsetof(system_status_var, select_scan_count), SHOW_LONG_STATUS},
1060
{"Slow_queries", (char*) offsetof(system_status_var, long_query_count), SHOW_LONG_STATUS},
1061
{"Sort_merge_passes", (char*) offsetof(system_status_var, filesort_merge_passes), SHOW_LONG_STATUS},
1062
{"Sort_range", (char*) offsetof(system_status_var, filesort_range_count), SHOW_LONG_STATUS},
1063
{"Sort_rows", (char*) offsetof(system_status_var, filesort_rows), SHOW_LONG_STATUS},
1064
{"Sort_scan", (char*) offsetof(system_status_var, filesort_scan_count), SHOW_LONG_STATUS},
1065
{"Table_locks_immediate", (char*) &locks_immediate, SHOW_INT},
1066
{"Table_locks_waited", (char*) &locks_waited, SHOW_INT},
1067
{"Threads_connected", (char*) &connection_count, SHOW_INT},
1068
{"Uptime", (char*) &show_starttime_cont, SHOW_FUNC},
1069
{"Uptime_since_flush_status",(char*) &show_flushstatustime_cont, SHOW_FUNC},
1070
{NULL, NULL, SHOW_LONGLONG}
1073
static int init_common_variables(const char *conf_file_name, int argc,
1074
char **argv, const char **groups)
1077
umask(((~internal::my_umask) & 0666));
1078
my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
1079
tzset(); // Set tzname
1081
curr_time= time(NULL);
1082
if (curr_time == (time_t)-1)
1085
max_system_variables.pseudo_thread_id= UINT32_MAX;
1086
server_start_time= flush_status_time= curr_time;
1088
if (init_thread_environment())
1090
drizzle_init_variables();
1094
localtime_r(&server_start_time,&tm_tmp);
1095
strncpy(system_time_zone, tzname[tm_tmp.tm_isdst != 0 ? 1 : 0],
1096
sizeof(system_time_zone)-1);
1100
We set SYSTEM time zone as reasonable default and
1101
also for failure of my_tz_init() and bootstrap mode.
1102
If user explicitly set time zone with --default-time-zone
1103
option we will change this value in my_tz_init().
1105
global_system_variables.time_zone= my_tz_SYSTEM;
1107
if (gethostname(glob_hostname,sizeof(glob_hostname)) < 0)
1109
strncpy(glob_hostname, STRING_WITH_LEN("localhost"));
1110
errmsg_printf(ERRMSG_LVL_WARN, _("gethostname failed, using '%s' as hostname"),
1112
strncpy(pidfile_name, STRING_WITH_LEN("drizzle"));
1115
strncpy(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
1116
strcpy(internal::fn_ext(pidfile_name),".pid"); // Add proper extension
1119
Add server status variables to the dynamic list of
1120
status variables that is shown by SHOW STATUS.
1121
Later, in plugin_init, new entries could be added to that list.
1123
if (add_com_status_vars(com_status_vars))
1124
return 1; // an error was already reported
1126
if (add_status_vars(status_vars))
1127
return 1; // an error was already reported
1129
internal::load_defaults(conf_file_name, groups, &argc, &argv);
1132
get_options(&defaults_argc, defaults_argv);
1134
current_pid= getpid(); /* Save for later ref */
1135
init_time(); /* Init time-functions (read zone) */
1137
if (init_errmessage()) /* Read error messages from file */
1139
if (item_create_init())
1143
/* Creates static regex matching for temporal values */
1144
if (! init_temporal_formats())
1147
if (!(default_charset_info=
1148
get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)))
1150
return 1; // Eof of the list
1153
if (default_collation_name)
1155
const CHARSET_INFO * const default_collation= get_charset_by_name(default_collation_name);
1156
if (not default_collation)
1158
errmsg_printf(ERRMSG_LVL_ERROR, _(ER(ER_UNKNOWN_COLLATION)), default_collation_name);
1161
if (not my_charset_same(default_charset_info, default_collation))
1163
errmsg_printf(ERRMSG_LVL_ERROR, _(ER(ER_COLLATION_CHARSET_MISMATCH)),
1164
default_collation_name,
1165
default_charset_info->csname);
1168
default_charset_info= default_collation;
1170
/* Set collactions that depends on the default collation */
1171
global_system_variables.collation_server= default_charset_info;
1173
if (not (character_set_filesystem=
1174
get_charset_by_csname(character_set_filesystem_name, MY_CS_PRIMARY)))
1176
global_system_variables.character_set_filesystem= character_set_filesystem;
1178
if (!(my_default_lc_time_names=
1179
my_locale_by_name(lc_time_names_name)))
1181
errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown locale: '%s'"), lc_time_names_name);
1184
global_system_variables.lc_time_names= my_default_lc_time_names;
1186
/* Reset table_alias_charset */
1187
table_alias_charset= files_charset_info;
1193
static int init_thread_environment()
1195
pthread_mutexattr_t attr;
1196
pthread_mutexattr_init(&attr);
1198
(void) pthread_mutex_init(&LOCK_create_db, NULL);
1199
(void) pthread_mutex_init(&LOCK_open, NULL);
1201
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
1202
(void) pthread_mutex_init(&LOCK_thread_count, &attr);
1203
(void) pthread_mutex_init(&LOCK_global_system_variables, &attr);
1205
(void) pthread_mutex_init(&LOCK_status, MY_MUTEX_INIT_FAST);
1206
(void) pthread_rwlock_init(&LOCK_system_variables_hash, NULL);
1207
(void) pthread_mutex_init(&LOCK_global_read_lock, MY_MUTEX_INIT_FAST);
1208
(void) pthread_cond_init(&COND_thread_count,NULL);
1209
(void) pthread_cond_init(&COND_server_end,NULL);
1210
(void) pthread_cond_init(&COND_refresh,NULL);
1211
(void) pthread_cond_init(&COND_global_read_lock,NULL);
1213
pthread_mutexattr_destroy(&attr);
1215
if (pthread_key_create(&THR_Session,NULL) ||
1216
pthread_key_create(&THR_Mem_root,NULL))
1218
errmsg_printf(ERRMSG_LVL_ERROR, _("Can't create thread-keys"));
1225
static int init_server_components(plugin::Registry &plugins)
1228
We need to call each of these following functions to ensure that
1229
all things are initialized so that unireg_abort() doesn't fail
1231
if (table_cache_init())
1233
TableShare::cacheStart();
1240
if (xid_cache_init())
1242
errmsg_printf(ERRMSG_LVL_ERROR, _("Out of memory"));
1246
/* Allow storage engine to give real error messages */
1247
if (ha_init_errors())
1250
if (plugin_init(plugins, &defaults_argc, defaults_argv,
1251
((opt_help) ? true : false)))
1253
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize plugins."));
1257
if (opt_help || opt_help_extended)
1260
/* we do want to exit if there are any other unknown options */
1261
if (defaults_argc > 1)
1264
char **tmp_argv= defaults_argv;
1265
struct my_option no_opts[]=
1267
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
1270
We need to eat any 'loose' arguments first before we conclude
1271
that there are unprocessed options.
1272
But we need to preserve defaults_argv pointer intact for
1273
internal::free_defaults() to work. Thus we use a copy here.
1275
my_getopt_skip_unknown= 0;
1277
if ((ho_error= handle_options(&defaults_argc, &tmp_argv, no_opts,
1278
drizzled_get_one_option)))
1279
unireg_abort(ho_error);
1284
_("%s: Too many arguments (first extra is '%s').\n"
1285
"Use --verbose --help to get a list of available options\n"),
1286
internal::my_progname, *tmp_argv);
1291
string scheduler_name;
1294
scheduler_name= opt_scheduler;
1298
scheduler_name= opt_scheduler_default;
1301
if (plugin::Scheduler::setPlugin(scheduler_name))
1303
errmsg_printf(ERRMSG_LVL_ERROR,
1304
_("No scheduler found, cannot continue!\n"));
1309
This is entirely for legacy. We will create a new "disk based" engine and a
1310
"memory" engine which will be configurable longterm.
1312
const std::string myisam_engine_name("MyISAM");
1313
const std::string heap_engine_name("MEMORY");
1314
myisam_engine= plugin::StorageEngine::findByName(myisam_engine_name);
1315
heap_engine= plugin::StorageEngine::findByName(heap_engine_name);
1318
Check that the default storage engine is actually available.
1320
if (default_storage_engine_str)
1322
const std::string name(default_storage_engine_str);
1323
plugin::StorageEngine *engine;
1325
engine= plugin::StorageEngine::findByName(name);
1328
errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown/unsupported storage engine: %s"),
1329
default_storage_engine_str);
1332
global_system_variables.storage_engine= engine;
1335
if (plugin::XaResourceManager::recoverAllXids(0))
1340
init_update_queries();
1346
/****************************************************************************
1347
Handle start options
1348
******************************************************************************/
1350
enum options_drizzled
1360
OPT_TC_HEURISTIC_RECOVER,
1361
OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE,
1362
OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
1367
OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_BLOCK_SIZE,
1368
OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_AGE_THRESHOLD,
1369
OPT_MAX_ALLOWED_PACKET,
1370
OPT_MAX_CONNECT_ERRORS,
1371
OPT_MAX_HEP_TABLE_SIZE,
1373
OPT_MAX_SORT_LENGTH,
1374
OPT_MAX_SEEKS_FOR_KEY, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS,
1375
OPT_MAX_LENGTH_FOR_SORT_DATA,
1376
OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE,
1377
OPT_MAX_ERROR_COUNT, OPT_MULTI_RANGE_COUNT, OPT_MYISAM_DATA_POINTER_SIZE,
1378
OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
1379
OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
1380
OPT_MYISAM_USE_MMAP, OPT_MYISAM_REPAIR_THREADS,
1381
OPT_NET_BUFFER_LENGTH,
1382
OPT_PRELOAD_BUFFER_SIZE,
1384
OPT_RECORD_RND_BUFFER, OPT_DIV_PRECINCREMENT,
1386
OPT_SORT_BUFFER, OPT_TABLE_OPEN_CACHE, OPT_TABLE_DEF_CACHE,
1387
OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK,
1389
OPT_RANGE_ALLOC_BLOCK_SIZE,
1390
OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE,
1391
OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE,
1392
OPT_OLD_ALTER_TABLE,
1393
OPT_GROUP_CONCAT_MAX_LEN,
1394
OPT_DEFAULT_COLLATION,
1395
OPT_CHARACTER_SET_FILESYSTEM,
1398
OPT_DEFAULT_TIME_ZONE,
1399
OPT_OPTIMIZER_SEARCH_DEPTH,
1402
OPT_OPTIMIZER_PRUNE_LEVEL,
1403
OPT_AUTO_INCREMENT, OPT_AUTO_INCREMENT_OFFSET,
1404
OPT_ENABLE_LARGE_PAGES,
1406
OPT_TABLE_LOCK_WAIT_TIMEOUT,
1411
OPT_PORT_OPEN_TIMEOUT,
1412
OPT_SECURE_FILE_PRIV,
1413
OPT_MIN_EXAMINED_ROW_LIMIT
1417
struct my_option my_long_options[] =
1419
{"help", '?', N_("Display this help and exit."),
1420
(char**) &opt_help, (char**) &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
1422
{"help-extended", '?',
1423
N_("Display this help and exit after initializing plugins."),
1424
(char**) &opt_help_extended, (char**) &opt_help_extended,
1425
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1426
{"auto-increment-increment", OPT_AUTO_INCREMENT,
1427
N_("Auto-increment columns are incremented by this"),
1428
(char**) &global_system_variables.auto_increment_increment,
1429
(char**) &max_system_variables.auto_increment_increment, 0, GET_ULL,
1430
OPT_ARG, 1, 1, UINT64_MAX, 0, 1, 0 },
1431
{"auto-increment-offset", OPT_AUTO_INCREMENT_OFFSET,
1432
N_("Offset added to Auto-increment columns. Used when "
1433
"auto-increment-increment != 1"),
1434
(char**) &global_system_variables.auto_increment_offset,
1435
(char**) &max_system_variables.auto_increment_offset, 0, GET_ULL, OPT_ARG,
1436
1, 1, UINT64_MAX, 0, 1, 0 },
1438
N_("Path to installation directory. All paths are usually resolved "
1439
"relative to this."),
1440
(char**) &drizzle_home_ptr, (char**) &drizzle_home_ptr, 0, GET_STR, REQUIRED_ARG,
1443
N_("Chroot drizzled daemon during startup."),
1444
(char**) &drizzled_chroot, (char**) &drizzled_chroot, 0, GET_STR, REQUIRED_ARG,
1446
{"collation-server", OPT_DEFAULT_COLLATION,
1447
N_("Set the default collation."),
1448
(char**) &default_collation_name, (char**) &default_collation_name,
1449
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
1450
{"completion-type", OPT_COMPLETION_TYPE,
1451
N_("Default completion type."),
1452
(char**) &global_system_variables.completion_type,
1453
(char**) &max_system_variables.completion_type, 0, GET_UINT,
1454
REQUIRED_ARG, 0, 0, 2, 0, 1, 0},
1455
{"core-file", OPT_WANT_CORE,
1456
N_("Write core on errors."),
1457
0, 0, 0, GET_NO_ARG,
1458
NO_ARG, 0, 0, 0, 0, 0, 0},
1460
N_("Path to the database root."),
1461
(char**) &drizzle_data_home,
1462
(char**) &drizzle_data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1463
{"default-storage-engine", OPT_STORAGE_ENGINE,
1464
N_("Set the default storage engine (table type) for tables."),
1465
(char**)&default_storage_engine_str, (char**)&default_storage_engine_str,
1466
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1467
{"default-time-zone", OPT_DEFAULT_TIME_ZONE,
1468
N_("Set the default time zone."),
1469
(char**) &default_tz_name, (char**) &default_tz_name,
1470
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
1471
#ifdef HAVE_STACK_TRACE_ON_SEGV
1472
{"enable-pstack", OPT_DO_PSTACK,
1473
N_("Print a symbolic stack trace on failure."),
1474
(char**) &opt_do_pstack, (char**) &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0,
1476
#endif /* HAVE_STACK_TRACE_ON_SEGV */
1477
/* See how it's handled in get_one_option() */
1479
N_("Used for debugging; Use at your own risk!"),
1480
0, 0, 0, GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
1481
/* We must always support the next option to make scripts like mysqltest
1483
{"gdb", OPT_DEBUGGING,
1484
N_("Set up signals usable for debugging"),
1485
(char**) &opt_debugging, (char**) &opt_debugging,
1486
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1489
(char**) &language_ptr, (char**) &language_ptr, 0, GET_STR, REQUIRED_ARG,
1491
{"lc-time-names", OPT_LC_TIME_NAMES,
1492
N_("Set the language used for the month names and the days of the week."),
1493
(char**) &lc_time_names_name,
1494
(char**) &lc_time_names_name,
1495
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
1496
{"log-warnings", 'W',
1497
N_("Log some not critical warnings to the log file."),
1498
(char**) &global_system_variables.log_warnings,
1499
(char**) &max_system_variables.log_warnings, 0, GET_BOOL, OPT_ARG, 1, 0, 0,
1501
{"pid-file", OPT_PID_FILE,
1502
N_("Pid file used by safe_mysqld."),
1503
(char**) &pidfile_name_ptr, (char**) &pidfile_name_ptr, 0, GET_STR,
1504
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1505
{"port-open-timeout", OPT_PORT_OPEN_TIMEOUT,
1506
N_("Maximum time in seconds to wait for the port to become free. "
1507
"(Default: no wait)"),
1508
(char**) &drizzled_bind_timeout,
1509
(char**) &drizzled_bind_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1510
{"secure-file-priv", OPT_SECURE_FILE_PRIV,
1511
N_("Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
1512
"within specified directory"),
1513
(char**) &opt_secure_file_priv, (char**) &opt_secure_file_priv, 0,
1514
GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1515
{"server-id", OPT_SERVER_ID,
1516
N_("Uniquely identifies the server instance in the community of "
1517
"replication partners."),
1518
(char**) &server_id, (char**) &server_id, 0, GET_UINT32, REQUIRED_ARG, 0, 0, 0,
1520
{"skip-stack-trace", OPT_SKIP_STACK_TRACE,
1521
N_("Don't print a stack trace on failure."),
1522
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
1524
{"symbolic-links", 's',
1525
N_("Enable symbolic link support."),
1526
(char**) &internal::my_use_symdir, (char**) &internal::my_use_symdir, 0, GET_BOOL, NO_ARG,
1528
The system call realpath() produces warnings under valgrind and
1529
purify. These are not suppressed: instead we disable symlinks
1530
option if compiled with valgrind support.
1532
IF_PURIFY(0,1), 0, 0, 0, 0, 0},
1533
{"timed_mutexes", OPT_TIMED_MUTEXES,
1534
N_("Specify whether to time mutexes (only InnoDB mutexes are currently "
1536
(char**) &internal::timed_mutexes, (char**) &internal::timed_mutexes, 0, GET_BOOL, NO_ARG, 0,
1539
N_("Path for temporary files."),
1540
(char**) &opt_drizzle_tmpdir,
1541
(char**) &opt_drizzle_tmpdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1542
{"transaction-isolation", OPT_TX_ISOLATION,
1543
N_("Default transaction isolation level."),
1544
0, 0, 0, GET_STR, REQUIRED_ARG, 0,
1547
N_("Run drizzled daemon as user."),
1548
0, 0, 0, GET_STR, REQUIRED_ARG,
1551
N_("Output version information and exit."),
1552
0, 0, 0, GET_NO_ARG,
1553
NO_ARG, 0, 0, 0, 0, 0, 0},
1554
{"back_log", OPT_BACK_LOG,
1555
N_("The number of outstanding connection requests Drizzle can have. This "
1556
"comes into play when the main Drizzle thread gets very many connection "
1557
"requests in a very short time."),
1558
(char**) &back_log, (char**) &back_log, 0, GET_UINT,
1559
REQUIRED_ARG, 50, 1, 65535, 0, 1, 0 },
1560
{ "bulk_insert_buffer_size", OPT_BULK_INSERT_BUFFER_SIZE,
1561
N_("Size of tree cache used in bulk insert optimization. Note that this is "
1562
"a limit per thread!"),
1563
(char**) &global_system_variables.bulk_insert_buff_size,
1564
(char**) &max_system_variables.bulk_insert_buff_size,
1565
0, GET_ULL, REQUIRED_ARG, 8192*1024, 0, ULONG_MAX, 0, 1, 0},
1566
{ "div_precision_increment", OPT_DIV_PRECINCREMENT,
1567
N_("Precision of the result of '/' operator will be increased on that "
1569
(char**) &global_system_variables.div_precincrement,
1570
(char**) &max_system_variables.div_precincrement, 0, GET_UINT,
1571
REQUIRED_ARG, 4, 0, DECIMAL_MAX_SCALE, 0, 0, 0},
1572
{ "group_concat_max_len", OPT_GROUP_CONCAT_MAX_LEN,
1573
N_("The maximum length of the result of function group_concat."),
1574
(char**) &global_system_variables.group_concat_max_len,
1575
(char**) &max_system_variables.group_concat_max_len, 0, GET_UINT64,
1576
REQUIRED_ARG, 1024, 4, ULONG_MAX, 0, 1, 0},
1577
{ "join_buffer_size", OPT_JOIN_BUFF_SIZE,
1578
N_("The size of the buffer that is used for full joins."),
1579
(char**) &global_system_variables.join_buff_size,
1580
(char**) &max_system_variables.join_buff_size, 0, GET_UINT64,
1581
REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ULONG_MAX,
1582
MALLOC_OVERHEAD, IO_SIZE, 0},
1583
{"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
1584
N_("Max packetlength to send/receive from to server."),
1585
(char**) &global_system_variables.max_allowed_packet,
1586
(char**) &max_system_variables.max_allowed_packet, 0, GET_UINT32,
1587
REQUIRED_ARG, 1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
1588
{"max_connect_errors", OPT_MAX_CONNECT_ERRORS,
1589
N_("If there is more than this number of interrupted connections from a "
1590
"host this host will be blocked from further connections."),
1591
(char**) &max_connect_errors, (char**) &max_connect_errors, 0, GET_UINT64,
1592
REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ULONG_MAX, 0, 1, 0},
1593
{"max_error_count", OPT_MAX_ERROR_COUNT,
1594
N_("Max number of errors/warnings to store for a statement."),
1595
(char**) &global_system_variables.max_error_count,
1596
(char**) &max_system_variables.max_error_count,
1597
0, GET_UINT64, REQUIRED_ARG, DEFAULT_ERROR_COUNT, 0, 65535, 0, 1, 0},
1598
{"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE,
1599
N_("Don't allow creation of heap tables bigger than this."),
1600
(char**) &global_system_variables.max_heap_table_size,
1601
(char**) &max_system_variables.max_heap_table_size, 0, GET_ULL,
1602
REQUIRED_ARG, 16*1024*1024L, 16384, MAX_MEM_TABLE_SIZE,
1603
MALLOC_OVERHEAD, 1024, 0},
1604
{"max_join_size", OPT_MAX_JOIN_SIZE,
1605
N_("Joins that are probably going to read more than max_join_size records "
1606
"return an error."),
1607
(char**) &global_system_variables.max_join_size,
1608
(char**) &max_system_variables.max_join_size, 0, GET_HA_ROWS, REQUIRED_ARG,
1609
INT32_MAX, 1, INT32_MAX, 0, 1, 0},
1610
{"max_length_for_sort_data", OPT_MAX_LENGTH_FOR_SORT_DATA,
1611
N_("Max number of bytes in sorted records."),
1612
(char**) &global_system_variables.max_length_for_sort_data,
1613
(char**) &max_system_variables.max_length_for_sort_data, 0, GET_ULL,
1614
REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
1615
{ "max_seeks_for_key", OPT_MAX_SEEKS_FOR_KEY,
1616
N_("Limit assumed max number of seeks when looking up rows based on a key"),
1617
(char**) &global_system_variables.max_seeks_for_key,
1618
(char**) &max_system_variables.max_seeks_for_key, 0, GET_UINT64,
1619
REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0 },
1620
{"max_sort_length", OPT_MAX_SORT_LENGTH,
1621
N_("The number of bytes to use when sorting BLOB or TEXT values "
1622
"(only the first max_sort_length bytes of each value are used; the "
1623
"rest are ignored)."),
1624
(char**) &global_system_variables.max_sort_length,
1625
(char**) &max_system_variables.max_sort_length, 0, GET_SIZE,
1626
REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
1627
{"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
1628
N_("After this many write locks, allow some read locks to run in between."),
1629
(char**) &max_write_lock_count, (char**) &max_write_lock_count, 0, GET_ULL,
1630
REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0},
1631
{"min_examined_row_limit", OPT_MIN_EXAMINED_ROW_LIMIT,
1632
N_("Don't log queries which examine less than min_examined_row_limit "
1634
(char**) &global_system_variables.min_examined_row_limit,
1635
(char**) &max_system_variables.min_examined_row_limit, 0, GET_ULL,
1636
REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1L, 0},
1637
{"optimizer_prune_level", OPT_OPTIMIZER_PRUNE_LEVEL,
1638
N_("Controls the heuristic(s) applied during query optimization to prune "
1639
"less-promising partial plans from the optimizer search space. Meaning: "
1640
"false - do not apply any heuristic, thus perform exhaustive search; "
1641
"true - prune plans based on number of retrieved rows."),
1642
(char**) &global_system_variables.optimizer_prune_level,
1643
(char**) &max_system_variables.optimizer_prune_level,
1644
0, GET_BOOL, OPT_ARG, 1, 0, 1, 0, 1, 0},
1645
{"optimizer_search_depth", OPT_OPTIMIZER_SEARCH_DEPTH,
1646
N_("Maximum depth of search performed by the query optimizer. Values "
1647
"larger than the number of relations in a query result in better query "
1648
"plans, but take longer to compile a query. Smaller values than the "
1649
"number of tables in a relation result in faster optimization, but may "
1650
"produce very bad query plans. If set to 0, the system will "
1651
"automatically pick a reasonable value; if set to MAX_TABLES+2, the "
1652
"optimizer will switch to the original find_best (used for "
1653
"testing/comparison)."),
1654
(char**) &global_system_variables.optimizer_search_depth,
1655
(char**) &max_system_variables.optimizer_search_depth,
1656
0, GET_UINT, OPT_ARG, 0, 0, MAX_TABLES+2, 0, 1, 0},
1657
{"plugin_dir", OPT_PLUGIN_DIR,
1658
N_("Directory for plugins."),
1659
(char**) &opt_plugin_dir_ptr, (char**) &opt_plugin_dir_ptr, 0,
1660
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1661
{"plugin_add", OPT_PLUGIN_ADD,
1662
N_("Optional comma separated list of plugins to load at startup in addition "
1663
"to the default list of plugins. "
1664
"[for example: --plugin_add=crc32,logger_gearman]"),
1665
(char**) &opt_plugin_add, (char**) &opt_plugin_add, 0,
1666
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1667
{"plugin_remove", OPT_PLUGIN_ADD,
1668
N_("Optional comma separated list of plugins to not load at startup. Effectively "
1669
"removes a plugin from the list of plugins to be loaded. "
1670
"[for example: --plugin_remove=crc32,logger_gearman]"),
1671
(char**) &opt_plugin_remove, (char**) &opt_plugin_remove, 0,
1672
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1673
{"plugin_load", OPT_PLUGIN_LOAD,
1674
N_("Optional comma separated list of plugins to load at starup instead of "
1675
"the default plugin load list. "
1676
"[for example: --plugin_load=crc32,logger_gearman]"),
1677
(char**) &opt_plugin_load, (char**) &opt_plugin_load, 0,
1678
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1679
{"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
1680
N_("The size of the buffer that is allocated when preloading indexes"),
1681
(char**) &global_system_variables.preload_buff_size,
1682
(char**) &max_system_variables.preload_buff_size, 0, GET_ULL,
1683
REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0},
1684
{"query_alloc_block_size", OPT_QUERY_ALLOC_BLOCK_SIZE,
1685
N_("Allocation block size for query parsing and execution"),
1686
(char**) &global_system_variables.query_alloc_block_size,
1687
(char**) &max_system_variables.query_alloc_block_size, 0, GET_UINT,
1688
REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
1689
{"query_prealloc_size", OPT_QUERY_PREALLOC_SIZE,
1690
N_("Persistent buffer for query parsing and execution"),
1691
(char**) &global_system_variables.query_prealloc_size,
1692
(char**) &max_system_variables.query_prealloc_size, 0, GET_UINT,
1693
REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, QUERY_ALLOC_PREALLOC_SIZE,
1694
ULONG_MAX, 0, 1024, 0},
1695
{"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE,
1696
N_("Allocation block size for storing ranges during optimization"),
1697
(char**) &global_system_variables.range_alloc_block_size,
1698
(char**) &max_system_variables.range_alloc_block_size, 0, GET_SIZE,
1699
REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, SIZE_MAX,
1701
{"read_buffer_size", OPT_RECORD_BUFFER,
1702
N_("Each thread that does a sequential scan allocates a buffer of this "
1703
"size for each table it scans. If you do many sequential scans, you may "
1704
"want to increase this value."),
1705
(char**) &global_system_variables.read_buff_size,
1706
(char**) &max_system_variables.read_buff_size,0, GET_UINT, REQUIRED_ARG,
1707
128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, INT32_MAX, MALLOC_OVERHEAD, IO_SIZE,
1709
{"read_rnd_buffer_size", OPT_RECORD_RND_BUFFER,
1710
N_("When reading rows in sorted order after a sort, the rows are read "
1711
"through this buffer to avoid a disk seeks. If not set, then it's set "
1712
"to the value of record_buffer."),
1713
(char**) &global_system_variables.read_rnd_buff_size,
1714
(char**) &max_system_variables.read_rnd_buff_size, 0,
1715
GET_UINT, REQUIRED_ARG, 256*1024L, 64 /*IO_SIZE*2+MALLOC_OVERHEAD*/ ,
1716
UINT32_MAX, MALLOC_OVERHEAD, 1 /* Small lower limit to be able to test MRR */, 0},
1717
{"scheduler", OPT_SCHEDULER,
1718
N_("Select scheduler to be used (by default multi-thread)."),
1719
(char**)&opt_scheduler, (char**)&opt_scheduler,
1720
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1721
/* x8 compared to MySQL's x2. We have UTF8 to consider. */
1722
{"sort_buffer_size", OPT_SORT_BUFFER,
1723
N_("Each thread that needs to do a sort allocates a buffer of this size."),
1724
(char**) &global_system_variables.sortbuff_size,
1725
(char**) &max_system_variables.sortbuff_size, 0, GET_SIZE, REQUIRED_ARG,
1726
MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*8, SIZE_MAX,
1727
MALLOC_OVERHEAD, 1, 0},
1728
{"table_definition_cache", OPT_TABLE_DEF_CACHE,
1729
N_("The number of cached table definitions."),
1730
(char**) &table_def_size, (char**) &table_def_size,
1731
0, GET_SIZE, REQUIRED_ARG, 128, 1, 512*1024L, 0, 1, 0},
1732
{"table_open_cache", OPT_TABLE_OPEN_CACHE,
1733
N_("The number of cached open tables."),
1734
(char**) &table_cache_size, (char**) &table_cache_size, 0, GET_UINT64,
1735
REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, TABLE_OPEN_CACHE_MIN, 512*1024L, 0, 1, 0},
1736
{"table_lock_wait_timeout", OPT_TABLE_LOCK_WAIT_TIMEOUT,
1737
N_("Timeout in seconds to wait for a table level lock before returning an "
1738
"error. Used only if the connection has active cursors."),
1739
(char**) &table_lock_wait_timeout, (char**) &table_lock_wait_timeout,
1740
0, GET_ULL, REQUIRED_ARG, 50, 1, 1024 * 1024 * 1024, 0, 1, 0},
1741
{"thread_stack", OPT_THREAD_STACK,
1742
N_("The stack size for each thread."),
1743
(char**) &my_thread_stack_size,
1744
(char**) &my_thread_stack_size, 0, GET_SIZE,
1745
REQUIRED_ARG,DEFAULT_THREAD_STACK,
1746
UINT32_C(1024*512), SIZE_MAX, 0, 1024, 0},
1747
{"tmp_table_size", OPT_TMP_TABLE_SIZE,
1748
N_("If an internal in-memory temporary table exceeds this size, Drizzle will"
1749
" automatically convert it to an on-disk MyISAM table."),
1750
(char**) &global_system_variables.tmp_table_size,
1751
(char**) &max_system_variables.tmp_table_size, 0, GET_ULL,
1752
REQUIRED_ARG, 16*1024*1024L, 1024, MAX_MEM_TABLE_SIZE, 0, 1, 0},
1753
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
1756
static void print_version(void)
1759
Note: the instance manager keys off the string 'Ver' so it can find the
1760
version from the output of 'drizzled --version', so don't change it!
1762
printf("%s Ver %s for %s-%s on %s (%s)\n",internal::my_progname,
1763
PANDORA_RELEASE_VERSION, HOST_VENDOR, HOST_OS, HOST_CPU,
1764
COMPILATION_COMMENT);
1767
static void usage(void)
1769
if (!(default_charset_info= get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)))
1771
if (!default_collation_name)
1772
default_collation_name= (char*) default_charset_info->name;
1774
puts(_("Copyright (C) 2008 Sun Microsystems\n"
1775
"This software comes with ABSOLUTELY NO WARRANTY. "
1776
"This is free software,\n"
1777
"and you are welcome to modify and redistribute it under the GPL "
1779
"Starts the Drizzle database server\n"));
1781
printf(_("Usage: %s [OPTIONS]\n"), internal::my_progname);
1783
internal::print_defaults(DRIZZLE_CONFIG_NAME,load_default_groups);
1786
/* Print out all the options including plugin supplied options */
1787
my_print_help_inc_plugins(my_long_options);
1793
Initialize all Drizzle global variables to default values.
1795
We don't need to set numeric variables refered to in my_long_options
1796
as these are initialized by my_getopt.
1799
The reason to set a lot of global variables to zero is to allow one to
1800
restart the embedded server with a clean environment
1801
It's also needed on some exotic platforms where global variables are
1802
not set to 0 when a program starts.
1804
We don't need to set numeric variables refered to in my_long_options
1805
as these are initialized by my_getopt.
1808
static void drizzle_init_variables(void)
1810
/* Things reset to zero */
1811
drizzle_home[0]= pidfile_name[0]= 0;
1812
opt_tc_log_file= (char *)"tc.log"; // no hostname in tc_log file name !
1813
opt_secure_file_priv= 0;
1818
dropping_tables= ha_open_options=0;
1821
abort_loop= select_thread_in_use= false;
1822
ready_to_exit= shutdown_in_progress= 0;
1823
aborted_threads= aborted_connects= 0;
1824
max_used_connections= 0;
1825
drizzled_user= drizzled_chroot= 0;
1826
memset(&global_status_var, 0, sizeof(global_status_var));
1829
/* Character sets */
1830
system_charset_info= &my_charset_utf8_general_ci;
1831
files_charset_info= &my_charset_utf8_general_ci;
1832
table_alias_charset= &my_charset_bin;
1833
character_set_filesystem= &my_charset_bin;
1835
/* Things with default values that are not zero */
1836
drizzle_home_ptr= drizzle_home;
1837
pidfile_name_ptr= pidfile_name;
1838
language_ptr= language;
1839
drizzle_data_home= drizzle_real_data_home;
1840
session_startup_options= (OPTION_AUTO_IS_NULL | OPTION_SQL_NOTES);
1841
refresh_version= 1L; /* Increments on each reload */
1842
global_thread_id= 1UL;
1843
getSessionList().clear();
1845
/* Set directory paths */
1846
strncpy(language, LANGUAGE, sizeof(language)-1);
1847
strncpy(drizzle_real_data_home, get_relative_path(LOCALSTATEDIR),
1848
sizeof(drizzle_real_data_home)-1);
1849
drizzle_data_home_buff[0]=FN_CURLIB; // all paths are relative from here
1850
drizzle_data_home_buff[1]=0;
1851
drizzle_data_home_len= 2;
1853
/* Variables in libraries */
1854
default_character_set_name= "utf8";
1855
default_collation_name= (char *)compiled_default_collation_name;
1856
character_set_filesystem_name= "binary";
1857
lc_time_names_name= (char*) "en_US";
1858
/* Set default values for some option variables */
1859
default_storage_engine_str= (char*) "innodb";
1860
global_system_variables.storage_engine= NULL;
1861
global_system_variables.tx_isolation= ISO_REPEATABLE_READ;
1862
global_system_variables.select_limit= (uint64_t) HA_POS_ERROR;
1863
max_system_variables.select_limit= (uint64_t) HA_POS_ERROR;
1864
global_system_variables.max_join_size= (uint64_t) HA_POS_ERROR;
1865
max_system_variables.max_join_size= (uint64_t) HA_POS_ERROR;
1867
/* Variables that depends on compile options */
1868
#ifdef HAVE_BROKEN_REALPATH
1869
have_symlink=SHOW_OPTION_NO;
1871
have_symlink=SHOW_OPTION_YES;
1875
if (!(tmpenv = getenv("MY_BASEDIR_VERSION")))
1877
(void) strncpy(drizzle_home, tmpenv, sizeof(drizzle_home)-1);
1879
connection_count= 0;
1883
bool drizzled_get_one_option(int optid, const struct my_option *opt,
1888
global_system_variables.tx_isolation= ISO_SERIALIZABLE;
1891
strncpy(drizzle_home,argument,sizeof(drizzle_home)-1);
1894
if (default_collation_name == compiled_default_collation_name)
1895
default_collation_name= 0;
1898
strncpy(drizzle_real_data_home,argument, sizeof(drizzle_real_data_home)-1);
1899
/* Correct pointer set by my_getopt (for embedded library) */
1900
drizzle_data_home= drizzle_real_data_home;
1901
drizzle_data_home_len= strlen(drizzle_data_home);
1904
if (!drizzled_user || !strcmp(drizzled_user, argument))
1905
drizzled_user= argument;
1907
errmsg_printf(ERRMSG_LVL_WARN, _("Ignoring user change to '%s' because the user was "
1908
"set to '%s' earlier on the command line\n"),
1909
argument, drizzled_user);
1912
strncpy(language, argument, sizeof(language)-1);
1919
global_system_variables.log_warnings++;
1920
else if (argument == disabled_my_option)
1921
global_system_variables.log_warnings= 0L;
1923
global_system_variables.log_warnings= atoi(argument);
1928
test_flags.set((uint32_t) atoi(argument));
1931
case (int) OPT_WANT_CORE:
1932
test_flags.set(TEST_CORE_ON_SIGNAL);
1934
case (int) OPT_SKIP_STACK_TRACE:
1935
test_flags.set(TEST_NO_STACKTRACE);
1937
case (int) OPT_SKIP_SYMLINKS:
1938
internal::my_use_symdir=0;
1940
case (int) OPT_BIND_ADDRESS:
1942
struct addrinfo *res_lst, hints;
1944
memset(&hints, 0, sizeof(struct addrinfo));
1945
hints.ai_socktype= SOCK_STREAM;
1946
hints.ai_protocol= IPPROTO_TCP;
1948
if (getaddrinfo(argument, NULL, &hints, &res_lst) != 0)
1950
errmsg_printf(ERRMSG_LVL_ERROR, _("Can't start server: cannot resolve hostname!"));
1954
if (res_lst->ai_next)
1956
errmsg_printf(ERRMSG_LVL_ERROR, _("Can't start server: bind-address refers to "
1957
"multiple interfaces!"));
1960
freeaddrinfo(res_lst);
1963
case (int) OPT_PID_FILE:
1964
strncpy(pidfile_name, argument, sizeof(pidfile_name)-1);
1968
case OPT_TX_ISOLATION:
1971
type= find_type_or_exit(argument, &tx_isolation_typelib, opt->name);
1972
global_system_variables.tx_isolation= (type-1);
1975
case OPT_TC_HEURISTIC_RECOVER:
1976
tc_heuristic_recover= find_type_or_exit(argument,
1977
&tc_heuristic_recover_typelib,
1985
static void option_error_reporter(enum loglevel level, const char *format, ...)
1988
va_start(args, format);
1990
/* Don't print warnings for --loose options during bootstrap */
1991
if (level == ERROR_LEVEL || global_system_variables.log_warnings)
1993
plugin::ErrorMessage::vprintf(current_session, ERROR_LEVEL, format, args);
2001
- FIXME add EXIT_TOO_MANY_ARGUMENTS to "drizzled/error.h" and return that code?
2003
static void get_options(int *argc,char **argv)
2007
my_getopt_error_reporter= option_error_reporter;
2009
string progname(argv[0]);
2011
/* Skip unknown options so that they may be processed later by plugins */
2012
my_getopt_skip_unknown= true;
2014
if ((ho_error= handle_options(argc, &argv, my_long_options,
2015
drizzled_get_one_option)))
2017
(*argc)++; /* add back one for the progname handle_options removes */
2018
/* no need to do this for argv as we are discarding it. */
2020
#if defined(HAVE_BROKEN_REALPATH)
2021
internal::my_use_symdir=0;
2022
internal::my_disable_symlinks=1;
2023
have_symlink=SHOW_OPTION_NO;
2025
if (!internal::my_use_symdir)
2027
internal::my_disable_symlinks=1;
2028
have_symlink=SHOW_OPTION_DISABLED;
2033
/* Allow break with SIGINT, no core or stack trace */
2034
test_flags.set(TEST_SIGINT);
2035
test_flags.set(TEST_NO_STACKTRACE);
2036
test_flags.reset(TEST_CORE_ON_SIGNAL);
2039
if (drizzled_chroot)
2040
set_root(drizzled_chroot);
2041
fix_paths(progname);
2044
Set some global variables from the global_system_variables
2045
In most cases the global variables will not be used
2047
internal::my_default_record_cache_size=global_system_variables.read_buff_size;
2051
static const char *get_relative_path(const char *path)
2053
if (internal::test_if_hard_path(path) &&
2054
(strncmp(path, PREFIX, strlen(PREFIX)) == 0) &&
2055
strcmp(PREFIX,FN_ROOTDIR))
2057
if (strlen(PREFIX) < strlen(path))
2058
path+=(size_t) strlen(PREFIX);
2059
while (*path == FN_LIBCHAR)
2066
static void fix_paths(string &progname)
2068
char buff[FN_REFLEN],*pos,rp_buff[PATH_MAX];
2069
internal::convert_dirname(drizzle_home,drizzle_home,NULL);
2070
/* Resolve symlinks to allow 'drizzle_home' to be a relative symlink */
2071
#if defined(HAVE_BROKEN_REALPATH)
2072
internal::my_load_path(drizzle_home, drizzle_home, NULL);
2074
if (!realpath(drizzle_home,rp_buff))
2075
internal::my_load_path(rp_buff, drizzle_home, NULL);
2076
rp_buff[FN_REFLEN-1]= '\0';
2077
strcpy(drizzle_home,rp_buff);
2078
/* Ensure that drizzle_home ends in FN_LIBCHAR */
2079
pos= strchr(drizzle_home, '\0');
2081
if (pos[-1] != FN_LIBCHAR)
2086
internal::convert_dirname(drizzle_real_data_home,drizzle_real_data_home,NULL);
2087
(void) internal::fn_format(buff, drizzle_real_data_home, "", "",
2088
(MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
2089
(void) internal::unpack_dirname(drizzle_unpacked_real_data_home, buff);
2090
internal::convert_dirname(language,language,NULL);
2091
(void) internal::my_load_path(drizzle_home, drizzle_home,""); // Resolve current dir
2092
(void) internal::my_load_path(drizzle_real_data_home, drizzle_real_data_home,drizzle_home);
2093
(void) internal::my_load_path(pidfile_name, pidfile_name,drizzle_real_data_home);
2095
if (opt_plugin_dir_ptr == NULL)
2097
/* No plugin dir has been specified. Figure out where the plugins are */
2098
if (progname[0] != FN_LIBCHAR)
2100
/* We have a relative path and need to find the absolute */
2101
char working_dir[FN_REFLEN];
2102
char *working_dir_ptr= working_dir;
2103
working_dir_ptr= getcwd(working_dir_ptr, FN_REFLEN);
2104
string new_path(working_dir);
2105
if (*(new_path.end()-1) != '/')
2106
new_path.push_back('/');
2107
if (progname[0] == '.' && progname[1] == '/')
2108
new_path.append(progname.substr(2));
2110
new_path.append(progname);
2111
progname.swap(new_path);
2114
/* Now, trim off the exe name */
2115
string progdir(progname.substr(0, progname.rfind(FN_LIBCHAR)+1));
2116
if (progdir.rfind(".libs/") != string::npos)
2118
progdir.assign(progdir.substr(0, progdir.rfind(".libs/")));
2120
string testfile(progdir);
2121
testfile.append("drizzled.o");
2122
struct stat testfile_stat;
2123
if (stat(testfile.c_str(), &testfile_stat))
2125
/* drizzled.o doesn't exist - we are not in a source dir.
2128
(void) internal::my_load_path(opt_plugin_dir, get_relative_path(PKGPLUGINDIR),
2133
/* We are in a source dir! Plugin dir is ../plugin/.libs */
2134
size_t last_libchar_pos= progdir.rfind(FN_LIBCHAR,progdir.size()-2)+1;
2135
string source_plugindir(progdir.substr(0,last_libchar_pos));
2136
source_plugindir.append("plugin/.libs");
2137
(void) internal::my_load_path(opt_plugin_dir, source_plugindir.c_str(), "");
2142
(void) internal::my_load_path(opt_plugin_dir, opt_plugin_dir_ptr, drizzle_home);
2144
opt_plugin_dir_ptr= opt_plugin_dir;
2146
const char *sharedir= get_relative_path(PKGDATADIR);
2147
if (internal::test_if_hard_path(sharedir))
2148
strncpy(buff,sharedir,sizeof(buff)-1);
2151
strcpy(buff, drizzle_home);
2152
strncat(buff, sharedir, sizeof(buff)-strlen(drizzle_home)-1);
2154
internal::convert_dirname(buff,buff,NULL);
2155
(void) internal::my_load_path(language,language,buff);
2161
tmp_string= getenv("TMPDIR");
2163
if (opt_drizzle_tmpdir)
2164
drizzle_tmpdir= strdup(opt_drizzle_tmpdir);
2165
else if (tmp_string == NULL)
2166
drizzle_tmpdir= strdup(P_tmpdir);
2168
drizzle_tmpdir= strdup(tmp_string);
2170
assert(drizzle_tmpdir);
2172
if (stat(drizzle_tmpdir, &buf) || (S_ISDIR(buf.st_mode) == false))
2179
Convert the secure-file-priv option to system format, allowing
2180
a quick strcmp to check if read or write is in an allowed dir
2182
if (opt_secure_file_priv)
2184
internal::convert_dirname(buff, opt_secure_file_priv, NULL);
2185
free(opt_secure_file_priv);
2186
opt_secure_file_priv= strdup(buff);
2187
if (opt_secure_file_priv == NULL)
2192
} /* namespace drizzled */
2194
using namespace drizzled;
2197
static void init_signals(void)
2200
struct sigaction sa;
2202
if (!(test_flags.test(TEST_NO_STACKTRACE) ||
2203
test_flags.test(TEST_CORE_ON_SIGNAL)))
2205
sa.sa_flags = SA_RESETHAND | SA_NODEFER;
2206
sigemptyset(&sa.sa_mask);
2207
sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
2210
sa.sa_handler=handle_segfault;
2211
sigaction(SIGSEGV, &sa, NULL);
2212
sigaction(SIGABRT, &sa, NULL);
2214
sigaction(SIGBUS, &sa, NULL);
2216
sigaction(SIGILL, &sa, NULL);
2217
sigaction(SIGFPE, &sa, NULL);
2220
if (test_flags.test(TEST_CORE_ON_SIGNAL))
2222
/* Change limits so that we will get a core file */
2224
rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
2225
if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
2226
errmsg_printf(ERRMSG_LVL_WARN,
2227
_("setrlimit could not change the size of core files "
2228
"to 'infinity'; We may not be able to generate a "
2229
"core file on signals"));
2231
(void) sigemptyset(&set);
2232
my_sigset(SIGPIPE,SIG_IGN);
2233
sigaddset(&set,SIGPIPE);
2234
#ifndef IGNORE_SIGHUP_SIGQUIT
2235
sigaddset(&set,SIGQUIT);
2236
sigaddset(&set,SIGHUP);
2238
sigaddset(&set,SIGTERM);
2240
/* Fix signals if blocked by parents (can happen on Mac OS X) */
2241
sigemptyset(&sa.sa_mask);
2243
sa.sa_handler = print_signal_warning;
2244
sigaction(SIGTERM, &sa, (struct sigaction*) 0);
2246
sa.sa_handler = print_signal_warning;
2247
sigaction(SIGHUP, &sa, (struct sigaction*) 0);
2249
sigaddset(&set,SIGTSTP);
2251
if (test_flags.test(TEST_SIGINT))
2253
my_sigset(thr_kill_signal, end_thread_signal);
2255
sigdelset(&set, thr_kill_signal);
2258
sigaddset(&set,SIGINT);
2259
sigprocmask(SIG_SETMASK,&set,NULL);
2260
pthread_sigmask(SIG_SETMASK,&set,NULL);
2264
int main(int argc, char **argv)
2266
#if defined(ENABLE_NLS)
2267
# if defined(HAVE_LOCALE_H)
2268
setlocale(LC_ALL, "");
2270
bindtextdomain("drizzle", LOCALEDIR);
2271
textdomain("drizzle");
2274
plugin::Registry &plugins= plugin::Registry::singleton();
2275
plugin::Client *client;
2278
MY_INIT(argv[0]); // init my_sys library & pthreads
2279
/* nothing should come before this line ^^^ */
2281
/* Set signal used to kill Drizzle */
2282
#if defined(SIGUSR2)
2283
thr_kill_signal= internal::thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2;
2285
thr_kill_signal= SIGINT;
2288
if (init_common_variables(DRIZZLE_CONFIG_NAME,
2289
argc, argv, load_default_groups))
2290
unireg_abort(1); // Will do exit
2295
select_thread=pthread_self();
2296
select_thread_in_use=1;
2298
if (chdir(drizzle_real_data_home) && !opt_help)
2300
errmsg_printf(ERRMSG_LVL_ERROR, _("Data directory %s does not exist\n"), drizzle_real_data_home);
2303
drizzle_data_home= drizzle_data_home_buff;
2304
drizzle_data_home[0]=FN_CURLIB; // all paths are relative from here
2305
drizzle_data_home[1]=0;
2306
drizzle_data_home_len= 2;
2308
if ((user_info= check_user(drizzled_user)))
2310
set_user(drizzled_user, user_info);
2318
if (init_server_components(plugins))
2321
if (plugin::Listen::setup())
2325
init signals & alarm
2326
After this we can't quit by a simple unireg_abort
2328
error_handler_hook= my_message_sql;
2330
assert(plugin::num_trx_monitored_objects > 0);
2331
if (drizzle_rm_tmp_tables() ||
2332
my_tz_init((Session *)0, default_tz_name))
2335
select_thread_in_use=0;
2336
(void) pthread_kill(signal_thread, SIGTERM);
2338
(void) unlink(pidfile_name); // Not needed anymore
2345
errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)), internal::my_progname,
2346
PANDORA_RELEASE_VERSION, COMPILATION_COMMENT);
2349
/* Listen for new connections and start new session for each connection
2350
accepted. The listen.getClient() method will return NULL when the server
2351
should be shutdown. */
2352
while ((client= plugin::Listen::getClient()) != NULL)
2354
if (!(session= new Session(client)))
2360
/* If we error on creation we drop the connection and delete the session. */
2361
if (session->schedule())
2362
Session::unlink(session);
2365
/* (void) pthread_attr_destroy(&connection_attrib); */
2368
(void) pthread_mutex_lock(&LOCK_thread_count);
2369
select_thread_in_use=0; // For close_connections
2370
(void) pthread_mutex_unlock(&LOCK_thread_count);
2371
(void) pthread_cond_broadcast(&COND_thread_count);
2373
/* Wait until cleanup is done */
2374
(void) pthread_mutex_lock(&LOCK_thread_count);
2375
while (!ready_to_exit)
2376
pthread_cond_wait(&COND_server_end,&LOCK_thread_count);
2377
(void) pthread_mutex_unlock(&LOCK_thread_count);
2380
plugin::Registry::shutdown();