mariadb/sql/mysqld.cc
unknown 49162e0e54 Added back -max to server name if we are using InnoDB.
libmysql/libmysql.c:
  Compatibility fix
sql/mysqld.cc:
  Added back -max if we are using InnoDB.
  (This should not be done in the 3.23 version)
2002-12-11 12:59:55 +02:00

4360 lines
141 KiB
C++

/* 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();
#else
#define 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;
#ifdef __STDC__
#define my_fromhost(A) fromhost(A)
#define my_hosts_access(A) hosts_access(A)
#define my_eval_client(A) eval_client(A)
#else
#define my_fromhost(A) fromhost()
#define my_hosts_access(A) hosts_access()
#define my_eval_client(A) eval_client()
#endif
#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 */
#if defined(__i386__)
fpsetmask(~(FP_X_INV | FP_X_DNML | FP_X_OFL | FP_X_UFL | FP_X_DZ |
FP_X_IMP));
#else
fpsetmask(~(FP_X_INV | FP_X_OFL | FP_X_UFL | FP_X_DZ |
FP_X_IMP));
#endif
}
#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;
static bool opt_enable_named_pipe = 0;
#endif
#ifdef __WIN__
static bool opt_console=0,start_mode=0, use_opt_args;
static int opt_argc;
static char **opt_argv;
#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 /* __WIN__ */
#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;
struct rand_struct sql_rand; // used by sql_class.cc:THD::THD()
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=1;
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;
static char shutdown_event_name[40];
#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
close_server_sock();
}
(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 && opt_enable_named_pipe)
{
HANDLE temp;
DBUG_PRINT( "quit", ("Closing named pipes") );
/* Create connection to the handle named pipe handler to break the loop */
if ((temp = CreateFile(szPipeName,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL )) != INVALID_HANDLE_VALUE)
{
WaitNamedPipe(szPipeName, 1000);
DWORD dwMode = PIPE_READMODE_BYTE | PIPE_WAIT;
SetNamedPipeHandleState(temp, &dwMode, NULL, NULL);
CancelIo(temp);
DisconnectNamedPipe(temp);
CloseHandle(temp);
}
}
#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",("calling shutdown on TCP/IP socket"));
VOID(shutdown(ip_sock,2));
#ifdef NOT_USED
/*
The following code is disabled as it cases MySQL to hang on
AIX 4.3 during shutdown
*/
DBUG_PRINT("info",("calling closesocket on TCP/IP socket"));
VOID(closesocket(ip_sock));
#endif
ip_sock=INVALID_SOCKET;
}
if (unix_sock != INVALID_SOCKET)
{
DBUG_PRINT("info",("calling shutdown on unix socket"));
VOID(shutdown(unix_sock,2));
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
abort_loop=1; // Break connection loops
close_server_sock(); // Force accept to wake up
#endif
#if defined(__WIN__)
{
if (!SetEvent(hEventShutdown))
{
DBUG_PRINT("error",("Got error: %ld from SetEvent",GetLastError()));
}
}
#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 (!kill_in_progress)
{
pthread_t tmp;
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();
#ifdef SIGNALS_DONT_BREAK_READ
exit(0);
#else
pthread_exit(0); // Exit is in main thread
#endif
}
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);
}
my_setwd("/", MYF(0));
#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));
if (bind(ip_sock, my_reinterpret_cast(struct sockaddr *) (&IPaddr),
sizeof(IPaddr)) < 0)
{
DBUG_PRINT("error",("Got error: %d from bind",socket_errno));
sql_perror("Can't start server: Bind on TCP/IP port");
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_perror("Can't start server: listen() on TCP/IP port");
sql_print_error("Warning: listen() on TCP/IP failed with error %d",
socket_errno);
unireg_abort(1);
}
}
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 &&
opt_enable_named_pipe)
{
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 ||
(!opt_disable_networking && 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 (!kill_in_progress)
{
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 against 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)
{
fprintf(stderr, "Writing a core file\n");
fflush(stderr);
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");
strmake(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
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(MYSQL_CONFIG_NAME,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);
#ifdef __WIN__
#define MYSQL_ERR_FILE "mysql.err"
if (!opt_console)
{
freopen(MYSQL_ERR_FILE,"a+",stdout);
freopen(MYSQL_ERR_FILE,"a+",stderr);
}
#endif
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__
if (!opt_console)
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, shutdown_event_name);
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 || opt_disable_networking))
{
sql_print_error("TCP/IP or --enable-named-pipe should be configured on NT OS");
unireg_abort(1);
}
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 && opt_enable_named_pipe)
{
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
#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);
#ifdef __WIN__
if (Service.IsNT())
{
if(start_mode)
Service.Stop();
else
{
Service.SetShutdownEvent(0);
if(hEventShutdown) CloseHandle(hEventShutdown);
}
}
else
{
Service.SetShutdownEvent(0);
if(hEventShutdown) CloseHandle(hEventShutdown);
}
#endif
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
exit(0);
return(0); /* purecov: deadcode */
}
#if defined(__WIN__)
int mysql_service(void *p)
{
if (use_opt_args)
win_main(opt_argc, opt_argv);
else
win_main(Service.my_argc, Service.my_argv);
return 0;
}
/*
Handle basic handling of services, like installation and removal
SYNOPSIS
default_service_handling()
argv Pointer to argument list
servicename Internal name of service
displayname Display name of service (in taskbar ?)
file_path Path to this program
RETURN VALUES
0 option handled
1 Could not handle option
*/
bool default_service_handling(char **argv,
const char *servicename,
const char *displayname,
const char *file_path)
{
if (Service.got_service_option(argv, "install"))
{
Service.Install(1, servicename, displayname, file_path);
return 0;
}
if (Service.got_service_option(argv, "install-manual"))
{
Service.Install(0, servicename, displayname, file_path);
return 0;
}
if (Service.got_service_option(argv, "remove"))
{
Service.Remove(servicename);
return 0;
}
return 1;
}
int main(int argc, char **argv)
{
/* When several instances are running on the same machine, we
need to have an unique named hEventShudown through the
application PID e.g.: MySQLShutdown1890; MySQLShutdown2342
*/
int2str((int) GetCurrentProcessId(),strmov(shutdown_event_name,
"MySQLShutdown"), 10);
if (Service.GetOS()) /* true NT family */
{
char file_path[FN_REFLEN];
my_path(file_path, argv[0], ""); /* Find name in path */
fn_format(file_path,argv[0],file_path,"",1+4+16); /* Force full path */
if (argc == 2)
{
if (!default_service_handling(argv,MYSQL_SERVICENAME, MYSQL_SERVICENAME,
file_path))
return 0;
if (Service.IsService(argv[1]))
{
/* start an optional service */
load_default_groups[0]= argv[1];
start_mode= 1;
Service.Init(argv[1], mysql_service);
return 0;
}
}
else if (argc == 3) /* install or remove any optional service */
{
/* Add service name after filename */
uint length=strlen(file_path);
*strxnmov(file_path + length, sizeof(file_path)-length-2, " ",
argv[2], NullS)= '\0';
if (!default_service_handling(argv, argv[2], argv[2], file_path))
return 0;
if (Service.IsService(argv[2]))
{
/* start an optional service */
use_opt_args=1;
opt_argc=argc;
opt_argv=argv;
start_mode= 1;
Service.Init(argv[2], mysql_service);
return 0;
}
}
else if (argc == 4)
{
/*
Install an optional service with optional config file
mysqld --install-manual mysqldopt --defaults-file=c:\miguel\my.ini
*/
uint length=strlen(file_path);
*strxnmov(file_path + length, sizeof(file_path)-length-2, " ",
argv[3], " ", argv[2], NullS)= '\0';
if (!default_service_handling(argv, argv[2], argv[2], file_path))
return 0;
}
else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME))
{
/* start the default service */
start_mode= 1;
Service.Init(MYSQL_SERVICENAME, mysql_service);
return 0;
}
}
/* Start as standalone server */
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->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);
}
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);
my_fromhost(&req);
if (!my_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",
my_eval_client(&req));
/*
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...
*/
if (req.sink)
((void (*)(int))req.sink)(req.fd);
(void) shutdown(new_sock,2);
(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_HAVE_NAMED_PIPE,
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},
{"enable-named-pipe", no_argument, 0, (int) OPT_HAVE_NAMED_PIPE},
{"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_LONG},
{"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_AS_LONGLONG},
{"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},
#ifdef __NT__
{"named_pipe", (char*) &opt_enable_named_pipe, SHOW_BOOL},
#endif
{"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_status", (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_status", (char*) (com_stat+(uint) SQLCOM_SHOW_SLAVE_STAT),SHOW_LONG},
{"Com_show_status", (char*) (com_stat+(uint) SQLCOM_SHOW_STATUS),SHOW_LONG},
{"Com_show_innodb_status", (char*) (com_stat+(uint) SQLCOM_SHOW_INNODB_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_CONST},
{"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\
--local-infile=[1|0] Enable/disable LOAD DATA LOCAL INFILE\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 the default service (NT)\n\
--install-manual Install the default service started manually (NT)\n\
--remove Remove the default service from the service list (NT)\n\
--enable-named-pipe Enable the named pipe (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\
Value 0: write and flush once per second\n\
Value 1: write and flush at each commit\n\
Value 2: write at commit, flush once per second\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(MYSQL_CONFIG_NAME,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) strmake(default_charset, MYSQL_CHARSET, sizeof(default_charset)-1);
(void) strmake(language, LANGUAGE, sizeof(language)-1);
(void) strmake(mysql_real_data_home, get_relative_path(DATADIR),
sizeof(mysql_real_data_home)-1);
#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) strmake(mysql_home, tmpenv, sizeof(mysql_home)-1);
#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':
strmake(mysql_home,optarg,sizeof(mysql_home)-1);
break;
case 'l':
opt_log=1;
opt_logname=optarg; // Use hostname.log if null
break;
case 'h':
strmake(mysql_real_data_home,optarg, sizeof(mysql_real_data_home)-1);
break;
case 'L':
strmake(language, optarg, sizeof(language)-1);
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;
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:
strmake(pidfile_name, optarg, sizeof(pidfile_name)-1);
break;
case (int) OPT_INIT_FILE:
opt_init_file=optarg;
break;
case (int) OPT_HAVE_NAMED_PIPE:
#if __NT__
opt_enable_named_pipe=1;
#endif
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':
strmake(default_charset, optarg, sizeof(default_charset)-1);
break;
case OPT_CHARSETS_DIR:
strmake(mysql_charsets_dir, optarg, sizeof(mysql_charsets_dir)-1);
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 ? 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))
strmake(buff,sharedir,sizeof(buff)-1); /* purecov: tested */
else
strxnmov(buff,sizeof(buff)-1,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)
{
strxnmov(mysql_charsets_dir, sizeof(mysql_charsets_dir)-1, buff,
CHARSET_DIR, NullS);
charsets_dir=mysql_charsets_dir;
}
/* Add '/' to TMPDIR if needed */
char *tmp= (char*) my_malloc(FN_REFLEN,MYF(MY_FAE));
if (tmp)
{
strmake(tmp, mysql_tmpdir, FN_REFLEN-1);
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>;
FIX_GCC_LINKING_PROBLEM
#endif