00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "config.h"
00021 #include <drizzled/configmake.h>
00022 #include <drizzled/atomics.h>
00023
00024 #include <netdb.h>
00025 #include <sys/types.h>
00026 #include <netinet/tcp.h>
00027 #include <netinet/in.h>
00028 #include <signal.h>
00029 #include <limits.h>
00030
00031 #include "drizzled/internal/my_sys.h"
00032 #include "drizzled/internal/my_bit.h"
00033 #include <drizzled/my_hash.h>
00034 #include <drizzled/stacktrace.h>
00035 #include "drizzled/my_error.h"
00036 #include <drizzled/error.h>
00037 #include <drizzled/errmsg_print.h>
00038 #include <drizzled/tztime.h>
00039 #include <drizzled/sql_base.h>
00040 #include <drizzled/show.h>
00041 #include <drizzled/sql_parse.h>
00042 #include <drizzled/item/cmpfunc.h>
00043 #include <drizzled/session.h>
00044 #include <drizzled/item/create.h>
00045 #include <drizzled/unireg.h>
00046 #include "drizzled/temporal_format.h"
00047 #include "drizzled/plugin/listen.h"
00048 #include "drizzled/plugin/error_message.h"
00049 #include "drizzled/plugin/client.h"
00050 #include "drizzled/plugin/scheduler.h"
00051 #include "drizzled/probes.h"
00052 #include "drizzled/session_list.h"
00053 #include "drizzled/charset.h"
00054 #include "plugin/myisam/myisam.h"
00055
00056 #include <google/protobuf/stubs/common.h>
00057
00058 #if TIME_WITH_SYS_TIME
00059 # include <sys/time.h>
00060 # include <time.h>
00061 #else
00062 # if HAVE_SYS_TIME_H
00063 # include <sys/time.h>
00064 # else
00065 # include <time.h>
00066 # endif
00067 #endif
00068
00069 #ifdef HAVE_SYS_PRCTL_H
00070 #include <sys/prctl.h>
00071 #endif
00072 #include <sys/socket.h>
00073
00074 #include <locale.h>
00075
00076 #define mysqld_charset &my_charset_utf8_general_ci
00077
00078 #ifdef HAVE_purify
00079 #define IF_PURIFY(A,B) (A)
00080 #else
00081 #define IF_PURIFY(A,B) (B)
00082 #endif
00083
00084 #define MAX_MEM_TABLE_SIZE SIZE_MAX
00085
00086 #include <errno.h>
00087 #include <sys/stat.h>
00088 #include "drizzled/my_getopt.h"
00089 #ifdef HAVE_SYSENT_H
00090 #include <sysent.h>
00091 #endif
00092 #include <pwd.h>
00093 #include <grp.h>
00094
00095 #include <sys/resource.h>
00096
00097 #ifdef HAVE_SELECT_H
00098 # include <select.h>
00099 #endif
00100
00101 #ifdef HAVE_SYS_SELECT_H
00102 #include <sys/select.h>
00103 #endif
00104
00105 #include <sys/utsname.h>
00106
00107 #ifdef HAVE_SYS_MMAN_H
00108 #include <sys/mman.h>
00109 #endif
00110
00111 #if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
00112 #include <ieeefp.h>
00113 #endif
00114
00115 #ifdef HAVE_FPU_CONTROL_H
00116 #include <fpu_control.h>
00117 #endif
00118
00119 #ifdef HAVE_SYS_FPU_H
00120
00121 #include <sys/fpu.h>
00122 #endif
00123
00124 inline void setup_fpu()
00125 {
00126 #if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
00127
00128
00129
00130
00131
00132 #if defined(__i386__)
00133 fpsetmask(~(FP_X_INV | FP_X_DNML | FP_X_OFL | FP_X_UFL | FP_X_DZ |
00134 FP_X_IMP));
00135 #else
00136 fpsetmask(~(FP_X_INV | FP_X_OFL | FP_X_UFL | FP_X_DZ |
00137 FP_X_IMP));
00138 #endif
00139 #endif
00140
00141
00142
00143
00144
00145 #if defined(__i386__) && defined(HAVE_FPU_CONTROL_H) && defined(_FPU_DOUBLE)
00146 fpu_control_t cw;
00147 _FPU_GETCW(cw);
00148 cw= (cw & ~_FPU_EXTENDED) | _FPU_DOUBLE;
00149 _FPU_SETCW(cw);
00150 #endif
00151 }
00152
00153 #include "drizzled/internal/my_pthread.h"
00154
00155 #include <drizzled/gettext.h>
00156
00157 #ifdef SOLARIS
00158 extern "C" int gethostname(char *name, int namelen);
00159 #endif
00160
00161 using namespace std;
00162 using namespace drizzled;
00163
00164
00165
00166
00167 const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"};
00168 static const char *optimizer_switch_names[]=
00169 {
00170 "no_materialization", "no_semijoin",
00171 NULL
00172 };
00173
00174
00175 static const unsigned int optimizer_switch_names_len[]=
00176 {
00177 19,
00178 11
00179 };
00180
00181 TYPELIB optimizer_switch_typelib= { array_elements(optimizer_switch_names)-1,"",
00182 optimizer_switch_names,
00183 (unsigned int *)optimizer_switch_names_len };
00184
00185 static const char *tc_heuristic_recover_names[]=
00186 {
00187 "COMMIT", "ROLLBACK", NULL
00188 };
00189 static TYPELIB tc_heuristic_recover_typelib=
00190 {
00191 array_elements(tc_heuristic_recover_names)-1,"",
00192 tc_heuristic_recover_names, NULL
00193 };
00194
00195 const char *first_keyword= "first";
00196 const char * const DRIZZLE_CONFIG_NAME= "drizzled";
00197 #define GET_HA_ROWS GET_ULL
00198
00199 const char *tx_isolation_names[] =
00200 { "READ-UNCOMMITTED", "READ-COMMITTED", "REPEATABLE-READ", "SERIALIZABLE",
00201 NULL};
00202
00203 TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"",
00204 tx_isolation_names, NULL};
00205
00206
00207
00208
00209 static bool opt_help= false;
00210 static bool opt_help_extended= false;
00211
00212 arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
00213 {{&Arg_comparator::compare_string, &Arg_comparator::compare_e_string},
00214 {&Arg_comparator::compare_real, &Arg_comparator::compare_e_real},
00215 {&Arg_comparator::compare_int_signed, &Arg_comparator::compare_e_int},
00216 {&Arg_comparator::compare_row, &Arg_comparator::compare_e_row},
00217 {&Arg_comparator::compare_decimal, &Arg_comparator::compare_e_decimal}};
00218
00219
00220
00221 static bool volatile select_thread_in_use;
00222 static bool volatile ready_to_exit;
00223 static bool opt_debugging= 0;
00224 static uint32_t wake_thread;
00225 static uint32_t killed_threads;
00226 static char *drizzled_user, *drizzled_chroot;
00227 static char *language_ptr;
00228 static const char *default_character_set_name;
00229 static const char *character_set_filesystem_name;
00230 static char *lc_time_names_name;
00231 static char *default_collation_name;
00232 static char *default_storage_engine_str;
00233 static const char *compiled_default_collation_name= "utf8_general_ci";
00234
00235
00236
00237 bool locked_in_memory;
00238 bool volatile abort_loop;
00239 bool volatile shutdown_in_progress;
00240 uint32_t max_used_connections;
00241 const string opt_scheduler_default("multi_thread");
00242 char *opt_scheduler= NULL;
00243
00244 size_t my_thread_stack_size= 65536;
00245
00246
00247
00248
00249 plugin::StorageEngine *heap_engine;
00250 plugin::StorageEngine *myisam_engine;
00251
00252 char* opt_secure_file_priv= 0;
00253
00254 static bool calling_initgroups= false;
00256 uint32_t drizzled_bind_timeout;
00257 std::bitset<12> test_flags;
00258 uint32_t dropping_tables, ha_open_options;
00259 uint32_t tc_heuristic_recover= 0;
00260 uint64_t session_startup_options;
00261 uint32_t back_log;
00262 uint32_t server_id;
00263 uint64_t table_cache_size;
00264 size_t table_def_size;
00265 uint64_t aborted_threads;
00266 uint64_t aborted_connects;
00267 uint64_t max_connect_errors;
00268 uint32_t global_thread_id= 1UL;
00269 pid_t current_pid;
00270
00271 extern const double log_10[309];
00272
00273 const double log_10[] = {
00274 1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007, 1e008, 1e009,
00275 1e010, 1e011, 1e012, 1e013, 1e014, 1e015, 1e016, 1e017, 1e018, 1e019,
00276 1e020, 1e021, 1e022, 1e023, 1e024, 1e025, 1e026, 1e027, 1e028, 1e029,
00277 1e030, 1e031, 1e032, 1e033, 1e034, 1e035, 1e036, 1e037, 1e038, 1e039,
00278 1e040, 1e041, 1e042, 1e043, 1e044, 1e045, 1e046, 1e047, 1e048, 1e049,
00279 1e050, 1e051, 1e052, 1e053, 1e054, 1e055, 1e056, 1e057, 1e058, 1e059,
00280 1e060, 1e061, 1e062, 1e063, 1e064, 1e065, 1e066, 1e067, 1e068, 1e069,
00281 1e070, 1e071, 1e072, 1e073, 1e074, 1e075, 1e076, 1e077, 1e078, 1e079,
00282 1e080, 1e081, 1e082, 1e083, 1e084, 1e085, 1e086, 1e087, 1e088, 1e089,
00283 1e090, 1e091, 1e092, 1e093, 1e094, 1e095, 1e096, 1e097, 1e098, 1e099,
00284 1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109,
00285 1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119,
00286 1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129,
00287 1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139,
00288 1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149,
00289 1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159,
00290 1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169,
00291 1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179,
00292 1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189,
00293 1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199,
00294 1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209,
00295 1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219,
00296 1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229,
00297 1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239,
00298 1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249,
00299 1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259,
00300 1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269,
00301 1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279,
00302 1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289,
00303 1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299,
00304 1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308
00305 };
00306
00307 time_t server_start_time;
00308 time_t flush_status_time;
00309
00310 char drizzle_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
00311 char *default_tz_name;
00312 char glob_hostname[FN_REFLEN];
00313 char drizzle_real_data_home[FN_REFLEN],
00314 language[FN_REFLEN],
00315 *opt_tc_log_file;
00316 char drizzle_unpacked_real_data_home[FN_REFLEN];
00317 const key_map key_map_empty(0);
00318 key_map key_map_full(0);
00319
00320 uint32_t drizzle_data_home_len;
00321 char drizzle_data_home_buff[2], *drizzle_data_home=drizzle_real_data_home;
00322 char *drizzle_tmpdir= NULL;
00323 char *opt_drizzle_tmpdir= NULL;
00324
00326 const char *in_left_expr_name= "<left expr>";
00328 const char *in_additional_cond= "<IN COND>";
00329 const char *in_having_cond= "<IN HAVING>";
00330
00331 my_decimal decimal_zero;
00332
00333
00334 FILE *stderror_file=0;
00335
00336 struct system_variables global_system_variables;
00337 struct system_variables max_system_variables;
00338 struct system_status_var global_status_var;
00339
00340 const CHARSET_INFO *system_charset_info, *files_charset_info ;
00341 const CHARSET_INFO *table_alias_charset;
00342 const CHARSET_INFO *character_set_filesystem;
00343
00344 MY_LOCALE *my_default_lc_time_names;
00345
00346 SHOW_COMP_OPTION have_symlink;
00347
00348
00349
00350 pthread_key_t THR_Mem_root;
00351 pthread_key_t THR_Session;
00352 pthread_mutex_t LOCK_create_db;
00353 pthread_mutex_t LOCK_open;
00354 pthread_mutex_t LOCK_thread_count;
00355 pthread_mutex_t LOCK_status;
00356 pthread_mutex_t LOCK_global_read_lock;
00357 pthread_mutex_t LOCK_global_system_variables;
00358
00359 pthread_rwlock_t LOCK_system_variables_hash;
00360 pthread_cond_t COND_refresh, COND_thread_count, COND_global_read_lock;
00361 pthread_t signal_thread;
00362 pthread_cond_t COND_server_end;
00363
00364
00365
00366 static bool segfaulted;
00367 #ifdef HAVE_STACK_TRACE_ON_SEGV
00368 static bool opt_do_pstack;
00369 #endif
00370 int cleanup_done;
00371 static char *drizzle_home_ptr, *pidfile_name_ptr;
00372 static int defaults_argc;
00373 static char **defaults_argv;
00374
00375 struct passwd *user_info;
00376 static pthread_t select_thread;
00377 static uint32_t thr_kill_signal;
00378
00383 drizzled::atomic<uint32_t> connection_count;
00384
00388 uint64_t refresh_version;
00389
00390
00391 bool drizzle_rm_tmp_tables();
00392
00393 extern "C" pthread_handler_t signal_hand(void *arg);
00394 static void drizzle_init_variables(void);
00395 static void get_options(int *argc,char **argv);
00396 extern "C" bool drizzled_get_one_option(int, const struct my_option *, char *);
00397 static int init_thread_environment();
00398 static const char *get_relative_path(const char *path);
00399 static void fix_paths(string &progname);
00400 extern "C" pthread_handler_t handle_slave(void *arg);
00401 static void clean_up(bool print_message);
00402
00403 static void usage(void);
00404 static void clean_up_mutexes(void);
00405 void close_connections(void);
00406
00407
00408
00409
00410
00411 void close_connections(void)
00412 {
00413
00414 plugin::Listen::shutdown();
00415
00416
00417 (void) pthread_mutex_lock(&LOCK_thread_count);
00418
00419 while (select_thread_in_use)
00420 {
00421 struct timespec abstime;
00422 int error;
00423
00424 set_timespec(abstime, 2);
00425 for (uint32_t tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
00426 {
00427 error=pthread_cond_timedwait(&COND_thread_count,&LOCK_thread_count, &abstime);
00428 if (error != EINTR)
00429 break;
00430 }
00431 }
00432 (void) pthread_mutex_unlock(&LOCK_thread_count);
00433
00434
00435
00436
00437
00438
00439
00440
00441 Session *tmp;
00442
00443 (void) pthread_mutex_lock(&LOCK_thread_count);
00444
00445 for( vector<Session*>::iterator it= getSessionList().begin(); it != getSessionList().end(); ++it )
00446 {
00447 tmp= *it;
00448 tmp->killed= Session::KILL_CONNECTION;
00449 tmp->scheduler->killSession(tmp);
00450 DRIZZLE_CONNECTION_DONE(tmp->thread_id);
00451 if (tmp->mysys_var)
00452 {
00453 tmp->mysys_var->abort=1;
00454 pthread_mutex_lock(&tmp->mysys_var->mutex);
00455 if (tmp->mysys_var->current_cond)
00456 {
00457 pthread_mutex_lock(tmp->mysys_var->current_mutex);
00458 pthread_cond_broadcast(tmp->mysys_var->current_cond);
00459 pthread_mutex_unlock(tmp->mysys_var->current_mutex);
00460 }
00461 pthread_mutex_unlock(&tmp->mysys_var->mutex);
00462 }
00463 }
00464 (void) pthread_mutex_unlock(&LOCK_thread_count);
00465
00466 if (connection_count)
00467 sleep(2);
00468
00469
00470
00471
00472
00473
00474 for (;;)
00475 {
00476 (void) pthread_mutex_lock(&LOCK_thread_count);
00477 if (getSessionList().empty())
00478 {
00479 (void) pthread_mutex_unlock(&LOCK_thread_count);
00480 break;
00481 }
00482 tmp= getSessionList().front();
00483
00484 tmp->client->close();
00485 (void) pthread_mutex_unlock(&LOCK_thread_count);
00486 }
00487 }
00488
00489 extern "C" void print_signal_warning(int sig);
00490
00491 extern "C" void print_signal_warning(int sig)
00492 {
00493 if (global_system_variables.log_warnings)
00494 errmsg_printf(ERRMSG_LVL_WARN, _("Got signal %d from thread %"PRIu64),
00495 sig, global_thread_id);
00496 #ifndef HAVE_BSD_SIGNALS
00497 my_sigset(sig,print_signal_warning);
00498 #endif
00499 if (sig == SIGALRM)
00500 alarm(2);
00501 }
00502
00513 void unireg_end(void)
00514 {
00515 clean_up(1);
00516 my_thread_end();
00517 #if defined(SIGNALS_DONT_BREAK_READ)
00518 exit(0);
00519 #else
00520 pthread_exit(0);
00521 #endif
00522 }
00523
00524
00525 void unireg_abort(int exit_code)
00526 {
00527
00528 if (exit_code)
00529 errmsg_printf(ERRMSG_LVL_ERROR, _("Aborting\n"));
00530 else if (opt_help || opt_help_extended)
00531 usage();
00532 clean_up(!opt_help && (exit_code));
00533 clean_up_mutexes();
00534 my_end();
00535 exit(exit_code);
00536 }
00537
00538
00539 static void clean_up(bool print_message)
00540 {
00541 if (cleanup_done++)
00542 return;
00543
00544 table_cache_free();
00545 TableShare::cacheStop();
00546 set_var_free();
00547 free_charsets();
00548 ha_end();
00549 plugin::Registry &plugins= plugin::Registry::singleton();
00550 plugin_shutdown(plugins);
00551 xid_cache_free();
00552 free_status_vars();
00553 if (defaults_argv)
00554 free_defaults(defaults_argv);
00555 free(drizzle_tmpdir);
00556 if (opt_secure_file_priv)
00557 free(opt_secure_file_priv);
00558
00559 deinit_temporal_formats();
00560
00561 #if GOOGLE_PROTOBUF_VERSION >= 2001000
00562 google::protobuf::ShutdownProtobufLibrary();
00563 #endif
00564
00565 (void) unlink(pidfile_name);
00566
00567 if (print_message && server_start_time)
00568 errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_SHUTDOWN_COMPLETE)),my_progname);
00569
00570
00571 (void *)my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST);
00572
00573
00574
00575 (void) pthread_mutex_lock(&LOCK_thread_count);
00576 ready_to_exit=1;
00577
00578 (void) pthread_cond_broadcast(&COND_server_end);
00579 (void) pthread_mutex_unlock(&LOCK_thread_count);
00580
00581
00582
00583
00584
00585 }
00586
00587
00588 static void clean_up_mutexes()
00589 {
00590 (void) pthread_mutex_destroy(&LOCK_create_db);
00591 (void) pthread_mutex_destroy(&LOCK_open);
00592 (void) pthread_mutex_destroy(&LOCK_thread_count);
00593 (void) pthread_mutex_destroy(&LOCK_status);
00594 (void) pthread_mutex_destroy(&LOCK_global_system_variables);
00595 (void) pthread_rwlock_destroy(&LOCK_system_variables_hash);
00596 (void) pthread_mutex_destroy(&LOCK_global_read_lock);
00597 (void) pthread_cond_destroy(&COND_thread_count);
00598 (void) pthread_cond_destroy(&COND_server_end);
00599 (void) pthread_cond_destroy(&COND_refresh);
00600 (void) pthread_cond_destroy(&COND_global_read_lock);
00601 }
00602
00603
00604
00605
00606 static struct passwd *check_user(const char *user)
00607 {
00608 struct passwd *tmp_user_info;
00609 uid_t user_id= geteuid();
00610
00611
00612 if (user_id)
00613 {
00614 if (user)
00615 {
00616
00617 tmp_user_info= getpwnam(user);
00618 if ((!tmp_user_info || user_id != tmp_user_info->pw_uid) &&
00619 global_system_variables.log_warnings)
00620 errmsg_printf(ERRMSG_LVL_WARN, _("One can only use the --user switch "
00621 "if running as root\n"));
00622 }
00623 return NULL;
00624 }
00625 if (!user)
00626 {
00627 errmsg_printf(ERRMSG_LVL_ERROR, _("Fatal error: Please read \"Security\" section of "
00628 "the manual to find out how to run drizzled as root!\n"));
00629 unireg_abort(1);
00630 }
00631 if (!strcmp(user,"root"))
00632 return NULL;
00633
00634 if (!(tmp_user_info= getpwnam(user)))
00635 {
00636
00637 const char *pos;
00638 for (pos= user; my_isdigit(mysqld_charset,*pos); pos++) ;
00639 if (*pos)
00640 goto err;
00641 if (!(tmp_user_info= getpwuid(atoi(user))))
00642 goto err;
00643 }
00644 return tmp_user_info;
00645
00646 err:
00647 errmsg_printf(ERRMSG_LVL_ERROR, _("Fatal error: Can't change to run as user '%s' ; "
00648 "Please check that the user exists!\n"),user);
00649 unireg_abort(1);
00650
00651 #ifdef PR_SET_DUMPABLE
00652 if (test_flags.test(TEST_CORE_ON_SIGNAL))
00653 {
00654
00655 (void) prctl(PR_SET_DUMPABLE, 1);
00656 }
00657 #endif
00658
00659
00660 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x590)
00661 return NULL;
00662 #endif
00663
00664 }
00665
00666 static void set_user(const char *user, struct passwd *user_info_arg)
00667 {
00668 assert(user_info_arg != 0);
00669
00670
00671
00672
00673
00674
00675 calling_initgroups= true;
00676 initgroups((char*) user, user_info_arg->pw_gid);
00677 calling_initgroups= false;
00678 if (setgid(user_info_arg->pw_gid) == -1)
00679 {
00680 sql_perror("setgid");
00681 unireg_abort(1);
00682 }
00683 if (setuid(user_info_arg->pw_uid) == -1)
00684 {
00685 sql_perror("setuid");
00686 unireg_abort(1);
00687 }
00688 }
00689
00690
00691 static void set_effective_user(struct passwd *user_info_arg)
00692 {
00693 assert(user_info_arg != 0);
00694 if (setregid((gid_t)-1, user_info_arg->pw_gid) == -1)
00695 {
00696 sql_perror("setregid");
00697 unireg_abort(1);
00698 }
00699 if (setreuid((uid_t)-1, user_info_arg->pw_uid) == -1)
00700 {
00701 sql_perror("setreuid");
00702 unireg_abort(1);
00703 }
00704 }
00705
00706
00708 static void set_root(const char *path)
00709 {
00710 if ((chroot(path) == -1) || !chdir("/"))
00711 {
00712 sql_perror("chroot");
00713 unireg_abort(1);
00714 }
00715 }
00716
00717 extern "C" void end_thread_signal(int );
00718
00720 extern "C" void end_thread_signal(int )
00721 {
00722 Session *session=current_session;
00723 if (session)
00724 {
00725 statistic_increment(killed_threads, &LOCK_status);
00726 session->scheduler->killSessionNow(session);
00727 DRIZZLE_CONNECTION_DONE(session->thread_id);
00728 }
00729 return;
00730 }
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744 void Session::unlink(Session *session)
00745 {
00746 connection_count.decrement();
00747
00748 session->cleanup();
00749
00750 (void) pthread_mutex_lock(&LOCK_thread_count);
00751 pthread_mutex_lock(&session->LOCK_delete);
00752
00753 getSessionList().erase(remove(getSessionList().begin(),
00754 getSessionList().end(),
00755 session));
00756
00757 delete session;
00758 (void) pthread_mutex_unlock(&LOCK_thread_count);
00759
00760 return;
00761 }
00762
00763
00764 #ifdef THREAD_SPECIFIC_SIGPIPE
00765
00770 extern "C" void abort_thread(int )
00771 {
00772 Session *session=current_session;
00773 if (session)
00774 session->killed= Session::KILL_CONNECTION;
00775 return;;
00776 }
00777 #endif
00778
00779 #if defined(BACKTRACE_DEMANGLE)
00780 #include <cxxabi.h>
00781 extern "C" char *my_demangle(const char *mangled_name, int *status)
00782 {
00783 return abi::__cxa_demangle(mangled_name, NULL, NULL, status);
00784 }
00785 #endif
00786
00787 extern "C" void handle_segfault(int sig);
00788
00789 extern "C" void handle_segfault(int sig)
00790 {
00791 time_t curr_time;
00792 struct tm tm;
00793
00794
00795
00796
00797
00798
00799
00800 if (segfaulted)
00801 {
00802 fprintf(stderr, _("Fatal signal %d while backtracing\n"), sig);
00803 exit(1);
00804 }
00805
00806 segfaulted = 1;
00807
00808 curr_time= time(NULL);
00809 if(curr_time == (time_t)-1)
00810 {
00811 fprintf(stderr, "Fetal: time() call failed\n");
00812 exit(1);
00813 }
00814
00815 localtime_r(&curr_time, &tm);
00816
00817 fprintf(stderr,"%02d%02d%02d %2d:%02d:%02d - drizzled got signal %d;\n"
00818 "This could be because you hit a bug. It is also possible that "
00819 "this binary\n or one of the libraries it was linked against is "
00820 "corrupt, improperly built,\n or misconfigured. This error can "
00821 "also be caused by malfunctioning hardware.\n",
00822 tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday,
00823 tm.tm_hour, tm.tm_min, tm.tm_sec,
00824 sig);
00825 fprintf(stderr, _("We will try our best to scrape up some info that "
00826 "will hopefully help diagnose\n"
00827 "the problem, but since we have already crashed, "
00828 "something is definitely wrong\nand this may fail.\n\n"));
00829 fprintf(stderr, "key_buffer_size=%u\n",
00830 (uint32_t) dflt_key_cache->key_cache_mem_size);
00831 fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
00832 fprintf(stderr, "max_used_connections=%u\n", max_used_connections);
00833 fprintf(stderr, "connection_count=%u\n", uint32_t(connection_count));
00834 fprintf(stderr, _("It is possible that drizzled could use up to \n"
00835 "key_buffer_size + (read_buffer_size + "
00836 "sort_buffer_size)*thread_count\n"
00837 "bytes of memory\n"
00838 "Hope that's ok; if not, decrease some variables in the "
00839 "equation.\n\n"));
00840
00841 #ifdef HAVE_STACKTRACE
00842 Session *session= current_session;
00843
00844 if (! (test_flags.test(TEST_NO_STACKTRACE)))
00845 {
00846 fprintf(stderr,"session: 0x%lx\n",(long) session);
00847 fprintf(stderr,_("Attempting backtrace. You can use the following "
00848 "information to find out\n"
00849 "where drizzled died. If you see no messages after this, "
00850 "something went\n"
00851 "terribly wrong...\n"));
00852 print_stacktrace(session ? (unsigned char*) session->thread_stack : (unsigned char*) 0,
00853 my_thread_stack_size);
00854 }
00855 if (session)
00856 {
00857 const char *kreason= "UNKNOWN";
00858 switch (session->killed) {
00859 case Session::NOT_KILLED:
00860 kreason= "NOT_KILLED";
00861 break;
00862 case Session::KILL_BAD_DATA:
00863 kreason= "KILL_BAD_DATA";
00864 break;
00865 case Session::KILL_CONNECTION:
00866 kreason= "KILL_CONNECTION";
00867 break;
00868 case Session::KILL_QUERY:
00869 kreason= "KILL_QUERY";
00870 break;
00871 case Session::KILLED_NO_VALUE:
00872 kreason= "KILLED_NO_VALUE";
00873 break;
00874 }
00875 fprintf(stderr, _("Trying to get some variables.\n"
00876 "Some pointers may be invalid and cause the "
00877 "dump to abort...\n"));
00878 safe_print_str("session->query", session->query, 1024);
00879 fprintf(stderr, "session->thread_id=%"PRIu32"\n", (uint32_t) session->thread_id);
00880 fprintf(stderr, "session->killed=%s\n", kreason);
00881 }
00882 fflush(stderr);
00883 #endif
00884
00885 if (calling_initgroups)
00886 fprintf(stderr, _("\nThis crash occurred while the server was calling "
00887 "initgroups(). This is\n"
00888 "often due to the use of a drizzled that is statically "
00889 "linked against glibc\n"
00890 "and configured to use LDAP in /etc/nsswitch.conf. "
00891 "You will need to either\n"
00892 "upgrade to a version of glibc that does not have this "
00893 "problem (2.3.4 or\n"
00894 "later when used with nscd), disable LDAP in your "
00895 "nsswitch.conf, or use a\n"
00896 "drizzled that is not statically linked.\n"));
00897
00898 if (thd_lib_detected == THD_LIB_LT && !getenv("LD_ASSUME_KERNEL"))
00899 fprintf(stderr,
00900 _("\nYou are running a statically-linked LinuxThreads binary "
00901 "on an NPTL system.\n"
00902 "This can result in crashes on some distributions due "
00903 "to LT/NPTL conflicts.\n"
00904 "You should either build a dynamically-linked binary, or force "
00905 "LinuxThreads\n"
00906 "to be used with the LD_ASSUME_KERNEL environment variable. "
00907 "Please consult\n"
00908 "the documentation for your distribution on how to do that.\n"));
00909
00910 if (locked_in_memory)
00911 {
00912 fprintf(stderr,
00913 _("\nThe '--memlock' argument, which was enabled, uses system "
00914 "calls that are\n"
00915 "unreliable and unstable on some operating systems and "
00916 "operating-system\n"
00917 "versions (notably, some versions of Linux). "
00918 "This crash could be due to use\n"
00919 "of those buggy OS calls. You should consider whether you "
00920 "really need the\n"
00921 "'--memlock' parameter and/or consult the OS "
00922 "distributor about 'mlockall'\n bugs.\n"));
00923 }
00924
00925 #ifdef HAVE_WRITE_CORE
00926 if (test_flags.test(TEST_CORE_ON_SIGNAL))
00927 {
00928 fprintf(stderr, _("Writing a core file\n"));
00929 fflush(stderr);
00930 write_core(sig);
00931 }
00932 #endif
00933
00934 exit(1);
00935 }
00936
00937 #ifndef SA_RESETHAND
00938 #define SA_RESETHAND 0
00939 #endif
00940 #ifndef SA_NODEFER
00941 #define SA_NODEFER 0
00942 #endif
00943
00944 static void init_signals(void)
00945 {
00946 sigset_t set;
00947 struct sigaction sa;
00948
00949 if (!(test_flags.test(TEST_NO_STACKTRACE) ||
00950 test_flags.test(TEST_CORE_ON_SIGNAL)))
00951 {
00952 sa.sa_flags = SA_RESETHAND | SA_NODEFER;
00953 sigemptyset(&sa.sa_mask);
00954 sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
00955
00956 init_stacktrace();
00957 sa.sa_handler=handle_segfault;
00958 sigaction(SIGSEGV, &sa, NULL);
00959 sigaction(SIGABRT, &sa, NULL);
00960 #ifdef SIGBUS
00961 sigaction(SIGBUS, &sa, NULL);
00962 #endif
00963 sigaction(SIGILL, &sa, NULL);
00964 sigaction(SIGFPE, &sa, NULL);
00965 }
00966
00967 if (test_flags.test(TEST_CORE_ON_SIGNAL))
00968 {
00969
00970 struct rlimit rl;
00971 rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
00972 if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
00973 errmsg_printf(ERRMSG_LVL_WARN,
00974 _("setrlimit could not change the size of core files "
00975 "to 'infinity'; We may not be able to generate a "
00976 "core file on signals"));
00977 }
00978 (void) sigemptyset(&set);
00979 my_sigset(SIGPIPE,SIG_IGN);
00980 sigaddset(&set,SIGPIPE);
00981 #ifndef IGNORE_SIGHUP_SIGQUIT
00982 sigaddset(&set,SIGQUIT);
00983 sigaddset(&set,SIGHUP);
00984 #endif
00985 sigaddset(&set,SIGTERM);
00986
00987
00988 sigemptyset(&sa.sa_mask);
00989 sa.sa_flags = 0;
00990 sa.sa_handler = print_signal_warning;
00991 sigaction(SIGTERM, &sa, (struct sigaction*) 0);
00992 sa.sa_flags = 0;
00993 sa.sa_handler = print_signal_warning;
00994 sigaction(SIGHUP, &sa, (struct sigaction*) 0);
00995 #ifdef SIGTSTP
00996 sigaddset(&set,SIGTSTP);
00997 #endif
00998 if (test_flags.test(TEST_SIGINT))
00999 {
01000 my_sigset(thr_kill_signal, end_thread_signal);
01001
01002 sigdelset(&set, thr_kill_signal);
01003 }
01004 else
01005 sigaddset(&set,SIGINT);
01006 sigprocmask(SIG_SETMASK,&set,NULL);
01007 pthread_sigmask(SIG_SETMASK,&set,NULL);
01008 return;;
01009 }
01010
01011 void my_message_sql(uint32_t error, const char *str, myf MyFlags);
01012
01017 void my_message_sql(uint32_t error, const char *str, myf MyFlags)
01018 {
01019 Session *session;
01020
01021
01022
01023
01024 if ((session= current_session))
01025 {
01026 if (MyFlags & ME_FATALERROR)
01027 session->is_fatal_error= 1;
01028
01029
01030
01031
01032
01033 if (session->handle_error(error, str,
01034 DRIZZLE_ERROR::WARN_LEVEL_ERROR))
01035 return;;
01036
01037
01038
01039
01040
01041 if (! (session->lex->current_select &&
01042 session->lex->current_select->no_error && !session->is_fatal_error))
01043 {
01044 if (! session->main_da.is_error())
01045 {
01046 if (error == 0)
01047 error= ER_UNKNOWN_ERROR;
01048 if (str == NULL)
01049 str= ER(error);
01050 session->main_da.set_error_status(error, str);
01051 }
01052 }
01053
01054 if (!session->no_warnings_for_error && !session->is_fatal_error)
01055 {
01056
01057
01058
01059
01060 session->no_warnings_for_error= true;
01061 push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error, str);
01062 session->no_warnings_for_error= false;
01063 }
01064 }
01065 if (!session || MyFlags & ME_NOREFRESH)
01066 errmsg_printf(ERRMSG_LVL_ERROR, "%s: %s",my_progname,str);
01067 }
01068
01069
01070 static const char *load_default_groups[]= {
01071 DRIZZLE_CONFIG_NAME, "server", 0, 0};
01072
01073 static int show_starttime(SHOW_VAR *var, char *buff)
01074 {
01075 var->type= SHOW_LONG;
01076 var->value= buff;
01077 *((long *)buff)= (long) (time(NULL) - server_start_time);
01078 return 0;
01079 }
01080
01081 static int show_flushstatustime(SHOW_VAR *var, char *buff)
01082 {
01083 var->type= SHOW_LONG;
01084 var->value= buff;
01085 *((long *)buff)= (long) (time(NULL) - flush_status_time);
01086 return 0;
01087 }
01088
01089 static int show_open_tables(SHOW_VAR *var, char *buff)
01090 {
01091 var->type= SHOW_LONG;
01092 var->value= buff;
01093 *((long *)buff)= (long)cached_open_tables();
01094 return 0;
01095 }
01096
01097 static int show_table_definitions(SHOW_VAR *var, char *buff)
01098 {
01099 var->type= SHOW_LONG;
01100 var->value= buff;
01101 *((long *)buff)= (long)cached_table_definitions();
01102 return 0;
01103 }
01104
01105 static st_show_var_func_container
01106 show_open_tables_cont= { &show_open_tables };
01107 static st_show_var_func_container
01108 show_table_definitions_cont= { &show_table_definitions };
01109 static st_show_var_func_container
01110 show_starttime_cont= { &show_starttime };
01111 static st_show_var_func_container
01112 show_flushstatustime_cont= { &show_flushstatustime };
01113
01114
01115
01116
01117 static SHOW_VAR com_status_vars[]= {
01118 {"admin_commands", (char*) offsetof(STATUS_VAR, com_other), SHOW_LONG_STATUS},
01119 {"alter_db", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ALTER_DB]), SHOW_LONG_STATUS},
01120 {"alter_table", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ALTER_TABLE]), SHOW_LONG_STATUS},
01121 {"analyze", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ANALYZE]), SHOW_LONG_STATUS},
01122 {"begin", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_BEGIN]), SHOW_LONG_STATUS},
01123 {"change_db", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_CHANGE_DB]), SHOW_LONG_STATUS},
01124 {"check", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_CHECK]), SHOW_LONG_STATUS},
01125 {"checksum", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_CHECKSUM]), SHOW_LONG_STATUS},
01126 {"commit", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_COMMIT]), SHOW_LONG_STATUS},
01127 {"create_db", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_CREATE_DB]), SHOW_LONG_STATUS},
01128 {"create_index", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_CREATE_INDEX]), SHOW_LONG_STATUS},
01129 {"create_table", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_CREATE_TABLE]), SHOW_LONG_STATUS},
01130 {"delete", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_DELETE]), SHOW_LONG_STATUS},
01131 {"drop_db", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_DROP_DB]), SHOW_LONG_STATUS},
01132 {"drop_index", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_DROP_INDEX]), SHOW_LONG_STATUS},
01133 {"drop_table", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_DROP_TABLE]), SHOW_LONG_STATUS},
01134 {"empty_query", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_EMPTY_QUERY]), SHOW_LONG_STATUS},
01135 {"flush", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_FLUSH]), SHOW_LONG_STATUS},
01136 {"insert", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_INSERT]), SHOW_LONG_STATUS},
01137 {"insert_select", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_INSERT_SELECT]), SHOW_LONG_STATUS},
01138 {"kill", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_KILL]), SHOW_LONG_STATUS},
01139 {"load", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_LOAD]), SHOW_LONG_STATUS},
01140 {"release_savepoint", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_RELEASE_SAVEPOINT]), SHOW_LONG_STATUS},
01141 {"rename_table", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_RENAME_TABLE]), SHOW_LONG_STATUS},
01142 {"replace", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_REPLACE]), SHOW_LONG_STATUS},
01143 {"replace_select", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_REPLACE_SELECT]), SHOW_LONG_STATUS},
01144 {"rollback", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ROLLBACK]), SHOW_LONG_STATUS},
01145 {"rollback_to_savepoint",(char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ROLLBACK_TO_SAVEPOINT]), SHOW_LONG_STATUS},
01146 {"savepoint", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SAVEPOINT]), SHOW_LONG_STATUS},
01147 {"select", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SELECT]), SHOW_LONG_STATUS},
01148 {"set_option", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SET_OPTION]), SHOW_LONG_STATUS},
01149 {"show_create_db", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_CREATE_DB]), SHOW_LONG_STATUS},
01150 {"show_create_table", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_CREATE]), SHOW_LONG_STATUS},
01151 {"show_databases", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_DATABASES]), SHOW_LONG_STATUS},
01152 {"show_engine_status", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_ENGINE_STATUS]), SHOW_LONG_STATUS},
01153 {"show_errors", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_ERRORS]), SHOW_LONG_STATUS},
01154 {"show_fields", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_FIELDS]), SHOW_LONG_STATUS},
01155 {"show_keys", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_KEYS]), SHOW_LONG_STATUS},
01156 {"show_open_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_OPEN_TABLES]), SHOW_LONG_STATUS},
01157 {"show_processlist", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_PROCESSLIST]), SHOW_LONG_STATUS},
01158 {"show_status", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS},
01159 {"show_table_status", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS},
01160 {"show_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_TABLES]), SHOW_LONG_STATUS},
01161 {"show_variables", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS},
01162 {"show_warnings", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
01163 {"truncate", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_TRUNCATE]), SHOW_LONG_STATUS},
01164 {"unlock_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_UNLOCK_TABLES]), SHOW_LONG_STATUS},
01165 {"update", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_UPDATE]), SHOW_LONG_STATUS},
01166 {NULL, NULL, SHOW_LONGLONG}
01167 };
01168
01169 static SHOW_VAR status_vars[]= {
01170 {"Aborted_clients", (char*) &aborted_threads, SHOW_LONGLONG},
01171 {"Aborted_connects", (char*) &aborted_connects, SHOW_LONGLONG},
01172 {"Bytes_received", (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONGLONG_STATUS},
01173 {"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS},
01174 {"Com", (char*) com_status_vars, SHOW_ARRAY},
01175 {"Connections", (char*) &global_thread_id, SHOW_INT_NOFLUSH},
01176 {"Created_tmp_disk_tables", (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS},
01177 {"Created_tmp_files", (char*) &my_tmp_file_created,SHOW_INT},
01178 {"Created_tmp_tables", (char*) offsetof(STATUS_VAR, created_tmp_tables), SHOW_LONG_STATUS},
01179 {"Flush_commands", (char*) &refresh_version, SHOW_INT_NOFLUSH},
01180 {"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
01181 {"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS},
01182 {"Handler_prepare", (char*) offsetof(STATUS_VAR, ha_prepare_count), SHOW_LONG_STATUS},
01183 {"Handler_read_first", (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS},
01184 {"Handler_read_key", (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS},
01185 {"Handler_read_next", (char*) offsetof(STATUS_VAR, ha_read_next_count), SHOW_LONG_STATUS},
01186 {"Handler_read_prev", (char*) offsetof(STATUS_VAR, ha_read_prev_count), SHOW_LONG_STATUS},
01187 {"Handler_read_rnd", (char*) offsetof(STATUS_VAR, ha_read_rnd_count), SHOW_LONG_STATUS},
01188 {"Handler_read_rnd_next", (char*) offsetof(STATUS_VAR, ha_read_rnd_next_count), SHOW_LONG_STATUS},
01189 {"Handler_rollback", (char*) offsetof(STATUS_VAR, ha_rollback_count), SHOW_LONG_STATUS},
01190 {"Handler_savepoint", (char*) offsetof(STATUS_VAR, ha_savepoint_count), SHOW_LONG_STATUS},
01191 {"Handler_savepoint_rollback",(char*) offsetof(STATUS_VAR, ha_savepoint_rollback_count), SHOW_LONG_STATUS},
01192 {"Handler_update", (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS},
01193 {"Handler_write", (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS},
01194 {"Key_blocks_not_flushed", (char*) offsetof(KEY_CACHE, global_blocks_changed), SHOW_KEY_CACHE_LONG},
01195 {"Key_blocks_unused", (char*) offsetof(KEY_CACHE, blocks_unused), SHOW_KEY_CACHE_LONG},
01196 {"Key_blocks_used", (char*) offsetof(KEY_CACHE, blocks_used), SHOW_KEY_CACHE_LONG},
01197 {"Key_read_requests", (char*) offsetof(KEY_CACHE, global_cache_r_requests), SHOW_KEY_CACHE_LONGLONG},
01198 {"Key_reads", (char*) offsetof(KEY_CACHE, global_cache_read), SHOW_KEY_CACHE_LONGLONG},
01199 {"Key_write_requests", (char*) offsetof(KEY_CACHE, global_cache_w_requests), SHOW_KEY_CACHE_LONGLONG},
01200 {"Key_writes", (char*) offsetof(KEY_CACHE, global_cache_write), SHOW_KEY_CACHE_LONGLONG},
01201 {"Last_query_cost", (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS},
01202 {"Max_used_connections", (char*) &max_used_connections, SHOW_INT},
01203 {"Open_files", (char*) &my_file_opened, SHOW_INT_NOFLUSH},
01204 {"Open_streams", (char*) &my_stream_opened, SHOW_INT_NOFLUSH},
01205 {"Open_table_definitions", (char*) &show_table_definitions_cont, SHOW_FUNC},
01206 {"Open_tables", (char*) &show_open_tables_cont, SHOW_FUNC},
01207 {"Opened_files", (char*) &my_file_total_opened, SHOW_INT_NOFLUSH},
01208 {"Opened_tables", (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS},
01209 {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS},
01210 {"Questions", (char*) offsetof(STATUS_VAR, questions), SHOW_LONG_STATUS},
01211 {"Select_full_join", (char*) offsetof(STATUS_VAR, select_full_join_count), SHOW_LONG_STATUS},
01212 {"Select_full_range_join", (char*) offsetof(STATUS_VAR, select_full_range_join_count), SHOW_LONG_STATUS},
01213 {"Select_range", (char*) offsetof(STATUS_VAR, select_range_count), SHOW_LONG_STATUS},
01214 {"Select_range_check", (char*) offsetof(STATUS_VAR, select_range_check_count), SHOW_LONG_STATUS},
01215 {"Select_scan", (char*) offsetof(STATUS_VAR, select_scan_count), SHOW_LONG_STATUS},
01216 {"Slow_queries", (char*) offsetof(STATUS_VAR, long_query_count), SHOW_LONG_STATUS},
01217 {"Sort_merge_passes", (char*) offsetof(STATUS_VAR, filesort_merge_passes), SHOW_LONG_STATUS},
01218 {"Sort_range", (char*) offsetof(STATUS_VAR, filesort_range_count), SHOW_LONG_STATUS},
01219 {"Sort_rows", (char*) offsetof(STATUS_VAR, filesort_rows), SHOW_LONG_STATUS},
01220 {"Sort_scan", (char*) offsetof(STATUS_VAR, filesort_scan_count), SHOW_LONG_STATUS},
01221 {"Table_locks_immediate", (char*) &locks_immediate, SHOW_INT},
01222 {"Table_locks_waited", (char*) &locks_waited, SHOW_INT},
01223 {"Threads_connected", (char*) &connection_count, SHOW_INT},
01224 {"Uptime", (char*) &show_starttime_cont, SHOW_FUNC},
01225 {"Uptime_since_flush_status",(char*) &show_flushstatustime_cont, SHOW_FUNC},
01226 {NULL, NULL, SHOW_LONGLONG}
01227 };
01228
01229 static int init_common_variables(const char *conf_file_name, int argc,
01230 char **argv, const char **groups)
01231 {
01232 time_t curr_time;
01233 umask(((~my_umask) & 0666));
01234 my_decimal_set_zero(&decimal_zero);
01235 tzset();
01236
01237 curr_time= time(NULL);
01238 if (curr_time == (time_t)-1)
01239 return 1;
01240
01241 max_system_variables.pseudo_thread_id= UINT32_MAX;
01242 server_start_time= flush_status_time= curr_time;
01243
01244 if (init_thread_environment())
01245 return 1;
01246 drizzle_init_variables();
01247
01248 {
01249 struct tm tm_tmp;
01250 localtime_r(&server_start_time,&tm_tmp);
01251 strncpy(system_time_zone, tzname[tm_tmp.tm_isdst != 0 ? 1 : 0],
01252 sizeof(system_time_zone)-1);
01253
01254 }
01255
01256
01257
01258
01259
01260
01261 global_system_variables.time_zone= my_tz_SYSTEM;
01262
01263 if (gethostname(glob_hostname,sizeof(glob_hostname)) < 0)
01264 {
01265 strncpy(glob_hostname, STRING_WITH_LEN("localhost"));
01266 errmsg_printf(ERRMSG_LVL_WARN, _("gethostname failed, using '%s' as hostname"),
01267 glob_hostname);
01268 strncpy(pidfile_name, STRING_WITH_LEN("drizzle"));
01269 }
01270 else
01271 strncpy(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
01272 strcpy(fn_ext(pidfile_name),".pid");
01273
01274
01275
01276
01277
01278
01279 if (add_status_vars(status_vars))
01280 return 1;
01281
01282 load_defaults(conf_file_name, groups, &argc, &argv);
01283 defaults_argv=argv;
01284 defaults_argc=argc;
01285 get_options(&defaults_argc, defaults_argv);
01286
01287 current_pid= getpid();
01288 init_time();
01289
01290 if (init_errmessage())
01291 return 1;
01292 if (item_create_init())
01293 return 1;
01294 if (set_var_init())
01295 return 1;
01296
01297 if (! init_temporal_formats())
01298 return 1;
01299
01300 if (!(default_charset_info=
01301 get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)))
01302 {
01303 return 1;
01304 }
01305
01306 if (default_collation_name)
01307 {
01308 const CHARSET_INFO * const default_collation= get_charset_by_name(default_collation_name);
01309 if (!default_collation)
01310 {
01311 errmsg_printf(ERRMSG_LVL_ERROR, _(ER(ER_UNKNOWN_COLLATION)), default_collation_name);
01312 return 1;
01313 }
01314 if (!my_charset_same(default_charset_info, default_collation))
01315 {
01316 errmsg_printf(ERRMSG_LVL_ERROR, _(ER(ER_COLLATION_CHARSET_MISMATCH)),
01317 default_collation_name,
01318 default_charset_info->csname);
01319 return 1;
01320 }
01321 default_charset_info= default_collation;
01322 }
01323
01324 global_system_variables.collation_server= default_charset_info;
01325
01326 global_system_variables.optimizer_switch= 0;
01327
01328 if (!(character_set_filesystem=
01329 get_charset_by_csname(character_set_filesystem_name, MY_CS_PRIMARY)))
01330 return 1;
01331 global_system_variables.character_set_filesystem= character_set_filesystem;
01332
01333 if (!(my_default_lc_time_names=
01334 my_locale_by_name(lc_time_names_name)))
01335 {
01336 errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown locale: '%s'"), lc_time_names_name);
01337 return 1;
01338 }
01339 global_system_variables.lc_time_names= my_default_lc_time_names;
01340
01341
01342 table_alias_charset= files_charset_info;
01343
01344 return 0;
01345 }
01346
01347
01348 static int init_thread_environment()
01349 {
01350 (void) pthread_mutex_init(&LOCK_create_db, NULL);
01351 (void) pthread_mutex_init(&LOCK_open, NULL);
01352 (void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
01353 (void) pthread_mutex_init(&LOCK_status,MY_MUTEX_INIT_FAST);
01354 (void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
01355 (void) pthread_rwlock_init(&LOCK_system_variables_hash, NULL);
01356 (void) pthread_mutex_init(&LOCK_global_read_lock, MY_MUTEX_INIT_FAST);
01357 (void) pthread_cond_init(&COND_thread_count,NULL);
01358 (void) pthread_cond_init(&COND_server_end,NULL);
01359 (void) pthread_cond_init(&COND_refresh,NULL);
01360 (void) pthread_cond_init(&COND_global_read_lock,NULL);
01361
01362 if (pthread_key_create(&THR_Session,NULL) ||
01363 pthread_key_create(&THR_Mem_root,NULL))
01364 {
01365 errmsg_printf(ERRMSG_LVL_ERROR, _("Can't create thread-keys"));
01366 return 1;
01367 }
01368 return 0;
01369 }
01370
01371
01372 static int init_server_components(plugin::Registry &plugins)
01373 {
01374
01375
01376
01377
01378 if (table_cache_init())
01379 unireg_abort(1);
01380 TableShare::cacheStart();
01381
01382 setup_fpu();
01383 init_thr_lock();
01384
01385
01386
01387 if (xid_cache_init())
01388 {
01389 errmsg_printf(ERRMSG_LVL_ERROR, _("Out of memory"));
01390 unireg_abort(1);
01391 }
01392
01393
01394 if (ha_init_errors())
01395 return(1);
01396
01397 if (plugin_init(plugins, &defaults_argc, defaults_argv,
01398 ((opt_help) ? true : false)))
01399 {
01400 errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize plugins."));
01401 unireg_abort(1);
01402 }
01403
01404 if (opt_help || opt_help_extended)
01405 unireg_abort(0);
01406
01407
01408 if (defaults_argc > 1)
01409 {
01410 int ho_error;
01411 char **tmp_argv= defaults_argv;
01412 struct my_option no_opts[]=
01413 {
01414 {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
01415 };
01416
01417
01418
01419
01420
01421
01422 my_getopt_skip_unknown= 0;
01423
01424 if ((ho_error= handle_options(&defaults_argc, &tmp_argv, no_opts,
01425 drizzled_get_one_option)))
01426 unireg_abort(ho_error);
01427
01428 if (defaults_argc)
01429 {
01430 fprintf(stderr,
01431 _("%s: Too many arguments (first extra is '%s').\n"
01432 "Use --verbose --help to get a list of available options\n"),
01433 my_progname, *tmp_argv);
01434 unireg_abort(1);
01435 }
01436 }
01437
01438 string scheduler_name;
01439 if (opt_scheduler)
01440 {
01441 scheduler_name= opt_scheduler;
01442 }
01443 else
01444 {
01445 scheduler_name= opt_scheduler_default;
01446 }
01447
01448 if (plugin::Scheduler::setPlugin(scheduler_name))
01449 {
01450 errmsg_printf(ERRMSG_LVL_ERROR,
01451 _("No scheduler found, cannot continue!\n"));
01452 unireg_abort(1);
01453 }
01454
01455
01456 if (ha_init())
01457 {
01458 errmsg_printf(ERRMSG_LVL_ERROR, _("Can't init databases"));
01459 unireg_abort(1);
01460 }
01461
01462
01463
01464
01465
01466 const std::string myisam_engine_name("MyISAM");
01467 const std::string heap_engine_name("MEMORY");
01468 myisam_engine= plugin::StorageEngine::findByName(myisam_engine_name);
01469 heap_engine= plugin::StorageEngine::findByName(heap_engine_name);
01470
01471
01472
01473
01474 if (default_storage_engine_str)
01475 {
01476 const std::string name(default_storage_engine_str);
01477 plugin::StorageEngine *engine;
01478
01479 engine= plugin::StorageEngine::findByName(name);
01480 if (engine == NULL)
01481 {
01482 errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown/unsupported table type: %s"),
01483 default_storage_engine_str);
01484 unireg_abort(1);
01485 }
01486 if (!engine->is_enabled())
01487 {
01488 errmsg_printf(ERRMSG_LVL_ERROR, _("Default storage engine (%s) is not available"),
01489 default_storage_engine_str);
01490 unireg_abort(1);
01491
01492 }
01493 else
01494 {
01495
01496
01497
01498
01499 global_system_variables.storage_engine= engine;
01500 }
01501 }
01502
01503 if (plugin::StorageEngine::recover(0))
01504 {
01505 unireg_abort(1);
01506 }
01507
01508 #if defined(MCL_CURRENT)
01509 if (locked_in_memory && !getuid())
01510 {
01511 if (setreuid((uid_t)-1, 0) == -1)
01512 {
01513 sql_perror("setreuid");
01514 unireg_abort(1);
01515 }
01516 if (mlockall(MCL_CURRENT))
01517 {
01518 if (global_system_variables.log_warnings)
01519 errmsg_printf(ERRMSG_LVL_WARN, _("Failed to lock memory. Errno: %d\n"),errno);
01520 locked_in_memory= 0;
01521 }
01522 if (user_info)
01523 set_user(drizzled_user, user_info);
01524 }
01525 else
01526 #endif
01527 locked_in_memory=0;
01528
01529 init_update_queries();
01530 return(0);
01531 }
01532
01533
01534 int main(int argc, char **argv)
01535 {
01536 #if defined(ENABLE_NLS)
01537 # if defined(HAVE_LOCALE_H)
01538 setlocale(LC_ALL, "");
01539 # endif
01540 bindtextdomain("drizzle", LOCALEDIR);
01541 textdomain("drizzle");
01542 #endif
01543
01544 plugin::Registry &plugins= plugin::Registry::singleton();
01545 plugin::Client *client;
01546 Session *session;
01547
01548 MY_INIT(argv[0]);
01549
01550
01551
01552 #if defined(SIGUSR2)
01553 thr_kill_signal= thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2;
01554 #else
01555 thr_kill_signal= SIGINT;
01556 #endif
01557
01558 if (init_common_variables(DRIZZLE_CONFIG_NAME,
01559 argc, argv, load_default_groups))
01560 unireg_abort(1);
01561
01562 init_signals();
01563
01564
01565 select_thread=pthread_self();
01566 select_thread_in_use=1;
01567
01568 if (chdir(drizzle_real_data_home) && !opt_help)
01569 {
01570 errmsg_printf(ERRMSG_LVL_ERROR, _("Data directory %s does not exist\n"), drizzle_real_data_home);
01571 unireg_abort(1);
01572 }
01573 drizzle_data_home= drizzle_data_home_buff;
01574 drizzle_data_home[0]=FN_CURLIB;
01575 drizzle_data_home[1]=0;
01576 drizzle_data_home_len= 2;
01577
01578 if ((user_info= check_user(drizzled_user)))
01579 {
01580 #if defined(MCL_CURRENT)
01581 if (locked_in_memory)
01582 set_effective_user(user_info);
01583 else
01584 #endif
01585 set_user(drizzled_user, user_info);
01586 }
01587
01588 if (server_id == 0)
01589 {
01590 server_id= 1;
01591 }
01592
01593 if (init_server_components(plugins))
01594 unireg_abort(1);
01595
01596 if (plugin::Listen::setup())
01597 unireg_abort(1);
01598
01599
01600
01601
01602
01603 error_handler_hook= my_message_sql;
01604
01605 if (drizzle_rm_tmp_tables() ||
01606 my_tz_init((Session *)0, default_tz_name))
01607 {
01608 abort_loop= true;
01609 select_thread_in_use=0;
01610 (void) pthread_kill(signal_thread, SIGTERM);
01611
01612 (void) unlink(pidfile_name);
01613
01614 exit(1);
01615 }
01616
01617 init_status_vars();
01618
01619 errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)), my_progname,
01620 PANDORA_RELEASE_VERSION, COMPILATION_COMMENT);
01621
01622
01623
01624
01625
01626 while ((client= plugin::Listen::getClient()) != NULL)
01627 {
01628 if (!(session= new Session(client)))
01629 {
01630 delete client;
01631 continue;
01632 }
01633
01634
01635 if (session->schedule())
01636 Session::unlink(session);
01637 }
01638
01639
01640
01641
01642 (void) pthread_mutex_lock(&LOCK_thread_count);
01643 select_thread_in_use=0;
01644 (void) pthread_mutex_unlock(&LOCK_thread_count);
01645 (void) pthread_cond_broadcast(&COND_thread_count);
01646
01647
01648 (void) pthread_mutex_lock(&LOCK_thread_count);
01649 while (!ready_to_exit)
01650 pthread_cond_wait(&COND_server_end,&LOCK_thread_count);
01651 (void) pthread_mutex_unlock(&LOCK_thread_count);
01652
01653 clean_up(1);
01654 plugin::Registry::shutdown();
01655 clean_up_mutexes();
01656 my_end();
01657 return 0;
01658 }
01659
01660
01661
01662
01663
01664
01665 enum options_drizzled
01666 {
01667 OPT_SOCKET=256,
01668 OPT_BIND_ADDRESS,
01669 OPT_PID_FILE,
01670 OPT_STORAGE_ENGINE,
01671 OPT_INIT_FILE,
01672 OPT_WANT_CORE,
01673 OPT_MEMLOCK,
01674 OPT_SERVER_ID,
01675 OPT_TC_HEURISTIC_RECOVER,
01676 OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE,
01677 OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
01678 OPT_DO_PSTACK,
01679 OPT_LOCAL_INFILE,
01680 OPT_BACK_LOG,
01681 OPT_JOIN_BUFF_SIZE,
01682 OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_BLOCK_SIZE,
01683 OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_AGE_THRESHOLD,
01684 OPT_MAX_ALLOWED_PACKET,
01685 OPT_MAX_CONNECT_ERRORS,
01686 OPT_MAX_HEP_TABLE_SIZE,
01687 OPT_MAX_JOIN_SIZE,
01688 OPT_MAX_SORT_LENGTH,
01689 OPT_MAX_SEEKS_FOR_KEY, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS,
01690 OPT_MAX_LENGTH_FOR_SORT_DATA,
01691 OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE,
01692 OPT_MAX_ERROR_COUNT, OPT_MULTI_RANGE_COUNT, OPT_MYISAM_DATA_POINTER_SIZE,
01693 OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
01694 OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
01695 OPT_MYISAM_USE_MMAP, OPT_MYISAM_REPAIR_THREADS,
01696 OPT_NET_BUFFER_LENGTH,
01697 OPT_PRELOAD_BUFFER_SIZE,
01698 OPT_RECORD_BUFFER,
01699 OPT_RECORD_RND_BUFFER, OPT_DIV_PRECINCREMENT,
01700 OPT_DEBUGGING,
01701 OPT_SORT_BUFFER, OPT_TABLE_OPEN_CACHE, OPT_TABLE_DEF_CACHE,
01702 OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK,
01703 OPT_WAIT_TIMEOUT,
01704 OPT_RANGE_ALLOC_BLOCK_SIZE,
01705 OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE,
01706 OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE,
01707 OPT_OLD_ALTER_TABLE,
01708 OPT_GROUP_CONCAT_MAX_LEN,
01709 OPT_DEFAULT_COLLATION,
01710 OPT_CHARACTER_SET_FILESYSTEM,
01711 OPT_LC_TIME_NAMES,
01712 OPT_INIT_CONNECT,
01713 OPT_DEFAULT_TIME_ZONE,
01714 OPT_OPTIMIZER_SEARCH_DEPTH,
01715 OPT_SCHEDULER,
01716 OPT_PROTOCOL,
01717 OPT_OPTIMIZER_PRUNE_LEVEL,
01718 OPT_AUTO_INCREMENT, OPT_AUTO_INCREMENT_OFFSET,
01719 OPT_ENABLE_LARGE_PAGES,
01720 OPT_TIMED_MUTEXES,
01721 OPT_TABLE_LOCK_WAIT_TIMEOUT,
01722 OPT_PLUGIN_ADD,
01723 OPT_PLUGIN_LOAD,
01724 OPT_PLUGIN_DIR,
01725 OPT_PORT_OPEN_TIMEOUT,
01726 OPT_SECURE_FILE_PRIV,
01727 OPT_MIN_EXAMINED_ROW_LIMIT
01728 };
01729
01730
01731 struct my_option my_long_options[] =
01732 {
01733 {"help", '?', N_("Display this help and exit."),
01734 (char**) &opt_help, (char**) &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
01735 0, 0},
01736 {"help-extended", '?',
01737 N_("Display this help and exit after initializing plugins."),
01738 (char**) &opt_help_extended, (char**) &opt_help_extended,
01739 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
01740 {"auto-increment-increment", OPT_AUTO_INCREMENT,
01741 N_("Auto-increment columns are incremented by this"),
01742 (char**) &global_system_variables.auto_increment_increment,
01743 (char**) &max_system_variables.auto_increment_increment, 0, GET_ULL,
01744 OPT_ARG, 1, 1, UINT64_MAX, 0, 1, 0 },
01745 {"auto-increment-offset", OPT_AUTO_INCREMENT_OFFSET,
01746 N_("Offset added to Auto-increment columns. Used when "
01747 "auto-increment-increment != 1"),
01748 (char**) &global_system_variables.auto_increment_offset,
01749 (char**) &max_system_variables.auto_increment_offset, 0, GET_ULL, OPT_ARG,
01750 1, 1, UINT64_MAX, 0, 1, 0 },
01751 {"basedir", 'b',
01752 N_("Path to installation directory. All paths are usually resolved "
01753 "relative to this."),
01754 (char**) &drizzle_home_ptr, (char**) &drizzle_home_ptr, 0, GET_STR, REQUIRED_ARG,
01755 0, 0, 0, 0, 0, 0},
01756 {"chroot", 'r',
01757 N_("Chroot drizzled daemon during startup."),
01758 (char**) &drizzled_chroot, (char**) &drizzled_chroot, 0, GET_STR, REQUIRED_ARG,
01759 0, 0, 0, 0, 0, 0},
01760 {"collation-server", OPT_DEFAULT_COLLATION,
01761 N_("Set the default collation."),
01762 (char**) &default_collation_name, (char**) &default_collation_name,
01763 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
01764 {"completion-type", OPT_COMPLETION_TYPE,
01765 N_("Default completion type."),
01766 (char**) &global_system_variables.completion_type,
01767 (char**) &max_system_variables.completion_type, 0, GET_UINT,
01768 REQUIRED_ARG, 0, 0, 2, 0, 1, 0},
01769 {"core-file", OPT_WANT_CORE,
01770 N_("Write core on errors."),
01771 0, 0, 0, GET_NO_ARG,
01772 NO_ARG, 0, 0, 0, 0, 0, 0},
01773 {"datadir", 'h',
01774 N_("Path to the database root."),
01775 (char**) &drizzle_data_home,
01776 (char**) &drizzle_data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
01777 {"default-storage-engine", OPT_STORAGE_ENGINE,
01778 N_("Set the default storage engine (table type) for tables."),
01779 (char**)&default_storage_engine_str, (char**)&default_storage_engine_str,
01780 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
01781 {"default-time-zone", OPT_DEFAULT_TIME_ZONE,
01782 N_("Set the default time zone."),
01783 (char**) &default_tz_name, (char**) &default_tz_name,
01784 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
01785 #ifdef HAVE_STACK_TRACE_ON_SEGV
01786 {"enable-pstack", OPT_DO_PSTACK,
01787 N_("Print a symbolic stack trace on failure."),
01788 (char**) &opt_do_pstack, (char**) &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0,
01789 0, 0, 0, 0},
01790 #endif
01791
01792 {"exit-info", 'T',
01793 N_("Used for debugging; Use at your own risk!"),
01794 0, 0, 0, GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
01795
01796
01797 {"gdb", OPT_DEBUGGING,
01798 N_("Set up signals usable for debugging"),
01799 (char**) &opt_debugging, (char**) &opt_debugging,
01800 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
01801 {"language", 'L',
01802 N_("(IGNORED)"),
01803 (char**) &language_ptr, (char**) &language_ptr, 0, GET_STR, REQUIRED_ARG,
01804 0, 0, 0, 0, 0, 0},
01805 {"lc-time-names", OPT_LC_TIME_NAMES,
01806 N_("Set the language used for the month names and the days of the week."),
01807 (char**) &lc_time_names_name,
01808 (char**) &lc_time_names_name,
01809 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
01810 {"log-warnings", 'W',
01811 N_("Log some not critical warnings to the log file."),
01812 (char**) &global_system_variables.log_warnings,
01813 (char**) &max_system_variables.log_warnings, 0, GET_BOOL, OPT_ARG, 1, 0, 0,
01814 0, 0, 0},
01815 {"memlock", OPT_MEMLOCK,
01816 N_("Lock drizzled in memory."),
01817 (char**) &locked_in_memory,
01818 (char**) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
01819 {"pid-file", OPT_PID_FILE,
01820 N_("Pid file used by safe_mysqld."),
01821 (char**) &pidfile_name_ptr, (char**) &pidfile_name_ptr, 0, GET_STR,
01822 REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
01823 {"port-open-timeout", OPT_PORT_OPEN_TIMEOUT,
01824 N_("Maximum time in seconds to wait for the port to become free. "
01825 "(Default: no wait)"),
01826 (char**) &drizzled_bind_timeout,
01827 (char**) &drizzled_bind_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
01828 {"secure-file-priv", OPT_SECURE_FILE_PRIV,
01829 N_("Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
01830 "within specified directory"),
01831 (char**) &opt_secure_file_priv, (char**) &opt_secure_file_priv, 0,
01832 GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
01833 {"server-id", OPT_SERVER_ID,
01834 N_("Uniquely identifies the server instance in the community of "
01835 "replication partners."),
01836 (char**) &server_id, (char**) &server_id, 0, GET_UINT32, REQUIRED_ARG, 0, 0, 0,
01837 0, 0, 0},
01838 {"skip-stack-trace", OPT_SKIP_STACK_TRACE,
01839 N_("Don't print a stack trace on failure."),
01840 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
01841 0, 0, 0, 0},
01842 {"symbolic-links", 's',
01843 N_("Enable symbolic link support."),
01844 (char**) &my_use_symdir, (char**) &my_use_symdir, 0, GET_BOOL, NO_ARG,
01845
01846
01847
01848
01849
01850 IF_PURIFY(0,1), 0, 0, 0, 0, 0},
01851 {"timed_mutexes", OPT_TIMED_MUTEXES,
01852 N_("Specify whether to time mutexes (only InnoDB mutexes are currently "
01853 "supported)"),
01854 (char**) &timed_mutexes, (char**) &timed_mutexes, 0, GET_BOOL, NO_ARG, 0,
01855 0, 0, 0, 0, 0},
01856 {"tmpdir", 't',
01857 N_("Path for temporary files."),
01858 (char**) &opt_drizzle_tmpdir,
01859 (char**) &opt_drizzle_tmpdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
01860 {"transaction-isolation", OPT_TX_ISOLATION,
01861 N_("Default transaction isolation level."),
01862 0, 0, 0, GET_STR, REQUIRED_ARG, 0,
01863 0, 0, 0, 0, 0},
01864 {"user", 'u',
01865 N_("Run drizzled daemon as user."),
01866 0, 0, 0, GET_STR, REQUIRED_ARG,
01867 0, 0, 0, 0, 0, 0},
01868 {"version", 'V',
01869 N_("Output version information and exit."),
01870 0, 0, 0, GET_NO_ARG,
01871 NO_ARG, 0, 0, 0, 0, 0, 0},
01872 {"back_log", OPT_BACK_LOG,
01873 N_("The number of outstanding connection requests Drizzle can have. This "
01874 "comes into play when the main Drizzle thread gets very many connection "
01875 "requests in a very short time."),
01876 (char**) &back_log, (char**) &back_log, 0, GET_UINT,
01877 REQUIRED_ARG, 50, 1, 65535, 0, 1, 0 },
01878 { "bulk_insert_buffer_size", OPT_BULK_INSERT_BUFFER_SIZE,
01879 N_("Size of tree cache used in bulk insert optimization. Note that this is "
01880 "a limit per thread!"),
01881 (char**) &global_system_variables.bulk_insert_buff_size,
01882 (char**) &max_system_variables.bulk_insert_buff_size,
01883 0, GET_ULL, REQUIRED_ARG, 8192*1024, 0, ULONG_MAX, 0, 1, 0},
01884 { "div_precision_increment", OPT_DIV_PRECINCREMENT,
01885 N_("Precision of the result of '/' operator will be increased on that "
01886 "value."),
01887 (char**) &global_system_variables.div_precincrement,
01888 (char**) &max_system_variables.div_precincrement, 0, GET_UINT,
01889 REQUIRED_ARG, 4, 0, DECIMAL_MAX_SCALE, 0, 0, 0},
01890 { "group_concat_max_len", OPT_GROUP_CONCAT_MAX_LEN,
01891 N_("The maximum length of the result of function group_concat."),
01892 (char**) &global_system_variables.group_concat_max_len,
01893 (char**) &max_system_variables.group_concat_max_len, 0, GET_UINT64,
01894 REQUIRED_ARG, 1024, 4, ULONG_MAX, 0, 1, 0},
01895 { "join_buffer_size", OPT_JOIN_BUFF_SIZE,
01896 N_("The size of the buffer that is used for full joins."),
01897 (char**) &global_system_variables.join_buff_size,
01898 (char**) &max_system_variables.join_buff_size, 0, GET_UINT64,
01899 REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ULONG_MAX,
01900 MALLOC_OVERHEAD, IO_SIZE, 0},
01901 {"key_buffer_size", OPT_KEY_BUFFER_SIZE,
01902 N_("The size of the buffer used for index blocks for MyISAM tables. "
01903 "Increase this to get better index handling (for all reads and multiple "
01904 "writes) to as much as you can afford;"),
01905 (char**) &dflt_key_cache_var.param_buff_size,
01906 (char**) 0,
01907 0, (GET_ULL),
01908 REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, SIZE_MAX, MALLOC_OVERHEAD,
01909 IO_SIZE, 0},
01910 {"key_cache_age_threshold", OPT_KEY_CACHE_AGE_THRESHOLD,
01911 N_("This characterizes the number of hits a hot block has to be untouched "
01912 "until it is considered aged enough to be downgraded to a warm block. "
01913 "This specifies the percentage ratio of that number of hits to the "
01914 "total number of blocks in key cache"),
01915 (char**) &dflt_key_cache_var.param_age_threshold,
01916 (char**) 0,
01917 0, (GET_UINT32), REQUIRED_ARG,
01918 300, 100, ULONG_MAX, 0, 100, 0},
01919 {"key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE,
01920 N_("The default size of key cache blocks"),
01921 (char**) &dflt_key_cache_var.param_block_size,
01922 (char**) 0,
01923 0, (GET_UINT32), REQUIRED_ARG,
01924 KEY_CACHE_BLOCK_SIZE, 512, 1024 * 16, 0, 512, 0},
01925 {"key_cache_division_limit", OPT_KEY_CACHE_DIVISION_LIMIT,
01926 N_("The minimum percentage of warm blocks in key cache"),
01927 (char**) &dflt_key_cache_var.param_division_limit,
01928 (char**) 0,
01929 0, (GET_UINT32) , REQUIRED_ARG, 100,
01930 1, 100, 0, 1, 0},
01931 {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
01932 N_("Max packetlength to send/receive from to server."),
01933 (char**) &global_system_variables.max_allowed_packet,
01934 (char**) &max_system_variables.max_allowed_packet, 0, GET_UINT32,
01935 REQUIRED_ARG, 1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
01936 {"max_connect_errors", OPT_MAX_CONNECT_ERRORS,
01937 N_("If there is more than this number of interrupted connections from a "
01938 "host this host will be blocked from further connections."),
01939 (char**) &max_connect_errors, (char**) &max_connect_errors, 0, GET_UINT64,
01940 REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ULONG_MAX, 0, 1, 0},
01941 {"max_error_count", OPT_MAX_ERROR_COUNT,
01942 N_("Max number of errors/warnings to store for a statement."),
01943 (char**) &global_system_variables.max_error_count,
01944 (char**) &max_system_variables.max_error_count,
01945 0, GET_UINT64, REQUIRED_ARG, DEFAULT_ERROR_COUNT, 0, 65535, 0, 1, 0},
01946 {"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE,
01947 N_("Don't allow creation of heap tables bigger than this."),
01948 (char**) &global_system_variables.max_heap_table_size,
01949 (char**) &max_system_variables.max_heap_table_size, 0, GET_ULL,
01950 REQUIRED_ARG, 16*1024*1024L, 16384, MAX_MEM_TABLE_SIZE,
01951 MALLOC_OVERHEAD, 1024, 0},
01952 {"max_join_size", OPT_MAX_JOIN_SIZE,
01953 N_("Joins that are probably going to read more than max_join_size records "
01954 "return an error."),
01955 (char**) &global_system_variables.max_join_size,
01956 (char**) &max_system_variables.max_join_size, 0, GET_HA_ROWS, REQUIRED_ARG,
01957 INT32_MAX, 1, INT32_MAX, 0, 1, 0},
01958 {"max_length_for_sort_data", OPT_MAX_LENGTH_FOR_SORT_DATA,
01959 N_("Max number of bytes in sorted records."),
01960 (char**) &global_system_variables.max_length_for_sort_data,
01961 (char**) &max_system_variables.max_length_for_sort_data, 0, GET_ULL,
01962 REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
01963 { "max_seeks_for_key", OPT_MAX_SEEKS_FOR_KEY,
01964 N_("Limit assumed max number of seeks when looking up rows based on a key"),
01965 (char**) &global_system_variables.max_seeks_for_key,
01966 (char**) &max_system_variables.max_seeks_for_key, 0, GET_UINT64,
01967 REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0 },
01968 {"max_sort_length", OPT_MAX_SORT_LENGTH,
01969 N_("The number of bytes to use when sorting BLOB or TEXT values "
01970 "(only the first max_sort_length bytes of each value are used; the "
01971 "rest are ignored)."),
01972 (char**) &global_system_variables.max_sort_length,
01973 (char**) &max_system_variables.max_sort_length, 0, GET_SIZE,
01974 REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
01975 {"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
01976 N_("After this many write locks, allow some read locks to run in between."),
01977 (char**) &max_write_lock_count, (char**) &max_write_lock_count, 0, GET_ULL,
01978 REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0},
01979 {"min_examined_row_limit", OPT_MIN_EXAMINED_ROW_LIMIT,
01980 N_("Don't log queries which examine less than min_examined_row_limit "
01981 "rows to file."),
01982 (char**) &global_system_variables.min_examined_row_limit,
01983 (char**) &max_system_variables.min_examined_row_limit, 0, GET_ULL,
01984 REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1L, 0},
01985 {"optimizer_prune_level", OPT_OPTIMIZER_PRUNE_LEVEL,
01986 N_("Controls the heuristic(s) applied during query optimization to prune "
01987 "less-promising partial plans from the optimizer search space. Meaning: "
01988 "false - do not apply any heuristic, thus perform exhaustive search; "
01989 "true - prune plans based on number of retrieved rows."),
01990 (char**) &global_system_variables.optimizer_prune_level,
01991 (char**) &max_system_variables.optimizer_prune_level,
01992 0, GET_BOOL, OPT_ARG, 1, 0, 1, 0, 1, 0},
01993 {"optimizer_search_depth", OPT_OPTIMIZER_SEARCH_DEPTH,
01994 N_("Maximum depth of search performed by the query optimizer. Values "
01995 "larger than the number of relations in a query result in better query "
01996 "plans, but take longer to compile a query. Smaller values than the "
01997 "number of tables in a relation result in faster optimization, but may "
01998 "produce very bad query plans. If set to 0, the system will "
01999 "automatically pick a reasonable value; if set to MAX_TABLES+2, the "
02000 "optimizer will switch to the original find_best (used for "
02001 "testing/comparison)."),
02002 (char**) &global_system_variables.optimizer_search_depth,
02003 (char**) &max_system_variables.optimizer_search_depth,
02004 0, GET_UINT, OPT_ARG, 0, 0, MAX_TABLES+2, 0, 1, 0},
02005 {"plugin_dir", OPT_PLUGIN_DIR,
02006 N_("Directory for plugins."),
02007 (char**) &opt_plugin_dir_ptr, (char**) &opt_plugin_dir_ptr, 0,
02008 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
02009 {"plugin_add", OPT_PLUGIN_ADD,
02010 N_("Optional comma separated list of plugins to load at startup in addition "
02011 "to the default list of plugins. "
02012 "[for example: --plugin_add=crc32,logger_gearman]"),
02013 (char**) &opt_plugin_add, (char**) &opt_plugin_add, 0,
02014 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
02015 {"plugin_load", OPT_PLUGIN_LOAD,
02016 N_("Optional comma separated list of plugins to load at starup instead of "
02017 "the default plugin load list. "
02018 "[for example: --plugin_load=crc32,logger_gearman]"),
02019 (char**) &opt_plugin_load, (char**) &opt_plugin_load, 0,
02020 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
02021 {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
02022 N_("The size of the buffer that is allocated when preloading indexes"),
02023 (char**) &global_system_variables.preload_buff_size,
02024 (char**) &max_system_variables.preload_buff_size, 0, GET_ULL,
02025 REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0},
02026 {"query_alloc_block_size", OPT_QUERY_ALLOC_BLOCK_SIZE,
02027 N_("Allocation block size for query parsing and execution"),
02028 (char**) &global_system_variables.query_alloc_block_size,
02029 (char**) &max_system_variables.query_alloc_block_size, 0, GET_UINT,
02030 REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
02031 {"query_prealloc_size", OPT_QUERY_PREALLOC_SIZE,
02032 N_("Persistent buffer for query parsing and execution"),
02033 (char**) &global_system_variables.query_prealloc_size,
02034 (char**) &max_system_variables.query_prealloc_size, 0, GET_UINT,
02035 REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, QUERY_ALLOC_PREALLOC_SIZE,
02036 ULONG_MAX, 0, 1024, 0},
02037 {"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE,
02038 N_("Allocation block size for storing ranges during optimization"),
02039 (char**) &global_system_variables.range_alloc_block_size,
02040 (char**) &max_system_variables.range_alloc_block_size, 0, GET_SIZE,
02041 REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, SIZE_MAX,
02042 0, 1024, 0},
02043 {"read_buffer_size", OPT_RECORD_BUFFER,
02044 N_("Each thread that does a sequential scan allocates a buffer of this "
02045 "size for each table it scans. If you do many sequential scans, you may "
02046 "want to increase this value."),
02047 (char**) &global_system_variables.read_buff_size,
02048 (char**) &max_system_variables.read_buff_size,0, GET_UINT, REQUIRED_ARG,
02049 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, INT32_MAX, MALLOC_OVERHEAD, IO_SIZE,
02050 0},
02051 {"read_rnd_buffer_size", OPT_RECORD_RND_BUFFER,
02052 N_("When reading rows in sorted order after a sort, the rows are read "
02053 "through this buffer to avoid a disk seeks. If not set, then it's set "
02054 "to the value of record_buffer."),
02055 (char**) &global_system_variables.read_rnd_buff_size,
02056 (char**) &max_system_variables.read_rnd_buff_size, 0,
02057 GET_UINT, REQUIRED_ARG, 256*1024L, 64 ,
02058 UINT32_MAX, MALLOC_OVERHEAD, 1 , 0},
02059 {"scheduler", OPT_SCHEDULER,
02060 N_("Select scheduler to be used (by default multi-thread)."),
02061 (char**)&opt_scheduler, (char**)&opt_scheduler,
02062 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
02063
02064 {"sort_buffer_size", OPT_SORT_BUFFER,
02065 N_("Each thread that needs to do a sort allocates a buffer of this size."),
02066 (char**) &global_system_variables.sortbuff_size,
02067 (char**) &max_system_variables.sortbuff_size, 0, GET_SIZE, REQUIRED_ARG,
02068 MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*8, SIZE_MAX,
02069 MALLOC_OVERHEAD, 1, 0},
02070 {"table_definition_cache", OPT_TABLE_DEF_CACHE,
02071 N_("The number of cached table definitions."),
02072 (char**) &table_def_size, (char**) &table_def_size,
02073 0, GET_SIZE, REQUIRED_ARG, 128, 1, 512*1024L, 0, 1, 0},
02074 {"table_open_cache", OPT_TABLE_OPEN_CACHE,
02075 N_("The number of cached open tables."),
02076 (char**) &table_cache_size, (char**) &table_cache_size, 0, GET_UINT64,
02077 REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
02078 {"table_lock_wait_timeout", OPT_TABLE_LOCK_WAIT_TIMEOUT,
02079 N_("Timeout in seconds to wait for a table level lock before returning an "
02080 "error. Used only if the connection has active cursors."),
02081 (char**) &table_lock_wait_timeout, (char**) &table_lock_wait_timeout,
02082 0, GET_ULL, REQUIRED_ARG, 50, 1, 1024 * 1024 * 1024, 0, 1, 0},
02083 {"thread_stack", OPT_THREAD_STACK,
02084 N_("The stack size for each thread."),
02085 (char**) &my_thread_stack_size,
02086 (char**) &my_thread_stack_size, 0, GET_SIZE,
02087 REQUIRED_ARG,DEFAULT_THREAD_STACK,
02088 UINT32_C(1024*512), SIZE_MAX, 0, 1024, 0},
02089 {"tmp_table_size", OPT_TMP_TABLE_SIZE,
02090 N_("If an internal in-memory temporary table exceeds this size, Drizzle will"
02091 " automatically convert it to an on-disk MyISAM table."),
02092 (char**) &global_system_variables.tmp_table_size,
02093 (char**) &max_system_variables.tmp_table_size, 0, GET_ULL,
02094 REQUIRED_ARG, 16*1024*1024L, 1024, MAX_MEM_TABLE_SIZE, 0, 1, 0},
02095 {"transaction_alloc_block_size", OPT_TRANS_ALLOC_BLOCK_SIZE,
02096 N_("Allocation block size for transactions to be stored in binary log"),
02097 (char**) &global_system_variables.trans_alloc_block_size,
02098 (char**) &max_system_variables.trans_alloc_block_size, 0, GET_UINT,
02099 REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
02100 {"transaction_prealloc_size", OPT_TRANS_PREALLOC_SIZE,
02101 N_("Persistent buffer for transactions to be stored in binary log"),
02102 (char**) &global_system_variables.trans_prealloc_size,
02103 (char**) &max_system_variables.trans_prealloc_size, 0, GET_UINT,
02104 REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
02105 {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
02106 };
02107
02108 static void print_version(void)
02109 {
02110
02111
02112
02113
02114 printf("%s Ver %s for %s-%s on %s (%s)\n",my_progname,
02115 PANDORA_RELEASE_VERSION, HOST_VENDOR, HOST_OS, HOST_CPU,
02116 COMPILATION_COMMENT);
02117 }
02118
02119 static void usage(void)
02120 {
02121 if (!(default_charset_info= get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)))
02122 exit(1);
02123 if (!default_collation_name)
02124 default_collation_name= (char*) default_charset_info->name;
02125 print_version();
02126 puts(_("Copyright (C) 2008 Sun Microsystems\n"
02127 "This software comes with ABSOLUTELY NO WARRANTY. "
02128 "This is free software,\n"
02129 "and you are welcome to modify and redistribute it under the GPL "
02130 "license\n\n"
02131 "Starts the Drizzle database server\n"));
02132
02133 printf(_("Usage: %s [OPTIONS]\n"), my_progname);
02134 {
02135 print_defaults(DRIZZLE_CONFIG_NAME,load_default_groups);
02136 puts("");
02137
02138
02139 my_print_help_inc_plugins(my_long_options);
02140 }
02141 }
02142
02143
02160 static void drizzle_init_variables(void)
02161 {
02162
02163 drizzle_home[0]= pidfile_name[0]= 0;
02164 opt_tc_log_file= (char *)"tc.log";
02165 opt_secure_file_priv= 0;
02166 segfaulted= 0;
02167 cleanup_done= 0;
02168 defaults_argc= 0;
02169 defaults_argv= 0;
02170 dropping_tables= ha_open_options=0;
02171 test_flags.reset();
02172 wake_thread=0;
02173 abort_loop= select_thread_in_use= false;
02174 ready_to_exit= shutdown_in_progress= 0;
02175 aborted_threads= aborted_connects= 0;
02176 max_used_connections= 0;
02177 drizzled_user= drizzled_chroot= 0;
02178 memset(&global_status_var, 0, sizeof(global_status_var));
02179 key_map_full.set();
02180
02181
02182 system_charset_info= &my_charset_utf8_general_ci;
02183 files_charset_info= &my_charset_utf8_general_ci;
02184 table_alias_charset= &my_charset_bin;
02185 character_set_filesystem= &my_charset_bin;
02186
02187
02188 drizzle_home_ptr= drizzle_home;
02189 pidfile_name_ptr= pidfile_name;
02190 language_ptr= language;
02191 drizzle_data_home= drizzle_real_data_home;
02192 session_startup_options= (OPTION_AUTO_IS_NULL | OPTION_SQL_NOTES);
02193 refresh_version= 1L;
02194 global_thread_id= 1UL;
02195 getSessionList().clear();
02196
02197
02198 strncpy(language, LANGUAGE, sizeof(language)-1);
02199 strncpy(drizzle_real_data_home, get_relative_path(LOCALSTATEDIR),
02200 sizeof(drizzle_real_data_home)-1);
02201 drizzle_data_home_buff[0]=FN_CURLIB;
02202 drizzle_data_home_buff[1]=0;
02203 drizzle_data_home_len= 2;
02204
02205
02206 default_character_set_name= "utf8";
02207 default_collation_name= (char *)compiled_default_collation_name;
02208 character_set_filesystem_name= "binary";
02209 lc_time_names_name= (char*) "en_US";
02210
02211 default_storage_engine_str= (char*) "innodb";
02212 global_system_variables.storage_engine= NULL;
02213 global_system_variables.tx_isolation= ISO_REPEATABLE_READ;
02214 global_system_variables.select_limit= (uint64_t) HA_POS_ERROR;
02215 max_system_variables.select_limit= (uint64_t) HA_POS_ERROR;
02216 global_system_variables.max_join_size= (uint64_t) HA_POS_ERROR;
02217 max_system_variables.max_join_size= (uint64_t) HA_POS_ERROR;
02218
02219
02220 #ifdef HAVE_BROKEN_REALPATH
02221 have_symlink=SHOW_OPTION_NO;
02222 #else
02223 have_symlink=SHOW_OPTION_YES;
02224 #endif
02225
02226 const char *tmpenv;
02227 if (!(tmpenv = getenv("MY_BASEDIR_VERSION")))
02228 tmpenv = PREFIX;
02229 (void) strncpy(drizzle_home, tmpenv, sizeof(drizzle_home)-1);
02230
02231 connection_count= 0;
02232 }
02233
02234
02235 extern "C" bool
02236 drizzled_get_one_option(int optid, const struct my_option *opt,
02237 char *argument)
02238 {
02239 switch(optid) {
02240 case 'a':
02241 global_system_variables.tx_isolation= ISO_SERIALIZABLE;
02242 break;
02243 case 'b':
02244 strncpy(drizzle_home,argument,sizeof(drizzle_home)-1);
02245 break;
02246 case 'C':
02247 if (default_collation_name == compiled_default_collation_name)
02248 default_collation_name= 0;
02249 break;
02250 case 'h':
02251 strncpy(drizzle_real_data_home,argument, sizeof(drizzle_real_data_home)-1);
02252
02253 drizzle_data_home= drizzle_real_data_home;
02254 drizzle_data_home_len= strlen(drizzle_data_home);
02255 break;
02256 case 'u':
02257 if (!drizzled_user || !strcmp(drizzled_user, argument))
02258 drizzled_user= argument;
02259 else
02260 errmsg_printf(ERRMSG_LVL_WARN, _("Ignoring user change to '%s' because the user was "
02261 "set to '%s' earlier on the command line\n"),
02262 argument, drizzled_user);
02263 break;
02264 case 'L':
02265 strncpy(language, argument, sizeof(language)-1);
02266 break;
02267 case 'V':
02268 print_version();
02269 exit(0);
02270 case 'W':
02271 if (!argument)
02272 global_system_variables.log_warnings++;
02273 else if (argument == disabled_my_option)
02274 global_system_variables.log_warnings= 0L;
02275 else
02276 global_system_variables.log_warnings= atoi(argument);
02277 break;
02278 case 'T':
02279 if (argument)
02280 {
02281 test_flags.set((uint32_t) atoi(argument));
02282 }
02283 break;
02284 case (int) OPT_WANT_CORE:
02285 test_flags.set(TEST_CORE_ON_SIGNAL);
02286 break;
02287 case (int) OPT_SKIP_STACK_TRACE:
02288 test_flags.set(TEST_NO_STACKTRACE);
02289 break;
02290 case (int) OPT_SKIP_SYMLINKS:
02291 my_use_symdir=0;
02292 break;
02293 case (int) OPT_BIND_ADDRESS:
02294 {
02295 struct addrinfo *res_lst, hints;
02296
02297 memset(&hints, 0, sizeof(struct addrinfo));
02298 hints.ai_socktype= SOCK_STREAM;
02299 hints.ai_protocol= IPPROTO_TCP;
02300
02301 if (getaddrinfo(argument, NULL, &hints, &res_lst) != 0)
02302 {
02303 errmsg_printf(ERRMSG_LVL_ERROR, _("Can't start server: cannot resolve hostname!"));
02304 exit(1);
02305 }
02306
02307 if (res_lst->ai_next)
02308 {
02309 errmsg_printf(ERRMSG_LVL_ERROR, _("Can't start server: bind-address refers to "
02310 "multiple interfaces!"));
02311 exit(1);
02312 }
02313 freeaddrinfo(res_lst);
02314 }
02315 break;
02316 case (int) OPT_PID_FILE:
02317 strncpy(pidfile_name, argument, sizeof(pidfile_name)-1);
02318 break;
02319 case OPT_SERVER_ID:
02320 break;
02321 case OPT_TX_ISOLATION:
02322 {
02323 int type;
02324 type= find_type_or_exit(argument, &tx_isolation_typelib, opt->name);
02325 global_system_variables.tx_isolation= (type-1);
02326 break;
02327 }
02328 case OPT_TC_HEURISTIC_RECOVER:
02329 tc_heuristic_recover= find_type_or_exit(argument,
02330 &tc_heuristic_recover_typelib,
02331 opt->name);
02332 break;
02333 }
02334
02335 return 0;
02336 }
02337
02338 extern "C" void option_error_reporter(enum loglevel level, const char *format, ...);
02339
02340 extern "C" void option_error_reporter(enum loglevel level, const char *format, ...)
02341 {
02342 va_list args;
02343 va_start(args, format);
02344
02345
02346 if (level == ERROR_LEVEL || global_system_variables.log_warnings)
02347 {
02348 plugin::ErrorMessage::vprintf(current_session, ERROR_LEVEL, format, args);
02349 }
02350 va_end(args);
02351 }
02352
02353
02358 static void get_options(int *argc,char **argv)
02359 {
02360 int ho_error;
02361
02362 my_getopt_error_reporter= option_error_reporter;
02363
02364 string progname(argv[0]);
02365
02366
02367 my_getopt_skip_unknown= true;
02368
02369 if ((ho_error= handle_options(argc, &argv, my_long_options,
02370 drizzled_get_one_option)))
02371 exit(ho_error);
02372 (*argc)++;
02373
02374
02375 #if defined(HAVE_BROKEN_REALPATH)
02376 my_use_symdir=0;
02377 my_disable_symlinks=1;
02378 have_symlink=SHOW_OPTION_NO;
02379 #else
02380 if (!my_use_symdir)
02381 {
02382 my_disable_symlinks=1;
02383 have_symlink=SHOW_OPTION_DISABLED;
02384 }
02385 #endif
02386 if (opt_debugging)
02387 {
02388
02389 test_flags.set(TEST_SIGINT);
02390 test_flags.set(TEST_NO_STACKTRACE);
02391 test_flags.reset(TEST_CORE_ON_SIGNAL);
02392 }
02393
02394 if (drizzled_chroot)
02395 set_root(drizzled_chroot);
02396 fix_paths(progname);
02397
02398
02399
02400
02401
02402 my_default_record_cache_size=global_system_variables.read_buff_size;
02403 }
02404
02405
02406 static const char *get_relative_path(const char *path)
02407 {
02408 if (test_if_hard_path(path) &&
02409 (strncmp(path, PREFIX, strlen(PREFIX)) == 0) &&
02410 strcmp(PREFIX,FN_ROOTDIR))
02411 {
02412 if (strlen(PREFIX) < strlen(path))
02413 path+=(size_t) strlen(PREFIX);
02414 while (*path == FN_LIBCHAR)
02415 path++;
02416 }
02417 return path;
02418 }
02419
02420
02421 static void fix_paths(string &progname)
02422 {
02423 char buff[FN_REFLEN],*pos,rp_buff[PATH_MAX];
02424 convert_dirname(drizzle_home,drizzle_home,NULL);
02425
02426 #if defined(HAVE_BROKEN_REALPATH)
02427 my_load_path(drizzle_home, drizzle_home, NULL);
02428 #else
02429 if (!realpath(drizzle_home,rp_buff))
02430 my_load_path(rp_buff, drizzle_home, NULL);
02431 rp_buff[FN_REFLEN-1]= '\0';
02432 strcpy(drizzle_home,rp_buff);
02433
02434 pos= strchr(drizzle_home, '\0');
02435 #endif
02436 if (pos[-1] != FN_LIBCHAR)
02437 {
02438 pos[0]= FN_LIBCHAR;
02439 pos[1]= 0;
02440 }
02441 convert_dirname(drizzle_real_data_home,drizzle_real_data_home,NULL);
02442 (void) fn_format(buff, drizzle_real_data_home, "", "",
02443 (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
02444 (void) unpack_dirname(drizzle_unpacked_real_data_home, buff);
02445 convert_dirname(language,language,NULL);
02446 (void) my_load_path(drizzle_home, drizzle_home,"");
02447 (void) my_load_path(drizzle_real_data_home, drizzle_real_data_home,drizzle_home);
02448 (void) my_load_path(pidfile_name, pidfile_name,drizzle_real_data_home);
02449
02450 if (opt_plugin_dir_ptr == NULL)
02451 {
02452
02453 if (progname[0] != FN_LIBCHAR)
02454 {
02455
02456 char working_dir[FN_REFLEN];
02457 char *working_dir_ptr= working_dir;
02458 working_dir_ptr= getcwd(working_dir_ptr, FN_REFLEN);
02459 string new_path(working_dir);
02460 if (*(new_path.end()-1) != '/')
02461 new_path.push_back('/');
02462 if (progname[0] == '.' && progname[1] == '/')
02463 new_path.append(progname.substr(2));
02464 else
02465 new_path.append(progname);
02466 progname.swap(new_path);
02467 }
02468
02469
02470 string progdir(progname.substr(0, progname.rfind(FN_LIBCHAR)+1));
02471 if (progdir.rfind(".libs/") != string::npos)
02472 {
02473 progdir.assign(progdir.substr(0, progdir.rfind(".libs/")));
02474 }
02475 string testfile(progdir);
02476 testfile.append("drizzled.o");
02477 struct stat testfile_stat;
02478 if (stat(testfile.c_str(), &testfile_stat))
02479 {
02480
02481
02482
02483 (void) my_load_path(opt_plugin_dir, get_relative_path(PKGPLUGINDIR),
02484 drizzle_home);
02485 }
02486 else
02487 {
02488
02489 size_t last_libchar_pos= progdir.rfind(FN_LIBCHAR,progdir.size()-2)+1;
02490 string source_plugindir(progdir.substr(0,last_libchar_pos));
02491 source_plugindir.append("plugin/.libs");
02492 (void) my_load_path(opt_plugin_dir, source_plugindir.c_str(), "");
02493 }
02494 }
02495 else
02496 {
02497 (void) my_load_path(opt_plugin_dir, opt_plugin_dir_ptr, drizzle_home);
02498 }
02499 opt_plugin_dir_ptr= opt_plugin_dir;
02500
02501 const char *sharedir= get_relative_path(PKGDATADIR);
02502 if (test_if_hard_path(sharedir))
02503 strncpy(buff,sharedir,sizeof(buff)-1);
02504 else
02505 {
02506 strcpy(buff, drizzle_home);
02507 strncat(buff, sharedir, sizeof(buff)-strlen(drizzle_home)-1);
02508 }
02509 convert_dirname(buff,buff,NULL);
02510 (void) my_load_path(language,language,buff);
02511
02512 {
02513 char *tmp_string;
02514 struct stat buf;
02515
02516 tmp_string= getenv("TMPDIR");
02517
02518 if (opt_drizzle_tmpdir)
02519 drizzle_tmpdir= strdup(opt_drizzle_tmpdir);
02520 else if (tmp_string == NULL)
02521 drizzle_tmpdir= strdup(P_tmpdir);
02522 else
02523 drizzle_tmpdir= strdup(tmp_string);
02524
02525 assert(drizzle_tmpdir);
02526
02527 if (stat(drizzle_tmpdir, &buf) || (S_ISDIR(buf.st_mode) == false))
02528 {
02529 exit(1);
02530 }
02531 }
02532
02533
02534
02535
02536
02537 if (opt_secure_file_priv)
02538 {
02539 convert_dirname(buff, opt_secure_file_priv, NULL);
02540 free(opt_secure_file_priv);
02541 opt_secure_file_priv= strdup(buff);
02542 if (opt_secure_file_priv == NULL)
02543 exit(1);
02544 }
02545 }
02546