615
802
if ((chroot(path) == -1) || !chdir("/"))
617
sql_perror(N_("Process chroot failed"));
804
sql_perror("chroot");
810
static void network_init(void)
816
char port_buf[NI_MAXSERV];
818
struct addrinfo *next;
819
struct addrinfo hints;
824
memset(fds, 0, sizeof(struct pollfd) * UINT8_MAX);
825
memset(&hints, 0, sizeof (hints));
826
hints.ai_flags= AI_PASSIVE;
827
hints.ai_socktype= SOCK_STREAM;
829
snprintf(port_buf, NI_MAXSERV, "%d", drizzled_port);
830
error= getaddrinfo(my_bind_addr_str, port_buf, &hints, &ai);
833
sql_perror(ER(ER_IPSOCK_ERROR)); /* purecov: tested */
834
unireg_abort(1); /* purecov: tested */
837
for (next= ai, pollfd_count= 0; next; next= next->ai_next, pollfd_count++)
841
ip_sock= socket(next->ai_family, next->ai_socktype, next->ai_protocol);
845
sql_perror(ER(ER_IPSOCK_ERROR)); /* purecov: tested */
846
unireg_abort(1); /* purecov: tested */
849
fds[pollfd_count].fd= ip_sock;
850
fds[pollfd_count].events= POLLIN | POLLERR;
852
/* Add options for our listening socket */
854
struct linger ling = {0, 0};
858
if (next->ai_family == AF_INET6)
860
error= setsockopt(ip_sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &flags, sizeof(flags));
863
perror("setsockopt");
868
error= setsockopt(ip_sock, SOL_SOCKET, SO_REUSEADDR, (char*)&flags, sizeof(flags));
871
perror("setsockopt");
874
error= setsockopt(ip_sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&flags, sizeof(flags));
877
perror("setsockopt");
880
error= setsockopt(ip_sock, SOL_SOCKET, SO_LINGER, (void *)&ling, sizeof(ling));
883
perror("setsockopt");
886
error= setsockopt(ip_sock, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags));
889
perror("setsockopt");
896
Sometimes the port is not released fast enough when stopping and
897
restarting the server. This happens quite often with the test suite
898
on busy Linux systems. Retry to bind the address at these intervals:
899
Sleep intervals: 1, 2, 4, 6, 9, 13, 17, 22, ...
900
Retry at second: 1, 3, 7, 13, 22, 35, 52, 74, ...
901
Limit the sequence by drizzled_port_timeout (set --port-open-timeout=#).
903
for (waited= 0, retry= 1; ; retry++, waited+= this_wait)
905
if (((ret= ::bind(ip_sock, next->ai_addr, next->ai_addrlen)) >= 0 ) ||
906
(errno != EADDRINUSE) ||
907
(waited >= drizzled_port_timeout))
909
errmsg_printf(ERRMSG_LVL_INFO, _("Retrying bind on TCP/IP port %u"), drizzled_port);
910
this_wait= retry * retry / 3 + 1;
915
sql_perror(_("Can't start server: Bind on TCP/IP port"));
916
errmsg_printf(ERRMSG_LVL_ERROR, _("Do you already have another drizzled server running "
917
"on port: %d ?"),drizzled_port);
920
if (listen(ip_sock,(int) back_log) < 0)
922
sql_perror(_("Can't start server: listen() on TCP/IP port"));
923
errmsg_printf(ERRMSG_LVL_ERROR, _("listen() on TCP/IP failed with error %d"),
935
/** Called when a thread is aborted. */
937
extern "C" void end_thread_signal(int )
939
Session *session=current_session;
942
statistic_increment(killed_threads, &LOCK_status);
943
(void)thread_scheduler.end_thread(session, 0); /* purecov: inspected */
945
return;; /* purecov: deadcode */
624
950
Unlink session from global list of available connections and free session
628
954
session Thread handler
957
LOCK_thread_count is locked and left locked
631
void drizzled::Session::unlink(Session::shared_ptr &session)
960
void unlink_session(Session *session)
633
connection_count.decrement();
635
964
session->cleanup();
637
boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
639
if (unlikely(plugin::EventObserver::disconnectSession(*session)))
641
// We should do something about an error...
643
session::Cache::singleton().erase(session);
966
(void) pthread_mutex_lock(&LOCK_thread_count);
967
pthread_mutex_lock(&session->LOCK_delete);
969
(void) pthread_mutex_unlock(&LOCK_thread_count);
975
#ifdef THREAD_SPECIFIC_SIGPIPE
977
Aborts a thread nicely. Comes here on SIGPIPE.
980
One should have to fix that thr_alarm know about this thread too.
982
extern "C" void abort_thread(int )
984
Session *session=current_session;
986
session->killed= Session::KILL_CONNECTION;
991
#if defined(BACKTRACE_DEMANGLE)
993
extern "C" char *my_demangle(const char *mangled_name, int *status)
995
return abi::__cxa_demangle(mangled_name, NULL, NULL, status);
1000
extern "C" void handle_segfault(int sig)
1006
Strictly speaking, one needs a mutex here
1007
but since we have got SIGSEGV already, things are a mess
1008
so not having the mutex is not as bad as possibly using a buggy
1009
mutex - so we keep things simple
1013
fprintf(stderr, _("Fatal " SIGNAL_FMT " while backtracing\n"), sig);
1019
curr_time= time(NULL);
1020
if(curr_time == (time_t)-1)
1022
fprintf(stderr, "Fetal: time() call failed\n");
1026
localtime_r(&curr_time, &tm);
1028
fprintf(stderr,"%02d%02d%02d %2d:%02d:%02d - drizzled got "
1030
"This could be because you hit a bug. It is also possible that "
1031
"this binary\n or one of the libraries it was linked against is "
1032
"corrupt, improperly built,\n or misconfigured. This error can "
1033
"also be caused by malfunctioning hardware.\n",
1034
tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday,
1035
tm.tm_hour, tm.tm_min, tm.tm_sec,
1037
fprintf(stderr, _("We will try our best to scrape up some info that "
1038
"will hopefully help diagnose\n"
1039
"the problem, but since we have already crashed, "
1040
"something is definitely wrong\nand this may fail.\n\n"));
1041
fprintf(stderr, "key_buffer_size=%u\n",
1042
(uint32_t) dflt_key_cache->key_cache_mem_size);
1043
fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
1044
fprintf(stderr, "max_used_connections=%u\n", max_used_connections);
1045
fprintf(stderr, "max_threads=%u\n", thread_scheduler.max_threads);
1046
fprintf(stderr, "thread_count=%u\n", thread_scheduler.count());
1047
fprintf(stderr, "connection_count=%u\n", uint32_t(connection_count));
1048
fprintf(stderr, _("It is possible that drizzled could use up to \n"
1049
"key_buffer_size + (read_buffer_size + "
1050
"sort_buffer_size)*max_threads = %"PRIu64" K\n"
1052
"Hope that's ok; if not, decrease some variables in the "
1054
(uint64_t)(((uint32_t) dflt_key_cache->key_cache_mem_size +
1055
(global_system_variables.read_buff_size +
1056
global_system_variables.sortbuff_size) *
1057
thread_scheduler.max_threads) / 1024));
1059
#ifdef HAVE_STACKTRACE
1060
Session *session= current_session;
1062
if (!(test_flags & TEST_NO_STACKTRACE))
1064
fprintf(stderr,"session: 0x%lx\n",(long) session);
1065
fprintf(stderr,_("Attempting backtrace. You can use the following "
1066
"information to find out\n"
1067
"where drizzled died. If you see no messages after this, "
1069
"terribly wrong...\n"));
1070
print_stacktrace(session ? (unsigned char*) session->thread_stack : (unsigned char*) 0,
1071
my_thread_stack_size);
1075
const char *kreason= "UNKNOWN";
1076
switch (session->killed) {
1077
case Session::NOT_KILLED:
1078
kreason= "NOT_KILLED";
1080
case Session::KILL_BAD_DATA:
1081
kreason= "KILL_BAD_DATA";
1083
case Session::KILL_CONNECTION:
1084
kreason= "KILL_CONNECTION";
1086
case Session::KILL_QUERY:
1087
kreason= "KILL_QUERY";
1089
case Session::KILLED_NO_VALUE:
1090
kreason= "KILLED_NO_VALUE";
1093
fprintf(stderr, _("Trying to get some variables.\n"
1094
"Some pointers may be invalid and cause the "
1095
"dump to abort...\n"));
1096
safe_print_str("session->query", session->query, 1024);
1097
fprintf(stderr, "session->thread_id=%"PRIu32"\n", (uint32_t) session->thread_id);
1098
fprintf(stderr, "session->killed=%s\n", kreason);
1101
#endif /* HAVE_STACKTRACE */
1103
#ifdef HAVE_INITGROUPS
1104
if (calling_initgroups)
1105
fprintf(stderr, _("\nThis crash occurred while the server was calling "
1106
"initgroups(). This is\n"
1107
"often due to the use of a drizzled that is statically "
1108
"linked against glibc\n"
1109
"and configured to use LDAP in /etc/nsswitch.conf. "
1110
"You will need to either\n"
1111
"upgrade to a version of glibc that does not have this "
1112
"problem (2.3.4 or\n"
1113
"later when used with nscd), disable LDAP in your "
1114
"nsswitch.conf, or use a\n"
1115
"drizzled that is not statically linked.\n"));
1118
if (thd_lib_detected == THD_LIB_LT && !getenv("LD_ASSUME_KERNEL"))
1120
_("\nYou are running a statically-linked LinuxThreads binary "
1121
"on an NPTL system.\n"
1122
"This can result in crashes on some distributions due "
1123
"to LT/NPTL conflicts.\n"
1124
"You should either build a dynamically-linked binary, or force "
1126
"to be used with the LD_ASSUME_KERNEL environment variable. "
1128
"the documentation for your distribution on how to do that.\n"));
1130
if (locked_in_memory)
1133
_("\nThe '--memlock' argument, which was enabled, uses system "
1135
"unreliable and unstable on some operating systems and "
1136
"operating-system\n"
1137
"versions (notably, some versions of Linux). "
1138
"This crash could be due to use\n"
1139
"of those buggy OS calls. You should consider whether you "
1141
"'--memlock' parameter and/or consult the OS "
1142
"distributor about 'mlockall'\n bugs.\n"));
1145
#ifdef HAVE_WRITE_CORE
1146
if (test_flags & TEST_CORE_ON_SIGNAL)
1148
fprintf(stderr, _("Writing a core file\n"));
647
1157
#ifndef SA_RESETHAND
648
1158
#define SA_RESETHAND 0
651
1161
#define SA_NODEFER 0
657
const char *load_default_groups[]=
659
DRIZZLE_CONFIG_NAME, "server", 0, 0
1164
static void init_signals(void)
1167
struct sigaction sa;
1169
if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL))
1171
sa.sa_flags = SA_RESETHAND | SA_NODEFER;
1172
sigemptyset(&sa.sa_mask);
1173
sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
1176
sa.sa_handler=handle_segfault;
1177
sigaction(SIGSEGV, &sa, NULL);
1178
sigaction(SIGABRT, &sa, NULL);
1180
sigaction(SIGBUS, &sa, NULL);
1182
sigaction(SIGILL, &sa, NULL);
1183
sigaction(SIGFPE, &sa, NULL);
1186
#ifdef HAVE_GETRLIMIT
1187
if (test_flags & TEST_CORE_ON_SIGNAL)
1189
/* Change limits so that we will get a core file */
1191
rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
1192
if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
1193
errmsg_printf(ERRMSG_LVL_WARN, _("setrlimit could not change the size of core files "
1194
"to 'infinity'; We may not be able to generate a "
1195
"core file on signals"));
1198
(void) sigemptyset(&set);
1199
my_sigset(SIGPIPE,SIG_IGN);
1200
sigaddset(&set,SIGPIPE);
1201
#ifndef IGNORE_SIGHUP_SIGQUIT
1202
sigaddset(&set,SIGQUIT);
1203
sigaddset(&set,SIGHUP);
1205
sigaddset(&set,SIGTERM);
1207
/* Fix signals if blocked by parents (can happen on Mac OS X) */
1208
sigemptyset(&sa.sa_mask);
1210
sa.sa_handler = print_signal_warning;
1211
sigaction(SIGTERM, &sa, (struct sigaction*) 0);
1213
sa.sa_handler = print_signal_warning;
1214
sigaction(SIGHUP, &sa, (struct sigaction*) 0);
1216
sigaddset(&set,SIGTSTP);
1218
if (test_flags & TEST_SIGINT)
1220
my_sigset(thr_kill_signal, end_thread_signal);
1222
sigdelset(&set, thr_kill_signal);
1225
sigaddset(&set,SIGINT);
1226
sigprocmask(SIG_SETMASK,&set,NULL);
1227
pthread_sigmask(SIG_SETMASK,&set,NULL);
1231
static void check_data_home(const char *)
1236
All global error messages are sent here where the first one is stored
1240
extern "C" void my_message_sql(uint32_t error, const char *str, myf MyFlags);
1242
void my_message_sql(uint32_t error, const char *str, myf MyFlags)
1246
Put here following assertion when situation with EE_* error codes
1249
if ((session= current_session))
1251
if (MyFlags & ME_FATALERROR)
1252
session->is_fatal_error= 1;
1255
TODO: There are two exceptions mechanism (Session and sp_rcontext),
1256
this could be improved by having a common stack of handlers.
1258
if (session->handle_error(error, str,
1259
DRIZZLE_ERROR::WARN_LEVEL_ERROR))
1263
session->lex->current_select == 0 if lex structure is not inited
1264
(not query command (COM_QUERY))
1266
if (! (session->lex->current_select &&
1267
session->lex->current_select->no_error && !session->is_fatal_error))
1269
if (! session->main_da.is_error()) // Return only first message
1272
error= ER_UNKNOWN_ERROR;
1275
session->main_da.set_error_status(session, error, str);
1279
if (!session->no_warnings_for_error && !session->is_fatal_error)
1282
Suppress infinite recursion if there a memory allocation error
1283
inside push_warning.
1285
session->no_warnings_for_error= true;
1286
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error, str);
1287
session->no_warnings_for_error= false;
1290
if (!session || MyFlags & ME_NOREFRESH)
1291
errmsg_printf(ERRMSG_LVL_ERROR, "%s: %s",my_progname,str); /* purecov: inspected */
1296
static const char *load_default_groups[]= {
1297
DRIZZLE_CONFIG_NAME,"server", DRIZZLE_BASE_VERSION, 0, 0};
1299
SHOW_VAR com_status_vars[]= {
1300
{"admin_commands", (char*) offsetof(STATUS_VAR, com_other), SHOW_LONG_STATUS},
1301
{"assign_to_keycache", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ASSIGN_TO_KEYCACHE]), SHOW_LONG_STATUS},
1302
{"alter_db", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ALTER_DB]), SHOW_LONG_STATUS},
1303
{"alter_table", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ALTER_TABLE]), SHOW_LONG_STATUS},
1304
{"analyze", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ANALYZE]), SHOW_LONG_STATUS},
1305
{"begin", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_BEGIN]), SHOW_LONG_STATUS},
1306
{"change_db", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_CHANGE_DB]), SHOW_LONG_STATUS},
1307
{"check", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_CHECK]), SHOW_LONG_STATUS},
1308
{"checksum", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_CHECKSUM]), SHOW_LONG_STATUS},
1309
{"commit", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_COMMIT]), SHOW_LONG_STATUS},
1310
{"create_db", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_CREATE_DB]), SHOW_LONG_STATUS},
1311
{"create_index", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_CREATE_INDEX]), SHOW_LONG_STATUS},
1312
{"create_table", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_CREATE_TABLE]), SHOW_LONG_STATUS},
1313
{"delete", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_DELETE]), SHOW_LONG_STATUS},
1314
{"delete_multi", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_DELETE_MULTI]), SHOW_LONG_STATUS},
1315
{"drop_db", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_DROP_DB]), SHOW_LONG_STATUS},
1316
{"drop_index", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_DROP_INDEX]), SHOW_LONG_STATUS},
1317
{"drop_table", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_DROP_TABLE]), SHOW_LONG_STATUS},
1318
{"empty_query", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_EMPTY_QUERY]), SHOW_LONG_STATUS},
1319
{"flush", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_FLUSH]), SHOW_LONG_STATUS},
1320
{"insert", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_INSERT]), SHOW_LONG_STATUS},
1321
{"insert_select", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_INSERT_SELECT]), SHOW_LONG_STATUS},
1322
{"kill", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_KILL]), SHOW_LONG_STATUS},
1323
{"load", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_LOAD]), SHOW_LONG_STATUS},
1324
{"lock_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_LOCK_TABLES]), SHOW_LONG_STATUS},
1325
{"optimize", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_OPTIMIZE]), SHOW_LONG_STATUS},
1326
{"release_savepoint", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_RELEASE_SAVEPOINT]), SHOW_LONG_STATUS},
1327
{"rename_table", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_RENAME_TABLE]), SHOW_LONG_STATUS},
1328
{"repair", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_REPAIR]), SHOW_LONG_STATUS},
1329
{"replace", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_REPLACE]), SHOW_LONG_STATUS},
1330
{"replace_select", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_REPLACE_SELECT]), SHOW_LONG_STATUS},
1331
{"rollback", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ROLLBACK]), SHOW_LONG_STATUS},
1332
{"rollback_to_savepoint",(char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ROLLBACK_TO_SAVEPOINT]), SHOW_LONG_STATUS},
1333
{"savepoint", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SAVEPOINT]), SHOW_LONG_STATUS},
1334
{"select", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SELECT]), SHOW_LONG_STATUS},
1335
{"set_option", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SET_OPTION]), SHOW_LONG_STATUS},
1336
{"show_create_db", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_CREATE_DB]), SHOW_LONG_STATUS},
1337
{"show_create_table", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_CREATE]), SHOW_LONG_STATUS},
1338
{"show_databases", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_DATABASES]), SHOW_LONG_STATUS},
1339
{"show_engine_status", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_ENGINE_STATUS]), SHOW_LONG_STATUS},
1340
{"show_errors", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_ERRORS]), SHOW_LONG_STATUS},
1341
{"show_fields", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_FIELDS]), SHOW_LONG_STATUS},
1342
{"show_keys", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_KEYS]), SHOW_LONG_STATUS},
1343
{"show_open_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_OPEN_TABLES]), SHOW_LONG_STATUS},
1344
{"show_plugins", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_PLUGINS]), SHOW_LONG_STATUS},
1345
{"show_processlist", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_PROCESSLIST]), SHOW_LONG_STATUS},
1346
{"show_status", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS},
1347
{"show_table_status", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS},
1348
{"show_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_TABLES]), SHOW_LONG_STATUS},
1349
{"show_variables", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS},
1350
{"show_warnings", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
1351
{"truncate", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_TRUNCATE]), SHOW_LONG_STATUS},
1352
{"unlock_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_UNLOCK_TABLES]), SHOW_LONG_STATUS},
1353
{"update", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_UPDATE]), SHOW_LONG_STATUS},
1354
{"update_multi", (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_UPDATE_MULTI]), SHOW_LONG_STATUS},
1355
{NULL, NULL, SHOW_LONGLONG}
662
static void find_plugin_dir(string progname)
664
if (progname[0] != FN_LIBCHAR)
666
/* We have a relative path and need to find the absolute */
667
char working_dir[FN_REFLEN];
668
char *working_dir_ptr= working_dir;
669
working_dir_ptr= getcwd(working_dir_ptr, FN_REFLEN);
670
string new_path(working_dir);
671
if (*(new_path.end()-1) != '/')
672
new_path.push_back('/');
673
if (progname[0] == '.' && progname[1] == '/')
674
new_path.append(progname.substr(2));
676
new_path.append(progname);
677
progname.swap(new_path);
680
/* Now, trim off the exe name */
681
string progdir(progname.substr(0, progname.rfind(FN_LIBCHAR)+1));
682
if (progdir.rfind(".libs/") != string::npos)
684
progdir.assign(progdir.substr(0, progdir.rfind(".libs/")));
686
string testlofile(progdir);
687
testlofile.append("drizzled.lo");
688
string testofile(progdir);
689
testofile.append("drizzled.o");
690
struct stat testfile_stat;
691
if (not (stat(testlofile.c_str(), &testfile_stat) && stat(testofile.c_str(), &testfile_stat)))
693
/* We are in a source dir! Plugin dir is ../plugin/.libs */
694
size_t last_libchar_pos= progdir.rfind(FN_LIBCHAR,progdir.size()-2)+1;
695
base_plugin_dir= progdir.substr(0,last_libchar_pos);
696
base_plugin_dir /= "plugin";
697
base_plugin_dir /= ".libs";
700
if (plugin_dir.root_directory() == "")
702
fs::path full_plugin_dir(fs::system_complete(base_plugin_dir));
703
full_plugin_dir /= plugin_dir;
704
plugin_dir= full_plugin_dir;
708
static void notify_plugin_dir(fs::path in_plugin_dir)
710
plugin_dir= in_plugin_dir;
711
if (plugin_dir.root_directory() == "")
713
fs::path full_plugin_dir(fs::system_complete(basedir));
714
full_plugin_dir /= plugin_dir;
715
plugin_dir= full_plugin_dir;
719
static void expand_secure_file_priv(fs::path in_secure_file_priv)
721
secure_file_priv= fs::system_complete(in_secure_file_priv);
724
static void check_limits_aii(uint64_t in_auto_increment_increment)
726
global_system_variables.auto_increment_increment= 1;
727
if (in_auto_increment_increment < 1 || in_auto_increment_increment > UINT64_MAX)
729
cout << N_("Error: Invalid Value for auto_increment_increment");
732
global_system_variables.auto_increment_increment= in_auto_increment_increment;
735
static void check_limits_aio(uint64_t in_auto_increment_offset)
737
global_system_variables.auto_increment_offset= 1;
738
if (in_auto_increment_offset < 1 || in_auto_increment_offset > UINT64_MAX)
740
cout << N_("Error: Invalid Value for auto_increment_offset");
743
global_system_variables.auto_increment_offset= in_auto_increment_offset;
746
static void check_limits_completion_type(uint32_t in_completion_type)
748
global_system_variables.completion_type= 0;
749
if (in_completion_type > 2)
751
cout << N_("Error: Invalid Value for completion_type");
754
global_system_variables.completion_type= in_completion_type;
758
static void check_limits_dpi(uint32_t in_div_precincrement)
760
global_system_variables.div_precincrement= 4;
761
if (in_div_precincrement > DECIMAL_MAX_SCALE)
763
cout << N_("Error: Invalid Value for div-precision-increment");
766
global_system_variables.div_precincrement= in_div_precincrement;
769
static void check_limits_gcml(uint64_t in_group_concat_max_len)
771
global_system_variables.group_concat_max_len= 1024;
772
if (in_group_concat_max_len > ULONG_MAX || in_group_concat_max_len < 4)
774
cout << N_("Error: Invalid Value for group_concat_max_len");
777
global_system_variables.group_concat_max_len= in_group_concat_max_len;
780
static void check_limits_join_buffer_size(uint64_t in_join_buffer_size)
782
global_system_variables.join_buff_size= (128*1024L);
783
if (in_join_buffer_size < IO_SIZE*2 || in_join_buffer_size > ULONG_MAX)
785
cout << N_("Error: Invalid Value for join_buffer_size");
788
in_join_buffer_size-= in_join_buffer_size % IO_SIZE;
789
global_system_variables.join_buff_size= in_join_buffer_size;
792
static void check_limits_map(uint32_t in_max_allowed_packet)
794
global_system_variables.max_allowed_packet= (64*1024*1024L);
795
if (in_max_allowed_packet < 1024 || in_max_allowed_packet > 1024*1024L*1024L)
797
cout << N_("Error: Invalid Value for max_allowed_packet");
800
in_max_allowed_packet-= in_max_allowed_packet % 1024;
801
global_system_variables.max_allowed_packet= in_max_allowed_packet;
804
static void check_limits_mce(uint64_t in_max_connect_errors)
806
max_connect_errors= MAX_CONNECT_ERRORS;
807
if (in_max_connect_errors < 1 || in_max_connect_errors > ULONG_MAX)
809
cout << N_("Error: Invalid Value for max_connect_errors");
812
max_connect_errors= in_max_connect_errors;
815
static void check_limits_max_err_cnt(uint64_t in_max_error_count)
817
global_system_variables.max_error_count= DEFAULT_ERROR_COUNT;
818
if (in_max_error_count > 65535)
820
cout << N_("Error: Invalid Value for max_error_count");
823
global_system_variables.max_error_count= in_max_error_count;
826
static void check_limits_mhts(uint64_t in_max_heap_table_size)
828
global_system_variables.max_heap_table_size= (16*1024*1024L);
829
if (in_max_heap_table_size < 16384 || in_max_heap_table_size > MAX_MEM_TABLE_SIZE)
831
cout << N_("Error: Invalid Value for max_heap_table_size");
834
in_max_heap_table_size-= in_max_heap_table_size % 1024;
835
global_system_variables.max_heap_table_size= in_max_heap_table_size;
838
static void check_limits_merl(uint64_t in_min_examined_row_limit)
840
global_system_variables.min_examined_row_limit= 0;
841
if (in_min_examined_row_limit > ULONG_MAX)
843
cout << N_("Error: Invalid Value for min_examined_row_limit");
846
global_system_variables.min_examined_row_limit= in_min_examined_row_limit;
849
static void check_limits_max_join_size(drizzled::ha_rows in_max_join_size)
851
global_system_variables.max_join_size= INT32_MAX;
852
if ((uint64_t)in_max_join_size < 1 || (uint64_t)in_max_join_size > INT32_MAX)
854
cout << N_("Error: Invalid Value for max_join_size");
857
global_system_variables.max_join_size= in_max_join_size;
860
static void check_limits_mlfsd(int64_t in_max_length_for_sort_data)
862
global_system_variables.max_length_for_sort_data= 1024;
863
if (in_max_length_for_sort_data < 4 || in_max_length_for_sort_data > 8192*1024L)
865
cout << N_("Error: Invalid Value for max_length_for_sort_data");
868
global_system_variables.max_length_for_sort_data= in_max_length_for_sort_data;
871
static void check_limits_msfk(uint64_t in_max_seeks_for_key)
873
global_system_variables.max_seeks_for_key= ULONG_MAX;
874
if (in_max_seeks_for_key < 1 || in_max_seeks_for_key > ULONG_MAX)
876
cout << N_("Error: Invalid Value for max_seeks_for_key");
879
global_system_variables.max_seeks_for_key= in_max_seeks_for_key;
882
static void check_limits_max_sort_length(size_t in_max_sort_length)
884
global_system_variables.max_sort_length= 1024;
885
if ((int64_t)in_max_sort_length < 4 || (int64_t)in_max_sort_length > 8192*1024L)
887
cout << N_("Error: Invalid Value for max_sort_length");
890
global_system_variables.max_sort_length= in_max_sort_length;
893
static void check_limits_osd(uint32_t in_optimizer_search_depth)
895
global_system_variables.optimizer_search_depth= 0;
896
if (in_optimizer_search_depth > MAX_TABLES + 2)
898
cout << N_("Error: Invalid Value for optimizer_search_depth");
901
global_system_variables.optimizer_search_depth= in_optimizer_search_depth;
904
static void check_limits_pbs(uint64_t in_preload_buff_size)
906
global_system_variables.preload_buff_size= (32*1024L);
907
if (in_preload_buff_size < 1024 || in_preload_buff_size > 1024*1024*1024L)
909
cout << N_("Error: Invalid Value for preload_buff_size");
912
global_system_variables.preload_buff_size= in_preload_buff_size;
915
static void check_limits_qabs(uint32_t in_query_alloc_block_size)
917
global_system_variables.query_alloc_block_size= QUERY_ALLOC_BLOCK_SIZE;
918
if (in_query_alloc_block_size < 1024)
920
cout << N_("Error: Invalid Value for query_alloc_block_size");
923
in_query_alloc_block_size-= in_query_alloc_block_size % 1024;
924
global_system_variables.query_alloc_block_size= in_query_alloc_block_size;
927
static void check_limits_qps(uint32_t in_query_prealloc_size)
929
global_system_variables.query_prealloc_size= QUERY_ALLOC_PREALLOC_SIZE;
930
if (in_query_prealloc_size < QUERY_ALLOC_PREALLOC_SIZE)
932
cout << N_("Error: Invalid Value for query_prealloc_size");
935
in_query_prealloc_size-= in_query_prealloc_size % 1024;
936
global_system_variables.query_prealloc_size= in_query_prealloc_size;
939
static void check_limits_rabs(size_t in_range_alloc_block_size)
941
global_system_variables.range_alloc_block_size= RANGE_ALLOC_BLOCK_SIZE;
942
if (in_range_alloc_block_size < RANGE_ALLOC_BLOCK_SIZE)
944
cout << N_("Error: Invalid Value for range_alloc_block_size");
947
in_range_alloc_block_size-= in_range_alloc_block_size % 1024;
948
global_system_variables.range_alloc_block_size= in_range_alloc_block_size;
951
static void check_limits_read_buffer_size(int32_t in_read_buff_size)
953
global_system_variables.read_buff_size= (128*1024L);
954
if (in_read_buff_size < IO_SIZE*2 || in_read_buff_size > INT32_MAX)
956
cout << N_("Error: Invalid Value for read_buff_size");
959
in_read_buff_size-= in_read_buff_size % IO_SIZE;
960
global_system_variables.read_buff_size= in_read_buff_size;
963
static void check_limits_read_rnd_buffer_size(uint32_t in_read_rnd_buff_size)
965
global_system_variables.read_rnd_buff_size= (256*1024L);
966
if (in_read_rnd_buff_size < 64 || in_read_rnd_buff_size > UINT32_MAX)
968
cout << N_("Error: Invalid Value for read_rnd_buff_size");
971
global_system_variables.read_rnd_buff_size= in_read_rnd_buff_size;
974
static void check_limits_sort_buffer_size(size_t in_sortbuff_size)
976
global_system_variables.sortbuff_size= MAX_SORT_MEMORY;
977
if ((uint32_t)in_sortbuff_size < MIN_SORT_MEMORY)
979
cout << N_("Error: Invalid Value for sort_buff_size");
982
global_system_variables.sortbuff_size= in_sortbuff_size;
985
static void check_limits_tdc(uint32_t in_table_def_size)
988
if (in_table_def_size < 1 || in_table_def_size > 512*1024L)
990
cout << N_("Error: Invalid Value for table_def_size");
993
table_def_size= in_table_def_size;
996
static void check_limits_toc(uint32_t in_table_cache_size)
998
table_cache_size= TABLE_OPEN_CACHE_DEFAULT;
999
if (in_table_cache_size < TABLE_OPEN_CACHE_MIN || in_table_cache_size > 512*1024L)
1001
cout << N_("Error: Invalid Value for table_cache_size");
1004
table_cache_size= in_table_cache_size;
1007
static void check_limits_tlwt(uint64_t in_table_lock_wait_timeout)
1009
table_lock_wait_timeout= 50;
1010
if (in_table_lock_wait_timeout < 1 || in_table_lock_wait_timeout > 1024*1024*1024)
1012
cout << N_("Error: Invalid Value for table_lock_wait_timeout");
1015
table_lock_wait_timeout= in_table_lock_wait_timeout;
1018
static void check_limits_thread_stack(uint32_t in_my_thread_stack_size)
1020
my_thread_stack_size= in_my_thread_stack_size - (in_my_thread_stack_size % 1024);
1023
static void check_limits_tmp_table_size(uint64_t in_tmp_table_size)
1025
global_system_variables.tmp_table_size= 16*1024*1024L;
1026
if (in_tmp_table_size < 1024 || in_tmp_table_size > MAX_MEM_TABLE_SIZE)
1028
cout << N_("Error: Invalid Value for table_lock_wait_timeout");
1031
global_system_variables.tmp_table_size= in_tmp_table_size;
1034
static void check_limits_transaction_message_threshold(size_t in_transaction_message_threshold)
1036
global_system_variables.transaction_message_threshold= 1024*1024;
1037
if ((int64_t) in_transaction_message_threshold < 128*1024 || (int64_t)in_transaction_message_threshold > 1024*1024)
1039
cout << N_("Error: Invalid Value for transaction_message_threshold valid values are between 131072 - 1048576 bytes");
1042
global_system_variables.transaction_message_threshold= in_transaction_message_threshold;
1045
static void process_defaults_files()
1047
for (vector<string>::iterator iter= defaults_file_list.begin();
1048
iter != defaults_file_list.end();
1051
fs::path file_location= *iter;
1053
ifstream input_defaults_file(file_location.file_string().c_str());
1055
po::parsed_options file_parsed=
1056
dpo::parse_config_file(input_defaults_file, full_options, true);
1057
vector<string> file_unknown=
1058
po::collect_unrecognized(file_parsed.options, po::include_positional);
1060
for (vector<string>::iterator it= file_unknown.begin();
1061
it != file_unknown.end();
1064
string new_unknown_opt("--");
1065
new_unknown_opt.append(*it);
1067
if (it != file_unknown.end())
1069
if ((*it) != "true")
1071
new_unknown_opt.push_back('=');
1072
new_unknown_opt.append(*it);
1079
unknown_options.push_back(new_unknown_opt);
1081
store(file_parsed, vm);
1085
static void compose_defaults_file_list(vector<string> in_options)
1087
for (vector<string>::iterator it= in_options.begin();
1088
it != in_options.end();
1092
if (fs::is_regular_file(p))
1093
defaults_file_list.push_back(*it);
1096
errmsg_printf(ERRMSG_LVL_ERROR,
1097
_("Defaults file '%s' not found\n"), (*it).c_str());
1104
int init_common_variables(int argc, char **argv, module::Registry &plugins)
1358
static int init_common_variables(const char *conf_file_name, int argc,
1359
char **argv, const char **groups)
1106
1361
time_t curr_time;
1107
umask(((~internal::my_umask) & 0666));
1362
umask(((~my_umask) & 0666));
1108
1363
my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
1109
1364
tzset(); // Set tzname
1136
1392
if (gethostname(glob_hostname,sizeof(glob_hostname)) < 0)
1138
1394
strncpy(glob_hostname, STRING_WITH_LEN("localhost"));
1139
errmsg_printf(ERRMSG_LVL_WARN, _("gethostname failed, using '%s' as hostname"),
1141
pid_file= "drizzle";
1395
errmsg_printf(ERRMSG_LVL_WARN, _("gethostname failed, using '%s' as hostname"),
1397
strncpy(pidfile_name, STRING_WITH_LEN("drizzle"));
1145
pid_file= glob_hostname;
1147
pid_file.replace_extension(".pid");
1149
system_config_dir /= "drizzle";
1151
config_options.add_options()
1152
("help,?", po::value<bool>(&opt_help)->default_value(false)->zero_tokens(),
1153
N_("Display this help and exit."))
1154
("no-defaults", po::value<bool>()->default_value(false)->zero_tokens(),
1155
N_("Configuration file defaults are not used if no-defaults is set"))
1156
("defaults-file", po::value<vector<string> >()->composing()->notifier(&compose_defaults_file_list),
1157
N_("Configuration file to use"))
1158
("config-dir", po::value<fs::path>(&system_config_dir),
1159
N_("Base location for config files"))
1160
("plugin-dir", po::value<fs::path>(&plugin_dir)->notifier(¬ify_plugin_dir),
1161
N_("Directory for plugins."))
1164
plugin_load_options.add_options()
1165
("plugin-add", po::value<vector<string> >()->composing()->notifier(&compose_plugin_add),
1166
N_("Optional comma separated list of plugins to load at startup in addition "
1167
"to the default list of plugins. "
1168
"[for example: --plugin_add=crc32,logger_gearman]"))
1169
("plugin-remove", po::value<vector<string> >()->composing()->notifier(&compose_plugin_remove),
1170
N_("Optional comma separated list of plugins to not load at startup. Effectively "
1171
"removes a plugin from the list of plugins to be loaded. "
1172
"[for example: --plugin_remove=crc32,logger_gearman]"))
1173
("plugin-load", po::value<string>()->notifier(¬ify_plugin_load)->default_value(PANDORA_PLUGIN_LIST),
1174
N_("Optional comma separated list of plugins to load at starup instead of "
1175
"the default plugin load list. "
1176
"[for example: --plugin_load=crc32,logger_gearman]"))
1179
long_options.add_options()
1180
("auto-increment-increment", po::value<uint64_t>(&global_system_variables.auto_increment_increment)->default_value(1)->notifier(&check_limits_aii),
1181
N_("Auto-increment columns are incremented by this"))
1182
("auto-increment-offset", po::value<uint64_t>(&global_system_variables.auto_increment_offset)->default_value(1)->notifier(&check_limits_aio),
1183
N_("Offset added to Auto-increment columns. Used when auto-increment-increment != 1"))
1184
("basedir,b", po::value<fs::path>(&basedir),
1185
N_("Path to installation directory. All paths are usually resolved "
1186
"relative to this."))
1187
("chroot,r", po::value<string>(),
1188
N_("Chroot drizzled daemon during startup."))
1189
("collation-server", po::value<string>(),
1190
N_("Set the default collation."))
1191
("completion-type", po::value<uint32_t>(&global_system_variables.completion_type)->default_value(0)->notifier(&check_limits_completion_type),
1192
N_("Default completion type."))
1193
("core-file", N_("Write core on errors."))
1194
("datadir", po::value<fs::path>(&data_home),
1195
N_("Path to the database root."))
1196
("default-storage-engine", po::value<string>(),
1197
N_("Set the default storage engine for tables."))
1198
("default-time-zone", po::value<string>(),
1199
N_("Set the default time zone."))
1200
("exit-info,T", po::value<long>(),
1201
N_("Used for debugging; Use at your own risk!"))
1202
("gdb", po::value<bool>(&opt_debugging)->default_value(false)->zero_tokens(),
1203
N_("Set up signals usable for debugging"))
1204
("lc-time-name", po::value<string>(),
1205
N_("Set the language used for the month names and the days of the week."))
1206
("log-warnings,W", po::value<bool>(&global_system_variables.log_warnings)->default_value(false)->zero_tokens(),
1207
N_("Log some not critical warnings to the log file."))
1208
("pid-file", po::value<fs::path>(&pid_file),
1209
N_("Pid file used by drizzled."))
1210
("port-open-timeout", po::value<uint32_t>(&drizzled_bind_timeout)->default_value(0),
1211
N_("Maximum time in seconds to wait for the port to become free. "))
1212
("replicate-query", po::value<bool>(&global_system_variables.replicate_query)->default_value(false)->zero_tokens(),
1213
N_("Include the SQL query in replicated protobuf messages."))
1214
("secure-file-priv", po::value<fs::path>(&secure_file_priv)->notifier(expand_secure_file_priv),
1215
N_("Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
1216
"within specified directory"))
1217
("server-id", po::value<uint32_t>(&server_id)->default_value(0),
1218
N_("Uniquely identifies the server instance in the community of "
1219
"replication partners."))
1220
("skip-stack-trace",
1221
N_("Don't print a stack trace on failure."))
1222
("symbolic-links,s", po::value<bool>(&internal::my_use_symdir)->default_value(IF_PURIFY(false,true))->zero_tokens(),
1223
N_("Enable symbolic link support."))
1224
("timed-mutexes", po::value<bool>(&internal::timed_mutexes)->default_value(false)->zero_tokens(),
1225
N_("Specify whether to time mutexes (only InnoDB mutexes are currently "
1227
("tmpdir,t", po::value<string>(),
1228
N_("Path for temporary files."))
1229
("transaction-isolation", po::value<string>(),
1230
N_("Default transaction isolation level."))
1231
("transaction-message-threshold", po::value<size_t>(&global_system_variables.transaction_message_threshold)->default_value(1024*1024)->notifier(&check_limits_transaction_message_threshold),
1232
N_("Max message size written to transaction log, valid values 131072 - 1048576 bytes."))
1233
("user,u", po::value<string>(),
1234
N_("Run drizzled daemon as user."))
1236
N_("Output version information and exit."))
1237
("back-log", po::value<back_log_constraints>(&back_log),
1238
N_("The number of outstanding connection requests Drizzle can have. This "
1239
"comes into play when the main Drizzle thread gets very many connection "
1240
"requests in a very short time."))
1241
("bulk-insert-buffer-size",
1242
po::value<uint64_t>(&global_system_variables.bulk_insert_buff_size)->default_value(8192*1024),
1243
N_("Size of tree cache used in bulk insert optimization. Note that this is "
1244
"a limit per thread!"))
1245
("div-precision-increment", po::value<uint32_t>(&global_system_variables.div_precincrement)->default_value(4)->notifier(&check_limits_dpi),
1246
N_("Precision of the result of '/' operator will be increased on that "
1248
("group-concat-max-len", po::value<uint64_t>(&global_system_variables.group_concat_max_len)->default_value(1024)->notifier(&check_limits_gcml),
1249
N_("The maximum length of the result of function group_concat."))
1250
("join-buffer-size", po::value<uint64_t>(&global_system_variables.join_buff_size)->default_value(128*1024L)->notifier(&check_limits_join_buffer_size),
1251
N_("The size of the buffer that is used for full joins."))
1252
("join-heap-threshold",
1253
po::value<uint64_t>()->default_value(0),
1254
N_("A global cap on the amount of memory that can be allocated by session join buffers (0 means unlimited)"))
1255
("max-allowed-packet", po::value<uint32_t>(&global_system_variables.max_allowed_packet)->default_value(64*1024*1024L)->notifier(&check_limits_map),
1256
N_("Max packetlength to send/receive from to server."))
1257
("max-connect-errors", po::value<uint64_t>(&max_connect_errors)->default_value(MAX_CONNECT_ERRORS)->notifier(&check_limits_mce),
1258
N_("If there is more than this number of interrupted connections from a "
1259
"host this host will be blocked from further connections."))
1260
("max-error-count", po::value<uint64_t>(&global_system_variables.max_error_count)->default_value(DEFAULT_ERROR_COUNT)->notifier(&check_limits_max_err_cnt),
1261
N_("Max number of errors/warnings to store for a statement."))
1262
("max-heap-table-size", po::value<uint64_t>(&global_system_variables.max_heap_table_size)->default_value(16*1024*1024L)->notifier(&check_limits_mhts),
1263
N_("Don't allow creation of heap tables bigger than this."))
1264
("max-join-size", po::value<drizzled::ha_rows>(&global_system_variables.max_join_size)->default_value(INT32_MAX)->notifier(&check_limits_max_join_size),
1265
N_("Joins that are probably going to read more than max_join_size records "
1266
"return an error."))
1267
("max-length-for-sort-data", po::value<uint64_t>(&global_system_variables.max_length_for_sort_data)->default_value(1024)->notifier(&check_limits_mlfsd),
1268
N_("Max number of bytes in sorted records."))
1269
("max-seeks-for-key", po::value<uint64_t>(&global_system_variables.max_seeks_for_key)->default_value(ULONG_MAX)->notifier(&check_limits_msfk),
1270
N_("Limit assumed max number of seeks when looking up rows based on a key"))
1271
("max-sort-length", po::value<size_t>(&global_system_variables.max_sort_length)->default_value(1024)->notifier(&check_limits_max_sort_length),
1272
N_("The number of bytes to use when sorting BLOB or TEXT values "
1273
"(only the first max_sort_length bytes of each value are used; the "
1274
"rest are ignored)."))
1275
("max-write-lock-count", po::value<uint64_t>(&max_write_lock_count)->default_value(UINT64_MAX),
1276
N_("After this many write locks, allow some read locks to run in between."))
1277
("min-examined-row-limit", po::value<uint64_t>(&global_system_variables.min_examined_row_limit)->default_value(0)->notifier(&check_limits_merl),
1278
N_("Don't log queries which examine less than min_examined_row_limit "
1280
("disable-optimizer-prune",
1281
N_("Do not apply any heuristic(s) during query optimization to prune, "
1282
"thus perform an exhaustive search from the optimizer search space."))
1283
("optimizer-search-depth", po::value<uint32_t>(&global_system_variables.optimizer_search_depth)->default_value(0)->notifier(&check_limits_osd),
1284
N_("Maximum depth of search performed by the query optimizer. Values "
1285
"larger than the number of relations in a query result in better query "
1286
"plans, but take longer to compile a query. Smaller values than the "
1287
"number of tables in a relation result in faster optimization, but may "
1288
"produce very bad query plans. If set to 0, the system will "
1289
"automatically pick a reasonable value; if set to MAX_TABLES+2, the "
1290
"optimizer will switch to the original find_best (used for "
1291
"testing/comparison)."))
1292
("preload-buffer-size", po::value<uint64_t>(&global_system_variables.preload_buff_size)->default_value(32*1024L)->notifier(&check_limits_pbs),
1293
N_("The size of the buffer that is allocated when preloading indexes"))
1294
("query-alloc-block-size",
1295
po::value<uint32_t>(&global_system_variables.query_alloc_block_size)->default_value(QUERY_ALLOC_BLOCK_SIZE)->notifier(&check_limits_qabs),
1296
N_("Allocation block size for query parsing and execution"))
1297
("query-prealloc-size",
1298
po::value<uint32_t>(&global_system_variables.query_prealloc_size)->default_value(QUERY_ALLOC_PREALLOC_SIZE)->notifier(&check_limits_qps),
1299
N_("Persistent buffer for query parsing and execution"))
1300
("range-alloc-block-size",
1301
po::value<size_t>(&global_system_variables.range_alloc_block_size)->default_value(RANGE_ALLOC_BLOCK_SIZE)->notifier(&check_limits_rabs),
1302
N_("Allocation block size for storing ranges during optimization"))
1303
("read-buffer-size",
1304
po::value<uint32_t>(&global_system_variables.read_buff_size)->default_value(128*1024L)->notifier(&check_limits_read_buffer_size),
1305
N_("Each thread that does a sequential scan allocates a buffer of this "
1306
"size for each table it scans. If you do many sequential scans, you may "
1307
"want to increase this value."))
1308
("read-buffer-threshold",
1309
po::value<uint64_t>()->default_value(0),
1310
N_("A global cap on the size of read-buffer-size (0 means unlimited)"))
1311
("read-rnd-buffer-size",
1312
po::value<uint32_t>(&global_system_variables.read_rnd_buff_size)->default_value(256*1024L)->notifier(&check_limits_read_rnd_buffer_size),
1313
N_("When reading rows in sorted order after a sort, the rows are read "
1314
"through this buffer to avoid a disk seeks. If not set, then it's set "
1315
"to the value of record_buffer."))
1316
("read-rnd-threshold",
1317
po::value<uint64_t>()->default_value(0),
1318
N_("A global cap on the size of read-rnd-buffer-size (0 means unlimited)"))
1319
("scheduler", po::value<string>(),
1320
N_("Select scheduler to be used (by default multi-thread)."))
1321
("sort-buffer-size",
1322
po::value<size_t>(&global_system_variables.sortbuff_size)->default_value(MAX_SORT_MEMORY)->notifier(&check_limits_sort_buffer_size),
1323
N_("Each thread that needs to do a sort allocates a buffer of this size."))
1324
("sort-heap-threshold",
1325
po::value<uint64_t>()->default_value(0),
1326
N_("A global cap on the amount of memory that can be allocated by session sort buffers (0 means unlimited)"))
1327
("table-definition-cache", po::value<size_t>(&table_def_size)->default_value(128)->notifier(&check_limits_tdc),
1328
N_("The number of cached table definitions."))
1329
("table-open-cache", po::value<uint64_t>(&table_cache_size)->default_value(TABLE_OPEN_CACHE_DEFAULT)->notifier(&check_limits_toc),
1330
N_("The number of cached open tables."))
1331
("table-lock-wait-timeout", po::value<uint64_t>(&table_lock_wait_timeout)->default_value(50)->notifier(&check_limits_tlwt),
1332
N_("Timeout in seconds to wait for a table level lock before returning an "
1333
"error. Used only if the connection has active cursors."))
1334
("thread-stack", po::value<size_t>(&my_thread_stack_size)->default_value(DEFAULT_THREAD_STACK)->notifier(&check_limits_thread_stack),
1335
N_("The stack size for each thread."))
1337
po::value<uint64_t>(&global_system_variables.tmp_table_size)->default_value(16*1024*1024L)->notifier(&check_limits_tmp_table_size),
1338
N_("If an internal in-memory temporary table exceeds this size, Drizzle will"
1339
" automatically convert it to an on-disk MyISAM table."))
1342
full_options.add(long_options);
1343
full_options.add(plugin_load_options);
1345
initial_options.add(config_options);
1346
initial_options.add(plugin_load_options);
1348
int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
1349
/* Get options about where config files and the like are */
1350
po::parsed_options parsed= po::command_line_parser(argc, argv).style(style).
1351
options(initial_options).allow_unregistered().run();
1353
po::collect_unrecognized(parsed.options, po::include_positional);
1357
po::store(parsed, vm);
1359
catch (std::exception&)
1361
errmsg_printf(ERRMSG_LVL_ERROR, _("Duplicate entry for command line option\n"));
1365
if (not vm["no-defaults"].as<bool>())
1367
fs::path system_config_file_drizzle(system_config_dir);
1368
system_config_file_drizzle /= "drizzled.cnf";
1369
defaults_file_list.insert(defaults_file_list.begin(),
1370
system_config_file_drizzle.file_string());
1372
fs::path config_conf_d_location(system_config_dir);
1373
config_conf_d_location /= "conf.d";
1376
CachedDirectory config_conf_d(config_conf_d_location.file_string());
1377
if (not config_conf_d.fail())
1380
for (CachedDirectory::Entries::const_iterator iter= config_conf_d.getEntries().begin();
1381
iter != config_conf_d.getEntries().end();
1384
string file_entry((*iter)->filename);
1386
if (not file_entry.empty()
1387
&& file_entry != "."
1388
&& file_entry != "..")
1390
fs::path the_entry(config_conf_d_location);
1391
the_entry /= file_entry;
1392
defaults_file_list.push_back(the_entry.file_string());
1398
/* TODO: here is where we should add a process_env_vars */
1400
/* We need a notify here so that plugin_init will work properly */
1405
catch (po::validation_error &err)
1407
errmsg_printf(ERRMSG_LVL_ERROR,
1409
"Use --help to get a list of available options\n"),
1410
internal::my_progname, err.what());
1414
process_defaults_files();
1416
/* Process with notify a second time because a config file may contain
1417
plugin loader options */
1423
catch (po::validation_error &err)
1425
errmsg_printf(ERRMSG_LVL_ERROR,
1427
"Use --help to get a list of available options\n"),
1428
internal::my_progname, err.what());
1432
/* At this point, we've read all the options we need to read from files and
1433
collected most of them into unknown options - now let's load everything
1400
strncpy(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
1401
strcpy(fn_ext(pidfile_name),".pid"); // Add proper extension
1404
Add server status variables to the dynamic list of
1405
status variables that is shown by SHOW STATUS.
1406
Later, in plugin_init, and mysql_install_plugin
1407
new entries could be added to that list.
1436
if (plugin_init(plugins, plugin_options))
1438
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize plugins\n"));
1442
full_options.add(plugin_options);
1444
vector<string> final_unknown_options;
1447
po::parsed_options final_parsed=
1448
po::command_line_parser(unknown_options).style(style).
1449
options(full_options).extra_parser(dpo::parse_size_arg).run();
1451
final_unknown_options=
1452
po::collect_unrecognized(final_parsed.options, po::include_positional);
1454
po::store(final_parsed, vm);
1457
catch (po::validation_error &err)
1459
errmsg_printf(ERRMSG_LVL_ERROR,
1461
"Use --help to get a list of available options\n"),
1462
internal::my_progname, err.what());
1465
catch (po::invalid_command_line_syntax &err)
1467
errmsg_printf(ERRMSG_LVL_ERROR,
1469
"Use --help to get a list of available options\n"),
1470
internal::my_progname, err.what());
1473
catch (po::unknown_option &err)
1475
errmsg_printf(ERRMSG_LVL_ERROR,
1476
_("%s\nUse --help to get a list of available options\n"),
1485
catch (po::validation_error &err)
1487
errmsg_printf(ERRMSG_LVL_ERROR,
1489
"Use --help to get a list of available options\n"),
1490
internal::my_progname, err.what());
1496
/* Inverted Booleans */
1498
global_system_variables.optimizer_prune_level=
1499
vm.count("disable-optimizer-prune") ? false : true;
1501
if (vm.count("help") == 0 && vm.count("help-extended") == 0)
1503
if ((user_info= check_user(drizzled_user)))
1505
set_user(drizzled_user, user_info);
1511
current_pid= getpid(); /* Save for later ref */
1409
if (add_status_vars(status_vars))
1410
return 1; // an error was already reported
1412
load_defaults(conf_file_name, groups, &argc, &argv);
1415
get_options(&defaults_argc, defaults_argv);
1416
set_server_version();
1419
/* connections and databases needs lots of files */
1420
(void) my_set_max_open_files(0xFFFFFFFF);
1422
current_pid=(ulong) getpid(); /* Save for later ref */
1512
1423
init_time(); /* Init time-functions (read zone) */
1425
if (init_errmessage()) /* Read error messages from file */
1514
1427
if (item_create_init())
1518
1431
/* Creates static regex matching for temporal values */
1519
1432
if (! init_temporal_formats())
1522
if (!(default_charset_info=
1523
get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)))
1435
Process a comma-separated character set list and choose
1436
the first available character set. This is mostly for
1437
test purposes, to be able to start "mysqld" even if
1438
the requested character set is not available (see bug#18743).
1525
errmsg_printf(ERRMSG_LVL_ERROR, _("Error getting default charset"));
1526
return 1; // Eof of the list
1442
char *next_character_set_name= strchr(default_character_set_name, ',');
1443
if (next_character_set_name)
1444
*next_character_set_name++= '\0';
1445
if (!(default_charset_info=
1446
get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)))
1448
if (next_character_set_name)
1450
default_character_set_name= next_character_set_name;
1451
default_collation_name= 0; // Ignore collation
1454
return 1; // Eof of the list
1529
if (vm.count("scheduler"))
1530
opt_scheduler= vm["scheduler"].as<string>().c_str();
1532
1460
if (default_collation_name)
1534
1462
const CHARSET_INFO * const default_collation= get_charset_by_name(default_collation_name);
1535
if (not default_collation)
1463
if (!default_collation)
1537
errmsg_printf(ERRMSG_LVL_ERROR, _(ER(ER_UNKNOWN_COLLATION)), default_collation_name);
1465
errmsg_printf(ERRMSG_LVL_ERROR, _(ER(ER_UNKNOWN_COLLATION)), default_collation_name);
1540
if (not my_charset_same(default_charset_info, default_collation))
1468
if (!my_charset_same(default_charset_info, default_collation))
1542
errmsg_printf(ERRMSG_LVL_ERROR, _(ER(ER_COLLATION_CHARSET_MISMATCH)),
1543
default_collation_name,
1544
default_charset_info->csname);
1470
errmsg_printf(ERRMSG_LVL_ERROR, _(ER(ER_COLLATION_CHARSET_MISMATCH)),
1471
default_collation_name,
1472
default_charset_info->csname);
1547
1475
default_charset_info= default_collation;
1549
1477
/* Set collactions that depends on the default collation */
1550
1478
global_system_variables.collation_server= default_charset_info;
1552
if (not (character_set_filesystem=
1553
get_charset_by_csname(character_set_filesystem_name, MY_CS_PRIMARY)))
1555
errmsg_printf(ERRMSG_LVL_ERROR, _("Error setting collation"));
1479
global_system_variables.collation_database= default_charset_info;
1481
global_system_variables.optimizer_use_mrr= 1;
1482
global_system_variables.optimizer_switch= 0;
1484
if (!(character_set_filesystem=
1485
get_charset_by_csname(character_set_filesystem_name, MY_CS_PRIMARY)))
1558
1487
global_system_variables.character_set_filesystem= character_set_filesystem;
1560
1489
if (!(my_default_lc_time_names=
1561
1490
my_locale_by_name(lc_time_names_name)))
1563
errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown locale: '%s'"), lc_time_names_name);
1492
errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown locale: '%s'"), lc_time_names_name);
1566
1495
global_system_variables.lc_time_names= my_default_lc_time_names;
1568
/* Reset table_alias_charset */
1497
sys_init_connect.value_length= 0;
1498
if ((sys_init_connect.value= opt_init_connect))
1499
sys_init_connect.value_length= strlen(opt_init_connect);
1501
sys_init_connect.value=strdup("");
1502
if (sys_init_connect.value == NULL)
1505
if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
1508
/* Reset table_alias_charset, now that lower_case_table_names is set. */
1509
lower_case_table_names= 1; /* This we need to look at */
1569
1510
table_alias_charset= files_charset_info;
1575
int init_server_components(module::Registry &plugins)
1516
static int init_thread_environment()
1518
(void) pthread_mutex_init(&LOCK_drizzleclient_create_db,MY_MUTEX_INIT_SLOW);
1519
(void) pthread_mutex_init(&LOCK_lock_db,MY_MUTEX_INIT_SLOW);
1520
(void) pthread_mutex_init(&LOCK_open, NULL);
1521
(void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
1522
(void) pthread_mutex_init(&LOCK_status,MY_MUTEX_INIT_FAST);
1523
(void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
1524
(void) pthread_rwlock_init(&LOCK_system_variables_hash, NULL);
1525
(void) pthread_mutex_init(&LOCK_global_read_lock, MY_MUTEX_INIT_FAST);
1526
(void) pthread_rwlock_init(&LOCK_sys_init_connect, NULL);
1527
(void) pthread_cond_init(&COND_thread_count,NULL);
1528
(void) pthread_cond_init(&COND_refresh,NULL);
1529
(void) pthread_cond_init(&COND_global_read_lock,NULL);
1531
if (pthread_key_create(&THR_Session,NULL) ||
1532
pthread_key_create(&THR_Mem_root,NULL))
1534
errmsg_printf(ERRMSG_LVL_ERROR, _("Can't create thread-keys"));
1541
static int init_server_components()
1578
1544
We need to call each of these following functions to ensure that
1579
1545
all things are initialized so that unireg_abort() doesn't fail
1581
if (table_cache_init())
1583
errmsg_printf(ERRMSG_LVL_ERROR, _("Could not initialize table cache\n"));
1547
if (table_cache_init() | table_def_init())
1584
1548
unireg_abort(1);
1587
// Resize the definition Cache at startup
1588
table::Cache::singleton().rehash(table_def_size);
1589
definition::Cache::singleton().rehash(table_def_size);
1590
message::Cache::singleton().rehash(table_def_size);
1550
drizzleclient_randominit(&sql_rand,
1551
(uint64_t) server_start_time,
1552
(uint64_t) server_start_time/2);
1594
1556
/* Setup logs */
1596
1558
if (xid_cache_init())
1598
errmsg_printf(ERRMSG_LVL_ERROR, _("XA cache initialization failed: Out of memory\n"));
1560
errmsg_printf(ERRMSG_LVL_ERROR, _("Out of memory"));
1599
1561
unireg_abort(1);
1564
/* call ha_init_key_cache() on all key caches to init them */
1565
process_key_caches(&ha_init_key_cache);
1602
1567
/* Allow storage engine to give real error messages */
1568
if (ha_init_errors())
1571
if (plugin_init(&defaults_argc, defaults_argv,
1572
(opt_noacl ? PLUGIN_INIT_SKIP_PLUGIN_TABLE : 0) |
1573
(opt_help ? PLUGIN_INIT_SKIP_INITIALIZATION : 0)))
1575
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize plugins."));
1607
1580
unireg_abort(0);
1609
if (plugin_finalize(plugins))
1582
/* we do want to exit if there are any other unknown options */
1583
if (defaults_argc > 1)
1586
char **tmp_argv= defaults_argv;
1587
struct my_option no_opts[]=
1589
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
1592
We need to eat any 'loose' arguments first before we conclude
1593
that there are unprocessed options.
1594
But we need to preserve defaults_argv pointer intact for
1595
free_defaults() to work. Thus we use a copy here.
1597
my_getopt_skip_unknown= 0;
1599
if ((ho_error= handle_options(&defaults_argc, &tmp_argv, no_opts,
1600
drizzled_get_one_option)))
1601
unireg_abort(ho_error);
1606
_("%s: Too many arguments (first extra is '%s').\n"
1607
"Use --verbose --help to get a list of available options\n"),
1608
my_progname, *tmp_argv);
1613
/* We have to initialize the storage engines before CSV logging */
1616
errmsg_printf(ERRMSG_LVL_ERROR, _("Can't init databases"));
1611
1617
unireg_abort(1);
1614
string scheduler_name;
1617
scheduler_name= opt_scheduler;
1621
scheduler_name= opt_scheduler_default;
1622
opt_scheduler= opt_scheduler_default;
1625
if (plugin::Scheduler::setPlugin(scheduler_name))
1627
errmsg_printf(ERRMSG_LVL_ERROR,
1628
_("No scheduler found, cannot continue!\n"));
1633
This is entirely for legacy. We will create a new "disk based" engine and a
1634
"memory" engine which will be configurable longterm.
1636
const std::string myisam_engine_name("MyISAM");
1637
const std::string heap_engine_name("MEMORY");
1638
myisam_engine= plugin::StorageEngine::findByName(myisam_engine_name);
1639
heap_engine= plugin::StorageEngine::findByName(heap_engine_name);
1642
1621
Check that the default storage engine is actually available.
1644
1623
if (default_storage_engine_str)
1646
const std::string name(default_storage_engine_str);
1647
plugin::StorageEngine *engine;
1625
LEX_STRING name= { default_storage_engine_str,
1626
strlen(default_storage_engine_str) };
1649
engine= plugin::StorageEngine::findByName(name);
1652
errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown/unsupported storage engine: %s\n"),
1630
if ((plugin= ha_resolve_by_name(0, &name)))
1632
hton= plugin_data(plugin,handlerton *);
1636
errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown/unsupported table type: %s"),
1637
default_storage_engine_str);
1640
if (!ha_storage_engine_is_enabled(hton))
1642
errmsg_printf(ERRMSG_LVL_ERROR, _("Default storage engine (%s) is not available"),
1653
1643
default_storage_engine_str);
1654
1644
unireg_abort(1);
1656
global_system_variables.storage_engine= engine;
1645
//assert(global_system_variables.table_plugin);
1650
Need to unlock as global_system_variables.table_plugin
1651
was acquired during plugin_init()
1653
plugin_unlock(0, global_system_variables.table_plugin);
1654
global_system_variables.table_plugin= plugin;
1659
if (plugin::XaResourceManager::recoverAllXids())
1661
/* This function alredy generates error messages */
1662
1660
unireg_abort(1);
1663
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
1664
if (locked_in_memory && !getuid())
1666
if (setreuid((uid_t)-1, 0) == -1)
1667
{ // this should never happen
1668
sql_perror("setreuid");
1671
if (mlockall(MCL_CURRENT))
1673
if (global_system_variables.log_warnings)
1674
errmsg_printf(ERRMSG_LVL_WARN, _("Failed to lock memory. Errno: %d\n"),errno);
1675
locked_in_memory= 0;
1678
set_user(drizzled_user, user_info);
1665
1684
init_update_queries();
1689
int main(int argc, char **argv)
1691
#if defined(ENABLE_NLS)
1692
# if defined(HAVE_LOCALE_H)
1693
setlocale(LC_ALL, "");
1695
bindtextdomain("drizzle", LOCALEDIR);
1696
textdomain("drizzle");
1699
MY_INIT(argv[0]); // init my_sys library & pthreads
1700
/* nothing should come before this line ^^^ */
1702
/* Set signal used to kill Drizzle */
1703
#if defined(SIGUSR2)
1704
thr_kill_signal= thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2;
1706
thr_kill_signal= SIGINT;
1709
#ifdef _CUSTOMSTARTUPCONFIG_
1710
if (_cust_check_startup())
1712
/ * _cust_check_startup will report startup failure error * /
1717
if (init_common_variables(DRIZZLE_CONFIG_NAME,
1718
argc, argv, load_default_groups))
1719
unireg_abort(1); // Will do exit
1723
#ifdef TODO_MOVE_OUT_TO_SCHEDULER_API
1724
pthread_attr_setstacksize(&connection_attrib, my_thread_stack_size);
1726
#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
1728
/* Retrieve used stack size; Needed for checking stack overflows */
1729
size_t stack_size= 0;
1730
pthread_attr_getstacksize(&connection_attrib, &stack_size);
1731
/* We must check if stack_size = 0 as Solaris 2.9 can return 0 here */
1732
if (stack_size && stack_size < my_thread_stack_size)
1734
if (global_system_variables.log_warnings)
1736
errmsg_printf(ERRMSG_LVL_WARN, _("Asked for %"PRIu64" thread stack, "
1738
(uint64_t)my_thread_stack_size,
1739
(uint64_t)stack_size);
1741
my_thread_stack_size= stack_size;
1747
select_thread=pthread_self();
1748
select_thread_in_use=1;
1751
We have enough space for fiddling with the argv, continue
1753
check_data_home(drizzle_real_data_home);
1754
if (chdir(drizzle_real_data_home) && !opt_help)
1755
unireg_abort(1); /* purecov: inspected */
1756
drizzle_data_home= drizzle_data_home_buff;
1757
drizzle_data_home[0]=FN_CURLIB; // all paths are relative from here
1758
drizzle_data_home[1]=0;
1759
drizzle_data_home_len= 2;
1761
if ((user_info= check_user(drizzled_user)))
1763
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
1764
if (locked_in_memory) // getuid() == 0 here
1765
set_effective_user(user_info);
1768
set_user(drizzled_user, user_info);
1776
if (init_server_components())
1781
safe_read_error_hook= safe_read_error_impl;
1784
init signals & alarm
1785
After this we can't quit by a simple unireg_abort
1787
error_handler_hook= my_message_sql;
1789
if (drizzle_rm_tmp_tables() || my_tz_init((Session *)0, default_tz_name))
1792
select_thread_in_use=0;
1793
(void) pthread_kill(signal_thread, SIGTERM);
1795
(void) unlink(pidfile_name); // Not needed anymore
1802
errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)),my_progname,server_version,
1803
"", drizzled_port, COMPILATION_COMMENT);
1806
handle_connections_sockets();
1807
/* (void) pthread_attr_destroy(&connection_attrib); */
1810
(void) pthread_mutex_lock(&LOCK_thread_count);
1811
select_thread_in_use=0; // For close_connections
1812
(void) pthread_mutex_unlock(&LOCK_thread_count);
1813
(void) pthread_cond_broadcast(&COND_thread_count);
1815
/* Wait until cleanup is done */
1816
(void) pthread_mutex_lock(&LOCK_thread_count);
1817
while (!ready_to_exit)
1818
pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
1819
(void) pthread_mutex_unlock(&LOCK_thread_count);
1823
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
1829
Create new thread to handle incoming connection.
1831
This function will create new thread to handle the incoming
1832
connection. If there are idle cached threads one will be used.
1833
'session' will be pushed into 'threads'.
1835
In single-threaded mode (\#define ONE_THREAD) connection will be
1836
handled inside this function.
1838
@param[in,out] session Thread handle of future thread.
1841
static void create_new_thread(Session *session)
1845
if (connection_count > max_used_connections)
1846
max_used_connections= connection_count;
1849
The initialization of thread_id is done in create_embedded_session() for
1850
the embedded library.
1851
TODO: refactor this to avoid code duplication there
1853
session->thread_id= session->variables.pseudo_thread_id= thread_id++;
1856
If we error on creation we drop the connection and delete the session.
1858
pthread_mutex_lock(&LOCK_thread_count);
1859
session_list.append(session);
1860
pthread_mutex_unlock(&LOCK_thread_count);
1861
if (thread_scheduler.add_connection(session))
1863
char error_message_buff[DRIZZLE_ERRMSG_SIZE];
1865
session->killed= Session::KILL_CONNECTION; // Safety
1867
statistic_increment(aborted_connects, &LOCK_status);
1869
/* Can't use my_error() since store_globals has not been called. */
1870
snprintf(error_message_buff, sizeof(error_message_buff), ER(ER_CANT_CREATE_THREAD), 1); /* TODO replace will better error message */
1871
net_send_error(session, ER_CANT_CREATE_THREAD, error_message_buff);
1872
unlink_session(session);
1877
/* Handle new connections and spawn new process to handle them */
1879
void handle_connections_sockets()
1883
uint32_t error_count=0;
1885
struct sockaddr_storage cAddr;
1891
if ((number_of= poll(fds, pollfd_count, -1)) == -1)
1895
if (!select_errors++ && !abort_loop) /* purecov: inspected */
1896
errmsg_printf(ERRMSG_LVL_ERROR, _("drizzled: Got error %d from select"),
1897
errno); /* purecov: inspected */
1904
#ifdef FIXME_IF_WE_WERE_KEEPING_THIS
1905
assert(number_of > 1); /* Not handling this at the moment */
1913
for (x= 0, sock= -1; x < pollfd_count; x++)
1915
if (fds[x].revents == POLLIN)
1923
for (uint32_t retry=0; retry < MAX_ACCEPT_RETRY; retry++)
1925
socklen_t length= sizeof(struct sockaddr_storage);
1926
new_sock= accept(sock, (struct sockaddr *)(&cAddr),
1928
if (new_sock != -1 || (errno != EINTR && errno != EAGAIN))
1935
if ((error_count++ & 255) == 0) // This can happen often
1936
sql_perror("Error in accept");
1937
if (errno == ENFILE || errno == EMFILE)
1938
sleep(1); // Give other threads some time
1944
struct sockaddr_storage dummy;
1945
dummyLen = sizeof(dummy);
1946
if ( getsockname(new_sock,(struct sockaddr *)&dummy,
1947
(socklen_t *)&dummyLen) < 0 )
1949
sql_perror("Error on new connection socket");
1950
(void) shutdown(new_sock, SHUT_RDWR);
1951
(void) close(new_sock);
1954
dummyLen = sizeof(dummy);
1955
if ( getpeername(new_sock, (struct sockaddr *)&dummy,
1956
(socklen_t *)&dummyLen) < 0)
1958
sql_perror("Error on new connection socket");
1959
(void) shutdown(new_sock, SHUT_RDWR);
1960
(void) close(new_sock);
1966
** Don't allow too many connections
1969
if (!(session= new Session))
1971
(void) shutdown(new_sock, SHUT_RDWR);
1975
if (drizzleclient_net_init_sock(&session->net, new_sock, sock == 0))
1981
create_new_thread(session);
1671
1986
/****************************************************************************
1672
1987
Handle start options
1673
1988
******************************************************************************/
1675
1990
enum options_drizzled
1994
OPT_BIND_ADDRESS, OPT_PID_FILE,
1680
1995
OPT_STORAGE_ENGINE,
1997
OPT_DELAY_KEY_WRITE_ALL,
1998
OPT_DELAY_KEY_WRITE,
1685
2003
OPT_TC_HEURISTIC_RECOVER,
2004
OPT_ENGINE_CONDITION_PUSHDOWN,
1686
2005
OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE,
1687
2006
OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
1689
2008
OPT_LOCAL_INFILE,
2010
OPT_CONNECT_TIMEOUT,
1691
2011
OPT_JOIN_BUFF_SIZE,
2012
OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_BLOCK_SIZE,
2013
OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_AGE_THRESHOLD,
1692
2014
OPT_MAX_ALLOWED_PACKET,
1693
2015
OPT_MAX_CONNECT_ERRORS,
1694
2016
OPT_MAX_HEP_TABLE_SIZE,
1798
2148
N_("Set up signals usable for debugging"),
1799
2149
(char**) &opt_debugging, (char**) &opt_debugging,
1800
2150
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
2151
{"init-connect", OPT_INIT_CONNECT,
2152
N_("Command(s) that are executed for each new connection"),
2153
(char**) &opt_init_connect, (char**) &opt_init_connect, 0, GET_STR_ALLOC,
2154
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
2155
{"init-file", OPT_INIT_FILE,
2156
N_("Read SQL commands from this file at startup."),
2157
(char**) &opt_init_file, (char**) &opt_init_file, 0, GET_STR, REQUIRED_ARG,
2161
(char**) &language_ptr, (char**) &language_ptr, 0, GET_STR, REQUIRED_ARG,
1801
2163
{"lc-time-names", OPT_LC_TIME_NAMES,
1802
2164
N_("Set the language used for the month names and the days of the week."),
1803
2165
(char**) &lc_time_names_name,
1804
2166
(char**) &lc_time_names_name,
1805
2167
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
2169
N_("Log connections and queries to file."),
2170
(char**) &opt_logname,
2171
(char**) &opt_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
2172
{"log-isam", OPT_ISAM_LOG,
2173
N_("Log all MyISAM changes to file."),
2174
(char**) &myisam_log_filename, (char**) &myisam_log_filename, 0, GET_STR,
2175
OPT_ARG, 0, 0, 0, 0, 0, 0},
1806
2176
{"log-warnings", 'W',
1807
2177
N_("Log some not critical warnings to the log file."),
1808
2178
(char**) &global_system_variables.log_warnings,
1809
2179
(char**) &max_system_variables.log_warnings, 0, GET_BOOL, OPT_ARG, 1, 0, 0,
2181
{"memlock", OPT_MEMLOCK,
2182
N_("Lock drizzled in memory."),
2183
(char**) &locked_in_memory,
2184
(char**) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
2185
{"myisam-recover", OPT_MYISAM_RECOVER,
2186
N_("Syntax: myisam-recover[=option[,option...]], where option can be "
2187
"DEFAULT, BACKUP, FORCE or QUICK."),
2188
(char**) &myisam_recover_options_str, (char**) &myisam_recover_options_str, 0,
2189
GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
2190
{"old-alter-table", OPT_OLD_ALTER_TABLE,
2191
N_("Use old, non-optimized alter table."),
2192
(char**) &global_system_variables.old_alter_table,
2193
(char**) &max_system_variables.old_alter_table, 0, GET_BOOL, NO_ARG,
1811
2195
{"pid-file", OPT_PID_FILE,
1812
N_("Pid file used by drizzled."),
1813
NULL, NULL, 0, GET_STR,
2196
N_("Pid file used by safe_mysqld."),
2197
(char**) &pidfile_name_ptr, (char**) &pidfile_name_ptr, 0, GET_STR,
1814
2198
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
2200
N_("Port number to use for connection or 0 for default to, in "
2201
"order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
2202
"built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ")."),
2203
(char**) &drizzled_port,
2204
(char**) &drizzled_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1815
2205
{"port-open-timeout", OPT_PORT_OPEN_TIMEOUT,
1816
2206
N_("Maximum time in seconds to wait for the port to become free. "
1817
2207
"(Default: no wait)"),
1818
(char**) &drizzled_bind_timeout,
1819
(char**) &drizzled_bind_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
2208
(char**) &drizzled_port_timeout,
2209
(char**) &drizzled_port_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1820
2210
{"secure-file-priv", OPT_SECURE_FILE_PRIV,
1821
2211
N_("Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
1822
2212
"within specified directory"),
2213
(char**) &opt_secure_file_priv, (char**) &opt_secure_file_priv, 0,
1824
2214
GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1825
2215
{"server-id", OPT_SERVER_ID,
1826
2216
N_("Uniquely identifies the server instance in the community of "
2053
2510
(char**) &my_thread_stack_size,
2054
2511
(char**) &my_thread_stack_size, 0, GET_SIZE,
2055
2512
REQUIRED_ARG,DEFAULT_THREAD_STACK,
2056
UINT32_C(1024*512), (int64_t)SIZE_MAX, 0, 1024, 0},
2513
UINT32_C(1024*128), SIZE_MAX, 0, 1024, 0},
2057
2514
{"tmp_table_size", OPT_TMP_TABLE_SIZE,
2058
2515
N_("If an internal in-memory temporary table exceeds this size, Drizzle will"
2059
2516
" automatically convert it to an on-disk MyISAM table."),
2060
2517
(char**) &global_system_variables.tmp_table_size,
2061
2518
(char**) &max_system_variables.tmp_table_size, 0, GET_ULL,
2062
REQUIRED_ARG, 16*1024*1024L, 1024, (int64_t)MAX_MEM_TABLE_SIZE, 0, 1, 0},
2519
REQUIRED_ARG, 16*1024*1024L, 1024, MAX_MEM_TABLE_SIZE, 0, 1, 0},
2520
{"transaction_alloc_block_size", OPT_TRANS_ALLOC_BLOCK_SIZE,
2521
N_("Allocation block size for transactions to be stored in binary log"),
2522
(char**) &global_system_variables.trans_alloc_block_size,
2523
(char**) &max_system_variables.trans_alloc_block_size, 0, GET_UINT,
2524
REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
2525
{"transaction_prealloc_size", OPT_TRANS_PREALLOC_SIZE,
2526
N_("Persistent buffer for transactions to be stored in binary log"),
2527
(char**) &global_system_variables.trans_prealloc_size,
2528
(char**) &max_system_variables.trans_prealloc_size, 0, GET_UINT,
2529
REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
2530
{"wait_timeout", OPT_WAIT_TIMEOUT,
2531
N_("The number of seconds the server waits for activity on a connection "
2532
"before closing it."),
2533
(char**) &global_system_variables.net_wait_timeout,
2534
(char**) &max_system_variables.net_wait_timeout, 0, GET_UINT,
2535
REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT,
2063
2537
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
2540
static int show_net_compression(Session *session,
2544
var->type= SHOW_MY_BOOL;
2545
var->value= (char *)&session->net.compress;
2549
static st_show_var_func_container
2550
show_net_compression_cont= { &show_net_compression };
2552
static int show_starttime(Session *session, SHOW_VAR *var, char *buff)
2554
var->type= SHOW_LONG;
2556
*((long *)buff)= (long) (session->query_start() - server_start_time);
2560
static st_show_var_func_container
2561
show_starttime_cont= { &show_starttime };
2563
static int show_flushstatustime(Session *session, SHOW_VAR *var, char *buff)
2565
var->type= SHOW_LONG;
2567
*((long *)buff)= (long) (session->query_start() - flush_status_time);
2571
static st_show_var_func_container
2572
show_flushstatustime_cont= { &show_flushstatustime };
2574
static int show_open_tables(Session *, SHOW_VAR *var, char *buff)
2576
var->type= SHOW_LONG;
2578
*((long *)buff)= (long)cached_open_tables();
2582
static int show_table_definitions(Session *,
2583
SHOW_VAR *var, char *buff)
2585
var->type= SHOW_LONG;
2587
*((long *)buff)= (long)cached_table_definitions();
2591
static st_show_var_func_container
2592
show_open_tables_cont= { &show_open_tables };
2593
static st_show_var_func_container
2594
show_table_definitions_cont= { &show_table_definitions };
2597
Variables shown by SHOW STATUS in alphabetical order
2600
SHOW_VAR status_vars[]= {
2601
{"Aborted_clients", (char*) &aborted_threads, SHOW_LONGLONG},
2602
{"Aborted_connects", (char*) &aborted_connects, SHOW_LONGLONG},
2603
{"Bytes_received", (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONGLONG_STATUS},
2604
{"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS},
2605
{"Com", (char*) com_status_vars, SHOW_ARRAY},
2606
{"Compression", (char*) &show_net_compression_cont, SHOW_FUNC},
2607
{"Connections", (char*) &thread_id, SHOW_INT_NOFLUSH},
2608
{"Created_tmp_disk_tables", (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS},
2609
{"Created_tmp_files", (char*) &my_tmp_file_created,SHOW_INT},
2610
{"Created_tmp_tables", (char*) offsetof(STATUS_VAR, created_tmp_tables), SHOW_LONG_STATUS},
2611
{"Flush_commands", (char*) &refresh_version, SHOW_INT_NOFLUSH},
2612
{"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
2613
{"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS},
2614
{"Handler_prepare", (char*) offsetof(STATUS_VAR, ha_prepare_count), SHOW_LONG_STATUS},
2615
{"Handler_read_first", (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS},
2616
{"Handler_read_key", (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS},
2617
{"Handler_read_next", (char*) offsetof(STATUS_VAR, ha_read_next_count), SHOW_LONG_STATUS},
2618
{"Handler_read_prev", (char*) offsetof(STATUS_VAR, ha_read_prev_count), SHOW_LONG_STATUS},
2619
{"Handler_read_rnd", (char*) offsetof(STATUS_VAR, ha_read_rnd_count), SHOW_LONG_STATUS},
2620
{"Handler_read_rnd_next", (char*) offsetof(STATUS_VAR, ha_read_rnd_next_count), SHOW_LONG_STATUS},
2621
{"Handler_rollback", (char*) offsetof(STATUS_VAR, ha_rollback_count), SHOW_LONG_STATUS},
2622
{"Handler_savepoint", (char*) offsetof(STATUS_VAR, ha_savepoint_count), SHOW_LONG_STATUS},
2623
{"Handler_savepoint_rollback",(char*) offsetof(STATUS_VAR, ha_savepoint_rollback_count), SHOW_LONG_STATUS},
2624
{"Handler_update", (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS},
2625
{"Handler_write", (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS},
2626
{"Key_blocks_not_flushed", (char*) offsetof(KEY_CACHE, global_blocks_changed), SHOW_KEY_CACHE_LONG},
2627
{"Key_blocks_unused", (char*) offsetof(KEY_CACHE, blocks_unused), SHOW_KEY_CACHE_LONG},
2628
{"Key_blocks_used", (char*) offsetof(KEY_CACHE, blocks_used), SHOW_KEY_CACHE_LONG},
2629
{"Key_read_requests", (char*) offsetof(KEY_CACHE, global_cache_r_requests), SHOW_KEY_CACHE_LONGLONG},
2630
{"Key_reads", (char*) offsetof(KEY_CACHE, global_cache_read), SHOW_KEY_CACHE_LONGLONG},
2631
{"Key_write_requests", (char*) offsetof(KEY_CACHE, global_cache_w_requests), SHOW_KEY_CACHE_LONGLONG},
2632
{"Key_writes", (char*) offsetof(KEY_CACHE, global_cache_write), SHOW_KEY_CACHE_LONGLONG},
2633
{"Last_query_cost", (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS},
2634
{"Max_used_connections", (char*) &max_used_connections, SHOW_INT},
2635
{"Open_files", (char*) &my_file_opened, SHOW_INT_NOFLUSH},
2636
{"Open_streams", (char*) &my_stream_opened, SHOW_INT_NOFLUSH},
2637
{"Open_table_definitions", (char*) &show_table_definitions_cont, SHOW_FUNC},
2638
{"Open_tables", (char*) &show_open_tables_cont, SHOW_FUNC},
2639
{"Opened_files", (char*) &my_file_total_opened, SHOW_INT_NOFLUSH},
2640
{"Opened_tables", (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS},
2641
{"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS},
2642
{"Questions", (char*) offsetof(STATUS_VAR, questions), SHOW_LONG_STATUS},
2643
{"Select_full_join", (char*) offsetof(STATUS_VAR, select_full_join_count), SHOW_LONG_STATUS},
2644
{"Select_full_range_join", (char*) offsetof(STATUS_VAR, select_full_range_join_count), SHOW_LONG_STATUS},
2645
{"Select_range", (char*) offsetof(STATUS_VAR, select_range_count), SHOW_LONG_STATUS},
2646
{"Select_range_check", (char*) offsetof(STATUS_VAR, select_range_check_count), SHOW_LONG_STATUS},
2647
{"Select_scan", (char*) offsetof(STATUS_VAR, select_scan_count), SHOW_LONG_STATUS},
2648
{"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONGLONG},
2649
{"Slow_queries", (char*) offsetof(STATUS_VAR, long_query_count), SHOW_LONG_STATUS},
2650
{"Sort_merge_passes", (char*) offsetof(STATUS_VAR, filesort_merge_passes), SHOW_LONG_STATUS},
2651
{"Sort_range", (char*) offsetof(STATUS_VAR, filesort_range_count), SHOW_LONG_STATUS},
2652
{"Sort_rows", (char*) offsetof(STATUS_VAR, filesort_rows), SHOW_LONG_STATUS},
2653
{"Sort_scan", (char*) offsetof(STATUS_VAR, filesort_scan_count), SHOW_LONG_STATUS},
2654
{"Table_locks_immediate", (char*) &locks_immediate, SHOW_INT},
2655
{"Table_locks_waited", (char*) &locks_waited, SHOW_INT},
2656
{"Threads_connected", (char*) &connection_count, SHOW_INT},
2657
{"Uptime", (char*) &show_starttime_cont, SHOW_FUNC},
2658
{"Uptime_since_flush_status",(char*) &show_flushstatustime_cont, SHOW_FUNC},
2659
{NULL, NULL, SHOW_LONGLONG}
2066
2662
static void print_version(void)
2664
set_server_version();
2069
2666
Note: the instance manager keys off the string 'Ver' so it can find the
2070
2667
version from the output of 'drizzled --version', so don't change it!
2072
printf("%s Ver %s for %s-%s on %s (%s)\n",internal::my_progname,
2073
PANDORA_RELEASE_VERSION, HOST_VENDOR, HOST_OS, HOST_CPU,
2074
COMPILATION_COMMENT);
2669
printf("%s Ver %s for %s on %s (%s)\n",my_progname,
2670
server_version,SYSTEM_TYPE,MACHINE_TYPE, COMPILATION_COMMENT);
2077
2673
static void usage(void)
2190
2803
have_symlink=SHOW_OPTION_YES;
2807
if (!(tmpenv = getenv("MY_BASEDIR_VERSION")))
2809
(void) strncpy(drizzle_home, tmpenv, sizeof(drizzle_home)-1);
2193
2811
connection_count= 0;
2199
- FIXME add EXIT_TOO_MANY_ARGUMENTS to "drizzled/error.h" and return that code?
2201
static void get_options()
2816
drizzled_get_one_option(int optid, const struct my_option *opt,
2204
fs::path &data_home_catalog= getDataHomeCatalog();
2205
data_home_catalog= getDataHome();
2206
data_home_catalog /= "local";
2208
if (vm.count("user"))
2210
if (! drizzled_user || ! strcmp(drizzled_user, vm["user"].as<string>().c_str()))
2211
drizzled_user= (char *)vm["user"].as<string>().c_str();
2821
opt_endinfo=1; /* unireg: memory allocation */
2824
global_system_variables.tx_isolation= ISO_SERIALIZABLE;
2827
strncpy(drizzle_home,argument,sizeof(drizzle_home)-1);
2830
if (default_collation_name == compiled_default_collation_name)
2831
default_collation_name= 0;
2834
strncpy(drizzle_real_data_home,argument, sizeof(drizzle_real_data_home)-1);
2835
/* Correct pointer set by my_getopt (for embedded library) */
2836
drizzle_data_home= drizzle_real_data_home;
2837
drizzle_data_home_len= strlen(drizzle_data_home);
2840
if (!drizzled_user || !strcmp(drizzled_user, argument))
2841
drizzled_user= argument;
2214
2843
errmsg_printf(ERRMSG_LVL_WARN, _("Ignoring user change to '%s' because the user was "
2215
"set to '%s' earlier on the command line\n"),
2216
vm["user"].as<string>().c_str(), drizzled_user);
2219
if (vm.count("version"))
2844
"set to '%s' earlier on the command line\n"),
2845
argument, drizzled_user);
2848
strncpy(language, argument, sizeof(language)-1);
2221
2851
print_version();
2225
if (vm.count("sort-heap-threshold"))
2227
if ((vm["sort-heap-threshold"].as<uint64_t>() > 0) and
2228
(vm["sort-heap-threshold"].as<uint64_t>() <
2229
global_system_variables.sortbuff_size))
2231
cout << N_("Error: sort-heap-threshold cannot be less than sort-buffer-size") << endl;
2235
global_sort_buffer.setMaxSize(vm["sort-heap-threshold"].as<uint64_t>());
2238
if (vm.count("join-heap-threshold"))
2240
if ((vm["join-heap-threshold"].as<uint64_t>() > 0) and
2241
(vm["join-heap-threshold"].as<uint64_t>() <
2242
global_system_variables.join_buff_size))
2244
cout << N_("Error: join-heap-threshold cannot be less than join-buffer-size") << endl;
2248
global_join_buffer.setMaxSize(vm["join-heap-threshold"].as<uint64_t>());
2251
if (vm.count("read-rnd-threshold"))
2253
if ((vm["read-rnd-threshold"].as<uint64_t>() > 0) and
2254
(vm["read-rnd-threshold"].as<uint64_t>() <
2255
global_system_variables.read_rnd_buff_size))
2257
cout << N_("Error: read-rnd-threshold cannot be less than read-rnd-buffer-size") << endl;
2261
global_read_rnd_buffer.setMaxSize(vm["read-rnd-threshold"].as<uint64_t>());
2264
if (vm.count("read-buffer-threshold"))
2266
if ((vm["read-buffer-threshold"].as<uint64_t>() > 0) and
2267
(vm["read-buffer-threshold"].as<uint64_t>() <
2268
global_system_variables.read_buff_size))
2270
cout << N_("Error: read-buffer-threshold cannot be less than read-buffer-size") << endl;
2274
global_read_buffer.setMaxSize(vm["read-buffer-threshold"].as<uint64_t>());
2277
if (vm.count("exit-info"))
2279
if (vm["exit-info"].as<long>())
2281
test_flags.set((uint32_t) vm["exit-info"].as<long>());
2285
if (vm.count("want-core"))
2287
test_flags.set(TEST_CORE_ON_SIGNAL);
2290
if (vm.count("skip-stack-trace"))
2292
test_flags.set(TEST_NO_STACKTRACE);
2295
if (vm.count("skip-symlinks"))
2297
internal::my_use_symdir=0;
2300
if (vm.count("transaction-isolation"))
2303
type= find_type_or_exit((char *)vm["transaction-isolation"].as<string>().c_str(), &tx_isolation_typelib, "transaction-isolation");
2304
global_system_variables.tx_isolation= (type-1);
2307
/* @TODO Make this all strings */
2308
if (vm.count("default-storage-engine"))
2310
default_storage_engine_str= (char *)vm["default-storage-engine"].as<string>().c_str();
2855
global_system_variables.log_warnings++;
2856
else if (argument == disabled_my_option)
2857
global_system_variables.log_warnings= 0L;
2859
global_system_variables.log_warnings= atoi(argument);
2862
test_flags= argument ? (uint32_t) atoi(argument) : 0;
2865
case (int) OPT_WANT_CORE:
2866
test_flags |= TEST_CORE_ON_SIGNAL;
2868
case (int) OPT_SKIP_STACK_TRACE:
2869
test_flags|=TEST_NO_STACKTRACE;
2871
case (int) OPT_SKIP_SYMLINKS:
2874
case (int) OPT_BIND_ADDRESS:
2876
struct addrinfo *res_lst, hints;
2878
memset(&hints, 0, sizeof(struct addrinfo));
2879
hints.ai_socktype= SOCK_STREAM;
2880
hints.ai_protocol= IPPROTO_TCP;
2882
if (getaddrinfo(argument, NULL, &hints, &res_lst) != 0)
2884
errmsg_printf(ERRMSG_LVL_ERROR, _("Can't start server: cannot resolve hostname!"));
2888
if (res_lst->ai_next)
2890
errmsg_printf(ERRMSG_LVL_ERROR, _("Can't start server: bind-address refers to "
2891
"multiple interfaces!"));
2894
freeaddrinfo(res_lst);
2897
case (int) OPT_PID_FILE:
2898
strncpy(pidfile_name, argument, sizeof(pidfile_name)-1);
2901
server_id_supplied = 1;
2903
case OPT_DELAY_KEY_WRITE_ALL:
2904
if (argument != disabled_my_option)
2905
argument= (char*) "ALL";
2907
case OPT_DELAY_KEY_WRITE:
2908
if (argument == disabled_my_option)
2909
delay_key_write_options= (uint32_t) DELAY_KEY_WRITE_NONE;
2910
else if (! argument)
2911
delay_key_write_options= (uint32_t) DELAY_KEY_WRITE_ON;
2915
type= find_type_or_exit(argument, &delay_key_write_typelib, opt->name);
2916
delay_key_write_options= (uint32_t) type-1;
2919
case OPT_TX_ISOLATION:
2922
type= find_type_or_exit(argument, &tx_isolation_typelib, opt->name);
2923
global_system_variables.tx_isolation= (type-1);
2926
case OPT_MYISAM_RECOVER:
2930
myisam_recover_options= HA_RECOVER_DEFAULT;
2931
myisam_recover_options_str= myisam_recover_typelib.type_names[0];
2933
else if (!argument[0])
2935
myisam_recover_options= HA_RECOVER_NONE;
2936
myisam_recover_options_str= "OFF";
2940
myisam_recover_options_str=argument;
2941
myisam_recover_options=
2942
find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name);
2944
ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
2947
case OPT_TC_HEURISTIC_RECOVER:
2948
tc_heuristic_recover= find_type_or_exit(argument,
2949
&tc_heuristic_recover_typelib,
2952
case OPT_MYISAM_STATS_METHOD:
2954
uint32_t method_conv;
2957
myisam_stats_method_str= argument;
2958
method= find_type_or_exit(argument, &myisam_stats_method_typelib,
2962
method_conv= MI_STATS_METHOD_IGNORE_NULLS;
2965
method_conv= MI_STATS_METHOD_NULLS_EQUAL;
2969
method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
2972
global_system_variables.myisam_stats_method= method_conv;
2980
/** Handle arguments for multiple key caches. */
2982
extern "C" char **drizzle_getopt_value(const char *keyname, uint32_t key_length,
2983
const struct my_option *option);
2986
drizzle_getopt_value(const char *keyname, uint32_t key_length,
2987
const struct my_option *option)
2989
switch (option->id) {
2990
case OPT_KEY_BUFFER_SIZE:
2991
case OPT_KEY_CACHE_BLOCK_SIZE:
2992
case OPT_KEY_CACHE_DIVISION_LIMIT:
2993
case OPT_KEY_CACHE_AGE_THRESHOLD:
2995
KEY_CACHE *key_cache;
2996
if (!(key_cache= get_or_create_key_cache(keyname, key_length)))
2998
switch (option->id) {
2999
case OPT_KEY_BUFFER_SIZE:
3000
return (char**) &key_cache->param_buff_size;
3001
case OPT_KEY_CACHE_BLOCK_SIZE:
3002
return (char**) &key_cache->param_block_size;
3003
case OPT_KEY_CACHE_DIVISION_LIMIT:
3004
return (char**) &key_cache->param_division_limit;
3005
case OPT_KEY_CACHE_AGE_THRESHOLD:
3006
return (char**) &key_cache->param_age_threshold;
3010
return (char **)option->value;
3014
extern "C" void option_error_reporter(enum loglevel level, const char *format, ...);
3016
void option_error_reporter(enum loglevel level, const char *format, ...)
3019
va_start(args, format);
3021
/* Don't print warnings for --loose options during bootstrap */
3022
if (level == ERROR_LEVEL || global_system_variables.log_warnings)
3024
errmsg_vprintf (current_session, ERROR_LEVEL, format, args);
3032
- FIXME add EXIT_TOO_MANY_ARGUMENTS to "mysys_err.h" and return that code?
3034
static void get_options(int *argc,char **argv)
3038
my_getopt_register_get_addr(drizzle_getopt_value);
3039
my_getopt_error_reporter= option_error_reporter;
2313
3041
/* Skip unknown options so that they may be processed later by plugins */
2314
3042
my_getopt_skip_unknown= true;
3044
if ((ho_error= handle_options(argc, &argv, my_long_options,
3045
drizzled_get_one_option)))
3047
(*argc)++; /* add back one for the progname handle_options removes */
3048
/* no need to do this for argv as we are discarding it. */
2317
3050
#if defined(HAVE_BROKEN_REALPATH)
2318
internal::my_use_symdir=0;
2319
internal::my_disable_symlinks=1;
3052
my_disable_symlinks=1;
2320
3053
have_symlink=SHOW_OPTION_NO;
2322
if (!internal::my_use_symdir)
2324
internal::my_disable_symlinks=1;
3057
my_disable_symlinks=1;
2325
3058
have_symlink=SHOW_OPTION_DISABLED;
2328
3061
if (opt_debugging)
2330
3063
/* Allow break with SIGINT, no core or stack trace */
2331
test_flags.set(TEST_SIGINT);
2332
test_flags.set(TEST_NO_STACKTRACE);
2333
test_flags.reset(TEST_CORE_ON_SIGNAL);
3064
test_flags|= TEST_SIGINT | TEST_NO_STACKTRACE;
3065
test_flags&= ~TEST_CORE_ON_SIGNAL;
3067
/* Set global MyISAM variables from delay_key_write_options */
3068
fix_delay_key_write((Session*) 0, OPT_GLOBAL);
2336
3070
if (drizzled_chroot)
2337
3071
set_root(drizzled_chroot);
2340
3075
Set some global variables from the global_system_variables
2341
3076
In most cases the global variables will not be used
2343
internal::my_default_record_cache_size=global_system_variables.read_buff_size;
2347
static void fix_paths()
2349
fs::path pid_file_path(pid_file);
2350
if (pid_file_path.root_path().string() == "")
2352
pid_file_path= getDataHome();
2353
pid_file_path /= pid_file;
2355
pid_file= fs::system_complete(pid_file_path);
2359
const char *tmp_string= getenv("TMPDIR") ? getenv("TMPDIR") : NULL;
3078
my_default_record_cache_size=global_system_variables.read_buff_size;
3079
myisam_max_temp_length= INT32_MAX;
3083
Create version name for running drizzled version
3084
We automaticly add suffixes -debug, -embedded and -log to the version
3085
name to make the version more descriptive.
3086
(DRIZZLE_SERVER_SUFFIX is set by the compilation environment)
3089
#ifdef DRIZZLE_SERVER_SUFFIX
3090
#define DRIZZLE_SERVER_SUFFIX_STR STRINGIFY_ARG(DRIZZLE_SERVER_SUFFIX)
3092
#define DRIZZLE_SERVER_SUFFIX_STR ""
3095
static void set_server_version(void)
3097
char *end= server_version;
3098
end+= sprintf(server_version, "%s%s", VERSION,
3099
DRIZZLE_SERVER_SUFFIX_STR);
3103
static const char *get_relative_path(const char *path)
3105
if (test_if_hard_path(path) &&
3106
is_prefix(path,PREFIX) &&
3107
strcmp(PREFIX,FN_ROOTDIR))
3109
if (strlen(PREFIX) < strlen(path))
3110
path+=(size_t) strlen(PREFIX);
3111
while (*path == FN_LIBCHAR)
3118
static void fix_paths(void)
3120
char buff[FN_REFLEN],*pos;
3121
convert_dirname(drizzle_home,drizzle_home,NULL);
3122
/* Resolve symlinks to allow 'drizzle_home' to be a relative symlink */
3123
my_realpath(drizzle_home,drizzle_home,MYF(0));
3124
/* Ensure that drizzle_home ends in FN_LIBCHAR */
3125
pos= strchr(drizzle_home, '\0');
3126
if (pos[-1] != FN_LIBCHAR)
3131
convert_dirname(drizzle_real_data_home,drizzle_real_data_home,NULL);
3132
(void) fn_format(buff, drizzle_real_data_home, "", "",
3133
(MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
3134
(void) unpack_dirname(drizzle_unpacked_real_data_home, buff);
3135
convert_dirname(language,language,NULL);
3136
(void) my_load_path(drizzle_home, drizzle_home,""); // Resolve current dir
3137
(void) my_load_path(drizzle_real_data_home, drizzle_real_data_home,drizzle_home);
3138
(void) my_load_path(pidfile_name, pidfile_name,drizzle_real_data_home);
3139
(void) my_load_path(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr :
3140
get_relative_path(PKGPLUGINDIR),
3142
opt_plugin_dir_ptr= opt_plugin_dir;
3144
const char *sharedir= get_relative_path(PKGDATADIR);
3145
if (test_if_hard_path(sharedir))
3146
strncpy(buff,sharedir,sizeof(buff)-1); /* purecov: tested */
3149
strcpy(buff, drizzle_home);
3150
strncat(buff, sharedir, sizeof(buff)-strlen(drizzle_home)-1);
3152
convert_dirname(buff,buff,NULL);
3153
(void) my_load_path(language,language,buff);
2360
3157
struct stat buf;
2361
drizzle_tmpdir.clear();
2363
if (vm.count("tmpdir"))
2365
drizzle_tmpdir.append(vm["tmpdir"].as<string>());
3159
tmp_string= getenv("TMPDIR");
3161
if (opt_drizzle_tmpdir)
3162
drizzle_tmpdir= strdup(opt_drizzle_tmpdir);
2367
3163
else if (tmp_string == NULL)
2369
drizzle_tmpdir.append(getDataHome().file_string());
2370
drizzle_tmpdir.push_back(FN_LIBCHAR);
2371
drizzle_tmpdir.append(GLOBAL_TEMPORARY_EXT);
2375
drizzle_tmpdir.append(tmp_string);
2378
drizzle_tmpdir= fs::path(fs::system_complete(fs::path(drizzle_tmpdir))).file_string();
2379
assert(drizzle_tmpdir.size());
2381
if (mkdir(drizzle_tmpdir.c_str(), 0777) == -1)
2383
if (errno != EEXIST)
2385
perror(drizzle_tmpdir.c_str());
2390
if (stat(drizzle_tmpdir.c_str(), &buf) || (S_ISDIR(buf.st_mode) == false))
2392
perror(drizzle_tmpdir.c_str());
2399
} /* namespace drizzled */
3164
drizzle_tmpdir= strdup(P_tmpdir);
3166
drizzle_tmpdir= strdup(tmp_string);
3168
assert(drizzle_tmpdir);
3170
if (stat(drizzle_tmpdir, &buf) || (S_ISDIR(buf.st_mode) == false))
3177
Convert the secure-file-priv option to system format, allowing
3178
a quick strcmp to check if read or write is in an allowed dir
3180
if (opt_secure_file_priv)
3182
convert_dirname(buff, opt_secure_file_priv, NULL);
3183
free(opt_secure_file_priv);
3184
opt_secure_file_priv= strdup(buff);
3185
if (opt_secure_file_priv == NULL)
3191
static uint32_t find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
3198
if ((res= find_bit_type(x, bit_lib)) == ~(uint32_t) 0)
3200
ptr= bit_lib->type_names;
3202
fprintf(stderr, _("No option given to %s\n"), option);
3204
fprintf(stderr, _("Wrong option to %s. Option(s) given: %s\n"),
3206
fprintf(stderr, _("Alternatives are: '%s'"), *ptr);
3208
fprintf(stderr, ",'%s'", *ptr);
3209
fprintf(stderr, "\n");
3218
a bitfield from a string of substrings separated by ','
3220
~(uint32_t) 0 on error.
3223
static uint32_t find_bit_type(const char *x, TYPELIB *bit_lib)
3227
const char *end,*i,*j;
3228
const char **array, *pos;
3229
uint32_t found,found_int,bit;
3234
while (*pos == ' ') pos++;
3235
found_end= *pos == 0;
3238
if ((end=strrchr(pos,',')) != NULL) /* Let end point at fieldend */
3240
while (end > pos && end[-1] == ' ')
3241
end--; /* Skip end-space */
3246
end=pos+strlen(pos);
3249
found_int=0; found_count=0;
3250
for (array=bit_lib->type_names, bit=1 ; (i= *array++) ; bit<<=1)
3255
if (my_toupper(mysqld_charset,*i++) !=
3256
my_toupper(mysqld_charset,*j++))
3265
else if (j != pos) // Half field found
3267
found_count++; // Could be one of two values
3271
if (found_count != 1)
3272
return(~(uint32_t) 0); // No unique value
3278
} /* find_bit_type */
3281
bool safe_read_error_impl(NET *net)
3284
return drizzleclient_vio_was_interrupted(net->vio);
3289
/*****************************************************************************
3290
Instantiate templates
3291
*****************************************************************************/
3293
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
3294
/* Used templates */
3295
template class I_List<Session>;
3296
template class I_List_iterator<Session>;
3297
template class I_List<i_string>;
3298
template class I_List<i_string_pair>;
3299
template class I_List<NAMED_LIST>;
3300
template class I_List<Statement>;
3301
template class I_List_iterator<Statement>;