00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <drizzled/configmake.h>
00023 #include <drizzled/atomics.h>
00024 #include <drizzled/data_home.h>
00025
00026 #include <netdb.h>
00027 #include <sys/types.h>
00028 #include <netinet/tcp.h>
00029 #include <netinet/in.h>
00030 #include <signal.h>
00031 #include <limits.h>
00032 #include <stdexcept>
00033
00034 #include <boost/program_options.hpp>
00035 #include <drizzled/program_options/config_file.h>
00036 #include <boost/thread/recursive_mutex.hpp>
00037 #include <boost/thread/mutex.hpp>
00038 #include <boost/thread/shared_mutex.hpp>
00039 #include <boost/thread/condition_variable.hpp>
00040 #include <boost/filesystem.hpp>
00041 #include <boost/detail/atomic_count.hpp>
00042
00043 #include <drizzled/cached_directory.h>
00044 #include <drizzled/charset.h>
00045 #include <drizzled/data_home.h>
00046 #include <drizzled/debug.h>
00047 #include <drizzled/definition/cache.h>
00048 #include <drizzled/drizzled.h>
00049 #include <drizzled/errmsg_print.h>
00050 #include <drizzled/error.h>
00051 #include <drizzled/global_buffer.h>
00052 #include <drizzled/internal/my_bit.h>
00053 #include <drizzled/internal/my_sys.h>
00054 #include <drizzled/item/cmpfunc.h>
00055 #include <drizzled/item/create.h>
00056 #include <drizzled/message/cache.h>
00057 #include <drizzled/module/load_list.h>
00058 #include <drizzled/module/registry.h>
00059 #include <drizzled/plugin/client.h>
00060 #include <drizzled/plugin/error_message.h>
00061 #include <drizzled/plugin/event_observer.h>
00062 #include <drizzled/plugin/listen.h>
00063 #include <drizzled/plugin/monitored_in_transaction.h>
00064 #include <drizzled/plugin/scheduler.h>
00065 #include <drizzled/plugin/storage_engine.h>
00066 #include <drizzled/plugin/xa_resource_manager.h>
00067 #include <drizzled/probes.h>
00068 #include <drizzled/replication_services.h>
00069 #include <drizzled/session.h>
00070 #include <drizzled/session/cache.h>
00071 #include <drizzled/show.h>
00072 #include <drizzled/sql_base.h>
00073 #include <drizzled/sql_parse.h>
00074 #include <drizzled/statistics_variables.h>
00075 #include <drizzled/table/cache.h>
00076 #include <drizzled/temporal_format.h>
00077 #include <drizzled/unireg.h>
00078 #include <plugin/myisam/myisam.h>
00079 #include <drizzled/typelib.h>
00080 #include <drizzled/visibility.h>
00081 #include <drizzled/system_variables.h>
00082 #include <drizzled/open_tables_state.h>
00083
00084 #include <google/protobuf/stubs/common.h>
00085
00086 #if TIME_WITH_SYS_TIME
00087 # include <sys/time.h>
00088 # include <time.h>
00089 #else
00090 # if HAVE_SYS_TIME_H
00091 # include <sys/time.h>
00092 # else
00093 # include <time.h>
00094 # endif
00095 #endif
00096
00097 #ifdef HAVE_SYS_PRCTL_H
00098 #include <sys/prctl.h>
00099 #endif
00100 #include <sys/socket.h>
00101
00102
00103 #include <errno.h>
00104 #include <sys/stat.h>
00105 #include <drizzled/option.h>
00106 #ifdef HAVE_SYSENT_H
00107 #include <sysent.h>
00108 #endif
00109 #include <pwd.h>
00110 #include <grp.h>
00111
00112 #ifdef HAVE_SELECT_H
00113 # include <select.h>
00114 #endif
00115
00116 #ifdef HAVE_SYS_SELECT_H
00117 #include <sys/select.h>
00118 #endif
00119
00120 #include <sys/utsname.h>
00121
00122 #ifdef HAVE_SYS_MMAN_H
00123 #include <sys/mman.h>
00124 #endif
00125
00126 #if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
00127 #include <ieeefp.h>
00128 #endif
00129
00130 #ifdef HAVE_FPU_CONTROL_H
00131 #include <fpu_control.h>
00132 #endif
00133
00134 #ifdef HAVE_SYS_FPU_H
00135
00136 #include <sys/fpu.h>
00137 #endif
00138
00139 #include <drizzled/internal/my_pthread.h>
00140 #include <drizzled/constrained_value.h>
00141
00142 #include <drizzled/gettext.h>
00143
00144
00145 #ifdef HAVE_VALGRIND
00146 #define IF_PURIFY(A,B) (A)
00147 #else
00148 #define IF_PURIFY(A,B) (B)
00149 #endif
00150
00151 #define MAX_MEM_TABLE_SIZE SIZE_MAX
00152 #include <iostream>
00153 #include <fstream>
00154
00155
00156 using namespace std;
00157 namespace fs=boost::filesystem;
00158 namespace po=boost::program_options;
00159 namespace dpo=drizzled::program_options;
00160
00161 bool opt_daemon= false;
00162
00163 namespace drizzled {
00164
00165 inline void setup_fpu()
00166 {
00167 #if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
00168
00169
00170
00171
00172
00173 #if defined(__i386__)
00174 fpsetmask(~(FP_X_INV | FP_X_DNML | FP_X_OFL | FP_X_UFL | FP_X_DZ |
00175 FP_X_IMP));
00176 #else
00177 fpsetmask(~(FP_X_INV | FP_X_OFL | FP_X_UFL | FP_X_DZ |
00178 FP_X_IMP));
00179 #endif
00180 #endif
00181
00182
00183
00184
00185
00186 #if defined(__i386__) && defined(HAVE_FPU_CONTROL_H) && defined(_FPU_DOUBLE)
00187 fpu_control_t cw;
00188 _FPU_GETCW(cw);
00189 cw= (cw & ~_FPU_EXTENDED) | _FPU_DOUBLE;
00190 _FPU_SETCW(cw);
00191 #endif
00192 }
00193
00194 #ifdef SOLARIS
00195 extern "C" int gethostname(char *name, int namelen);
00196 #endif
00197
00198 const char *first_keyword= "first";
00199 const char * const DRIZZLE_CONFIG_NAME= "drizzled";
00200
00201 #define GET_HA_ROWS GET_ULL
00202
00203 const char *tx_isolation_names[] = {"READ-UNCOMMITTED", "READ-COMMITTED", "REPEATABLE-READ", "SERIALIZABLE", NULL};
00204
00205 TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names) - 1, "", tx_isolation_names, NULL};
00206
00207 arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
00208 {{&Arg_comparator::compare_string, &Arg_comparator::compare_e_string},
00209 {&Arg_comparator::compare_real, &Arg_comparator::compare_e_real},
00210 {&Arg_comparator::compare_int_signed, &Arg_comparator::compare_e_int},
00211 {&Arg_comparator::compare_row, &Arg_comparator::compare_e_row},
00212 {&Arg_comparator::compare_decimal, &Arg_comparator::compare_e_decimal}};
00213
00214
00215
00216 static bool opt_debugging= false;
00217 static uint32_t wake_thread;
00218 static const char* drizzled_chroot;
00219 static const char* default_character_set_name= "utf8";
00220 static const char* lc_time_names_name= "en_US";
00221 static const char* default_storage_engine_str= "innodb";
00222 static const char* const compiled_default_collation_name= "utf8_general_ci";
00223 static const char* default_collation_name= compiled_default_collation_name;
00224
00225
00226
00227 const char *drizzled_user;
00228 bool volatile select_thread_in_use;
00229 bool volatile abort_loop;
00230 DRIZZLED_API bool volatile shutdown_in_progress;
00231 const char* opt_scheduler= "multi_thread";
00232
00233 DRIZZLED_API size_t my_thread_stack_size= 0;
00234
00235
00236
00237
00238 plugin::StorageEngine *heap_engine;
00239 plugin::StorageEngine *myisam_engine;
00240
00241 bool calling_initgroups= false;
00243 uint32_t drizzled_bind_timeout;
00244 uint32_t dropping_tables, ha_open_options;
00245 uint32_t tc_heuristic_recover= 0;
00246 uint64_t session_startup_options;
00247 back_log_constraints back_log(SOMAXCONN);
00248 DRIZZLED_API uint32_t server_id;
00249 DRIZZLED_API string server_uuid;
00250 uint64_t table_cache_size;
00251 size_t table_def_size;
00252 uint32_t global_thread_id= 1UL;
00253 pid_t current_pid;
00254
00255 extern const double log_10[309];
00256
00257 const double log_10[] = {
00258 1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007, 1e008, 1e009,
00259 1e010, 1e011, 1e012, 1e013, 1e014, 1e015, 1e016, 1e017, 1e018, 1e019,
00260 1e020, 1e021, 1e022, 1e023, 1e024, 1e025, 1e026, 1e027, 1e028, 1e029,
00261 1e030, 1e031, 1e032, 1e033, 1e034, 1e035, 1e036, 1e037, 1e038, 1e039,
00262 1e040, 1e041, 1e042, 1e043, 1e044, 1e045, 1e046, 1e047, 1e048, 1e049,
00263 1e050, 1e051, 1e052, 1e053, 1e054, 1e055, 1e056, 1e057, 1e058, 1e059,
00264 1e060, 1e061, 1e062, 1e063, 1e064, 1e065, 1e066, 1e067, 1e068, 1e069,
00265 1e070, 1e071, 1e072, 1e073, 1e074, 1e075, 1e076, 1e077, 1e078, 1e079,
00266 1e080, 1e081, 1e082, 1e083, 1e084, 1e085, 1e086, 1e087, 1e088, 1e089,
00267 1e090, 1e091, 1e092, 1e093, 1e094, 1e095, 1e096, 1e097, 1e098, 1e099,
00268 1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109,
00269 1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119,
00270 1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129,
00271 1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139,
00272 1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149,
00273 1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159,
00274 1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169,
00275 1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179,
00276 1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189,
00277 1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199,
00278 1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209,
00279 1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219,
00280 1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229,
00281 1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239,
00282 1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249,
00283 1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259,
00284 1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269,
00285 1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279,
00286 1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289,
00287 1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299,
00288 1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308
00289 };
00290
00291 time_t server_start_time;
00292 time_t flush_status_time;
00293
00294 fs::path basedir(PREFIX);
00295 fs::path pid_file;
00296 fs::path secure_file_priv;
00297 fs::path plugin_dir;
00298 fs::path system_config_dir(SYSCONFDIR);
00299
00300 const char *opt_tc_log_file;
00301 const key_map key_map_empty(0);
00302 key_map key_map_full(0);
00303
00304 std::string drizzle_tmpdir;
00305 char *opt_drizzle_tmpdir= NULL;
00306
00308 const char *in_left_expr_name= "<left expr>";
00310 const char *in_additional_cond= "<IN COND>";
00311 const char *in_having_cond= "<IN HAVING>";
00312
00313
00314
00315 FILE *stderror_file=0;
00316
00317 drizzle_system_variables global_system_variables;
00318 drizzle_system_variables max_system_variables;
00319 global_counters current_global_counters;
00320
00321 DRIZZLED_API const charset_info_st *system_charset_info;
00322 const charset_info_st *files_charset_info;
00323 const charset_info_st *table_alias_charset;
00324 const charset_info_st *character_set_filesystem;
00325
00326 MY_LOCALE *my_default_lc_time_names;
00327
00328 SHOW_COMP_OPTION have_symlink;
00329
00330 boost::condition_variable_any COND_refresh;
00331 boost::condition_variable COND_thread_count;
00332 pthread_t signal_thread;
00333
00334
00335
00336 int cleanup_done;
00337
00338 passwd *user_info;
00339
00340 boost::detail::atomic_count connection_count(0);
00341
00342 global_buffer_constraint<uint64_t> global_sort_buffer(0);
00343 global_buffer_constraint<uint64_t> global_join_buffer(0);
00344 global_buffer_constraint<uint64_t> global_read_rnd_buffer(0);
00345 global_buffer_constraint<uint64_t> global_read_buffer(0);
00346
00347 DRIZZLED_API size_t transaction_message_threshold;
00348
00349 static void drizzle_init_variables();
00350 static void get_options();
00351 static void fix_paths();
00352
00353 void close_connections();
00354
00355 fs::path base_plugin_dir(PKGPLUGINDIR);
00356
00357 po::options_description general_options(_("General Options"));
00358 po::options_description config_options(_("Config File Options"));
00359 po::options_description long_options(_("Kernel Options"));
00360 po::options_description plugin_load_options(_("Plugin Loading Options"));
00361 po::options_description plugin_options(_("Plugin Options"));
00362 po::options_description initial_options(_("Config and Plugin Loading"));
00363 po::options_description full_options(_("Kernel and Plugin Loading and Plugin"));
00364 vector<string> unknown_options;
00365 vector<string> defaults_file_list;
00366 po::variables_map vm;
00367
00368 po::variables_map &getVariablesMap()
00369 {
00370 return vm;
00371 }
00372
00373 static std::string g_hostname= "localhost";
00374
00375 const std::string& getServerHostname()
00376 {
00377 return g_hostname;
00378 }
00379
00380 static void print_version()
00381 {
00382
00383
00384
00385
00386 printf("%s Ver %s for %s-%s on %s (%s)\n", internal::my_progname,
00387 PANDORA_RELEASE_VERSION, HOST_VENDOR, HOST_OS, HOST_CPU, COMPILATION_COMMENT);
00388 }
00389
00390
00391
00392
00393
00394 void close_connections()
00395 {
00396
00397 plugin::Listen::shutdown();
00398
00399
00400 {
00401 boost::mutex::scoped_lock scopedLock(session::Cache::mutex());
00402
00403 while (select_thread_in_use)
00404 {
00405 boost::xtime xt;
00406 xtime_get(&xt, boost::TIME_UTC);
00407 xt.sec += 2;
00408
00409 for (uint32_t tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
00410 {
00411 bool success= COND_thread_count.timed_wait(scopedLock, xt);
00412 if (not success)
00413 break;
00414 }
00415 }
00416 }
00417
00418
00419
00420
00421
00422
00423
00424
00425 {
00426 boost::mutex::scoped_lock scopedLock(session::Cache::mutex());
00427 session::Cache::list list= session::Cache::getCache();
00428
00429 BOOST_FOREACH(session::Cache::list::reference tmp, list)
00430 {
00431 tmp->setKilled(Session::KILL_CONNECTION);
00432 tmp->scheduler->killSession(tmp.get());
00433 DRIZZLE_CONNECTION_DONE(tmp->thread_id);
00434
00435 tmp->lockOnSys();
00436 }
00437 }
00438
00439 if (session::Cache::count())
00440 sleep(2);
00441
00442
00443
00444
00445
00446
00447 for (;;)
00448 {
00449 boost::mutex::scoped_lock scopedLock(session::Cache::mutex());
00450 session::Cache::list list= session::Cache::getCache();
00451
00452 if (list.empty())
00453 {
00454 break;
00455 }
00456
00457 list.front()->getClient()->close();
00458 }
00459 }
00460
00461 static bool unireg_startup_completed= false;
00462 void unireg_startup_finished()
00463 {
00464 unireg_startup_completed= true;
00465 }
00466
00467 void unireg_exit()
00468 {
00469 internal::my_end();
00470 assert(unireg_startup_completed == false);
00471 exit(EXIT_SUCCESS);
00472 }
00473
00474 void unireg_actual_abort(const char *file, int line, const char *func, const std::string& message)
00475 {
00476 std::stringstream temp;
00477 temp << _("Aborting:") << "\"" << message << "\"" << ". Abort was called from " << file << ":" << line << " in " << func << "()";
00478 errmsg_printf(error::ERROR, "%s", temp.str().c_str());
00479
00480 clean_up(vm.count("help") == 0);
00481 internal::my_end();
00482
00483 assert(unireg_startup_completed == false);
00484 exit(EXIT_FAILURE);
00485 }
00486
00487
00488 void clean_up(bool print_message)
00489 {
00490 if (cleanup_done++)
00491 return;
00492
00493 table_cache_free();
00494 free_charsets();
00495 module::Registry &modules= module::Registry::singleton();
00496 modules.shutdownModules();
00497
00498 deinit_temporal_formats();
00499
00500 #if GOOGLE_PROTOBUF_VERSION >= 2001000
00501 google::protobuf::ShutdownProtobufLibrary();
00502 #endif
00503
00504 (void) unlink(pid_file.file_string().c_str());
00505
00506 if (print_message && server_start_time)
00507 errmsg_printf(drizzled::error::INFO, _(ER(ER_SHUTDOWN_COMPLETE)),internal::my_progname);
00508
00509 session::Cache::shutdownFirst();
00510
00511
00512
00513
00514
00515 }
00516
00517
00518
00519
00520 passwd *check_user(const char *user)
00521 {
00522 passwd *tmp_user_info;
00523 uid_t user_id= geteuid();
00524
00525
00526 if (user_id)
00527 {
00528 if (user)
00529 {
00530
00531 tmp_user_info= getpwnam(user);
00532 if ((!tmp_user_info || user_id != tmp_user_info->pw_uid) &&
00533 global_system_variables.log_warnings)
00534 {
00535 errmsg_printf(error::WARN, _("One can only use the --user switch if running as root"));
00536 }
00537 }
00538 return NULL;
00539 }
00540 if (not user)
00541 {
00542 unireg_abort << _("drizzled cannot be run as root, use --user to start drizzled up as another user");
00543 }
00544
00545 if (not strcmp(user, "root"))
00546 {
00547 return NULL;
00548 }
00549
00550 if ((tmp_user_info= getpwnam(user)) == NULL)
00551 {
00552
00553 const char *pos= user;
00554 for (; my_charset_utf8_general_ci.isdigit(*pos); pos++)
00555 {
00556 }
00557 if (*pos)
00558 goto err;
00559
00560 if ((tmp_user_info= getpwuid(atoi(user))) == NULL)
00561 goto err;
00562 }
00563 return tmp_user_info;
00564
00565 err:
00566 unireg_abort << "Fatal error: Can't change to run as user '" << user << "' ; Please check that the user exists!";
00567
00568 #ifdef PR_SET_DUMPABLE
00569 if (getDebug().test(debug::CORE_ON_SIGNAL))
00570 {
00571
00572 (void) prctl(PR_SET_DUMPABLE, 1);
00573 }
00574 #endif
00575
00576 return NULL;
00577 }
00578
00579 void set_user(const char *user, passwd *user_info_arg)
00580 {
00581 assert(user_info_arg != 0);
00582 initgroups(user, user_info_arg->pw_gid);
00583 if (setgid(user_info_arg->pw_gid) == -1)
00584 {
00585 unireg_abort << _("Set process group ID failed ") << strerror(errno);
00586 }
00587 if (setuid(user_info_arg->pw_uid) == -1)
00588 {
00589 unireg_abort << _("Set process user ID failed") << strerror(errno);
00590 }
00591 }
00592
00593
00594
00596 static void set_root(const char *path)
00597 {
00598 if ((chroot(path) == -1) or chdir("/") == 0)
00599 {
00600 unireg_abort << _("Process chroot failed");
00601 }
00602 }
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613 void Session::unlink(session_id_t &session_id)
00614 {
00615 Session::shared_ptr session= session::Cache::find(session_id);
00616
00617 if (session)
00618 unlink(session);
00619 }
00620
00621 void Session::unlink(const Session::shared_ptr& session)
00622 {
00623 --connection_count;
00624
00625 session->cleanup();
00626
00627 boost::mutex::scoped_lock scopedLock(session::Cache::mutex());
00628
00629 if (unlikely(plugin::EventObserver::disconnectSession(*session)))
00630 {
00631
00632 }
00633 session::Cache::erase(session);
00634 }
00635
00636
00637 #ifndef SA_RESETHAND
00638 #define SA_RESETHAND 0
00639 #endif
00640 #ifndef SA_NODEFER
00641 #define SA_NODEFER 0
00642 #endif
00643
00644
00645
00646
00647 const char *load_default_groups[]=
00648 {
00649 DRIZZLE_CONFIG_NAME, "server", 0, 0
00650 };
00651
00652 static void find_plugin_dir(string progname)
00653 {
00654 fs::path full_progname(fs::system_complete(progname));
00655
00656 fs::path progdir(full_progname.parent_path());
00657 if (progdir.filename() == ".libs")
00658 {
00659 progdir= progdir.parent_path();
00660 }
00661
00662 if (fs::exists(progdir / "drizzled.lo") || fs::exists(progdir / "drizzled.o"))
00663 {
00664
00665 base_plugin_dir= progdir.parent_path();
00666 base_plugin_dir /= "plugin";
00667 base_plugin_dir /= ".libs";
00668 }
00669
00670 if (plugin_dir.root_directory() == "")
00671 {
00672 fs::path full_plugin_dir(fs::system_complete(base_plugin_dir));
00673 full_plugin_dir /= plugin_dir;
00674 plugin_dir= full_plugin_dir;
00675 }
00676 }
00677
00678 static void notify_plugin_dir(fs::path in_plugin_dir)
00679 {
00680 plugin_dir= in_plugin_dir;
00681 if (plugin_dir.root_directory() == "")
00682 {
00683 fs::path full_plugin_dir(fs::system_complete(basedir));
00684 full_plugin_dir /= plugin_dir;
00685 plugin_dir= full_plugin_dir;
00686 }
00687 }
00688
00689 static void expand_secure_file_priv(fs::path in_secure_file_priv)
00690 {
00691 secure_file_priv= fs::system_complete(in_secure_file_priv);
00692 }
00693
00694 static void check_limits_aii(uint64_t in_auto_increment_increment)
00695 {
00696 global_system_variables.auto_increment_increment= 1;
00697 if (in_auto_increment_increment < 1 || in_auto_increment_increment > UINT64_MAX)
00698 {
00699 unireg_abort << _("Invalid Value for auto_increment_increment");
00700 }
00701 global_system_variables.auto_increment_increment= in_auto_increment_increment;
00702 }
00703
00704 static void check_limits_aio(uint64_t in_auto_increment_offset)
00705 {
00706 global_system_variables.auto_increment_offset= 1;
00707 if (in_auto_increment_offset < 1 || in_auto_increment_offset > UINT64_MAX)
00708 {
00709 unireg_abort << _("Invalid Value for auto_increment_offset");
00710 }
00711 global_system_variables.auto_increment_offset= in_auto_increment_offset;
00712 }
00713
00714 static void check_limits_completion_type(uint32_t in_completion_type)
00715 {
00716 global_system_variables.completion_type= 0;
00717 if (in_completion_type > 2)
00718 {
00719 unireg_abort << _("Invalid Value for completion_type");
00720 }
00721 global_system_variables.completion_type= in_completion_type;
00722 }
00723
00724
00725 static void check_limits_dpi(uint32_t in_div_precincrement)
00726 {
00727 global_system_variables.div_precincrement= 4;
00728 if (in_div_precincrement > DECIMAL_MAX_SCALE)
00729 {
00730 unireg_abort << _("Invalid Value for div-precision-increment");
00731 }
00732 global_system_variables.div_precincrement= in_div_precincrement;
00733 }
00734
00735 static void check_limits_gcml(uint64_t in_group_concat_max_len)
00736 {
00737 global_system_variables.group_concat_max_len= 1024;
00738 if (in_group_concat_max_len > ULONG_MAX || in_group_concat_max_len < 4)
00739 {
00740 unireg_abort << _("Invalid Value for group_concat_max_len");
00741 }
00742 global_system_variables.group_concat_max_len= in_group_concat_max_len;
00743 }
00744
00745 static void check_limits_join_buffer_size(uint64_t in_join_buffer_size)
00746 {
00747 global_system_variables.join_buff_size= (128*1024L);
00748 if (in_join_buffer_size < IO_SIZE*2 || in_join_buffer_size > ULONG_MAX)
00749 {
00750 unireg_abort << _("Invalid Value for join_buffer_size");
00751 }
00752 in_join_buffer_size-= in_join_buffer_size % IO_SIZE;
00753 global_system_variables.join_buff_size= in_join_buffer_size;
00754 }
00755
00756 static void check_limits_map(uint32_t in_max_allowed_packet)
00757 {
00758 global_system_variables.max_allowed_packet= (64*1024*1024L);
00759 if (in_max_allowed_packet < 1024 || in_max_allowed_packet > 1024*1024L*1024L)
00760 {
00761 unireg_abort << _("Invalid Value for max_allowed_packet");
00762 }
00763 in_max_allowed_packet-= in_max_allowed_packet % 1024;
00764 global_system_variables.max_allowed_packet= in_max_allowed_packet;
00765 }
00766
00767 static void check_limits_max_err_cnt(uint64_t in_max_error_count)
00768 {
00769 global_system_variables.max_error_count= DEFAULT_ERROR_COUNT;
00770 if (in_max_error_count > 65535)
00771 {
00772 unireg_abort << _("Invalid Value for max_error_count");
00773 }
00774 global_system_variables.max_error_count= in_max_error_count;
00775 }
00776
00777 static void check_limits_mhts(uint64_t in_max_heap_table_size)
00778 {
00779 global_system_variables.max_heap_table_size= (16*1024*1024L);
00780 if (in_max_heap_table_size < 16384 || in_max_heap_table_size > MAX_MEM_TABLE_SIZE)
00781 {
00782 unireg_abort << _("Invalid Value for max_heap_table_size");
00783 }
00784 in_max_heap_table_size-= in_max_heap_table_size % 1024;
00785 global_system_variables.max_heap_table_size= in_max_heap_table_size;
00786 }
00787
00788 static void check_limits_merl(uint64_t in_min_examined_row_limit)
00789 {
00790 global_system_variables.min_examined_row_limit= 0;
00791 if (in_min_examined_row_limit > ULONG_MAX)
00792 {
00793 unireg_abort << _("Invalid Value for min_examined_row_limit");
00794 }
00795 global_system_variables.min_examined_row_limit= in_min_examined_row_limit;
00796 }
00797
00798 static void check_limits_max_join_size(ha_rows in_max_join_size)
00799 {
00800 global_system_variables.max_join_size= INT32_MAX;
00801 if ((uint64_t)in_max_join_size < 1 || (uint64_t)in_max_join_size > INT32_MAX)
00802 {
00803 unireg_abort << _("Invalid Value for max_join_size");
00804 }
00805 global_system_variables.max_join_size= in_max_join_size;
00806 }
00807
00808 static void check_limits_mlfsd(int64_t in_max_length_for_sort_data)
00809 {
00810 global_system_variables.max_length_for_sort_data= 1024;
00811 if (in_max_length_for_sort_data < 4 || in_max_length_for_sort_data > 8192*1024L)
00812 {
00813 unireg_abort << _("Invalid Value for max_length_for_sort_data");
00814 }
00815 global_system_variables.max_length_for_sort_data= in_max_length_for_sort_data;
00816 }
00817
00818 static void check_limits_msfk(uint64_t in_max_seeks_for_key)
00819 {
00820 global_system_variables.max_seeks_for_key= ULONG_MAX;
00821 if (in_max_seeks_for_key < 1 || in_max_seeks_for_key > ULONG_MAX)
00822 {
00823 unireg_abort << _("Invalid Value for max_seeks_for_key");
00824 }
00825 global_system_variables.max_seeks_for_key= in_max_seeks_for_key;
00826 }
00827
00828 static void check_limits_max_sort_length(size_t in_max_sort_length)
00829 {
00830 global_system_variables.max_sort_length= 1024;
00831 if ((int64_t)in_max_sort_length < 4 || (int64_t)in_max_sort_length > 8192*1024L)
00832 {
00833 unireg_abort << _("Invalid Value for max_sort_length");
00834 }
00835 global_system_variables.max_sort_length= in_max_sort_length;
00836 }
00837
00838 static void check_limits_osd(uint32_t in_optimizer_search_depth)
00839 {
00840 global_system_variables.optimizer_search_depth= 0;
00841 if (in_optimizer_search_depth > MAX_TABLES + 2)
00842 {
00843 unireg_abort << _("Invalid Value for optimizer_search_depth");
00844 }
00845 global_system_variables.optimizer_search_depth= in_optimizer_search_depth;
00846 }
00847
00848 static void check_limits_pbs(uint64_t in_preload_buff_size)
00849 {
00850 global_system_variables.preload_buff_size= (32*1024L);
00851 if (in_preload_buff_size < 1024 || in_preload_buff_size > 1024*1024*1024L)
00852 {
00853 unireg_abort << _("Invalid Value for preload_buff_size");
00854 }
00855 global_system_variables.preload_buff_size= in_preload_buff_size;
00856 }
00857
00858 static void check_limits_qabs(uint32_t in_query_alloc_block_size)
00859 {
00860 global_system_variables.query_alloc_block_size= QUERY_ALLOC_BLOCK_SIZE;
00861 if (in_query_alloc_block_size < 1024)
00862 {
00863 unireg_abort << _("Invalid Value for query_alloc_block_size");
00864 }
00865 in_query_alloc_block_size-= in_query_alloc_block_size % 1024;
00866 global_system_variables.query_alloc_block_size= in_query_alloc_block_size;
00867 }
00868
00869 static void check_limits_qps(uint32_t in_query_prealloc_size)
00870 {
00871 global_system_variables.query_prealloc_size= QUERY_ALLOC_PREALLOC_SIZE;
00872 if (in_query_prealloc_size < QUERY_ALLOC_PREALLOC_SIZE)
00873 {
00874 unireg_abort << _("Invalid Value for query_prealloc_size");
00875 }
00876 in_query_prealloc_size-= in_query_prealloc_size % 1024;
00877 global_system_variables.query_prealloc_size= in_query_prealloc_size;
00878 }
00879
00880 static void check_limits_rabs(size_t in_range_alloc_block_size)
00881 {
00882 global_system_variables.range_alloc_block_size= RANGE_ALLOC_BLOCK_SIZE;
00883 if (in_range_alloc_block_size < RANGE_ALLOC_BLOCK_SIZE)
00884 {
00885 unireg_abort << _("Invalid Value for range_alloc_block_size");
00886 }
00887 in_range_alloc_block_size-= in_range_alloc_block_size % 1024;
00888 global_system_variables.range_alloc_block_size= in_range_alloc_block_size;
00889 }
00890
00891 static void check_limits_read_buffer_size(int32_t in_read_buff_size)
00892 {
00893 global_system_variables.read_buff_size= (128*1024L);
00894 if (in_read_buff_size < IO_SIZE*2 || in_read_buff_size > INT32_MAX)
00895 {
00896 unireg_abort << _("Invalid Value for read_buff_size");
00897 }
00898 in_read_buff_size-= in_read_buff_size % IO_SIZE;
00899 global_system_variables.read_buff_size= in_read_buff_size;
00900 }
00901
00902 static void check_limits_read_rnd_buffer_size(uint32_t in_read_rnd_buff_size)
00903 {
00904 global_system_variables.read_rnd_buff_size= (256*1024L);
00905 if (in_read_rnd_buff_size < 64 || in_read_rnd_buff_size > UINT32_MAX)
00906 {
00907 unireg_abort << _("Invalid Value for read_rnd_buff_size");
00908 }
00909 global_system_variables.read_rnd_buff_size= in_read_rnd_buff_size;
00910 }
00911
00912 static void check_limits_sort_buffer_size(size_t in_sortbuff_size)
00913 {
00914 global_system_variables.sortbuff_size= MAX_SORT_MEMORY;
00915 if ((uint32_t)in_sortbuff_size < MIN_SORT_MEMORY)
00916 {
00917 unireg_abort << _("Invalid Value for sort_buff_size");
00918 }
00919 global_system_variables.sortbuff_size= in_sortbuff_size;
00920 }
00921
00922 static void check_limits_tdc(uint32_t in_table_def_size)
00923 {
00924 table_def_size= 128;
00925 if (in_table_def_size < 1 || in_table_def_size > 512*1024L)
00926 {
00927 unireg_abort << _("Invalid Value for table_def_size");
00928 }
00929 table_def_size= in_table_def_size;
00930 }
00931
00932 static void check_limits_toc(uint32_t in_table_cache_size)
00933 {
00934 table_cache_size= TABLE_OPEN_CACHE_DEFAULT;
00935 if (in_table_cache_size < TABLE_OPEN_CACHE_MIN || in_table_cache_size > 512*1024L)
00936 {
00937 unireg_abort << _("Invalid Value for table_cache_size");
00938 }
00939 table_cache_size= in_table_cache_size;
00940 }
00941
00942 static void check_limits_tlwt(uint64_t in_table_lock_wait_timeout)
00943 {
00944 table_lock_wait_timeout= 50;
00945 if (in_table_lock_wait_timeout < 1 || in_table_lock_wait_timeout > 1024*1024*1024)
00946 {
00947 unireg_abort << _("Invalid Value for table_lock_wait_timeout");
00948 }
00949 table_lock_wait_timeout= in_table_lock_wait_timeout;
00950 }
00951
00952 static void check_limits_thread_stack(uint32_t in_my_thread_stack_size)
00953 {
00954 my_thread_stack_size= in_my_thread_stack_size - (in_my_thread_stack_size % 1024);
00955 }
00956
00957 static void check_limits_tmp_table_size(uint64_t in_tmp_table_size)
00958 {
00959 global_system_variables.tmp_table_size= 16*1024*1024L;
00960 if (in_tmp_table_size < 1024 || in_tmp_table_size > MAX_MEM_TABLE_SIZE)
00961 {
00962 unireg_abort << _("Invalid Value for table_lock_wait_timeout");
00963 }
00964 global_system_variables.tmp_table_size= in_tmp_table_size;
00965 }
00966
00967 static void check_limits_transaction_message_threshold(size_t in_transaction_message_threshold)
00968 {
00969 transaction_message_threshold= 1024*1024;
00970 if ((int64_t) in_transaction_message_threshold < 128*1024 || (int64_t)in_transaction_message_threshold > 1024*1024)
00971 {
00972 unireg_abort << _("Invalid Value for transaction_message_threshold valid values are between 131072 - 1048576 bytes");
00973 }
00974 transaction_message_threshold= in_transaction_message_threshold;
00975 }
00976
00977 static void process_defaults_files()
00978 {
00979 BOOST_FOREACH(vector<string>::reference iter, defaults_file_list)
00980 {
00981 fs::path file_location= iter;
00982
00983 ifstream input_defaults_file(file_location.file_string().c_str());
00984
00985 po::parsed_options file_parsed= dpo::parse_config_file(input_defaults_file, full_options, true);
00986 vector<string> file_unknown= po::collect_unrecognized(file_parsed.options, po::include_positional);
00987
00988 for (vector<string>::iterator it= file_unknown.begin(); it != file_unknown.end(); ++it)
00989 {
00990 string new_unknown_opt("--" + *it);
00991 ++it;
00992 if (it == file_unknown.end())
00993 break;
00994 if (*it != "true")
00995 new_unknown_opt += "=" + *it;
00996 unknown_options.push_back(new_unknown_opt);
00997 }
00998 store(file_parsed, vm);
00999 }
01000 }
01001
01002 static void compose_defaults_file_list(const vector<string>& in_options)
01003 {
01004 BOOST_FOREACH(const string& it, in_options)
01005 {
01006 fs::path p(it);
01007 if (fs::is_regular_file(p))
01008 {
01009 defaults_file_list.push_back(it);
01010 }
01011 else
01012 {
01013 unireg_abort << "Defaults file '" << it << "' not found";
01014 }
01015 }
01016 }
01017
01018 bool init_variables_before_daemonizing(int argc, char **argv)
01019 {
01020 umask(((~internal::my_umask) & 0666));
01021 decimal_zero.set_zero();
01022 tzset();
01023
01024 time_t curr_time= time(NULL);
01025 if (curr_time == (time_t)-1)
01026 {
01027 return false;
01028 }
01029
01030 max_system_variables.pseudo_thread_id= UINT32_MAX;
01031 server_start_time= flush_status_time= curr_time;
01032
01033 drizzle_init_variables();
01034
01035 find_plugin_dir(argv[0]);
01036
01037 char ret_hostname[FN_REFLEN];
01038 if (gethostname(ret_hostname,sizeof(ret_hostname)) < 0)
01039 {
01040 errmsg_printf(error::WARN, _("gethostname failed, using '%s' as hostname"), getServerHostname().c_str());
01041 pid_file= "drizzle";
01042 }
01043 else
01044 {
01045 g_hostname= ret_hostname;
01046 pid_file= getServerHostname();
01047 }
01048 pid_file.replace_extension(".pid");
01049
01050 system_config_dir /= "drizzle";
01051
01052 general_options.add_options()
01053 ("help,?",
01054 _("Display help and exit."))
01055 ("daemon,d", po::value<bool>(&opt_daemon)->default_value(false)->zero_tokens(),
01056 _("Run as a daemon."))
01057 ("user,u", po::value<string>(),
01058 _("Run drizzled daemon as user."))
01059 ("version,V",
01060 _("Print version information and exit."))
01061 ;
01062
01063 config_options.add_options()
01064 ("no-defaults", po::value<bool>()->default_value(false)->zero_tokens(),
01065 _("Configuration file defaults are not used if no-defaults is set"))
01066 ("defaults-file", po::value<vector<string> >()->composing()->notifier(&compose_defaults_file_list),
01067 _("Configuration file to use"))
01068 ("config-dir", po::value<fs::path>(&system_config_dir),
01069 _("Base location for config files"))
01070 ("plugin-dir", po::value<fs::path>(&plugin_dir)->notifier(¬ify_plugin_dir),
01071 _("Directory for plugins."))
01072 ;
01073
01074 plugin_load_options.add_options()
01075 ("plugin-add", po::value<vector<string> >()->composing()->notifier(&compose_plugin_add),
01076 _("Optional comma separated list of plugins to load at startup in addition "
01077 "to the default list of plugins. "
01078 "[for example: --plugin_add=crc32,logger_gearman]"))
01079 ("plugin-remove", po::value<vector<string> >()->composing()->notifier(&compose_plugin_remove),
01080 _("Optional comma separated list of plugins to not load at startup. Effectively "
01081 "removes a plugin from the list of plugins to be loaded. "
01082 "[for example: --plugin_remove=crc32,logger_gearman]"))
01083 ("plugin-load", po::value<string>()->notifier(¬ify_plugin_load)->default_value(PANDORA_PLUGIN_LIST),
01084 _("Optional comma separated list of plugins to load at starup instead of "
01085 "the default plugin load list. "
01086 "[for example: --plugin_load=crc32,logger_gearman]"))
01087 ;
01088
01089 long_options.add_options()
01090 ("auto-increment-increment", po::value<uint64_t>(&global_system_variables.auto_increment_increment)->default_value(1)->notifier(&check_limits_aii),
01091 _("Auto-increment columns are incremented by this"))
01092 ("auto-increment-offset", po::value<uint64_t>(&global_system_variables.auto_increment_offset)->default_value(1)->notifier(&check_limits_aio),
01093 _("Offset added to Auto-increment columns. Used when auto-increment-increment != 1"))
01094 ("basedir,b", po::value<fs::path>(&basedir),
01095 _("Path to installation directory. All paths are usually resolved "
01096 "relative to this."))
01097 ("chroot,r", po::value<string>(),
01098 _("Chroot drizzled daemon during startup."))
01099 ("collation-server", po::value<string>(),
01100 _("Set the default collation."))
01101 ("completion-type", po::value<uint32_t>(&global_system_variables.completion_type)->default_value(0)->notifier(&check_limits_completion_type),
01102 _("Default completion type."))
01103 ("core-file", _("Write core on errors."))
01104 ("datadir", po::value<fs::path>(&getMutableDataHome()),
01105 _("Path to the database root."))
01106 ("default-storage-engine", po::value<string>(),
01107 _("Set the default storage engine for tables."))
01108 ("default-time-zone", po::value<string>(),
01109 _("Set the default time zone."))
01110 ("exit-info,T", po::value<long>(),
01111 _("Used for debugging; Use at your own risk!"))
01112 ("gdb", po::value<bool>(&opt_debugging)->default_value(false)->zero_tokens(),
01113 _("Set up signals usable for debugging"))
01114 ("lc-time-name", po::value<string>(),
01115 _("Set the language used for the month names and the days of the week."))
01116 ("log-warnings,W", po::value<bool>(&global_system_variables.log_warnings)->default_value(false)->zero_tokens(),
01117 _("Log some not critical warnings to the log file."))
01118 ("pid-file", po::value<fs::path>(&pid_file),
01119 _("Pid file used by drizzled."))
01120 ("port-open-timeout", po::value<uint32_t>(&drizzled_bind_timeout)->default_value(0),
01121 _("Maximum time in seconds to wait for the port to become free. "))
01122 ("replicate-query", po::value<bool>(&global_system_variables.replicate_query)->default_value(false)->zero_tokens(),
01123 _("Include the SQL query in replicated protobuf messages."))
01124 ("secure-file-priv", po::value<fs::path>(&secure_file_priv)->notifier(expand_secure_file_priv),
01125 _("Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
01126 "within specified directory"))
01127 ("server-id", po::value<uint32_t>(&server_id)->default_value(0),
01128 _("Uniquely identifies the server instance in the community of "
01129 "replication partners."))
01130 ("skip-stack-trace",
01131 _("Don't print a stack trace on failure."))
01132 ("symbolic-links,s", po::value<bool>(&internal::my_use_symdir)->default_value(IF_PURIFY(false,true))->zero_tokens(),
01133 _("Enable symbolic link support."))
01134 ("timed-mutexes", po::value<bool>(&internal::timed_mutexes)->default_value(false)->zero_tokens(),
01135 _("Specify whether to time mutexes (only InnoDB mutexes are currently "
01136 "supported)"))
01137 ("tmpdir,t", po::value<string>(),
01138 _("Path for temporary files."))
01139 ("transaction-isolation", po::value<string>(),
01140 _("Default transaction isolation level."))
01141 ("transaction-message-threshold", po::value<size_t>(&transaction_message_threshold)->default_value(1024*1024)->notifier(&check_limits_transaction_message_threshold),
01142 _("Max message size written to transaction log, valid values 131072 - 1048576 bytes."))
01143 ("back-log", po::value<back_log_constraints>(&back_log),
01144 _("The number of outstanding connection requests Drizzle can have. This "
01145 "comes into play when the main Drizzle thread gets very many connection "
01146 "requests in a very short time."))
01147 ("bulk-insert-buffer-size",
01148 po::value<uint64_t>(&global_system_variables.bulk_insert_buff_size)->default_value(8192*1024),
01149 _("Size of tree cache used in bulk insert optimization. Note that this is "
01150 "a limit per thread!"))
01151 ("div-precision-increment", po::value<uint32_t>(&global_system_variables.div_precincrement)->default_value(4)->notifier(&check_limits_dpi),
01152 _("Precision of the result of '/' operator will be increased on that "
01153 "value."))
01154 ("group-concat-max-len", po::value<uint64_t>(&global_system_variables.group_concat_max_len)->default_value(1024)->notifier(&check_limits_gcml),
01155 _("The maximum length of the result of function group_concat."))
01156 ("join-buffer-size", po::value<uint64_t>(&global_system_variables.join_buff_size)->default_value(128*1024L)->notifier(&check_limits_join_buffer_size),
01157 _("The size of the buffer that is used for full joins."))
01158 ("join-heap-threshold",
01159 po::value<uint64_t>()->default_value(0),
01160 _("A global cap on the amount of memory that can be allocated by session join buffers (0 means unlimited)"))
01161 ("max-allowed-packet", po::value<uint32_t>(&global_system_variables.max_allowed_packet)->default_value(64*1024*1024L)->notifier(&check_limits_map),
01162 _("Max packetlength to send/receive from to server."))
01163 ("max-error-count", po::value<uint64_t>(&global_system_variables.max_error_count)->default_value(DEFAULT_ERROR_COUNT)->notifier(&check_limits_max_err_cnt),
01164 _("Max number of errors/warnings to store for a statement."))
01165 ("max-heap-table-size", po::value<uint64_t>(&global_system_variables.max_heap_table_size)->default_value(16*1024*1024L)->notifier(&check_limits_mhts),
01166 _("Don't allow creation of heap tables bigger than this."))
01167 ("max-join-size", po::value<ha_rows>(&global_system_variables.max_join_size)->default_value(INT32_MAX)->notifier(&check_limits_max_join_size),
01168 _("Joins that are probably going to read more than max_join_size records "
01169 "return an error."))
01170 ("max-length-for-sort-data", po::value<uint64_t>(&global_system_variables.max_length_for_sort_data)->default_value(1024)->notifier(&check_limits_mlfsd),
01171 _("Max number of bytes in sorted records."))
01172 ("max-seeks-for-key", po::value<uint64_t>(&global_system_variables.max_seeks_for_key)->default_value(ULONG_MAX)->notifier(&check_limits_msfk),
01173 _("Limit assumed max number of seeks when looking up rows based on a key"))
01174 ("max-sort-length", po::value<size_t>(&global_system_variables.max_sort_length)->default_value(1024)->notifier(&check_limits_max_sort_length),
01175 _("The number of bytes to use when sorting BLOB or TEXT values "
01176 "(only the first max_sort_length bytes of each value are used; the "
01177 "rest are ignored)."))
01178 ("max-write-lock-count", po::value<uint64_t>(&max_write_lock_count)->default_value(UINT64_MAX),
01179 _("After this many write locks, allow some read locks to run in between."))
01180 ("min-examined-row-limit", po::value<uint64_t>(&global_system_variables.min_examined_row_limit)->default_value(0)->notifier(&check_limits_merl),
01181 _("Don't log queries which examine less than min_examined_row_limit "
01182 "rows to file."))
01183 ("disable-optimizer-prune",
01184 _("Do not apply any heuristic(s) during query optimization to prune, "
01185 "thus perform an exhaustive search from the optimizer search space."))
01186 ("optimizer-search-depth", po::value<uint32_t>(&global_system_variables.optimizer_search_depth)->default_value(0)->notifier(&check_limits_osd),
01187 _("Maximum depth of search performed by the query optimizer. Values "
01188 "larger than the number of relations in a query result in better query "
01189 "plans, but take longer to compile a query. Smaller values than the "
01190 "number of tables in a relation result in faster optimization, but may "
01191 "produce very bad query plans. If set to 0, the system will "
01192 "automatically pick a reasonable value; if set to MAX_TABLES+2, the "
01193 "optimizer will switch to the original find_best (used for "
01194 "testing/comparison)."))
01195 ("preload-buffer-size", po::value<uint64_t>(&global_system_variables.preload_buff_size)->default_value(32*1024L)->notifier(&check_limits_pbs),
01196 _("The size of the buffer that is allocated when preloading indexes"))
01197 ("query-alloc-block-size",
01198 po::value<uint32_t>(&global_system_variables.query_alloc_block_size)->default_value(QUERY_ALLOC_BLOCK_SIZE)->notifier(&check_limits_qabs),
01199 _("Allocation block size for query parsing and execution"))
01200 ("query-prealloc-size",
01201 po::value<uint32_t>(&global_system_variables.query_prealloc_size)->default_value(QUERY_ALLOC_PREALLOC_SIZE)->notifier(&check_limits_qps),
01202 _("Persistent buffer for query parsing and execution"))
01203 ("range-alloc-block-size",
01204 po::value<size_t>(&global_system_variables.range_alloc_block_size)->default_value(RANGE_ALLOC_BLOCK_SIZE)->notifier(&check_limits_rabs),
01205 _("Allocation block size for storing ranges during optimization"))
01206 ("read-buffer-size",
01207 po::value<uint32_t>(&global_system_variables.read_buff_size)->default_value(128*1024L)->notifier(&check_limits_read_buffer_size),
01208 _("Each thread that does a sequential scan allocates a buffer of this "
01209 "size for each table it scans. If you do many sequential scans, you may "
01210 "want to increase this value."))
01211 ("read-buffer-threshold",
01212 po::value<uint64_t>()->default_value(0),
01213 _("A global cap on the size of read-buffer-size (0 means unlimited)"))
01214 ("read-rnd-buffer-size",
01215 po::value<uint32_t>(&global_system_variables.read_rnd_buff_size)->default_value(256*1024L)->notifier(&check_limits_read_rnd_buffer_size),
01216 _("When reading rows in sorted order after a sort, the rows are read "
01217 "through this buffer to avoid a disk seeks. If not set, then it's set "
01218 "to the value of record_buffer."))
01219 ("read-rnd-threshold",
01220 po::value<uint64_t>()->default_value(0),
01221 _("A global cap on the size of read-rnd-buffer-size (0 means unlimited)"))
01222 ("scheduler", po::value<string>(),
01223 _("Select scheduler to be used (by default multi-thread)."))
01224 ("sort-buffer-size",
01225 po::value<size_t>(&global_system_variables.sortbuff_size)->default_value(MAX_SORT_MEMORY)->notifier(&check_limits_sort_buffer_size),
01226 _("Each thread that needs to do a sort allocates a buffer of this size."))
01227 ("sort-heap-threshold",
01228 po::value<uint64_t>()->default_value(0),
01229 _("A global cap on the amount of memory that can be allocated by session sort buffers (0 means unlimited)"))
01230 ("table-definition-cache", po::value<size_t>(&table_def_size)->default_value(128)->notifier(&check_limits_tdc),
01231 _("The number of cached table definitions."))
01232 ("table-open-cache", po::value<uint64_t>(&table_cache_size)->default_value(TABLE_OPEN_CACHE_DEFAULT)->notifier(&check_limits_toc),
01233 _("The number of cached open tables."))
01234 ("table-lock-wait-timeout", po::value<uint64_t>(&table_lock_wait_timeout)->default_value(50)->notifier(&check_limits_tlwt),
01235 _("Timeout in seconds to wait for a table level lock before returning an "
01236 "error. Used only if the connection has active cursors."))
01237 ("thread-stack", po::value<size_t>(&my_thread_stack_size)->default_value(0)->notifier(&check_limits_thread_stack),
01238 _("The stack size for each thread."))
01239 ("tmp-table-size",
01240 po::value<uint64_t>(&global_system_variables.tmp_table_size)->default_value(16*1024*1024L)->notifier(&check_limits_tmp_table_size),
01241 _("If an internal in-memory temporary table exceeds this size, Drizzle will"
01242 " automatically convert it to an on-disk MyISAM table."))
01243 ("verbose", po::value<std::string>()->default_value(error::verbose_string())->notifier(&error::check_verbosity),
01244 _("The verbosity of messages from drizzled. Possible values are INSPECT, INFO, WARN or ERROR"))
01245 ;
01246
01247 full_options.add(long_options);
01248 full_options.add(plugin_load_options);
01249
01250 initial_options.add(general_options);
01251 initial_options.add(config_options);
01252 initial_options.add(plugin_load_options);
01253
01254 int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
01255
01256
01257 po::parsed_options parsed= po::command_line_parser(argc, argv).style(style).
01258 options(initial_options).allow_unregistered().run();
01259
01260 unknown_options= po::collect_unrecognized(parsed.options, po::include_positional);
01261
01262 try
01263 {
01264 po::store(parsed, vm);
01265 }
01266 catch (std::exception&)
01267 {
01268 unireg_abort << _("Duplicate entry for command line option");
01269 }
01270
01271
01272
01273
01274 try
01275 {
01276 po::notify(vm);
01277 }
01278 catch (po::validation_error &err)
01279 {
01280 unireg_abort << "Use --help to get a list of available options. " << err.what();
01281 }
01282
01283 if (vm.count("version"))
01284 {
01285 print_version();
01286 unireg_exit();
01287 }
01288
01289 if (vm.count("no-defaults"))
01290 {
01291 fs::path system_config_file_drizzle(system_config_dir);
01292 system_config_file_drizzle /= "drizzled.cnf";
01293 defaults_file_list.insert(defaults_file_list.begin(), system_config_file_drizzle.file_string());
01294
01295 fs::path config_conf_d_location(system_config_dir);
01296 config_conf_d_location /= "conf.d";
01297
01298 CachedDirectory config_conf_d(config_conf_d_location.file_string());
01299 if (not config_conf_d.fail())
01300 {
01301 BOOST_FOREACH(CachedDirectory::Entries::const_reference iter, config_conf_d.getEntries())
01302 {
01303 string file_entry(iter->filename);
01304 if (not file_entry.empty() && file_entry != "." && file_entry != "..")
01305 defaults_file_list.push_back((config_conf_d_location / file_entry).file_string());
01306 }
01307 }
01308 }
01309
01310 process_defaults_files();
01311
01312
01313
01314
01315 try
01316 {
01317 po::notify(vm);
01318 }
01319 catch (po::validation_error &err)
01320 {
01321 unireg_abort << "Use --help to get a list of available options. " << err.what();
01322 }
01323
01324 return true;
01325 }
01326
01327
01328
01329 bool init_variables_after_daemonizing(module::Registry &plugins)
01330 {
01331 int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
01332
01333 current_pid= getpid();
01334
01335
01336
01337
01338
01339 if (plugin_init(plugins, plugin_options))
01340 {
01341 unireg_abort << _("Failed to initialize plugins");
01342 }
01343
01344 full_options.add(plugin_options);
01345
01346 vector<string> final_unknown_options;
01347 try
01348 {
01349 po::parsed_options final_parsed=
01350 po::command_line_parser(unknown_options).style(style).
01351 options(full_options).extra_parser(dpo::parse_size_arg).run();
01352
01353 final_unknown_options=
01354 po::collect_unrecognized(final_parsed.options, po::include_positional);
01355
01356 po::store(final_parsed, vm);
01357
01358 }
01359 catch (po::validation_error &err)
01360 {
01361 unireg_abort << "Use --help to get a list of available options. " << err.what();
01362 }
01363 catch (po::invalid_command_line_syntax &err)
01364 {
01365 unireg_abort << "Use --help to get a list of available options. " << err.what();
01366 }
01367 catch (po::unknown_option &err)
01368 {
01369 unireg_abort << "Use --help to get a list of available options. " << err.what();
01370 }
01371
01372 try
01373 {
01374 po::notify(vm);
01375 }
01376 catch (po::validation_error &err)
01377 {
01378 unireg_abort << "Use --help to get a list of available options. " << err.what();
01379 }
01380
01381 get_options();
01382
01383
01384
01385 global_system_variables.optimizer_prune_level= not vm.count("disable-optimizer-prune");
01386
01387 if ((user_info= check_user(drizzled_user)))
01388 {
01389 set_user(drizzled_user, user_info);
01390 }
01391
01392 fix_paths();
01393
01394 init_time();
01395
01396 item_create_init();
01397 if (sys_var_init())
01398 {
01399 return false;
01400 }
01401
01402
01403 if (not init_temporal_formats())
01404 {
01405 return false;
01406 }
01407
01408 if (!(default_charset_info= get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)))
01409 {
01410 errmsg_printf(error::ERROR, _("Error getting default charset"));
01411 return false;
01412 }
01413
01414 if (vm.count("scheduler"))
01415 {
01416 opt_scheduler= vm["scheduler"].as<string>().c_str();
01417 }
01418
01419
01420 global_system_variables.collation_server= default_charset_info;
01421
01422 if (not (character_set_filesystem= get_charset_by_csname("binary", MY_CS_PRIMARY)))
01423 {
01424 errmsg_printf(error::ERROR, _("Error setting collation"));
01425 return false;
01426 }
01427 global_system_variables.character_set_filesystem= character_set_filesystem;
01428
01429 if ((my_default_lc_time_names= my_locale_by_name(lc_time_names_name)) == NULL)
01430 {
01431 errmsg_printf(error::ERROR, _("Unknown locale: '%s'"), lc_time_names_name);
01432 return false;
01433 }
01434 global_system_variables.lc_time_names= my_default_lc_time_names;
01435
01436
01437 table_alias_charset= files_charset_info;
01438
01439 return true;
01440 }
01441
01442 bool was_help_requested()
01443 {
01444 return bool(vm.count("help"));
01445 }
01446
01447 void usage();
01448
01449 void init_server_components(module::Registry &plugins)
01450 {
01451 if (was_help_requested())
01452 {
01453 usage();
01454 }
01455
01456
01457
01458
01459
01460
01461
01462 table::Cache::rehash(table_def_size);
01463 definition::Cache::rehash(table_def_size);
01464 message::Cache::singleton().rehash(table_def_size);
01465
01466 setup_fpu();
01467
01468
01469 ha_init_errors();
01470
01471 if (plugin_finalize(plugins))
01472 {
01473 unireg_abort << "plugin_finalize() failed";
01474 }
01475
01476 if (plugin::Scheduler::setPlugin(opt_scheduler))
01477 {
01478 unireg_abort << _("No scheduler found");
01479 }
01480
01481
01482
01483
01484
01485 myisam_engine= plugin::StorageEngine::findByName("MyISAM");
01486 heap_engine= plugin::StorageEngine::findByName("MEMORY");
01487
01488
01489
01490
01491 if (default_storage_engine_str)
01492 {
01493 plugin::StorageEngine *engine= plugin::StorageEngine::findByName(default_storage_engine_str);
01494 if (engine == NULL)
01495 {
01496 unireg_abort << _("Unknown/unsupported storage engine: ") << default_storage_engine_str;
01497 }
01498 global_system_variables.storage_engine= engine;
01499 }
01500
01501 if (plugin::XaResourceManager::recoverAllXids())
01502 {
01503
01504 unireg_abort << "plugin::XaResourceManager::recoverAllXids() failed";
01505 }
01506
01507 init_update_queries();
01508 }
01509
01510
01511
01512
01513
01514
01515 enum options_drizzled
01516 {
01517 OPT_SOCKET=256,
01518 OPT_BIND_ADDRESS,
01519 OPT_PID_FILE,
01520 OPT_STORAGE_ENGINE,
01521 OPT_INIT_FILE,
01522 OPT_WANT_CORE,
01523 OPT_MEMLOCK,
01524 OPT_SERVER_ID,
01525 OPT_TC_HEURISTIC_RECOVER,
01526 OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE,
01527 OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
01528 OPT_DO_PSTACK,
01529 OPT_LOCAL_INFILE,
01530 OPT_BACK_LOG,
01531 OPT_JOIN_BUFF_SIZE,
01532 OPT_MAX_ALLOWED_PACKET,
01533 OPT_MAX_HEP_TABLE_SIZE,
01534 OPT_MAX_JOIN_SIZE,
01535 OPT_MAX_SORT_LENGTH,
01536 OPT_MAX_SEEKS_FOR_KEY, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS,
01537 OPT_MAX_LENGTH_FOR_SORT_DATA,
01538 OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE,
01539 OPT_MAX_ERROR_COUNT, OPT_MULTI_RANGE_COUNT, OPT_MYISAM_DATA_POINTER_SIZE,
01540 OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
01541 OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
01542 OPT_MYISAM_USE_MMAP, OPT_MYISAM_REPAIR_THREADS,
01543 OPT_NET_BUFFER_LENGTH,
01544 OPT_PRELOAD_BUFFER_SIZE,
01545 OPT_RECORD_BUFFER,
01546 OPT_RECORD_RND_BUFFER, OPT_DIV_PRECINCREMENT,
01547 OPT_DEBUGGING,
01548 OPT_SORT_BUFFER, OPT_TABLE_OPEN_CACHE, OPT_TABLE_DEF_CACHE,
01549 OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK,
01550 OPT_WAIT_TIMEOUT,
01551 OPT_RANGE_ALLOC_BLOCK_SIZE,
01552 OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE,
01553 OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE,
01554 OPT_OLD_ALTER_TABLE,
01555 OPT_GROUP_CONCAT_MAX_LEN,
01556 OPT_DEFAULT_COLLATION,
01557 OPT_CHARACTER_SET_FILESYSTEM,
01558 OPT_LC_TIME_NAMES,
01559 OPT_INIT_CONNECT,
01560 OPT_DEFAULT_TIME_ZONE,
01561 OPT_OPTIMIZER_SEARCH_DEPTH,
01562 OPT_SCHEDULER,
01563 OPT_PROTOCOL,
01564 OPT_OPTIMIZER_PRUNE_LEVEL,
01565 OPT_AUTO_INCREMENT, OPT_AUTO_INCREMENT_OFFSET,
01566 OPT_ENABLE_LARGE_PAGES,
01567 OPT_TIMED_MUTEXES,
01568 OPT_TABLE_LOCK_WAIT_TIMEOUT,
01569 OPT_PLUGIN_ADD,
01570 OPT_PLUGIN_REMOVE,
01571 OPT_PLUGIN_LOAD,
01572 OPT_PLUGIN_DIR,
01573 OPT_PORT_OPEN_TIMEOUT,
01574 OPT_SECURE_FILE_PRIV,
01575 OPT_MIN_EXAMINED_ROW_LIMIT,
01576 OPT_PRINT_DEFAULTS
01577 };
01578
01579
01580 struct option my_long_options[] =
01581 {
01582 {"auto-increment-increment", OPT_AUTO_INCREMENT,
01583 N_("Auto-increment columns are incremented by this"),
01584 (char**) &global_system_variables.auto_increment_increment,
01585 NULL, 0, GET_ULL,
01586 OPT_ARG, 1, 1, INT64_MAX, 0, 1, 0 },
01587 {"auto-increment-offset", OPT_AUTO_INCREMENT_OFFSET,
01588 N_("Offset added to Auto-increment columns. Used when "
01589 "auto-increment-increment != 1"),
01590 (char**) &global_system_variables.auto_increment_offset,
01591 NULL, 0, GET_ULL, OPT_ARG,
01592 1, 1, INT64_MAX, 0, 1, 0 },
01593 {"basedir", 'b',
01594 N_("Path to installation directory. All paths are usually resolved "
01595 "relative to this."),
01596 NULL, NULL, 0, GET_STR, REQUIRED_ARG,
01597 0, 0, 0, 0, 0, 0},
01598 {"chroot", 'r',
01599 N_("Chroot drizzled daemon during startup."),
01600 (char**) &drizzled_chroot, NULL, 0, GET_STR, REQUIRED_ARG,
01601 0, 0, 0, 0, 0, 0},
01602 {"completion-type", OPT_COMPLETION_TYPE,
01603 N_("Default completion type."),
01604 (char**) &global_system_variables.completion_type,
01605 NULL, 0, GET_UINT,
01606 REQUIRED_ARG, 0, 0, 2, 0, 1, 0},
01607 {"core-file", OPT_WANT_CORE,
01608 N_("Write core on errors."),
01609 0, 0, 0, GET_NO_ARG,
01610 NO_ARG, 0, 0, 0, 0, 0, 0},
01611 {"datadir", 'h',
01612 N_("Path to the database root."),
01613 NULL, NULL, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
01614
01615 {"exit-info", 'T',
01616 N_("Used for debugging; Use at your own risk!"),
01617 0, 0, 0, GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
01618
01619
01620 {"gdb", OPT_DEBUGGING,
01621 N_("Set up signals usable for debugging"),
01622 (char**) &opt_debugging, NULL,
01623 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
01624 {"log-warnings", 'W',
01625 N_("Log some not critical warnings to the log file."),
01626 (char**) &global_system_variables.log_warnings,
01627 NULL, 0, GET_BOOL, OPT_ARG, 1, 0, 0,
01628 0, 0, 0},
01629 {"pid-file", OPT_PID_FILE,
01630 N_("Pid file used by drizzled."),
01631 NULL, NULL, 0, GET_STR,
01632 REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
01633 {"port-open-timeout", OPT_PORT_OPEN_TIMEOUT,
01634 N_("Maximum time in seconds to wait for the port to become free. "
01635 "(Default: no wait)"),
01636 (char**) &drizzled_bind_timeout,
01637 NULL, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
01638 {"secure-file-priv", OPT_SECURE_FILE_PRIV,
01639 N_("Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
01640 "within specified directory"),
01641 NULL, NULL, 0,
01642 GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
01643 {"server-id", OPT_SERVER_ID,
01644 N_("Uniquely identifies the server instance in the community of "
01645 "replication partners."),
01646 (char**) &server_id, NULL, 0, GET_UINT32, REQUIRED_ARG, 0, 0, 0,
01647 0, 0, 0},
01648 {"skip-stack-trace", OPT_SKIP_STACK_TRACE,
01649 N_("Don't print a stack trace on failure."),
01650 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
01651 0, 0, 0, 0},
01652 {"symbolic-links", 's',
01653 N_("Enable symbolic link support."),
01654 (char**) &internal::my_use_symdir, NULL, 0, GET_BOOL, NO_ARG,
01655
01656
01657
01658
01659
01660 IF_PURIFY(0,1), 0, 0, 0, 0, 0},
01661 {"timed_mutexes", OPT_TIMED_MUTEXES,
01662 N_("Specify whether to time mutexes (only InnoDB mutexes are currently "
01663 "supported)"),
01664 (char**) &internal::timed_mutexes, NULL, 0, GET_BOOL, NO_ARG, 0,
01665 0, 0, 0, 0, 0},
01666 {"transaction-isolation", OPT_TX_ISOLATION,
01667 N_("Default transaction isolation level."),
01668 0, 0, 0, GET_STR, REQUIRED_ARG, 0,
01669 0, 0, 0, 0, 0},
01670 {"user", 'u',
01671 N_("Run drizzled daemon as user."),
01672 0, 0, 0, GET_STR, REQUIRED_ARG,
01673 0, 0, 0, 0, 0, 0},
01674 {"back_log", OPT_BACK_LOG,
01675 N_("The number of outstanding connection requests Drizzle can have. This "
01676 "comes into play when the main Drizzle thread gets very many connection "
01677 "requests in a very short time."),
01678 (char**) &back_log, NULL, 0, GET_UINT,
01679 REQUIRED_ARG, 50, 1, 65535, 0, 1, 0 },
01680 { "bulk_insert_buffer_size", OPT_BULK_INSERT_BUFFER_SIZE,
01681 N_("Size of tree cache used in bulk insert optimization. Note that this is "
01682 "a limit per thread!"),
01683 (char**) &global_system_variables.bulk_insert_buff_size,
01684 NULL,
01685 0, GET_ULL, REQUIRED_ARG, 8192*1024, 0, ULONG_MAX, 0, 1, 0},
01686 { "div_precision_increment", OPT_DIV_PRECINCREMENT,
01687 N_("Precision of the result of '/' operator will be increased on that "
01688 "value."),
01689 (char**) &global_system_variables.div_precincrement,
01690 NULL, 0, GET_UINT,
01691 REQUIRED_ARG, 4, 0, DECIMAL_MAX_SCALE, 0, 0, 0},
01692 { "join_buffer_size", OPT_JOIN_BUFF_SIZE,
01693 N_("The size of the buffer that is used for full joins."),
01694 (char**) &global_system_variables.join_buff_size,
01695 NULL, 0, GET_UINT64,
01696 REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ULONG_MAX,
01697 MALLOC_OVERHEAD, IO_SIZE, 0},
01698 {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
01699 N_("Max packetlength to send/receive from to server."),
01700 (char**) &global_system_variables.max_allowed_packet,
01701 NULL, 0, GET_UINT32,
01702 REQUIRED_ARG, 64*1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
01703 {"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE,
01704 N_("Don't allow creation of heap tables bigger than this."),
01705 (char**) &global_system_variables.max_heap_table_size,
01706 NULL, 0, GET_ULL,
01707 REQUIRED_ARG, 16*1024*1024L, 16384, (int64_t)MAX_MEM_TABLE_SIZE,
01708 MALLOC_OVERHEAD, 1024, 0},
01709 {"max_join_size", OPT_MAX_JOIN_SIZE,
01710 N_("Joins that are probably going to read more than max_join_size records "
01711 "return an error."),
01712 (char**) &global_system_variables.max_join_size,
01713 NULL, 0, GET_HA_ROWS, REQUIRED_ARG,
01714 INT32_MAX, 1, INT32_MAX, 0, 1, 0},
01715 {"max_length_for_sort_data", OPT_MAX_LENGTH_FOR_SORT_DATA,
01716 N_("Max number of bytes in sorted records."),
01717 (char**) &global_system_variables.max_length_for_sort_data,
01718 NULL, 0, GET_ULL,
01719 REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
01720 { "max_seeks_for_key", OPT_MAX_SEEKS_FOR_KEY,
01721 N_("Limit assumed max number of seeks when looking up rows based on a key"),
01722 (char**) &global_system_variables.max_seeks_for_key,
01723 NULL, 0, GET_UINT64,
01724 REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0 },
01725 {"max_sort_length", OPT_MAX_SORT_LENGTH,
01726 N_("The number of bytes to use when sorting BLOB or TEXT values "
01727 "(only the first max_sort_length bytes of each value are used; the "
01728 "rest are ignored)."),
01729 (char**) &global_system_variables.max_sort_length,
01730 NULL, 0, GET_SIZE,
01731 REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
01732 {"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
01733 N_("After this many write locks, allow some read locks to run in between."),
01734 (char**) &max_write_lock_count, NULL, 0, GET_ULL,
01735 REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0},
01736 {"min_examined_row_limit", OPT_MIN_EXAMINED_ROW_LIMIT,
01737 N_("Don't log queries which examine less than min_examined_row_limit "
01738 "rows to file."),
01739 (char**) &global_system_variables.min_examined_row_limit,
01740 NULL, 0, GET_ULL,
01741 REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1L, 0},
01742 {"optimizer_prune_level", OPT_OPTIMIZER_PRUNE_LEVEL,
01743 N_("Controls the heuristic(s) applied during query optimization to prune "
01744 "less-promising partial plans from the optimizer search space. Meaning: "
01745 "false - do not apply any heuristic, thus perform exhaustive search; "
01746 "true - prune plans based on number of retrieved rows."),
01747 (char**) &global_system_variables.optimizer_prune_level,
01748 NULL,
01749 0, GET_BOOL, OPT_ARG, 1, 0, 1, 0, 1, 0},
01750 {"optimizer_search_depth", OPT_OPTIMIZER_SEARCH_DEPTH,
01751 N_("Maximum depth of search performed by the query optimizer. Values "
01752 "larger than the number of relations in a query result in better query "
01753 "plans, but take longer to compile a query. Smaller values than the "
01754 "number of tables in a relation result in faster optimization, but may "
01755 "produce very bad query plans. If set to 0, the system will "
01756 "automatically pick a reasonable value; if set to MAX_TABLES+2, the "
01757 "optimizer will switch to the original find_best (used for "
01758 "testing/comparison)."),
01759 (char**) &global_system_variables.optimizer_search_depth,
01760 NULL,
01761 0, GET_UINT, OPT_ARG, 0, 0, MAX_TABLES+2, 0, 1, 0},
01762 {"plugin_dir", OPT_PLUGIN_DIR,
01763 N_("Directory for plugins."),
01764 NULL, NULL, 0,
01765 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
01766 {"plugin_add", OPT_PLUGIN_ADD,
01767 N_("Optional comma separated list of plugins to load at startup in addition "
01768 "to the default list of plugins. "
01769 "[for example: --plugin_add=crc32,logger_gearman]"),
01770 NULL, NULL, 0,
01771 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
01772 {"plugin_remove", OPT_PLUGIN_ADD,
01773 N_("Optional comma separated list of plugins to not load at startup. Effectively "
01774 "removes a plugin from the list of plugins to be loaded. "
01775 "[for example: --plugin_remove=crc32,logger_gearman]"),
01776 NULL, NULL, 0,
01777 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
01778 {"plugin_load", OPT_PLUGIN_LOAD,
01779 N_("Optional comma separated list of plugins to load at starup instead of "
01780 "the default plugin load list. "
01781 "[for example: --plugin_load=crc32,logger_gearman]"),
01782 NULL, NULL, 0,
01783 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
01784 {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
01785 N_("The size of the buffer that is allocated when preloading indexes"),
01786 (char**) &global_system_variables.preload_buff_size,
01787 NULL, 0, GET_ULL,
01788 REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0},
01789 {"query_alloc_block_size", OPT_QUERY_ALLOC_BLOCK_SIZE,
01790 N_("Allocation block size for query parsing and execution"),
01791 (char**) &global_system_variables.query_alloc_block_size,
01792 NULL, 0, GET_UINT,
01793 REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
01794 {"query_prealloc_size", OPT_QUERY_PREALLOC_SIZE,
01795 N_("Persistent buffer for query parsing and execution"),
01796 (char**) &global_system_variables.query_prealloc_size,
01797 NULL, 0, GET_UINT,
01798 REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, QUERY_ALLOC_PREALLOC_SIZE,
01799 ULONG_MAX, 0, 1024, 0},
01800 {"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE,
01801 N_("Allocation block size for storing ranges during optimization"),
01802 (char**) &global_system_variables.range_alloc_block_size,
01803 NULL, 0, GET_SIZE,
01804 REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, (int64_t)SIZE_MAX,
01805 0, 1024, 0},
01806 {"read_buffer_size", OPT_RECORD_BUFFER,
01807 N_("Each thread that does a sequential scan allocates a buffer of this "
01808 "size for each table it scans. If you do many sequential scans, you may "
01809 "want to increase this value."),
01810 (char**) &global_system_variables.read_buff_size,
01811 NULL,0, GET_UINT, REQUIRED_ARG,
01812 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, INT32_MAX, MALLOC_OVERHEAD, IO_SIZE,
01813 0},
01814 {"read_rnd_buffer_size", OPT_RECORD_RND_BUFFER,
01815 N_("When reading rows in sorted order after a sort, the rows are read "
01816 "through this buffer to avoid a disk seeks. If not set, then it's set "
01817 "to the value of record_buffer."),
01818 (char**) &global_system_variables.read_rnd_buff_size,
01819 NULL, 0,
01820 GET_UINT, REQUIRED_ARG, 256*1024L, 64 ,
01821 UINT32_MAX, MALLOC_OVERHEAD, 1 , 0},
01822
01823 {"sort_buffer_size", OPT_SORT_BUFFER,
01824 N_("Each thread that needs to do a sort allocates a buffer of this size."),
01825 (char**) &global_system_variables.sortbuff_size,
01826 NULL, 0, GET_SIZE, REQUIRED_ARG,
01827 MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*8, (int64_t)SIZE_MAX,
01828 MALLOC_OVERHEAD, 1, 0},
01829 {"table_definition_cache", OPT_TABLE_DEF_CACHE,
01830 N_("The number of cached table definitions."),
01831 (char**) &table_def_size, NULL,
01832 0, GET_SIZE, REQUIRED_ARG, 128, 1, 512*1024L, 0, 1, 0},
01833 {"table_open_cache", OPT_TABLE_OPEN_CACHE,
01834 N_("The number of cached open tables."),
01835 (char**) &table_cache_size, NULL, 0, GET_UINT64,
01836 REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, TABLE_OPEN_CACHE_MIN, 512*1024L, 0, 1, 0},
01837 {"table_lock_wait_timeout", OPT_TABLE_LOCK_WAIT_TIMEOUT,
01838 N_("Timeout in seconds to wait for a table level lock before returning an "
01839 "error. Used only if the connection has active cursors."),
01840 (char**) &table_lock_wait_timeout, NULL,
01841 0, GET_ULL, REQUIRED_ARG, 50, 1, 1024 * 1024 * 1024, 0, 1, 0},
01842 {"thread_stack", OPT_THREAD_STACK,
01843 N_("The stack size for each thread."),
01844 (char**) &my_thread_stack_size,
01845 NULL, 0, GET_SIZE,
01846 REQUIRED_ARG,0,
01847 UINT32_C(1024*512), (int64_t)SIZE_MAX, 0, 1024, 0},
01848 {"tmp_table_size", OPT_TMP_TABLE_SIZE,
01849 N_("If an internal in-memory temporary table exceeds this size, Drizzle will"
01850 " automatically convert it to an on-disk MyISAM table."),
01851 (char**) &global_system_variables.tmp_table_size,
01852 NULL, 0, GET_ULL,
01853 REQUIRED_ARG, 16*1024*1024L, 1024, (int64_t)MAX_MEM_TABLE_SIZE, 0, 1, 0},
01854 {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
01855 };
01856
01857 void usage()
01858 {
01859 if ((default_charset_info= get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)) == NULL)
01860 {
01861 unireg_abort << "Failed to load default_charset_info:" << default_character_set_name;
01862 }
01863
01864 if (default_collation_name == NULL)
01865 {
01866 default_collation_name= default_charset_info->name;
01867 }
01868
01869 print_version();
01870 puts(_("Copyright (C) 2010-2011 Drizzle Developers, Copyright (C) 2008 Sun Microsystems\n"
01871 "This software comes with ABSOLUTELY NO WARRANTY. "
01872 "This is free software,\n"
01873 "and you are welcome to modify and redistribute it under the GPL "
01874 "license\n\n"));
01875
01876
01877 printf(_("Usage: %s [OPTIONS]\n"), internal::my_progname);
01878
01879 po::options_description all_options("Drizzled Options");
01880 all_options.add(general_options);
01881 all_options.add(config_options);
01882 all_options.add(plugin_load_options);
01883 all_options.add(long_options);
01884 all_options.add(plugin_options);
01885 cout << all_options << endl;
01886
01887 unireg_exit();
01888 }
01889
01906 static void drizzle_init_variables()
01907 {
01908
01909 opt_tc_log_file= (char *)"tc.log";
01910 cleanup_done= 0;
01911 dropping_tables= ha_open_options=0;
01912 getDebug().reset();
01913 wake_thread=0;
01914 abort_loop= select_thread_in_use= false;
01915 shutdown_in_progress= 0;
01916 drizzled_user= drizzled_chroot= 0;
01917 memset(¤t_global_counters, 0, sizeof(current_global_counters));
01918 key_map_full.set();
01919
01920
01921 system_charset_info= &my_charset_utf8_general_ci;
01922 files_charset_info= &my_charset_utf8_general_ci;
01923 table_alias_charset= &my_charset_bin;
01924 character_set_filesystem= &my_charset_bin;
01925
01926
01927 session_startup_options= (OPTION_AUTO_IS_NULL | OPTION_SQL_NOTES);
01928 global_thread_id= 1;
01929 session::Cache::getCache().clear();
01930
01931
01932 global_system_variables.storage_engine= NULL;
01933 global_system_variables.tx_isolation= ISO_REPEATABLE_READ;
01934 global_system_variables.select_limit= (uint64_t) HA_POS_ERROR;
01935 max_system_variables.select_limit= (uint64_t) HA_POS_ERROR;
01936 global_system_variables.max_join_size= (uint64_t) HA_POS_ERROR;
01937 max_system_variables.max_join_size= (uint64_t) HA_POS_ERROR;
01938 max_system_variables.auto_increment_increment= UINT64_MAX;
01939 max_system_variables.auto_increment_offset= UINT64_MAX;
01940 max_system_variables.completion_type= 2;
01941 max_system_variables.log_warnings= true;
01942 max_system_variables.bulk_insert_buff_size= ULONG_MAX;
01943 max_system_variables.div_precincrement= DECIMAL_MAX_SCALE;
01944 max_system_variables.group_concat_max_len= ULONG_MAX;
01945 max_system_variables.join_buff_size= ULONG_MAX;
01946 max_system_variables.max_allowed_packet= 1024L*1024L*1024L;
01947 max_system_variables.max_error_count= 65535;
01948 max_system_variables.max_heap_table_size= MAX_MEM_TABLE_SIZE;
01949 max_system_variables.max_join_size= INT32_MAX;
01950 max_system_variables.max_length_for_sort_data= 8192*1024L;
01951 max_system_variables.max_seeks_for_key= ULONG_MAX;
01952 max_system_variables.max_sort_length= 8192*1024L;
01953 max_system_variables.min_examined_row_limit= ULONG_MAX;
01954 max_system_variables.optimizer_prune_level= 1;
01955 max_system_variables.optimizer_search_depth= MAX_TABLES+2;
01956 max_system_variables.preload_buff_size= 1024*1024*1024L;
01957 max_system_variables.query_alloc_block_size= UINT32_MAX;
01958 max_system_variables.query_prealloc_size= UINT32_MAX;
01959 max_system_variables.range_alloc_block_size= SIZE_MAX;
01960 max_system_variables.read_buff_size= INT32_MAX;
01961 max_system_variables.read_rnd_buff_size= UINT32_MAX;
01962 max_system_variables.sortbuff_size= SIZE_MAX;
01963 max_system_variables.tmp_table_size= MAX_MEM_TABLE_SIZE;
01964
01965
01966 #ifdef HAVE_BROKEN_REALPATH
01967 have_symlink=SHOW_OPTION_NO;
01968 #else
01969 have_symlink=SHOW_OPTION_YES;
01970 #endif
01971 }
01972
01973
01978 static void get_options()
01979 {
01980 catalog::resetPath_for_local_identifier();
01981
01982 if (vm.count("user"))
01983 {
01984 if (drizzled_user == NULL or strcmp(drizzled_user, vm["user"].as<string>().c_str()) == 0)
01985 {
01986 drizzled_user= (char *)vm["user"].as<string>().c_str();
01987 }
01988 else
01989 {
01990 errmsg_printf(error::WARN, _("Ignoring user change to '%s' because the user was set to '%s' earlier on the command line"),
01991 vm["user"].as<string>().c_str(), drizzled_user);
01992 }
01993 }
01994
01995 if (vm.count("sort-heap-threshold"))
01996 {
01997 if ((vm["sort-heap-threshold"].as<uint64_t>() > 0) and
01998 (vm["sort-heap-threshold"].as<uint64_t>() < global_system_variables.sortbuff_size))
01999 {
02000 unireg_abort << _("sort-heap-threshold cannot be less than sort-buffer-size");
02001 }
02002
02003 global_sort_buffer.setMaxSize(vm["sort-heap-threshold"].as<uint64_t>());
02004 }
02005
02006 if (vm.count("join-heap-threshold"))
02007 {
02008 if ((vm["join-heap-threshold"].as<uint64_t>() > 0) and
02009 (vm["join-heap-threshold"].as<uint64_t>() < global_system_variables.join_buff_size))
02010 {
02011 unireg_abort << _("join-heap-threshold cannot be less than join-buffer-size");
02012 }
02013
02014 global_join_buffer.setMaxSize(vm["join-heap-threshold"].as<uint64_t>());
02015 }
02016
02017 if (vm.count("read-rnd-threshold"))
02018 {
02019 if ((vm["read-rnd-threshold"].as<uint64_t>() > 0) and
02020 (vm["read-rnd-threshold"].as<uint64_t>() < global_system_variables.read_rnd_buff_size))
02021 {
02022 unireg_abort << _("read-rnd-threshold cannot be less than read-rnd-buffer-size");
02023 }
02024
02025 global_read_rnd_buffer.setMaxSize(vm["read-rnd-threshold"].as<uint64_t>());
02026 }
02027
02028 if (vm.count("read-buffer-threshold"))
02029 {
02030 if ((vm["read-buffer-threshold"].as<uint64_t>() > 0) and
02031 (vm["read-buffer-threshold"].as<uint64_t>() < global_system_variables.read_buff_size))
02032 {
02033 unireg_abort << _("read-buffer-threshold cannot be less than read-buffer-size");
02034 }
02035
02036 global_read_buffer.setMaxSize(vm["read-buffer-threshold"].as<uint64_t>());
02037 }
02038
02039 if (vm.count("exit-info"))
02040 {
02041 if (vm["exit-info"].as<long>())
02042 {
02043 getDebug().set((uint32_t) vm["exit-info"].as<long>());
02044 }
02045 }
02046
02047 if (vm.count("want-core"))
02048 {
02049 getDebug().set(debug::CORE_ON_SIGNAL);
02050 }
02051
02052 if (vm.count("skip-stack-trace"))
02053 {
02054 getDebug().set(debug::NO_STACKTRACE);
02055 }
02056
02057 if (vm.count("skip-symlinks"))
02058 {
02059 internal::my_use_symdir= 0;
02060 }
02061
02062 if (vm.count("collation-server"))
02063 {
02064 const charset_info_st * const default_collation= get_charset_by_name(vm["collation-server"].as<string>().c_str());
02065 if (not default_collation)
02066 {
02067 unireg_abort << "Unknown collation: " << default_collation_name;
02068 }
02069
02070 if (not my_charset_same(default_charset_info, default_collation))
02071 {
02072 unireg_abort << "COLLATION '" << default_collation_name << "' is not valid for CHARACTER SET '" << default_charset_info->csname << "'";
02073 }
02074 default_charset_info= default_collation;
02075 }
02076
02077 if (vm.count("transaction-isolation"))
02078 {
02079 int type= tx_isolation_typelib.find_type_or_exit(vm["transaction-isolation"].as<string>().c_str(), "transaction-isolation");
02080 global_system_variables.tx_isolation= type - 1;
02081 }
02082
02083
02084 if (vm.count("default-storage-engine"))
02085 {
02086 default_storage_engine_str= vm["default-storage-engine"].as<string>().c_str();
02087 }
02088
02089
02090 #if defined(HAVE_BROKEN_REALPATH)
02091 internal::my_use_symdir=0;
02092 internal::my_disable_symlinks=1;
02093 have_symlink=SHOW_OPTION_NO;
02094 #else
02095 if (!internal::my_use_symdir)
02096 {
02097 internal::my_disable_symlinks=1;
02098 have_symlink=SHOW_OPTION_DISABLED;
02099 }
02100 #endif
02101 if (opt_debugging)
02102 {
02103
02104 getDebug().set(debug::ALLOW_SIGINT);
02105 getDebug().set(debug::NO_STACKTRACE);
02106 getDebug().reset(debug::CORE_ON_SIGNAL);
02107 }
02108
02109 if (drizzled_chroot)
02110 {
02111 set_root(drizzled_chroot);
02112 }
02113
02114
02115
02116
02117
02118 internal::my_default_record_cache_size=global_system_variables.read_buff_size;
02119 }
02120
02121
02122 static void fix_paths()
02123 {
02124 if (vm.count("help"))
02125 return;
02126
02127 fs::path pid_file_path(pid_file);
02128 if (pid_file_path.root_path().string() == "")
02129 {
02130 pid_file_path= getDataHome();
02131 pid_file_path /= pid_file;
02132 }
02133 pid_file= fs::system_complete(pid_file_path);
02134
02135 const char *tmp_string= getenv("TMPDIR");
02136 struct stat buf;
02137 drizzle_tmpdir.clear();
02138
02139 if (vm.count("tmpdir"))
02140 {
02141 drizzle_tmpdir.append(vm["tmpdir"].as<string>());
02142 }
02143 else if (tmp_string == NULL)
02144 {
02145 drizzle_tmpdir.append(getDataHome().file_string());
02146 drizzle_tmpdir.push_back(FN_LIBCHAR);
02147 drizzle_tmpdir.append(GLOBAL_TEMPORARY_EXT);
02148 }
02149 else
02150 {
02151 drizzle_tmpdir.append(tmp_string);
02152 }
02153
02154 drizzle_tmpdir= fs::path(fs::system_complete(fs::path(drizzle_tmpdir))).file_string();
02155 assert(drizzle_tmpdir.size());
02156
02157 assert(getuid() != 0 and geteuid() != 0);
02158 if (getuid() == 0 or geteuid() == 0)
02159 {
02160 unireg_abort << "Drizzle cannot be run as root, please see the Security piece of the manual for more information.";
02161 }
02162
02163 if (mkdir(drizzle_tmpdir.c_str(), 0777) == -1)
02164 {
02165 if (errno != EEXIST)
02166 {
02167 unireg_abort << "There was an error creating the '"
02168 << fs::path(drizzle_tmpdir).leaf()
02169 << "' part of the path '"
02170 << drizzle_tmpdir
02171 << "'. Please check the path exists and is writable.";
02172 }
02173 }
02174
02175 if (stat(drizzle_tmpdir.c_str(), &buf) || not S_ISDIR(buf.st_mode))
02176 {
02177 unireg_abort << "There was an error opening the path '" << drizzle_tmpdir << "', please check the path exists and is writable.";
02178 }
02179 }
02180
02181 }
02182