diff options
Diffstat (limited to 'sql/mysqld.cc')
-rw-r--r-- | sql/mysqld.cc | 1132 |
1 files changed, 755 insertions, 377 deletions
diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 08407d52e09..8bec9dc474a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1,4 +1,5 @@ -/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +/* Copyright (C) 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. + 2009-2010 Monty Program 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 @@ -13,6 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#define DEFINE_VARIABLES_LOG_SLOW // Declare variables in log_slow.h #include "mysql_priv.h" #include <m_ctype.h> #include <my_dir.h> @@ -26,6 +28,7 @@ #include "mysqld_suffix.h" #include "mysys_err.h" #include "events.h" +#include <waiting_threads.h> #include "debug_sync.h" #include "../storage/myisam/ha_myisam.h" @@ -57,12 +60,6 @@ #define mysqld_charset &my_charset_latin1 -#ifdef HAVE_purify -#define IF_PURIFY(A,B) (A) -#else -#define IF_PURIFY(A,B) (B) -#endif - #if SIZEOF_CHARP == 4 #define MAX_MEM_TABLE_SIZE ~(ulong) 0 #else @@ -76,9 +73,9 @@ char pstack_file_name[80]; #endif /* __linux__ */ -/* We have HAVE_purify below as this speeds up the shutdown of MySQL */ +/* We have HAVE_valgrind below as this speeds up the shutdown of MySQL */ -#if defined(HAVE_DEC_3_2_THREADS) || defined(SIGNALS_DONT_BREAK_READ) || defined(HAVE_purify) && defined(__linux__) +#if defined(HAVE_DEC_3_2_THREADS) || defined(SIGNALS_DONT_BREAK_READ) || defined(HAVE_valgrind) && defined(__linux__) #define HAVE_CLOSE_SERVER_SOCK 1 #endif @@ -167,7 +164,7 @@ static void registerwithneb(); static void getvolumename(); static void getvolumeID(BYTE *volumeName); #endif /* __NETWARE__ */ - + #ifdef _AIX41 int initgroups(const char *,unsigned int); @@ -337,9 +334,14 @@ TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"", static const char *optimizer_switch_names[]= { - "index_merge","index_merge_union","index_merge_sort_union", - "index_merge_intersection", "default", NullS + "index_merge","index_merge_union","index_merge_sort_union", + "index_merge_intersection", +#ifndef DBUG_OFF + "table_elimination", +#endif + "default", NullS }; + /* Corresponding defines are named OPTIMIZER_SWITCH_XXX */ static const unsigned int optimizer_switch_names_len[]= { @@ -347,6 +349,9 @@ static const unsigned int optimizer_switch_names_len[]= sizeof("index_merge_union") - 1, sizeof("index_merge_sort_union") - 1, sizeof("index_merge_intersection") - 1, +#ifndef DBUG_OFF + sizeof("table_elimination") - 1, +#endif sizeof("default") - 1 }; TYPELIB optimizer_switch_typelib= { array_elements(optimizer_switch_names)-1,"", @@ -401,7 +406,7 @@ arg_cmp_func Arg_comparator::comparator_matrix[5][2] = const char *log_output_names[] = { "NONE", "FILE", "TABLE", NullS}; static const unsigned int log_output_names_len[]= { 4, 4, 5, 0 }; TYPELIB log_output_typelib= {array_elements(log_output_names)-1,"", - log_output_names, + log_output_names, (unsigned int *) log_output_names_len}; /* static variables */ @@ -412,8 +417,10 @@ static bool volatile select_thread_in_use, signal_thread_in_use; static bool volatile ready_to_exit; static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0; static my_bool opt_short_log_format= 0; +static my_bool opt_ignore_wrong_options= 0, opt_expect_abort= 0; +static my_bool opt_sync= 0; static uint kill_cached_threads, wake_thread; -static ulong killed_threads, thread_created; +ulong thread_created; static ulong max_used_connections; static ulong my_bind_addr; /**< the address we bind to */ static volatile ulong cached_thread_count= 0; @@ -421,18 +428,24 @@ static const char *sql_mode_str= "OFF"; /* Text representation for OPTIMIZER_SWITCH_DEFAULT */ static const char *optimizer_switch_str="index_merge=on,index_merge_union=on," "index_merge_sort_union=on," - "index_merge_intersection=on"; + "index_merge_intersection=on" +#ifndef DBUG_OFF + ",table_elimination=on"; +#else + ; +#endif static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr; static char *opt_init_slave, *language_ptr, *opt_init_connect; static char *default_character_set_name; static char *character_set_filesystem_name; static char *lc_time_names_name; static char *my_bind_addr_str; -static char *default_collation_name; +static char *default_collation_name; static char *default_storage_engine_str; static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME; static I_List<THD> thread_cache; static double long_query_time; +static ulong opt_my_crc_dbug_check; static pthread_cond_t COND_thread_cache, COND_flush_thread_cache; @@ -471,7 +484,7 @@ bool in_bootstrap= FALSE; @brief 'grant_option' is used to indicate if privileges needs to be checked, in which case the lock, LOCK_grant, is used to protect access to the grant table. - @note This flag is dropped in 5.1 + @note This flag is dropped in 5.1 @see grant_init() */ bool volatile grant_option; @@ -483,7 +496,7 @@ my_bool opt_local_infile, opt_slave_compressed_protocol; my_bool opt_safe_user_create = 0, opt_no_mix_types = 0; my_bool opt_show_slave_auth_info, opt_sql_bin_update = 0; my_bool opt_log_slave_updates= 0; -bool slave_warning_issued = false; +bool slave_warning_issued = false; /* Legacy global handlerton. These will be removed (please do not add more). @@ -546,6 +559,7 @@ const char *opt_binlog_format= binlog_format_names[opt_binlog_format_id]; static bool calling_initgroups= FALSE; /**< Used in SIGSEGV handler. */ #endif uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options; +uint mysqld_extra_port; uint mysqld_port_timeout; uint delay_key_write_options, protocol_version; uint lower_case_table_names; @@ -573,6 +587,7 @@ ulong delayed_insert_errors,flush_time; ulong specialflag=0; ulong binlog_cache_use= 0, binlog_cache_disk_use= 0; ulong max_connections, max_connect_errors; +ulong extra_max_connections; uint max_user_connections= 0; /** Limit of the total number of prepared statements in the server. @@ -620,6 +635,7 @@ char *mysqld_unix_port, *opt_mysql_tmpdir; const char **errmesg; /**< Error messages */ const char *myisam_recover_options_str="OFF"; const char *myisam_stats_method_str="nulls_unequal"; +const char *opt_thread_handling= thread_handling_typelib.type_names[0]; /** name of reference on left espression in rewritten IN subquery */ const char *in_left_expr_name= "<left expr>"; @@ -669,12 +685,12 @@ pthread_key(MEM_ROOT**,THR_MALLOC); pthread_key(THD*, THR_THD); pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count, LOCK_mapped_file, LOCK_status, LOCK_global_read_lock, - LOCK_error_log, LOCK_uuid_generator, + LOCK_error_log, LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received, LOCK_global_system_variables, - LOCK_user_conn, LOCK_slave_list, LOCK_active_mi, - LOCK_connection_count; + LOCK_user_conn, LOCK_slave_list, LOCK_active_mi, + LOCK_connection_count, LOCK_uuid_generator; /** The below lock protects access to two global server variables: max_prepared_stmt_count and prepared_stmt_count. These variables @@ -703,7 +719,8 @@ uint master_port= MYSQL_PORT, master_connect_retry = 60; uint report_port= MYSQL_PORT; ulong master_retry_count=0; char *master_user, *master_password, *master_host, *master_info_file; -char *relay_log_info_file, *report_user, *report_password, *report_host; +char *relay_log_info_file; +char *report_user, *report_password, *report_host; char *opt_relay_logname = 0, *opt_relaylog_index_name=0; my_bool master_ssl; char *master_ssl_key, *master_ssl_cert; @@ -729,13 +746,12 @@ static char *opt_bin_logname; int orig_argc; char **orig_argv; -static my_socket unix_sock,ip_sock; -struct rand_struct sql_rand; ///< used by sql_class.cc:THD::THD() +static my_socket unix_sock, base_ip_sock, extra_ip_sock; +struct my_rnd_struct sql_rand; ///< used by sql_class.cc:THD::THD() #ifndef EMBEDDED_LIBRARY struct passwd *user_info; static pthread_t select_thread; -static uint thr_kill_signal; #endif /* OS specific variables */ @@ -792,7 +808,7 @@ my_bool opt_enable_shared_memory; HANDLE smem_event_connect_request= 0; #endif -scheduler_functions thread_scheduler; +scheduler_functions thread_scheduler, extra_thread_scheduler; #define SSL_VARS_NOT_STATIC #include "sslopt-vars.h" @@ -819,7 +835,7 @@ struct st_VioSSLFd *ssl_acceptor_fd; Number of currently active user connections. The variable is protected by LOCK_connection_count. */ -uint connection_count= 0; +uint connection_count= 0, extra_connection_count= 0; /* Function declarations */ @@ -847,6 +863,7 @@ static ulong find_bit_type_or_exit(const char *x, TYPELIB *bit_lib, const char *option, int *error); static void clean_up(bool print_message); static int test_if_case_insensitive(const char *dir_name); +static void register_mutex_order(); #ifndef EMBEDDED_LIBRARY static void usage(void); @@ -901,7 +918,7 @@ static void close_connections(void) break; } #ifdef EXTRA_DEBUG - if (error != 0 && !count++) + if (error != 0 && error != ETIMEDOUT && !count++) sql_print_error("Got error %d from pthread_cond_timedwait",error); #endif close_server_sock(); @@ -914,11 +931,17 @@ static void close_connections(void) DBUG_PRINT("quit",("Closing sockets")); if (!opt_disable_networking ) { - if (ip_sock != INVALID_SOCKET) + if (base_ip_sock != INVALID_SOCKET) { - (void) shutdown(ip_sock, SHUT_RDWR); - (void) closesocket(ip_sock); - ip_sock= INVALID_SOCKET; + (void) shutdown(base_ip_sock, SHUT_RDWR); + (void) closesocket(base_ip_sock); + base_ip_sock= INVALID_SOCKET; + } + if (extra_ip_sock != INVALID_SOCKET) + { + (void) shutdown(extra_ip_sock, SHUT_RDWR); + (void) closesocket(extra_ip_sock); + extra_ip_sock= INVALID_SOCKET; } } #ifdef __NT__ @@ -976,18 +999,30 @@ static void close_connections(void) tmp->killed= THD::KILL_CONNECTION; thread_scheduler.post_kill_notification(tmp); + pthread_mutex_lock(&tmp->LOCK_thd_data); 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); + uint i; + for (i=0; i < 2; i++) + { + int ret= pthread_mutex_trylock(tmp->mysys_var->current_mutex); + pthread_cond_broadcast(tmp->mysys_var->current_cond); + if (!ret) + { + /* Thread has surely got the signal, unlock and abort */ + pthread_mutex_unlock(tmp->mysys_var->current_mutex); + break; + } + sleep(1); + } } pthread_mutex_unlock(&tmp->mysys_var->mutex); } + pthread_mutex_unlock(&tmp->LOCK_thd_data); } (void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list @@ -1043,42 +1078,41 @@ static void close_connections(void) } -static void close_server_sock() -{ #ifdef HAVE_CLOSE_SERVER_SOCK - DBUG_ENTER("close_server_sock"); - my_socket tmp_sock; - tmp_sock=ip_sock; - if (tmp_sock != INVALID_SOCKET) +static void close_socket(my_socket sock, const char *info) +{ + DBUG_ENTER("close_socket"); + + if (sock != INVALID_SOCKET) { - ip_sock=INVALID_SOCKET; - DBUG_PRINT("info",("calling shutdown on TCP/IP socket")); - VOID(shutdown(tmp_sock, SHUT_RDWR)); + DBUG_PRINT("info", ("calling shutdown on %s socket", info)); + (void) shutdown(sock, SHUT_RDWR); #if defined(__NETWARE__) /* The following code is disabled for normal systems as it causes MySQL to hang on AIX 4.3 during shutdown */ - DBUG_PRINT("info",("calling closesocket on TCP/IP socket")); - VOID(closesocket(tmp_sock)); + DBUG_PRINT("info", ("calling closesocket on %s socket", info)); + (void) closesocket(tmp_sock); #endif } - tmp_sock=unix_sock; - if (tmp_sock != INVALID_SOCKET) - { - unix_sock=INVALID_SOCKET; - DBUG_PRINT("info",("calling shutdown on unix socket")); - VOID(shutdown(tmp_sock, SHUT_RDWR)); -#if defined(__NETWARE__) - /* - The following code is disabled for normal systems as it may cause MySQL - to hang on AIX 4.3 during shutdown - */ - DBUG_PRINT("info",("calling closesocket on unix/IP socket")); - VOID(closesocket(tmp_sock)); + DBUG_VOID_RETURN; +} #endif + + +static void close_server_sock() +{ +#ifdef HAVE_CLOSE_SERVER_SOCK + DBUG_ENTER("close_server_sock"); + + close_socket(base_ip_sock, "TCP/IP"); + close_socket(extra_ip_sock, "TCP/IP"); + close_socket(unix_sock, "unix/IP"); + + if (unix_sock != INVALID_SOCKET) VOID(unlink(mysqld_unix_port)); - } + base_ip_sock= extra_ip_sock= unix_sock= INVALID_SOCKET; DBUG_VOID_RETURN; #endif } @@ -1173,18 +1207,21 @@ static void __cdecl kill_server(int sig_ptr) else sql_print_error(ER(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */ -#if defined(HAVE_SMEM) && defined(__WIN__) - /* - Send event to smem_event_connect_request for aborting - */ - if (!SetEvent(smem_event_connect_request)) - { - DBUG_PRINT("error", - ("Got error: %ld from SetEvent of smem_event_connect_request", - GetLastError())); - } -#endif - +#if defined(HAVE_SMEM) && defined(__WIN__) + /* + Send event to smem_event_connect_request for aborting + */ + if (opt_enable_shared_memory) + { + if (!SetEvent(smem_event_connect_request)) + { + DBUG_PRINT("error", + ("Got error: %ld from SetEvent of smem_event_connect_request", + GetLastError())); + } + } +#endif + close_connections(); if (sig != MYSQL_KILL_SIGNAL && sig != 0) @@ -1334,8 +1371,10 @@ void clean_up(bool print_message) if (tc_log) tc_log->close(); xid_cache_free(); + wt_end(); delete_elements(&key_caches, (void (*)(const char*, uchar*)) free_key_cache); multi_keycache_free(); + sp_cache_end(); free_status_vars(); end_thr_alarm(1); /* Free allocated memory */ my_free_open_file_info(); @@ -1431,6 +1470,7 @@ static void wait_for_signal_thread_to_end() static void clean_up_mutexes() { + DBUG_ENTER("clean_up_mutexes"); (void) pthread_mutex_destroy(&LOCK_mysql_create_db); (void) pthread_mutex_destroy(&LOCK_lock_db); (void) pthread_mutex_destroy(&LOCK_Acl); @@ -1462,13 +1502,15 @@ static void clean_up_mutexes() (void) pthread_mutex_destroy(&LOCK_rpl_status); (void) pthread_cond_destroy(&COND_rpl_status); #endif + (void) pthread_mutex_destroy(&LOCK_server_started); + (void) pthread_cond_destroy(&COND_server_started); (void) pthread_mutex_destroy(&LOCK_active_mi); (void) rwlock_destroy(&LOCK_sys_init_connect); (void) rwlock_destroy(&LOCK_sys_init_slave); (void) pthread_mutex_destroy(&LOCK_global_system_variables); + (void) pthread_mutex_destroy(&LOCK_uuid_generator); (void) rwlock_destroy(&LOCK_system_variables_hash); (void) pthread_mutex_destroy(&LOCK_global_read_lock); - (void) pthread_mutex_destroy(&LOCK_uuid_generator); (void) pthread_mutex_destroy(&LOCK_prepared_stmt_count); (void) pthread_cond_destroy(&COND_thread_count); (void) pthread_cond_destroy(&COND_refresh); @@ -1476,11 +1518,35 @@ static void clean_up_mutexes() (void) pthread_cond_destroy(&COND_thread_cache); (void) pthread_cond_destroy(&COND_flush_thread_cache); (void) pthread_cond_destroy(&COND_manager); + DBUG_VOID_RETURN; } #endif /*EMBEDDED_LIBRARY*/ +/** + Register order of mutex for wrong mutex deadlock detector + + By aquiring all mutex in order here, the mutex order detector in + mysys/thr_mutex.c, will give a warning on first wrong mutex usage! +*/ + +static void register_mutex_order() +{ +#ifdef SAFE_MUTEX + /* + We must have LOCK_open before LOCK_global_system_variables because + LOCK_open is hold while sql_plugin.c::intern_sys_var_ptr() is called. + */ + pthread_mutex_lock(&LOCK_open); + pthread_mutex_lock(&LOCK_global_system_variables); + + pthread_mutex_unlock(&LOCK_global_system_variables); + pthread_mutex_unlock(&LOCK_open); +#endif +} + + /**************************************************************************** ** Init IP and UNIX socket ****************************************************************************/ @@ -1651,80 +1717,100 @@ static void set_root(const char *path) #endif } -static void network_init(void) +/** + Activate usage of a tcp port +*/ + +static my_socket activate_tcp_port(uint port) { - struct sockaddr_in IPaddr; -#ifdef HAVE_SYS_UN_H - struct sockaddr_un UNIXaddr; -#endif + struct sockaddr_in IPaddr; + my_socket ip_sock; int arg=1; int ret; uint waited; uint this_wait; uint retry; - DBUG_ENTER("network_init"); + DBUG_ENTER("activate_tcp_port"); + DBUG_PRINT("enter",("port: %u", port)); LINT_INIT(ret); + 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) port); + +#ifndef __WIN__ + /* + We should not use SO_REUSEADDR on windows as this would enable a + user to open two mysqld servers with the same TCP/IP port. + */ + (void) setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,sizeof(arg)); +#endif /* __WIN__ */ + /* + Sometimes the port is not released fast enough when stopping and + restarting the server. This happens quite often with the test suite + on busy Linux systems. Retry to bind the address at these intervals: + Sleep intervals: 1, 2, 4, 6, 9, 13, 17, 22, ... + Retry at second: 1, 3, 7, 13, 22, 35, 52, 74, ... + Limit the sequence by mysqld_port_timeout (set --port-open-timeout=#). + */ + + for (waited= 0, retry= 1; ; retry++, waited+= this_wait) + { + if (((ret= bind(ip_sock, my_reinterpret_cast(struct sockaddr *) (&IPaddr), + sizeof(IPaddr))) >= 0) || + (socket_errno != SOCKET_EADDRINUSE) || + (waited >= mysqld_port_timeout)) + break; + sql_print_information("Retrying bind on TCP/IP port %u", port); + this_wait= retry * retry / 3 + 1; + sleep(this_wait); + } + if (ret < 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: %u ?", 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("listen() on TCP/IP failed with error %d", + socket_errno); + unireg_abort(1); + } + DBUG_RETURN(ip_sock); +} + + +static void network_init(void) +{ +#ifdef HAVE_SYS_UN_H + struct sockaddr_un UNIXaddr; +#endif + int arg=1; + DBUG_ENTER("network_init"); + if (thread_scheduler.init()) unireg_abort(1); /* purecov: inspected */ set_ports(); - if (mysqld_port != 0 && !opt_disable_networking && !opt_bootstrap) + if (!opt_disable_networking && !opt_bootstrap) { - DBUG_PRINT("general",("IP Socket is %d",mysqld_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) mysqld_port); - -#ifndef __WIN__ - /* - We should not use SO_REUSEADDR on windows as this would enable a - user to open two mysqld servers with the same TCP/IP port. - */ - (void) setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,sizeof(arg)); -#endif /* __WIN__ */ - /* - Sometimes the port is not released fast enough when stopping and - restarting the server. This happens quite often with the test suite - on busy Linux systems. Retry to bind the address at these intervals: - Sleep intervals: 1, 2, 4, 6, 9, 13, 17, 22, ... - Retry at second: 1, 3, 7, 13, 22, 35, 52, 74, ... - Limit the sequence by mysqld_port_timeout (set --port-open-timeout=#). - */ - for (waited= 0, retry= 1; ; retry++, waited+= this_wait) - { - if (((ret= bind(ip_sock, my_reinterpret_cast(struct sockaddr *) (&IPaddr), - sizeof(IPaddr))) >= 0) || - (socket_errno != SOCKET_EADDRINUSE) || - (waited >= mysqld_port_timeout)) - break; - sql_print_information("Retrying bind on TCP/IP port %u", mysqld_port); - this_wait= retry * retry / 3 + 1; - sleep(this_wait); - } - if (ret < 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 ?",mysqld_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("listen() on TCP/IP failed with error %d", - socket_errno); - unireg_abort(1); - } + if (mysqld_port) + base_ip_sock= activate_tcp_port(mysqld_port); + if (mysqld_extra_port) + extra_ip_sock= activate_tcp_port(mysqld_extra_port); } #ifdef __NT__ @@ -1732,7 +1818,7 @@ static void network_init(void) if (Service.IsNT() && mysqld_unix_port[0] && !opt_bootstrap && opt_enable_named_pipe) { - + strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\.\\pipe\\", mysqld_unix_port, NullS); bzero((char*) &saPipeSecurity, sizeof(saPipeSecurity)); @@ -1859,17 +1945,14 @@ void close_connection(THD *thd, uint errcode, bool lock) #endif /* EMBEDDED_LIBRARY */ -/** Called when a thread is aborted. */ +/** Called when mysqld is aborted with ^C */ /* ARGSUSED */ -extern "C" sig_handler end_thread_signal(int sig __attribute__((unused))) +extern "C" sig_handler end_mysqld_signal(int sig __attribute__((unused))) { - THD *thd=current_thd; - DBUG_ENTER("end_thread_signal"); - if (thd && ! thd->bootstrap) - { - statistic_increment(killed_threads, &LOCK_status); - thread_scheduler.end_thread(thd,0); /* purecov: inspected */ - } + DBUG_ENTER("end_mysqld_signal"); + /* Don't call kill_mysql() if signal thread is not running */ + if (signal_thread_in_use) + kill_mysql(); // Take down mysqld nicely DBUG_VOID_RETURN; /* purecov: deadcode */ } @@ -1892,7 +1975,7 @@ void unlink_thd(THD *thd) thd->cleanup(); pthread_mutex_lock(&LOCK_connection_count); - --connection_count; + (*thd->scheduler->connection_count)--; pthread_mutex_unlock(&LOCK_connection_count); (void) pthread_mutex_lock(&LOCK_thread_count); @@ -1977,6 +2060,8 @@ bool one_thread_per_connection_end(THD *thd, bool put_in_cache) { DBUG_ENTER("one_thread_per_connection_end"); unlink_thd(thd); + /* Mark that current_thd is not valid anymore */ + my_pthread_setspecific_ptr(THR_THD, 0); if (put_in_cache) put_in_cache= cache_thread(); pthread_mutex_unlock(&LOCK_thread_count); @@ -2096,8 +2181,8 @@ void win_install_sigabrt_handler(void) #ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER #define DEBUGGER_ATTACH_TIMEOUT 120 /* - Wait for debugger to attach and break into debugger. If debugger is not attached, - resume after timeout. + Wait for debugger to attach and break into debugger. If debugger is + not attached, resume after timeout. */ static void wait_for_debugger(int timeout_sec) { @@ -2276,7 +2361,7 @@ static void registerwithneb() { ConsumerRegistrationInfo reg_info; - + /* Clear NEB registration structure */ bzero((char*) ®_info, sizeof(struct ConsumerRegistrationInfo)); @@ -2292,7 +2377,7 @@ static void registerwithneb() reg_info.CRIOwnerID= (LoadDefinitionStructure *)getnlmhandle(); reg_info.CRIConsumerESR= NULL; // No consumer ESR required reg_info.CRISecurityToken= 0; // No security token for the event - reg_info.CRIConsumerFlags= 0; // SMP_ENABLED_BIT; + reg_info.CRIConsumerFlags= 0; // SMP_ENABLED_BIT; reg_info.CRIFilterName= 0; // No event filtering reg_info.CRIFilterDataLength= 0; // No filtering data reg_info.CRIFilterData= 0; // No filtering data @@ -2317,7 +2402,7 @@ static void registerwithneb() Get the NSS volume ID of the MySQL Data volume. Volume ID is stored in a global variable */ - getvolumeID((BYTE*) datavolname); + getvolumeID((BYTE*) datavolname); } @@ -2381,7 +2466,7 @@ static void getvolumeID(BYTE *volumeName) strxmov(path, (const char *) ADMIN_VOL_PATH, (const char *) volumeName, NullS); - if ((status= zOpen(rootKey, zNSS_TASK, zNSPACE_LONG|zMODE_UTF8, + if ((status= zOpen(rootKey, zNSS_TASK, zNSPACE_LONG|zMODE_UTF8, (BYTE *) path, zRR_READ_ACCESS, &fileKey)) != zOK) { consoleprintf("\nGetNSSVolumeProperties - Failed to get file, status: %d\n.", (int) status); @@ -2389,7 +2474,7 @@ static void getvolumeID(BYTE *volumeName) } getInfoMask= zGET_IDS | zGET_VOLUME_INFO ; - if ((status= zGetInfo(fileKey, getInfoMask, sizeof(info), + if ((status= zGetInfo(fileKey, getInfoMask, sizeof(info), zINFO_VERSION_A, &info)) != zOK) { consoleprintf("\nGetNSSVolumeProperties - Failed in zGetInfo, status: %d\n.", (int) status); @@ -2464,6 +2549,9 @@ extern "C" sig_handler handle_segfault(int sig) { time_t curr_time; struct tm tm; +#ifdef HAVE_STACKTRACE + THD *thd=current_thd; +#endif /* Strictly speaking, one needs a mutex here @@ -2482,13 +2570,19 @@ extern "C" sig_handler handle_segfault(int sig) curr_time= my_time(0); localtime_r(&curr_time, &tm); - fprintf(stderr,"\ -%02d%02d%02d %2d:%02d:%02d - mysqld got " SIGNAL_FMT " ;\n\ + fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d ", + tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); + if (opt_expect_abort && sig == SIGABRT) + { + fprintf(stderr,"[Note] mysqld did an expected abort\n"); + goto end; + } + + fprintf(stderr,"[ERROR] mysqld got " SIGNAL_FMT " ;\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", - tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec, sig); fprintf(stderr, "\ We will try our best to scrape up some info that will hopefully help diagnose\n\ @@ -2498,15 +2592,17 @@ and this may fail.\n\n"); (ulong) dflt_key_cache->key_cache_mem_size); fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size); fprintf(stderr, "max_used_connections=%lu\n", max_used_connections); - fprintf(stderr, "max_threads=%u\n", thread_scheduler.max_threads); + fprintf(stderr, "max_threads=%u\n", thread_scheduler.max_threads + + (uint) extra_max_connections); fprintf(stderr, "threads_connected=%u\n", thread_count); fprintf(stderr, "It is possible that mysqld could use up to \n\ key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = %lu K\n\ bytes of memory\n", ((ulong) dflt_key_cache->key_cache_mem_size + (global_system_variables.read_buff_size + global_system_variables.sortbuff_size) * - thread_scheduler.max_threads + - max_connections * sizeof(THD)) / 1024); + (thread_scheduler.max_threads + extra_max_connections) + + (max_connections + extra_max_connections)* sizeof(THD)) + / 1024); fprintf(stderr, "Hope that's ok; if not, decrease some variables in the equation.\n\n"); #if defined(HAVE_LINUXTHREADS) @@ -2522,7 +2618,6 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n", #endif /* HAVE_LINUXTHREADS */ #ifdef HAVE_STACKTRACE - THD *thd=current_thd; if (!(test_flags & TEST_NO_STACKTRACE)) { @@ -2586,7 +2681,7 @@ You should either build a dynamically-linked binary, or force LinuxThreads\n\ to be used with the LD_ASSUME_KERNEL environment variable. Please consult\n\ the documentation for your distribution on how to do that.\n"); #endif - + if (locked_in_memory) { fprintf(stderr, "\n\ @@ -2607,9 +2702,13 @@ bugs.\n"); } #endif +end: #ifndef __WIN__ - /* On Windows, do not terminate, but pass control to exception filter */ + /* Terminate */ exit(1); +#else + /* On Windows, do not terminate, but pass control to exception filter */ + ; #endif } @@ -2659,7 +2758,7 @@ static void init_signals(void) { /* Change limits so that we will get a core file */ STRUCT_RLIMIT rl; - rl.rlim_cur = rl.rlim_max = RLIM_INFINITY; + rl.rlim_cur = rl.rlim_max = (rlim_t) RLIM_INFINITY; if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings) sql_print_warning("setrlimit could not change the size of core files to 'infinity'; We may not be able to generate a core file on signals"); } @@ -2688,12 +2787,13 @@ static void init_signals(void) sigaddset(&set,THR_SERVER_ALARM); if (test_flags & TEST_SIGINT) { - my_sigset(thr_kill_signal, end_thread_signal); - // May be SIGINT - sigdelset(&set, thr_kill_signal); + /* Allow SIGINT to break mysqld. This is for debugging with --gdb */ + my_sigset(SIGINT, end_mysqld_signal); + sigdelset(&set, SIGINT); } else sigaddset(&set,SIGINT); + sigprocmask(SIG_SETMASK,&set,NULL); pthread_sigmask(SIG_SETMASK,&set,NULL); DBUG_VOID_RETURN; @@ -2753,12 +2853,13 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused))) This should actually be '+ max_number_of_slaves' instead of +10, but the +10 should be quite safe. */ - init_thr_alarm(thread_scheduler.max_threads + + init_thr_alarm(thread_scheduler.max_threads + extra_max_connections + global_system_variables.max_insert_delayed_threads + 10); - if (thd_lib_detected != THD_LIB_LT && (test_flags & TEST_SIGINT)) + if (test_flags & TEST_SIGINT) { - (void) sigemptyset(&set); // Setup up SIGINT for debug - (void) sigaddset(&set,SIGINT); // For debugging + /* Allow SIGINT to break mysqld. This is for debugging with --gdb */ + (void) sigemptyset(&set); + (void) sigaddset(&set,SIGINT); (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL); } (void) sigemptyset(&set); // Setup up SIGINT for debug @@ -2898,6 +2999,8 @@ extern "C" int my_message_sql(uint error, const char *str, myf MyFlags); int my_message_sql(uint error, const char *str, myf MyFlags) { THD *thd; + MYSQL_ERROR::enum_warning_level level; + sql_print_message_func func; DBUG_ENTER("my_message_sql"); DBUG_PRINT("error", ("error: %u message: '%s'", error, str)); @@ -2911,24 +3014,44 @@ int my_message_sql(uint error, const char *str, myf MyFlags) TODO: DBUG_ASSERT(error != 0); */ - if (error == 0) { /* At least, prevent new abuse ... */ - DBUG_ASSERT(strncmp(str, "MyISAM table", 12) == 0); + DBUG_ASSERT(strncmp(str, "MyISAM table", 12) == 0 || + strncmp(str, "MARIA table", 11) == 0); error= ER_UNKNOWN_ERROR; } + if (MyFlags & ME_JUST_INFO) + { + level= MYSQL_ERROR::WARN_LEVEL_NOTE; + func= sql_print_information; + } + else if (MyFlags & ME_JUST_WARNING) + { + level= MYSQL_ERROR::WARN_LEVEL_WARN; + func= sql_print_warning; + } + else + { + level= MYSQL_ERROR::WARN_LEVEL_ERROR; + func= sql_print_error; + } + if ((thd= current_thd)) { /* TODO: There are two exceptions mechanism (THD and sp_rcontext), this could be improved by having a common stack of handlers. */ - if (thd->handle_error(error, str, - MYSQL_ERROR::WARN_LEVEL_ERROR)) + if (thd->handle_error(error, str, level)) DBUG_RETURN(0); + if (level == MYSQL_ERROR::WARN_LEVEL_WARN) + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, error, str); + if (level != MYSQL_ERROR::WARN_LEVEL_ERROR) + goto to_error_log; + thd->is_slave_error= 1; // needed to catch query errors during replication /* @@ -2984,11 +3107,12 @@ int my_message_sql(uint error, const char *str, myf MyFlags) } } +to_error_log: /* When simulating OOM, skip writing to error log to avoid mtr errors */ DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_RETURN(0);); - if (!thd || MyFlags & ME_NOREFRESH) - sql_print_error("%s: %s",my_progname,str); /* purecov: inspected */ + if (!thd || (MyFlags & ME_NOREFRESH)) + (*func)("%s: %s", my_progname_short, str); /* purecov: inspected */ DBUG_RETURN(0); } @@ -3031,7 +3155,9 @@ const char *load_default_groups[]= { #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE "mysql_cluster", #endif -"mysqld","server", MYSQL_BASE_VERSION, 0, 0}; +"mysqld", "server", MYSQL_BASE_VERSION, +"mariadb", MARIADB_BASE_VERSION, +0, 0}; #if defined(__WIN__) && !defined(EMBEDDED_LIBRARY) static const int load_default_groups_sz= @@ -3049,10 +3175,8 @@ sizeof(load_default_groups)/sizeof(load_default_groups[0]); The default value is taken from either opt_date_time_formats[] or the ISO format (ANSI SQL) - @retval - 0 ok - @retval - 1 error + @retval 0 ok + @retval 1 error */ static bool init_global_datetime_format(timestamp_type format_type, @@ -3357,7 +3481,8 @@ static int init_common_variables(const char *conf_file_name, int argc, uint files, wanted_files, max_open_files; /* MyISAM requires two file handles per table. */ - wanted_files= 10+max_connections+table_cache_size*2; + wanted_files= (10 + max_connections + extra_max_connections + + table_cache_size*2); /* We are trying to allocate no less than max_connections*5 file handles (i.e. we are trying to set the limit so that they will @@ -3368,7 +3493,8 @@ static int init_common_variables(const char *conf_file_name, int argc, can't get max_connections*5 but still got no less than was requested (value of wanted_files). */ - max_open_files= max(max(wanted_files, max_connections*5), + max_open_files= max(max(wanted_files, + (max_connections + extra_max_connections)*5), open_files_limit); files= my_set_max_open_files(max_open_files); @@ -3473,7 +3599,7 @@ static int init_common_variables(const char *conf_file_name, int argc, global_system_variables.character_set_results= default_charset_info; global_system_variables.character_set_client= default_charset_info; - if (!(character_set_filesystem= + if (!(character_set_filesystem= get_charset_by_csname(character_set_filesystem_name, MY_CS_PRIMARY, MYF(MY_WME)))) return 1; @@ -3486,7 +3612,7 @@ static int init_common_variables(const char *conf_file_name, int argc, return 1; } global_system_variables.lc_time_names= my_default_lc_time_names; - + sys_init_connect.value_length= 0; if ((sys_init_connect.value= opt_init_connect)) sys_init_connect.value_length= strlen(opt_init_connect); @@ -3502,23 +3628,23 @@ static int init_common_variables(const char *conf_file_name, int argc, sys_init_slave.is_os_charset= TRUE; /* check log options and issue warnings if needed */ - if (opt_log && opt_logname && !(log_output_options & LOG_FILE) && - !(log_output_options & LOG_NONE)) + if (opt_log && opt_logname && *opt_logname && + !(log_output_options & (LOG_FILE | LOG_NONE))) sql_print_warning("Although a path was specified for the " "--log option, log tables are used. " "To enable logging to files use the --log-output option."); - if (opt_slow_log && opt_slow_logname && !(log_output_options & LOG_FILE) - && !(log_output_options & LOG_NONE)) + if (opt_slow_log && opt_slow_logname && *opt_slow_logname && + !(log_output_options & (LOG_FILE | LOG_NONE))) sql_print_warning("Although a path was specified for the " "--log_slow_queries option, log tables are used. " "To enable logging to files use the --log-output=file option."); - s= opt_logname ? opt_logname : make_default_log_name(buff, ".log"); + s= opt_logname && *opt_logname ? opt_logname : make_default_log_name(buff, ".log"); sys_var_general_log_path.value= my_strdup(s, MYF(0)); sys_var_general_log_path.value_length= strlen(s); - s= opt_slow_logname ? opt_slow_logname : make_default_log_name(buff, "-slow.log"); + s= opt_slow_logname && *opt_slow_logname ? opt_slow_logname : make_default_log_name(buff, "-slow.log"); sys_var_slow_log_path.value= my_strdup(s, MYF(0)); sys_var_slow_log_path.value_length= strlen(s); @@ -3621,7 +3747,7 @@ static int init_thread_environment() openssl_stdlocks= (openssl_lock_t*) OPENSSL_malloc(CRYPTO_num_locks() * sizeof(openssl_lock_t)); for (int i= 0; i < CRYPTO_num_locks(); ++i) - (void) my_rwlock_init(&openssl_stdlocks[i].lock, NULL); + (void) my_rwlock_init(&openssl_stdlocks[i].lock, NULL); CRYPTO_set_dynlock_create_callback(openssl_dynlock_create); CRYPTO_set_dynlock_destroy_callback(openssl_dynlock_destroy); CRYPTO_set_dynlock_lock_callback(openssl_lock); @@ -3662,26 +3788,27 @@ static int init_thread_environment() sql_print_error("Can't create thread-keys"); return 1; } + register_mutex_order(); return 0; } #if defined(HAVE_OPENSSL) && !defined(HAVE_YASSL) static unsigned long openssl_id_function() -{ +{ return (unsigned long) pthread_self(); -} +} static openssl_lock_t *openssl_dynlock_create(const char *file, int line) -{ +{ openssl_lock_t *lock= new openssl_lock_t; my_rwlock_init(&lock->lock, NULL); return lock; } -static void openssl_dynlock_destroy(openssl_lock_t *lock, const char *file, +static void openssl_dynlock_destroy(openssl_lock_t *lock, const char *file, int line) { rwlock_destroy(&lock->lock); @@ -3701,7 +3828,7 @@ static void openssl_lock_function(int mode, int n, const char *file, int line) } -static void openssl_lock(int mode, openssl_lock_t *lock, const char *file, +static void openssl_lock(int mode, openssl_lock_t *lock, const char *file, int line) { int err; @@ -3726,7 +3853,7 @@ static void openssl_lock(int mode, openssl_lock_t *lock, const char *file, sql_print_error("Fatal: OpenSSL interface problem (mode=0x%x)", mode); abort(); } - if (err) + if (err) { sql_print_error("Fatal: can't %s OpenSSL lock", what); abort(); @@ -3795,12 +3922,14 @@ static int init_server_components() query_cache_set_min_res_unit(query_cache_min_res_unit); query_cache_init(); query_cache_resize(query_cache_size); - randominit(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2); + my_rnd_init(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2); setup_fpu(); init_thr_lock(); + my_uuid_init((ulong) (my_rnd(&sql_rand))*12345,12345); #ifdef HAVE_REPLICATION init_slave_list(); #endif + wt_init(); /* Setup logs */ @@ -3825,12 +3954,19 @@ static int init_server_components() if (freopen(log_error_file, "a+", stdout)) #endif { - if (freopen(log_error_file, "a+", stderr)) - setbuf(stderr, NULL); + if (!(freopen(log_error_file, "a+", stderr))) + sql_print_warning("Couldn't reopen stderr"); + setbuf(stderr, NULL); } } } + /* set up the hook before initializing plugins which may use it */ + error_handler_hook= my_message_sql; + proc_info_hook= (const char *(*)(void *, const char *, const char *, + const char *, const unsigned int)) + set_thd_proc_info; + if (xid_cache_init()) { sql_print_error("Out of memory"); @@ -3916,7 +4052,7 @@ with --log-bin instead."); if (opt_binlog_format_id == BINLOG_FORMAT_UNSPEC) global_system_variables.binlog_format= BINLOG_FORMAT_STMT; else - { + { DBUG_ASSERT(global_system_variables.binlog_format != BINLOG_FORMAT_UNSPEC); } @@ -4005,9 +4141,6 @@ a file name for --log-bin-index option", opt_binlog_index_name); plugins_are_initialized= TRUE; /* Don't separate from init function */ } - if (opt_help) - unireg_abort(0); - /* we do want to exit if there are any other unknown options */ if (defaults_argc > 1) { @@ -4032,13 +4165,15 @@ a file name for --log-bin-index option", opt_binlog_index_name); if (defaults_argc) { - fprintf(stderr, "%s: Too many arguments (first extra is '%s').\n" - "Use --verbose --help to get a list of available options\n", + fprintf(stderr, "%s: Too many arguments (first extra is '%s').\n", my_progname, *tmp_argv); unireg_abort(1); } } + if (opt_help) + unireg_abort(0); + /* if the errmsg.sys is not loaded, terminate to maintain behaviour */ if (!errmesg[0][0]) unireg_abort(1); @@ -4098,7 +4233,7 @@ a file name for --log-bin-index option", opt_binlog_index_name); strlen(default_storage_engine_str) }; plugin_ref plugin; handlerton *hton; - + if ((plugin= ha_resolve_by_name(0, &name))) hton= plugin_data(plugin, handlerton*); else @@ -4120,13 +4255,22 @@ a file name for --log-bin-index option", opt_binlog_index_name); else { /* - Need to unlock as global_system_variables.table_plugin + Need to unlock as global_system_variables.table_plugin was acquired during plugin_init() */ + pthread_mutex_lock(&LOCK_global_system_variables); plugin_unlock(0, global_system_variables.table_plugin); global_system_variables.table_plugin= plugin; + pthread_mutex_unlock(&LOCK_global_system_variables); } } +#if defined(WITH_MARIA_STORAGE_ENGINE) && defined(USE_MARIA_FOR_TMP_TABLES) + if (!ha_storage_engine_is_enabled(maria_hton) && !opt_bootstrap) + { + sql_print_error("Maria engine is not enabled or did not start. The Maria engine must be enabled to continue as mysqld was configured with --with-maria-tmp-tables"); + unireg_abort(1); + } +#endif tc_log= (total_ha_2pc > 1 ? (opt_bin_log ? (TC_LOG *) &mysql_bin_log : @@ -4262,7 +4406,7 @@ static void handle_connections_methods() handler_count--; } } -#endif +#endif while (handler_count > 0) pthread_cond_wait(&COND_handler_count,&LOCK_thread_count); @@ -4275,7 +4419,7 @@ void decrement_handler_count() pthread_mutex_lock(&LOCK_thread_count); handler_count--; pthread_cond_signal(&COND_handler_count); - pthread_mutex_unlock(&LOCK_thread_count); + pthread_mutex_unlock(&LOCK_thread_count); my_thread_end(); } #else @@ -4331,13 +4475,6 @@ int main(int argc, char **argv) MY_INIT(argv[0]); // init my_sys library & pthreads /* nothing should come before this line ^^^ */ - /* Set signal used to kill MySQL */ -#if defined(SIGUSR2) - thr_kill_signal= thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2; -#else - thr_kill_signal= SIGINT; -#endif - /* Perform basic logger initialization logger. Should be called after MY_INIT, as it initializes mutexes. Log tables are inited later. @@ -4475,8 +4612,11 @@ we force server id to 2, but this MySQL server will not act as a slave."); #ifdef __WIN__ if (!opt_console) { - freopen(log_error_file,"a+",stdout); - freopen(log_error_file,"a+",stderr); + if (!freopen(log_error_file,"a+",stdout) || + !freopen(log_error_file,"a+",stderr)) + { + sql_print_warning("Couldn't reopen stdout or stderr"); + } setbuf(stderr, NULL); FreeConsole(); // Remove window } @@ -4492,7 +4632,6 @@ we force server id to 2, but this MySQL server will not act as a slave."); init signals & alarm After this we can't quit by a simple unireg_abort */ - error_handler_hook= my_message_sql; start_signal_handler(); // Creates pidfile if (mysql_rm_tmp_tables() || acl_init(opt_noacl) || @@ -4547,7 +4686,13 @@ we force server id to 2, but this MySQL server will not act as a slave."); { select_thread_in_use= 0; // Allow 'kill' to work bootstrap(stdin); - unireg_abort(bootstrap_error ? 1 : 0); + if (!kill_in_progress) + unireg_abort(bootstrap_error ? 1 : 0); + else + { + sleep(2); // Wait for kill + exit(0); + } } if (opt_init_file) { @@ -4588,7 +4733,7 @@ we force server id to 2, but this MySQL server will not act as a slave."); #endif /* __NT__ */ /* (void) pthread_attr_destroy(&connection_attrib); */ - + DBUG_PRINT("quit",("Exiting main thread")); #ifndef __WIN__ @@ -4670,10 +4815,8 @@ static char *add_quoted_string(char *to, const char *from, char *to_end) @param file_path Path to this program @param startup_option Startup option to mysqld - @retval - 0 option handled - @retval - 1 Could not handle option + @retval 0 option handled + @retval 1 Could not handle option */ static bool @@ -4904,12 +5047,13 @@ static bool read_init_file(char *file_name) When we enter this function, LOCK_thread_count is hold! */ - + void handle_connection_in_main_thread(THD *thd) { safe_mutex_assert_owner(&LOCK_thread_count); thread_cache_size=0; // Safety threads.append(thd); + thd->start_utime= my_micro_time(); pthread_mutex_unlock(&LOCK_thread_count); thd->start_utime= my_micro_time(); handle_one_connection(thd); @@ -4951,7 +5095,7 @@ void create_thread_to_handle_connection(THD *thd) (void) pthread_mutex_unlock(&LOCK_thread_count); pthread_mutex_lock(&LOCK_connection_count); - --connection_count; + (*thd->scheduler->connection_count)--; pthread_mutex_unlock(&LOCK_connection_count); statistic_increment(aborted_connects,&LOCK_status); @@ -5000,7 +5144,8 @@ static void create_new_thread(THD *thd) pthread_mutex_lock(&LOCK_connection_count); - if (connection_count >= max_connections + 1 || abort_loop) + if (*thd->scheduler->connection_count >= + *thd->scheduler->max_connections + 1|| abort_loop) { pthread_mutex_unlock(&LOCK_connection_count); @@ -5010,10 +5155,10 @@ static void create_new_thread(THD *thd) DBUG_VOID_RETURN; } - ++connection_count; + ++*thd->scheduler->connection_count; - if (connection_count > max_used_connections) - max_used_connections= connection_count; + if (connection_count + extra_connection_count > max_used_connections) + max_used_connections= connection_count + extra_connection_count; pthread_mutex_unlock(&LOCK_connection_count); @@ -5030,7 +5175,7 @@ static void create_new_thread(THD *thd) thread_count++; - thread_scheduler.add_connection(thd); + thd->scheduler->add_connection(thd); DBUG_VOID_RETURN; } @@ -5045,10 +5190,11 @@ inline void kill_broken_server() #if !defined(__NETWARE__) unix_sock == INVALID_SOCKET || #endif - (!opt_disable_networking && ip_sock == INVALID_SOCKET)) + (!opt_disable_networking && base_ip_sock == INVALID_SOCKET)) { select_thread_in_use = 0; /* The following call will never return */ + DBUG_PRINT("general", ("killing server because socket is closed")); kill_server(IF_NETWARE(MYSQL_KILL_SIGNAL, (void*) MYSQL_KILL_SIGNAL)); } } @@ -5064,26 +5210,38 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused))) { my_socket sock,new_sock; uint error_count=0; - uint max_used_connection= (uint) (max(ip_sock,unix_sock)+1); + uint max_used_connection; fd_set readFDs,clientFDs; THD *thd; struct sockaddr_in cAddr; - int ip_flags=0,socket_flags=0,flags; + int base_ip_flags=0, extra_ip_flags= 0, socket_flags=0, flags; st_vio *vio_tmp; DBUG_ENTER("handle_connections_sockets"); + max_used_connection= (uint) (max(base_ip_sock, unix_sock)); + max_used_connection= (uint) (max(extra_ip_sock, (int) max_used_connection)); + max_used_connection++; + LINT_INIT(new_sock); (void) my_pthread_getprio(pthread_self()); // For debugging FD_ZERO(&clientFDs); - if (ip_sock != INVALID_SOCKET) + if (base_ip_sock != INVALID_SOCKET) + { + FD_SET(base_ip_sock, &clientFDs); +#ifdef HAVE_FCNTL + base_ip_flags = fcntl(base_ip_sock, F_GETFL, 0); +#endif + } + if (extra_ip_sock != INVALID_SOCKET) { - FD_SET(ip_sock,&clientFDs); + FD_SET(extra_ip_sock, &clientFDs); #ifdef HAVE_FCNTL - ip_flags = fcntl(ip_sock, F_GETFL, 0); + extra_ip_flags = fcntl(extra_ip_sock, F_GETFL, 0); #endif } + #ifdef HAVE_SYS_UN_H FD_SET(unix_sock,&clientFDs); #ifdef HAVE_FCNTL @@ -5121,14 +5279,22 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused))) #ifdef HAVE_SYS_UN_H if (FD_ISSET(unix_sock,&readFDs)) { - sock = unix_sock; + sock= unix_sock; flags= socket_flags; } else #endif { - sock = ip_sock; - flags= ip_flags; + if (FD_ISSET(base_ip_sock,&readFDs)) + { + sock= base_ip_sock; + flags= base_ip_flags; + } + else + { + sock= extra_ip_sock; + flags= extra_ip_flags; + } } #if !defined(NO_FCNTL_NONBLOCK) @@ -5146,7 +5312,7 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused))) size_socket length=sizeof(struct sockaddr_in); new_sock = accept(sock, my_reinterpret_cast(struct sockaddr *) (&cAddr), &length); -#ifdef __NETWARE__ +#ifdef __NETWARE__ // TODO: temporary fix, waiting for TCP/IP fix - DEFECT000303149 if ((new_sock == INVALID_SOCKET) && (socket_errno == EINVAL)) { @@ -5181,7 +5347,7 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused))) #ifdef HAVE_LIBWRAP { - if (sock == ip_sock) + if (sock == base_ip_sock || sock == extra_ip_sock) { struct request_info req; signal(SIGCHLD, SIG_DFL); @@ -5261,6 +5427,11 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused))) if (sock == unix_sock) thd->security_ctx->host=(char*) my_localhost; + if (sock == extra_ip_sock) + { + thd->extra_port= 1; + thd->scheduler= &extra_thread_scheduler; + } create_new_thread(thd); } DBUG_LEAVE; @@ -5565,7 +5736,7 @@ errorconn: NullS); sql_perror(buff); } - if (handle_client_file_map) + if (handle_client_file_map) CloseHandle(handle_client_file_map); if (handle_client_map) UnmapViewOfFile(handle_client_map); @@ -5613,10 +5784,11 @@ error: enum options_mysqld { - OPT_ISAM_LOG=256, OPT_SKIP_NEW, - OPT_SKIP_GRANT, OPT_SKIP_LOCK, + 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_EXTRA_PORT, OPT_BIN_LOG, OPT_SKIP_RESOLVE, OPT_SKIP_NETWORKING, OPT_BIN_LOG_INDEX, OPT_BIND_ADDRESS, OPT_PID_FILE, @@ -5643,11 +5815,11 @@ enum options_mysqld #ifndef DBUG_OFF OPT_BINLOG_SHOW_XID, #endif - OPT_BINLOG_ROWS_EVENT_MAX_SIZE, + OPT_BINLOG_ROWS_EVENT_MAX_SIZE, OPT_WANT_CORE, OPT_CONCURRENT_INSERT, OPT_MEMLOCK, OPT_MYISAM_RECOVER, OPT_REPLICATE_REWRITE_DB, OPT_SERVER_ID, - OPT_SKIP_SLAVE_START, OPT_SAFE_SHOW_DB, + OPT_SKIP_SLAVE_START, OPT_SAFE_SHOW_DB, OPT_SAFEMALLOC_MEM_LIMIT, OPT_REPLICATE_DO_TABLE, OPT_REPLICATE_IGNORE_TABLE, OPT_REPLICATE_WILD_DO_TABLE, OPT_REPLICATE_WILD_IGNORE_TABLE, OPT_REPLICATE_SAME_SERVER_ID, @@ -5655,7 +5827,7 @@ enum options_mysqld OPT_ABORT_SLAVE_EVENT_COUNT, OPT_LOG_BIN_TRUST_FUNCTION_CREATORS, OPT_LOG_BIN_TRUST_FUNCTION_CREATORS_OLD, - OPT_ENGINE_CONDITION_PUSHDOWN, OPT_NDB_CONNECTSTRING, + OPT_ENGINE_CONDITION_PUSHDOWN, OPT_NDB_CONNECTSTRING, OPT_NDB_USE_EXACT_COUNT, OPT_NDB_USE_TRANSACTIONS, OPT_NDB_FORCE_SEND, OPT_NDB_AUTOINCREMENT_PREFETCH_SZ, OPT_NDB_SHM, OPT_NDB_OPTIMIZED_NODE_SELECTION, OPT_NDB_CACHE_CHECK_TIME, @@ -5666,7 +5838,7 @@ enum options_mysqld OPT_NDB_REPORT_THRESH_BINLOG_EPOCH_SLIP, OPT_NDB_REPORT_THRESH_BINLOG_MEM_USAGE, OPT_NDB_USE_COPYING_ALTER_TABLE, - OPT_SKIP_SAFEMALLOC, + OPT_SKIP_SAFEMALLOC, OPT_MUTEX_DEADLOCK_DETECTOR, OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE, OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS, OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL, @@ -5700,11 +5872,16 @@ enum options_mysqld OPT_MAX_LENGTH_FOR_SORT_DATA, OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE, OPT_MAX_ERROR_COUNT, OPT_MULTI_RANGE_COUNT, OPT_MYISAM_DATA_POINTER_SIZE, + OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE, OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE, OPT_MYISAM_USE_MMAP, OPT_MYISAM_REPAIR_THREADS, OPT_MYISAM_MMAP_SIZE, OPT_MYISAM_STATS_METHOD, + + OPT_PAGECACHE_BUFFER_SIZE, + OPT_PAGECACHE_DIVISION_LIMIT, OPT_PAGECACHE_AGE_THRESHOLD, + OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT, OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT, OPT_OPEN_FILES_LIMIT, @@ -5714,7 +5891,7 @@ enum options_mysqld OPT_RECORD_RND_BUFFER, OPT_DIV_PRECINCREMENT, OPT_RELAY_LOG_SPACE_LIMIT, OPT_RELAY_LOG_PURGE, OPT_SLAVE_NET_TIMEOUT, OPT_SLAVE_COMPRESSED_PROTOCOL, OPT_SLOW_LAUNCH_TIME, - OPT_SLAVE_TRANS_RETRIES, OPT_READONLY, OPT_DEBUGGING, + OPT_SLAVE_TRANS_RETRIES, OPT_READONLY, OPT_DEBUGGING, OPT_DEBUG_FLUSH, OPT_SORT_BUFFER, OPT_TABLE_OPEN_CACHE, OPT_TABLE_DEF_CACHE, OPT_THREAD_CONCURRENCY, OPT_THREAD_CACHE_SIZE, OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK, @@ -5724,7 +5901,7 @@ enum options_mysqld OPT_RANGE_ALLOC_BLOCK_SIZE, OPT_ALLOW_SUSPICIOUS_UDFS, OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE, OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE, - OPT_SYNC_FRM, OPT_SYNC_BINLOG, + OPT_SYNC_FRM, OPT_SYNC_BINLOG, OPT_SYNC, OPT_SYNC_REPLICATION, OPT_SYNC_REPLICATION_SLAVE_ID, OPT_SYNC_REPLICATION_TIMEOUT, @@ -5776,11 +5953,19 @@ enum options_mysqld OPT_SECURE_FILE_PRIV, OPT_MIN_EXAMINED_ROW_LIMIT, OPT_LOG_SLOW_SLAVE_STATEMENTS, + OPT_DEBUG_CRC, OPT_DEBUG_ON, OPT_OLD_MODE, + OPT_TEST_IGNORE_WRONG_OPTIONS, OPT_TEST_RESTART, #if defined(ENABLED_DEBUG_SYNC) OPT_DEBUG_SYNC_TIMEOUT, #endif /* defined(ENABLED_DEBUG_SYNC) */ - OPT_OLD_MODE, OPT_SLAVE_EXEC_MODE, + OPT_DEADLOCK_SEARCH_DEPTH_SHORT, + OPT_DEADLOCK_SEARCH_DEPTH_LONG, + OPT_DEADLOCK_TIMEOUT_SHORT, + OPT_DEADLOCK_TIMEOUT_LONG, + OPT_LOG_SLOW_RATE_LIMIT, + OPT_LOG_SLOW_VERBOSITY, + OPT_LOG_SLOW_FILTER, OPT_GENERAL_LOG_FILE, OPT_SLOW_QUERY_LOG_FILE, OPT_IGNORE_BUILTIN_INNODB, @@ -5907,9 +6092,35 @@ struct my_option my_long_options[] = NO_ARG, 0, 0, 0, 0, 0, 0}, {"datadir", 'h', "Path to the database root.", &mysql_data_home, &mysql_data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"deadlock-search-depth-short", OPT_DEADLOCK_SEARCH_DEPTH_SHORT, + "Short search depth for the two-step deadlock detection", + &global_system_variables.wt_deadlock_search_depth_short, + &max_system_variables.wt_deadlock_search_depth_short, + 0, GET_ULONG, REQUIRED_ARG, 4, 0, 32, 0, 0, 0}, + {"deadlock-search-depth-long", OPT_DEADLOCK_SEARCH_DEPTH_LONG, + "Long search depth for the two-step deadlock detection", + &global_system_variables.wt_deadlock_search_depth_long, + &max_system_variables.wt_deadlock_search_depth_long, + 0, GET_ULONG, REQUIRED_ARG, 15, 0, 33, 0, 0, 0}, + {"deadlock-timeout-short", OPT_DEADLOCK_TIMEOUT_SHORT, + "Short timeout for the two-step deadlock detection (in microseconds)", + &global_system_variables.wt_timeout_short, + &max_system_variables.wt_timeout_short, + 0, GET_ULONG, REQUIRED_ARG, 10000, 0, ULONG_MAX, 0, 0, 0}, + {"deadlock-timeout-long", OPT_DEADLOCK_TIMEOUT_LONG, + "Long timeout for the two-step deadlock detection (in microseconds)", + &global_system_variables.wt_timeout_long, + &max_system_variables.wt_timeout_long, + 0, GET_ULONG, REQUIRED_ARG, 50000000, 0, ULONG_MAX, 0, 0, 0}, #ifndef DBUG_OFF {"debug", '#', "Debug log.", &default_dbug_option, &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-crc-break", OPT_DEBUG_CRC, + "Call my_debug_put_break_here() if crc matches this number (for debug).", + &opt_my_crc_dbug_check, &opt_my_crc_dbug_check, + 0, GET_ULONG, REQUIRED_ARG, 0, 0, ~(ulong) 0L, 0, 0, 0}, + {"debug-flush", OPT_DEBUG_FLUSH, "Default debug log with flush after write", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"default-character-set", OPT_DEFAULT_CHARACTER_SET_OLD, "Set the default character set (deprecated option, use --character-set-server instead).", @@ -5983,6 +6194,15 @@ struct my_option my_long_options[] = GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, /* We must always support the next option to make scripts like mysqltest easier to do */ + {"extra-port", OPT_EXTRA_PORT, + "Extra port number to use for tcp-connections in a one-thread-per-connection manner. 0 means don't use another port", + &mysqld_extra_port, + &mysqld_extra_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"extra-max-connections", OPT_MAX_CONNECTIONS, + "The number of connections on 'extra-port.", + &extra_max_connections, + &extra_max_connections, 0, GET_ULONG, REQUIRED_ARG, 1, 1, 100000, + 0, 1, 0}, {"gdb", OPT_DEBUGGING, "Set up signals usable for debugging.", &opt_debugging, &opt_debugging, @@ -6106,7 +6326,7 @@ each time the SQL thread starts.", &opt_log_slow_slave_statements, &opt_log_slow_slave_statements, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"log_slow_queries", OPT_SLOW_QUERY_LOG, + {"log-slow-queries", OPT_SLOW_QUERY_LOG, "Log slow queries to a table or log file. Defaults logging to table " "mysql.slow_log or hostname-slow.log if --log-output=file is used. " "Must be enabled to activate other slow log options. " @@ -6126,7 +6346,7 @@ each time the SQL thread starts.", #ifdef HAVE_MMAP {"log-tc-size", OPT_LOG_TC_SIZE, "Size of transaction coordinator log.", &opt_tc_log_size, &opt_tc_log_size, 0, GET_ULONG, - REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, ULONG_MAX, 0, + REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, (longlong) ULONG_MAX, 0, TC_LOG_PAGE_SIZE, 0}, #endif {"log-update", OPT_UPDATE_LOG, @@ -6216,6 +6436,13 @@ each time the SQL thread starts.", #endif /* HAVE_REPLICATION */ {"memlock", OPT_MEMLOCK, "Lock mysqld in memory.", &locked_in_memory, &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, +#ifdef SAFE_MUTEX + {"mutex-deadlock-detector", OPT_MUTEX_DEADLOCK_DETECTOR, + "Enable checking of wrong mutex usage.", + &safe_mutex_deadlock_detector, + &safe_mutex_deadlock_detector, + 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, +#endif {"myisam-recover", OPT_MYISAM_RECOVER, "Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.", &myisam_recover_options_str, &myisam_recover_options_str, 0, @@ -6605,7 +6832,7 @@ thread is in the relay logs.", purify. These are not suppressed: instead we disable symlinks option if compiled with valgrind support. */ - IF_PURIFY(0,1), 0, 0, 0, 0, 0}, + IF_VALGRIND(0,1), 0, 0, 0, 0, 0}, {"sysdate-is-now", OPT_SYSDATE_IS_NOW, "Non-default option to alias SYSDATE() to NOW() to make it safe-replicable. " "Since 5.0, SYSDATE() returns a `dynamic' value different for different " @@ -6633,6 +6860,14 @@ thread is in the relay logs.", #endif &use_temp_pool, &use_temp_pool, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, + {"test-ignore-wrong-options", OPT_TEST_IGNORE_WRONG_OPTIONS, + "Ignore wrong enums values in command line arguments. Useful only for test scripts", + &opt_ignore_wrong_options, &opt_ignore_wrong_options, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"test-expect-abort", OPT_TEST_RESTART, + "Expect that server aborts with 'abort'; Don't write out server variables on 'abort'. Useful only for test scripts", + &opt_expect_abort, &opt_expect_abort, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"timed_mutexes", OPT_TIMED_MUTEXES, "Specify whether to time mutexes (only InnoDB mutexes are currently supported).", &timed_mutexes, &timed_mutexes, 0, GET_BOOL, NO_ARG, 0, @@ -6650,10 +6885,11 @@ thread is in the relay logs.", {"transaction-isolation", OPT_TX_ISOLATION, "Default transaction isolation level.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"use-symbolic-links", OPT_SYMBOLIC_LINKS, "Enable symbolic link support. " + {"use-symbolic-links", OPT_SYMBOLIC_LINKS, + "Enable symbolic link support. " "Deprecated option; use --symbolic-links instead.", &my_use_symdir, &my_use_symdir, 0, GET_BOOL, NO_ARG, - IF_PURIFY(0,1), 0, 0, 0, 0, 0}, + IF_VALGRIND(0,1), 0, 0, 0, 0, 0}, {"user", 'u', "Run mysqld daemon as user.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"verbose", 'v', "Used with --help option for detailed help.", @@ -6674,12 +6910,12 @@ thread is in the relay logs.", "during a transaction. If you often use big, multi-statement " "transactions you can increase this to get more performance.", &binlog_cache_size, &binlog_cache_size, 0, GET_ULONG, - REQUIRED_ARG, 32*1024L, IO_SIZE, ULONG_MAX, 0, IO_SIZE, 0}, + REQUIRED_ARG, 32*1024L, IO_SIZE, (longlong) ULONG_MAX, 0, IO_SIZE, 0}, {"bulk_insert_buffer_size", OPT_BULK_INSERT_BUFFER_SIZE, "Size of tree cache used in bulk insert optimization. Note that this " "is a limit per thread.", &global_system_variables.bulk_insert_buff_size, &max_system_variables.bulk_insert_buff_size, - 0, GET_ULONG, REQUIRED_ARG, 8192*1024, 0, ULONG_MAX, 0, 1, 0}, + 0, GET_ULONG, REQUIRED_ARG, 8192*1024, 0, (longlong) ULONG_MAX, 0, 1, 0}, {"connect_timeout", OPT_CONNECT_TIMEOUT, "The number of seconds the mysqld server is waiting for a connect packet " "before responding with 'Bad handshake'.", &connect_timeout, &connect_timeout, @@ -6704,7 +6940,7 @@ thread is in the relay logs.", "will check if there are any SELECT statements pending. If so, it allows " "these to execute before continuing.", &delayed_insert_limit, &delayed_insert_limit, 0, GET_ULONG, - REQUIRED_ARG, DELAYED_LIMIT, 1, ULONG_MAX, 0, 1, 0}, + REQUIRED_ARG, DELAYED_LIMIT, 1, (longlong) ULONG_MAX, 0, 1, 0}, {"delayed_insert_timeout", OPT_DELAYED_INSERT_TIMEOUT, "How long a INSERT DELAYED thread should wait for INSERT statements before terminating.", &delayed_insert_timeout, &delayed_insert_timeout, 0, @@ -6714,7 +6950,7 @@ thread is in the relay logs.", "If the queue becomes full, any client that does INSERT DELAYED will wait " "until there is room in the queue again.", &delayed_queue_size, &delayed_queue_size, 0, GET_ULONG, - REQUIRED_ARG, DELAYED_QUEUE_SIZE, 1, ULONG_MAX, 0, 1, 0}, + REQUIRED_ARG, DELAYED_QUEUE_SIZE, 1, (longlong) ULONG_MAX, 0, 1, 0}, {"div_precision_increment", OPT_DIV_PRECINCREMENT, "Precision of the result of '/' operator will be increased on that value.", &global_system_variables.div_precincrement, @@ -6754,7 +6990,7 @@ thread is in the relay logs.", "The maximum length of the result of function group_concat.", &global_system_variables.group_concat_max_len, &max_system_variables.group_concat_max_len, 0, GET_ULONG, - REQUIRED_ARG, 1024, 4, ULONG_MAX, 0, 1, 0}, + REQUIRED_ARG, 1024, 4, (longlong) ULONG_MAX, 0, 1, 0}, {"interactive_timeout", OPT_INTERACTIVE_TIMEOUT, "The number of seconds the server waits for activity on an interactive " "connection before closing it.", @@ -6765,7 +7001,7 @@ thread is in the relay logs.", "The size of the buffer that is used for full joins.", &global_system_variables.join_buff_size, &max_system_variables.join_buff_size, 0, GET_ULONG, - REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ULONG_MAX, + REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, (longlong) ULONG_MAX, MALLOC_OVERHEAD, IO_SIZE, 0}, {"keep_files_on_create", OPT_KEEP_FILES_ON_CREATE, "Don't overwrite stale .MYD and .MYI even if no directory is specified.", @@ -6785,22 +7021,48 @@ thread is in the relay logs.", "until it is considered aged enough to be downgraded to a warm block. " "This specifies the percentage ratio of that number of hits to the total " "number of blocks in key cache.", - &dflt_key_cache_var.param_age_threshold, NULL, NULL, - (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG, 300, 100, ULONG_MAX, 0, 100, 0}, + &dflt_key_cache_var.param_age_threshold, 0, 0, + (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG, 300, 100, (longlong) ULONG_MAX, + 0, 100, 0}, {"key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE, "The default size of key cache blocks.", &dflt_key_cache_var.param_block_size, NULL, NULL, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG, KEY_CACHE_BLOCK_SIZE, 512, 1024 * 16, 0, 512, 0}, {"key_cache_division_limit", OPT_KEY_CACHE_DIVISION_LIMIT, "The minimum percentage of warm blocks in key cache.", - &dflt_key_cache_var.param_division_limit, NULL, NULL, + &dflt_key_cache_var.param_division_limit, 0, 0, (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100, 1, 100, 0, 1, 0}, + {"log-slow-filter", OPT_LOG_SLOW_FILTER, + "Log only the queries that followed certain execution plan. Multiple flags " + "allowed in a comma-separated string. [admin, filesort, filesort_on_disk, " + "full_join, full_scan, query_cache, query_cache_miss, tmp_table, " + "tmp_table_on_disk]. Sets log-slow-admin-command to ON", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, QPLAN_ALWAYS_SET, 0, 0}, + {"log-slow-rate_limit", OPT_LOG_SLOW_RATE_LIMIT, + "If set, only write to slow log every 'log_slow_rate_limit' query (use " + "this to reduce output on slow query log)", + &global_system_variables.log_slow_rate_limit, + &max_system_variables.log_slow_rate_limit, 0, GET_ULONG, + REQUIRED_ARG, 1, 1, ~0L, 0, 1L, 0}, + {"log-slow-verbosity", OPT_LOG_SLOW_VERBOSITY, + "Choose how verbose the messages to your slow log will be. Multiple flags " + "allowed in a comma-separated string. [query_plan, innodb]", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, + {"log-slow-file", OPT_SLOW_QUERY_LOG_FILE, + "Log slow queries to given log file. Defaults logging to hostname-slow.log", + &opt_slow_logname, &opt_slow_logname, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"long_query_time", OPT_LONG_QUERY_TIME, "Log all queries that have taken more than long_query_time seconds to " "execute. The argument will be treated as a decimal value with " "microsecond precision.", &long_query_time, &long_query_time, 0, GET_DOUBLE, REQUIRED_ARG, 10, 0, LONG_TIMEOUT, 0, 0, 0}, + {"log-slow-time", OPT_LONG_QUERY_TIME, + "Log all queries that have taken more than long_query_time seconds to execute to file. " + "The argument will be treated as a decimal value with microsecond precission.", + &long_query_time, &long_query_time, 0, GET_DOUBLE, + REQUIRED_ARG, 10, 0, LONG_TIMEOUT, 0, 0, 0}, {"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES, "If set to 1, table names are stored in lowercase on disk and table names " "will be case-insensitive. Should be set to 2 if you are using a case-" @@ -6831,7 +7093,7 @@ thread is in the relay logs.", "If there is more than this number of interrupted connections from a host " "this host will be blocked from further connections.", &max_connect_errors, &max_connect_errors, 0, GET_ULONG, - REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ULONG_MAX, 0, 1, 0}, + REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, (longlong) ULONG_MAX, 0, 1, 0}, // Default max_connections of 151 is larger than Apache's default max // children, to avoid "too many connections" error in a common setup {"max_connections", OPT_MAX_CONNECTIONS, @@ -6878,7 +7140,7 @@ thread is in the relay logs.", "Limit assumed max number of seeks when looking up rows based on a key.", &global_system_variables.max_seeks_for_key, &max_system_variables.max_seeks_for_key, 0, GET_ULONG, - REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0 }, + REQUIRED_ARG, (longlong) ULONG_MAX, 1, (longlong) ULONG_MAX, 0, 1, 0 }, {"max_sort_length", OPT_MAX_SORT_LENGTH, "The number of bytes to use when sorting BLOB or TEXT values (only the " "first max_sort_length bytes of each value are used; the rest are ignored).", @@ -6894,7 +7156,7 @@ thread is in the relay logs.", "Maximum number of temporary tables a client can keep open at a time.", &global_system_variables.max_tmp_tables, &max_system_variables.max_tmp_tables, 0, GET_ULONG, - REQUIRED_ARG, 32, 1, ULONG_MAX, 0, 1, 0}, + REQUIRED_ARG, 32, 1, (longlong) ULONG_MAX, 0, 1, 0}, {"max_user_connections", OPT_MAX_USER_CONNECTIONS, "The maximum number of active connections for a single user (0 = no limit).", &max_user_connections, &max_user_connections, 0, GET_UINT, @@ -6902,17 +7164,17 @@ thread is in the relay logs.", {"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT, "After this many write locks, allow some read locks to run in between.", &max_write_lock_count, &max_write_lock_count, 0, GET_ULONG, - REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0}, + REQUIRED_ARG, (longlong) ULONG_MAX, 1, (longlong) ULONG_MAX, 0, 1, 0}, {"min_examined_row_limit", OPT_MIN_EXAMINED_ROW_LIMIT, "Don't log queries which examine less than min_examined_row_limit rows to file.", &global_system_variables.min_examined_row_limit, &max_system_variables.min_examined_row_limit, 0, GET_ULONG, - REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1L, 0}, + REQUIRED_ARG, 0, 0, (longlong) ULONG_MAX, 0, 1L, 0}, {"multi_range_count", OPT_MULTI_RANGE_COUNT, "Number of key ranges to request at once.", &global_system_variables.multi_range_count, &max_system_variables.multi_range_count, 0, - GET_ULONG, REQUIRED_ARG, 256, 1, ULONG_MAX, 0, 1, 0}, + GET_ULONG, REQUIRED_ARG, 256, 1, (longlong) ULONG_MAX, 0, 1, 0}, {"myisam_block_size", OPT_MYISAM_BLOCK_SIZE, "Block size to be used for MyISAM index pages.", &opt_myisam_block_size, &opt_myisam_block_size, 0, GET_ULONG, REQUIRED_ARG, @@ -6947,13 +7209,13 @@ thread is in the relay logs.", "disables parallel repair.", &global_system_variables.myisam_repair_threads, &max_system_variables.myisam_repair_threads, 0, - GET_ULONG, REQUIRED_ARG, 1, 1, ULONG_MAX, 0, 1, 0}, + GET_ULONG, REQUIRED_ARG, 1, 1, (longlong) ULONG_MAX, 0, 1, 0}, {"myisam_sort_buffer_size", OPT_MYISAM_SORT_BUFFER_SIZE, "The buffer that is allocated when sorting the index when doing a REPAIR " "or when creating indexes with CREATE INDEX or ALTER TABLE.", &global_system_variables.myisam_sort_buff_size, &max_system_variables.myisam_sort_buff_size, 0, - GET_ULONG, REQUIRED_ARG, 8192 * 1024, 4096, ~0L, 0, 1, 0}, + GET_ULONG, REQUIRED_ARG, 8192 * 1024, 4096, (longlong) ULONG_MAX, 0, 1, 0}, {"myisam_use_mmap", OPT_MYISAM_USE_MMAP, "Use memory mapping for reading and writing MyISAM tables.", &opt_myisam_use_mmap, &opt_myisam_use_mmap, 0, GET_BOOL, NO_ARG, @@ -6978,7 +7240,8 @@ thread is in the relay logs.", "If a read on a communication port is interrupted, retry this many times before giving up.", &global_system_variables.net_retry_count, &max_system_variables.net_retry_count,0, - GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, ULONG_MAX, 0, 1, 0}, + GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, (longlong) ULONG_MAX, + 0, 1, 0}, {"net_write_timeout", OPT_NET_WRITE_TIMEOUT, "Number of seconds to wait for a block to be written to a connection before " "aborting the write.", @@ -7017,9 +7280,12 @@ thread is in the relay logs.", 0, GET_ULONG, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0}, {"optimizer_switch", OPT_OPTIMIZER_SWITCH, "optimizer_switch=option=val[,option=val...], where option={index_merge, " - "index_merge_union, index_merge_sort_union, index_merge_intersection} and " - "val={on, off, default}.", - &optimizer_switch_str, &optimizer_switch_str, 0, GET_STR, REQUIRED_ARG, + "index_merge_union, index_merge_sort_union, index_merge_intersection" +#ifndef DBUG_OFF + ", table_elimination" +#endif + "} and val={on, off, default}.", + &optimizer_switch_str, &optimizer_switch_str, 0, GET_STR, REQUIRED_ARG, /*OPTIMIZER_SWITCH_DEFAULT*/0, 0, 0, 0, 0, 0}, {"plugin_dir", OPT_PLUGIN_DIR, "Directory for plugins.", @@ -7040,18 +7306,19 @@ thread is in the relay logs.", "Allocation block size for query parsing and execution.", &global_system_variables.query_alloc_block_size, &max_system_variables.query_alloc_block_size, 0, GET_ULONG, - REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0}, + REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, (longlong) ULONG_MAX, 0, 1024, + 0}, #ifdef HAVE_QUERY_CACHE {"query_cache_limit", OPT_QUERY_CACHE_LIMIT, "Don't cache results that are bigger than this.", &query_cache_limit, &query_cache_limit, 0, GET_ULONG, - REQUIRED_ARG, 1024*1024L, 0, ULONG_MAX, 0, 1, 0}, + REQUIRED_ARG, 1024*1024L, 0, (longlong) ULONG_MAX, 0, 1, 0}, {"query_cache_min_res_unit", OPT_QUERY_CACHE_MIN_RES_UNIT, "Minimal size of unit in which space for results is allocated (last unit " "will be trimmed after writing all result data).", &query_cache_min_res_unit, &query_cache_min_res_unit, 0, GET_ULONG, REQUIRED_ARG, QUERY_CACHE_MIN_RESULT_DATA_SIZE, - 0, ULONG_MAX, 0, 1, 0}, + 0, (longlong) ULONG_MAX, 0, 1, 0}, #endif /*HAVE_QUERY_CACHE*/ {"query_cache_size", OPT_QUERY_CACHE_SIZE, "The memory allocated to store results from old queries.", @@ -7075,13 +7342,13 @@ thread is in the relay logs.", &global_system_variables.query_prealloc_size, &max_system_variables.query_prealloc_size, 0, GET_ULONG, REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, QUERY_ALLOC_PREALLOC_SIZE, - ULONG_MAX, 0, 1024, 0}, + (longlong) ULONG_MAX, 0, 1024, 0}, {"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE, "Allocation block size for storing ranges during optimization.", &global_system_variables.range_alloc_block_size, &max_system_variables.range_alloc_block_size, 0, GET_ULONG, - REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, ULONG_MAX, - 0, 1024, 0}, + REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, + (longlong) ULONG_MAX, 0, 1024, 0}, {"read_buffer_size", OPT_RECORD_BUFFER, "Each thread that does a sequential scan allocates a buffer of this size " "for each table it scans. If you do many sequential scans, you may want " @@ -7144,16 +7411,20 @@ thread is in the relay logs.", "Each thread that needs to do a sort allocates a buffer of this size.", &global_system_variables.sortbuff_size, &max_system_variables.sortbuff_size, 0, GET_ULONG, REQUIRED_ARG, - MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, ~0L, MALLOC_OVERHEAD, - 1, 0}, + MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, (longlong) ULONG_MAX, + MALLOC_OVERHEAD, 1, 0}, {"sync-binlog", OPT_SYNC_BINLOG, "Synchronously flush binary log to disk after every #th event. " "Use 0 (default) to disable synchronous flushing.", &sync_binlog_period, &sync_binlog_period, 0, GET_ULONG, - REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1, 0}, + REQUIRED_ARG, 0, 0, (longlong) ULONG_MAX, 0, 1, 0}, {"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default.", &opt_sync_frm, &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, + {"sync-sys", OPT_SYNC, + "Enable/disable system sync calls. Should only be turned off when running " + "tests or debugging!!", + &opt_sync, &opt_sync, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"table_cache", OPT_TABLE_OPEN_CACHE, "Deprecated; use --table_open_cache instead.", &table_cache_size, &table_cache_size, 0, GET_ULONG, @@ -7191,15 +7462,15 @@ thread is in the relay logs.", {"thread_stack", OPT_THREAD_STACK, "The stack size for each thread.", &my_thread_stack_size, &my_thread_stack_size, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK, - 1024L*128L, ULONG_MAX, 0, 1024, 0}, + (sizeof(void*)<=4)?1024L*128L: ((256-16)*1024L), (longlong) ULONG_MAX, 0, 1024, 0}, { "time_format", OPT_TIME_FORMAT, "The TIME format (for future).", &opt_date_time_formats[MYSQL_TIMESTAMP_TIME], &opt_date_time_formats[MYSQL_TIMESTAMP_TIME], 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"tmp_table_size", OPT_TMP_TABLE_SIZE, - "If an internal in-memory temporary table exceeds this size, MySQL will" - " automatically convert it to an on-disk MyISAM table.", + "If an internal in-memory temporary table exceeds this size, MySQL will " + "automatically convert it to an on-disk MyISAM/Maria table.", &global_system_variables.tmp_table_size, &max_system_variables.tmp_table_size, 0, GET_ULL, REQUIRED_ARG, 16*1024*1024L, 1024, MAX_MEM_TABLE_SIZE, 0, 1, 0}, @@ -7207,15 +7478,18 @@ thread is in the relay logs.", "Allocation block size for transactions to be stored in binary log.", &global_system_variables.trans_alloc_block_size, &max_system_variables.trans_alloc_block_size, 0, GET_ULONG, - REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0}, + REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, (longlong) ULONG_MAX, 0, 1024, + 0}, {"transaction_prealloc_size", OPT_TRANS_PREALLOC_SIZE, "Persistent buffer for transactions to be stored in binary log.", &global_system_variables.trans_prealloc_size, &max_system_variables.trans_prealloc_size, 0, GET_ULONG, - REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ULONG_MAX, 0, 1024, 0}, + REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, (longlong) ULONG_MAX, 0, + 1024, 0}, {"thread_handling", OPT_THREAD_HANDLING, "Define threads usage for handling queries: " - "one-thread-per-connection or no-threads.", 0, 0, + "one-thread-per-connection or no-threads.", + &opt_thread_handling, &opt_thread_handling, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"updatable_views_with_limit", OPT_UPDATABLE_VIEWS_WITH_LIMIT, "1 = YES = Don't issue an error message (warning only) if a VIEW without " @@ -7510,7 +7784,7 @@ static int show_ssl_ctx_get_session_cache_mode(THD *thd, SHOW_VAR *var, char *bu } /* - Functions relying on SSL + Functions relying on SSL Note: In the show_ssl_* functions, we need to check if we have a valid vio-object since this isn't always true, specifically when session_status or global_status is requested from @@ -7715,6 +7989,7 @@ SHOW_VAR status_vars[]= { {"Ssl_verify_mode", (char*) &show_ssl_get_verify_mode, SHOW_FUNC}, {"Ssl_version", (char*) &show_ssl_get_version, SHOW_FUNC}, #endif /* HAVE_OPENSSL */ + {"Syncs", (char*) &my_sync_count, SHOW_LONG_NOFLUSH}, {"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG}, {"Table_locks_waited", (char*) &locks_waited, SHOW_LONG}, #ifdef HAVE_MMAP @@ -7823,7 +8098,10 @@ static int mysql_init_variables(void) /* Things reset to zero */ opt_skip_slave_start= opt_reckless_slave = 0; mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0; +#if defined(HAVE_REALPATH) && !defined(HAVE_valgrind) && !defined(HAVE_BROKEN_REALPATH) + /* We can only test for sub paths if my_symlink.c is using realpath */ myisam_test_invalid_symlink= test_if_data_home_dir; +#endif opt_log= opt_slow_log= 0; opt_update_log= 0; log_output_options= find_bit_type(log_output_str, &log_output_typelib); @@ -7887,7 +8165,7 @@ static int mysql_init_variables(void) if (error) return 1; opt_specialflag= SPECIAL_ENGLISH; - unix_sock= ip_sock= INVALID_SOCKET; + unix_sock= base_ip_sock= extra_ip_sock= INVALID_SOCKET; mysql_home_ptr= mysql_home; pidfile_name_ptr= pidfile_name; log_error_file_ptr= log_error_file; @@ -7900,7 +8178,13 @@ static int mysql_init_variables(void) refresh_version= 1L; /* Increments on each reload */ global_query_id= thread_id= 1L; strmov(server_version, MYSQL_SERVER_VERSION); - myisam_recover_options_str= sql_mode_str= "OFF"; + sql_mode_str= ""; + + /* By default, auto-repair MyISAM tables after crash */ + myisam_recover_options_str= "DEFAULT"; + myisam_recover_options= HA_RECOVER_DEFAULT; + ha_open_options|= HA_OPEN_ABORT_IF_CRASHED; + myisam_stats_method_str= "nulls_unequal"; my_bind_addr = htonl(INADDR_ANY); threads.empty(); @@ -7912,6 +8196,7 @@ static int mysql_init_variables(void) sql_print_error("Cannot allocate the keycache"); return 1; } + /* set key_cache_hash.default_value = dflt_key_cache */ multi_keycache_init(); @@ -7951,6 +8236,9 @@ static int mysql_init_variables(void) global_system_variables.old_passwords= 0; global_system_variables.old_alter_table= 0; global_system_variables.binlog_format= BINLOG_FORMAT_UNSPEC; + global_system_variables.log_slow_verbosity= LOG_SLOW_VERBOSITY_INIT; + global_system_variables.log_slow_filter= QPLAN_ALWAYS_SET; + /* Default behavior for 4.1 and 5.0 is to treat NULL values as unequal when collecting index statistics for MyISAM tables. @@ -8059,6 +8347,38 @@ static int mysql_init_variables(void) } +/** + Find type for option + + If opt_ignore_wrong_options is set ignore wrong values + otherwise exit + + @return + @retval 0 ok ; *result is updated + @retval 1 error ; *result is not touched +*/ + +static my_bool find_opt_type(const char *x, TYPELIB *typelib, + const char *option, int *result) +{ + int res; + + if (opt_ignore_wrong_options) + { + if ((res= find_type_with_warning(x, typelib, option)) <= 0) + return 1; + } + else + res= find_type_or_exit(x, typelib, option); + *result= res; + return 0; +} + + +/** + Get next option from the command line +*/ + my_bool mysqld_get_one_option(int optid, const struct my_option *opt __attribute__((unused)), @@ -8067,12 +8387,25 @@ mysqld_get_one_option(int optid, int error; switch(optid) { - case '#': #ifndef DBUG_OFF - DBUG_SET_INITIAL(argument ? argument : default_dbug_option); -#endif + case OPT_DEBUG_FLUSH: + argument= IF_WIN((char*) default_dbug_option, (char*) "d:t:i:O,/tmp/mysqld.trace"); + /* fall through */ + case '#': + if (!argument) + argument= (char*) default_dbug_option; + if (argument[0] == '0' && !argument[1]) + { + DEBUGGER_OFF; + break; + } + DEBUGGER_ON; + if (argument[0] == '1' && !argument[1]) + break; + DBUG_SET_INITIAL(argument); opt_endinfo=1; /* unireg: memory allocation */ break; +#endif case '0': WARN_DEPRECATED(NULL, VER_CELOSIA, "--log-long-format", "--log-short-format"); break; @@ -8187,9 +8520,13 @@ mysqld_get_one_option(int optid, case (int) OPT_INIT_RPL_ROLE: { int role; - role= find_type_or_exit(argument, &rpl_role_typelib, opt->name); - rpl_status = (role == 1) ? RPL_AUTH_MASTER : RPL_IDLE_SLAVE; - break; + LINT_INIT(role); + + if (!find_opt_type(argument, &rpl_role_typelib, opt->name, &role)) + { + rpl_status = (role == 1) ? RPL_AUTH_MASTER : RPL_IDLE_SLAVE; + break; + } } case (int)OPT_REPLICATE_IGNORE_DB: { @@ -8240,8 +8577,12 @@ mysqld_get_one_option(int optid, case OPT_BINLOG_FORMAT: { int id; - id= find_type_or_exit(argument, &binlog_format_typelib, opt->name); - global_system_variables.binlog_format= opt_binlog_format_id= id - 1; + LINT_INIT(id); + + if (!find_opt_type(argument, &binlog_format_typelib, opt->name, &id)) + { + global_system_variables.binlog_format= opt_binlog_format_id= id - 1; + } break; } case (int)OPT_BINLOG_DO_DB: @@ -8287,7 +8628,7 @@ mysqld_get_one_option(int optid, } #endif /* HAVE_REPLICATION */ case (int) OPT_SLOW_QUERY_LOG: - WARN_DEPRECATED(NULL, "7.0", "--log_slow_queries", "'--slow_query_log'/'--slow_query_log_file'"); + WARN_DEPRECATED(NULL, "7.0", "--log_slow_queries", "'--slow_query_log'/'--log-slow-file'"); opt_slow_log= 1; break; #ifdef WITH_CSV_STORAGE_ENGINE @@ -8367,7 +8708,7 @@ mysqld_get_one_option(int optid, return 1; #endif opt_disable_networking=1; - mysqld_port=0; + mysqld_port= mysqld_extra_port= 0; break; case (int) OPT_SKIP_SHOW_DB: opt_skip_show_db=1; @@ -8424,9 +8765,9 @@ mysqld_get_one_option(int optid, case OPT_MASTER_PASSWORD: case OPT_MASTER_PORT: case OPT_MASTER_CONNECT_RETRY: - case OPT_MASTER_SSL: + case OPT_MASTER_SSL: case OPT_MASTER_SSL_KEY: - case OPT_MASTER_SSL_CERT: + case OPT_MASTER_SSL_CERT: case OPT_MASTER_SSL_CAPATH: case OPT_MASTER_SSL_CIPHER: case OPT_MASTER_SSL_CA: @@ -8452,6 +8793,25 @@ mysqld_get_one_option(int optid, case OPT_BOOTSTRAP: opt_noacl=opt_bootstrap=1; break; + case OPT_LOG_SLOW_FILTER: + global_system_variables.log_slow_filter= + find_bit_type_or_exit(argument, &log_slow_filter_typelib, + opt->name, &error); + /* + If we are using filters, we set opt_slow_admin_statements to be always + true so we can maintain everything with filters + */ + opt_log_slow_admin_statements= 1; + if (error) + return 1; + break; + case OPT_LOG_SLOW_VERBOSITY: + global_system_variables.log_slow_verbosity= + find_bit_type_or_exit(argument, &log_slow_verbosity_typelib, + opt->name, &error); + if (error) + return 1; + break; case OPT_SERVER_ID: server_id_supplied = 1; break; @@ -8470,15 +8830,12 @@ mysqld_get_one_option(int optid, else { int type; - type= find_type_or_exit(argument, &delay_key_write_typelib, opt->name); - delay_key_write_options= (uint) type-1; + LINT_INIT(type); + + if (!find_opt_type(argument, &delay_key_write_typelib, opt->name, &type)) + delay_key_write_options= (uint) type-1; } break; - case OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE: - sql_print_warning("--myisam_max_extra_sort_file_size is deprecated and " - "does nothing in this version. It will be removed in " - "a future release."); - break; case OPT_CHARSETS_DIR: strmake(mysql_charsets_dir, argument, sizeof(mysql_charsets_dir)-1); charsets_dir = mysql_charsets_dir; @@ -8486,8 +8843,10 @@ mysqld_get_one_option(int optid, case OPT_TX_ISOLATION: { int type; - type= find_type_or_exit(argument, &tx_isolation_typelib, opt->name); - global_system_variables.tx_isolation= (type-1); + LINT_INIT(type); + + if (!find_opt_type(argument, &tx_isolation_typelib, opt->name, &type)) + global_system_variables.tx_isolation= (type-1); break; } #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE @@ -8516,8 +8875,8 @@ mysqld_get_one_option(int optid, break; case OPT_NDB_DISTRIBUTION: int id; - id= find_type_or_exit(argument, &ndb_distribution_typelib, opt->name); - opt_ndb_distribution_id= (enum ndb_distribution)(id-1); + if (!find_opt_type(argument, &ndb_distribution_typelib, opt->name, &id)) + opt_ndb_distribution_id= (enum ndb_distribution)(id-1); break; case OPT_NDB_EXTRA_LOGGING: if (!argument) @@ -8530,26 +8889,31 @@ mysqld_get_one_option(int optid, #endif case OPT_MYISAM_RECOVER: { - if (!argument) - { - myisam_recover_options= HA_RECOVER_DEFAULT; - myisam_recover_options_str= myisam_recover_typelib.type_names[0]; - } - else if (!argument[0]) + if (argument && (!argument[0] || + my_strcasecmp(system_charset_info, argument, "OFF") == 0)) { myisam_recover_options= HA_RECOVER_NONE; myisam_recover_options_str= "OFF"; + ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED; } else { - myisam_recover_options_str=argument; - myisam_recover_options= - find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name, - &error); - if (error) - return 1; + if (!argument) + { + myisam_recover_options= HA_RECOVER_DEFAULT; + myisam_recover_options_str= myisam_recover_typelib.type_names[0]; + } + else + { + myisam_recover_options_str=argument; + myisam_recover_options= + find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name, + &error); + if (error) + return 1; + } + ha_open_options|=HA_OPEN_ABORT_IF_CRASHED; } - ha_open_options|=HA_OPEN_ABORT_IF_CRASHED; break; } case OPT_CONCURRENT_INSERT: @@ -8560,32 +8924,34 @@ mysqld_get_one_option(int optid, myisam_concurrent_insert= 0; /* --skip-concurrent-insert */ break; case OPT_TC_HEURISTIC_RECOVER: - tc_heuristic_recover= find_type_or_exit(argument, - &tc_heuristic_recover_typelib, - opt->name); + find_opt_type(argument, &tc_heuristic_recover_typelib, + opt->name, (int*) &tc_heuristic_recover); break; case OPT_MYISAM_STATS_METHOD: { ulong method_conv; int method; LINT_INIT(method_conv); + LINT_INIT(method); myisam_stats_method_str= argument; - method= find_type_or_exit(argument, &myisam_stats_method_typelib, - opt->name); - switch (method-1) { - case 2: - method_conv= MI_STATS_METHOD_IGNORE_NULLS; - break; - case 1: - method_conv= MI_STATS_METHOD_NULLS_EQUAL; - break; - case 0: - default: - method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL; - break; + if (!find_opt_type(argument, &myisam_stats_method_typelib, + opt->name, &method)) + { + switch (method-1) { + case 2: + method_conv= MI_STATS_METHOD_IGNORE_NULLS; + break; + case 1: + method_conv= MI_STATS_METHOD_NULLS_EQUAL; + break; + case 0: + default: + method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL; + break; + } + global_system_variables.myisam_stats_method= method_conv; } - global_system_variables.myisam_stats_method= method_conv; break; } case OPT_SQL_MODE: @@ -8623,13 +8989,16 @@ mysqld_get_one_option(int optid, break; } case OPT_ONE_THREAD: - global_system_variables.thread_handling= - SCHEDULER_ONE_THREAD_PER_CONNECTION; + global_system_variables.thread_handling= SCHEDULER_NO_THREADS; + opt_thread_handling= thread_handling_typelib.type_names[global_system_variables.thread_handling]; break; case OPT_THREAD_HANDLING: { - global_system_variables.thread_handling= - find_type_or_exit(argument, &thread_handling_typelib, opt->name)-1; + int id; + LINT_INIT(id); + if (!find_opt_type(argument, &thread_handling_typelib, opt->name, &id)) + global_system_variables.thread_handling= id - 1; + opt_thread_handling= thread_handling_typelib.type_names[global_system_variables.thread_handling]; break; } case OPT_FT_BOOLEAN_SYNTAX: @@ -8649,6 +9018,10 @@ mysqld_get_one_option(int optid, lower_case_table_names= argument ? atoi(argument) : 1; lower_case_table_names_used= 1; break; + case OPT_TEST_IGNORE_WRONG_OPTIONS: + /* Used for testing options */ + opt_ignore_wrong_options= 1; + break; #if defined(ENABLED_DEBUG_SYNC) case OPT_DEBUG_SYNC_TIMEOUT: /* @@ -8777,6 +9150,8 @@ static int get_options(int *argc,char **argv) /* Set global slave_exec_mode from its option */ fix_slave_exec_mode(); + global_system_variables.log_slow_filter= + fix_log_slow_filter(global_system_variables.log_slow_filter); #ifndef EMBEDDED_LIBRARY if (mysqld_chroot) set_root(mysqld_chroot); @@ -8793,12 +9168,14 @@ static int get_options(int *argc,char **argv) In most cases the global variables will not be used */ my_disable_locking= myisam_single_user= test(opt_external_locking == 0); + my_disable_sync= opt_sync == 0; my_default_record_cache_size=global_system_variables.read_buff_size; myisam_max_temp_length= (my_off_t) global_system_variables.myisam_max_sort_file_size; /* Set global variables based on startup options */ myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size); + my_crc_dbug_check= opt_my_crc_dbug_check; /* long_query_time is in microseconds */ global_system_variables.long_query_time= max_system_variables.long_query_time= @@ -8817,14 +9194,19 @@ static int get_options(int *argc,char **argv) #ifdef EMBEDDED_LIBRARY one_thread_scheduler(&thread_scheduler); + one_thread_scheduler(&extra_thread_scheduler); #else if (global_system_variables.thread_handling <= SCHEDULER_ONE_THREAD_PER_CONNECTION) - one_thread_per_connection_scheduler(&thread_scheduler); + one_thread_per_connection_scheduler(&thread_scheduler, &max_connections, + &connection_count); else if (global_system_variables.thread_handling == SCHEDULER_NO_THREADS) one_thread_scheduler(&thread_scheduler); else pool_of_threads_scheduler(&thread_scheduler); /* purecov: tested */ + one_thread_per_connection_scheduler(&extra_thread_scheduler, + &extra_max_connections, + &extra_connection_count); #endif return 0; } @@ -8918,23 +9300,22 @@ bool is_secure_file_path(char *path) /* The supplied file path might have been a file and not a directory. */ - int length= (int)dirname_length(path); - if (length >= FN_REFLEN) - return FALSE; + size_t length= dirname_length(path); // Guaranteed to be < FN_REFLEN memcpy(buff2, path, length); buff2[length]= '\0'; if (length == 0 || my_realpath(buff1, buff2, 0)) return FALSE; } convert_dirname(buff2, buff1, NullS); - if (strncmp(opt_secure_file_priv, buff2, strlen(opt_secure_file_priv))) - return FALSE; - return TRUE; + return is_prefix(buff2, opt_secure_file_priv) ? TRUE : FALSE; } + static int fix_paths(void) { char buff[FN_REFLEN],*pos; + DBUG_ENTER("fix_paths"); + convert_dirname(mysql_home,mysql_home,NullS); /* Resolve symlinks to allow 'mysql_home' to be a relative symlink */ my_realpath(mysql_home,mysql_home,MYF(0)); @@ -8979,41 +9360,41 @@ static int fix_paths(void) charsets_dir=mysql_charsets_dir; if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir)) - return 1; + DBUG_RETURN(1); #ifdef HAVE_REPLICATION if (!slave_load_tmpdir) { if (!(slave_load_tmpdir = (char*) my_strdup(mysql_tmpdir, MYF(MY_FAE)))) - return 1; + DBUG_RETURN(1); } #endif /* HAVE_REPLICATION */ /* Convert the secure-file-priv option to system format, allowing a quick strcmp to check if read or write is in an allowed dir - */ + */ if (opt_secure_file_priv) { if (*opt_secure_file_priv == 0) { + /* For easy check later */ + my_free(opt_secure_file_priv, MYF(0)); opt_secure_file_priv= 0; } else { - if (strlen(opt_secure_file_priv) >= FN_REFLEN) - opt_secure_file_priv[FN_REFLEN-1]= '\0'; + char *secure_file_real_path; if (my_realpath(buff, opt_secure_file_priv, 0)) { sql_print_warning("Failed to normalize the argument for --secure-file-priv."); - return 1; + DBUG_RETURN(1); } - char *secure_file_real_path= (char *)my_malloc(FN_REFLEN, MYF(MY_FAE)); + secure_file_real_path= (char *)my_malloc(FN_REFLEN, MYF(MY_FAE)); convert_dirname(secure_file_real_path, buff, NullS); my_free(opt_secure_file_priv, MYF(0)); opt_secure_file_priv= secure_file_real_path; } } - - return 0; + DBUG_RETURN(0); } @@ -9115,12 +9496,9 @@ skip: ; @param dir_name Directory to test - @retval - -1 Don't know (Test failed) - @retval - 0 File system is case sensitive - @retval - 1 File system is case insensitive + @retval -1 Don't know (Test failed) + @retval 0 File system is case sensitive + @retval 1 File system is case insensitive */ static int test_if_case_insensitive(const char *dir_name) |