/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "mysql_priv.h" #include <mysql.h> #include <m_ctype.h> #include <my_dir.h> #include "sql_acl.h" #include "slave.h" #include "sql_repl.h" #include "stacktrace.h" #ifdef HAVE_BERKELEY_DB #include "ha_berkeley.h" #endif #ifdef HAVE_INNOBASE_DB #include "ha_innobase.h" #endif #ifdef HAVE_GEMINI_DB #include "ha_gemini.h" #endif #include "ha_myisam.h" #include <nisam.h> #include <thr_alarm.h> #include <ft_global.h> #ifndef DBUG_OFF #define ONE_THREAD #endif #if defined(HAVE_DEC_3_2_THREADS) || defined(SIGNALS_DONT_BREAK_READ) #define HAVE_CLOSE_SERVER_SOCK 1 void close_server_sock(); #endif extern "C" { // Because of SCO 3.2V4.2 #include <errno.h> #include <sys/stat.h> #ifndef __GNU_LIBRARY__ #define __GNU_LIBRARY__ // Skip warnings in getopt.h #endif #include <getopt.h> #ifdef HAVE_SYSENT_H #include <sysent.h> #endif #ifdef HAVE_PWD_H #include <pwd.h> // For getpwent #endif #ifdef HAVE_GRP_H #include <grp.h> #endif #if defined(OS2) # include <sys/un.h> #elif !defined( __WIN__) #include <sys/resource.h> #ifdef HAVE_SYS_UN_H # include <sys/un.h> #endif #include <netdb.h> #ifdef HAVE_SELECT_H # include <select.h> #endif #ifdef HAVE_SYS_SELECT_H #include <sys/select.h> #endif #include <sys/utsname.h> #else #include <windows.h> #endif // __WIN__ #ifdef HAVE_LIBWRAP #include <tcpd.h> #include <syslog.h> #ifdef NEED_SYS_SYSLOG_H #include <sys/syslog.h> #endif /* NEED_SYS_SYSLOG_H */ int allow_severity = LOG_INFO; int deny_severity = LOG_WARNING; #endif /* HAVE_LIBWRAP */ #ifdef HAVE_SYS_MMAN_H #include <sys/mman.h> #endif #ifdef _AIX41 int initgroups(const char *,unsigned int); #endif #if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H) #include <ieeefp.h> #ifdef HAVE_FP_EXCEPT // Fix type conflict typedef fp_except fp_except_t; #endif /* We can't handle floating point expections with threads, so disable this on freebsd */ inline void reset_floating_point_exceptions() { /* Don't fall for overflow, underflow,divide-by-zero or loss of precision */ fpsetmask(~(FP_X_INV | FP_X_DNML | FP_X_OFL | FP_X_UFL | FP_X_DZ | FP_X_IMP)); } #else #define reset_floating_point_exceptions() #endif /* __FreeBSD__ && HAVE_IEEEFP_H */ } /* cplusplus */ #if defined(HAVE_LINUXTHREADS) #define THR_KILL_SIGNAL SIGINT #else #define THR_KILL_SIGNAL SIGUSR2 // Can't use this with LinuxThreads #endif #ifdef HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R #include <sys/types.h> #else #include <my_pthread.h> // For thr_setconcurency() #endif #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE) && !defined(HAVE_mit_thread) #define SET_RLIMIT_NOFILE #endif #ifdef SOLARIS extern "C" int gethostname(char *name, int namelen); #endif #define MYSQL_KILL_SIGNAL SIGTERM #ifndef DBUG_OFF static const char* default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace", "d:t:i:o,/tmp/mysqld.trace"); #endif #ifdef __NT__ static char szPipeName [ 257 ]; static SECURITY_ATTRIBUTES saPipeSecurity; static SECURITY_DESCRIPTOR sdPipeDescriptor; static HANDLE hPipe = INVALID_HANDLE_VALUE; static pthread_cond_t COND_handler_count; static uint handler_count; #endif #ifdef __WIN__ static bool opt_console=0,start_mode=0; #endif /* Set prefix for windows binary */ #ifdef __WIN__ #undef MYSQL_SERVER_SUFFIX #ifdef __NT__ #if defined(HAVE_INNOBASE_DB) || defined(HAVE_BERKELEY_DB) #define MYSQL_SERVER_SUFFIX "-max-nt" #else #define MYSQL_SERVER_SUFFIX "-nt" #endif /* ...DB */ #elif defined(HAVE_INNOBASE_DB) || defined(HAVE_BERKELEY_DB) #define MYSQL_SERVER_SUFFIX "-max" #else #define MYSQL_SERVER_SUFFIX "" #endif /* __NT__ */ #endif #ifdef HAVE_BERKELEY_DB SHOW_COMP_OPTION have_berkeley_db=SHOW_OPTION_YES; #else SHOW_COMP_OPTION have_berkeley_db=SHOW_OPTION_NO; #endif #ifdef HAVE_GEMINI_DB SHOW_COMP_OPTION have_gemini=SHOW_OPTION_YES; #else SHOW_COMP_OPTION have_gemini=SHOW_OPTION_NO; #endif #ifdef HAVE_INNOBASE_DB SHOW_COMP_OPTION have_innodb=SHOW_OPTION_YES; #else SHOW_COMP_OPTION have_innodb=SHOW_OPTION_NO; #endif #ifndef NO_ISAM SHOW_COMP_OPTION have_isam=SHOW_OPTION_YES; #else SHOW_COMP_OPTION have_isam=SHOW_OPTION_NO; #endif #ifdef USE_RAID SHOW_COMP_OPTION have_raid=SHOW_OPTION_YES; #else SHOW_COMP_OPTION have_raid=SHOW_OPTION_NO; #endif #ifdef HAVE_OPENSSL SHOW_COMP_OPTION have_ssl=SHOW_OPTION_YES; #else SHOW_COMP_OPTION have_ssl=SHOW_OPTION_NO; #endif static bool opt_skip_slave_start = 0; // if set, slave is not autostarted static ulong opt_specialflag=SPECIAL_ENGLISH; static my_socket unix_sock= INVALID_SOCKET,ip_sock= INVALID_SOCKET; static ulong back_log,connect_timeout,concurrency; static my_string opt_logname=0,opt_update_logname=0, opt_binlog_index_name = 0,opt_slow_logname=0; static char mysql_home[FN_REFLEN],pidfile_name[FN_REFLEN]; static pthread_t select_thread; static bool opt_log,opt_update_log,opt_bin_log,opt_slow_log,opt_noacl, opt_disable_networking=0, opt_bootstrap=0,opt_skip_show_db=0, opt_myisam_log=0, opt_large_files=sizeof(my_off_t) > 4; bool opt_sql_bin_update = 0, opt_log_slave_updates = 0, opt_safe_show_db=0, opt_safe_user_create=0; FILE *bootstrap_file=0; int segfaulted = 0; // ensure we do not enter SIGSEGV handler twice extern MASTER_INFO glob_mi; extern int init_master_info(MASTER_INFO* mi); // if sql_bin_update is true, SQL_LOG_UPDATE and SQL_LOG_BIN are kept in sync, // and are treated as aliases for each other static bool kill_in_progress=FALSE; static struct rand_struct sql_rand; static int cleanup_done; static char **defaults_argv,time_zone[30]; static const char *default_table_type_name; static char glob_hostname[FN_REFLEN]; #ifdef HAVE_OPENSSL static bool opt_use_ssl = FALSE; static char *opt_ssl_key = 0; static char *opt_ssl_cert = 0; static char *opt_ssl_ca = 0; static char *opt_ssl_capath = 0; static VioSSLAcceptorFd* ssl_acceptor_fd = 0; #endif /* HAVE_OPENSSL */ I_List <i_string_pair> replicate_rewrite_db; I_List<i_string> replicate_do_db, replicate_ignore_db; // allow the user to tell us which db to replicate and which to ignore I_List<i_string> binlog_do_db, binlog_ignore_db; /* if we guessed server_id , we need to know about it */ uint32 server_id = 0; bool server_id_supplied = 0; uint mysql_port; uint test_flags, select_errors=0, dropping_tables=0,ha_open_options=0; uint volatile thread_count=0, thread_running=0, kill_cached_threads=0, wake_thread=0, global_read_lock=0; ulong thd_startup_options=(OPTION_UPDATE_LOG | OPTION_AUTO_IS_NULL | OPTION_BIN_LOG | OPTION_QUOTE_SHOW_CREATE ); uint protocol_version=PROTOCOL_VERSION; ulong keybuff_size,sortbuff_size,max_item_sort_length,table_cache_size, max_join_size,join_buff_size,tmp_table_size,thread_stack, thread_stack_min,net_wait_timeout,what_to_log= ~ (1L << (uint) COM_TIME), query_buff_size, lower_case_table_names, mysqld_net_retry_count, net_interactive_timeout, slow_launch_time = 2L, net_read_timeout,net_write_timeout,slave_open_temp_tables=0, open_files_limit=0, max_binlog_size, record_rnd_cache_size; ulong com_stat[(uint) SQLCOM_END], com_other; ulong slave_net_timeout; ulong thread_cache_size=0, binlog_cache_size=0, max_binlog_cache_size=0; volatile ulong cached_thread_count=0; // replication parameters, if master_host is not NULL, we are a slave my_string master_user = (char*) "test", master_password = 0, master_host=0, master_info_file = (char*) "master.info"; const char *localhost=LOCAL_HOST; const char *delayed_user="DELAYED"; uint master_port = MYSQL_PORT, master_connect_retry = 60; ulong max_tmp_tables,max_heap_table_size,master_retry_count=0; ulong bytes_sent = 0L, bytes_received = 0L; bool opt_endinfo,using_udf_functions,low_priority_updates, locked_in_memory; bool opt_using_transactions, using_update_log, opt_warnings=0; bool opt_local_infile; bool volatile abort_loop,select_thread_in_use,grant_option; bool volatile ready_to_exit,shutdown_in_progress; ulong refresh_version=1L,flush_version=1L; /* Increments on each reload */ ulong query_id=1L,long_query_count,long_query_time,aborted_threads, aborted_connects,delayed_insert_timeout,delayed_insert_limit, delayed_queue_size,delayed_insert_threads,delayed_insert_writes, delayed_rows_in_use,delayed_insert_errors,flush_time, thread_created; ulong filesort_rows, filesort_range_count, filesort_scan_count; ulong filesort_merge_passes; ulong select_range_check_count, select_range_count, select_scan_count; ulong select_full_range_join_count,select_full_join_count; ulong specialflag=0,opened_tables=0,created_tmp_tables=0, created_tmp_disk_tables=0; ulong max_connections,max_insert_delayed_threads,max_used_connections, max_connect_errors, max_user_connections = 0; ulong thread_id=1L,current_pid; ulong slow_launch_threads = 0; ulong myisam_max_sort_file_size, myisam_max_extra_sort_file_size; char mysql_real_data_home[FN_REFLEN], mysql_data_home[2],language[LIBLEN],reg_ext[FN_EXTLEN], default_charset[LIBLEN],mysql_charsets_dir[FN_REFLEN], *charsets_list, blob_newline,f_fyllchar,max_sort_char,*mysqld_user,*mysqld_chroot, *opt_init_file; char *opt_bin_logname = 0; // this one needs to be seen in sql_parse.cc char server_version[SERVER_VERSION_LENGTH]=MYSQL_SERVER_VERSION; const char *first_keyword="first"; const char **errmesg; /* Error messages */ const char *myisam_recover_options_str="OFF"; const char *sql_mode_str="OFF"; const char *default_tx_isolation_name; enum_tx_isolation default_tx_isolation=ISO_READ_COMMITTED; #ifdef HAVE_GEMINI_DB const char *gemini_recovery_options_str="FULL"; #endif my_string mysql_unix_port=NULL,mysql_tmpdir=NULL; ulong my_bind_addr; /* the address we bind to */ DATE_FORMAT dayord; double log_10[32]; /* 10 potences */ I_List<THD> threads,thread_cache; time_t start_time; ulong opt_sql_mode = 0L; const char *sql_mode_names[] = { "REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE", "SERIALIZE","ONLY_FULL_GROUP_BY", NullS }; TYPELIB sql_mode_typelib= {array_elements(sql_mode_names),"", sql_mode_names}; MY_BITMAP temp_pool; bool use_temp_pool=0; pthread_key(MEM_ROOT*,THR_MALLOC); pthread_key(THD*, THR_THD); pthread_key(NET*, THR_NET); pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count, LOCK_mapped_file, LOCK_status, LOCK_grant, LOCK_error_log, LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received, LOCK_binlog_update, LOCK_slave, LOCK_server_id, LOCK_user_conn; pthread_cond_t COND_refresh,COND_thread_count,COND_binlog_update, COND_slave_stopped, COND_slave_start; pthread_cond_t COND_thread_cache,COND_flush_thread_cache; pthread_t signal_thread; pthread_attr_t connection_attrib; enum db_type default_table_type=DB_TYPE_MYISAM; #ifdef __WIN__ #undef getpid #include <process.h> HANDLE hEventShutdown; #include "nt_servc.h" static NTService Service; // Service object for WinNT #endif #ifdef OS2 pthread_cond_t eventShutdown; #endif static void start_signal_handler(void); static void *signal_hand(void *arg); static void set_options(void); static void get_options(int argc,char **argv); static char *get_relative_path(const char *path); static void fix_paths(void); static pthread_handler_decl(handle_connections_sockets,arg); static pthread_handler_decl(kill_server_thread,arg); static int bootstrap(FILE *file); static bool read_init_file(char *file_name); #ifdef __NT__ static pthread_handler_decl(handle_connections_namedpipes,arg); #endif extern pthread_handler_decl(handle_slave,arg); #ifdef SET_RLIMIT_NOFILE static uint set_maximum_open_files(uint max_file_limit); #endif static ulong find_bit_type(const char *x, TYPELIB *bit_lib); /**************************************************************************** ** Code to end mysqld ****************************************************************************/ static void close_connections(void) { #ifdef EXTRA_DEBUG int count=0; #endif NET net; DBUG_ENTER("close_connections"); /* Clear thread cache */ kill_cached_threads++; flush_thread_cache(); /* kill flush thread */ (void) pthread_mutex_lock(&LOCK_manager); if (manager_thread_in_use) { DBUG_PRINT("quit",("killing manager thread: %lx",manager_thread)); (void) pthread_cond_signal(&COND_manager); } (void) pthread_mutex_unlock(&LOCK_manager); /* kill connection thread */ #if !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) DBUG_PRINT("quit",("waiting for select thread: %lx",select_thread)); (void) pthread_mutex_lock(&LOCK_thread_count); while (select_thread_in_use) { struct timespec abstime; int error; LINT_INIT(error); #ifndef DONT_USE_THR_ALARM if (pthread_kill(select_thread,THR_CLIENT_ALARM)) break; // allready dead #endif #ifdef HAVE_TIMESPEC_TS_SEC abstime.ts_sec=time(NULL)+2; // Bsd 2.1 abstime.ts_nsec=0; #else struct timeval tv; gettimeofday(&tv,0); abstime.tv_sec=tv.tv_sec+2; abstime.tv_nsec=tv.tv_usec*1000; #endif for (uint tmp=0 ; tmp < 10 ; tmp++) { error=pthread_cond_timedwait(&COND_thread_count,&LOCK_thread_count, &abstime); if (error != EINTR) break; } #ifdef EXTRA_DEBUG if (error != 0 && !count++) sql_print_error("Got error %d from pthread_cond_timedwait",error); #endif #if defined(HAVE_DEC_3_2_THREADS) || defined(SIGNALS_DONT_BREAK_READ) close_server_sock(); #endif } (void) pthread_mutex_unlock(&LOCK_thread_count); #endif /* __WIN__ */ /* Abort listening to new connections */ DBUG_PRINT("quit",("Closing sockets")); if ( !opt_disable_networking ) { if (ip_sock != INVALID_SOCKET) { (void) shutdown(ip_sock,2); (void) closesocket(ip_sock); ip_sock= INVALID_SOCKET; } } #ifdef __NT__ if ( hPipe != INVALID_HANDLE_VALUE ) { HANDLE hTempPipe = &hPipe; DBUG_PRINT( "quit", ("Closing named pipes") ); hPipe = INVALID_HANDLE_VALUE; CancelIo( hTempPipe ); DisconnectNamedPipe( hTempPipe ); CloseHandle( hTempPipe ); } #endif #ifdef HAVE_SYS_UN_H if (unix_sock != INVALID_SOCKET) { (void) shutdown(unix_sock,2); (void) closesocket(unix_sock); (void) unlink(mysql_unix_port); unix_sock= INVALID_SOCKET; } #endif end_thr_alarm(); // Don't allow alarms end_slave(); /* First signal all threads that it's time to die */ THD *tmp; (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list I_List_iterator<THD> it(threads); while ((tmp=it++)) { DBUG_PRINT("quit",("Informing thread %ld that it's time to die", tmp->thread_id)); tmp->killed=1; if (tmp->mysys_var) { tmp->mysys_var->abort=1; pthread_mutex_lock(&tmp->mysys_var->mutex); if (tmp->mysys_var->current_cond) { pthread_mutex_lock(tmp->mysys_var->current_mutex); pthread_cond_broadcast(tmp->mysys_var->current_cond); pthread_mutex_unlock(tmp->mysys_var->current_mutex); } pthread_mutex_unlock(&tmp->mysys_var->mutex); } } (void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list if (thread_count) { sleep(1); // Give threads time to die } /* Force remaining threads to die by closing the connection to the client */ (void) my_net_init(&net, (Vio*) 0); for (;;) { DBUG_PRINT("quit",("Locking LOCK_thread_count")); (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list if (!(tmp=threads.get())) { DBUG_PRINT("quit",("Unlocking LOCK_thread_count")); (void) pthread_mutex_unlock(&LOCK_thread_count); break; } #ifndef __bsdi__ // Bug in BSDI kernel if ((net.vio=tmp->net.vio) != 0) { sql_print_error(ER(ER_FORCING_CLOSE),my_progname, tmp->thread_id,tmp->user ? tmp->user : ""); close_connection(&net,0,0); } #endif DBUG_PRINT("quit",("Unlocking LOCK_thread_count")); (void) pthread_mutex_unlock(&LOCK_thread_count); } net_end(&net); /* All threads has now been aborted */ DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count)); (void) pthread_mutex_lock(&LOCK_thread_count); while (thread_count) { (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count); DBUG_PRINT("quit",("One thread died (count=%u)",thread_count)); } (void) pthread_mutex_unlock(&LOCK_thread_count); mysql_log.close(1); mysql_slow_log.close(1); mysql_update_log.close(1); mysql_bin_log.close(1); DBUG_PRINT("quit",("close_connections thread")); DBUG_VOID_RETURN; } #ifdef HAVE_CLOSE_SERVER_SOCK void close_server_sock() { DBUG_ENTER("close_server_sock"); if (ip_sock != INVALID_SOCKET) { DBUG_PRINT("info",("closing TCP/IP socket")); VOID(shutdown(ip_sock,2)); VOID(closesocket(ip_sock)); ip_sock=INVALID_SOCKET; } if (unix_sock != INVALID_SOCKET) { DBUG_PRINT("info",("closing Unix socket")); VOID(shutdown(unix_sock,2)); VOID(closesocket(unix_sock)); VOID(unlink(mysql_unix_port)); unix_sock=INVALID_SOCKET; } DBUG_VOID_RETURN; } #endif void kill_mysql(void) { DBUG_ENTER("kill_mysql"); #ifdef SIGNALS_DONT_BREAK_READ close_server_sock(); /* force accept to wake up */ #endif #if defined(__WIN__) { if (!SetEvent(hEventShutdown)) { DBUG_PRINT("error",("Got error: %ld from SetEvent",GetLastError())); } // or: // HANDLE hEvent=OpenEvent(0, FALSE, "MySqlShutdown"); // SetEvent(hEventShutdown); // CloseHandle(hEvent); } #elif defined(OS2) pthread_cond_signal( &eventShutdown); // post semaphore #elif defined(HAVE_PTHREAD_KILL) if (pthread_kill(signal_thread,MYSQL_KILL_SIGNAL))// End everything nicely { DBUG_PRINT("error",("Got error %d from pthread_kill",errno)); /* purecov: inspected */ } #elif !defined(SIGNALS_DONT_BREAK_READ) kill(current_pid,MYSQL_KILL_SIGNAL); #endif DBUG_PRINT("quit",("After pthread_kill")); shutdown_in_progress=1; // Safety if kill didn't work #ifdef SIGNALS_DONT_BREAK_READ if (!abort_loop) { pthread_t tmp; abort_loop=1; if (pthread_create(&tmp,&connection_attrib, kill_server_thread, (void*) 0)) sql_print_error("Error: Can't create thread to kill server"); } #endif DBUG_VOID_RETURN; } /* Force server down. kill all connections and threads and exit */ #if defined(OS2) extern "C" void kill_server(int sig_ptr) #define RETURN_FROM_KILL_SERVER return #elif !defined(__WIN__) static void *kill_server(void *sig_ptr) #define RETURN_FROM_KILL_SERVER return 0 #else static void __cdecl kill_server(int sig_ptr) #define RETURN_FROM_KILL_SERVER return #endif { int sig=(int) (long) sig_ptr; // This is passed a int DBUG_ENTER("kill_server"); // if there is a signal during the kill in progress, we do not need // another one if (kill_in_progress) // Safety RETURN_FROM_KILL_SERVER; kill_in_progress=TRUE; abort_loop=1; // This should be set signal(sig,SIG_IGN); if (sig == MYSQL_KILL_SIGNAL || sig == 0) sql_print_error(ER(ER_NORMAL_SHUTDOWN),my_progname); else sql_print_error(ER(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */ #if defined(USE_ONE_SIGNAL_HAND) && !defined(__WIN__) && !defined(OS2) my_thread_init(); // If this is a new thread #endif close_connections(); if (sig != MYSQL_KILL_SIGNAL && sig != 0) unireg_abort(1); /* purecov: inspected */ else unireg_end(0); pthread_exit(0); /* purecov: deadcode */ RETURN_FROM_KILL_SERVER; } #ifdef USE_ONE_SIGNAL_HAND pthread_handler_decl(kill_server_thread,arg __attribute__((unused))) { my_thread_init(); // Initialize new thread kill_server(0); my_thread_end(); // Normally never reached return 0; } #endif static sig_handler print_signal_warning(int sig) { if (opt_warnings) sql_print_error("Warning: Got signal %d from thread %d", sig,my_thread_id()); #ifdef DONT_REMEMBER_SIGNAL sigset(sig,print_signal_warning); /* int. thread system calls */ #endif #if !defined(__WIN__) && !defined(OS2) if (sig == SIGALRM) alarm(2); /* reschedule alarm */ #endif } void unireg_end(int signal_number __attribute__((unused))) { clean_up(); pthread_exit(0); // Exit is in main thread } void unireg_abort(int exit_code) { if (exit_code) sql_print_error("Aborting\n"); clean_up(); /* purecov: inspected */ exit(exit_code); /* purecov: inspected */ } void clean_up(bool print_message) { DBUG_PRINT("exit",("clean_up")); if (cleanup_done++) return; /* purecov: inspected */ if (use_slave_mask) bitmap_free(&slave_error_mask); acl_free(1); grant_free(); sql_cache_free(); table_cache_free(); hostname_cache_free(); item_user_lock_free(); lex_free(); /* Free some memory */ #ifdef HAVE_DLOPEN if (!opt_noacl) udf_free(); #endif (void) ha_panic(HA_PANIC_CLOSE); /* close all tables and logs */ end_key_cache(); #ifdef USE_RAID end_raid(); #endif free_defaults(defaults_argv); my_free(charsets_list, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql_tmpdir,MYF(0)); x_free(opt_bin_logname); bitmap_free(&temp_pool); free_max_user_conn(); #ifndef __WIN__ if (!opt_bootstrap) (void) my_delete(pidfile_name,MYF(0)); // This may not always exist #endif if (print_message) sql_print_error(ER(ER_SHUTDOWN_COMPLETE),my_progname); x_free((gptr) my_errmsg[ERRMAPP]); /* Free messages */ my_thread_end(); /* Tell main we are ready */ (void) pthread_mutex_lock(&LOCK_thread_count); ready_to_exit=1; /* do the broadcast inside the lock to ensure that my_end() is not called */ (void) pthread_cond_broadcast(&COND_thread_count); (void) pthread_mutex_unlock(&LOCK_thread_count); } /* clean_up */ /**************************************************************************** ** Init IP and UNIX socket ****************************************************************************/ static void set_ports() { char *env; if (!mysql_port && !opt_disable_networking) { // Get port if not from commandline struct servent *serv_ptr; mysql_port = MYSQL_PORT; if ((serv_ptr = getservbyname("mysql", "tcp"))) mysql_port = ntohs((u_short) serv_ptr->s_port); /* purecov: inspected */ if ((env = getenv("MYSQL_TCP_PORT"))) mysql_port = (uint) atoi(env); /* purecov: inspected */ } if (!mysql_unix_port) { #ifdef __WIN__ mysql_unix_port = (char*) MYSQL_NAMEDPIPE; #else mysql_unix_port = (char*) MYSQL_UNIX_ADDR; #endif if ((env = getenv("MYSQL_UNIX_PORT"))) mysql_unix_port = env; /* purecov: inspected */ } } /* Change to run as another user if started with --user */ static void set_user(const char *user) { #if !defined(__WIN__) && !defined(OS2) struct passwd *ent; // don't bother if we aren't superuser if (geteuid()) { if (user) fprintf(stderr, "Warning: One can only use the --user switch if running as root\n"); return; } else if (!user) { if (!opt_bootstrap) { fprintf(stderr,"Fatal error: Please read \"Security\" section of the manual to find out how to run mysqld as root!\n"); unireg_abort(1); } return; } if (!strcmp(user,"root")) return; // Avoid problem with dynamic libraries if (!(ent = getpwnam(user))) { fprintf(stderr,"Fatal error: Can't change to run as user '%s' ; Please check that the user exists!\n",user); unireg_abort(1); } #ifdef HAVE_INITGROUPS initgroups((char*) user,ent->pw_gid); #endif if (setgid(ent->pw_gid) == -1) { sql_perror("setgid"); unireg_abort(1); } if (setuid(ent->pw_uid) == -1) { sql_perror("setuid"); unireg_abort(1); } #endif } /* Change root user if started with --chroot */ static void set_root(const char *path) { #if !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) if (chroot(path) == -1) { sql_perror("chroot"); unireg_abort(1); } #endif } static void server_init(void) { struct sockaddr_in IPaddr; #ifdef HAVE_SYS_UN_H struct sockaddr_un UNIXaddr; #endif int arg=1; DBUG_ENTER("server_init"); #ifdef __WIN__ if ( !opt_disable_networking ) { WSADATA WsaData; if (SOCKET_ERROR == WSAStartup (0x0101, &WsaData)) { my_message(0,"WSAStartup Failed\n",MYF(0)); unireg_abort(1); } } #endif /* __WIN__ */ set_ports(); if (mysql_port != 0 && !opt_disable_networking && !opt_bootstrap) { DBUG_PRINT("general",("IP Socket is %d",mysql_port)); ip_sock = socket(AF_INET, SOCK_STREAM, 0); if (ip_sock == INVALID_SOCKET) { DBUG_PRINT("error",("Got error: %d from socket()",socket_errno)); sql_perror(ER(ER_IPSOCK_ERROR)); /* purecov: tested */ unireg_abort(1); /* purecov: tested */ } bzero((char*) &IPaddr, sizeof(IPaddr)); IPaddr.sin_family = AF_INET; IPaddr.sin_addr.s_addr = my_bind_addr; IPaddr.sin_port = (unsigned short) htons((unsigned short) mysql_port); (void) setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,sizeof(arg)); for(;;) { if (bind(ip_sock, my_reinterpret_cast(struct sockaddr *) (&IPaddr), sizeof(IPaddr)) >= 0) break; DBUG_PRINT("error",("Got error: %d from bind",socket_errno)); sql_perror("Can't start server: Bind on TCP/IP port");/* Had a loop here */ sql_print_error("Do you already have another mysqld server running on port: %d ?",mysql_port); unireg_abort(1); } if (listen(ip_sock,(int) back_log) < 0) sql_print_error("Warning: listen() on TCP/IP failed with error %d", socket_errno); } if (mysqld_chroot) set_root(mysqld_chroot); set_user(mysqld_user); // set_user now takes care of mysqld_user==NULL #ifdef __NT__ /* create named pipe */ if (Service.IsNT() && mysql_unix_port[0] && !opt_bootstrap) { sprintf( szPipeName, "\\\\.\\pipe\\%s", mysql_unix_port ); ZeroMemory( &saPipeSecurity, sizeof(saPipeSecurity) ); ZeroMemory( &sdPipeDescriptor, sizeof(sdPipeDescriptor) ); if ( !InitializeSecurityDescriptor(&sdPipeDescriptor, SECURITY_DESCRIPTOR_REVISION) ) { sql_perror("Can't start server : Initialize security descriptor"); unireg_abort(1); } if (!SetSecurityDescriptorDacl(&sdPipeDescriptor, TRUE, NULL, FALSE)) { sql_perror("Can't start server : Set security descriptor"); unireg_abort(1); } saPipeSecurity.nLength = sizeof( SECURITY_ATTRIBUTES ); saPipeSecurity.lpSecurityDescriptor = &sdPipeDescriptor; saPipeSecurity.bInheritHandle = FALSE; if ((hPipe = CreateNamedPipe(szPipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, (int) net_buffer_length, (int) net_buffer_length, NMPWAIT_USE_DEFAULT_WAIT, &saPipeSecurity )) == INVALID_HANDLE_VALUE) { LPVOID lpMsgBuf; int error=GetLastError(); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); MessageBox( NULL, (LPTSTR) lpMsgBuf, "Error from CreateNamedPipe", MB_OK|MB_ICONINFORMATION ); LocalFree( lpMsgBuf ); unireg_abort(1); } } #endif #if defined(HAVE_SYS_UN_H) /* ** Create the UNIX socket */ if (mysql_unix_port[0] && !opt_bootstrap) { DBUG_PRINT("general",("UNIX Socket is %s",mysql_unix_port)); if ((unix_sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { sql_perror("Can't start server : UNIX Socket "); /* purecov: inspected */ unireg_abort(1); /* purecov: inspected */ } bzero((char*) &UNIXaddr, sizeof(UNIXaddr)); UNIXaddr.sun_family = AF_UNIX; strmov(UNIXaddr.sun_path, mysql_unix_port); (void) unlink(mysql_unix_port); (void) setsockopt(unix_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg, sizeof(arg)); umask(0); if (bind(unix_sock, my_reinterpret_cast(struct sockaddr *) (&UNIXaddr), sizeof(UNIXaddr)) < 0) { sql_perror("Can't start server : Bind on unix socket"); /* purecov: tested */ sql_print_error("Do you already have another mysqld server running on socket: %s ?",mysql_unix_port); unireg_abort(1); /* purecov: tested */ } umask(((~my_umask) & 0666)); #if defined(S_IFSOCK) && defined(SECURE_SOCKETS) (void) chmod(mysql_unix_port,S_IFSOCK); /* Fix solaris 2.6 bug */ #endif if (listen(unix_sock,(int) back_log) < 0) sql_print_error("Warning: listen() on Unix socket failed with error %d", socket_errno); } #endif DBUG_PRINT("info",("server started")); DBUG_VOID_RETURN; } void yyerror(const char *s) { NET *net=my_pthread_getspecific_ptr(NET*,THR_NET); char *yytext=(char*) current_lex->tok_start; if (!strcmp(s,"parse error")) s=ER(ER_SYNTAX_ERROR); net_printf(net,ER_PARSE_ERROR, s, yytext ? (char*) yytext : "", current_lex->yylineno); } void close_connection(NET *net,uint errcode,bool lock) { Vio* vio; DBUG_ENTER("close_connection"); DBUG_PRINT("enter",("fd: %s error: '%s'", net->vio? vio_description(net->vio):"(not connected)", errcode ? ER(errcode) : "")); if (lock) (void) pthread_mutex_lock(&LOCK_thread_count); if ((vio=net->vio) != 0) { if (errcode) send_error(net,errcode,ER(errcode)); /* purecov: inspected */ vio_close(vio); /* vio is freed in delete thd */ } if (lock) (void) pthread_mutex_unlock(&LOCK_thread_count); DBUG_VOID_RETURN; } /* Called when a thread is aborted */ /* ARGSUSED */ sig_handler end_thread_signal(int sig __attribute__((unused))) { THD *thd=current_thd; DBUG_ENTER("end_thread_signal"); if (thd) end_thread(thd,0); DBUG_VOID_RETURN; /* purecov: deadcode */ } void end_thread(THD *thd, bool put_in_cache) { DBUG_ENTER("end_thread"); thd->cleanup(); (void) pthread_mutex_lock(&LOCK_thread_count); thread_count--; delete thd; if (put_in_cache && cached_thread_count < thread_cache_size && ! abort_loop && !kill_cached_threads) { /* Don't kill the thread, just put it in cache for reuse */ DBUG_PRINT("info", ("Adding thread to cache")) cached_thread_count++; while (!abort_loop && ! wake_thread && ! kill_cached_threads) (void) pthread_cond_wait(&COND_thread_cache, &LOCK_thread_count); cached_thread_count--; if (kill_cached_threads) pthread_cond_signal(&COND_flush_thread_cache); if (wake_thread) { wake_thread--; thd=thread_cache.get(); thd->real_id=pthread_self(); (void) thd->store_globals(); threads.append(thd); pthread_mutex_unlock(&LOCK_thread_count); DBUG_VOID_RETURN; } } DBUG_PRINT("info", ("sending a broadcast")) /* Tell main we are ready */ (void) pthread_mutex_unlock(&LOCK_thread_count); (void) pthread_cond_broadcast(&COND_thread_count); DBUG_PRINT("info", ("unlocked thread_count mutex")) #ifdef ONE_THREAD if (!(test_flags & TEST_NO_THREADS)) // For debugging under Linux #endif { my_thread_end(); pthread_exit(0); } DBUG_VOID_RETURN; } #ifdef SIGNALS_DONT_BREAK_READ inline void kill_broken_server() { /* hack to get around signals ignored in syscalls for problem OS's */ if (unix_sock == INVALID_SOCKET || ip_sock ==INVALID_SOCKET) { select_thread_in_use = 0; kill_server((void*)MYSQL_KILL_SIGNAL); /* never returns */ } } #define MAYBE_BROKEN_SYSCALL kill_broken_server(); #else #define MAYBE_BROKEN_SYSCALL #endif /* Start a cached thread. LOCK_thread_count is locked on entry */ static void start_cached_thread(THD *thd) { thread_cache.append(thd); wake_thread++; thread_count++; pthread_cond_signal(&COND_thread_cache); } void flush_thread_cache() { (void) pthread_mutex_lock(&LOCK_thread_count); kill_cached_threads++; while (cached_thread_count) { pthread_cond_broadcast(&COND_thread_cache); pthread_cond_wait(&COND_flush_thread_cache,&LOCK_thread_count); } kill_cached_threads--; (void) pthread_mutex_unlock(&LOCK_thread_count); } /* ** Aborts a thread nicely. Commes here on SIGPIPE ** TODO: One should have to fix that thr_alarm know about this ** thread too */ #ifdef THREAD_SPECIFIC_SIGPIPE static sig_handler abort_thread(int sig __attribute__((unused))) { THD *thd=current_thd; DBUG_ENTER("abort_thread"); if (thd) thd->killed=1; DBUG_VOID_RETURN; } #endif /****************************************************************************** ** Setup a signal thread with handles all signals ** Because linux doesn't support scemas use a mutex to check that ** the signal thread is ready before continuing ******************************************************************************/ #if defined(__WIN__) || defined(OS2) static void init_signals(void) { int signals[] = {SIGINT,SIGILL,SIGFPE,SIGSEGV,SIGTERM,SIGABRT } ; for (uint i=0 ; i < sizeof(signals)/sizeof(int) ; i++) signal( signals[i], kill_server) ; #if defined(__WIN__) signal(SIGBREAK,SIG_IGN); //ignore SIGBREAK for NT #else signal(SIGBREAK, kill_server); #endif } static void start_signal_handler(void) { } #elif defined(__EMX__) static void init_signals(void) { signal(SIGQUIT, sig_kill); signal(SIGKILL, sig_kill); signal(SIGTERM, sig_kill); signal(SIGINT, sig_kill); signal(SIGHUP, sig_reload); // Flush everything signal(SIGALRM, SIG_IGN); signal(SIGBREAK,SIG_IGN); signal_thread = pthread_self(); } static void sig_reload(int signo) { reload_acl_and_cache((THD*) 0,REFRESH_LOG, (TABLE_LIST*) 0); // Flush everything signal(signo, SIG_ACK); } static void sig_kill(int signo) { if (!abort_loop) { abort_loop=1; // mark abort for threads kill_server((void*) signo); } signal(signo, SIG_ACK); } static void start_signal_handler(void) { } #else /* if ! __WIN__ && ! __EMX__ */ #ifdef HAVE_LINUXTHREADS #define UNSAFE_DEFAULT_LINUX_THREADS 200 #endif static sig_handler handle_segfault(int sig) { THD *thd=current_thd; /* Strictly speaking, we should need a mutex here but since we have got SIGSEGV already, things are a mess so not having the mutex is not as bad as possibly using a buggy mutex - so we keep things simple. */ if (segfaulted) { fprintf(stderr, "Fatal signal %d while backtracing\n", sig); exit(1); } segfaulted = 1; fprintf(stderr,"\ mysqld got signal %d;\n\ This could be because you hit a bug. It is also possible that this binary\n\ or one of the libraries it was linked agaist is corrupt, improperly built,\n\ or misconfigured. This error can also be caused by malfunctioning hardware.\n", sig); fprintf(stderr, "\ We will try our best to scrape up some info that will hopefully help diagnose\n\ the problem, but since we have already crashed, something is definitely wrong\n\ and this may fail\n\n"); fprintf(stderr, "key_buffer_size=%ld\n", keybuff_size); fprintf(stderr, "record_buffer=%ld\n", my_default_record_cache_size); fprintf(stderr, "sort_buffer=%ld\n", sortbuff_size); fprintf(stderr, "max_used_connections=%ld\n", max_used_connections); fprintf(stderr, "max_connections=%ld\n", max_connections); fprintf(stderr, "threads_connected=%d\n", thread_count); fprintf(stderr, "It is possible that mysqld could use up to \n\ key_buffer_size + (record_buffer + sort_buffer)*max_connections = %ld K\n\ bytes of memory\n", (keybuff_size + (my_default_record_cache_size + sortbuff_size) * max_connections)/ 1024); fprintf(stderr, "Hope that's ok, if not, decrease some variables in the equation\n\n"); #if defined(HAVE_LINUXTHREADS) if (sizeof(char*) == 4 && thread_count > UNSAFE_DEFAULT_LINUX_THREADS) { fprintf(stderr, "\ You seem to be running 32-bit Linux and have %d concurrent connections.\n\ If you have not changed STACK_SIZE in LinuxThreads and build the binary \n\ yourself, LinuxThreads is quite likely to steal a part of global heap for\n\ the thread stack. Please read http://www.mysql.com/doc/L/i/Linux.html\n\n", thread_count); } #endif /* HAVE_LINUXTHREADS */ #ifdef HAVE_STACKTRACE if(!(test_flags & TEST_NO_STACKTRACE)) { #ifdef HAVE_GEMINI_DB utrace(); #endif print_stacktrace(thd ? (gptr) thd->thread_stack : (gptr) 0, thread_stack); } if (thd) { fprintf(stderr, "Trying to get some variables.\n\ Some pointers may be invalid and cause the dump to abort...\n"); safe_print_str("thd->query", thd->query, 1024); fprintf(stderr, "thd->thread_id=%ld\n", thd->thread_id); fprintf(stderr, "\n\ Successfully dumped variables, if you ran with --log, take a look at the\n\ details of what thread %ld did to cause the crash. In some cases of really\n\ bad corruption, the values shown above may be invalid\n\n", thd->thread_id); } fprintf(stderr, "\ The manual page at http://www.mysql.com/doc/C/r/Crashing.html contains\n\ information that should help you find out what is causing the crash\n"); fflush(stderr); #endif /* HAVE_STACKTRACE */ if (test_flags & TEST_CORE_ON_SIGNAL) write_core(sig); exit(1); } #ifndef SA_RESETHAND #define SA_RESETHAND 0 #endif #ifndef SA_NODEFER #define SA_NODEFER 0 #endif static void init_signals(void) { sigset_t set; DBUG_ENTER("init_signals"); sigset(THR_KILL_SIGNAL,end_thread_signal); sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called! if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL)) { struct sigaction sa; sa.sa_flags = SA_RESETHAND | SA_NODEFER; sigemptyset(&sa.sa_mask); sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL); init_stacktrace(); sa.sa_handler=handle_segfault; sigaction(SIGSEGV, &sa, NULL); #ifdef SIGBUS sigaction(SIGBUS, &sa, NULL); #endif sigaction(SIGILL, &sa, NULL); } (void) sigemptyset(&set); #ifdef THREAD_SPECIFIC_SIGPIPE sigset(SIGPIPE,abort_thread); sigaddset(&set,SIGPIPE); #else (void) signal(SIGPIPE,SIG_IGN); // Can't know which thread sigaddset(&set,SIGPIPE); #endif sigaddset(&set,SIGINT); sigaddset(&set,SIGQUIT); sigaddset(&set,SIGTERM); sigaddset(&set,SIGHUP); sigset(SIGTERM,print_signal_warning); // If it's blocked by parent signal(SIGHUP,print_signal_warning); // If it's blocked by parent #ifdef SIGTSTP sigaddset(&set,SIGTSTP); #endif sigaddset(&set,THR_SERVER_ALARM); sigdelset(&set,THR_KILL_SIGNAL); // May be SIGINT sigdelset(&set,THR_CLIENT_ALARM); // For alarms (void) pthread_sigmask(SIG_SETMASK,&set,NULL); DBUG_VOID_RETURN; } static void start_signal_handler(void) { int error; pthread_attr_t thr_attr; DBUG_ENTER("start_signal_handler"); (void) pthread_attr_init(&thr_attr); #if !defined(HAVE_DEC_3_2_THREADS) pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_SYSTEM); (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED); if (!(opt_specialflag & SPECIAL_NO_PRIOR)) my_pthread_attr_setprio(&thr_attr,INTERRUPT_PRIOR); pthread_attr_setstacksize(&thr_attr,32768); #endif (void) pthread_mutex_lock(&LOCK_thread_count); if ((error=pthread_create(&signal_thread,&thr_attr,signal_hand,0))) { sql_print_error("Can't create interrupt-thread (error %d, errno: %d)", error,errno); exit(1); } (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count); pthread_mutex_unlock(&LOCK_thread_count); (void) pthread_attr_destroy(&thr_attr); DBUG_VOID_RETURN; } /* ** This threads handles all signals and alarms */ /* ARGSUSED */ static void *signal_hand(void *arg __attribute__((unused))) { sigset_t set; int sig; my_thread_init(); // Init new thread DBUG_ENTER("signal_hand"); /* Setup alarm handler */ init_thr_alarm(max_connections+max_insert_delayed_threads); #if SIGINT != THR_KILL_SIGNAL (void) sigemptyset(&set); // Setup up SIGINT for debug (void) sigaddset(&set,SIGINT); // For debugging (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL); #endif (void) sigemptyset(&set); // Setup up SIGINT for debug #ifdef USE_ONE_SIGNAL_HAND (void) sigaddset(&set,THR_SERVER_ALARM); // For alarms #endif (void) sigaddset(&set,SIGQUIT); (void) sigaddset(&set,SIGTERM); #if THR_CLIENT_ALARM != SIGHUP (void) sigaddset(&set,SIGHUP); #endif (void) sigaddset(&set,SIGTSTP); /* Save pid to this process (or thread on Linux) */ if (!opt_bootstrap) { File pidFile; if ((pidFile = my_create(pidfile_name,0664, O_WRONLY, MYF(MY_WME))) >= 0) { char buff[21]; sprintf(buff,"%lu",(ulong) getpid()); (void) my_write(pidFile, buff,strlen(buff),MYF(MY_WME)); (void) my_close(pidFile,MYF(0)); } } // signal to start_signal_handler that we are ready (void) pthread_mutex_lock(&LOCK_thread_count); (void) pthread_cond_signal(&COND_thread_count); (void) pthread_mutex_unlock(&LOCK_thread_count); for (;;) { int error; // Used when debugging if (shutdown_in_progress && !abort_loop) { sig= MYSQL_KILL_SIGNAL; error=0; } else while ((error=my_sigwait(&set,&sig)) == EINTR) ; if (cleanup_done) pthread_exit(0); // Safety switch (sig) { case SIGTERM: case SIGQUIT: case SIGKILL: #ifdef EXTRA_DEBUG sql_print_error("Got signal %d to shutdown mysqld",sig); #endif DBUG_PRINT("info",("Got signal: %d abort_loop: %d",sig,abort_loop)); if (!abort_loop) { abort_loop=1; // mark abort for threads #ifdef USE_ONE_SIGNAL_HAND pthread_t tmp; if (!(opt_specialflag & SPECIAL_NO_PRIOR)) my_pthread_attr_setprio(&connection_attrib,INTERRUPT_PRIOR); if (pthread_create(&tmp,&connection_attrib, kill_server_thread, (void*) 0)) sql_print_error("Error: Can't create thread to kill server"); #else kill_server((void*) sig); // MIT THREAD has a alarm thread #endif } break; case SIGHUP: reload_acl_and_cache((THD*) 0,REFRESH_LOG, (TABLE_LIST*) 0); // Flush logs mysql_print_status((THD*) 0); // Send debug some info break; #ifdef USE_ONE_SIGNAL_HAND case THR_SERVER_ALARM: process_alarm(sig); // Trigger alarms. break; #endif default: #ifdef EXTRA_DEBUG sql_print_error("Warning: Got signal: %d, error: %d",sig,error); /* purecov: tested */ #endif break; /* purecov: tested */ } } return(0); /* purecov: deadcode */ } #endif /* __WIN__*/ /* ** All global error messages are sent here where the first one is stored for ** the client */ /* ARGSUSED */ static int my_message_sql(uint error, const char *str, myf MyFlags __attribute__((unused))) { NET *net; DBUG_ENTER("my_message_sql"); DBUG_PRINT("error",("Message: '%s'",str)); if ((net=my_pthread_getspecific_ptr(NET*,THR_NET))) { if (!net->last_error[0]) // Return only first message { strmake(net->last_error,str,sizeof(net->last_error)-1); net->last_errno=error ? error : ER_UNKNOWN_ERROR; } } else sql_print_error("%s: %s",my_progname,str); /* purecov: inspected */ DBUG_RETURN(0); } #ifdef __WIN__ struct utsname { char nodename[FN_REFLEN]; }; int uname(struct utsname *a) { return -1; } #endif #ifdef __WIN__ pthread_handler_decl(handle_shutdown,arg) { MSG msg; my_thread_init(); /* this call should create the message queue for this thread */ PeekMessage(&msg, NULL, 1, 65534,PM_NOREMOVE); if (WaitForSingleObject(hEventShutdown,INFINITE)==WAIT_OBJECT_0) kill_server(MYSQL_KILL_SIGNAL); return 0; } int __stdcall handle_kill(ulong ctrl_type) { if (ctrl_type == CTRL_CLOSE_EVENT || ctrl_type == CTRL_SHUTDOWN_EVENT) { kill_server(MYSQL_KILL_SIGNAL); return TRUE; } return FALSE; } #endif #ifdef OS2 pthread_handler_decl(handle_shutdown,arg) { my_thread_init(); // wait semaphore pthread_cond_wait( &eventShutdown, NULL); // close semaphore and kill server pthread_cond_destroy( &eventShutdown); // exit main loop on main thread, so kill will be done from // main thread (this is thread 2) abort_loop = 1; // unblock select() so_cancel( ip_sock); so_cancel( unix_sock); return 0; } #endif const char *load_default_groups[]= { "mysqld","server",0 }; #ifdef HAVE_LIBWRAP char *libwrapName=NULL; #endif static void open_log(MYSQL_LOG *log, const char *hostname, const char *opt_name, const char *extension, enum_log_type type) { char tmp[FN_REFLEN]; if (!opt_name || !opt_name[0]) { /* TODO: The following should be using fn_format(); We just need to first change fn_format() to cut the file name if it's too long. */ strmake(tmp,hostname,FN_REFLEN-5); strmov(strcend(tmp,'.'),extension); opt_name=tmp; } // get rid of extention if the log is binary to avoid problems if (type == LOG_BIN) { char *p = fn_ext(opt_name); if (p) { uint length=(uint) (p-opt_name); strmake(tmp,opt_name,min(length,FN_REFLEN)); opt_name=tmp; } } log->open(opt_name,type); } #ifdef __WIN__ int win_main(int argc, char **argv) #else int main(int argc, char **argv) #endif { DEBUGGER_OFF; my_umask=0660; // Default umask for new files my_umask_dir=0700; // Default umask for new directories MY_INIT(argv[0]); // init my_sys library & pthreads tzset(); // Set tzname start_time=time((time_t*) 0); #ifdef OS2 { // fix timezone for daylight saving struct tm *ts = localtime(&start_time); if (ts->tm_isdst > 0) _timezone -= 3600; } #endif #ifdef HAVE_TZNAME #if defined(HAVE_LOCALTIME_R) && defined(_REENTRANT) { struct tm tm_tmp; localtime_r(&start_time,&tm_tmp); strmov(time_zone,tzname[tm_tmp.tm_isdst != 0 ? 1 : 0]); } #else { struct tm *start_tm; start_tm=localtime(&start_time); strmov(time_zone,tzname[start_tm->tm_isdst != 0 ? 1 : 0]); } #endif #endif if (gethostname(glob_hostname,sizeof(glob_hostname)-4) < 0) strmov(glob_hostname,"mysql"); strmov(pidfile_name,glob_hostname); strmov(strcend(pidfile_name,'.'),".pid"); // Add extension #ifndef DBUG_OFF strxmov(strend(server_version),MYSQL_SERVER_SUFFIX,"-debug",NullS); #else strmov(strend(server_version),MYSQL_SERVER_SUFFIX); #endif #ifdef _CUSTOMSTARTUPCONFIG_ if (_cust_check_startup()) { /* _cust_check_startup will report startup failure error */ exit( 1 ); } #endif load_defaults("my",load_default_groups,&argc,&argv); defaults_argv=argv; mysql_tmpdir=getenv("TMPDIR"); /* Use this if possible */ #if defined( __WIN__) || defined(OS2) if (!mysql_tmpdir) mysql_tmpdir=getenv("TEMP"); if (!mysql_tmpdir) mysql_tmpdir=getenv("TMP"); #endif if (!mysql_tmpdir || !mysql_tmpdir[0]) mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */ set_options(); get_options(argc,argv); if (opt_log || opt_update_log || opt_slow_log || opt_bin_log) strcat(server_version,"-log"); DBUG_PRINT("info",("%s Ver %s for %s on %s\n",my_progname, server_version, SYSTEM_TYPE,MACHINE_TYPE)); /* These must be set early */ (void) pthread_mutex_init(&LOCK_mysql_create_db,MY_MUTEX_INIT_SLOW); (void) pthread_mutex_init(&LOCK_Acl,MY_MUTEX_INIT_SLOW); (void) pthread_mutex_init(&LOCK_grant,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_open,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_mapped_file,MY_MUTEX_INIT_SLOW); (void) pthread_mutex_init(&LOCK_status,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_error_log,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_delayed_insert,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_delayed_status,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_delayed_create,MY_MUTEX_INIT_SLOW); (void) pthread_mutex_init(&LOCK_manager,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_crypt,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_bytes_sent,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_bytes_received,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_timezone,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_binlog_update, MY_MUTEX_INIT_FAST); // QQ NOT USED (void) pthread_mutex_init(&LOCK_slave, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_server_id, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST); (void) pthread_cond_init(&COND_thread_count,NULL); (void) pthread_cond_init(&COND_refresh,NULL); (void) pthread_cond_init(&COND_thread_cache,NULL); (void) pthread_cond_init(&COND_flush_thread_cache,NULL); (void) pthread_cond_init(&COND_manager,NULL); (void) pthread_cond_init(&COND_binlog_update, NULL); (void) pthread_cond_init(&COND_slave_stopped, NULL); (void) pthread_cond_init(&COND_slave_start, NULL); init_signals(); if (set_default_charset_by_name(default_charset, MYF(MY_WME))) unireg_abort(1); charsets_list = list_charsets(MYF(MY_COMPILED_SETS|MY_CONFIG_SETS)); #ifdef HAVE_OPENSSL if (opt_use_ssl) { ssl_acceptor_fd = VioSSLAcceptorFd_new(opt_ssl_key, opt_ssl_cert, opt_ssl_ca, opt_ssl_capath); if (!ssl_acceptor_fd) opt_use_ssl=0; /* having ssl_acceptor_fd!=0 signals the use of SSL */ } #endif /* HAVE_OPENSSL */ #ifdef HAVE_LIBWRAP libwrapName= my_progname+dirname_length(my_progname); openlog(libwrapName, LOG_PID, LOG_AUTH); #endif if (!(opt_specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(),CONNECT_PRIOR); /* Parameter for threads created for connections */ (void) pthread_attr_init(&connection_attrib); (void) pthread_attr_setdetachstate(&connection_attrib, PTHREAD_CREATE_DETACHED); pthread_attr_setstacksize(&connection_attrib,thread_stack); if (!(opt_specialflag & SPECIAL_NO_PRIOR)) my_pthread_attr_setprio(&connection_attrib,WAIT_PRIOR); pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM); #if defined( SET_RLIMIT_NOFILE) || defined( OS2) /* connections and databases neads lots of files */ { uint wanted_files=10+(uint) max(max_connections*5, max_connections+table_cache_size*2); set_if_bigger(wanted_files, open_files_limit); // Note that some system returns 0 if we succeed here: uint files=set_maximum_open_files(wanted_files); if (files && files < wanted_files && ! open_files_limit) { max_connections= (ulong) min((files-10),max_connections); table_cache_size= (ulong) max((files-10-max_connections)/2,64); DBUG_PRINT("warning", ("Changed limits: max_connections: %ld table_cache: %ld", max_connections,table_cache_size)); sql_print_error("Warning: Changed limits: max_connections: %ld table_cache: %ld",max_connections,table_cache_size); } } #endif unireg_init(opt_specialflag); /* Set up extern variabels */ init_errmessage(); /* Read error messages from file */ lex_init(); item_init(); mysys_uses_curses=0; #ifdef USE_REGEX regex_init(); #endif select_thread=pthread_self(); select_thread_in_use=1; if (use_temp_pool && bitmap_init(&temp_pool,1024,1)) unireg_abort(1); /* ** We have enough space for fiddling with the argv, continue */ umask(((~my_umask) & 0666)); if (my_setwd(mysql_real_data_home,MYF(MY_WME))) { unireg_abort(1); /* purecov: inspected */ } mysql_data_home[0]=FN_CURLIB; // all paths are relative from here mysql_data_home[1]=0; server_init(); table_cache_init(); hostname_cache_init(); sql_cache_init(); randominit(&sql_rand,(ulong) start_time,(ulong) start_time/2); reset_floating_point_exceptions(); init_thr_lock(); /* Fix varibles that are base 1024*1024 */ myisam_max_temp_length= (my_off_t) min(((ulonglong) myisam_max_sort_file_size)*1024*1024, (ulonglong) MAX_FILE_SIZE); myisam_max_extra_temp_length= (my_off_t) min(((ulonglong) myisam_max_extra_sort_file_size)*1024*1024, (ulonglong) MAX_FILE_SIZE); /* Setup log files */ if (opt_log) open_log(&mysql_log, glob_hostname, opt_logname, ".log", LOG_NORMAL); if (opt_update_log) { open_log(&mysql_update_log, glob_hostname, opt_update_logname, "", LOG_NEW); using_update_log=1; } //make sure slave thread gets started // if server_id is set, valid master.info is present, and master_host has // not been specified if(server_id && !master_host) { char fname[FN_REFLEN+128]; MY_STAT stat_area; fn_format(fname, master_info_file, mysql_data_home, "", 4+16+32); if(my_stat(fname, &stat_area, MYF(0)) && !init_master_info(&glob_mi)) master_host = glob_mi.host; } if (opt_bin_log && !server_id) { server_id= !master_host ? 1 : 2; switch (server_id) { #ifdef EXTRA_DEBUG case 1: sql_print_error("\ Warning: You have enabled the binary log, but you haven't set server-id:\n\ Updates will be logged to the binary log, but connections to slaves will\n\ not be accepted."); break; #endif case 2: sql_print_error("\ Warning: You should set server-id to a non-0 value if master_host is set.\n\ The server will not act as a slave."); break; } } if (opt_bin_log) { if (!opt_bin_logname) { char tmp[FN_REFLEN]; /* TODO: The following should be using fn_format(); We just need to first change fn_format() to cut the file name if it's too long. */ strmake(tmp,glob_hostname,FN_REFLEN-5); strmov(strcend(tmp,'.'),"-bin"); opt_bin_logname=my_strdup(tmp,MYF(MY_WME)); } mysql_bin_log.set_index_file_name(opt_binlog_index_name); open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin", LOG_BIN); using_update_log=1; } if (opt_slow_log) open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log", LOG_NORMAL); if (ha_init()) { sql_print_error("Can't init databases"); exit(1); } ha_key_cache(); #if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) if (locked_in_memory && !geteuid()) { if (mlockall(MCL_CURRENT)) { sql_print_error("Warning: Failed to lock memory. Errno: %d\n",errno); } else locked_in_memory=1; } #else locked_in_memory=0; #endif if (opt_myisam_log) (void) mi_log( 1 ); ft_init_stopwords(ft_precompiled_stopwords); /* SerG */ #ifdef __WIN__ #define MYSQL_ERR_FILE "mysql.err" if (!opt_console) { freopen(MYSQL_ERR_FILE,"a+",stdout); freopen(MYSQL_ERR_FILE,"a+",stderr); FreeConsole(); // Remove window } #endif /* init signals & alarm After this we can't quit by a simple unireg_abort */ error_handler_hook = my_message_sql; if (pthread_key_create(&THR_THD,NULL) || pthread_key_create(&THR_NET,NULL) || pthread_key_create(&THR_MALLOC,NULL)) { sql_print_error("Can't create thread-keys"); exit(1); } start_signal_handler(); // Creates pidfile if (acl_init(opt_noacl)) { select_thread_in_use=0; (void) pthread_kill(signal_thread,MYSQL_KILL_SIGNAL); #ifndef __WIN__ if (!opt_bootstrap) (void) my_delete(pidfile_name,MYF(MY_WME)); // Not neaded anymore #endif exit(1); } if (!opt_noacl) (void) grant_init(); if (max_user_connections) init_max_user_conn(); #ifdef HAVE_DLOPEN if (!opt_noacl) udf_init(); #endif if (opt_bootstrap) { int error=bootstrap(stdin); end_thr_alarm(); // Don't allow alarms unireg_abort(error ? 1 : 0); } if (opt_init_file) { if (read_init_file(opt_init_file)) { end_thr_alarm(); // Don't allow alarms unireg_abort(1); } } (void) thr_setconcurrency(concurrency); // 10 by default #ifdef __WIN__ //IRENA { hEventShutdown=CreateEvent(0, FALSE, FALSE, "MySqlShutdown"); pthread_t hThread; if (pthread_create(&hThread,&connection_attrib,handle_shutdown,0)) sql_print_error("Warning: Can't create thread to handle shutdown requests"); // On "Stop Service" we have to do regular shutdown Service.SetShutdownEvent(hEventShutdown); } #endif #ifdef OS2 { pthread_cond_init( &eventShutdown, NULL); pthread_t hThread; if (pthread_create(&hThread,&connection_attrib,handle_shutdown,0)) sql_print_error("Warning: Can't create thread to handle shutdown requests"); } #endif if ( #ifdef HAVE_BERKELEY_DB !berkeley_skip || #endif (flush_time && flush_time != ~(ulong) 0L)) { pthread_t hThread; if (pthread_create(&hThread,&connection_attrib,handle_manager,0)) sql_print_error("Warning: Can't create thread to manage maintenance"); } // slave thread if (master_host) { pthread_t hThread; if (!opt_skip_slave_start && pthread_create(&hThread, &connection_attrib, handle_slave, 0)) sql_print_error("Warning: Can't create thread to handle slave"); else if(opt_skip_slave_start) init_master_info(&glob_mi); } printf(ER(ER_READY),my_progname,server_version,""); fflush(stdout); #ifdef __NT__ if (hPipe == INVALID_HANDLE_VALUE && !have_tcpip) { sql_print_error("TCP/IP must be installed on Win98 platforms"); } else { pthread_mutex_lock(&LOCK_thread_count); (void) pthread_cond_init(&COND_handler_count,NULL); { pthread_t hThread; handler_count=0; if ( hPipe != INVALID_HANDLE_VALUE ) { handler_count++; if (pthread_create(&hThread,&connection_attrib, handle_connections_namedpipes, 0)) { sql_print_error("Warning: Can't create thread to handle named pipes"); handler_count--; } } if (have_tcpip && !opt_disable_networking) { handler_count++; if (pthread_create(&hThread,&connection_attrib, handle_connections_sockets, 0)) { sql_print_error("Warning: Can't create thread to handle named pipes"); handler_count--; } } while (handler_count > 0) { pthread_cond_wait(&COND_handler_count,&LOCK_thread_count); } } pthread_mutex_unlock(&LOCK_thread_count); } #else handle_connections_sockets(0); #ifdef EXTRA_DEBUG sql_print_error("Exiting main thread"); #endif #endif /* __NT__ */ /* (void) pthread_attr_destroy(&connection_attrib); */ DBUG_PRINT("quit",("Exiting main thread")); #ifndef __WIN__ #ifdef EXTRA_DEBUG sql_print_error("Before Lock_thread_count"); #endif (void) pthread_mutex_lock(&LOCK_thread_count); select_thread_in_use=0; // For close_connections (void) pthread_cond_broadcast(&COND_thread_count); (void) pthread_mutex_unlock(&LOCK_thread_count); #ifdef EXTRA_DEBUG sql_print_error("After lock_thread_count"); #endif #else if (Service.IsNT()) { if(start_mode) { if (WaitForSingleObject(hEventShutdown,1000)==WAIT_TIMEOUT) Service.Stop(); } else { Service.SetShutdownEvent(0); if(hEventShutdown) CloseHandle(hEventShutdown); } } else { Service.SetShutdownEvent(0); if(hEventShutdown) CloseHandle(hEventShutdown); } #endif /* Wait until cleanup is done */ (void) pthread_mutex_lock(&LOCK_thread_count); while (!ready_to_exit) { pthread_cond_wait(&COND_thread_count,&LOCK_thread_count); } (void) pthread_mutex_unlock(&LOCK_thread_count); my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); exit(0); return(0); /* purecov: deadcode */ } #ifdef __WIN__ /* ------------------------------------------------------------------------ main and thread entry function for Win32 (all this is needed only to run mysqld as a service on WinNT) -------------------------------------------------------------------------- */ int mysql_service(void *p) { win_main(Service.my_argc, Service.my_argv); return 0; } int main(int argc, char **argv) { // check environment variable OS if (Service.GetOS()) // "OS" defined; Should be NT { if (argc == 2) { char path[FN_REFLEN]; my_path(path, argv[0], ""); // Find name in path fn_format(path,argv[0],path,"",1+4+16); // Force use of full path if (!strcmp(argv[1],"-install") || !strcmp(argv[1],"--install")) { Service.Install(1,MYSQL_SERVICENAME,MYSQL_SERVICENAME,path); return 0; } else if (!strcmp(argv[1],"-install-manual") || !strcmp(argv[1],"--install-manual")) { Service.Install(0,MYSQL_SERVICENAME,MYSQL_SERVICENAME,path); return 0; } else if (!strcmp(argv[1],"-remove") || !strcmp(argv[1],"--remove")) { Service.Remove(MYSQL_SERVICENAME); return 0; } } else if (argc == 1) // No arguments; start as a service { // init service start_mode = 1; long tmp=Service.Init(MYSQL_SERVICENAME,mysql_service); return 0; } } // This is a WIN95 machine or a start of mysqld as a standalone program // we have to pass the arguments, in case of NT-service this will be done // by ServiceMain() Service.my_argc=argc; Service.my_argv=argv; mysql_service(NULL); return 0; } /* ------------------------------------------------------------------------ */ #endif static int bootstrap(FILE *file) { THD *thd= new THD; int error; thd->bootstrap=1; thd->client_capabilities=0; my_net_init(&thd->net,(Vio*) 0); thd->max_packet_length=thd->net.max_packet; thd->master_access= ~0; thd->thread_id=thread_id++; thread_count++; bootstrap_file=file; if (pthread_create(&thd->real_id,&connection_attrib,handle_bootstrap, (void*) thd)) { sql_print_error("Warning: Can't create thread to handle bootstrap"); return -1; } /* Wait for thread to die */ (void) pthread_mutex_lock(&LOCK_thread_count); while (thread_count) { (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count); DBUG_PRINT("quit",("One thread died (count=%u)",thread_count)); } (void) pthread_mutex_unlock(&LOCK_thread_count); error= thd->fatal_error; net_end(&thd->net); thd->cleanup(); delete thd; return error; } static bool read_init_file(char *file_name) { FILE *file; DBUG_ENTER("read_init_file"); DBUG_PRINT("enter",("name: %s",file_name)); if (!(file=my_fopen(file_name,O_RDONLY,MYF(MY_WME)))) return(1); bootstrap(file); /* Ignore errors from this */ (void) my_fclose(file,MYF(MY_WME)); return 0; } static void create_new_thread(THD *thd) { DBUG_ENTER("create_new_thread"); NET *net=&thd->net; // For easy ref net->timeout = (uint) connect_timeout; // Timeout for read if (protocol_version > 9) net->return_errno=1; /* don't allow too many connections */ if (thread_count - delayed_insert_threads >= max_connections+1 || abort_loop) { DBUG_PRINT("error",("Too many connections")); close_connection(net,ER_CON_COUNT_ERROR); delete thd; DBUG_VOID_RETURN; } if (pthread_mutex_lock(&LOCK_thread_count)) { DBUG_PRINT("error",("Can't lock LOCK_thread_count")); close_connection(net,ER_OUT_OF_RESOURCES); delete thd; DBUG_VOID_RETURN; } if (thread_count-delayed_insert_threads > max_used_connections) max_used_connections=thread_count-delayed_insert_threads; thd->thread_id=thread_id++; for (uint i=0; i < 8 ; i++) // Generate password teststring thd->scramble[i]= (char) (rnd(&sql_rand)*94+33); thd->scramble[8]=0; thd->rand=sql_rand; thd->real_id=pthread_self(); // Keep purify happy /* Start a new thread to handle connection */ #ifdef ONE_THREAD if (test_flags & TEST_NO_THREADS) // For debugging under Linux { thread_cache_size=0; // Safety thread_count++; threads.append(thd); thd->real_id=pthread_self(); (void) pthread_mutex_unlock(&LOCK_thread_count); handle_one_connection((void*) thd); } else #endif { if (cached_thread_count > wake_thread) { start_cached_thread(thd); (void) pthread_mutex_unlock(&LOCK_thread_count); } else { int error; thread_count++; thread_created++; threads.append(thd); DBUG_PRINT("info",(("creating thread %d"), thd->thread_id)); thd->connect_time = time(NULL); if ((error=pthread_create(&thd->real_id,&connection_attrib, handle_one_connection, (void*) thd))) { DBUG_PRINT("error", ("Can't create thread to handle request (error %d)", error)); thread_count--; thd->killed=1; // Safety (void) pthread_mutex_unlock(&LOCK_thread_count); net_printf(net,ER_CANT_CREATE_THREAD,error); (void) pthread_mutex_lock(&LOCK_thread_count); close_connection(net,0,0); delete thd; (void) pthread_mutex_unlock(&LOCK_thread_count); DBUG_VOID_RETURN; } (void) pthread_mutex_unlock(&LOCK_thread_count); } } DBUG_PRINT("info",("Thread created")); DBUG_VOID_RETURN; } /* Handle new connections and spawn new process to handle them */ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused))) { my_socket sock,new_sock; uint error_count=0; uint max_used_connection= (uint) (max(ip_sock,unix_sock)+1); fd_set readFDs,clientFDs; THD *thd; struct sockaddr_in cAddr; int ip_flags=0,socket_flags=0,flags; Vio *vio_tmp; DBUG_ENTER("handle_connections_sockets"); LINT_INIT(new_sock); (void) my_pthread_getprio(pthread_self()); // For debugging FD_ZERO(&clientFDs); if (ip_sock != INVALID_SOCKET) { FD_SET(ip_sock,&clientFDs); #ifdef HAVE_FCNTL ip_flags = fcntl(ip_sock, F_GETFL, 0); #endif } #ifdef HAVE_SYS_UN_H FD_SET(unix_sock,&clientFDs); #ifdef HAVE_FCNTL socket_flags=fcntl(unix_sock, F_GETFL, 0); #endif #endif DBUG_PRINT("general",("Waiting for connections.")); MAYBE_BROKEN_SYSCALL; while (!abort_loop) { readFDs=clientFDs; #ifdef HPUX if (select(max_used_connection,(int*) &readFDs,0,0,0) < 0) continue; #else if (select((int) max_used_connection,&readFDs,0,0,0) < 0) { if (socket_errno != SOCKET_EINTR) { if (!select_errors++ && !abort_loop) /* purecov: inspected */ sql_print_error("mysqld: Got error %d from select",socket_errno); /* purecov: inspected */ } MAYBE_BROKEN_SYSCALL; continue; } #endif /* HPUX */ if (abort_loop) break; /* ** Is this a new connection request */ #ifdef HAVE_SYS_UN_H if (FD_ISSET(unix_sock,&readFDs)) { sock = unix_sock; flags= socket_flags; } else #endif { sock = ip_sock; flags= ip_flags; } #if !defined(NO_FCNTL_NONBLOCK) if (!(test_flags & TEST_BLOCKING)) { #if defined(O_NONBLOCK) fcntl(sock, F_SETFL, flags | O_NONBLOCK); #elif defined(O_NDELAY) fcntl(sock, F_SETFL, flags | O_NDELAY); #endif } #endif /* NO_FCNTL_NONBLOCK */ for (uint retry=0; retry < MAX_ACCEPT_RETRY; retry++) { size_socket length=sizeof(struct sockaddr_in); new_sock = accept(sock, my_reinterpret_cast(struct sockaddr *) (&cAddr), &length); if (new_sock != INVALID_SOCKET || (socket_errno != SOCKET_EINTR && socket_errno != SOCKET_EAGAIN)) break; MAYBE_BROKEN_SYSCALL; #if !defined(NO_FCNTL_NONBLOCK) if (!(test_flags & TEST_BLOCKING)) { if (retry == MAX_ACCEPT_RETRY - 1) fcntl(sock, F_SETFL, flags); // Try without O_NONBLOCK } #endif } #if !defined(NO_FCNTL_NONBLOCK) if (!(test_flags & TEST_BLOCKING)) fcntl(sock, F_SETFL, flags); #endif if (new_sock == INVALID_SOCKET) { if ((error_count++ & 255) == 0) // This can happen often sql_perror("Error in accept"); MAYBE_BROKEN_SYSCALL; if (socket_errno == SOCKET_ENFILE || socket_errno == SOCKET_EMFILE) sleep(1); // Give other threads some time continue; } #ifdef HAVE_LIBWRAP { if (sock == ip_sock) { struct request_info req; signal(SIGCHLD, SIG_DFL); request_init(&req, RQ_DAEMON, libwrapName, RQ_FILE, new_sock, NULL); fromhost(&req); if (!hosts_access(&req)) { // This may be stupid but refuse() includes an exit(0) // which we surely don't want... // clean_exit() - same stupid thing ... syslog(deny_severity, "refused connect from %s", eval_client(&req)); if (req.sink) ((void (*)(int))req.sink)(req.fd); // C++ sucks (the gibberish in front just translates the supplied // sink function pointer in the req structure from a void (*sink)(); // to a void(*sink)(int) if you omit the cast, the C++ compiler // will cry... (void) shutdown(new_sock,2); // This looks fine to me... (void) closesocket(new_sock); continue; } } } #endif /* HAVE_LIBWRAP */ { size_socket dummyLen; struct sockaddr dummy; dummyLen = sizeof(struct sockaddr); if (getsockname(new_sock,&dummy, &dummyLen) < 0) { sql_perror("Error on new connection socket"); (void) shutdown(new_sock,2); (void) closesocket(new_sock); continue; } } /* ** Don't allow too many connections */ if (!(thd= new THD)) { (void) shutdown(new_sock,2); VOID(closesocket(new_sock)); continue; } if (!(vio_tmp=vio_new(new_sock, sock == unix_sock ? VIO_TYPE_SOCKET : VIO_TYPE_TCPIP, sock == unix_sock)) || my_net_init(&thd->net,vio_tmp)) { if (vio_tmp) vio_delete(vio_tmp); else { (void) shutdown(new_sock,2); (void) closesocket(new_sock); } delete thd; continue; } if (sock == unix_sock) thd->host=(char*) localhost; create_new_thread(thd); } #ifdef OS2 // kill server must be invoked from thread 1! kill_server(MYSQL_KILL_SIGNAL); #endif #ifdef __NT__ pthread_mutex_lock(&LOCK_thread_count); handler_count--; pthread_mutex_unlock(&LOCK_thread_count); pthread_cond_signal(&COND_handler_count); #endif DBUG_RETURN(0); } #ifdef __NT__ pthread_handler_decl(handle_connections_namedpipes,arg) { HANDLE hConnectedPipe; BOOL fConnected; THD *thd; my_thread_init(); DBUG_ENTER("handle_connections_namedpipes"); (void) my_pthread_getprio(pthread_self()); // For debugging DBUG_PRINT("general",("Waiting for named pipe connections.")); while (!abort_loop) { /* wait for named pipe connection */ fConnected = ConnectNamedPipe( hPipe, NULL ); if (abort_loop) break; if ( !fConnected ) fConnected = GetLastError() == ERROR_PIPE_CONNECTED; if ( !fConnected ) { CloseHandle( hPipe ); if ((hPipe = CreateNamedPipe(szPipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, (int) net_buffer_length, (int) net_buffer_length, NMPWAIT_USE_DEFAULT_WAIT, &saPipeSecurity )) == INVALID_HANDLE_VALUE ) { sql_perror("Can't create new named pipe!"); break; // Abort } } hConnectedPipe = hPipe; /* create new pipe for new connection */ if ((hPipe = CreateNamedPipe(szPipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, (int) net_buffer_length, (int) net_buffer_length, NMPWAIT_USE_DEFAULT_WAIT, &saPipeSecurity)) == INVALID_HANDLE_VALUE) { sql_perror("Can't create new named pipe!"); hPipe=hConnectedPipe; continue; // We have to try again } if ( !(thd = new THD)) { DisconnectNamedPipe( hConnectedPipe ); CloseHandle( hConnectedPipe ); continue; } if (!(thd->net.vio = vio_new_win32pipe(hConnectedPipe)) || my_net_init(&thd->net, thd->net.vio)) { close_connection(&thd->net,ER_OUT_OF_RESOURCES); delete thd; continue; } /* host name is unknown */ thd->host = my_strdup(localhost,MYF(0)); /* Host is unknown */ create_new_thread(thd); } pthread_mutex_lock(&LOCK_thread_count); handler_count--; pthread_cond_signal(&COND_handler_count); pthread_mutex_unlock(&LOCK_thread_count); DBUG_RETURN(0); } #endif /* __NT__ */ /****************************************************************************** ** handle start options ******************************************************************************/ enum options { OPT_ISAM_LOG=256, OPT_SKIP_NEW, OPT_SKIP_GRANT, OPT_SKIP_LOCK, OPT_ENABLE_LOCK, OPT_USE_LOCKING, OPT_SOCKET, OPT_UPDATE_LOG, OPT_BIN_LOG, OPT_SKIP_RESOLVE, OPT_SKIP_NETWORKING, OPT_BIN_LOG_INDEX, OPT_BIND_ADDRESS, OPT_PID_FILE, OPT_SKIP_PRIOR, OPT_BIG_TABLES, OPT_STANDALONE, OPT_ONE_THREAD, OPT_CONSOLE, OPT_LOW_PRIORITY_UPDATES, OPT_SKIP_HOST_CACHE, OPT_LONG_FORMAT, OPT_FLUSH, OPT_SAFE, OPT_BOOTSTRAP, OPT_SKIP_SHOW_DB, OPT_TABLE_TYPE, OPT_INIT_FILE, OPT_DELAY_KEY_WRITE, OPT_SLOW_QUERY_LOG, OPT_SKIP_DELAY_KEY_WRITE, OPT_CHARSETS_DIR, OPT_BDB_HOME, OPT_BDB_LOG, OPT_BDB_TMP, OPT_BDB_NOSYNC, OPT_BDB_LOCK, OPT_BDB_SKIP, OPT_BDB_NO_RECOVER, OPT_BDB_SHARED, OPT_MASTER_HOST, OPT_MASTER_USER, OPT_MASTER_PASSWORD, OPT_MASTER_PORT, OPT_MASTER_INFO_FILE, OPT_MASTER_CONNECT_RETRY, OPT_MASTER_RETRY_COUNT, OPT_SQL_BIN_UPDATE_SAME, OPT_REPLICATE_DO_DB, OPT_REPLICATE_IGNORE_DB, OPT_LOG_SLAVE_UPDATES, OPT_BINLOG_DO_DB, OPT_BINLOG_IGNORE_DB, OPT_WANT_CORE, OPT_SKIP_CONCURRENT_INSERT, OPT_MEMLOCK, OPT_MYISAM_RECOVER, OPT_REPLICATE_REWRITE_DB, OPT_SERVER_ID, OPT_SKIP_SLAVE_START, OPT_SKIP_INNOBASE, OPT_SAFEMALLOC_MEM_LIMIT, OPT_REPLICATE_DO_TABLE, OPT_REPLICATE_IGNORE_TABLE, OPT_REPLICATE_WILD_DO_TABLE, OPT_REPLICATE_WILD_IGNORE_TABLE, OPT_DISCONNECT_SLAVE_EVENT_COUNT, OPT_ABORT_SLAVE_EVENT_COUNT, OPT_INNODB_DATA_HOME_DIR, OPT_INNODB_DATA_FILE_PATH, OPT_INNODB_LOG_GROUP_HOME_DIR, OPT_INNODB_LOG_ARCH_DIR, OPT_INNODB_LOG_ARCHIVE, OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT, OPT_INNODB_FAST_SHUTDOWN, OPT_INNODB_UNIX_FILE_FLUSH_METHOD, OPT_SAFE_SHOW_DB, OPT_GEMINI_SKIP, OPT_INNODB_SKIP, OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_GEMINI_FLUSH_LOG, OPT_GEMINI_RECOVER, OPT_GEMINI_UNBUFFERED_IO, OPT_SKIP_SAFEMALLOC, OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS, OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL, OPT_SAFE_USER_CREATE, OPT_SQL_MODE, OPT_SLAVE_SKIP_ERRORS, OPT_LOCAL_INFILE }; static struct option long_options[] = { {"ansi", no_argument, 0, 'a'}, {"basedir", required_argument, 0, 'b'}, #ifdef HAVE_BERKELEY_DB {"bdb-home", required_argument, 0, (int) OPT_BDB_HOME}, {"bdb-lock-detect", required_argument, 0, (int) OPT_BDB_LOCK}, {"bdb-logdir", required_argument, 0, (int) OPT_BDB_LOG}, {"bdb-no-recover", no_argument, 0, (int) OPT_BDB_NO_RECOVER}, {"bdb-no-sync", no_argument, 0, (int) OPT_BDB_NOSYNC}, {"bdb-shared-data", no_argument, 0, (int) OPT_BDB_SHARED}, {"bdb-tmpdir", required_argument, 0, (int) OPT_BDB_TMP}, #endif {"big-tables", no_argument, 0, (int) OPT_BIG_TABLES}, {"binlog-do-db", required_argument, 0, (int) OPT_BINLOG_DO_DB}, {"binlog-ignore-db", required_argument, 0, (int) OPT_BINLOG_IGNORE_DB}, {"bind-address", required_argument, 0, (int) OPT_BIND_ADDRESS}, {"bootstrap", no_argument, 0, (int) OPT_BOOTSTRAP}, #ifdef __WIN__ {"console", no_argument, 0, (int) OPT_CONSOLE}, #endif {"core-file", no_argument, 0, (int) OPT_WANT_CORE}, {"chroot", required_argument, 0, 'r'}, {"character-sets-dir", required_argument, 0, (int) OPT_CHARSETS_DIR}, {"datadir", required_argument, 0, 'h'}, {"debug", optional_argument, 0, '#'}, {"default-character-set", required_argument, 0, 'C'}, {"default-table-type", required_argument, 0, (int) OPT_TABLE_TYPE}, {"delay-key-write-for-all-tables", no_argument, 0, (int) OPT_DELAY_KEY_WRITE}, {"enable-locking", no_argument, 0, (int) OPT_ENABLE_LOCK}, {"exit-info", optional_argument, 0, 'T'}, {"flush", no_argument, 0, (int) OPT_FLUSH}, #ifdef HAVE_GEMINI_DB {"gemini-flush-log-at-commit",no_argument, 0, (int) OPT_GEMINI_FLUSH_LOG}, {"gemini-recovery", required_argument, 0, (int) OPT_GEMINI_RECOVER}, {"gemini-unbuffered-io", no_argument, 0, (int) OPT_GEMINI_UNBUFFERED_IO}, #endif /* We must always support this option to make scripts like mysqltest easier to do */ {"innodb_data_file_path", required_argument, 0, OPT_INNODB_DATA_FILE_PATH}, #ifdef HAVE_INNOBASE_DB {"innodb_data_home_dir", required_argument, 0, OPT_INNODB_DATA_HOME_DIR}, {"innodb_log_group_home_dir", required_argument, 0, OPT_INNODB_LOG_GROUP_HOME_DIR}, {"innodb_log_arch_dir", required_argument, 0, OPT_INNODB_LOG_ARCH_DIR}, {"innodb_log_archive", optional_argument, 0, OPT_INNODB_LOG_ARCHIVE}, {"innodb_flush_log_at_trx_commit", optional_argument, 0, OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT}, {"innodb_fast_shutdown", optional_argument, 0, OPT_INNODB_FAST_SHUTDOWN}, {"innodb_flush_method", required_argument, 0, OPT_INNODB_UNIX_FILE_FLUSH_METHOD}, #endif {"help", no_argument, 0, '?'}, {"init-file", required_argument, 0, (int) OPT_INIT_FILE}, {"log", optional_argument, 0, 'l'}, {"language", required_argument, 0, 'L'}, {"local-infile", optional_argument, 0, (int) OPT_LOCAL_INFILE}, {"log-bin", optional_argument, 0, (int) OPT_BIN_LOG}, {"log-bin-index", required_argument, 0, (int) OPT_BIN_LOG_INDEX}, {"log-isam", optional_argument, 0, (int) OPT_ISAM_LOG}, {"log-update", optional_argument, 0, (int) OPT_UPDATE_LOG}, {"log-slow-queries", optional_argument, 0, (int) OPT_SLOW_QUERY_LOG}, {"log-long-format", no_argument, 0, (int) OPT_LONG_FORMAT}, {"log-slave-updates", no_argument, 0, (int) OPT_LOG_SLAVE_UPDATES}, {"low-priority-updates", no_argument, 0, (int) OPT_LOW_PRIORITY_UPDATES}, {"master-host", required_argument, 0, (int) OPT_MASTER_HOST}, {"master-user", required_argument, 0, (int) OPT_MASTER_USER}, {"master-password", required_argument, 0, (int) OPT_MASTER_PASSWORD}, {"master-port", required_argument, 0, (int) OPT_MASTER_PORT}, {"master-connect-retry", required_argument, 0, (int) OPT_MASTER_CONNECT_RETRY}, {"master-retry-count", required_argument, 0, (int) OPT_MASTER_RETRY_COUNT}, {"master-info-file", required_argument, 0, (int) OPT_MASTER_INFO_FILE}, {"myisam-recover", optional_argument, 0, (int) OPT_MYISAM_RECOVER}, {"memlock", no_argument, 0, (int) OPT_MEMLOCK}, // needs to be available for the test case to pass in non-debugging mode // is a no-op {"disconnect-slave-event-count", required_argument, 0, (int) OPT_DISCONNECT_SLAVE_EVENT_COUNT}, {"abort-slave-event-count", required_argument, 0, (int) OPT_ABORT_SLAVE_EVENT_COUNT}, {"max-binlog-dump-events", required_argument, 0, (int) OPT_MAX_BINLOG_DUMP_EVENTS}, {"sporadic-binlog-dump-fail", no_argument, 0, (int) OPT_SPORADIC_BINLOG_DUMP_FAIL}, {"safemalloc-mem-limit", required_argument, 0, (int) OPT_SAFEMALLOC_MEM_LIMIT}, {"new", no_argument, 0, 'n'}, {"old-protocol", no_argument, 0, 'o'}, #ifdef ONE_THREAD {"one-thread", no_argument, 0, (int) OPT_ONE_THREAD}, #endif {"pid-file", required_argument, 0, (int) OPT_PID_FILE}, {"port", required_argument, 0, 'P'}, {"replicate-do-db", required_argument, 0, (int) OPT_REPLICATE_DO_DB}, {"replicate-do-table", required_argument, 0, (int) OPT_REPLICATE_DO_TABLE}, {"replicate-wild-do-table", required_argument, 0, (int) OPT_REPLICATE_WILD_DO_TABLE}, {"replicate-ignore-db", required_argument, 0, (int) OPT_REPLICATE_IGNORE_DB}, {"replicate-ignore-table", required_argument, 0, (int) OPT_REPLICATE_IGNORE_TABLE}, {"replicate-wild-ignore-table", required_argument, 0, (int) OPT_REPLICATE_WILD_IGNORE_TABLE}, {"replicate-rewrite-db", required_argument, 0, (int) OPT_REPLICATE_REWRITE_DB}, {"safe-mode", no_argument, 0, (int) OPT_SAFE}, {"safe-show-database", no_argument, 0, (int) OPT_SAFE_SHOW_DB}, {"safe-user-create", no_argument, 0, (int) OPT_SAFE_USER_CREATE}, {"server-id", required_argument, 0, (int) OPT_SERVER_ID}, {"set-variable", required_argument, 0, 'O'}, {"skip-bdb", no_argument, 0, (int) OPT_BDB_SKIP}, {"skip-innodb", no_argument, 0, (int) OPT_INNODB_SKIP}, {"skip-gemini", no_argument, 0, (int) OPT_GEMINI_SKIP}, {"skip-concurrent-insert", no_argument, 0, (int) OPT_SKIP_CONCURRENT_INSERT}, {"skip-delay-key-write", no_argument, 0, (int) OPT_SKIP_DELAY_KEY_WRITE}, {"skip-grant-tables", no_argument, 0, (int) OPT_SKIP_GRANT}, {"skip-locking", no_argument, 0, (int) OPT_SKIP_LOCK}, {"skip-host-cache", no_argument, 0, (int) OPT_SKIP_HOST_CACHE}, {"skip-name-resolve", no_argument, 0, (int) OPT_SKIP_RESOLVE}, {"skip-networking", no_argument, 0, (int) OPT_SKIP_NETWORKING}, {"skip-new", no_argument, 0, (int) OPT_SKIP_NEW}, {"skip-safemalloc", no_argument, 0, (int) OPT_SKIP_SAFEMALLOC}, {"skip-show-database", no_argument, 0, (int) OPT_SKIP_SHOW_DB}, {"skip-slave-start", no_argument, 0, (int) OPT_SKIP_SLAVE_START}, {"skip-stack-trace", no_argument, 0, (int) OPT_SKIP_STACK_TRACE}, {"skip-symlink", no_argument, 0, (int) OPT_SKIP_SYMLINKS}, {"skip-thread-priority", no_argument, 0, (int) OPT_SKIP_PRIOR}, {"slave-skip-errors", required_argument,0, (int) OPT_SLAVE_SKIP_ERRORS}, {"socket", required_argument, 0, (int) OPT_SOCKET}, {"sql-bin-update-same", no_argument, 0, (int) OPT_SQL_BIN_UPDATE_SAME}, {"sql-mode", required_argument, 0, (int) OPT_SQL_MODE}, #include "sslopt-longopts.h" #ifdef __WIN__ {"standalone", no_argument, 0, (int) OPT_STANDALONE}, #endif {"transaction-isolation", required_argument, 0, (int) OPT_TX_ISOLATION}, {"temp-pool", no_argument, 0, (int) OPT_TEMP_POOL}, {"tmpdir", required_argument, 0, 't'}, {"use-locking", no_argument, 0, (int) OPT_USE_LOCKING}, #ifdef USE_SYMDIR {"use-symbolic-links", no_argument, 0, 's'}, #endif {"user", required_argument, 0, 'u'}, {"version", no_argument, 0, 'V'}, {"warnings", no_argument, 0, 'W'}, {0, 0, 0, 0} }; #define LONG_TIMEOUT ((ulong) 3600L*24L*365L) CHANGEABLE_VAR changeable_vars[] = { { "back_log", (long*) &back_log, 50, 1, 65535, 0, 1 }, #ifdef HAVE_BERKELEY_DB { "bdb_cache_size", (long*) &berkeley_cache_size, KEY_CACHE_SIZE, 20*1024, (long) ~0, 0, IO_SIZE }, {"bdb_log_buffer_size", (long*) &berkeley_log_buffer_size, 0, 256*1024L, ~0L, 0, 1024}, { "bdb_max_lock", (long*) &berkeley_max_lock, 10000, 0, (long) ~0, 0, 1 }, /* QQ: The following should be removed soon! */ { "bdb_lock_max", (long*) &berkeley_max_lock, 10000, 0, (long) ~0, 0, 1 }, #endif { "binlog_cache_size", (long*) &binlog_cache_size, 32*1024L, IO_SIZE, ~0L, 0, IO_SIZE }, { "connect_timeout", (long*) &connect_timeout, CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1 }, { "delayed_insert_timeout", (long*) &delayed_insert_timeout, DELAYED_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 }, { "delayed_insert_limit", (long*) &delayed_insert_limit, DELAYED_LIMIT, 1, ~0L, 0, 1 }, { "delayed_queue_size", (long*) &delayed_queue_size, DELAYED_QUEUE_SIZE, 1, ~0L, 0, 1 }, { "flush_time", (long*) &flush_time, FLUSH_TIME, 0, LONG_TIMEOUT, 0, 1 }, #ifdef HAVE_GEMINI_DB { "gemini_buffer_cache", (long*) &gemini_buffer_cache, 128 * 8192, 16, LONG_MAX, 0, 1 }, { "gemini_connection_limit", (long*) &gemini_connection_limit, 100, 10, LONG_MAX, 0, 1 }, { "gemini_io_threads", (long*) &gemini_io_threads, 2, 0, 256, 0, 1 }, { "gemini_log_cluster_size", (long*) &gemini_log_cluster_size, 256 * 1024, 16 * 1024, LONG_MAX, 0, 1 }, { "gemini_lock_table_size", (long*) &gemini_locktablesize, 4096, 1024, LONG_MAX, 0, 1 }, { "gemini_lock_wait_timeout",(long*) &gemini_lock_wait_timeout, 10, 1, LONG_MAX, 0, 1 }, { "gemini_spin_retries", (long*) &gemini_spin_retries, 1, 0, LONG_MAX, 0, 1 }, #endif #ifdef HAVE_INNOBASE_DB {"innodb_mirrored_log_groups", (long*) &innobase_mirrored_log_groups, 1, 1, 10, 0, 1}, {"innodb_log_files_in_group", (long*) &innobase_log_files_in_group, 2, 2, 100, 0, 1}, {"innodb_log_file_size", (long*) &innobase_log_file_size, 5*1024*1024L, 1*1024*1024L, ~0L, 0, 1024*1024L}, {"innodb_log_buffer_size", (long*) &innobase_log_buffer_size, 1024*1024L, 256*1024L, ~0L, 0, 1024}, {"innodb_buffer_pool_size", (long*) &innobase_buffer_pool_size, 8*1024*1024L, 1024*1024L, ~0L, 0, 1024*1024L}, {"innodb_additional_mem_pool_size", (long*) &innobase_additional_mem_pool_size, 1*1024*1024L, 512*1024L, ~0L, 0, 1024}, {"innodb_file_io_threads", (long*) &innobase_file_io_threads, 4, 4, 64, 0, 1}, {"innodb_lock_wait_timeout", (long*) &innobase_lock_wait_timeout, 50, 1, 1024 * 1024 * 1024, 0, 1}, {"innodb_thread_concurrency", (long*) &innobase_thread_concurrency, 8, 1, 1000, 0, 1}, {"innodb_force_recovery", (long*) &innobase_force_recovery, 0, 0, 6, 0, 1}, #endif { "interactive_timeout", (long*) &net_interactive_timeout, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 }, { "join_buffer_size", (long*) &join_buff_size, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE }, { "key_buffer_size", (long*) &keybuff_size, KEY_CACHE_SIZE, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD, IO_SIZE }, { "long_query_time", (long*) &long_query_time, 10, 1, LONG_TIMEOUT, 0, 1 }, { "lower_case_table_names", (long*) &lower_case_table_names, IF_WIN(1,0), 0, 1, 0, 1 }, { "max_allowed_packet", (long*) &max_allowed_packet, 1024*1024L, 80, 64*1024*1024L, MALLOC_OVERHEAD, 1024 }, { "max_binlog_cache_size", (long*) &max_binlog_cache_size, ~0L, IO_SIZE, ~0L, 0, IO_SIZE }, { "max_binlog_size", (long*) &max_binlog_size, 1024*1024L*1024L, 1024, 1024*1024L*1024L, 0, 1 }, { "max_connections", (long*) &max_connections, 100, 1, 16384, 0, 1 }, { "max_connect_errors", (long*) &max_connect_errors, MAX_CONNECT_ERRORS, 1, ~0L, 0, 1 }, { "max_delayed_threads", (long*) &max_insert_delayed_threads, 20, 1, 16384, 0, 1 }, { "max_heap_table_size", (long*) &max_heap_table_size, 16*1024*1024L, 16384, ~0L, MALLOC_OVERHEAD, 1024 }, { "max_join_size", (long*) &max_join_size, ~0L, 1, ~0L, 0, 1 }, { "max_sort_length", (long*) &max_item_sort_length, 1024, 4, 8192*1024L, 0, 1 }, { "max_tmp_tables", (long*) &max_tmp_tables, 32, 1, ~0L, 0, 1 }, { "max_user_connections", (long*) &max_user_connections, 0, 1, ~0L, 0, 1 }, { "max_write_lock_count", (long*) &max_write_lock_count, ~0L, 1, ~0L, 0, 1 }, { "myisam_max_extra_sort_file_size", (long*) &myisam_max_extra_sort_file_size, (long) (MI_MAX_TEMP_LENGTH/(1024L*1024L)), 0, ~0L, 0, 1 }, { "myisam_max_sort_file_size", (long*) &myisam_max_sort_file_size, (long) (LONG_MAX/(1024L*1024L)), 0, ~0L, 0, 1 }, { "myisam_sort_buffer_size", (long*) &myisam_sort_buffer_size, 8192*1024, 4, ~0L, 0, 1 }, { "net_buffer_length", (long*) &net_buffer_length, 16384, 1024, 1024*1024L, MALLOC_OVERHEAD, 1024 }, { "net_retry_count", (long*) &mysqld_net_retry_count, MYSQLD_NET_RETRY_COUNT, 1, ~0L, 0, 1 }, { "net_read_timeout", (long*) &net_read_timeout, NET_READ_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 }, { "net_write_timeout", (long*) &net_write_timeout, NET_WRITE_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 }, { "open_files_limit", (long*) &open_files_limit, 0, 0, 65535, 0, 1}, { "query_buffer_size", (long*) &query_buff_size, 0, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD, IO_SIZE }, { "record_buffer", (long*) &my_default_record_cache_size, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE }, { "record_rnd_buffer", (long*) &record_rnd_cache_size, 0, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE }, { "slave_net_timeout", (long*) &slave_net_timeout, SLAVE_NET_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 }, { "slow_launch_time", (long*) &slow_launch_time, 2L, 0L, LONG_TIMEOUT, 0, 1 }, { "sort_buffer", (long*) &sortbuff_size, MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, ~0L, MALLOC_OVERHEAD, 1 }, { "table_cache", (long*) &table_cache_size, 64, 1, 16384, 0, 1 }, { "thread_concurrency", (long*) &concurrency, DEFAULT_CONCURRENCY, 1, 512, 0, 1 }, { "thread_cache_size", (long*) &thread_cache_size, 0, 0, 16384, 0, 1 }, { "tmp_table_size", (long*) &tmp_table_size, 32*1024*1024L, 1024, ~0L, 0, 1 }, { "thread_stack", (long*) &thread_stack, DEFAULT_THREAD_STACK, 1024*32, ~0L, 0, 1024 }, { "wait_timeout", (long*) &net_wait_timeout, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 }, { NullS, (long*) 0, 0, 0, 0, 0, 0} }; struct show_var_st init_vars[]= { {"back_log", (char*) &back_log, SHOW_LONG}, {"basedir", mysql_home, SHOW_CHAR}, #ifdef HAVE_BERKELEY_DB {"bdb_cache_size", (char*) &berkeley_cache_size, SHOW_LONG}, {"bdb_log_buffer_size", (char*) &berkeley_log_buffer_size, SHOW_LONG}, {"bdb_home", (char*) &berkeley_home, SHOW_CHAR_PTR}, {"bdb_max_lock", (char*) &berkeley_max_lock, SHOW_LONG}, {"bdb_logdir", (char*) &berkeley_logdir, SHOW_CHAR_PTR}, {"bdb_shared_data", (char*) &berkeley_shared_data, SHOW_BOOL}, {"bdb_tmpdir", (char*) &berkeley_tmpdir, SHOW_CHAR_PTR}, {"bdb_version", (char*) DB_VERSION_STRING, SHOW_CHAR}, #endif {"binlog_cache_size", (char*) &binlog_cache_size, SHOW_LONG}, {"character_set", default_charset, SHOW_CHAR}, {"character_sets", (char*) &charsets_list, SHOW_CHAR_PTR}, {"concurrent_insert", (char*) &myisam_concurrent_insert, SHOW_MY_BOOL}, {"connect_timeout", (char*) &connect_timeout, SHOW_LONG}, {"datadir", mysql_real_data_home, SHOW_CHAR}, {"delay_key_write", (char*) &myisam_delay_key_write, SHOW_MY_BOOL}, {"delayed_insert_limit", (char*) &delayed_insert_limit, SHOW_LONG}, {"delayed_insert_timeout", (char*) &delayed_insert_timeout, SHOW_LONG}, {"delayed_queue_size", (char*) &delayed_queue_size, SHOW_LONG}, {"flush", (char*) &myisam_flush, SHOW_MY_BOOL}, {"flush_time", (char*) &flush_time, SHOW_LONG}, #ifdef HAVE_GEMINI_DB {"gemini_buffer_cache", (char*) &gemini_buffer_cache, SHOW_LONG}, {"gemini_connection_limit", (char*) &gemini_connection_limit, SHOW_LONG}, {"gemini_io_threads", (char*) &gemini_io_threads, SHOW_LONG}, {"gemini_log_cluster_size", (char*) &gemini_log_cluster_size, SHOW_LONG}, {"gemini_lock_table_size", (char*) &gemini_locktablesize, SHOW_LONG}, {"gemini_lock_wait_timeout",(char*) &gemini_lock_wait_timeout, SHOW_LONG}, {"gemini_recovery_options", (char*) &gemini_recovery_options_str, SHOW_CHAR_PTR}, {"gemini_spin_retries", (char*) &gemini_spin_retries, SHOW_LONG}, #endif {"have_bdb", (char*) &have_berkeley_db, SHOW_HAVE}, {"have_gemini", (char*) &have_gemini, SHOW_HAVE}, {"have_innodb", (char*) &have_innodb, SHOW_HAVE}, {"have_isam", (char*) &have_isam, SHOW_HAVE}, {"have_raid", (char*) &have_raid, SHOW_HAVE}, {"have_openssl", (char*) &have_ssl, SHOW_HAVE}, {"init_file", (char*) &opt_init_file, SHOW_CHAR_PTR}, #ifdef HAVE_INNOBASE_DB {"innodb_additional_mem_pool_size", (char*) &innobase_additional_mem_pool_size, SHOW_LONG }, {"innodb_buffer_pool_size", (char*) &innobase_buffer_pool_size, SHOW_LONG }, {"innodb_data_file_path", (char*) &innobase_data_file_path, SHOW_CHAR_PTR}, {"innodb_data_home_dir", (char*) &innobase_data_home_dir, SHOW_CHAR_PTR}, {"innodb_file_io_threads", (char*) &innobase_file_io_threads, SHOW_LONG }, {"innodb_force_recovery", (char*) &innobase_force_recovery, SHOW_LONG }, {"innodb_thread_concurrency", (char*) &innobase_thread_concurrency, SHOW_LONG }, {"innodb_flush_log_at_trx_commit", (char*) &innobase_flush_log_at_trx_commit, SHOW_MY_BOOL}, {"innodb_fast_shutdown", (char*) &innobase_fast_shutdown, SHOW_MY_BOOL}, {"innodb_flush_method", (char*) &innobase_unix_file_flush_method, SHOW_CHAR_PTR}, {"innodb_lock_wait_timeout", (char*) &innobase_lock_wait_timeout, SHOW_LONG }, {"innodb_log_arch_dir", (char*) &innobase_log_arch_dir, SHOW_CHAR_PTR}, {"innodb_log_archive", (char*) &innobase_log_archive, SHOW_MY_BOOL}, {"innodb_log_buffer_size", (char*) &innobase_log_buffer_size, SHOW_LONG }, {"innodb_log_file_size", (char*) &innobase_log_file_size, SHOW_LONG}, {"innodb_log_files_in_group", (char*) &innobase_log_files_in_group, SHOW_LONG}, {"innodb_log_group_home_dir", (char*) &innobase_log_group_home_dir, SHOW_CHAR_PTR}, {"innodb_mirrored_log_groups", (char*) &innobase_mirrored_log_groups, SHOW_LONG}, #endif {"interactive_timeout", (char*) &net_interactive_timeout, SHOW_LONG}, {"join_buffer_size", (char*) &join_buff_size, SHOW_LONG}, {"key_buffer_size", (char*) &keybuff_size, SHOW_LONG}, {"language", language, SHOW_CHAR}, {"large_files_support", (char*) &opt_large_files, SHOW_BOOL}, #ifdef HAVE_MLOCKALL {"locked_in_memory", (char*) &locked_in_memory, SHOW_BOOL}, #endif {"log", (char*) &opt_log, SHOW_BOOL}, {"log_update", (char*) &opt_update_log, SHOW_BOOL}, {"log_bin", (char*) &opt_bin_log, SHOW_BOOL}, {"log_slave_updates", (char*) &opt_log_slave_updates, SHOW_BOOL}, {"log_long_queries", (char*) &opt_slow_log, SHOW_BOOL}, {"long_query_time", (char*) &long_query_time, SHOW_LONG}, {"low_priority_updates", (char*) &low_priority_updates, SHOW_BOOL}, {"lower_case_table_names", (char*) &lower_case_table_names, SHOW_LONG}, {"max_allowed_packet", (char*) &max_allowed_packet, SHOW_LONG}, {"max_binlog_cache_size", (char*) &max_binlog_cache_size, SHOW_LONG}, {"max_binlog_size", (char*) &max_binlog_size, SHOW_LONG}, {"max_connections", (char*) &max_connections, SHOW_LONG}, {"max_connect_errors", (char*) &max_connect_errors, SHOW_LONG}, {"max_delayed_threads", (char*) &max_insert_delayed_threads, SHOW_LONG}, {"max_heap_table_size", (char*) &max_heap_table_size, SHOW_LONG}, {"max_join_size", (char*) &max_join_size, SHOW_LONG}, {"max_sort_length", (char*) &max_item_sort_length, SHOW_LONG}, {"max_user_connections", (char*) &max_user_connections, SHOW_LONG}, {"max_tmp_tables", (char*) &max_tmp_tables, SHOW_LONG}, {"max_write_lock_count", (char*) &max_write_lock_count, SHOW_LONG}, {"myisam_max_extra_sort_file_size", (char*) &myisam_max_extra_sort_file_size, SHOW_LONG}, {"myisam_max_sort_file_size",(char*) &myisam_max_sort_file_size, SHOW_LONG}, {"myisam_recover_options", (char*) &myisam_recover_options, SHOW_LONG}, {"myisam_sort_buffer_size", (char*) &myisam_sort_buffer_size, SHOW_LONG}, {"net_buffer_length", (char*) &net_buffer_length, SHOW_LONG}, {"net_read_timeout", (char*) &net_read_timeout, SHOW_LONG}, {"net_retry_count", (char*) &mysqld_net_retry_count, SHOW_LONG}, {"net_write_timeout", (char*) &net_write_timeout, SHOW_LONG}, {"open_files_limit", (char*) &open_files_limit, SHOW_LONG}, {"pid_file", (char*) pidfile_name, SHOW_CHAR}, {"port", (char*) &mysql_port, SHOW_INT}, {"protocol_version", (char*) &protocol_version, SHOW_INT}, {"record_buffer", (char*) &my_default_record_cache_size,SHOW_LONG}, {"record_rnd_buffer", (char*) &record_rnd_cache_size, SHOW_LONG}, {"query_buffer_size", (char*) &query_buff_size, SHOW_LONG}, {"safe_show_database", (char*) &opt_safe_show_db, SHOW_BOOL}, {"server_id", (char*) &server_id, SHOW_LONG}, {"slave_net_timeout", (char*) &slave_net_timeout, SHOW_LONG}, {"skip_locking", (char*) &my_disable_locking, SHOW_MY_BOOL}, {"skip_networking", (char*) &opt_disable_networking, SHOW_BOOL}, {"skip_show_database", (char*) &opt_skip_show_db, SHOW_BOOL}, {"slow_launch_time", (char*) &slow_launch_time, SHOW_LONG}, {"socket", (char*) &mysql_unix_port, SHOW_CHAR_PTR}, {"sort_buffer", (char*) &sortbuff_size, SHOW_LONG}, {"sql_mode", (char*) &opt_sql_mode, SHOW_LONG}, {"table_cache", (char*) &table_cache_size, SHOW_LONG}, {"table_type", (char*) &default_table_type_name, SHOW_CHAR_PTR}, {"thread_cache_size", (char*) &thread_cache_size, SHOW_LONG}, #ifdef HAVE_THR_SETCONCURRENCY {"thread_concurrency", (char*) &concurrency, SHOW_LONG}, #endif {"thread_stack", (char*) &thread_stack, SHOW_LONG}, {"transaction_isolation", (char*) &default_tx_isolation_name, SHOW_CHAR_PTR}, #ifdef HAVE_TZNAME {"timezone", time_zone, SHOW_CHAR}, #endif {"tmp_table_size", (char*) &tmp_table_size, SHOW_LONG}, {"tmpdir", (char*) &mysql_tmpdir, SHOW_CHAR_PTR}, {"version", server_version, SHOW_CHAR}, {"wait_timeout", (char*) &net_wait_timeout, SHOW_LONG}, {NullS, NullS, SHOW_LONG} }; struct show_var_st status_vars[]= { {"Aborted_clients", (char*) &aborted_threads, SHOW_LONG}, {"Aborted_connects", (char*) &aborted_connects, SHOW_LONG}, {"Bytes_received", (char*) &bytes_received, SHOW_LONG}, {"Bytes_sent", (char*) &bytes_sent, SHOW_LONG}, {"Com_admin_commands", (char*) &com_other, SHOW_LONG}, {"Com_alter_table", (char*) (com_stat+(uint) SQLCOM_ALTER_TABLE),SHOW_LONG}, {"Com_analyze", (char*) (com_stat+(uint) SQLCOM_ANALYZE),SHOW_LONG}, {"Com_backup_table", (char*) (com_stat+(uint) SQLCOM_BACKUP_TABLE),SHOW_LONG}, {"Com_begin", (char*) (com_stat+(uint) SQLCOM_BEGIN),SHOW_LONG}, {"Com_change_db", (char*) (com_stat+(uint) SQLCOM_CHANGE_DB),SHOW_LONG}, {"Com_change_master", (char*) (com_stat+(uint) SQLCOM_CHANGE_MASTER),SHOW_LONG}, {"Com_check", (char*) (com_stat+(uint) SQLCOM_CHECK),SHOW_LONG}, {"Com_commit", (char*) (com_stat+(uint) SQLCOM_COMMIT),SHOW_LONG}, {"Com_create_db", (char*) (com_stat+(uint) SQLCOM_CREATE_DB),SHOW_LONG}, {"Com_create_function", (char*) (com_stat+(uint) SQLCOM_CREATE_FUNCTION),SHOW_LONG}, {"Com_create_index", (char*) (com_stat+(uint) SQLCOM_CREATE_INDEX),SHOW_LONG}, {"Com_create_table", (char*) (com_stat+(uint) SQLCOM_CREATE_TABLE),SHOW_LONG}, {"Com_delete", (char*) (com_stat+(uint) SQLCOM_DELETE),SHOW_LONG}, {"Com_drop_db", (char*) (com_stat+(uint) SQLCOM_DROP_DB),SHOW_LONG}, {"Com_drop_function", (char*) (com_stat+(uint) SQLCOM_DROP_FUNCTION),SHOW_LONG}, {"Com_drop_index", (char*) (com_stat+(uint) SQLCOM_DROP_INDEX),SHOW_LONG}, {"Com_drop_table", (char*) (com_stat+(uint) SQLCOM_DROP_TABLE),SHOW_LONG}, {"Com_flush", (char*) (com_stat+(uint) SQLCOM_FLUSH),SHOW_LONG}, {"Com_grant", (char*) (com_stat+(uint) SQLCOM_GRANT),SHOW_LONG}, {"Com_insert", (char*) (com_stat+(uint) SQLCOM_INSERT),SHOW_LONG}, {"Com_insert_select", (char*) (com_stat+(uint) SQLCOM_INSERT_SELECT),SHOW_LONG}, {"Com_kill", (char*) (com_stat+(uint) SQLCOM_KILL),SHOW_LONG}, {"Com_load", (char*) (com_stat+(uint) SQLCOM_LOAD),SHOW_LONG}, {"Com_load_master_table", (char*) (com_stat+(uint) SQLCOM_LOAD_MASTER_TABLE),SHOW_LONG}, {"Com_lock_tables", (char*) (com_stat+(uint) SQLCOM_LOCK_TABLES),SHOW_LONG}, {"Com_optimize", (char*) (com_stat+(uint) SQLCOM_OPTIMIZE),SHOW_LONG}, {"Com_purge", (char*) (com_stat+(uint) SQLCOM_PURGE),SHOW_LONG}, {"Com_rename_table", (char*) (com_stat+(uint) SQLCOM_RENAME_TABLE),SHOW_LONG}, {"Com_repair", (char*) (com_stat+(uint) SQLCOM_REPAIR),SHOW_LONG}, {"Com_replace", (char*) (com_stat+(uint) SQLCOM_REPLACE),SHOW_LONG}, {"Com_replace_select", (char*) (com_stat+(uint) SQLCOM_REPLACE_SELECT),SHOW_LONG}, {"Com_reset", (char*) (com_stat+(uint) SQLCOM_RESET),SHOW_LONG}, {"Com_restore_table", (char*) (com_stat+(uint) SQLCOM_RESTORE_TABLE),SHOW_LONG}, {"Com_revoke", (char*) (com_stat+(uint) SQLCOM_REVOKE),SHOW_LONG}, {"Com_rollback", (char*) (com_stat+(uint) SQLCOM_ROLLBACK),SHOW_LONG}, {"Com_select", (char*) (com_stat+(uint) SQLCOM_SELECT),SHOW_LONG}, {"Com_set_option", (char*) (com_stat+(uint) SQLCOM_SET_OPTION),SHOW_LONG}, {"Com_show_binlogs", (char*) (com_stat+(uint) SQLCOM_SHOW_BINLOGS),SHOW_LONG}, {"Com_show_create", (char*) (com_stat+(uint) SQLCOM_SHOW_CREATE),SHOW_LONG}, {"Com_show_databases", (char*) (com_stat+(uint) SQLCOM_SHOW_DATABASES),SHOW_LONG}, {"Com_show_fields", (char*) (com_stat+(uint) SQLCOM_SHOW_FIELDS),SHOW_LONG}, {"Com_show_grants", (char*) (com_stat+(uint) SQLCOM_SHOW_GRANTS),SHOW_LONG}, {"Com_show_keys", (char*) (com_stat+(uint) SQLCOM_SHOW_KEYS),SHOW_LONG}, {"Com_show_logs", (char*) (com_stat+(uint) SQLCOM_SHOW_LOGS),SHOW_LONG}, {"Com_show_master_stat", (char*) (com_stat+(uint) SQLCOM_SHOW_MASTER_STAT),SHOW_LONG}, {"Com_show_open_tables", (char*) (com_stat+(uint) SQLCOM_SHOW_OPEN_TABLES),SHOW_LONG}, {"Com_show_processlist", (char*) (com_stat+(uint) SQLCOM_SHOW_PROCESSLIST),SHOW_LONG}, {"Com_show_slave_stat", (char*) (com_stat+(uint) SQLCOM_SHOW_SLAVE_STAT),SHOW_LONG}, {"Com_show_status", (char*) (com_stat+(uint) SQLCOM_SHOW_STATUS),SHOW_LONG}, {"Com_show_tables", (char*) (com_stat+(uint) SQLCOM_SHOW_TABLES),SHOW_LONG}, {"Com_show_variables", (char*) (com_stat+(uint) SQLCOM_SHOW_VARIABLES),SHOW_LONG}, {"Com_slave_start", (char*) (com_stat+(uint) SQLCOM_SLAVE_START),SHOW_LONG}, {"Com_slave_stop", (char*) (com_stat+(uint) SQLCOM_SLAVE_STOP),SHOW_LONG}, {"Com_truncate", (char*) (com_stat+(uint) SQLCOM_TRUNCATE),SHOW_LONG}, {"Com_unlock_tables", (char*) (com_stat+(uint) SQLCOM_UNLOCK_TABLES),SHOW_LONG}, {"Com_update", (char*) (com_stat+(uint) SQLCOM_UPDATE),SHOW_LONG}, {"Connections", (char*) &thread_id, SHOW_LONG_CONST}, {"Created_tmp_disk_tables", (char*) &created_tmp_disk_tables,SHOW_LONG}, {"Created_tmp_tables", (char*) &created_tmp_tables, SHOW_LONG}, {"Created_tmp_files", (char*) &my_tmp_file_created, SHOW_LONG}, {"Delayed_insert_threads", (char*) &delayed_insert_threads, SHOW_LONG}, {"Delayed_writes", (char*) &delayed_insert_writes, SHOW_LONG}, {"Delayed_errors", (char*) &delayed_insert_errors, SHOW_LONG}, {"Flush_commands", (char*) &refresh_version, SHOW_LONG_CONST}, {"Handler_delete", (char*) &ha_delete_count, SHOW_LONG}, {"Handler_read_first", (char*) &ha_read_first_count, SHOW_LONG}, {"Handler_read_key", (char*) &ha_read_key_count, SHOW_LONG}, {"Handler_read_next", (char*) &ha_read_next_count, SHOW_LONG}, {"Handler_read_prev", (char*) &ha_read_prev_count, SHOW_LONG}, {"Handler_read_rnd", (char*) &ha_read_rnd_count, SHOW_LONG}, {"Handler_read_rnd_next", (char*) &ha_read_rnd_next_count, SHOW_LONG}, {"Handler_update", (char*) &ha_update_count, SHOW_LONG}, {"Handler_write", (char*) &ha_write_count, SHOW_LONG}, {"Key_blocks_used", (char*) &_my_blocks_used, SHOW_LONG_CONST}, {"Key_read_requests", (char*) &_my_cache_r_requests, SHOW_LONG}, {"Key_reads", (char*) &_my_cache_read, SHOW_LONG}, {"Key_write_requests", (char*) &_my_cache_w_requests, SHOW_LONG}, {"Key_writes", (char*) &_my_cache_write, SHOW_LONG}, {"Max_used_connections", (char*) &max_used_connections, SHOW_LONG}, {"Not_flushed_key_blocks", (char*) &_my_blocks_changed, SHOW_LONG_CONST}, {"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use, SHOW_LONG_CONST}, {"Open_tables", (char*) 0, SHOW_OPENTABLES}, {"Open_files", (char*) &my_file_opened, SHOW_INT_CONST}, {"Open_streams", (char*) &my_stream_opened, SHOW_INT_CONST}, {"Opened_tables", (char*) &opened_tables, SHOW_LONG}, {"Questions", (char*) 0, SHOW_QUESTION}, {"Select_full_join", (char*) &select_full_join_count, SHOW_LONG}, {"Select_full_range_join", (char*) &select_full_range_join_count, SHOW_LONG}, {"Select_range", (char*) &select_range_count, SHOW_LONG}, {"Select_range_check", (char*) &select_range_check_count, SHOW_LONG}, {"Select_scan", (char*) &select_scan_count, SHOW_LONG}, {"Slave_running", (char*) &slave_running, SHOW_BOOL}, {"Slave_open_temp_tables", (char*) &slave_open_temp_tables, SHOW_LONG}, {"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONG}, {"Slow_queries", (char*) &long_query_count, SHOW_LONG}, {"Sort_merge_passes", (char*) &filesort_merge_passes, SHOW_LONG}, {"Sort_range", (char*) &filesort_range_count, SHOW_LONG}, {"Sort_rows", (char*) &filesort_rows, SHOW_LONG}, {"Sort_scan", (char*) &filesort_scan_count, SHOW_LONG}, {"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG}, {"Table_locks_waited", (char*) &locks_waited, SHOW_LONG}, {"Threads_cached", (char*) &cached_thread_count, SHOW_LONG_CONST}, {"Threads_created", (char*) &thread_created, SHOW_LONG_CONST}, {"Threads_connected", (char*) &thread_count, SHOW_INT_CONST}, {"Threads_running", (char*) &thread_running, SHOW_INT_CONST}, {"Uptime", (char*) 0, SHOW_STARTTIME}, {NullS, NullS, SHOW_LONG} }; static void print_version(void) { printf("%s Ver %s for %s on %s\n",my_progname, server_version,SYSTEM_TYPE,MACHINE_TYPE); } static void use_help(void) { print_version(); printf("Use '--help' or '--no-defaults --help' for a list of available options\n"); } static void usage(void) { print_version(); puts("\ Copyright (C) 2000 MySQL AB, by Monty and others\n\ This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\ and you are welcome to modify and redistribute it under the GPL license\n\ Starts the MySQL server\n"); printf("Usage: %s [OPTIONS]\n", my_progname); puts("\n\ --ansi Use ANSI SQL syntax instead of MySQL syntax\n\ -b, --basedir=path Path to installation directory. All paths are\n\ usually resolved relative to this\n\ --big-tables Allow big result sets by saving all temporary sets\n\ on file (Solves most 'table full' errors)\n\ --bind-address=IP Ip address to bind to\n\ --bootstrap Used by mysql installation scripts\n\ --character-sets-dir=...\n\ Directory where character sets are\n\ --chroot=path Chroot mysqld daemon during startup\n\ --core-file Write core on errors\n\ -h, --datadir=path Path to the database root"); #ifndef DBUG_OFF printf("\ -#, --debug[=...] Debug log. Default is '%s'\n",default_dbug_option); #ifdef SAFEMALLOC puts("\ --skip-safemalloc Don't use the memory allocation checking"); #endif #endif puts("\ --default-character-set=charset\n\ Set the default character set\n\ --default-table-type=type\n\ Set the default table type for tables\n\ --delay-key-write-for-all-tables\n\ Don't flush key buffers between writes for any MyISAM\n\ table\n\ --enable-locking Enable system locking\n\ -T, --exit-info Used for debugging; Use at your own risk!\n\ --flush Flush tables to disk between SQL commands\n\ -?, --help Display this help and exit\n\ --init-file=file Read SQL commands from this file at startup\n\ -L, --language=... Client error messages in given language. May be\n\ given as a full path\n\ -l, --log[=file] Log connections and queries to file\n\ --log-bin[=file] Log queries in new binary format (for replication)\n\ --log-bin-index=file File that holds the names for last binary log files\n\ --log-update[=file] Log updates to file.# where # is a unique number\n\ if not given.\n\ --log-isam[=file] Log all MyISAM changes to file\n\ --log-long-format Log some extra information to update log\n\ --low-priority-updates INSERT/DELETE/UPDATE has lower priority than selects\n\ --log-slow-queries=[file]\n\ Log slow queries to this log file. Defaults logging\n\ to hostname-slow.log\n\ --pid-file=path Pid file used by safe_mysqld\n\ --myisam-recover[=option[,option...]] where options is one of DEAULT,\n\ BACKUP or FORCE.\n\ --memlock Lock mysqld in memory\n\ -n, --new Use very new possible 'unsafe' functions\n\ -o, --old-protocol Use the old (3.20) protocol\n\ -P, --port=... Port number to use for connection\n"); #ifdef ONE_THREAD puts("\ --one-thread Only use one thread (for debugging under Linux)\n"); #endif puts("\ -O, --set-variable var=option\n\ Give a variable an value. --help lists variables\n\ -Sg, --skip-grant-tables\n\ Start without grant tables. This gives all users\n\ FULL ACCESS to all tables!\n\ --safe-mode Skip some optimize stages (for testing)\n\ --safe-show-database Don't show databases for which the user has no\n\ privileges\n\ --safe-user-create Don't new users cretaion without privileges to the\n\ mysql.user table\n\ --skip-concurrent-insert\n\ Don't use concurrent insert with MyISAM\n\ --skip-delay-key-write\n\ Ignore the delay_key_write option for all tables\n\ --skip-host-cache Don't cache host names\n\ --skip-locking Don't use system locking. To use isamchk one has\n\ to shut down the server.\n\ --skip-name-resolve Don't resolve hostnames.\n\ All hostnames are IP's or 'localhost'\n\ --skip-networking Don't allow connection with TCP/IP.\n\ --skip-new Don't use new, possible wrong routines.\n"); /* We have to break the string here because of VC++ limits */ puts("\ --skip-stack-trace Don't print a stack trace on failure\n\ --skip-show-database Don't allow 'SHOW DATABASE' commands\n\ --skip-thread-priority\n\ Don't give threads different priorities.\n\ --socket=... Socket file to use for connection\n\ -t, --tmpdir=path Path for temporary files\n\ --sql-mode=option[,option[,option...]] where option can be one of:\n\ REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES,\n\ IGNORE_SPACE, SERIALIZE, ONLY_FULL_GROUP_BY.\n\ --transaction-isolation\n\ Default transaction isolation level\n\ --temp-pool Use a pool of temporary files\n\ -u, --user=user_name Run mysqld daemon as user\n\ -V, --version output version information and exit\n\ -W, --warnings Log some not critical warnings to the log file\n"); #ifdef __WIN__ puts("NT and Win32 specific options:\n\ --console Don't remove the console window\n\ --install Install mysqld as a service (NT)\n\ --remove Remove mysqld from the service list (NT)\n\ --standalone Dummy option to start as a standalone program (NT)\ "); #ifdef USE_SYMDIR puts("--use-symbolic-links Enable symbolic link support"); #endif puts(""); #endif #ifdef HAVE_BERKELEY_DB puts("\ --bdb-home= directory Berkeley home direcory\n\ --bdb-lock-detect=# Berkeley lock detect\n\ (DEFAULT, OLDEST, RANDOM or YOUNGEST, # sec)\n\ --bdb-logdir=directory Berkeley DB log file directory\n\ --bdb-no-sync Don't synchronously flush logs\n\ --bdb-no-recover Don't try to recover Berkeley DB tables on start\n\ --bdb-shared-data Start Berkeley DB in multi-process mode\n\ --bdb-tmpdir=directory Berkeley DB tempfile name\n\ --skip-bdb Don't use berkeley db (will save memory)\n\ "); #endif /* HAVE_BERKELEY_DB */ #ifdef HAVE_GEMINI_DB puts("\ --gemini-recovery=mode Set Crash Recovery operating mode\n\ (FULL, NONE, FORCE - default FULL)\n\ --gemini-flush-log-at-commit\n\ Every commit forces a write to the reovery log\n\ --gemini-unbuffered-io Use unbuffered i/o\n\ --skip-gemini Don't use gemini (will save memory)\n\ "); #endif #ifdef HAVE_INNOBASE_DB puts("\ --innodb_data_home_dir=dir The common part for Innodb table spaces\n\ --innodb_data_file_path=dir Path to individual files and their sizes\n\ --innodb_flush_method=# With which method to flush data\n\ --innodb_flush_log_at_trx_commit[=#]\n\ Set to 0 if you don't want to flush logs\n\ --innodb_log_arch_dir=dir Where full logs should be archived\n\ --innodb_log_archive[=#] Set to 1 if you want to have logs archived\n\ --innodb_log_group_home_dir=dir Path to innodb log files.\n\ --skip-innodb Don't use Innodb (will save memory)\n\ "); #endif /* HAVE_INNOBASE_DB */ print_defaults("my",load_default_groups); puts(""); #include "sslopt-usage.h" fix_paths(); set_ports(); printf("\ To see what values a running MySQL server is using, type\n\ 'mysqladmin variables' instead of 'mysqld --help'.\n\ The default values (after parsing the command line arguments) are:\n\n"); printf("basedir: %s\n",mysql_home); printf("datadir: %s\n",mysql_real_data_home); printf("tmpdir: %s\n",mysql_tmpdir); printf("language: %s\n",language); #ifndef __WIN__ printf("pid file: %s\n",pidfile_name); #endif if (opt_logname) printf("logfile: %s\n",opt_logname); if (opt_update_logname) printf("update log: %s\n",opt_update_logname); if (opt_bin_log) { printf("binary log: %s\n",opt_bin_logname ? opt_bin_logname : ""); printf("binary log index: %s\n", opt_binlog_index_name ? opt_binlog_index_name : ""); } if (opt_slow_logname) printf("update log: %s\n",opt_slow_logname); printf("TCP port: %d\n",mysql_port); #if defined(HAVE_SYS_UN_H) printf("Unix socket: %s\n",mysql_unix_port); #endif if (my_disable_locking) puts("\nsystem locking is not in use"); if (opt_noacl) puts("\nGrant tables are not used. All users have full access rights"); printf("\nPossible variables for option --set-variable (-O) are:\n"); for (uint i=0 ; changeable_vars[i].name ; i++) printf("%-20s current value: %lu\n", changeable_vars[i].name, (ulong) *changeable_vars[i].varptr); } static void set_options(void) { set_all_changeable_vars( changeable_vars ); #if !defined( my_pthread_setprio ) && !defined( HAVE_PTHREAD_SETSCHEDPARAM ) opt_specialflag |= SPECIAL_NO_PRIOR; #endif (void) strmov( default_charset, MYSQL_CHARSET); (void) strmov( language, LANGUAGE); (void) strmov( mysql_real_data_home, get_relative_path(DATADIR)); #ifdef __WIN__ /* Allow Win32 users to move MySQL anywhere */ { char prg_dev[LIBLEN]; my_path(prg_dev,my_progname,"mysql/bin"); strcat(prg_dev,"/../"); // Remove 'bin' to get base dir cleanup_dirname(mysql_home,prg_dev); } #else const char *tmpenv; if ( !(tmpenv = getenv("MY_BASEDIR_VERSION"))) tmpenv = DEFAULT_MYSQL_HOME; (void) strmov( mysql_home, tmpenv ); #endif #if defined( HAVE_mit_thread ) || defined( __WIN__ ) || defined( HAVE_LINUXTHREADS ) my_disable_locking = 1; #endif my_bind_addr = htonl( INADDR_ANY ); } /* Initiates DEBUG - but no debugging here ! */ static void get_options(int argc,char **argv) { int c,option_index=0; myisam_delay_key_write=1; // Allow use of this while ((c=getopt_long(argc,argv,"ab:C:h:#::T::?l::L:O:P:sS::t:u:noVvWI?", long_options, &option_index)) != EOF) { switch(c) { case '#': #ifndef DBUG_OFF DBUG_PUSH(optarg ? optarg : default_dbug_option); #endif opt_endinfo=1; /* unireg: memory allocation */ break; case 'W': opt_warnings=1; break; case 'a': opt_sql_mode = (MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES | MODE_IGNORE_SPACE | MODE_SERIALIZABLE | MODE_ONLY_FULL_GROUP_BY); default_tx_isolation= ISO_SERIALIZABLE; break; case 'b': strmov(mysql_home,optarg); break; case 'l': opt_log=1; opt_logname=optarg; // Use hostname.log if null break; case 'h': strmov(mysql_real_data_home,optarg); break; case 'L': strmov(language,optarg); break; case 'n': opt_specialflag|= SPECIAL_NEW_FUNC; break; case 'o': protocol_version=PROTOCOL_VERSION-1; break; case 'O': if (set_changeable_var(optarg, changeable_vars)) { use_help(); exit(1); } break; case 'P': mysql_port= (unsigned int) atoi(optarg); break; case OPT_LOCAL_INFILE: opt_local_infile= test(optarg || atoi(optarg) != 0); break; case OPT_SLAVE_SKIP_ERRORS: init_slave_skip_errors(optarg); break; case OPT_SAFEMALLOC_MEM_LIMIT: #if !defined(DBUG_OFF) && defined(SAFEMALLOC) safemalloc_mem_limit = atoi(optarg); #endif break; case OPT_SOCKET: mysql_unix_port= optarg; break; case 'r': mysqld_chroot=optarg; break; #ifdef USE_SYMDIR case 's': my_use_symdir=1; /* Use internal symbolic links */ break; #endif case 't': mysql_tmpdir=optarg; break; case OPT_TEMP_POOL: use_temp_pool=1; break; case 'u': mysqld_user=optarg; break; case 'v': case 'V': print_version(); exit(0); case 'I': case '?': usage(); exit(0); case 'T': test_flags= optarg ? (uint) atoi(optarg) : 0; opt_endinfo=1; break; case 'S': if (!optarg) opt_specialflag|= SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE; else if (!strcmp(optarg,"l")) my_disable_locking=1; else if (!strcmp(optarg,"g")) opt_noacl=1; else { fprintf(stderr,"%s: Unrecognized option: %s\n",my_progname,optarg); use_help(); exit(1); } break; case (int) OPT_BIG_TABLES: thd_startup_options|=OPTION_BIG_TABLES; break; case (int) OPT_ISAM_LOG: opt_myisam_log=1; if (optarg) myisam_log_filename=optarg; break; case (int) OPT_UPDATE_LOG: opt_update_log=1; opt_update_logname=optarg; // Use hostname.# if null break; case (int) OPT_BIN_LOG_INDEX: opt_binlog_index_name = optarg; break; case (int) OPT_BIN_LOG: opt_bin_log=1; x_free(opt_bin_logname); if (optarg && optarg[0]) opt_bin_logname=my_strdup(optarg,MYF(0)); break; // needs to be handled (as no-op) in non-debugging mode for test suite case (int)OPT_DISCONNECT_SLAVE_EVENT_COUNT: #ifndef DBUG_OFF disconnect_slave_event_count = atoi(optarg); #endif break; case (int)OPT_ABORT_SLAVE_EVENT_COUNT: #ifndef DBUG_OFF abort_slave_event_count = atoi(optarg); #endif break; case (int)OPT_SPORADIC_BINLOG_DUMP_FAIL: #ifndef DBUG_OFF opt_sporadic_binlog_dump_fail = 1; #endif break; case (int)OPT_MAX_BINLOG_DUMP_EVENTS: #ifndef DBUG_OFF max_binlog_dump_events = atoi(optarg); #endif break; case (int) OPT_LOG_SLAVE_UPDATES: opt_log_slave_updates = 1; break; case (int)OPT_REPLICATE_IGNORE_DB: { i_string *db = new i_string(optarg); replicate_ignore_db.push_back(db); break; } case (int)OPT_REPLICATE_DO_DB: { i_string *db = new i_string(optarg); replicate_do_db.push_back(db); break; } case (int)OPT_REPLICATE_REWRITE_DB: { char* key = optarg,*p, *val; p = strstr(optarg, "->"); if (!p) { fprintf(stderr, "Bad syntax in replicate-rewrite-db - missing '->'!\n"); exit(1); } val = p--; while(isspace(*p) && p > optarg) *p-- = 0; if(p == optarg) { fprintf(stderr, "Bad syntax in replicate-rewrite-db - empty FROM db!\n"); exit(1); } *val = 0; val += 2; while(*val && isspace(*val)) *val++; if (!*val) { fprintf(stderr, "Bad syntax in replicate-rewrite-db - empty TO db!\n"); exit(1); } i_string_pair* db_pair = new i_string_pair(key, val); replicate_rewrite_db.push_back(db_pair); break; } case (int)OPT_BINLOG_IGNORE_DB: { i_string *db = new i_string(optarg); binlog_ignore_db.push_back(db); break; } case (int)OPT_BINLOG_DO_DB: { i_string *db = new i_string(optarg); binlog_do_db.push_back(db); break; } case (int)OPT_REPLICATE_DO_TABLE: { if (!do_table_inited) init_table_rule_hash(&replicate_do_table, &do_table_inited); if(add_table_rule(&replicate_do_table, optarg)) { fprintf(stderr, "Could not add do table rule '%s'!\n", optarg); exit(1); } table_rules_on = 1; break; } case (int)OPT_REPLICATE_WILD_DO_TABLE: { if (!wild_do_table_inited) init_table_rule_array(&replicate_wild_do_table, &wild_do_table_inited); if(add_wild_table_rule(&replicate_wild_do_table, optarg)) { fprintf(stderr, "Could not add do table rule '%s'!\n", optarg); exit(1); } table_rules_on = 1; break; } case (int)OPT_REPLICATE_WILD_IGNORE_TABLE: { if (!wild_ignore_table_inited) init_table_rule_array(&replicate_wild_ignore_table, &wild_ignore_table_inited); if(add_wild_table_rule(&replicate_wild_ignore_table, optarg)) { fprintf(stderr, "Could not add ignore table rule '%s'!\n", optarg); exit(1); } table_rules_on = 1; break; } case (int)OPT_REPLICATE_IGNORE_TABLE: { if (!ignore_table_inited) init_table_rule_hash(&replicate_ignore_table, &ignore_table_inited); if(add_table_rule(&replicate_ignore_table, optarg)) { fprintf(stderr, "Could not add ignore table rule '%s'!\n", optarg); exit(1); } table_rules_on = 1; break; } case (int) OPT_SQL_BIN_UPDATE_SAME: opt_sql_bin_update = 1; break; case (int) OPT_SLOW_QUERY_LOG: opt_slow_log=1; opt_slow_logname=optarg; break; case (int)OPT_SKIP_SLAVE_START: opt_skip_slave_start = 1; break; case (int) OPT_SKIP_NEW: opt_specialflag|= SPECIAL_NO_NEW_FUNC; default_table_type=DB_TYPE_ISAM; myisam_delay_key_write=0; myisam_concurrent_insert=0; myisam_recover_options= HA_RECOVER_NONE; my_disable_symlinks=1; ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED; break; case (int) OPT_SAFE: opt_specialflag|= SPECIAL_SAFE_MODE; myisam_delay_key_write=0; myisam_recover_options= HA_RECOVER_NONE; // To be changed ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED; break; case (int) OPT_SKIP_CONCURRENT_INSERT: myisam_concurrent_insert=0; break; case (int) OPT_SKIP_PRIOR: opt_specialflag|= SPECIAL_NO_PRIOR; break; case (int) OPT_SKIP_GRANT: opt_noacl=1; break; case (int) OPT_SKIP_LOCK: my_disable_locking=1; break; case (int) OPT_SKIP_HOST_CACHE: opt_specialflag|= SPECIAL_NO_HOST_CACHE; break; case (int) OPT_ENABLE_LOCK: my_disable_locking=0; break; case (int) OPT_USE_LOCKING: my_disable_locking=0; break; case (int) OPT_SKIP_RESOLVE: opt_specialflag|=SPECIAL_NO_RESOLVE; break; case (int) OPT_LONG_FORMAT: opt_specialflag|=SPECIAL_LONG_LOG_FORMAT; break; case (int) OPT_SKIP_NETWORKING: opt_disable_networking=1; mysql_port=0; break; case (int) OPT_SKIP_SHOW_DB: opt_skip_show_db=1; opt_specialflag|=SPECIAL_SKIP_SHOW_DB; mysql_port=0; break; case (int) OPT_MEMLOCK: locked_in_memory=1; break; case (int) OPT_ONE_THREAD: test_flags |= TEST_NO_THREADS; break; case (int) OPT_WANT_CORE: test_flags |= TEST_CORE_ON_SIGNAL; break; case (int) OPT_SKIP_STACK_TRACE: test_flags|=TEST_NO_STACKTRACE; break; case (int) OPT_SKIP_SYMLINKS: my_disable_symlinks=1; break; case (int) OPT_BIND_ADDRESS: if (optarg && isdigit(optarg[0])) { my_bind_addr = (ulong) inet_addr(optarg); } else { struct hostent *ent; if (!optarg || !optarg[0]) ent=gethostbyname(optarg); else { char myhostname[255]; if (gethostname(myhostname,sizeof(myhostname)) < 0) { sql_perror("Can't start server: cannot get my own hostname!"); exit(1); } ent=gethostbyname(myhostname); } if (!ent) { sql_perror("Can't start server: cannot resolve hostname!"); exit(1); } my_bind_addr = (ulong) ((in_addr*)ent->h_addr_list[0])->s_addr; } break; case (int) OPT_PID_FILE: strmov(pidfile_name,optarg); break; case (int) OPT_INIT_FILE: opt_init_file=optarg; break; #ifdef __WIN__ case (int) OPT_STANDALONE: /* Dummy option for NT */ break; case (int) OPT_CONSOLE: opt_console=1; break; #endif case (int) OPT_FLUSH: nisam_flush=myisam_flush=1; flush_time=0; // No auto flush break; case OPT_LOW_PRIORITY_UPDATES: thd_startup_options|=OPTION_LOW_PRIORITY_UPDATES; thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY; low_priority_updates=1; break; case OPT_BOOTSTRAP: opt_noacl=opt_bootstrap=1; break; case OPT_TABLE_TYPE: { int type; if ((type=find_type(optarg, &ha_table_typelib, 2)) <= 0) { fprintf(stderr,"Unknown table type: %s\n",optarg); exit(1); } default_table_type= (enum db_type) type; break; } case OPT_SERVER_ID: server_id = atoi(optarg); server_id_supplied = 1; break; case OPT_DELAY_KEY_WRITE: ha_open_options|=HA_OPEN_DELAY_KEY_WRITE; myisam_delay_key_write=1; break; case OPT_SKIP_DELAY_KEY_WRITE: myisam_delay_key_write=0; break; case 'C': strmov(default_charset,optarg); break; case OPT_CHARSETS_DIR: strmov(mysql_charsets_dir, optarg); charsets_dir = mysql_charsets_dir; break; #include "sslopt-case.h" case OPT_TX_ISOLATION: { int type; if ((type=find_type(optarg, &tx_isolation_typelib, 2)) <= 0) { fprintf(stderr,"Unknown transaction isolation type: %s\n",optarg); exit(1); } default_tx_isolation= (enum_tx_isolation) (type-1); break; } #ifdef HAVE_BERKELEY_DB case OPT_BDB_LOG: berkeley_logdir=optarg; break; case OPT_BDB_HOME: berkeley_home=optarg; break; case OPT_BDB_NOSYNC: berkeley_env_flags|=DB_TXN_NOSYNC; break; case OPT_BDB_NO_RECOVER: berkeley_init_flags&= ~(DB_RECOVER); break; case OPT_BDB_TMP: berkeley_tmpdir=optarg; break; case OPT_BDB_LOCK: { int type; if ((type=find_type(optarg, &berkeley_lock_typelib, 2)) > 0) berkeley_lock_type=berkeley_lock_types[type-1]; else { if (test_if_int(optarg,(uint) strlen(optarg))) berkeley_lock_scan_time=atoi(optarg); else { fprintf(stderr,"Unknown lock type: %s\n",optarg); exit(1); } } break; } case OPT_BDB_SHARED: berkeley_init_flags&= ~(DB_PRIVATE); berkeley_shared_data=1; break; #endif /* HAVE_BERKELEY_DB */ case OPT_BDB_SKIP: #ifdef HAVE_BERKELEY_DB berkeley_skip=1; have_berkeley_db=SHOW_OPTION_DISABLED; #endif break; case OPT_GEMINI_SKIP: #ifdef HAVE_GEMINI_DB gemini_skip=1; have_gemini=SHOW_OPTION_DISABLED; break; case OPT_GEMINI_RECOVER: gemini_recovery_options_str=optarg; if ((gemini_recovery_options= find_bit_type(optarg, &gemini_recovery_typelib)) == ~(ulong) 0) { fprintf(stderr, "Unknown option to gemini-recovery: %s\n",optarg); exit(1); } break; case OPT_GEMINI_FLUSH_LOG: gemini_options |= GEMOPT_FLUSH_LOG; break; case OPT_GEMINI_UNBUFFERED_IO: gemini_options |= GEMOPT_UNBUFFERED_IO; #endif break; case OPT_INNODB_SKIP: #ifdef HAVE_INNOBASE_DB innodb_skip=1; have_innodb=SHOW_OPTION_DISABLED; #endif break; case OPT_INNODB_DATA_FILE_PATH: #ifdef HAVE_INNOBASE_DB innobase_data_file_path=optarg; #endif break; #ifdef HAVE_INNOBASE_DB case OPT_INNODB_DATA_HOME_DIR: innobase_data_home_dir=optarg; break; case OPT_INNODB_LOG_GROUP_HOME_DIR: innobase_log_group_home_dir=optarg; break; case OPT_INNODB_LOG_ARCH_DIR: innobase_log_arch_dir=optarg; break; case OPT_INNODB_LOG_ARCHIVE: innobase_log_archive= optarg ? test(atoi(optarg)) : 1; break; case OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT: innobase_flush_log_at_trx_commit= optarg ? test(atoi(optarg)) : 1; break; case OPT_INNODB_FAST_SHUTDOWN: innobase_fast_shutdown= optarg ? test(atoi(optarg)) : 1; break; case OPT_INNODB_UNIX_FILE_FLUSH_METHOD: innobase_unix_file_flush_method=optarg; break; #endif /* HAVE_INNOBASE_DB */ case OPT_MYISAM_RECOVER: { if (!optarg) { myisam_recover_options= HA_RECOVER_DEFAULT; myisam_recover_options_str= myisam_recover_typelib.type_names[0]; } else { myisam_recover_options_str=optarg; if ((myisam_recover_options= find_bit_type(optarg, &myisam_recover_typelib)) == ~(ulong) 0) { fprintf(stderr, "Unknown option to myisam-recover: %s\n",optarg); exit(1); } } ha_open_options|=HA_OPEN_ABORT_IF_CRASHED; break; } case OPT_SQL_MODE: { sql_mode_str = optarg; if ((opt_sql_mode = find_bit_type(optarg, &sql_mode_typelib)) == ~(ulong) 0) { fprintf(stderr, "Unknown option to sql-mode: %s\n", optarg); exit(1); } default_tx_isolation= ((opt_sql_mode & MODE_SERIALIZABLE) ? ISO_SERIALIZABLE : ISO_READ_COMMITTED); break; } case OPT_MASTER_HOST: master_host=optarg; break; case OPT_MASTER_USER: master_user=optarg; break; case OPT_MASTER_PASSWORD: master_password=optarg; break; case OPT_MASTER_INFO_FILE: master_info_file=optarg; break; case OPT_MASTER_PORT: master_port= atoi(optarg); break; case OPT_MASTER_CONNECT_RETRY: master_connect_retry= atoi(optarg); break; case OPT_MASTER_RETRY_COUNT: master_retry_count= atoi(optarg); break; case OPT_SAFE_SHOW_DB: opt_safe_show_db=1; break; case OPT_SAFE_USER_CREATE: opt_safe_user_create=1; break; case OPT_SKIP_SAFEMALLOC: #ifdef SAFEMALLOC sf_malloc_quick=1; #endif break; default: fprintf(stderr,"%s: Unrecognized option: %c\n",my_progname,c); use_help(); exit(1); } } // Skipp empty arguments (from shell) while (argc != optind && !argv[optind][0]) optind++; if (argc != optind) { fprintf(stderr,"%s: Too many parameters\n",my_progname); use_help(); exit(1); } fix_paths(); default_table_type_name=ha_table_typelib.type_names[default_table_type-1]; default_tx_isolation_name=tx_isolation_typelib.type_names[default_tx_isolation]; /* To be deleted in MySQL 4.0 */ if (!record_rnd_cache_size) record_rnd_cache_size=my_default_record_cache_size; } static char *get_relative_path(const char *path) { if (test_if_hard_path(path) && is_prefix(path,DEFAULT_MYSQL_HOME) && strcmp(DEFAULT_MYSQL_HOME,FN_ROOTDIR)) { path+=(uint) strlen(DEFAULT_MYSQL_HOME); while (*path == FN_LIBCHAR) path++; } return (char*) path; } static void fix_paths(void) { (void) fn_format(mysql_home,mysql_home,"","",16); // Remove symlinks convert_dirname(mysql_home); convert_dirname(mysql_real_data_home); convert_dirname(language); (void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir (void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home); (void) my_load_path(pidfile_name,pidfile_name,mysql_real_data_home); char buff[FN_REFLEN],*sharedir=get_relative_path(SHAREDIR); if (test_if_hard_path(sharedir)) strmov(buff,sharedir); /* purecov: tested */ else strxmov(buff,mysql_home,sharedir,NullS); convert_dirname(buff); (void) my_load_path(language,language,buff); /* If --character-sets-dir isn't given, use shared library dir */ if (charsets_dir != mysql_charsets_dir) { strmov(strmov(mysql_charsets_dir,buff),CHARSET_DIR); charsets_dir=mysql_charsets_dir; } /* Add '/' to TMPDIR if needed */ char *tmp= (char*) my_malloc(FN_REFLEN,MYF(MY_FAE)); if (tmp) { strmov(tmp,mysql_tmpdir); mysql_tmpdir=tmp; convert_dirname(mysql_tmpdir); mysql_tmpdir=(char*) my_realloc(mysql_tmpdir,(uint) strlen(mysql_tmpdir)+1, MYF(MY_HOLD_ON_ERROR)); } } #ifdef SET_RLIMIT_NOFILE static uint set_maximum_open_files(uint max_file_limit) { struct rlimit rlimit; ulong old_cur; if (!getrlimit(RLIMIT_NOFILE,&rlimit)) { old_cur=rlimit.rlim_cur; if (rlimit.rlim_cur >= max_file_limit) // Nothing to do return rlimit.rlim_cur; /* purecov: inspected */ rlimit.rlim_cur=rlimit.rlim_max=max_file_limit; if (setrlimit(RLIMIT_NOFILE,&rlimit)) { sql_print_error("Warning: setrlimit couldn't increase number of open files to more than %ld", old_cur); /* purecov: inspected */ max_file_limit=old_cur; } else { (void) getrlimit(RLIMIT_NOFILE,&rlimit); if ((uint) rlimit.rlim_cur != max_file_limit) sql_print_error("Warning: setrlimit returned ok, but didn't change limits. Max open files is %ld", (ulong) rlimit.rlim_cur); /* purecov: inspected */ max_file_limit=rlimit.rlim_cur; } } return max_file_limit; } #endif #ifdef OS2 static uint set_maximum_open_files(uint max_file_limit) { LONG cbReqCount; ULONG cbCurMaxFH, cbCurMaxFH0; APIRET ulrc; // get current limit cbReqCount = 0; DosSetRelMaxFH( &cbReqCount, &cbCurMaxFH0); // set new limit cbReqCount = max_file_limit - cbCurMaxFH0; ulrc = DosSetRelMaxFH( &cbReqCount, &cbCurMaxFH); if (ulrc) { sql_print_error("Warning: DosSetRelMaxFH couldn't increase number of open files to more than %d", cbCurMaxFH0); cbCurMaxFH = cbCurMaxFH0; } return cbCurMaxFH; } #endif /* Return a bitfield from a string of substrings separated by ',' returns ~(ulong) 0 on error. */ static ulong find_bit_type(const char *x, TYPELIB *bit_lib) { bool found_end; int found_count; const char *end,*i,*j; const char **array, *pos; ulong found,found_int,bit; DBUG_ENTER("find_bit_type"); DBUG_PRINT("enter",("x: '%s'",x)); found=0; pos=(my_string) x; while (*pos == ' ') pos++; found_end= *pos == 0; while (!found_end) { if (!*(end=strcend(pos,','))) /* Let end point at fieldend */ { while (end > pos && end[-1] == ' ') end--; /* Skipp end-space */ found_end=1; } found_int=0; found_count=0; for (array=bit_lib->type_names, bit=1 ; (i= *array++) ; bit<<=1) { j=pos; while (j != end) { if (toupper(*i++) != toupper(*j++)) goto skipp; } found_int=bit; if (! *i) { found_count=1; break; } else if (j != pos) // Half field found { found_count++; // Could be one of two values } skipp: ; } if (found_count != 1) DBUG_RETURN(~(ulong) 0); // No unique value found|=found_int; pos=end+1; } DBUG_PRINT("exit",("bit-field: %ld",(ulong) found)); DBUG_RETURN(found); } /* find_bit_type */ /***************************************************************************** ** Instantiate templates *****************************************************************************/ #ifdef __GNUC__ /* Used templates */ template class I_List<THD>; template class I_List_iterator<THD>; template class I_List<i_string>; template class I_List<i_string_pair>; #endif