summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2012-03-09 08:06:59 +0100
committerSergei Golubchik <sergii@pisem.net>2012-03-09 08:06:59 +0100
commit4933d21e5d93840ddcf41bf25ed92fbe253ae92d (patch)
treea4d892b86aa46927978f82976fff61f1e5193383 /sql
parent97ee59d27d3daca806fdb3577df5a0e0a45a0a30 (diff)
parent7009bf411a8cb9a6e035b761b5e6352b4f474303 (diff)
downloadmariadb-git-4933d21e5d93840ddcf41bf25ed92fbe253ae92d.tar.gz
merge with mysql-5.5.21
Diffstat (limited to 'sql')
-rw-r--r--sql/item.cc20
-rw-r--r--sql/item_cmpfunc.cc37
-rw-r--r--sql/item_timefunc.h1
-rw-r--r--sql/log_event.h4
-rw-r--r--sql/mysqld.cc19
-rw-r--r--sql/mysqld.h5
-rw-r--r--sql/rpl_mi.cc4
-rw-r--r--sql/rpl_mi.h4
-rw-r--r--sql/rpl_rli.cc4
-rw-r--r--sql/rpl_rli.h6
-rw-r--r--sql/share/errmsg-utf8.txt16
-rw-r--r--sql/slave.cc68
-rw-r--r--sql/sp_cache.cc29
-rw-r--r--sql/sp_cache.h1
-rw-r--r--sql/sql_parse.cc2
-rw-r--r--sql/sql_plugin.cc1
-rw-r--r--sql/sql_prepare.cc6
-rw-r--r--sql/sql_repl.cc40
-rw-r--r--sql/sql_udf.cc3
-rw-r--r--sql/sys_vars.cc7
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(