diff options
author | Sergei Golubchik <sergii@pisem.net> | 2012-03-09 08:06:59 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2012-03-09 08:06:59 +0100 |
commit | 4933d21e5d93840ddcf41bf25ed92fbe253ae92d (patch) | |
tree | a4d892b86aa46927978f82976fff61f1e5193383 /sql | |
parent | 97ee59d27d3daca806fdb3577df5a0e0a45a0a30 (diff) | |
parent | 7009bf411a8cb9a6e035b761b5e6352b4f474303 (diff) | |
download | mariadb-git-4933d21e5d93840ddcf41bf25ed92fbe253ae92d.tar.gz |
merge with mysql-5.5.21
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.cc | 20 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 37 | ||||
-rw-r--r-- | sql/item_timefunc.h | 1 | ||||
-rw-r--r-- | sql/log_event.h | 4 | ||||
-rw-r--r-- | sql/mysqld.cc | 19 | ||||
-rw-r--r-- | sql/mysqld.h | 5 | ||||
-rw-r--r-- | sql/rpl_mi.cc | 4 | ||||
-rw-r--r-- | sql/rpl_mi.h | 4 | ||||
-rw-r--r-- | sql/rpl_rli.cc | 4 | ||||
-rw-r--r-- | sql/rpl_rli.h | 6 | ||||
-rw-r--r-- | sql/share/errmsg-utf8.txt | 16 | ||||
-rw-r--r-- | sql/slave.cc | 68 | ||||
-rw-r--r-- | sql/sp_cache.cc | 29 | ||||
-rw-r--r-- | sql/sp_cache.h | 1 | ||||
-rw-r--r-- | sql/sql_parse.cc | 2 | ||||
-rw-r--r-- | sql/sql_plugin.cc | 1 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 6 | ||||
-rw-r--r-- | sql/sql_repl.cc | 40 | ||||
-rw-r--r-- | sql/sql_udf.cc | 3 | ||||
-rw-r--r-- | sql/sys_vars.cc | 7 |
20 files changed, 184 insertions, 93 deletions
diff --git a/sql/item.cc b/sql/item.cc index de4716350c2..c4bb1a399ab 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1,5 +1,6 @@ /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. + Copyright (c) 2010, 2012, 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 @@ -8505,10 +8506,14 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item) or less than the original Item. A 0 may also be returned if out of memory. - @note We only use this on the range optimizer/partition pruning, + @note We use this in the range optimizer/partition pruning, because in some cases we can't store the value in the field without some precision/character loss. + We similarly use it to verify that expressions like + BIGINT_FIELD <cmp> <literal value> + is done correctly (as int/decimal/float according to literal type). + @todo rewrite it to use Arg_comparator (currently it's a simplified and incomplete version of it) */ @@ -8552,7 +8557,7 @@ int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) return my_time_compare(&field_time, &item_time); } - return stringcmp(field_result, item_result); + return sortcmp(field_result, item_result, field->charset()); } if (res_type == INT_RESULT) return 0; // Both are of type int @@ -8564,7 +8569,7 @@ int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) if (item->null_value) return 0; field_val= field->val_decimal(&field_buf); - return my_decimal_cmp(item_val, field_val); + return my_decimal_cmp(field_val, item_val); } /* We have to check field->cmp_type() instead of res_type, @@ -8585,10 +8590,15 @@ int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) } return my_time_compare(&field_time, &item_time); } - double result= item->val_real(); + /* + The patch for Bug#13463415 started using this function for comparing + BIGINTs. That uncovered a bug in Visual Studio 32bit optimized mode. + Prefixing the auto variables with volatile fixes the problem.... + */ + volatile double result= item->val_real(); if (item->null_value) return 0; - double field_result= field->val_real(); + volatile double field_result= field->val_real(); if (field_result < result) return -1; else if (field_result > result) diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 4ea5e9534a8..f5dc74c389c 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. - Copyright (c) 2009-2011 Monty Program Ab +/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. + Copyright (c) 2009, 2012 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 @@ -492,11 +492,22 @@ static bool convert_const_to_int(THD *thd, Item_field *field_item, orig_field_val= field->val_int(); if (!(*item)->save_in_field(field, 1) && !field->is_null()) { - Item *tmp= new Item_int_with_ref(field->val_int(), *item, - test(field->flags & UNSIGNED_FLAG)); - if (tmp) - thd->change_item_tree(item, tmp); - result= 1; // Item was replaced + int field_cmp= 0; + // If item is a decimal value, we must reject it if it was truncated. + if (field->type() == MYSQL_TYPE_LONGLONG) + { + field_cmp= stored_field_cmp_to_item(thd, field, *item); + DBUG_PRINT("info", ("convert_const_to_int %d", field_cmp)); + } + + if (0 == field_cmp) + { + Item *tmp= new Item_int_with_ref(field->val_int(), *item, + test(field->flags & UNSIGNED_FLAG)); + if (tmp) + thd->change_item_tree(item, tmp); + result= 1; // Item was replaced + } } /* Restore the original field value. */ if (save_field_value) @@ -2197,14 +2208,10 @@ void Item_func_between::fix_length_and_dec() if (field_item->field_type() == MYSQL_TYPE_LONGLONG || field_item->field_type() == MYSQL_TYPE_YEAR) { - /* - The following can't be recoded with || as convert_const_to_int - changes the argument - */ - if (convert_const_to_int(thd, field_item, &args[1])) - cmp_type=INT_RESULT; - if (convert_const_to_int(thd, field_item, &args[2])) - cmp_type=INT_RESULT; + const bool cvt_arg1= convert_const_to_int(thd, field_item, &args[1]); + const bool cvt_arg2= convert_const_to_int(thd, field_item, &args[2]); + if (cvt_arg1 && cvt_arg2) + cmp_type=INT_RESULT; // Works for all types. } } } diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index f6d08105cf4..3af08a8168e 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -419,6 +419,7 @@ public: decimals= args[0]->decimals; set_if_smaller(decimals, TIME_SECOND_PART_DIGITS); max_length=17 + (decimals ? decimals + 1 : 0); + maybe_null= 1; } void find_num_type() { hybrid_type= decimals ? DECIMAL_RESULT : INT_RESULT; } double real_op() { DBUG_ASSERT(0); return 0; } diff --git a/sql/log_event.h b/sql/log_event.h index 22e28c7ae13..7866a7d7efa 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -767,11 +767,11 @@ typedef struct st_print_event_info Such identifier is not yet unique generally as the event originating master is resetable. Also the crashed master can be replaced with some other. */ -struct event_coordinates +typedef struct event_coordinates { char * file_name; // binlog file name (directories stripped) my_off_t pos; // event's position in the binlog file -}; +} LOG_POS_COORD; /** @class Log_event diff --git a/sql/mysqld.cc b/sql/mysqld.cc index b290464a588..36b6897c56d 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -529,6 +529,11 @@ uint sync_binlog_period= 0, sync_relaylog_period= 0, sync_relayloginfo_period= 0, sync_masterinfo_period= 0; ulong expire_logs_days = 0; ulong rpl_recovery_rank=0; +/** + Soft upper limit for number of sp_head objects that can be stored + in the sp_cache for one connection. +*/ +ulong stored_program_cache_size= 0; const double log_10[] = { 1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007, 1e008, 1e009, @@ -728,8 +733,10 @@ PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_prep_xids, key_LOCK_system_variables_hash, key_LOCK_table_share, key_LOCK_thd_data, key_LOCK_user_conn, key_LOCK_uuid_short_generator, key_LOG_LOCK_log, key_master_info_data_lock, key_master_info_run_lock, + key_master_info_sleep_lock, key_mutex_slave_reporting_capability_err_lock, key_relay_log_info_data_lock, key_relay_log_info_log_space_lock, key_relay_log_info_run_lock, + key_relay_log_info_sleep_lock, key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data, key_LOCK_error_messages, key_LOG_INFO_lock, key_LOCK_thread_count, key_PARTITION_LOCK_auto_inc; @@ -787,10 +794,12 @@ static PSI_mutex_info all_server_mutexes[]= { &key_LOG_LOCK_log, "LOG::LOCK_log", 0}, { &key_master_info_data_lock, "Master_info::data_lock", 0}, { &key_master_info_run_lock, "Master_info::run_lock", 0}, + { &key_master_info_sleep_lock, "Master_info::sleep_lock", 0}, { &key_mutex_slave_reporting_capability_err_lock, "Slave_reporting_capability::err_lock", 0}, { &key_relay_log_info_data_lock, "Relay_log_info::data_lock", 0}, { &key_relay_log_info_log_space_lock, "Relay_log_info::log_space_lock", 0}, { &key_relay_log_info_run_lock, "Relay_log_info::run_lock", 0}, + { &key_relay_log_info_sleep_lock, "Relay_log_info::sleep_lock", 0}, { &key_structure_guard_mutex, "Query_cache::structure_guard_mutex", 0}, { &key_TABLE_SHARE_LOCK_ha_data, "TABLE_SHARE::LOCK_ha_data", 0}, { &key_LOCK_error_messages, "LOCK_error_messages", PSI_FLAG_GLOBAL}, @@ -828,8 +837,10 @@ PSI_cond_key key_BINLOG_COND_prep_xids, key_BINLOG_update_cond, key_delayed_insert_cond, key_delayed_insert_cond_client, key_item_func_sleep_cond, key_master_info_data_cond, key_master_info_start_cond, key_master_info_stop_cond, + key_master_info_sleep_cond, key_relay_log_info_data_cond, key_relay_log_info_log_space_cond, key_relay_log_info_start_cond, key_relay_log_info_stop_cond, + key_relay_log_info_sleep_cond, key_TABLE_SHARE_cond, key_user_level_lock_cond, key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache, key_BINLOG_COND_queue_busy; @@ -864,10 +875,12 @@ static PSI_cond_info all_server_conds[]= { &key_master_info_data_cond, "Master_info::data_cond", 0}, { &key_master_info_start_cond, "Master_info::start_cond", 0}, { &key_master_info_stop_cond, "Master_info::stop_cond", 0}, + { &key_master_info_sleep_cond, "Master_info::sleep_cond", 0}, { &key_relay_log_info_data_cond, "Relay_log_info::data_cond", 0}, { &key_relay_log_info_log_space_cond, "Relay_log_info::log_space_cond", 0}, { &key_relay_log_info_start_cond, "Relay_log_info::start_cond", 0}, { &key_relay_log_info_stop_cond, "Relay_log_info::stop_cond", 0}, + { &key_relay_log_info_sleep_cond, "Relay_log_info::sleep_cond", 0}, { &key_TABLE_SHARE_cond, "TABLE_SHARE::cond", 0}, { &key_user_level_lock_cond, "User_level_lock::cond", 0}, { &key_COND_thread_count, "COND_thread_count", PSI_FLAG_GLOBAL}, @@ -8054,8 +8067,10 @@ static int fix_paths(void) (void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir (void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home); (void) my_load_path(pidfile_name, pidfile_name_ptr, mysql_real_data_home); - (void) my_load_path(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr : - get_relative_path(PLUGINDIR), mysql_home); + + convert_dirname(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr : + get_relative_path(PLUGINDIR), NullS); + (void) my_load_path(opt_plugin_dir, opt_plugin_dir, mysql_home); opt_plugin_dir_ptr= opt_plugin_dir; pidfile_name_ptr= pidfile_name; diff --git a/sql/mysqld.h b/sql/mysqld.h index db7857d9cd5..988584f779a 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -172,6 +172,7 @@ extern ulonglong max_binlog_cache_size, max_binlog_stmt_cache_size; extern ulong max_binlog_size, max_relay_log_size; extern ulong opt_binlog_rows_event_max_size; extern ulong rpl_recovery_rank, thread_cache_size; +extern ulong stored_program_cache_size; extern ulong back_log; extern char language[FN_REFLEN]; extern "C" MYSQL_PLUGIN_IMPORT ulong server_id; @@ -234,8 +235,10 @@ extern PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_prep_xids, key_LOCK_table_share, key_LOCK_thd_data, key_LOCK_user_conn, key_LOG_LOCK_log, key_master_info_data_lock, key_master_info_run_lock, + key_master_info_sleep_lock, key_mutex_slave_reporting_capability_err_lock, key_relay_log_info_data_lock, key_relay_log_info_log_space_lock, key_relay_log_info_run_lock, + key_relay_log_info_sleep_lock, key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data, key_LOCK_error_messages, key_LOCK_thread_count, key_PARTITION_LOCK_auto_inc; extern PSI_mutex_key key_RELAYLOG_LOCK_index; @@ -258,8 +261,10 @@ extern PSI_cond_key key_BINLOG_COND_prep_xids, key_BINLOG_update_cond, key_delayed_insert_cond, key_delayed_insert_cond_client, key_item_func_sleep_cond, key_master_info_data_cond, key_master_info_start_cond, key_master_info_stop_cond, + key_master_info_sleep_cond, key_relay_log_info_data_cond, key_relay_log_info_log_space_cond, key_relay_log_info_start_cond, key_relay_log_info_stop_cond, + key_relay_log_info_sleep_cond, key_TABLE_SHARE_cond, key_user_level_lock_cond, key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache; extern PSI_cond_key key_RELAYLOG_update_cond, key_COND_wakeup_ready; diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index 164173467f1..ae2a4bbec01 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -46,9 +46,11 @@ Master_info::Master_info(bool is_slave_recovery) mysql_mutex_init(key_master_info_data_lock, &data_lock, MY_MUTEX_INIT_FAST); mysql_mutex_setflags(&run_lock, MYF_NO_DEADLOCK_DETECTION); mysql_mutex_setflags(&data_lock, MYF_NO_DEADLOCK_DETECTION); + mysql_mutex_init(key_master_info_sleep_lock, &sleep_lock, MY_MUTEX_INIT_FAST); mysql_cond_init(key_master_info_data_cond, &data_cond, NULL); mysql_cond_init(key_master_info_start_cond, &start_cond, NULL); mysql_cond_init(key_master_info_stop_cond, &stop_cond, NULL); + mysql_cond_init(key_master_info_sleep_cond, &sleep_cond, NULL); } Master_info::~Master_info() @@ -56,9 +58,11 @@ Master_info::~Master_info() delete_dynamic(&ignore_server_ids); mysql_mutex_destroy(&run_lock); mysql_mutex_destroy(&data_lock); + mysql_mutex_destroy(&sleep_lock); mysql_cond_destroy(&data_cond); mysql_cond_destroy(&start_cond); mysql_cond_destroy(&stop_cond); + mysql_cond_destroy(&sleep_cond); } /** diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index 5875290fa02..c98f7253b18 100644 --- a/sql/rpl_mi.h +++ b/sql/rpl_mi.h @@ -79,8 +79,8 @@ class Master_info : public Slave_reporting_capability File fd; // we keep the file open, so we need to remember the file pointer IO_CACHE file; - mysql_mutex_t data_lock, run_lock; - mysql_cond_t data_cond, start_cond, stop_cond; + mysql_mutex_t data_lock, run_lock, sleep_lock; + mysql_cond_t data_cond, start_cond, stop_cond, sleep_cond; THD *io_thd; MYSQL* mysql; uint32 file_id; /* for 3.23 load data infile */ diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 51e951128dd..da1fc98c3e1 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -78,10 +78,12 @@ Relay_log_info::Relay_log_info(bool is_slave_recovery) &data_lock, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_relay_log_info_log_space_lock, &log_space_lock, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_relay_log_info_sleep_lock, &sleep_lock, MY_MUTEX_INIT_FAST); mysql_cond_init(key_relay_log_info_data_cond, &data_cond, NULL); mysql_cond_init(key_relay_log_info_start_cond, &start_cond, NULL); mysql_cond_init(key_relay_log_info_stop_cond, &stop_cond, NULL); mysql_cond_init(key_relay_log_info_log_space_cond, &log_space_cond, NULL); + mysql_cond_init(key_relay_log_info_sleep_cond, &sleep_cond, NULL); relay_log.init_pthread_objects(); DBUG_VOID_RETURN; } @@ -94,10 +96,12 @@ Relay_log_info::~Relay_log_info() mysql_mutex_destroy(&run_lock); mysql_mutex_destroy(&data_lock); mysql_mutex_destroy(&log_space_lock); + mysql_mutex_destroy(&sleep_lock); mysql_cond_destroy(&data_cond); mysql_cond_destroy(&start_cond); mysql_cond_destroy(&stop_cond); mysql_cond_destroy(&log_space_cond); + mysql_cond_destroy(&sleep_cond); relay_log.cleanup(); free_annotate_event(); DBUG_VOID_RETURN; diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index 520b2b58bb9..fef910de65d 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -140,15 +140,13 @@ public: standard lock acquisition order to avoid deadlocks: run_lock, data_lock, relay_log.LOCK_log, relay_log.LOCK_index */ - mysql_mutex_t data_lock, run_lock; - + mysql_mutex_t data_lock, run_lock, sleep_lock; /* start_cond is broadcast when SQL thread is started stop_cond - when stopped data_cond - when data protected by data_lock changes */ - mysql_cond_t start_cond, stop_cond, data_cond; - + mysql_cond_t start_cond, stop_cond, data_cond, sleep_cond; /* parent Master_info structure */ Master_info *mi; diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 8e866c82123..90cee00fde4 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -4701,14 +4701,14 @@ ER_NOT_SUPPORTED_YET 42000 spa "Esta versión de MariaDB no soporta todavia '%s'" swe "Denna version av MariaDB kan ännu inte utföra '%s'" ER_MASTER_FATAL_ERROR_READING_BINLOG - nla "Kreeg fatale fout %d: '%-.256s' van master tijdens lezen van data uit binaire log" - eng "Got fatal error %d from master when reading data from binary log: '%-.256s'" - ger "Schwerer Fehler %d: '%-.256s vom Master beim Lesen des binären Logs" - ita "Errore fatale %d: '%-.256s' dal master leggendo i dati dal log binario" - por "Obteve fatal erro %d: '%-.256s' do master quando lendo dados do binary log" - rus "Получена неисправимая ошибка %d: '%-.256s' от головного сервера в процессе выборки данных из двоичного журнала" - spa "Recibió fatal error %d: '%-.256s' del master cuando leyendo datos del binary log" - swe "Fick fatalt fel %d: '%-.256s' från master vid läsning av binärloggen" + nla "Kreeg fatale fout %d: '%-.512s' van master tijdens lezen van data uit binaire log" + eng "Got fatal error %d from master when reading data from binary log: '%-.512s'" + ger "Schwerer Fehler %d: '%-.512s vom Master beim Lesen des binären Logs" + ita "Errore fatale %d: '%-.512s' dal master leggendo i dati dal log binario" + por "Obteve fatal erro %d: '%-.512s' do master quando lendo dados do binary log" + rus "Получена неисправимая ошибка %d: '%-.512s' от головного сервера в процессе выборки данных из двоичного журнала" + spa "Recibió fatal error %d: '%-.512s' del master cuando leyendo datos del binary log" + swe "Fick fatalt fel %d: '%-.512s' från master vid läsning av binärloggen" ER_SLAVE_IGNORED_TABLE eng "Slave SQL thread ignored the query because of replicate-*-table rules" ger "Slave-SQL-Thread hat die Abfrage aufgrund von replicate-*-table-Regeln ignoriert" diff --git a/sql/slave.cc b/sql/slave.cc index 1e717a2e98c..56f9c14703c 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -69,8 +69,6 @@ bool use_slave_mask = 0; MY_BITMAP slave_error_mask; char slave_skip_error_names[SHOW_VAR_FUNC_BUFF_SIZE]; -typedef bool (*CHECK_KILLED_FUNC)(THD*,void*); - char* slave_load_tmpdir = 0; Master_info *active_mi= 0; my_bool replicate_same_server_id; @@ -153,9 +151,6 @@ static int safe_reconnect(THD* thd, MYSQL* mysql, Master_info* mi, bool suppress_warnings); static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi, bool reconnect, bool suppress_warnings); -static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed, - void* thread_killed_arg); -static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi); static Log_event* next_event(Relay_log_info* rli); static int queue_event(Master_info* mi,const char* buf,ulong event_len); static int terminate_slave_thread(THD *thd, @@ -2268,35 +2263,42 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type) DBUG_RETURN(0); } +/* + Sleep for a given amount of time or until killed. + + @param thd Thread context of the current thread. + @param seconds The number of seconds to sleep. + @param func Function object to check if the thread has been killed. + @param info The Rpl_info object associated with this sleep. -static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed, - void* thread_killed_arg) + @retval True if the thread has been killed, false otherwise. +*/ +template <typename killed_func, typename rpl_info> +static inline bool slave_sleep(THD *thd, time_t seconds, + killed_func func, rpl_info info) { - int nap_time; - thr_alarm_t alarmed; - DBUG_ENTER("safe_sleep"); - thr_alarm_init(&alarmed); - time_t start_time= my_time(0); - time_t end_time= start_time+sec; + bool ret; + struct timespec abstime; + const char *old_proc_info; - while ((nap_time= (int) (end_time - start_time)) > 0) - { - ALARM alarm_buff; - /* - The only reason we are asking for alarm is so that - we will be woken up in case of murder, so if we do not get killed, - set the alarm so it goes off after we wake up naturally - */ - thr_alarm(&alarmed, 2 * nap_time, &alarm_buff); - sleep(nap_time); - thr_end_alarm(&alarmed); + mysql_mutex_t *lock= &info->sleep_lock; + mysql_cond_t *cond= &info->sleep_cond; - if ((*thread_killed)(thd,thread_killed_arg)) - DBUG_RETURN(1); - start_time= my_time(0); + /* Absolute system time at which the sleep time expires. */ + set_timespec(abstime, seconds); + mysql_mutex_lock(lock); + old_proc_info= thd->enter_cond(cond, lock, thd->proc_info); + + while (! (ret= func(thd, info))) + { + int error= mysql_cond_timedwait(cond, lock, &abstime); + if (error == ETIMEDOUT || error == ETIME) + break; } - DBUG_RETURN(0); + /* Implicitly unlocks the mutex. */ + thd->exit_cond(old_proc_info); + return ret; } @@ -2790,8 +2792,8 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli) exec_res= 0; rli->cleanup_context(thd, 1); /* chance for concurrent connection to get more locks */ - safe_sleep(thd, min(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE), - (CHECK_KILLED_FUNC)sql_slave_killed, (void*)rli); + slave_sleep(thd, min(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE), + sql_slave_killed, rli); mysql_mutex_lock(&rli->data_lock); // because of SHOW STATUS rli->trans_retries++; rli->retried_trans++; @@ -2889,8 +2891,7 @@ static int try_to_reconnect(THD *thd, MYSQL *mysql, Master_info *mi, { if (*retry_count > master_retry_count) return 1; // Don't retry forever - safe_sleep(thd, mi->connect_retry, (CHECK_KILLED_FUNC) io_slave_killed, - (void *) mi); + slave_sleep(thd, mi->connect_retry, io_slave_killed, mi); } if (check_io_slave_killed(thd, mi, messages[SLAVE_RECON_MSG_KILLED_WAITING])) return 1; @@ -4650,8 +4651,7 @@ static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi, change_rpl_status(RPL_ACTIVE_SLAVE,RPL_LOST_SOLDIER); break; } - safe_sleep(thd,mi->connect_retry,(CHECK_KILLED_FUNC)io_slave_killed, - (void*)mi); + slave_sleep(thd,mi->connect_retry,io_slave_killed, mi); } if (!slave_was_killed) diff --git a/sql/sp_cache.cc b/sql/sp_cache.cc index f0875b9c3f4..f88aed7ab3d 100644 --- a/sql/sp_cache.cc +++ b/sql/sp_cache.cc @@ -57,6 +57,20 @@ public: { my_hash_delete(&m_hashtable, (uchar *)sp); } + + /** + Remove all elements from a stored routine cache if the current + number of elements exceeds the argument value. + + @param[in] upper_limit_for_elements Soft upper limit of elements that + can be stored in the cache. + */ + void enforce_limit(ulong upper_limit_for_elements) + { + if (m_hashtable.records > upper_limit_for_elements) + my_hash_reset(&m_hashtable); + } + private: void init(); void cleanup(); @@ -234,6 +248,21 @@ ulong sp_cache_version() } +/** + Enforce that the current number of elements in the cache don't exceed + the argument value by flushing the cache if necessary. + + @param[in] c Cache to check + @param[in] upper_limit_for_elements Soft upper limit for number of sp_head + objects that can be stored in the cache. +*/ +void +sp_cache_enforce_limit(sp_cache *c, ulong upper_limit_for_elements) +{ + if (c) + c->enforce_limit(upper_limit_for_elements); +} + /************************************************************************* Internal functions *************************************************************************/ diff --git a/sql/sp_cache.h b/sql/sp_cache.h index 7c5d1dca6ef..ba70bf32400 100644 --- a/sql/sp_cache.h +++ b/sql/sp_cache.h @@ -63,5 +63,6 @@ sp_head *sp_cache_lookup(sp_cache **cp, sp_name *name); void sp_cache_invalidate(); void sp_cache_flush_obsolete(sp_cache **cp, sp_head **sp); ulong sp_cache_version(); +void sp_cache_enforce_limit(sp_cache *cp, ulong upper_limit_for_elements); #endif /* _SP_CACHE_H_ */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b6c8751cd3a..d1b2eade165 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5742,6 +5742,8 @@ void mysql_parse(THD *thd, char *rawbuf, uint length, query_cache_abort(&thd->query_cache_tls); } thd_proc_info(thd, "freeing items"); + sp_cache_enforce_limit(thd->sp_proc_cache, stored_program_cache_size); + sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size); thd->end_statement(); thd->cleanup_after_query(); DBUG_ASSERT(thd->change_list.is_empty()); diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index edeae8aa9c8..39f69b2656d 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -742,6 +742,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) dlpathlen= strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", dl->str, NullS) - dlpath; + (void) unpack_filename(dlpath, dlpath); plugin_dl.ref_count= 1; /* Open new dll handle */ if (!(plugin_dl.handle= dlopen(dlpath, RTLD_NOW))) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index da9dcc053cf..e25751a4b88 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2284,6 +2284,9 @@ void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length) thd->protocol= save_protocol; + sp_cache_enforce_limit(thd->sp_proc_cache, stored_program_cache_size); + sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size); + /* check_prepared_statemnt sends the metadata packet in case of success */ end: DBUG_VOID_RETURN; @@ -2645,6 +2648,9 @@ void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length) stmt->execute_loop(&expanded_query, open_cursor, packet, packet_end); thd->protocol= save_protocol; + sp_cache_enforce_limit(thd->sp_proc_cache, stored_program_cache_size); + sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size); + /* Close connection socket; for use with client testing (Bug#43560). */ DBUG_EXECUTE_IF("close_conn_after_stmt_execute", vio_close(thd->net.vio);); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 29ab8b1d05b..eb17ef0812c 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -625,8 +625,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, String* const packet = &thd->packet; int error; const char *errmsg = "Unknown error", *tmp_msg; - const char *fmt= "%s; the last event was read from '%s' at %s, the last byte read was read from '%s' at %s."; - char llbuff1[22], llbuff2[22]; + char llbuff0[22], llbuff1[22], llbuff2[22]; char error_text[MAX_SLAVE_ERRMSG]; // to be send to slave via my_message() NET* net = &thd->net; mysql_mutex_t *log_lock; @@ -646,16 +645,15 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, */ ulonglong heartbeat_period= get_heartbeat_period(thd); struct timespec heartbeat_buf; - struct event_coordinates coord_buf; struct timespec *heartbeat_ts= NULL; - struct event_coordinates *coord= NULL; + const LOG_POS_COORD start_coord= { log_ident, pos }, + *p_start_coord= &start_coord; + LOG_POS_COORD coord_buf= { log_file_name, BIN_LOG_HEADER_SIZE }, + *p_coord= &coord_buf; if (heartbeat_period != LL(0)) { heartbeat_ts= &heartbeat_buf; set_timespec_nsec(*heartbeat_ts, 0); - coord= &coord_buf; - coord->file_name= log_file_name; // initialization basing on what slave remembers - coord->pos= pos; } sql_print_information("Start binlog_dump to slave_server(%d), pos(%s, %lu)", thd->server_id, log_ident, (ulong)pos); @@ -776,6 +774,7 @@ impossible position"; mysql_bin_log, and it's already inited, and it will be destroyed only at shutdown). */ + p_coord->pos= pos; // the first hb matches the slave's last seen value log_lock= mysql_bin_log.get_log_lock(); log_cond= mysql_bin_log.get_log_cond(); if (pos > BIN_LOG_HEADER_SIZE) @@ -895,8 +894,7 @@ impossible position"; /* log's filename does not change while it's active */ - if (coord) - coord->pos= uint4korr(packet->ptr() + ev_offset + LOG_POS_OFFSET); + p_coord->pos= uint4korr(packet->ptr() + ev_offset + LOG_POS_OFFSET); event_type= (Log_event_type)((uchar)(*packet)[LOG_EVENT_OFFSET+ev_offset]); @@ -1026,10 +1024,8 @@ impossible position"; /* we read successfully, so we'll need to send it to the slave */ mysql_mutex_unlock(log_lock); read_packet = 1; - if (coord) - coord->pos= uint4korr(packet->ptr() + ev_offset + LOG_POS_OFFSET); - event_type= - (Log_event_type)((uchar)(*packet)[LOG_EVENT_OFFSET+ev_offset]); + p_coord->pos= uint4korr(packet->ptr() + ev_offset + LOG_POS_OFFSET); + event_type= (Log_event_type)((*packet)[LOG_EVENT_OFFSET+ev_offset]); break; case LOG_READ_EOF: @@ -1050,16 +1046,16 @@ impossible position"; signal_cnt= mysql_bin_log.signal_cnt; do { - if (coord) + if (heartbeat_period != 0) { - DBUG_ASSERT(heartbeat_ts && heartbeat_period != 0); + DBUG_ASSERT(heartbeat_ts); set_timespec_nsec(*heartbeat_ts, heartbeat_period); } thd->enter_cond(log_cond, log_lock, "Master has sent all binlog to slave; " "waiting for binlog to be updated"); ret= mysql_bin_log.wait_for_update_bin_log(thd, heartbeat_ts); - DBUG_ASSERT(ret == 0 || (heartbeat_period != 0 && coord != NULL)); + DBUG_ASSERT(ret == 0 || (heartbeat_period != 0)); if (ret == ETIMEDOUT || ret == ETIME) { #ifndef DBUG_OFF @@ -1077,7 +1073,7 @@ impossible position"; thd->exit_cond(old_msg); goto err; } - if (send_heartbeat_event(net, packet, coord, current_checksum_alg)) + if (send_heartbeat_event(net, packet, p_coord, current_checksum_alg)) { errmsg = "Failed on my_net_write()"; my_errno= ER_UNKNOWN_ERROR; @@ -1160,8 +1156,7 @@ impossible position"; goto err; } - if (coord) - coord->file_name= log_file_name; // reset to the next + p_coord->file_name= log_file_name; // reset to the next } } @@ -1186,9 +1181,12 @@ err: detailing the fatal error message with coordinates of the last position read. */ + const char *fmt= "%s; the start event position from '%s' at %s, the last event was read from '%s' at %s, the last byte read was read from '%s' at %s."; my_snprintf(error_text, sizeof(error_text), fmt, errmsg, - my_basename(coord->file_name), (llstr(coord->pos, llbuff1), llbuff1), - my_basename(log_file_name), (llstr(my_b_tell(&log), llbuff2), llbuff2)); + my_basename(p_start_coord->file_name), + (llstr(p_start_coord->pos, llbuff0), llbuff0), + my_basename(p_coord->file_name), (llstr(p_coord->pos, llbuff1), llbuff1), + my_basename(log_file_name), (llstr(my_b_tell(&log), llbuff2), llbuff2)); } else strcpy(error_text, errmsg); diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index e41598f943c..50c57b62067 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -228,6 +228,7 @@ void udf_init() char dlpath[FN_REFLEN]; strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", tmp->dl, NullS); + (void) unpack_filename(dlpath, dlpath); if (!(dl= dlopen(dlpath, RTLD_NOW))) { /* Print warning to log */ @@ -476,6 +477,8 @@ int mysql_create_function(THD *thd,udf_func *udf) { char dlpath[FN_REFLEN]; strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", udf->dl, NullS); + (void) unpack_filename(dlpath, dlpath); + if (!(dl = dlopen(dlpath, RTLD_NOW))) { DBUG_PRINT("error",("dlopen of %s failed, error: %d (%s)", diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 1542347d26d..72e9525db72 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -3438,6 +3438,13 @@ static Sys_var_tz Sys_time_zone( SESSION_VAR(time_zone), NO_CMD_LINE, DEFAULT(&default_tz), NO_MUTEX_GUARD, IN_BINLOG); +static Sys_var_ulong Sys_sp_cache_size( + "stored_program_cache", + "The soft upper limit for number of cached stored routines for " + "one connection.", + GLOBAL_VAR(stored_program_cache_size), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(256, 512 * 1024), DEFAULT(256), BLOCK_SIZE(1)); + export const char *plugin_maturity_names[]= { "unknown", "experimental", "alpha", "beta", "gamma", "stable", 0 }; static Sys_var_enum Sys_plugin_maturity( |