736
#if defined(BACKTRACE_DEMANGLE)
738
extern "C" char *my_demangle(const char *mangled_name, int *status)
740
return abi::__cxa_demangle(mangled_name, NULL, NULL, status);
744
extern "C" void handle_segfault(int sig);
746
extern "C" void handle_segfault(int sig)
752
Strictly speaking, one needs a mutex here
753
but since we have got SIGSEGV already, things are a mess
754
so not having the mutex is not as bad as possibly using a buggy
755
mutex - so we keep things simple
759
fprintf(stderr, _("Fatal signal %d while backtracing\n"), sig);
765
curr_time= time(NULL);
766
if(curr_time == (time_t)-1)
768
fprintf(stderr, "Fetal: time() call failed\n");
772
localtime_r(&curr_time, &tm);
774
fprintf(stderr,"%02d%02d%02d %2d:%02d:%02d - drizzled got signal %d;\n"
775
"This could be because you hit a bug. It is also possible that "
776
"this binary\n or one of the libraries it was linked against is "
777
"corrupt, improperly built,\n or misconfigured. This error can "
778
"also be caused by malfunctioning hardware.\n",
779
tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday,
780
tm.tm_hour, tm.tm_min, tm.tm_sec,
782
fprintf(stderr, _("We will try our best to scrape up some info that "
783
"will hopefully help diagnose\n"
784
"the problem, but since we have already crashed, "
785
"something is definitely wrong\nand this may fail.\n\n"));
786
fprintf(stderr, "key_buffer_size=%u\n",
787
(uint32_t) dflt_key_cache->key_cache_mem_size);
788
fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
789
fprintf(stderr, "max_used_connections=%u\n", max_used_connections);
790
fprintf(stderr, "connection_count=%u\n", uint32_t(connection_count));
791
fprintf(stderr, _("It is possible that drizzled could use up to \n"
792
"key_buffer_size + (read_buffer_size + "
793
"sort_buffer_size)*thread_count\n"
795
"Hope that's ok; if not, decrease some variables in the "
798
#ifdef HAVE_STACKTRACE
799
Session *session= current_session;
801
if (! (test_flags.test(TEST_NO_STACKTRACE)))
803
fprintf(stderr,"session: 0x%lx\n",(long) session);
804
fprintf(stderr,_("Attempting backtrace. You can use the following "
805
"information to find out\n"
806
"where drizzled died. If you see no messages after this, "
808
"terribly wrong...\n"));
809
print_stacktrace(session ? (unsigned char*) session->thread_stack : (unsigned char*) 0,
810
my_thread_stack_size);
814
const char *kreason= "UNKNOWN";
815
switch (session->killed) {
816
case Session::NOT_KILLED:
817
kreason= "NOT_KILLED";
819
case Session::KILL_BAD_DATA:
820
kreason= "KILL_BAD_DATA";
822
case Session::KILL_CONNECTION:
823
kreason= "KILL_CONNECTION";
825
case Session::KILL_QUERY:
826
kreason= "KILL_QUERY";
828
case Session::KILLED_NO_VALUE:
829
kreason= "KILLED_NO_VALUE";
832
fprintf(stderr, _("Trying to get some variables.\n"
833
"Some pointers may be invalid and cause the "
834
"dump to abort...\n"));
835
safe_print_str("session->query", session->query.c_str(), 1024);
836
fprintf(stderr, "session->thread_id=%"PRIu32"\n", (uint32_t) session->thread_id);
837
fprintf(stderr, "session->killed=%s\n", kreason);
840
#endif /* HAVE_STACKTRACE */
842
if (calling_initgroups)
843
fprintf(stderr, _("\nThis crash occurred while the server was calling "
844
"initgroups(). This is\n"
845
"often due to the use of a drizzled that is statically "
846
"linked against glibc\n"
847
"and configured to use LDAP in /etc/nsswitch.conf. "
848
"You will need to either\n"
849
"upgrade to a version of glibc that does not have this "
850
"problem (2.3.4 or\n"
851
"later when used with nscd), disable LDAP in your "
852
"nsswitch.conf, or use a\n"
853
"drizzled that is not statically linked.\n"));
855
if (internal::thd_lib_detected == THD_LIB_LT && !getenv("LD_ASSUME_KERNEL"))
857
_("\nYou are running a statically-linked LinuxThreads binary "
858
"on an NPTL system.\n"
859
"This can result in crashes on some distributions due "
860
"to LT/NPTL conflicts.\n"
861
"You should either build a dynamically-linked binary, or force "
863
"to be used with the LD_ASSUME_KERNEL environment variable. "
865
"the documentation for your distribution on how to do that.\n"));
867
#ifdef HAVE_WRITE_CORE
868
if (test_flags.test(TEST_CORE_ON_SIGNAL))
870
fprintf(stderr, _("Writing a core file\n"));
879
699
#ifndef SA_RESETHAND
880
700
#define SA_RESETHAND 0
888
All global error messages are sent here where the first one is stored
891
static void my_message_sql(uint32_t error, const char *str, myf MyFlags)
709
const char *load_default_groups[]=
895
Put here following assertion when situation with EE_* error codes
898
if ((session= current_session))
900
if (MyFlags & ME_FATALERROR)
901
session->is_fatal_error= 1;
904
TODO: There are two exceptions mechanism (Session and sp_rcontext),
905
this could be improved by having a common stack of handlers.
907
if (session->handle_error(error, str,
908
DRIZZLE_ERROR::WARN_LEVEL_ERROR))
912
session->lex->current_select == 0 if lex structure is not inited
913
(not query command (COM_QUERY))
915
if (! (session->lex->current_select &&
916
session->lex->current_select->no_error && !session->is_fatal_error))
918
if (! session->main_da.is_error()) // Return only first message
921
error= ER_UNKNOWN_ERROR;
924
session->main_da.set_error_status(error, str);
928
if (!session->no_warnings_for_error && !session->is_fatal_error)
931
Suppress infinite recursion if there a memory allocation error
934
session->no_warnings_for_error= true;
935
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error, str);
936
session->no_warnings_for_error= false;
939
if (!session || MyFlags & ME_NOREFRESH)
940
errmsg_printf(ERRMSG_LVL_ERROR, "%s: %s",internal::my_progname,str);
944
static const char *load_default_groups[]= {
945
DRIZZLE_CONFIG_NAME, "server", 0, 0};
711
DRIZZLE_CONFIG_NAME, "server", 0, 0
947
714
static int show_starttime(drizzle_show_var *var, char *buff)
965
732
static st_show_var_func_container show_flushstatustime_cont= { &show_flushstatustime };
968
Variables shown by SHOW STATUS in alphabetical order
970
static drizzle_show_var com_status_vars[]= {
971
{"admin_commands", (char*) offsetof(system_status_var, com_other), SHOW_LONG_STATUS},
972
{"alter_db", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_ALTER_DB]), SHOW_LONG_STATUS},
973
{"alter_table", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_ALTER_TABLE]), SHOW_LONG_STATUS},
974
{"analyze", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_ANALYZE]), SHOW_LONG_STATUS},
975
{"begin", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_BEGIN]), SHOW_LONG_STATUS},
976
{"change_db", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CHANGE_DB]), SHOW_LONG_STATUS},
977
{"check", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CHECK]), SHOW_LONG_STATUS},
978
{"checksum", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CHECKSUM]), SHOW_LONG_STATUS},
979
{"commit", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_COMMIT]), SHOW_LONG_STATUS},
980
{"create_db", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CREATE_DB]), SHOW_LONG_STATUS},
981
{"create_index", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CREATE_INDEX]), SHOW_LONG_STATUS},
982
{"create_table", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CREATE_TABLE]), SHOW_LONG_STATUS},
983
{"delete", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_DELETE]), SHOW_LONG_STATUS},
984
{"drop_db", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_DROP_DB]), SHOW_LONG_STATUS},
985
{"drop_index", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_DROP_INDEX]), SHOW_LONG_STATUS},
986
{"drop_table", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_DROP_TABLE]), SHOW_LONG_STATUS},
987
{"empty_query", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_EMPTY_QUERY]), SHOW_LONG_STATUS},
988
{"flush", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_FLUSH]), SHOW_LONG_STATUS},
989
{"insert", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_INSERT]), SHOW_LONG_STATUS},
990
{"insert_select", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_INSERT_SELECT]), SHOW_LONG_STATUS},
991
{"kill", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_KILL]), SHOW_LONG_STATUS},
992
{"load", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_LOAD]), SHOW_LONG_STATUS},
993
{"release_savepoint", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_RELEASE_SAVEPOINT]), SHOW_LONG_STATUS},
994
{"rename_table", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_RENAME_TABLE]), SHOW_LONG_STATUS},
995
{"replace", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_REPLACE]), SHOW_LONG_STATUS},
996
{"replace_select", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_REPLACE_SELECT]), SHOW_LONG_STATUS},
997
{"rollback", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_ROLLBACK]), SHOW_LONG_STATUS},
998
{"rollback_to_savepoint",(char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_ROLLBACK_TO_SAVEPOINT]), SHOW_LONG_STATUS},
999
{"savepoint", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SAVEPOINT]), SHOW_LONG_STATUS},
1000
{"select", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SELECT]), SHOW_LONG_STATUS},
1001
{"set_option", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SET_OPTION]), SHOW_LONG_STATUS},
1002
{"show_create_db", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SHOW_CREATE_DB]), SHOW_LONG_STATUS},
1003
{"show_create_table", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SHOW_CREATE]), SHOW_LONG_STATUS},
1004
{"show_errors", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SHOW_ERRORS]), SHOW_LONG_STATUS},
1005
{"show_warnings", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
1006
{"truncate", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_TRUNCATE]), SHOW_LONG_STATUS},
1007
{"unlock_tables", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_UNLOCK_TABLES]), SHOW_LONG_STATUS},
1008
{"update", (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_UPDATE]), SHOW_LONG_STATUS},
1009
{NULL, NULL, SHOW_LONGLONG}
1012
734
static drizzle_show_var status_vars[]= {
1013
735
{"Aborted_clients", (char*) &aborted_threads, SHOW_LONGLONG},
1014
736
{"Aborted_connects", (char*) &aborted_connects, SHOW_LONGLONG},
1445
1159
NO_ARG, 0, 0, 0, 0, 0, 0},
1446
1160
{"datadir", 'h',
1447
1161
N_("Path to the database root."),
1448
(char**) &drizzle_data_home,
1449
(char**) &drizzle_data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1162
(char**) &data_home,
1163
(char**) &data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1450
1164
{"default-storage-engine", OPT_STORAGE_ENGINE,
1451
1165
N_("Set the default storage engine (table type) for tables."),
1452
1166
(char**)&default_storage_engine_str, (char**)&default_storage_engine_str,
2064
1777
pos[0]= FN_LIBCHAR;
2067
internal::convert_dirname(drizzle_real_data_home,drizzle_real_data_home,NULL);
2068
(void) internal::fn_format(buff, drizzle_real_data_home, "", "",
1780
internal::convert_dirname(data_home_real,data_home_real,NULL);
1781
(void) internal::fn_format(buff, data_home_real, "", "",
2069
1782
(MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
2070
(void) internal::unpack_dirname(drizzle_unpacked_real_data_home, buff);
1783
(void) internal::unpack_dirname(data_home_real_unpacked, buff);
2071
1784
internal::convert_dirname(language,language,NULL);
2072
1785
(void) internal::my_load_path(drizzle_home, drizzle_home,""); // Resolve current dir
2073
(void) internal::my_load_path(drizzle_real_data_home, drizzle_real_data_home,drizzle_home);
2074
(void) internal::my_load_path(pidfile_name, pidfile_name,drizzle_real_data_home);
1786
(void) internal::my_load_path(data_home_real, data_home_real,drizzle_home);
1787
(void) internal::my_load_path(pidfile_name, pidfile_name,data_home_real);
2076
1789
if (opt_plugin_dir_ptr == NULL)
2173
1888
} /* namespace drizzled */
2175
using namespace drizzled;
2178
static void init_signals(void)
2181
struct sigaction sa;
2183
if (!(test_flags.test(TEST_NO_STACKTRACE) ||
2184
test_flags.test(TEST_CORE_ON_SIGNAL)))
2186
sa.sa_flags = SA_RESETHAND | SA_NODEFER;
2187
sigemptyset(&sa.sa_mask);
2188
sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
2191
sa.sa_handler=handle_segfault;
2192
sigaction(SIGSEGV, &sa, NULL);
2193
sigaction(SIGABRT, &sa, NULL);
2195
sigaction(SIGBUS, &sa, NULL);
2197
sigaction(SIGILL, &sa, NULL);
2198
sigaction(SIGFPE, &sa, NULL);
2201
if (test_flags.test(TEST_CORE_ON_SIGNAL))
2203
/* Change limits so that we will get a core file */
2205
rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
2206
if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
2207
errmsg_printf(ERRMSG_LVL_WARN,
2208
_("setrlimit could not change the size of core files "
2209
"to 'infinity'; We may not be able to generate a "
2210
"core file on signals"));
2212
(void) sigemptyset(&set);
2213
my_sigset(SIGPIPE,SIG_IGN);
2214
sigaddset(&set,SIGPIPE);
2215
#ifndef IGNORE_SIGHUP_SIGQUIT
2216
sigaddset(&set,SIGQUIT);
2217
sigaddset(&set,SIGHUP);
2219
sigaddset(&set,SIGTERM);
2221
/* Fix signals if blocked by parents (can happen on Mac OS X) */
2222
sigemptyset(&sa.sa_mask);
2224
sa.sa_handler = print_signal_warning;
2225
sigaction(SIGTERM, &sa, (struct sigaction*) 0);
2227
sa.sa_handler = print_signal_warning;
2228
sigaction(SIGHUP, &sa, (struct sigaction*) 0);
2230
sigaddset(&set,SIGTSTP);
2232
if (test_flags.test(TEST_SIGINT))
2234
my_sigset(thr_kill_signal, end_thread_signal);
2236
sigdelset(&set, thr_kill_signal);
2239
sigaddset(&set,SIGINT);
2240
sigprocmask(SIG_SETMASK,&set,NULL);
2241
pthread_sigmask(SIG_SETMASK,&set,NULL);
2245
int main(int argc, char **argv)
2247
#if defined(ENABLE_NLS)
2248
# if defined(HAVE_LOCALE_H)
2249
setlocale(LC_ALL, "");
2251
bindtextdomain("drizzle", LOCALEDIR);
2252
textdomain("drizzle");
2255
plugin::Registry &plugins= plugin::Registry::singleton();
2256
plugin::Client *client;
2259
MY_INIT(argv[0]); // init my_sys library & pthreads
2260
/* nothing should come before this line ^^^ */
2262
/* Set signal used to kill Drizzle */
2263
#if defined(SIGUSR2)
2264
thr_kill_signal= internal::thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2;
2266
thr_kill_signal= SIGINT;
2269
if (init_common_variables(DRIZZLE_CONFIG_NAME,
2270
argc, argv, load_default_groups))
2271
unireg_abort(1); // Will do exit
2276
select_thread=pthread_self();
2277
select_thread_in_use=1;
2279
if (chdir(drizzle_real_data_home) && !opt_help)
2281
errmsg_printf(ERRMSG_LVL_ERROR, _("Data directory %s does not exist\n"), drizzle_real_data_home);
2284
drizzle_data_home= drizzle_data_home_buff;
2285
drizzle_data_home[0]=FN_CURLIB; // all paths are relative from here
2286
drizzle_data_home[1]=0;
2287
drizzle_data_home_len= 2;
2289
if ((user_info= check_user(drizzled_user)))
2291
set_user(drizzled_user, user_info);
2299
if (init_server_components(plugins))
2302
if (plugin::Listen::setup())
2306
init signals & alarm
2307
After this we can't quit by a simple unireg_abort
2309
error_handler_hook= my_message_sql;
2311
assert(plugin::num_trx_monitored_objects > 0);
2312
if (drizzle_rm_tmp_tables() ||
2313
my_tz_init((Session *)0, default_tz_name))
2316
select_thread_in_use=0;
2317
(void) pthread_kill(signal_thread, SIGTERM);
2319
(void) unlink(pidfile_name); // Not needed anymore
2326
errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)), internal::my_progname,
2327
PANDORA_RELEASE_VERSION, COMPILATION_COMMENT);
2330
/* Listen for new connections and start new session for each connection
2331
accepted. The listen.getClient() method will return NULL when the server
2332
should be shutdown. */
2333
while ((client= plugin::Listen::getClient()) != NULL)
2335
if (!(session= new Session(client)))
2341
/* If we error on creation we drop the connection and delete the session. */
2342
if (session->schedule())
2343
Session::unlink(session);
2346
/* (void) pthread_attr_destroy(&connection_attrib); */
2349
(void) pthread_mutex_lock(&LOCK_thread_count);
2350
select_thread_in_use=0; // For close_connections
2351
(void) pthread_mutex_unlock(&LOCK_thread_count);
2352
(void) pthread_cond_broadcast(&COND_thread_count);
2354
/* Wait until cleanup is done */
2355
(void) pthread_mutex_lock(&LOCK_thread_count);
2356
while (!ready_to_exit)
2357
pthread_cond_wait(&COND_server_end,&LOCK_thread_count);
2358
(void) pthread_mutex_unlock(&LOCK_thread_count);
2361
plugin::Registry::shutdown();