diff options
Diffstat (limited to 'sql/mysqld.cc')
-rw-r--r-- | sql/mysqld.cc | 577 |
1 files changed, 359 insertions, 218 deletions
diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d3cada2405f..4b722479516 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2,8 +2,7 @@ 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. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -32,9 +31,7 @@ #include "../storage/maria/ha_maria.h" #endif -#ifdef HAVE_ROW_BASED_REPLICATION #include "rpl_injector.h" -#endif #ifdef WITH_INNOBASE_STORAGE_ENGINE #define OPT_INNODB_DEFAULT 1 @@ -54,6 +51,10 @@ #define OPT_NDBCLUSTER_DEFAULT 0 #endif +#ifndef DEFAULT_SKIP_THREAD_PRIORITY +#define DEFAULT_SKIP_THREAD_PRIORITY 0 +#endif + #include <thr_alarm.h> #include <ft_global.h> #include <errmsg.h> @@ -62,10 +63,6 @@ #define mysqld_charset &my_charset_latin1 -#ifndef DBUG_OFF -#define ONE_THREAD -#endif - #ifdef HAVE_purify #define IF_PURIFY(A,B) (A) #else @@ -285,6 +282,16 @@ static TYPELIB tc_heuristic_recover_typelib= array_elements(tc_heuristic_recover_names)-1,"", tc_heuristic_recover_names, NULL }; + +static const char *thread_handling_names[]= +{ "one-thread-per-connection", "no-threads", "pool-of-threads", NullS}; + +TYPELIB thread_handling_typelib= +{ + array_elements(thread_handling_names) - 1, "", + thread_handling_names, NULL +}; + const char *first_keyword= "first", *binary_keyword= "BINARY"; const char *my_localhost= "localhost", *delayed_user= "DELAYED"; #if SIZEOF_OFF_T > 4 && defined(BIG_TABLES) @@ -395,6 +402,7 @@ extern my_bool innobase_log_archive, innobase_use_large_pages, innobase_use_native_aio, innobase_file_per_table, innobase_locks_unsafe_for_binlog, + innobase_rollback_on_timeout, innobase_create_status_file; extern "C" { extern ulong srv_max_buf_pool_modified_pct; @@ -447,12 +455,8 @@ volatile bool mqh_used = 0; my_bool opt_noacl; my_bool sp_automatic_privileges= 1; -#ifdef HAVE_ROW_BASED_REPLICATION ulong opt_binlog_rows_event_max_size; const char *binlog_format_names[]= {"STATEMENT", "ROW", "MIXED", NullS}; -#else -const char *binlog_format_names[]= {"STATEMENT", NullS}; -#endif TYPELIB binlog_format_typelib= { array_elements(binlog_format_names)-1,"", binlog_format_names, NULL }; @@ -473,10 +477,11 @@ ulong what_to_log; ulong query_buff_size, slow_launch_time, slave_open_temp_tables; ulong open_files_limit, max_binlog_size, max_relay_log_size; ulong slave_net_timeout, slave_trans_retries; -ulong thread_cache_size=0, binlog_cache_size=0, max_binlog_cache_size=0; +ulong thread_cache_size=0, thread_pool_size= 0; +ulong binlog_cache_size=0, max_binlog_cache_size=0; ulong query_cache_size=0; ulong refresh_version, flush_version; /* Increments on each reload */ -query_id_t query_id; +query_id_t global_query_id; ulong aborted_threads, aborted_connects; ulong delayed_insert_timeout, delayed_insert_limit, delayed_queue_size; ulong delayed_insert_threads, delayed_insert_writes, delayed_rows_in_use; @@ -508,7 +513,8 @@ ulong rpl_recovery_rank=0; const char *log_output_str= "TABLE"; double log_10[32]; /* 10 potences */ -time_t start_time; +double log_01[32]; +time_t server_start_time; char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30]; char *default_tz_name; @@ -524,17 +530,19 @@ key_map key_map_full(0); // Will be initialized later const char *opt_date_time_formats[3]; char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home; -struct passwd *user_info; char server_version[SERVER_VERSION_LENGTH]; 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 *maria_stats_method_str="nulls_unequal"; + /* name of reference on left espression in rewritten IN subquery */ const char *in_left_expr_name= "<left expr>"; /* name of additional condition */ const char *in_additional_cond= "<IN COND>"; +const char *in_having_cond= "<IN HAVING>"; + my_decimal decimal_zero; /* classes for comparation parsing/processing */ Eq_creator eq_creator; @@ -544,7 +552,6 @@ Lt_creator lt_creator; Ge_creator ge_creator; Le_creator le_creator; - FILE *bootstrap_file; int bootstrap_error; FILE *stderror_file=0; @@ -565,7 +572,6 @@ CHARSET_INFO *system_charset_info, *files_charset_info ; CHARSET_INFO *national_charset_info, *table_alias_charset; CHARSET_INFO *character_set_filesystem; -SHOW_COMP_OPTION have_row_based_replication; SHOW_COMP_OPTION have_openssl, have_symlink, have_dlopen, have_query_cache; SHOW_COMP_OPTION have_geometry, have_rtree_keys; SHOW_COMP_OPTION have_crypt, have_compress; @@ -628,9 +634,13 @@ static char **defaults_argv; static char *opt_bin_logname; static my_socket unix_sock,ip_sock; -static pthread_t select_thread; struct rand_struct sql_rand; // used by sql_class.cc:THD::THD() +#ifndef EMBEDDED_LIBRARY +struct passwd *user_info; +static pthread_t select_thread; +#endif + /* OS specific variables */ #ifdef __WIN__ @@ -683,6 +693,8 @@ my_bool opt_enable_shared_memory; HANDLE smem_event_connect_request= 0; #endif +scheduler_functions thread_scheduler; + #define SSL_VARS_NOT_STATIC #include "sslopt-vars.h" #ifdef HAVE_OPENSSL @@ -707,7 +719,6 @@ struct st_VioSSLFd *ssl_acceptor_fd; /* Function declarations */ -static void start_signal_handler(void); pthread_handler_t signal_hand(void *arg); static void mysql_init_variables(void); static void get_options(int argc,char **argv); @@ -718,7 +729,6 @@ static void fix_paths(void); pthread_handler_t handle_connections_sockets(void *arg); pthread_handler_t kill_server_thread(void *arg); static void bootstrap(FILE *file); -static void close_server_sock(); static bool read_init_file(char *file_name); #ifdef __NT__ pthread_handler_t handle_connections_namedpipes(void *arg); @@ -729,11 +739,17 @@ pthread_handler_t handle_connections_shared_memory(void *arg); pthread_handler_t handle_slave(void *arg); static ulong find_bit_type(const char *x, TYPELIB *bit_lib); static void clean_up(bool print_message); +static int test_if_case_insensitive(const char *dir_name); + +#ifndef EMBEDDED_LIBRARY +static void start_signal_handler(void); +static void close_server_sock(); static void clean_up_mutexes(void); static void wait_for_signal_thread_to_end(void); -static int test_if_case_insensitive(const char *dir_name); static void create_pid_file(); static void end_ssl(); +#endif + #ifndef EMBEDDED_LIBRARY /**************************************************************************** @@ -859,6 +875,7 @@ static void close_connections(void) continue; tmp->killed= THD::KILL_CONNECTION; + thread_scheduler.post_kill_notification(tmp); if (tmp->mysys_var) { tmp->mysys_var->abort=1; @@ -923,7 +940,6 @@ static void close_connections(void) DBUG_PRINT("quit",("close_connections thread")); DBUG_VOID_RETURN; } -#endif /*EMBEDDED_LIBRARY*/ static void close_server_sock() @@ -966,12 +982,14 @@ static void close_server_sock() #endif } +#endif /*EMBEDDED_LIBRARY*/ + void kill_mysql(void) { DBUG_ENTER("kill_mysql"); -#ifdef SIGNALS_DONT_BREAK_READ +#if defined(SIGNALS_DONT_BREAK_READ) && !defined(EMBEDDED_LIBRARY) abort_loop=1; // Break connection loops close_server_sock(); // Force accept to wake up #endif @@ -1049,7 +1067,7 @@ static void __cdecl kill_server(int sig_ptr) kill_in_progress=TRUE; abort_loop=1; // This should be set if (sig != 0) // 0 is not a valid signal number - my_sigset(sig,SIG_IGN); + my_sigset(sig, SIG_IGN); /* purify inspected */ if (sig == MYSQL_KILL_SIGNAL || sig == 0) sql_print_information(ER(ER_NORMAL_SHUTDOWN),my_progname); else @@ -1173,9 +1191,7 @@ void clean_up(bool print_message) what they have that is dependent on the binlog */ ha_binlog_end(current_thd); -#ifdef HAVE_ROW_BASED_REPLICATION injector::free_instance(); -#endif mysql_bin_log.cleanup(); #ifdef HAVE_REPLICATION @@ -1185,6 +1201,7 @@ void clean_up(bool print_message) my_tz_free(); my_database_names_free(); #ifndef NO_EMBEDDED_ACCESS_CHECKS + servers_free(1); acl_free(1); grant_free(); #endif @@ -1238,7 +1255,9 @@ void clean_up(bool print_message) #endif delete binlog_filter; delete rpl_filter; +#ifndef EMBEDDED_LIBRARY end_ssl(); +#endif vio_end(); #ifdef USE_REGEX my_regex_end(); @@ -1250,6 +1269,7 @@ void clean_up(bool print_message) if (!opt_bootstrap) (void) my_delete(pidfile_name,MYF(0)); // This may not always exist #endif + thread_scheduler.end(); finish_client_errs(); my_free((gptr) my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST), MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR)); @@ -1271,6 +1291,8 @@ void clean_up(bool print_message) } /* clean_up */ +#ifndef EMBEDDED_LIBRARY + /* This is mainly needed when running with purify, but it's still nice to know that all child threads have died when mysqld exits @@ -1341,6 +1363,9 @@ static void clean_up_mutexes() (void) pthread_cond_destroy(&COND_manager); } +#endif /*EMBEDDED_LIBRARY*/ + + /**************************************************************************** ** Init IP and UNIX socket ****************************************************************************/ @@ -1375,7 +1400,7 @@ static void set_ports() static struct passwd *check_user(const char *user) { #if !defined(__WIN__) && !defined(__NETWARE__) - struct passwd *user_info; + struct passwd *tmp_user_info; uid_t user_id= geteuid(); // Don't bother if we aren't superuser @@ -1383,12 +1408,14 @@ static struct passwd *check_user(const char *user) { if (user) { - // Don't give a warning, if real user is same as given with --user - user_info= getpwnam(user); - if ((!user_info || user_id != user_info->pw_uid) && + /* Don't give a warning, if real user is same as given with --user */ + /* purecov: begin tested */ + tmp_user_info= getpwnam(user); + if ((!tmp_user_info || user_id != tmp_user_info->pw_uid) && global_system_variables.log_warnings) sql_print_warning( "One can only use the --user switch if running as root\n"); + /* purecov: end */ } return NULL; } @@ -1401,23 +1428,22 @@ static struct passwd *check_user(const char *user) } return NULL; } + /* purecov: begin tested */ if (!strcmp(user,"root")) return NULL; // Avoid problem with dynamic libraries - if (!(user_info= getpwnam(user))) + if (!(tmp_user_info= getpwnam(user))) { // Allow a numeric uid to be used const char *pos; for (pos= user; my_isdigit(mysqld_charset,*pos); pos++) ; if (*pos) // Not numeric id goto err; - if (!(user_info= getpwuid(atoi(user)))) + if (!(tmp_user_info= getpwuid(atoi(user)))) goto err; - else - return user_info; } - else - return user_info; + return tmp_user_info; + /* purecov: end */ err: sql_print_error("Fatal error: Can't change to run as user '%s' ; Please check that the user exists!\n",user); @@ -1426,10 +1452,11 @@ err: return NULL; } -static void set_user(const char *user, struct passwd *user_info) +static void set_user(const char *user, struct passwd *user_info_arg) { + /* purecov: begin tested */ #if !defined(__WIN__) && !defined(__NETWARE__) - DBUG_ASSERT(user_info != 0); + DBUG_ASSERT(user_info_arg != 0); #ifdef HAVE_INITGROUPS /* We can get a SIGSEGV when calling initgroups() on some systems when NSS @@ -1438,33 +1465,34 @@ static void set_user(const char *user, struct passwd *user_info) output a specific message to help the user resolve this problem. */ calling_initgroups= TRUE; - initgroups((char*) user, user_info->pw_gid); + initgroups((char*) user, user_info_arg->pw_gid); calling_initgroups= FALSE; #endif - if (setgid(user_info->pw_gid) == -1) + if (setgid(user_info_arg->pw_gid) == -1) { sql_perror("setgid"); unireg_abort(1); } - if (setuid(user_info->pw_uid) == -1) + if (setuid(user_info_arg->pw_uid) == -1) { sql_perror("setuid"); unireg_abort(1); } #endif + /* purecov: end */ } -static void set_effective_user(struct passwd *user_info) +static void set_effective_user(struct passwd *user_info_arg) { #if !defined(__WIN__) && !defined(__NETWARE__) - DBUG_ASSERT(user_info != 0); - if (setregid((gid_t)-1, user_info->pw_gid) == -1) + DBUG_ASSERT(user_info_arg != 0); + if (setregid((gid_t)-1, user_info_arg->pw_gid) == -1) { sql_perror("setregid"); unireg_abort(1); } - if (setreuid((uid_t)-1, user_info->pw_uid) == -1) + if (setreuid((uid_t)-1, user_info_arg->pw_uid) == -1) { sql_perror("setreuid"); unireg_abort(1); @@ -1501,6 +1529,9 @@ static void network_init(void) DBUG_ENTER("network_init"); LINT_INIT(ret); + if (thread_scheduler.init()) + unireg_abort(1); /* purecov: inspected */ + set_ports(); if (mysqld_port != 0 && !opt_disable_networking && !opt_bootstrap) @@ -1719,21 +1750,55 @@ extern "C" sig_handler end_thread_signal(int sig __attribute__((unused))) if (thd && ! thd->bootstrap) { statistic_increment(killed_threads, &LOCK_status); - end_thread(thd,0); + thread_scheduler.end_thread(thd,0); /* purecov: inspected */ } DBUG_VOID_RETURN; /* purecov: deadcode */ } -void end_thread(THD *thd, bool put_in_cache) +/* + Unlink thd from global list of available connections and free thd + + SYNOPSIS + unlink_thd() + thd Thread handler + + NOTES + LOCK_thread_count is locked and left locked +*/ + +void unlink_thd(THD *thd) { - DBUG_ENTER("end_thread"); + DBUG_ENTER("unlink_thd"); + DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd)); thd->cleanup(); (void) pthread_mutex_lock(&LOCK_thread_count); thread_count--; delete thd; + DBUG_VOID_RETURN; +} - if (put_in_cache && cached_thread_count < thread_cache_size && + +/* + Store thread in cache for reuse by new connections + + SYNOPSIS + cache_thread() + + NOTES + LOCK_thread_count has to be locked + + RETURN + 0 Thread was not put in cache + 1 Thread is to be reused by new connection. + (ie, caller should return, not abort with pthread_exit()) +*/ + + +static bool cache_thread() +{ + safe_mutex_assert_owner(&LOCK_thread_count); + if (cached_thread_count < thread_cache_size && ! abort_loop && !kill_cached_threads) { /* Don't kill the thread, just put it in cache for reuse */ @@ -1746,31 +1811,56 @@ void end_thread(THD *thd, bool put_in_cache) pthread_cond_signal(&COND_flush_thread_cache); if (wake_thread) { + THD *thd; wake_thread--; - thd=thread_cache.get(); - thd->real_id=pthread_self(); + thd= thread_cache.get(); thd->thread_stack= (char*) &thd; // For store_globals (void) thd->store_globals(); thd->thr_create_time= time(NULL); threads.append(thd); - pthread_mutex_unlock(&LOCK_thread_count); - DBUG_VOID_RETURN; + return(1); } } + return(0); +} + + +/* + End thread for the current connection + + SYNOPSIS + one_thread_per_connection_end() + thd Thread handler + put_in_cache Store thread in cache, if there is room in it + Normally this is true in all cases except when we got + out of resources initializing the current thread + + NOTES + If thread is cached, we will wait until thread is scheduled to be + reused and then we will return. + If thread is not cached, we end the thread. + + RETURN + 0 Signal to handle_one_connection to reuse connection +*/ + +bool one_thread_per_connection_end(THD *thd, bool put_in_cache) +{ + DBUG_ENTER("one_thread_per_connection_end"); + unlink_thd(thd); + if (put_in_cache) + put_in_cache= cache_thread(); + pthread_mutex_unlock(&LOCK_thread_count); + if (put_in_cache) + DBUG_RETURN(0); // Thread is reused - /* Tell main we are ready */ - (void) pthread_mutex_unlock(&LOCK_thread_count); /* It's safe to broadcast outside a lock (COND... is not deleted here) */ DBUG_PRINT("signal", ("Broadcasting COND_thread_count")); (void) pthread_cond_broadcast(&COND_thread_count); -#ifdef ONE_THREAD - if (!(test_flags & TEST_NO_THREADS)) // For debugging under Linux -#endif - { - my_thread_end(); - pthread_exit(0); - } - DBUG_VOID_RETURN; + + my_thread_end(); + pthread_exit(0); + DBUG_RETURN(0); // Impossible } @@ -1805,6 +1895,7 @@ extern "C" sig_handler abort_thread(int sig __attribute__((unused))) } #endif + /****************************************************************************** Setup a signal thread with handles all signals. Because Linux doesn't support schemas use a mutex to check that @@ -1824,6 +1915,7 @@ static void init_signals(void) #endif } + static void start_signal_handler(void) { // Save vm id of this process @@ -1831,6 +1923,7 @@ static void start_signal_handler(void) create_pid_file(); } + static void check_data_home(const char *path) {} @@ -2051,6 +2144,7 @@ static void init_signals(void) } + static void start_signal_handler(void) { // Save vm id of this process @@ -2107,14 +2201,15 @@ 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_connections=%lu\n", max_connections); + fprintf(stderr, "max_threads=%u\n", thread_scheduler.max_threads); 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_connections = %lu K\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) * - max_connections)/ 1024); + thread_scheduler.max_threads + + 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) @@ -2187,6 +2282,8 @@ bugs.\n"); #define SA_NODEFER 0 #endif +#ifndef EMBEDDED_LIBRARY + static void init_signals(void) { sigset_t set; @@ -2259,7 +2356,6 @@ static void init_signals(void) } -#ifndef EMBEDDED_LIBRARY static void start_signal_handler(void) { int error; @@ -2314,7 +2410,7 @@ 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(max_connections + + init_thr_alarm(thread_scheduler.max_threads + global_system_variables.max_insert_delayed_threads + 10); #if SIGINT != THR_KILL_SIGNAL if (test_flags & TEST_SIGINT) @@ -2433,11 +2529,11 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused))) } return(0); /* purecov: deadcode */ } -#endif /*!EMBEDDED_LIBRARY*/ static void check_data_home(const char *path) {} +#endif /*!EMBEDDED_LIBRARY*/ #endif /* __WIN__*/ @@ -2502,6 +2598,7 @@ static int my_message_sql(uint error, const char *str, myf MyFlags) } +#ifndef EMBEDDED_LIBRARY static void *my_str_malloc_mysqld(size_t size) { return my_malloc(size, MYF(MY_FAE)); @@ -2512,22 +2609,11 @@ static void my_str_free_mysqld(void *ptr) { my_free((gptr)ptr, MYF(MY_FAE)); } +#endif /* EMBEDDED_LIBRARY */ #ifdef __WIN__ -struct utsname -{ - char nodename[FN_REFLEN]; -}; - - -int uname(struct utsname *a) -{ - return -1; -} - - pthread_handler_t handle_shutdown(void *arg) { MSG msg; @@ -2618,7 +2704,15 @@ static int init_common_variables(const char *conf_file_name, int argc, tzset(); // Set tzname max_system_variables.pseudo_thread_id= (ulong)~0; - start_time=time((time_t*) 0); + server_start_time= time((time_t*) 0); + rpl_filter= new Rpl_filter; + binlog_filter= new Rpl_filter; + if (!rpl_filter || !binlog_filter) + { + sql_perror("Could not allocate replication and binlog filters"); + exit(1); + } + if (init_thread_environment()) return 1; mysql_init_variables(); @@ -2626,7 +2720,7 @@ static int init_common_variables(const char *conf_file_name, int argc, #ifdef HAVE_TZNAME { struct tm tm_tmp; - localtime_r(&start_time,&tm_tmp); + localtime_r(&server_start_time,&tm_tmp); strmake(system_time_zone, tzname[tm_tmp.tm_isdst != 0 ? 1 : 0], sizeof(system_time_zone)-1); @@ -3016,6 +3110,8 @@ static void openssl_lock(int mode, openssl_lock_t *lock, const char *file, #endif /* HAVE_OPENSSL */ +#ifndef EMBEDDED_LIBRARY + static void init_ssl() { #ifdef HAVE_OPENSSL @@ -3053,6 +3149,8 @@ static void end_ssl() #endif /* HAVE_OPENSSL */ } +#endif /* EMBEDDED_LIBRARY */ + static int init_server_components() { @@ -3068,7 +3166,7 @@ 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) start_time,(ulong) start_time/2); + randominit(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2); reset_floating_point_exceptions(); init_thr_lock(); #ifdef HAVE_REPLICATION @@ -3171,11 +3269,7 @@ with --log-bin instead."); } if (global_system_variables.binlog_format == BINLOG_FORMAT_UNSPEC) { -#if defined(HAVE_ROW_BASED_REPLICATION) global_system_variables.binlog_format= BINLOG_FORMAT_MIXED; -#else - global_system_variables.binlog_format= BINLOG_FORMAT_STMT; -#endif } /* Check that we have not let the format to unspecified at this point */ @@ -3330,7 +3424,7 @@ server."); #ifdef HAVE_REPLICATION if (opt_bin_log && expire_logs_days) { - long purge_time= time(0) - expire_logs_days*24*60*60; + long purge_time= (long) (time(0) - expire_logs_days*24*60*60); if (purge_time >= 0) mysql_bin_log.purge_logs_before_date(purge_time); } @@ -3375,6 +3469,8 @@ server."); } +#ifndef EMBEDDED_LIBRARY + static void create_maintenance_thread() { if (flush_time && flush_time != ~(ulong) 0L) @@ -3388,7 +3484,6 @@ static void create_maintenance_thread() static void create_shutdown_thread() { -#if !defined(EMBEDDED_LIBRARY) #ifdef __WIN__ hEventShutdown=CreateEvent(0, FALSE, FALSE, shutdown_event_name); pthread_t hThread; @@ -3397,10 +3492,11 @@ static void create_shutdown_thread() // On "Stop Service" we have to do regular shutdown Service.SetShutdownEvent(hEventShutdown); -#endif -#endif // EMBEDDED_LIBRARY +#endif /* __WIN__ */ } +#endif /* EMBEDDED_LIBRARY */ + #if (defined(__NT__) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY) static void handle_connections_methods() @@ -3480,15 +3576,8 @@ int win_main(int argc, char **argv) int main(int argc, char **argv) #endif { - rpl_filter= new Rpl_filter; - binlog_filter= new Rpl_filter; - if (!rpl_filter || !binlog_filter) - { - sql_perror("Could not allocate replication and binlog filters"); - exit(1); - } - MY_INIT(argv[0]); // init my_sys library & pthreads + /* nothing should come before this line ^^^ */ /* Perform basic logger initialization logger. Should be called after @@ -3641,7 +3730,7 @@ we force server id to 2, but this MySQL server will not act as a slave."); error_handler_hook= my_message_sql; start_signal_handler(); // Creates pidfile - if (acl_init(opt_noacl) || + if (mysql_rm_tmp_tables() || acl_init(opt_noacl) || my_tz_init((THD *)0, default_tz_name, opt_bootstrap)) { abort_loop=1; @@ -3660,6 +3749,9 @@ we force server id to 2, but this MySQL server will not act as a slave."); if (!opt_noacl) (void) grant_init(); + if (!opt_bootstrap) + servers_init(0); + if (!opt_noacl) { #ifdef HAVE_DLOPEN @@ -3707,15 +3799,18 @@ we force server id to 2, but this MySQL server will not act as a slave."); mysqld_port, MYSQL_COMPILATION_COMMENT); - // Signal threads waiting for server to be started - mysqld_server_started= 1; - pthread_cond_signal(&COND_server_started); - if (!opt_noacl) { if (Events::get_instance()->init()) unireg_abort(1); } + + /* Signal threads waiting for server to be started */ + pthread_mutex_lock(&LOCK_server_started); + mysqld_server_started= 1; + pthread_cond_signal(&COND_server_started); + pthread_mutex_unlock(&LOCK_server_started); + #if defined(__NT__) || defined(HAVE_SMEM) handle_connections_methods(); #else @@ -3981,7 +4076,7 @@ static void bootstrap(FILE *file) my_net_init(&thd->net,(st_vio*) 0); thd->max_client_packet_length= thd->net.max_packet; thd->security_ctx->master_access= ~(ulong)0; - thd->thread_id=thread_id++; + thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; thread_count++; bootstrap_file=file; @@ -4024,6 +4119,74 @@ static bool read_init_file(char *file_name) #ifndef EMBEDDED_LIBRARY + +/* + Simple scheduler that use the main thread to handle the request + + NOTES + This is only used for debugging, when starting mysqld with + --thread-handling=no-threads or --one-thread + + 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); + (void) pthread_mutex_unlock(&LOCK_thread_count); + handle_one_connection((void*) thd); +} + + +/* + Scheduler that uses one thread per connection +*/ + +void create_thread_to_handle_connection(THD *thd) +{ + if (cached_thread_count > wake_thread) + { + /* Get thread from cache */ + thread_cache.append(thd); + wake_thread++; + pthread_cond_signal(&COND_thread_cache); + } + else + { + /* Create new thread to handle connection */ + int error; + thread_created++; + threads.append(thd); + DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id)); + thd->connect_time = time(NULL); + if ((error=pthread_create(&thd->real_id,&connection_attrib, + handle_one_connection, + (void*) thd))) + { + /* purify: begin inspected */ + DBUG_PRINT("error", + ("Can't create thread to handle request (error %d)", + error)); + thread_count--; + thd->killed= THD::KILL_CONNECTION; // Safety + (void) pthread_mutex_unlock(&LOCK_thread_count); + statistic_increment(aborted_connects,&LOCK_status); + net_printf_error(thd, ER_CANT_CREATE_THREAD, error); + (void) pthread_mutex_lock(&LOCK_thread_count); + close_connection(thd,0,0); + delete thd; + (void) pthread_mutex_unlock(&LOCK_thread_count); + return; + /* purecov: end */ + } + } + (void) pthread_mutex_unlock(&LOCK_thread_count); + DBUG_PRINT("info",("Thread created")); +} + + /* Create new thread to handle incoming connection. @@ -4045,10 +4208,9 @@ static bool read_init_file(char *file_name) static void create_new_thread(THD *thd) { + NET *net=&thd->net; DBUG_ENTER("create_new_thread"); - NET *net=&thd->net; // For easy ref - net->read_timeout = (uint) connect_timeout; if (protocol_version > 9) net->return_errno=1; @@ -4061,64 +4223,15 @@ static void create_new_thread(THD *thd) DBUG_VOID_RETURN; } pthread_mutex_lock(&LOCK_thread_count); - thd->thread_id=thread_id++; - - thd->real_id=pthread_self(); // Keep purify happy + thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; /* Start a new thread to handle connection */ thread_count++; -#ifdef ONE_THREAD - if (test_flags & TEST_NO_THREADS) // For debugging under Linux - { - thread_cache_size=0; // Safety - threads.append(thd); - thd->real_id=pthread_self(); - (void) pthread_mutex_unlock(&LOCK_thread_count); - handle_one_connection((void*) thd); - } - else -#endif - { - if (thread_count-delayed_insert_threads > max_used_connections) - max_used_connections=thread_count-delayed_insert_threads; - - if (cached_thread_count > wake_thread) - { - thread_cache.append(thd); - wake_thread++; - pthread_cond_signal(&COND_thread_cache); - } - else - { - int error; - thread_created++; - threads.append(thd); - DBUG_PRINT("info",(("creating thread %lu"), 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= THD::KILL_CONNECTION; // Safety - (void) pthread_mutex_unlock(&LOCK_thread_count); - statistic_increment(aborted_connects,&LOCK_status); - net_printf_error(thd, ER_CANT_CREATE_THREAD, error); - (void) pthread_mutex_lock(&LOCK_thread_count); - close_connection(thd,0,0); - delete thd; - (void) pthread_mutex_unlock(&LOCK_thread_count); - DBUG_VOID_RETURN; - } - } - (void) pthread_mutex_unlock(&LOCK_thread_count); + if (thread_count - delayed_insert_threads > max_used_connections) + max_used_connections= thread_count - delayed_insert_threads; - } - DBUG_PRINT("info",("Thread created")); + thread_scheduler.add_connection(thd); DBUG_VOID_RETURN; } #endif /* EMBEDDED_LIBRARY */ @@ -4342,12 +4455,7 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused))) } if (sock == unix_sock) thd->security_ctx->host=(char*) my_localhost; -#ifdef __WIN__ - /* Set default wait_timeout */ - ulong wait_timeout= global_system_variables.net_wait_timeout * 1000; - (void) setsockopt(new_sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&wait_timeout, - sizeof(wait_timeout)); -#endif + create_new_thread(thd); } @@ -4713,9 +4821,7 @@ enum options_mysqld #ifndef DBUG_OFF OPT_BINLOG_SHOW_XID, #endif -#ifdef HAVE_ROW_BASED_REPLICATION OPT_BINLOG_ROWS_EVENT_MAX_SIZE, -#endif OPT_WANT_CORE, OPT_CONCURRENT_INSERT, OPT_MEMLOCK, OPT_MYISAM_RECOVER, OPT_REPLICATE_REWRITE_DB, OPT_SERVER_ID, @@ -4740,8 +4846,8 @@ enum options_mysqld OPT_LOG_BIN_TRUST_FUNCTION_CREATORS, OPT_SAFE_SHOW_DB, OPT_INNODB_SAFE_BINLOG, OPT_INNODB, OPT_ISAM, - OPT_ENGINE_CONDITION_PUSHDOWN, - OPT_NDBCLUSTER, OPT_NDB_CONNECTSTRING, OPT_NDB_USE_EXACT_COUNT, + OPT_ENGINE_CONDITION_PUSHDOWN, OPT_NDBCLUSTER, 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, OPT_NDB_MGMD, OPT_NDB_NODEID, @@ -4881,7 +4987,9 @@ enum options_mysqld OPT_PORT_OPEN_TIMEOUT, OPT_GENERAL_LOG, OPT_SLOW_LOG, - OPT_MERGE + OPT_MERGE, + OPT_THREAD_HANDLING, + OPT_INNODB_ROLLBACK_ON_TIMEOUT }; @@ -4932,7 +5040,6 @@ struct my_option my_long_options[] = (gptr*) &my_bind_addr_str, (gptr*) &my_bind_addr_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"binlog_format", OPT_BINLOG_FORMAT, -#ifdef HAVE_ROW_BASED_REPLICATION "Tell the master the form of binary logging to use: either 'row' for " "row-based binary logging, or 'statement' for statement-based binary " "logging, or 'mixed'. 'mixed' is statement-based binary logging except " @@ -4942,17 +5049,8 @@ struct my_option my_long_options[] = #ifdef HAVE_NDB_BINLOG "If ndbcluster is enabled, the default is 'row'." #endif -#else - "Tell the master the form of binary logging to use: this build " - "supports only statement-based binary logging, so only 'statement' is " - "a legal value." -#endif , 0, 0, 0, GET_STR, REQUIRED_ARG, -#ifdef HAVE_ROW_BASED_REPLICATION BINLOG_FORMAT_MIXED -#else - BINLOG_FORMAT_STMT -#endif , 0, 0, 0, 0, 0 }, {"binlog-do-db", OPT_BINLOG_DO_DB, "Tells the master it should log updates for the specified database, and exclude all others not explicitly mentioned.", @@ -4960,7 +5058,6 @@ struct my_option my_long_options[] = {"binlog-ignore-db", OPT_BINLOG_IGNORE_DB, "Tells the master that updates to the given database should not be logged tothe binary log.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, -#ifdef HAVE_ROW_BASED_REPLICATION {"binlog-row-event-max-size", OPT_BINLOG_ROWS_EVENT_MAX_SIZE, "The maximum size of a row-based binary log event in bytes. Rows will be " "grouped into events smaller than this size if possible. " @@ -4972,9 +5069,10 @@ struct my_option my_long_options[] = /* sub_size */ 0, /* block_size */ 256, /* app_type */ 0 }, -#endif +#ifndef DISABLE_GRANT_OPTIONS {"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, +#endif {"character-set-client-handshake", OPT_CHARACTER_SET_CLIENT_HANDSHAKE, "Don't ignore client side character set value sent during handshake.", (gptr*) &opt_character_set_client_handshake, @@ -5068,7 +5166,7 @@ struct my_option my_long_options[] = "Push supported query conditions to the storage engine.", (gptr*) &global_system_variables.engine_condition_pushdown, (gptr*) &global_system_variables.engine_condition_pushdown, - 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, /* See how it's handled in get_one_option() */ {"event-scheduler", OPT_EVENT_SCHEDULER, "Enable/disable the event scheduler.", NULL, NULL, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, @@ -5097,9 +5195,11 @@ Disable with --skip-large-pages.", {"init-connect", OPT_INIT_CONNECT, "Command(s) that are executed for each new connection", (gptr*) &opt_init_connect, (gptr*) &opt_init_connect, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +#ifndef DISABLE_GRANT_OPTIONS {"init-file", OPT_INIT_FILE, "Read SQL commands from this file at startup.", (gptr*) &opt_init_file, (gptr*) &opt_init_file, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +#endif {"init-rpl-role", OPT_INIT_RPL_ROLE, "Set the replication role.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"init-slave", OPT_INIT_SLAVE, "Command(s) that are executed when a slave connects to this master", @@ -5174,6 +5274,10 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite, (gptr*) &srv_max_purge_lag, (gptr*) &srv_max_purge_lag, 0, GET_LONG, REQUIRED_ARG, 0, 0, ~0L, 0, 1L, 0}, + {"innodb_rollback_on_timeout", OPT_INNODB_ROLLBACK_ON_TIMEOUT, + "Roll back the complete transaction on lock wait timeout, for 4.x compatibility (disabled by default)", + (gptr*) &innobase_rollback_on_timeout, (gptr*) &innobase_rollback_on_timeout, + 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"innodb_status_file", OPT_INNODB_STATUS_FILE, "Enable SHOW INNODB STATUS output in the innodb_status.<pid> file", (gptr*) &innobase_create_status_file, (gptr*) &innobase_create_status_file, @@ -5230,11 +5334,9 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite, "If equal to 0 (the default), then when --log-bin is used, creation of " "a stored function (or trigger) is allowed only to users having the SUPER privilege " "and only if this stored function (trigger) may not break binary logging." -#ifdef HAVE_ROW_BASED_REPLICATION "Note that if ALL connections to this server ALWAYS use row-based binary " "logging, the security issues do not exist and the binary logging cannot " "break, so you can safely set this to 1." -#endif ,(gptr*) &trust_function_creators, (gptr*) &trust_function_creators, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"log-error", OPT_ERROR_LOG_FILE, "Error log file.", @@ -5439,6 +5541,17 @@ Disable with --skip-ndbcluster (will save memory).", (gptr*) &global_system_variables.ndb_use_exact_count, (gptr*) &global_system_variables.ndb_use_exact_count, 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, + {"ndb-use-transactions", OPT_NDB_USE_TRANSACTIONS, + "Use transactions for large inserts, if enabled then large " + "inserts will be split into several smaller transactions", + (gptr*) &global_system_variables.ndb_use_transactions, + (gptr*) &global_system_variables.ndb_use_transactions, + 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, + {"ndb_use_transactions", OPT_NDB_USE_TRANSACTIONS, + "same as --ndb-use-transactions.", + (gptr*) &global_system_variables.ndb_use_transactions, + (gptr*) &global_system_variables.ndb_use_transactions, + 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, {"ndb-shm", OPT_NDB_SHM, "Use shared memory connections when available.", (gptr*) &opt_ndb_shm, @@ -5483,11 +5596,9 @@ Disable with --skip-ndbcluster (will save memory).", (gptr*) &global_system_variables.old_passwords, (gptr*) &max_system_variables.old_passwords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, -#ifdef ONE_THREAD {"one-thread", OPT_ONE_THREAD, - "Only use one thread (for debugging under Linux).", 0, 0, 0, GET_NO_ARG, - NO_ARG, 0, 0, 0, 0, 0, 0}, -#endif + "(deprecated): Only use one thread (for debugging under Linux). Use thread-handling=no-threads instead", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"old-style-user-limits", OPT_OLD_STYLE_USER_LIMITS, "Enable old-style user limits (before 5.0.3 user resources were counted per each user+host vs. per account)", (gptr*) &opt_old_style_user_limits, (gptr*) &opt_old_style_user_limits, @@ -5600,10 +5711,12 @@ Can't be set to 1 if --log-slave-updates is used.", "Show user and password in SHOW SLAVE HOSTS on this master", (gptr*) &opt_show_slave_auth_info, (gptr*) &opt_show_slave_auth_info, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, +#ifndef DISABLE_GRANT_OPTIONS {"skip-grant-tables", OPT_SKIP_GRANT, "Start without grant tables. This gives all users FULL ACCESS to all tables!", (gptr*) &opt_noacl, (gptr*) &opt_noacl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, +#endif {"skip-host-cache", OPT_SKIP_HOST_CACHE, "Don't cache host names.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"skip-locking", OPT_SKIP_LOCK, @@ -5636,8 +5749,8 @@ Can't be set to 1 if --log-slave-updates is used.", {"skip-symlink", OPT_SKIP_SYMLINKS, "Don't allow symlinking of tables. Deprecated option. Use --skip-symbolic-links instead.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"skip-thread-priority", OPT_SKIP_PRIOR, - "Don't give threads different priorities.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, - 0, 0, 0, 0, 0}, + "Don't give threads different priorities.", 0, 0, 0, GET_NO_ARG, NO_ARG, + DEFAULT_SKIP_THREAD_PRIORITY, 0, 0, 0, 0, 0}, #ifdef HAVE_REPLICATION {"slave-load-tmpdir", OPT_SLAVE_LOAD_TMPDIR, "The location where the slave should put its temporary files when \ @@ -5711,6 +5824,11 @@ log and this option does nothing anymore.", 0, 0, 0, 0, 0}, {"use-symbolic-links", 's', "Enable symbolic link support. Deprecated option; use --symbolic-links instead.", (gptr*) &my_use_symdir, (gptr*) &my_use_symdir, 0, GET_BOOL, NO_ARG, + /* + The system call realpath() produces warnings under valgrind and + purify. These are not suppressed: instead we disable symlinks + option if compiled with valgrind support. + */ IF_PURIFY(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}, @@ -6002,7 +6120,7 @@ The minimum value for this variable is 4096.", // children, to avoid "too many connections" error in a common setup {"max_connections", OPT_MAX_CONNECTIONS, "The number of simultaneous clients allowed.", (gptr*) &max_connections, - (gptr*) &max_connections, 0, GET_ULONG, REQUIRED_ARG, 151, 1, 16384, 0, 1, + (gptr*) &max_connections, 0, GET_ULONG, REQUIRED_ARG, 151, 1, 100000, 0, 1, 0}, {"max_delayed_threads", OPT_MAX_DELAYED_THREADS, "Don't start more than this number of threads to handle INSERT DELAYED statements. If set to zero, which means INSERT DELAYED is not used.", @@ -6287,6 +6405,12 @@ The minimum value for this variable is 4096.", "Permits the application to give the threads system a hint for the desired number of threads that should be run at the same time.", (gptr*) &concurrency, (gptr*) &concurrency, 0, GET_ULONG, REQUIRED_ARG, DEFAULT_CONCURRENCY, 1, 512, 0, 1, 0}, +#if HAVE_POOL_OF_THREADS == 1 + {"thread_pool_size", OPT_THREAD_CACHE_SIZE, + "How many threads we should create to handle query requests in case of 'thread_handling=pool-of-threads'", + (gptr*) &thread_pool_size, (gptr*) &thread_pool_size, 0, GET_ULONG, + REQUIRED_ARG, 20, 1, 16384, 0, 1, 0}, +#endif {"thread_stack", OPT_THREAD_STACK, "The stack size for each thread.", (gptr*) &my_thread_stack_size, (gptr*) &my_thread_stack_size, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK, @@ -6311,6 +6435,10 @@ The minimum value for this variable is 4096.", (gptr*) &global_system_variables.trans_prealloc_size, (gptr*) &max_system_variables.trans_prealloc_size, 0, GET_ULONG, REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ~0L, 0, 1024, 0}, + {"thread_handling", OPT_THREAD_HANDLING, + "Define threads usage for handling queries: " + "one-thread-per-connection or no-threads", 0, 0, + 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 presence of a key of the underlying table is used in queries with a LIMIT clause for updating. 0 = NO = Prohibit update of a VIEW, which does not contain a key of the underlying table and the query uses a LIMIT clause (usually get from GUI tools).", (gptr*) &global_system_variables.updatable_views_with_limit, @@ -6343,7 +6471,7 @@ static int show_starttime(THD *thd, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; - *((long *)buff)= (long) (thd->query_start() - start_time); + *((long *)buff)= (long) (thd->query_start() - server_start_time); return 0; } @@ -7027,7 +7155,7 @@ static void mysql_init_variables(void) protocol_version= PROTOCOL_VERSION; what_to_log= ~ (1L << (uint) COM_TIME); refresh_version= flush_version= 1L; /* Increments on each reload */ - query_id= thread_id= 1L; + global_query_id= thread_id= 1L; strmov(server_version, MYSQL_SERVER_VERSION); myisam_recover_options_str= sql_mode_str= "OFF"; myisam_stats_method_str= maria_stats_method_str= "nulls_unequal"; @@ -7122,11 +7250,6 @@ static void mysql_init_variables(void) #else have_partition_db= SHOW_OPTION_NO; #endif -#ifdef HAVE_ROW_BASED_REPLICATION - have_row_based_replication= SHOW_OPTION_YES; -#else - have_row_based_replication= SHOW_OPTION_NO; -#endif #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE have_ndbcluster=SHOW_OPTION_DISABLED; global_system_variables.ndb_index_stat_enable=FALSE; @@ -7272,7 +7395,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; case 'T': test_flags= argument ? (uint) atoi(argument) : 0; - test_flags&= ~TEST_NO_THREADS; opt_endinfo=1; break; case (int) OPT_BIG_TABLES: @@ -7356,7 +7478,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), int id; if ((id= find_type(argument, &binlog_format_typelib, 2)) <= 0) { -#ifdef HAVE_ROW_BASED_REPLICATION fprintf(stderr, "Unknown binary log format: '%s' " "(should be one of '%s', '%s', '%s')\n", @@ -7364,11 +7485,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), binlog_format_names[BINLOG_FORMAT_STMT], binlog_format_names[BINLOG_FORMAT_ROW], binlog_format_names[BINLOG_FORMAT_MIXED]); -#else - fprintf(stderr, - "Unknown binary log format: '%s' (only legal value is '%s')\n", - argument, binlog_format_names[BINLOG_FORMAT_STMT]); -#endif exit(1); } global_system_variables.binlog_format= id-1; @@ -7510,11 +7626,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), opt_skip_show_db=1; opt_specialflag|=SPECIAL_SKIP_SHOW_DB; break; -#ifdef ONE_THREAD - case (int) OPT_ONE_THREAD: - test_flags |= TEST_NO_THREADS; -#endif - break; case (int) OPT_WANT_CORE: test_flags |= TEST_CORE_ON_SIGNAL; break; @@ -7759,6 +7870,23 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), sql_mode); break; } + case OPT_ONE_THREAD: + global_system_variables.thread_handling= 2; + break; + case OPT_THREAD_HANDLING: + { + if ((global_system_variables.thread_handling= + find_type(argument, &thread_handling_typelib, 2)) <= 0 || + (global_system_variables.thread_handling == SCHEDULER_POOL_OF_THREADS + && !HAVE_POOL_OF_THREADS)) + { + /* purecov: begin tested */ + fprintf(stderr,"Unknown/unsupported thread-handling: %s\n",argument); + exit(1); + /* purecov: end */ + } + break; + } case OPT_FT_BOOLEAN_SYNTAX: if (ft_boolean_check_syntax_string((byte*) argument)) { @@ -7879,6 +8007,7 @@ static void get_options(int argc,char **argv) if (mysqld_chroot) set_root(mysqld_chroot); #else + global_system_variables.thread_handling = SCHEDULER_NO_THREADS; max_allowed_packet= global_system_variables.max_allowed_packet; net_buffer_length= global_system_variables.net_buffer_length; #endif @@ -7909,6 +8038,17 @@ static void get_options(int argc,char **argv) &global_system_variables.datetime_format)) exit(1); +#ifdef EMBEDDED_LIBRARY + one_thread_scheduler(&thread_scheduler); +#else + if (global_system_variables.thread_handling <= + SCHEDULER_ONE_THREAD_PER_CONNECTION) + one_thread_per_connection_scheduler(&thread_scheduler); + else if (global_system_variables.thread_handling == SCHEDULER_NO_THREADS) + one_thread_scheduler(&thread_scheduler); + else + pool_of_threads_scheduler(&thread_scheduler); /* purecov: tested */ +#endif } @@ -8126,6 +8266,8 @@ static int test_if_case_insensitive(const char *dir_name) /* Create file to store pid number */ +#ifndef EMBEDDED_LIBRARY + static void create_pid_file() { File file; @@ -8145,7 +8287,7 @@ static void create_pid_file() sql_perror("Can't start server: can't create PID file"); exit(1); } - +#endif /* EMBEDDED_LIBRARY */ /* Clear most status variables */ void refresh_status(THD *thd) @@ -8214,7 +8356,8 @@ my_bool innobase_log_archive, innobase_use_doublewrite, innobase_use_checksums, innobase_file_per_table, - innobase_locks_unsafe_for_binlog; + innobase_locks_unsafe_for_binlog, + innobase_rollback_on_timeout; extern "C" { ulong srv_max_buf_pool_modified_pct; @@ -8248,5 +8391,3 @@ template class I_List<NAMED_LIST>; template class I_List<Statement>; template class I_List_iterator<Statement>; #endif - - |