summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2017-03-30 12:48:42 +0200
committerSergei Golubchik <serg@mariadb.org>2017-03-30 12:48:42 +0200
commitda4d71d10d23c1ac2d10b72baee14991ccb7a146 (patch)
tree7cdf3a8c8e72ca7c1c8105427c04123f025bd870 /sql
parent9ec85009985d644ce7ae797bc3572d0ad0f69bb0 (diff)
parenta00517ac9707ffd51c092f5af5d198c5ee789bb4 (diff)
downloadmariadb-git-da4d71d10d23c1ac2d10b72baee14991ccb7a146.tar.gz
Merge branch '10.1' into 10.2
Diffstat (limited to 'sql')
-rw-r--r--sql/CMakeLists.txt2
-rw-r--r--sql/bounded_queue.h2
-rw-r--r--sql/contributors.h14
-rw-r--r--sql/create_options.cc2
-rw-r--r--sql/create_options.h2
-rw-r--r--sql/datadict.cc50
-rw-r--r--sql/datadict.h5
-rw-r--r--sql/event_scheduler.cc32
-rw-r--r--sql/filesort_utils.cc2
-rw-r--r--sql/gcalc_slicescan.cc2
-rw-r--r--sql/gcalc_slicescan.h2
-rw-r--r--sql/gcalc_tools.cc2
-rw-r--r--sql/gcalc_tools.h2
-rw-r--r--sql/group_by_handler.cc2
-rw-r--r--sql/group_by_handler.h2
-rw-r--r--sql/ha_partition.cc1
-rw-r--r--sql/handler.cc22
-rw-r--r--sql/item.h5
-rw-r--r--sql/item_cmpfunc.cc28
-rw-r--r--sql/item_cmpfunc.h7
-rw-r--r--sql/item_func.cc8
-rw-r--r--sql/item_strfunc.cc87
-rw-r--r--sql/item_subselect.cc9
-rw-r--r--sql/item_subselect.h9
-rw-r--r--sql/log.cc42
-rw-r--r--sql/log_event.cc18
-rw-r--r--sql/log_event_old.cc4
-rw-r--r--sql/log_slow.h2
-rw-r--r--sql/mdl.cc3
-rw-r--r--sql/multi_range_read.cc2
-rw-r--r--sql/multi_range_read.h2
-rw-r--r--sql/my_apc.cc2
-rw-r--r--sql/my_apc.h2
-rw-r--r--sql/my_json_writer.cc2
-rw-r--r--sql/my_json_writer.h2
-rw-r--r--sql/mysql_install_db.cc6
-rw-r--r--sql/mysql_upgrade_service.cc2
-rw-r--r--sql/mysqld.cc122
-rw-r--r--sql/mysqld.h6
-rw-r--r--sql/nt_servc.cc2
-rw-r--r--sql/nt_servc.h2
-rw-r--r--sql/opt_index_cond_pushdown.cc2
-rw-r--r--sql/opt_range.cc14
-rw-r--r--sql/opt_range_mrr.cc2
-rw-r--r--sql/opt_subselect.cc2
-rw-r--r--sql/opt_subselect.h2
-rw-r--r--sql/opt_table_elimination.cc2
-rw-r--r--sql/partition_info.cc2
-rw-r--r--sql/password.c66
-rw-r--r--sql/plistsort.c2
-rw-r--r--sql/rpl_mi.cc442
-rw-r--r--sql/rpl_mi.h19
-rw-r--r--sql/rpl_parallel.cc125
-rw-r--r--sql/rpl_parallel.h1
-rw-r--r--sql/rpl_rli.cc15
-rw-r--r--sql/rpl_rli.h2
-rw-r--r--sql/sha2.cc68
-rw-r--r--sql/share/errmsg-utf8.txt2
-rw-r--r--sql/slave.cc160
-rw-r--r--sql/slave.h3
-rw-r--r--sql/sql_acl.cc91
-rw-r--r--sql/sql_alter.h35
-rw-r--r--sql/sql_analyze_stmt.cc2
-rw-r--r--sql/sql_analyze_stmt.h2
-rw-r--r--sql/sql_base.cc2
-rw-r--r--sql/sql_binlog.cc1
-rw-r--r--sql/sql_class.cc42
-rw-r--r--sql/sql_connect.cc6
-rw-r--r--sql/sql_db.cc9
-rw-r--r--sql/sql_derived.cc3
-rw-r--r--sql/sql_explain.cc2
-rw-r--r--sql/sql_explain.h2
-rw-r--r--sql/sql_expression_cache.cc2
-rw-r--r--sql/sql_expression_cache.h2
-rw-r--r--sql/sql_insert.cc13
-rw-r--r--sql/sql_join_cache.cc2
-rw-r--r--sql/sql_join_cache.h2
-rw-r--r--sql/sql_lifo_buffer.h2
-rw-r--r--sql/sql_parse.cc132
-rw-r--r--sql/sql_parse.h3
-rw-r--r--sql/sql_plugin.cc29
-rw-r--r--sql/sql_plugin_services.ic66
-rw-r--r--sql/sql_prepare.cc2
-rw-r--r--sql/sql_reload.cc56
-rw-r--r--sql/sql_repl.cc74
-rw-r--r--sql/sql_select.cc98
-rw-r--r--sql/sql_show.cc52
-rw-r--r--sql/sql_statistics.cc2
-rw-r--r--sql/sql_table.cc3
-rw-r--r--sql/sql_udf.cc9
-rw-r--r--sql/sql_yacc.yy4
-rw-r--r--sql/sys_vars.cc127
-rw-r--r--sql/table.cc2
-rw-r--r--sql/threadpool.h2
-rw-r--r--sql/threadpool_common.cc2
-rw-r--r--sql/threadpool_generic.cc2
-rw-r--r--sql/threadpool_win.cc2
-rw-r--r--sql/winservice.c2
-rw-r--r--sql/winservice.h2
-rw-r--r--sql/wsrep_applier.h2
-rw-r--r--sql/wsrep_check_opts.cc2
-rw-r--r--sql/wsrep_hton.cc2
-rw-r--r--sql/wsrep_mysqld.cc2
-rw-r--r--sql/wsrep_mysqld.h2
-rw-r--r--sql/wsrep_notify.cc2
-rw-r--r--sql/wsrep_priv.h2
-rw-r--r--sql/wsrep_sst.cc2
-rw-r--r--sql/wsrep_utils.cc2
-rw-r--r--sql/wsrep_var.cc2
-rw-r--r--sql/wsrep_xid.cc2
110 files changed, 1327 insertions, 1037 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 243468e095a..fc41a31c3c4 100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -81,7 +81,7 @@ SET (SQL_SOURCE
../sql-common/client.c compat56.cc derror.cc des_key_file.cc
discover.cc ../sql-common/errmsg.c field.cc field_conv.cc
filesort_utils.cc
- filesort.cc gstream.cc sha2.cc
+ filesort.cc gstream.cc
signal_handler.cc
handler.cc hash_filo.h
hostname.cc init.cc item.cc item_buff.cc item_cmpfunc.cc
diff --git a/sql/bounded_queue.h b/sql/bounded_queue.h
index 88c2bbc238d..3573c5ceb27 100644
--- a/sql/bounded_queue.h
+++ b/sql/bounded_queue.h
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#ifndef BOUNDED_QUEUE_INCLUDED
#define BOUNDED_QUEUE_INCLUDED
diff --git a/sql/contributors.h b/sql/contributors.h
index 0359ec54022..3a771e2b493 100644
--- a/sql/contributors.h
+++ b/sql/contributors.h
@@ -37,16 +37,18 @@ struct show_table_contributors_st {
struct show_table_contributors_st show_table_contributors[]= {
/* MariaDB foundation sponsors, in contribution, size , time order */
- {"Booking.com", "http://www.booking.com", "Founding member, Platinum Sponsor of the MariaDB Foundation"},
+ {"Booking.com", "https://www.booking.com", "Founding member, Platinum Sponsor of the MariaDB Foundation"},
+ {"Alibaba Cloud", "https://intl.aliyun.com", "Platinum Sponsor of the MariaDB Foundation"},
{"MariaDB Corporation", "https://mariadb.com", "Founding member, Gold Sponsor of the MariaDB Foundation"},
- {"Visma", "http://visma.com", "Gold Sponsor of the MariaDB Foundation"},
- {"DBS", "http://dbs.com", "Gold Sponsor of the MariaDB Foundation"},
+ {"Visma", "https://visma.com", "Gold Sponsor of the MariaDB Foundation"},
+ {"DBS", "https://dbs.com", "Gold Sponsor of the MariaDB Foundation"},
{"Nexedi", "https://www.nexedi.com", "Silver Sponsor of the MariaDB Foundation"},
{"Acronis", "http://www.acronis.com", "Silver Sponsor of the MariaDB Foundation"},
{"Auttomattic", "https://automattic.com", "Bronze Sponsor of the MariaDB Foundation"},
- {"Verkkokauppa.com", "https://virtuozzo.com", "Bronze Sponsor of the MariaDB Foundation"},
- {"Virtuozzo", "https://virtuozzo.com/", "Bronze Sponsor of the MariaDB Foundation"},
- {"Tencent Game DBA", "http://tencentdba.com/about/", "Bronze Sponsor of the MariaDB Foundation"},
+ {"Verkkokauppa.com", "https://www.verkkokauppa.com", "Bronze Sponsor of the MariaDB Foundation"},
+ {"Virtuozzo", "https://virtuozzo.com", "Bronze Sponsor of the MariaDB Foundation"},
+ {"Tencent Game DBA", "http://tencentdba.com/about", "Bronze Sponsor of the MariaDB Foundation"},
+ {"Tencent TDSQL", "http://tdsql.org", "Bronze Sponsor of the MariaDB Foundation"},
/* Sponsors of important features */
{"Google", "USA", "Sponsoring encryption, parallel replication and GTID"},
diff --git a/sql/create_options.cc b/sql/create_options.cc
index 7edc2cb95f2..99562faa077 100644
--- a/sql/create_options.cc
+++ b/sql/create_options.cc
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/**
@file
diff --git a/sql/create_options.h b/sql/create_options.h
index 3e7f9ecfabf..191ec88750a 100644
--- a/sql/create_options.h
+++ b/sql/create_options.h
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/**
@file
diff --git a/sql/datadict.cc b/sql/datadict.cc
index c1e1e85c377..103a33214ae 100644
--- a/sql/datadict.cc
+++ b/sql/datadict.cc
@@ -39,25 +39,27 @@ static int read_string(File file, uchar**to, size_t length)
/**
Check type of .frm if we are not going to parse it.
- @param[in] thd The current session.
- @param[in] path path to FRM file.
- @param[out] dbt db_type of the table if FRMTYPE_TABLE, otherwise undefined.
+ @param[in] thd The current session.
+ @param[in] path path to FRM file.
+ @param[in/out] engine_name table engine name (length < NAME_CHAR_LEN)
+
+ engine_name is a LEX_STRING, where engine_name->str must point to
+ a buffer of at least NAME_CHAR_LEN+1 bytes.
@retval FRMTYPE_ERROR error
@retval FRMTYPE_TABLE table
@retval FRMTYPE_VIEW view
*/
-frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt)
+frm_type_enum dd_frm_type(THD *thd, char *path, LEX_STRING *engine_name)
{
File file;
uchar header[10]; //"TYPE=VIEW\n" it is 10 characters
size_t error;
frm_type_enum type= FRMTYPE_ERROR;
+ uchar dbt;
DBUG_ENTER("dd_frm_type");
- *dbt= DB_TYPE_UNKNOWN;
-
if ((file= mysql_file_open(key_file_frm, path, O_RDONLY | O_SHARE, MYF(0))) < 0)
DBUG_RETURN(FRMTYPE_ERROR);
error= mysql_file_read(file, (uchar*) header, sizeof(header), MYF(MY_NABP));
@@ -72,17 +74,24 @@ frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt)
type= FRMTYPE_TABLE;
- /*
- This is just a check for DB_TYPE. We'll return default unknown type
- if the following test is true (arg #3). This should not have effect
- on return value from this function (default FRMTYPE_TABLE)
- */
- if (!is_binary_frm_header(header))
+ if (!is_binary_frm_header(header) || !engine_name)
goto err;
- *dbt= (enum legacy_db_type) (uint) *(header + 3);
+ engine_name->length= 0;
+ dbt= header[3];
+
+ /* cannot use ha_resolve_by_legacy_type without a THD */
+ if (thd && dbt < DB_TYPE_FIRST_DYNAMIC)
+ {
+ handlerton *ht= ha_resolve_by_legacy_type(thd, (enum legacy_db_type)dbt);
+ if (ht)
+ {
+ *engine_name= hton2plugin[ht->slot]->name;
+ goto err;
+ }
+ }
- if (*dbt >= DB_TYPE_FIRST_DYNAMIC) /* read the true engine name */
+ /* read the true engine name */
{
MY_STAT state;
uchar *frm_image= 0;
@@ -110,15 +119,10 @@ frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt)
next_chunk+= connect_string_length + 2;
if (next_chunk + 2 < buff_end)
{
- uint str_db_type_length= uint2korr(next_chunk);
- LEX_STRING name;
- name.str= (char*) next_chunk + 2;
- name.length= str_db_type_length;
- plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name, false);
- if (tmp_plugin)
- *dbt= plugin_data(tmp_plugin, handlerton *)->db_type;
- else
- *dbt= DB_TYPE_UNKNOWN;
+ uint len= uint2korr(next_chunk);
+ if (len <= NAME_CHAR_LEN)
+ strmake(engine_name->str, (char*)next_chunk + 2,
+ engine_name->length= len);
}
}
diff --git a/sql/datadict.h b/sql/datadict.h
index dd80942daca..9b180a882f9 100644
--- a/sql/datadict.h
+++ b/sql/datadict.h
@@ -35,12 +35,11 @@ enum frm_type_enum
Prefer to use ha_table_exists() instead.
To check whether it's an frm of a view, use dd_frm_is_view().
*/
-frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt);
+frm_type_enum dd_frm_type(THD *thd, char *path, LEX_STRING *engine_name);
static inline bool dd_frm_is_view(THD *thd, char *path)
{
- enum legacy_db_type not_used;
- return dd_frm_type(thd, path, &not_used) == FRMTYPE_VIEW;
+ return dd_frm_type(thd, path, NULL) == FRMTYPE_VIEW;
}
bool dd_recreate_table(THD *thd, const char *db, const char *table_name,
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc
index 3450e60f85c..8ed5901b69a 100644
--- a/sql/event_scheduler.cc
+++ b/sql/event_scheduler.cc
@@ -133,9 +133,6 @@ post_init_event_thread(THD *thd)
thd->cleanup();
return TRUE;
}
-
- add_to_active_threads(thd);
- inc_thread_running();
return FALSE;
}
@@ -153,8 +150,8 @@ deinit_event_thread(THD *thd)
{
thd->proc_info= "Clearing";
DBUG_PRINT("exit", ("Event thread finishing"));
-
- delete_running_thd(thd);
+ unlink_not_visible_thd(thd);
+ delete thd;
}
@@ -188,6 +185,7 @@ pre_init_event_thread(THD* thd)
thd->net.read_timeout= slave_net_timeout;
thd->variables.option_bits|= OPTION_AUTO_IS_NULL;
thd->client_capabilities|= CLIENT_MULTI_RESULTS;
+ add_to_active_threads(thd);
/*
Guarantees that we will see the thread in SHOW PROCESSLIST though its
@@ -234,13 +232,8 @@ event_scheduler_thread(void *arg)
my_free(arg);
if (!res)
scheduler->run(thd);
- else
- {
- thd->proc_info= "Clearing";
- net_end(&thd->net);
- delete thd;
- }
+ deinit_event_thread(thd);
DBUG_LEAVE; // Against gcc warnings
my_thread_end();
return 0;
@@ -304,6 +297,7 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event)
DBUG_ENTER("Event_worker_thread::run");
DBUG_PRINT("info", ("Time is %ld, THD: 0x%lx", (long) my_time(0), (long) thd));
+ inc_thread_running();
if (res)
goto end;
@@ -332,6 +326,7 @@ end:
event->name.str));
delete event;
+ dec_thread_running();
deinit_event_thread(thd);
DBUG_VOID_RETURN;
@@ -436,13 +431,9 @@ Event_scheduler::start(int *err_no)
" Can not create thread for event scheduler (errno=%d)",
*err_no);
- new_thd->proc_info= "Clearing";
- DBUG_ASSERT(new_thd->net.buff != 0);
- net_end(&new_thd->net);
-
state= INITIALIZED;
scheduler_thd= NULL;
- delete new_thd;
+ deinit_event_thread(new_thd);
delete scheduler_param_value;
ret= true;
@@ -509,7 +500,6 @@ Event_scheduler::run(THD *thd)
}
LOCK_DATA();
- deinit_event_thread(thd);
scheduler_thd= NULL;
state= INITIALIZED;
DBUG_PRINT("info", ("Broadcasting COND_state back to the stoppers"));
@@ -569,10 +559,7 @@ Event_scheduler::execute_top(Event_queue_element_for_exec *event_name)
sql_print_error("Event_scheduler::execute_top: Can not create event worker"
" thread (errno=%d). Stopping event scheduler", res);
- new_thd->proc_info= "Clearing";
- DBUG_ASSERT(new_thd->net.buff != 0);
- net_end(&new_thd->net);
-
+ deinit_event_thread(new_thd);
goto error;
}
@@ -584,9 +571,6 @@ Event_scheduler::execute_top(Event_queue_element_for_exec *event_name)
error:
DBUG_PRINT("error", ("Event_scheduler::execute_top() res: %d", res));
- if (new_thd)
- delete new_thd;
-
delete event_name;
DBUG_RETURN(TRUE);
}
diff --git a/sql/filesort_utils.cc b/sql/filesort_utils.cc
index 34110dcfc1f..a0bc5ee6aa2 100644
--- a/sql/filesort_utils.cc
+++ b/sql/filesort_utils.cc
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#include "filesort_utils.h"
#include "sql_const.h"
diff --git a/sql/gcalc_slicescan.cc b/sql/gcalc_slicescan.cc
index f62c413fd35..ab48542add6 100644
--- a/sql/gcalc_slicescan.cc
+++ b/sql/gcalc_slicescan.cc
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#include <my_global.h>
diff --git a/sql/gcalc_slicescan.h b/sql/gcalc_slicescan.h
index 4996287ca88..b9516fc8d8c 100644
--- a/sql/gcalc_slicescan.h
+++ b/sql/gcalc_slicescan.h
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#ifndef GCALC_SLICESCAN_INCLUDED
diff --git a/sql/gcalc_tools.cc b/sql/gcalc_tools.cc
index da0252c6b67..71118ae1c9f 100644
--- a/sql/gcalc_tools.cc
+++ b/sql/gcalc_tools.cc
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#include <my_global.h>
diff --git a/sql/gcalc_tools.h b/sql/gcalc_tools.h
index 9e9b580b359..8bda3c144a6 100644
--- a/sql/gcalc_tools.h
+++ b/sql/gcalc_tools.h
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#ifndef GCALC_TOOLS_INCLUDED
diff --git a/sql/group_by_handler.cc b/sql/group_by_handler.cc
index e3420b8d48d..c1b5cfbe254 100644
--- a/sql/group_by_handler.cc
+++ b/sql/group_by_handler.cc
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/*
This file implements the group_by_handler code. This interface
diff --git a/sql/group_by_handler.h b/sql/group_by_handler.h
index b05b7fd39ae..d3f48a15c24 100644
--- a/sql/group_by_handler.h
+++ b/sql/group_by_handler.h
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/*
This file implements the group_by_handler interface. This interface
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index d1a5a7bb0ea..7f156c80205 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -7275,6 +7275,7 @@ int ha_partition::reset(void)
result= tmp;
}
bitmap_clear_all(&m_partitions_to_reset);
+ m_extra_prepare_for_update= FALSE;
DBUG_RETURN(result);
}
diff --git a/sql/handler.cc b/sql/handler.cc
index fb5d1699419..e07d656c986 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -3385,6 +3385,8 @@ void handler::print_error(int error, myf errflag)
textno=ER_FILE_USED;
break;
case ENOENT:
+ case ENOTDIR:
+ case ELOOP:
textno=ER_FILE_NOT_FOUND;
break;
case ENOSPC:
@@ -3862,7 +3864,6 @@ int handler::delete_table(const char *name)
int saved_error= 0;
int error= 0;
int enoent_or_zero;
- char buff[FN_REFLEN];
if (ht->discover_table)
enoent_or_zero= 0; // the table may not exist in the engine, it's ok
@@ -3871,8 +3872,7 @@ int handler::delete_table(const char *name)
for (const char **ext=bas_ext(); *ext ; ext++)
{
- fn_format(buff, name, "", *ext, MY_UNPACK_FILENAME|MY_APPEND_EXT);
- if (mysql_file_delete_with_symlink(key_file_misc, buff, MYF(0)))
+ if (mysql_file_delete_with_symlink(key_file_misc, name, *ext, 0))
{
if (my_errno != ENOENT)
{
@@ -4229,7 +4229,7 @@ enum_alter_inplace_result
handler::check_if_supported_inplace_alter(TABLE *altered_table,
Alter_inplace_info *ha_alter_info)
{
- DBUG_ENTER("check_if_supported_alter");
+ DBUG_ENTER("handler::check_if_supported_inplace_alter");
HA_CREATE_INFO *create_info= ha_alter_info->create_info;
@@ -5056,14 +5056,16 @@ bool ha_table_exists(THD *thd, const char *db, const char *table_name,
bool exists= true;
if (hton)
{
- enum legacy_db_type db_type;
- if (dd_frm_type(thd, path, &db_type) != FRMTYPE_VIEW)
+ char engine_buf[NAME_CHAR_LEN + 1];
+ LEX_STRING engine= { engine_buf, 0 };
+
+ if (dd_frm_type(thd, path, &engine) != FRMTYPE_VIEW)
{
- handlerton *ht= ha_resolve_by_legacy_type(thd, db_type);
- if ((*hton= ht))
+ plugin_ref p= plugin_lock_by_name(thd, &engine, MYSQL_STORAGE_ENGINE_PLUGIN);
+ *hton= p ? plugin_hton(p) : NULL;
+ if (*hton)
// verify that the table really exists
- exists= discover_existence(thd,
- plugin_int_to_ref(hton2plugin[ht->slot]), &args);
+ exists= discover_existence(thd, p, &args);
}
else
*hton= view_pseudo_hton;
diff --git a/sql/item.h b/sql/item.h
index 67640ce5f4d..6d69e3b60de 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -4930,6 +4930,11 @@ public:
virtual double val_real() = 0;
virtual longlong val_int() = 0;
virtual int save_in_field(Field *field, bool no_conversions) = 0;
+ bool walk(Item_processor processor, bool walk_subquery, void *args)
+ {
+ return (item->walk(processor, walk_subquery, args)) ||
+ (this->*processor)(args);
+ }
};
/**
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index a3b9041aed4..689ce656d60 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -645,6 +645,22 @@ int Arg_comparator::set_cmp_func(Item_func_or_sum *owner_arg,
return 0;
}
+ if (m_compare_type == REAL_RESULT &&
+ (((*a)->result_type() == DECIMAL_RESULT && !(*a)->const_item() &&
+ (*b)->result_type() == STRING_RESULT && (*b)->const_item()) ||
+ ((*b)->result_type() == DECIMAL_RESULT && !(*b)->const_item() &&
+ (*a)->result_type() == STRING_RESULT && (*a)->const_item())))
+ {
+ /*
+ <non-const decimal expression> <cmp> <const string expression>
+ or
+ <const string expression> <cmp> <non-const decimal expression>
+
+ Do comparison as decimal rather than float, in order not to lose precision.
+ */
+ m_compare_type= DECIMAL_RESULT;
+ }
+
if (m_compare_type == INT_RESULT &&
(*a)->field_type() == MYSQL_TYPE_YEAR &&
(*b)->field_type() == MYSQL_TYPE_YEAR)
@@ -5171,6 +5187,18 @@ bool Item_func_like::with_sargable_pattern() const
}
+SEL_TREE *Item_func_like::get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr)
+{
+ MEM_ROOT *tmp_root= param->mem_root;
+ param->thd->mem_root= param->old_root;
+ bool sargable_pattern= with_sargable_pattern();
+ param->thd->mem_root= tmp_root;
+ return sargable_pattern ?
+ Item_bool_func2::get_mm_tree(param, cond_ptr) :
+ Item_func::get_mm_tree(param, cond_ptr);
+}
+
+
bool fix_escape_item(THD *thd, Item *escape_item, String *tmp_str,
bool escape_used_in_parsing, CHARSET_INFO *cmp_cs,
int *escape)
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index cb51b1dda82..1a2cc3a6c81 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -1948,12 +1948,7 @@ public:
}
void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
table_map usable_tables, SARGABLE_PARAM **sargables);
- SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr)
- {
- return with_sargable_pattern() ?
- Item_bool_func2::get_mm_tree(param, cond_ptr) :
- Item_func::get_mm_tree(param, cond_ptr);
- }
+ SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr);
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
{
/*
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 2e0596da2d1..ed527cda218 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -3890,12 +3890,7 @@ longlong Item_master_pos_wait::val_int()
else
connection_name= thd->variables.default_master_connection;
- mysql_mutex_lock(&LOCK_active_mi);
- if (master_info_index) // master_info_index is set to NULL on shutdown.
- mi= master_info_index->get_master_info(&connection_name,
- Sql_condition::WARN_LEVEL_WARN);
- mysql_mutex_unlock(&LOCK_active_mi);
- if (!mi)
+ if (!(mi= get_master_info(&connection_name, Sql_condition::WARN_LEVEL_WARN)))
goto err;
if ((event_count = mi->rli.wait_for_pos(thd, log_name, pos, timeout)) == -2)
@@ -3903,6 +3898,7 @@ longlong Item_master_pos_wait::val_int()
null_value = 1;
event_count=0;
}
+ mi->release();
#endif
return event_count;
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 21f8ccb4348..b34f9fd1b58 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -33,9 +33,6 @@
#include <my_global.h> // HAVE_*
-/* May include caustic 3rd-party defs. Use early, so it can override nothing */
-#include "sha2.h"
-
#include "sql_priv.h"
/*
It is necessary to include set_var.h instead of item.h because there
@@ -51,9 +48,7 @@
#include "password.h" // my_make_scrambled_password,
// my_make_scrambled_password_323
#include <m_ctype.h>
-#include <base64.h>
#include <my_md5.h>
-#include "sha1.h"
C_MODE_START
#include "../mysys/my_static.h" // For soundex_map
C_MODE_END
@@ -171,14 +166,14 @@ String *Item_func_sha::val_str_ascii(String *str)
if (sptr) /* If we got value different from NULL */
{
/* Temporary buffer to store 160bit digest */
- uint8 digest[SHA1_HASH_SIZE];
- compute_sha1_hash(digest, (const char *) sptr->ptr(), sptr->length());
+ uint8 digest[MY_SHA1_HASH_SIZE];
+ my_sha1(digest, (const char *) sptr->ptr(), sptr->length());
/* Ensure that memory is free and we got result */
- if (!str->alloc(SHA1_HASH_SIZE*2))
+ if (!str->alloc(MY_SHA1_HASH_SIZE*2))
{
- array_to_hex((char *) str->ptr(), digest, SHA1_HASH_SIZE);
+ array_to_hex((char *) str->ptr(), digest, MY_SHA1_HASH_SIZE);
str->set_charset(&my_charset_numeric);
- str->length((uint) SHA1_HASH_SIZE*2);
+ str->length((uint) MY_SHA1_HASH_SIZE*2);
null_value=0;
return str;
}
@@ -190,18 +185,16 @@ String *Item_func_sha::val_str_ascii(String *str)
void Item_func_sha::fix_length_and_dec()
{
// size of hex representation of hash
- fix_length_and_charset(SHA1_HASH_SIZE * 2, default_charset());
+ fix_length_and_charset(MY_SHA1_HASH_SIZE * 2, default_charset());
}
String *Item_func_sha2::val_str_ascii(String *str)
{
DBUG_ASSERT(fixed == 1);
-#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
- unsigned char digest_buf[SHA512_DIGEST_LENGTH];
+ unsigned char digest_buf[512/8]; // enough for SHA512
String *input_string;
- unsigned char *input_ptr;
+ const char *input_ptr;
size_t input_len;
- uint digest_length= 0;
str->set_charset(&my_charset_bin);
@@ -216,31 +209,26 @@ String *Item_func_sha2::val_str_ascii(String *str)
if (null_value)
return (String *) NULL;
- input_ptr= (unsigned char *) input_string->ptr();
+ input_ptr= input_string->ptr();
input_len= input_string->length();
- switch ((uint) args[1]->val_int()) {
-#ifndef OPENSSL_NO_SHA512
+ longlong digest_length= args[1]->val_int();
+ switch (digest_length) {
case 512:
- digest_length= SHA512_DIGEST_LENGTH;
- (void) SHA512(input_ptr, input_len, digest_buf);
+ my_sha512(digest_buf, input_ptr, input_len);
break;
case 384:
- digest_length= SHA384_DIGEST_LENGTH;
- (void) SHA384(input_ptr, input_len, digest_buf);
+ my_sha384(digest_buf, input_ptr, input_len);
break;
-#endif
-#ifndef OPENSSL_NO_SHA256
case 224:
- digest_length= SHA224_DIGEST_LENGTH;
- (void) SHA224(input_ptr, input_len, digest_buf);
+ my_sha224(digest_buf, input_ptr, input_len);
break;
- case 256:
case 0: // SHA-256 is the default
- digest_length= SHA256_DIGEST_LENGTH;
- (void) SHA256(input_ptr, input_len, digest_buf);
+ digest_length= 256;
+ /* fall trough */
+ case 256:
+ my_sha256(digest_buf, input_ptr, input_len);
break;
-#endif
default:
if (!args[1]->const_item())
{
@@ -254,6 +242,7 @@ String *Item_func_sha2::val_str_ascii(String *str)
null_value= TRUE;
return NULL;
}
+ digest_length/= 8; /* bits to bytes */
/*
Since we're subverting the usual String methods, we must make sure that
@@ -269,17 +258,6 @@ String *Item_func_sha2::val_str_ascii(String *str)
null_value= FALSE;
return str;
-
-#else
- THD *thd= current_thd;
- push_warning_printf(thd,
- Sql_condition::WARN_LEVEL_WARN,
- ER_FEATURE_DISABLED,
- ER_THD(thd, ER_FEATURE_DISABLED),
- "sha2", "--with-ssl");
- null_value= TRUE;
- return (String *) NULL;
-#endif /* defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) */
}
@@ -288,27 +266,18 @@ void Item_func_sha2::fix_length_and_dec()
maybe_null= 1;
max_length = 0;
-#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
int sha_variant= args[1]->const_item() ? args[1]->val_int() : 512;
switch (sha_variant) {
-#ifndef OPENSSL_NO_SHA512
+ case 0: // SHA-256 is the default
+ sha_variant= 256;
+ /* fall trough */
case 512:
- fix_length_and_charset(SHA512_DIGEST_LENGTH * 2, default_charset());
- break;
case 384:
- fix_length_and_charset(SHA384_DIGEST_LENGTH * 2, default_charset());
- break;
-#endif
-#ifndef OPENSSL_NO_SHA256
case 256:
- case 0: // SHA-256 is the default
- fix_length_and_charset(SHA256_DIGEST_LENGTH * 2, default_charset());
- break;
case 224:
- fix_length_and_charset(SHA224_DIGEST_LENGTH * 2, default_charset());
+ fix_length_and_charset(sha_variant/8 * 2, default_charset());
break;
-#endif
default:
THD *thd= current_thd;
push_warning_printf(thd,
@@ -317,15 +286,6 @@ void Item_func_sha2::fix_length_and_dec()
ER_THD(thd, ER_WRONG_PARAMETERS_TO_NATIVE_FCT),
"sha2");
}
-
-#else
- THD *thd= current_thd;
- push_warning_printf(thd,
- Sql_condition::WARN_LEVEL_WARN,
- ER_FEATURE_DISABLED,
- ER_THD(thd, ER_FEATURE_DISABLED),
- "sha2", "--with-ssl");
-#endif /* defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) */
}
/* Implementation of AES encryption routines */
@@ -5203,4 +5163,3 @@ null:
my_free(names);
return NULL;
}
-
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 94bc71ca889..76c754d5627 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -934,7 +934,7 @@ void Item_subselect::update_used_tables()
if (!forced_const)
{
recalc_used_tables(parent_select, FALSE);
- if (!engine->uncacheable())
+ if (!(engine->uncacheable() & ~UNCACHEABLE_EXPLAIN))
{
// did all used tables become static?
if (!(used_tables_cache & ~engine->upper_select_const_tables()))
@@ -2113,6 +2113,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
We can encounter "NULL IN (SELECT ...)". Wrap the added condition
within a trig_cond.
*/
+ disable_cond_guard_for_const_null_left_expr(0);
item= new (thd->mem_root) Item_func_trig_cond(thd, item, get_cond_guard(0));
}
@@ -2137,6 +2138,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
having= new (thd->mem_root) Item_is_not_null_test(thd, this, having);
if (left_expr->maybe_null)
{
+ disable_cond_guard_for_const_null_left_expr(0);
if (!(having= new (thd->mem_root) Item_func_trig_cond(thd, having,
get_cond_guard(0))))
DBUG_RETURN(true);
@@ -2155,6 +2157,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
*/
if (!abort_on_null && left_expr->maybe_null)
{
+ disable_cond_guard_for_const_null_left_expr(0);
if (!(item= new (thd->mem_root) Item_func_trig_cond(thd, item,
get_cond_guard(0))))
DBUG_RETURN(true);
@@ -2184,6 +2187,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
(char *)"<result>"));
if (!abort_on_null && left_expr->maybe_null)
{
+ disable_cond_guard_for_const_null_left_expr(0);
if (!(new_having= new (thd->mem_root) Item_func_trig_cond(thd, new_having,
get_cond_guard(0))))
DBUG_RETURN(true);
@@ -2383,6 +2387,7 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join,
Item_cond_or(thd, item_eq, item_isnull);
if (!abort_on_null && left_expr->element_index(i)->maybe_null)
{
+ disable_cond_guard_for_const_null_left_expr(i);
if (!(col_item= new (thd->mem_root)
Item_func_trig_cond(thd, col_item, get_cond_guard(i))))
DBUG_RETURN(true);
@@ -2400,6 +2405,7 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join,
(char *)"<list ref>"));
if (!abort_on_null && left_expr->element_index(i)->maybe_null)
{
+ disable_cond_guard_for_const_null_left_expr(i);
if (!(item_nnull_test=
new (thd->mem_root)
Item_func_trig_cond(thd, item_nnull_test, get_cond_guard(i))))
@@ -2460,6 +2466,7 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join,
item= new (thd->mem_root) Item_cond_or(thd, item, item_isnull);
if (left_expr->element_index(i)->maybe_null)
{
+ disable_cond_guard_for_const_null_left_expr(i);
if (!(item= new (thd->mem_root)
Item_func_trig_cond(thd, item, get_cond_guard(i))))
DBUG_RETURN(true);
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 805e8958246..aa01f571a3d 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -633,6 +633,15 @@ public:
bool expr_cache_is_needed(THD *thd);
inline bool left_expr_has_null();
+ void disable_cond_guard_for_const_null_left_expr(int i)
+ {
+ if (left_expr->const_item() && !left_expr->is_expensive())
+ {
+ if (left_expr->element_index(i)->is_null())
+ set_cond_guard_var(i,FALSE);
+ }
+ }
+
int optimize(double *out_rows, double *cost);
/*
Return the identifier that we could use to identify the subquery for the
diff --git a/sql/log.cc b/sql/log.cc
index 7ad9790bb13..64c7698e2a2 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -2793,16 +2793,16 @@ int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name,
void MYSQL_QUERY_LOG::reopen_file()
{
char *save_name;
-
DBUG_ENTER("MYSQL_LOG::reopen_file");
+
+ mysql_mutex_lock(&LOCK_log);
if (!is_open())
{
DBUG_PRINT("info",("log is closed"));
+ mysql_mutex_unlock(&LOCK_log);
DBUG_VOID_RETURN;
}
- mysql_mutex_lock(&LOCK_log);
-
save_name= name;
name= 0; // Don't free name
close(LOG_CLOSE_TO_BE_OPENED);
@@ -2960,13 +2960,6 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
DBUG_ENTER("MYSQL_QUERY_LOG::write");
mysql_mutex_lock(&LOCK_log);
-
- if (!is_open())
- {
- mysql_mutex_unlock(&LOCK_log);
- DBUG_RETURN(0);
- }
-
if (is_open())
{ // Safety agains reopen
int tmp_errno= 0;
@@ -3216,7 +3209,9 @@ void MYSQL_BIN_LOG::cleanup()
stop_background_thread();
inited= 0;
+ mysql_mutex_lock(&LOCK_log);
close(LOG_CLOSE_INDEX|LOG_CLOSE_STOP_EVENT);
+ mysql_mutex_unlock(&LOCK_log);
delete description_event_for_queue;
delete description_event_for_exec;
@@ -3383,6 +3378,8 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
DBUG_ENTER("MYSQL_BIN_LOG::open");
DBUG_PRINT("enter",("log_type: %d",(int) log_type_arg));
+ mysql_mutex_assert_owner(&LOCK_log);
+
if (!is_relay_log)
{
if (!binlog_state_recover_done)
@@ -4342,7 +4339,7 @@ void MYSQL_BIN_LOG::wait_for_last_checkpoint_event()
int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
{
- int error;
+ int error, errcode;
char *to_purge_if_included= NULL;
inuse_relaylog *ir;
ulonglong log_space_reclaimed= 0;
@@ -4412,7 +4409,8 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
}
/* Store where we are in the new file for the execution thread */
- rli->flush();
+ if (rli->flush())
+ error= LOG_INFO_IO;
DBUG_EXECUTE_IF("crash_before_purge_logs", DBUG_SUICIDE(););
@@ -4428,10 +4426,10 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
* Need to update the log pos because purge logs has been called
* after fetching initially the log pos at the beginning of the method.
*/
- if((error=find_log_pos(&rli->linfo, rli->event_relay_log_name, 0)))
+ if ((errcode= find_log_pos(&rli->linfo, rli->event_relay_log_name, 0)))
{
sql_print_error("next log error: %d offset: %llu log: %s included: %d",
- error, rli->linfo.index_file_offset,
+ errcode, rli->linfo.index_file_offset,
rli->group_relay_log_name, included);
goto err;
}
@@ -5055,19 +5053,19 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock)
File UNINIT_VAR(old_file);
DBUG_ENTER("MYSQL_BIN_LOG::new_file_impl");
+ if (need_lock)
+ mysql_mutex_lock(&LOCK_log);
+ mysql_mutex_assert_owner(&LOCK_log);
+
if (!is_open())
{
DBUG_PRINT("info",("log is closed"));
+ mysql_mutex_unlock(&LOCK_log);
DBUG_RETURN(error);
}
- if (need_lock)
- mysql_mutex_lock(&LOCK_log);
mysql_mutex_lock(&LOCK_index);
- mysql_mutex_assert_owner(&LOCK_log);
- mysql_mutex_assert_owner(&LOCK_index);
-
/* Reuse old name if not binlog and not update log */
new_name_ptr= name;
@@ -5202,9 +5200,9 @@ end:
new_name_ptr, errno);
}
+ mysql_mutex_unlock(&LOCK_index);
if (need_lock)
mysql_mutex_unlock(&LOCK_log);
- mysql_mutex_unlock(&LOCK_index);
DBUG_RETURN(error);
}
@@ -8145,9 +8143,11 @@ int MYSQL_BIN_LOG::wait_for_update_binlog_end_pos(THD* thd,
void MYSQL_BIN_LOG::close(uint exiting)
{ // One can't set log_type here!
bool failed_to_save_state= false;
-
DBUG_ENTER("MYSQL_BIN_LOG::close");
DBUG_PRINT("enter",("exiting: %d", (int) exiting));
+
+ mysql_mutex_assert_owner(&LOCK_log);
+
if (log_state == LOG_OPENED)
{
#ifdef HAVE_REPLICATION
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 69d0f52d211..3aea3eaf2f1 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -46,7 +46,6 @@
#include "wsrep_mysqld.h"
#endif /* MYSQL_CLIENT */
-#include <base64.h>
#include <my_bitmap.h>
#include "rpl_utility.h"
#include "rpl_constants.h"
@@ -7219,9 +7218,11 @@ bool Rotate_log_event::write()
@retval
0 ok
+ 1 error
*/
int Rotate_log_event::do_update_pos(rpl_group_info *rgi)
{
+ int error= 0;
Relay_log_info *rli= rgi->rli;
DBUG_ENTER("Rotate_log_event::do_update_pos");
@@ -7270,7 +7271,7 @@ int Rotate_log_event::do_update_pos(rpl_group_info *rgi)
(ulong) rli->group_master_log_pos));
mysql_mutex_unlock(&rli->data_lock);
rpl_global_gtid_slave_state->record_and_update_gtid(thd, rgi);
- rli->flush();
+ error= rli->flush();
/*
Reset thd->variables.option_bits and sql_mode etc, because this could
@@ -7288,8 +7289,7 @@ int Rotate_log_event::do_update_pos(rpl_group_info *rgi)
else
rgi->inc_event_relay_log_pos();
-
- DBUG_RETURN(0);
+ DBUG_RETURN(error);
}
@@ -9053,6 +9053,7 @@ void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
int Stop_log_event::do_update_pos(rpl_group_info *rgi)
{
+ int error= 0;
Relay_log_info *rli= rgi->rli;
DBUG_ENTER("Stop_log_event::do_update_pos");
/*
@@ -9068,9 +9069,10 @@ int Stop_log_event::do_update_pos(rpl_group_info *rgi)
{
rpl_global_gtid_slave_state->record_and_update_gtid(thd, rgi);
rli->inc_group_relay_log_pos(0, rgi);
- rli->flush();
+ if (rli->flush())
+ error= 1;
}
- DBUG_RETURN(0);
+ DBUG_RETURN(error);
}
#endif /* !MYSQL_CLIENT */
@@ -11154,8 +11156,8 @@ int
Rows_log_event::do_update_pos(rpl_group_info *rgi)
{
Relay_log_info *rli= rgi->rli;
- DBUG_ENTER("Rows_log_event::do_update_pos");
int error= 0;
+ DBUG_ENTER("Rows_log_event::do_update_pos");
DBUG_PRINT("info", ("flags: %s",
get_flags(STMT_END_F) ? "STMT_END_F " : ""));
@@ -11167,7 +11169,7 @@ Rows_log_event::do_update_pos(rpl_group_info *rgi)
Step the group log position if we are not in a transaction,
otherwise increase the event log position.
*/
- rli->stmt_done(log_pos, thd, rgi);
+ error= rli->stmt_done(log_pos, thd, rgi);
/*
Clear any errors in thd->net.last_err*. It is not known if this is
needed or not. It is believed that any errors that may exist in
diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc
index 552221ee68a..381f4129321 100644
--- a/sql/log_event_old.cc
+++ b/sql/log_event_old.cc
@@ -1745,8 +1745,8 @@ int
Old_rows_log_event::do_update_pos(rpl_group_info *rgi)
{
Relay_log_info *rli= rgi->rli;
- DBUG_ENTER("Old_rows_log_event::do_update_pos");
int error= 0;
+ DBUG_ENTER("Old_rows_log_event::do_update_pos");
DBUG_PRINT("info", ("flags: %s",
get_flags(STMT_END_F) ? "STMT_END_F " : ""));
@@ -1758,7 +1758,7 @@ Old_rows_log_event::do_update_pos(rpl_group_info *rgi)
Step the group log position if we are not in a transaction,
otherwise increase the event log position.
*/
- rli->stmt_done(log_pos, thd, rgi);
+ error= rli->stmt_done(log_pos, thd, rgi);
/*
Clear any errors in thd->net.last_err*. It is not known if this is
needed or not. It is believed that any errors that may exist in
diff --git a/sql/log_slow.h b/sql/log_slow.h
index c641d2be87d..c52722f0cd7 100644
--- a/sql/log_slow.h
+++ b/sql/log_slow.h
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/* Defining what to log to slow log */
diff --git a/sql/mdl.cc b/sql/mdl.cc
index c05fdc0157b..f1a505f3d84 100644
--- a/sql/mdl.cc
+++ b/sql/mdl.cc
@@ -2126,7 +2126,8 @@ MDL_context::acquire_lock(MDL_request *mdl_request, double lock_wait_timeout)
find_deadlock();
struct timespec abs_timeout, abs_shortwait;
- set_timespec(abs_timeout, (ulonglong) lock_wait_timeout);
+ set_timespec_nsec(abs_timeout,
+ (ulonglong)(lock_wait_timeout * 1000000000ULL));
set_timespec(abs_shortwait, 1);
wait_status= MDL_wait::EMPTY;
diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc
index 5de9b4a9eec..53d0c3204a1 100644
--- a/sql/multi_range_read.cc
+++ b/sql/multi_range_read.cc
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#include "sql_parse.h"
#include <my_bit.h>
diff --git a/sql/multi_range_read.h b/sql/multi_range_read.h
index ffae6d63124..b8234998f74 100644
--- a/sql/multi_range_read.h
+++ b/sql/multi_range_read.h
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/**
@defgroup DS-MRR declarations
diff --git a/sql/my_apc.cc b/sql/my_apc.cc
index dcb8503b880..b165a801ce5 100644
--- a/sql/my_apc.cc
+++ b/sql/my_apc.cc
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#ifndef MY_APC_STANDALONE
diff --git a/sql/my_apc.h b/sql/my_apc.h
index 20b1ee4c4ec..46c6fbd549d 100644
--- a/sql/my_apc.h
+++ b/sql/my_apc.h
@@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/*
Interface
diff --git a/sql/my_json_writer.cc b/sql/my_json_writer.cc
index 135ce353552..390123fbba9 100644
--- a/sql/my_json_writer.cc
+++ b/sql/my_json_writer.cc
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#include <my_global.h>
#include "sql_priv.h"
diff --git a/sql/my_json_writer.h b/sql/my_json_writer.h
index 8ab20b10d73..c4b528ae10d 100644
--- a/sql/my_json_writer.h
+++ b/sql/my_json_writer.h
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
class Json_writer;
diff --git a/sql/mysql_install_db.cc b/sql/mysql_install_db.cc
index 58f19c427aa..5960346c60e 100644
--- a/sql/mysql_install_db.cc
+++ b/sql/mysql_install_db.cc
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/*
mysql_install_db creates a new database instance (optionally as service)
@@ -393,8 +393,8 @@ static int register_service()
CloseServiceHandle(sc_manager);
die("CreateService failed (%u)", GetLastError());
}
-
- SERVICE_DESCRIPTION sd= { "MariaDB database server" };
+ char description[] = "MariaDB database server";
+ SERVICE_DESCRIPTION sd= { description };
ChangeServiceConfig2(sc_service, SERVICE_CONFIG_DESCRIPTION, &sd);
CloseServiceHandle(sc_service);
CloseServiceHandle(sc_manager);
diff --git a/sql/mysql_upgrade_service.cc b/sql/mysql_upgrade_service.cc
index db916101eb1..36de05e54e4 100644
--- a/sql/mysql_upgrade_service.cc
+++ b/sql/mysql_upgrade_service.cc
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/*
mysql_upgrade_service upgrades mysql service on Windows.
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 7b8e3ee0ee6..6108ed6ffd4 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -21,7 +21,7 @@
#ifndef __WIN__
#include <netdb.h> // getservbyname, servent
#endif
-#include "sql_parse.h" // test_if_data_home_dir
+#include "sql_parse.h" // path_starts_from_data_home_dir
#include "sql_cache.h" // query_cache, query_cache_*
#include "sql_locale.h" // MY_LOCALES, my_locales, my_locale_by_name
#include "sql_show.h" // free_status_vars, add_status_vars,
@@ -750,12 +750,15 @@ mysql_mutex_t
LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
LOCK_crypt,
LOCK_global_system_variables,
- LOCK_user_conn, LOCK_slave_list, LOCK_active_mi,
+ LOCK_user_conn, LOCK_slave_list,
LOCK_connection_count, LOCK_error_messages, LOCK_slave_background;
mysql_mutex_t LOCK_stats, LOCK_global_user_client_stats,
LOCK_global_table_stats, LOCK_global_index_stats;
+/* This protects against changes in master_info_index */
+mysql_mutex_t LOCK_active_mi;
+
/**
The below lock protects access to two global server variables:
max_prepared_stmt_count and prepared_stmt_count. These variables
@@ -913,7 +916,7 @@ PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list,
key_LOCK_system_variables_hash, 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_master_info_sleep_lock, key_master_info_start_stop_lock,
key_mutex_slave_reporting_capability_err_lock, key_relay_log_info_data_lock,
key_rpl_group_info_sleep_lock,
key_relay_log_info_log_space_lock, key_relay_log_info_run_lock,
@@ -986,6 +989,7 @@ static PSI_mutex_info all_server_mutexes[]=
{ &key_LOCK_uuid_short_generator, "LOCK_uuid_short_generator", PSI_FLAG_GLOBAL},
{ &key_LOG_LOCK_log, "LOG::LOCK_log", 0},
{ &key_master_info_data_lock, "Master_info::data_lock", 0},
+ { &key_master_info_start_stop_lock, "Master_info::start_stop_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},
@@ -1478,7 +1482,7 @@ ulong query_cache_min_res_unit= QUERY_CACHE_MIN_RESULT_DATA_SIZE;
Query_cache query_cache;
#endif
#ifdef HAVE_SMEM
-char *shared_memory_base_name= default_shared_memory_base_name;
+const char *shared_memory_base_name= default_shared_memory_base_name;
my_bool opt_enable_shared_memory;
HANDLE smem_event_connect_request= 0;
#endif
@@ -1719,7 +1723,7 @@ static void close_connections(void)
mysql_mutex_unlock(&LOCK_thread_count); // For unlink from list
Events::deinit();
- end_slave();
+ slave_prepare_for_shutdown();
mysql_bin_log.stop_background_thread();
/*
@@ -1798,6 +1802,7 @@ static void close_connections(void)
DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
mysql_mutex_unlock(&LOCK_thread_count);
}
+ end_slave();
/* All threads has now been aborted */
DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count));
mysql_mutex_lock(&LOCK_thread_count);
@@ -2605,6 +2610,12 @@ static MYSQL_SOCKET activate_tcp_port(uint port)
(char*)&arg, sizeof(arg));
}
#endif
+
+#ifdef IP_FREEBIND
+ arg= 1;
+ (void) mysql_socket_setsockopt(ip_sock, IPPROTO_IP, IP_FREEBIND, (char*) &arg,
+ sizeof(arg));
+#endif
/*
Sometimes the port is not released fast enough when stopping and
restarting the server. This happens quite often with the test suite
@@ -2836,31 +2847,8 @@ void dec_connection_count(scheduler_functions *scheduler)
/*
- Delete THD and decrement thread counters, including thread_running
-
- This is mainly used to delete event threads which are not increasing
- global counters.
-*/
-
-void delete_running_thd(THD *thd)
-{
- thd->add_status_to_global();
- unlink_not_visible_thd(thd);
-
- delete thd;
- dec_thread_running();
-}
-
-/*
- Decrease number of threads. Signal when it reaches 0
-
- SYNOPSIS
- dec_thread_count()
-*/
-
-/*
- Send a signal to unblock close_conneciton() / rpl_slave_init_thread()
- if there is no more threads running with a THD attached
+ Send a signal to unblock close_conneciton() if there is no more
+ threads running with a THD attached
It's safe to check for thread_count and service_thread_count outside
of a mutex as we are only interested to see if they where decremented
@@ -5404,15 +5392,13 @@ static int init_server_components()
if (opt_bin_log)
{
- /**
- * mutex lock is not needed here.
- * but to be able to have mysql_mutex_assert_owner() in code,
- * we do it anyway */
- mysql_mutex_lock(mysql_bin_log.get_log_lock());
- int r= mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0, 0,
+ int error;
+ mysql_mutex_t *log_lock= mysql_bin_log.get_log_lock();
+ mysql_mutex_lock(log_lock);
+ error= mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0, 0,
WRITE_CACHE, max_binlog_size, 0, TRUE);
- mysql_mutex_unlock(mysql_bin_log.get_log_lock());
- if (r)
+ mysql_mutex_unlock(log_lock);
+ if (error)
unireg_abort(1);
}
@@ -7722,17 +7708,14 @@ static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff,
var->type= SHOW_MY_BOOL;
var->value= buff;
- mysql_mutex_lock(&LOCK_active_mi);
- if (master_info_index)
+
+ if ((mi= get_master_info(&thd->variables.default_master_connection,
+ Sql_condition::WARN_LEVEL_NOTE)))
{
- mi= master_info_index->
- get_master_info(&thd->variables.default_master_connection,
- Sql_condition::WARN_LEVEL_NOTE);
- if (mi)
- tmp= (my_bool) (mi->slave_running == MYSQL_SLAVE_RUN_READING &&
- mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN);
+ tmp= (my_bool) (mi->slave_running == MYSQL_SLAVE_RUN_READING &&
+ mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN);
+ mi->release();
}
- mysql_mutex_unlock(&LOCK_active_mi);
if (mi)
*((my_bool *)buff)= tmp;
else
@@ -7764,14 +7747,9 @@ static int show_slaves_running(THD *thd, SHOW_VAR *var, char *buff)
{
var->type= SHOW_LONGLONG;
var->value= buff;
- mysql_mutex_lock(&LOCK_active_mi);
- if (master_info_index)
- *((longlong *)buff)= master_info_index->any_slave_sql_running();
- else
- *((longlong *)buff)= 0;
+ *((longlong *)buff)= any_slave_sql_running();
- mysql_mutex_unlock(&LOCK_active_mi);
return 0;
}
@@ -7779,23 +7757,17 @@ static int show_slaves_running(THD *thd, SHOW_VAR *var, char *buff)
static int show_slave_received_heartbeats(THD *thd, SHOW_VAR *var, char *buff,
enum enum_var_type scope)
{
- Master_info *mi= NULL;
- longlong UNINIT_VAR(tmp);
+ Master_info *mi;
var->type= SHOW_LONGLONG;
var->value= buff;
- mysql_mutex_lock(&LOCK_active_mi);
- if (master_info_index)
+
+ if ((mi= get_master_info(&thd->variables.default_master_connection,
+ Sql_condition::WARN_LEVEL_NOTE)))
{
- mi= master_info_index->
- get_master_info(&thd->variables.default_master_connection,
- Sql_condition::WARN_LEVEL_NOTE);
- if (mi)
- tmp= mi->received_heartbeats;
+ *((longlong *)buff)= mi->received_heartbeats;
+ mi->release();
}
- mysql_mutex_unlock(&LOCK_active_mi);
- if (mi)
- *((longlong *)buff)= tmp;
else
var->type= SHOW_UNDEF;
return 0;
@@ -7805,23 +7777,17 @@ static int show_slave_received_heartbeats(THD *thd, SHOW_VAR *var, char *buff,
static int show_heartbeat_period(THD *thd, SHOW_VAR *var, char *buff,
enum enum_var_type scope)
{
- Master_info *mi= NULL;
- float UNINIT_VAR(tmp);
+ Master_info *mi;
var->type= SHOW_CHAR;
var->value= buff;
- mysql_mutex_lock(&LOCK_active_mi);
- if (master_info_index)
+
+ if ((mi= get_master_info(&thd->variables.default_master_connection,
+ Sql_condition::WARN_LEVEL_NOTE)))
{
- mi= master_info_index->
- get_master_info(&thd->variables.default_master_connection,
- Sql_condition::WARN_LEVEL_NOTE);
- if (mi)
- tmp= mi->heartbeat_period;
+ sprintf(buff, "%.3f", mi->heartbeat_period);
+ mi->release();
}
- mysql_mutex_unlock(&LOCK_active_mi);
- if (mi)
- sprintf(buff, "%.3f", tmp);
else
var->type= SHOW_UNDEF;
return 0;
@@ -8712,7 +8678,7 @@ static int mysql_init_variables(void)
mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0;
#if defined(HAVE_REALPATH) && !defined(HAVE_valgrind) && !defined(HAVE_BROKEN_REALPATH)
/* We can only test for sub paths if my_symlink.c is using realpath */
- myisam_test_invalid_symlink= test_if_data_home_dir;
+ mysys_test_invalid_symlink= path_starts_from_data_home_dir;
#endif
opt_log= 0;
opt_bin_log= opt_bin_log_used= 0;
diff --git a/sql/mysqld.h b/sql/mysqld.h
index 8f74194181a..613b57b133d 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -85,7 +85,6 @@ void kill_mysql(THD *thd= 0);
void close_connection(THD *thd, uint sql_errno= 0);
void handle_connection_in_main_thread(CONNECT *thd);
void create_thread_to_handle_connection(CONNECT *connect);
-void delete_running_thd(THD *thd);
void signal_thd_deleted();
void unlink_thd(THD *thd);
bool one_thread_per_connection_end(THD *thd, bool put_in_cache);
@@ -146,7 +145,8 @@ extern my_bool sp_automatic_privileges, opt_noacl;
extern ulong use_stat_tables;
extern my_bool opt_old_style_user_limits, trust_function_creators;
extern uint opt_crash_binlog_innodb;
-extern char *shared_memory_base_name, *mysqld_unix_port;
+extern const char *shared_memory_base_name;
+extern char *mysqld_unix_port;
extern my_bool opt_enable_shared_memory;
extern ulong opt_replicate_events_marked_for_skip;
extern char *default_tz_name;
@@ -295,7 +295,7 @@ extern PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list,
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_master_info_sleep_lock, key_master_info_start_stop_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_rpl_group_info_sleep_lock,
diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc
index d6a8eac7ed5..e05e43a0a59 100644
--- a/sql/nt_servc.cc
+++ b/sql/nt_servc.cc
@@ -508,7 +508,7 @@ BOOL NTService::IsService(LPCSTR ServiceName)
}
/* ------------------------------------------------------------------------
-------------------------------------------------------------------------- */
-BOOL NTService::got_service_option(char **argv, char *service_option)
+BOOL NTService::got_service_option(char **argv, const char *service_option)
{
char *option;
for (option= argv[1]; *option; option++)
diff --git a/sql/nt_servc.h b/sql/nt_servc.h
index 949499d8d7f..6781fe0ddfa 100644
--- a/sql/nt_servc.h
+++ b/sql/nt_servc.h
@@ -61,7 +61,7 @@ class NTService
BOOL SeekStatus(LPCSTR szInternName, int OperationType);
BOOL Remove(LPCSTR szInternName);
BOOL IsService(LPCSTR ServiceName);
- BOOL got_service_option(char **argv, char *service_option);
+ BOOL got_service_option(char **argv, const char *service_option);
BOOL is_super_user();
/*
diff --git a/sql/opt_index_cond_pushdown.cc b/sql/opt_index_cond_pushdown.cc
index a6707d458df..1dde5228263 100644
--- a/sql/opt_index_cond_pushdown.cc
+++ b/sql/opt_index_cond_pushdown.cc
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#include "sql_select.h"
#include "sql_test.h"
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 397ce6f7ecc..6d088cad91e 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -9297,6 +9297,13 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
if (!tmp->next_key_part)
{
+ if (key2->use_count)
+ {
+ SEL_ARG *key2_cpy= new SEL_ARG(*key2);
+ if (key2_cpy)
+ return 0;
+ key2= key2_cpy;
+ }
/*
tmp->next_key_part is empty: cut the range that is covered
by tmp from key2.
@@ -9328,13 +9335,6 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
key2: [---]
tmp: [---------]
*/
- if (key2->use_count)
- {
- SEL_ARG *key2_cpy= new SEL_ARG(*key2);
- if (key2_cpy)
- return 0;
- key2= key2_cpy;
- }
key2->copy_max_to_min(tmp);
continue;
}
diff --git a/sql/opt_range_mrr.cc b/sql/opt_range_mrr.cc
index fbccb7c4e1d..b3350191d13 100644
--- a/sql/opt_range_mrr.cc
+++ b/sql/opt_range_mrr.cc
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/****************************************************************************
MRR Range Sequence Interface implementation that walks a SEL_ARG* tree.
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index dc0caa32998..15b803ac49a 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/**
@file
diff --git a/sql/opt_subselect.h b/sql/opt_subselect.h
index 8daa973f825..7954becfad4 100644
--- a/sql/opt_subselect.h
+++ b/sql/opt_subselect.h
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/*
Semi-join subquery optimization code definitions
diff --git a/sql/opt_table_elimination.cc b/sql/opt_table_elimination.cc
index b4131093f0f..b7010d1f8ed 100644
--- a/sql/opt_table_elimination.cc
+++ b/sql/opt_table_elimination.cc
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/**
@file
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index 74c09b8a3c6..24506434a76 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -27,7 +27,7 @@
#include "sql_partition.h" // partition_info.h: LIST_PART_ENTRY
// NOT_A_PARTITION_ID
#include "partition_info.h"
-#include "sql_parse.h" // test_if_data_home_dir
+#include "sql_parse.h"
#include "sql_acl.h" // *_ACL
#include "sql_base.h" // fill_record
diff --git a/sql/password.c b/sql/password.c
index 37d06136d80..1f0a55a10fe 100644
--- a/sql/password.c
+++ b/sql/password.c
@@ -38,7 +38,7 @@
The new authentication is performed in following manner:
- SERVER: public_seed=create_random_string()
+ SERVER: public_seed=thd_create_random_password()
send(public_seed)
CLIENT: recv(public_seed)
@@ -66,7 +66,6 @@
#include <password.h>
#include <mysql.h>
#include <my_rnd.h>
-#include <sha1.h>
/************ MySQL 3.23-4.0 authentication routines: untouched ***********/
@@ -279,25 +278,6 @@ void make_password_from_salt_323(char *to, const ulong *salt)
**************** MySQL 4.1.1 authentication routines *************
*/
-/**
- Generate string of printable random characters of requested length.
-
- @param to[out] Buffer for generation; must be at least length+1 bytes
- long; result string is always null-terminated
- length[in] How many random characters to put in buffer
- rand_st Structure used for number generation
-*/
-
-void create_random_string(char *to, uint length,
- struct my_rnd_struct *rand_st)
-{
- char *end= to + length;
- /* Use pointer arithmetics as it is faster way to do so. */
- for (; to < end; to++)
- *to= (char) (my_rnd(rand_st)*94+33);
- *to= '\0';
-}
-
/* Character to use as version identifier for version 4.1 */
@@ -389,10 +369,10 @@ void compute_two_stage_sha1_hash(const char *password, size_t pass_len,
uint8 *hash_stage1, uint8 *hash_stage2)
{
/* Stage 1: hash password */
- compute_sha1_hash(hash_stage1, password, pass_len);
+ my_sha1(hash_stage1, password, pass_len);
/* Stage 2 : hash first stage's output. */
- compute_sha1_hash(hash_stage2, (const char *) hash_stage1, SHA1_HASH_SIZE);
+ my_sha1(hash_stage2, (const char *) hash_stage1, MY_SHA1_HASH_SIZE);
}
@@ -404,7 +384,7 @@ void compute_two_stage_sha1_hash(const char *password, size_t pass_len,
is stored in the database.
SYNOPSIS
my_make_scrambled_password()
- buf OUT buffer of size 2*SHA1_HASH_SIZE + 2 to store hex string
+ buf OUT buffer of size 2*MY_SHA1_HASH_SIZE + 2 to store hex string
password IN password string
pass_len IN length of password string
*/
@@ -412,14 +392,14 @@ void compute_two_stage_sha1_hash(const char *password, size_t pass_len,
void my_make_scrambled_password(char *to, const char *password,
size_t pass_len)
{
- uint8 hash_stage2[SHA1_HASH_SIZE];
+ uint8 hash_stage2[MY_SHA1_HASH_SIZE];
/* Two stage SHA1 hash of the password. */
compute_two_stage_sha1_hash(password, pass_len, (uint8 *) to, hash_stage2);
/* convert hash_stage2 to hex string */
*to++= PVERSION41_CHAR;
- octet2hex(to, (const char*) hash_stage2, SHA1_HASH_SIZE);
+ octet2hex(to, (const char*) hash_stage2, MY_SHA1_HASH_SIZE);
}
@@ -430,7 +410,7 @@ void my_make_scrambled_password(char *to, const char *password,
avoid strlen().
SYNOPSIS
make_scrambled_password()
- buf OUT buffer of size 2*SHA1_HASH_SIZE + 2 to store hex string
+ buf OUT buffer of size 2*MY_SHA1_HASH_SIZE + 2 to store hex string
password IN NULL-terminated password string
*/
@@ -451,7 +431,7 @@ void make_scrambled_password(char *to, const char *password)
SYNOPSIS
scramble()
buf OUT store scrambled string here. The buf must be at least
- SHA1_HASH_SIZE bytes long.
+ MY_SHA1_HASH_SIZE bytes long.
message IN random message, must be exactly SCRAMBLE_LENGTH long and
NULL-terminated.
password IN users' password
@@ -460,16 +440,16 @@ void make_scrambled_password(char *to, const char *password)
void
scramble(char *to, const char *message, const char *password)
{
- uint8 hash_stage1[SHA1_HASH_SIZE];
- uint8 hash_stage2[SHA1_HASH_SIZE];
+ uint8 hash_stage1[MY_SHA1_HASH_SIZE];
+ uint8 hash_stage2[MY_SHA1_HASH_SIZE];
/* Two stage SHA1 hash of the password. */
compute_two_stage_sha1_hash(password, strlen(password), hash_stage1,
hash_stage2);
/* create crypt string as sha1(message, hash_stage2) */;
- compute_sha1_hash_multi((uint8 *) to, message, SCRAMBLE_LENGTH,
- (const char *) hash_stage2, SHA1_HASH_SIZE);
+ my_sha1_multi((uint8 *) to, message, SCRAMBLE_LENGTH,
+ (const char *) hash_stage2, MY_SHA1_HASH_SIZE, NULL);
my_crypt(to, (const uchar *) to, hash_stage1, SCRAMBLE_LENGTH);
}
@@ -478,7 +458,7 @@ scramble(char *to, const char *message, const char *password)
Check that scrambled message corresponds to the password; the function
is used by server to check that received reply is authentic.
This function does not check lengths of given strings: message must be
- null-terminated, reply and hash_stage2 must be at least SHA1_HASH_SIZE
+ null-terminated, reply and hash_stage2 must be at least MY_SHA1_HASH_SIZE
long (if not, something fishy is going on).
SYNOPSIS
check_scramble()
@@ -498,19 +478,19 @@ my_bool
check_scramble(const uchar *scramble_arg, const char *message,
const uint8 *hash_stage2)
{
- uint8 buf[SHA1_HASH_SIZE];
- uint8 hash_stage2_reassured[SHA1_HASH_SIZE];
+ uint8 buf[MY_SHA1_HASH_SIZE];
+ uint8 hash_stage2_reassured[MY_SHA1_HASH_SIZE];
/* create key to encrypt scramble */
- compute_sha1_hash_multi(buf, message, SCRAMBLE_LENGTH,
- (const char *) hash_stage2, SHA1_HASH_SIZE);
+ my_sha1_multi(buf, message, SCRAMBLE_LENGTH,
+ (const char *) hash_stage2, MY_SHA1_HASH_SIZE, NULL);
/* encrypt scramble */
my_crypt((char *) buf, buf, scramble_arg, SCRAMBLE_LENGTH);
/* now buf supposedly contains hash_stage1: so we can get hash_stage2 */
- compute_sha1_hash(hash_stage2_reassured, (const char *) buf, SHA1_HASH_SIZE);
+ my_sha1(hash_stage2_reassured, (const char *) buf, MY_SHA1_HASH_SIZE);
- return MY_TEST(memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE));
+ return MY_TEST(memcmp(hash_stage2, hash_stage2_reassured, MY_SHA1_HASH_SIZE));
}
/*
@@ -518,27 +498,27 @@ check_scramble(const uchar *scramble_arg, const char *message,
SYNOPSIS
get_salt_from_password()
- res OUT buf to hold password. Must be at least SHA1_HASH_SIZE
+ res OUT buf to hold password. Must be at least MY_SHA1_HASH_SIZE
bytes long.
password IN 4.1.1 version value of user.password
*/
void get_salt_from_password(uint8 *hash_stage2, const char *password)
{
- hex2octet(hash_stage2, password+1 /* skip '*' */, SHA1_HASH_SIZE * 2);
+ hex2octet(hash_stage2, password+1 /* skip '*' */, MY_SHA1_HASH_SIZE * 2);
}
/*
Convert scrambled password from binary form to asciiz hex string.
SYNOPSIS
make_password_from_salt()
- to OUT store resulting string here, 2*SHA1_HASH_SIZE+2 bytes
+ to OUT store resulting string here, 2*MY_SHA1_HASH_SIZE+2 bytes
salt IN password in salt format
*/
void make_password_from_salt(char *to, const uint8 *hash_stage2)
{
*to++= PVERSION41_CHAR;
- octet2hex(to, (const char*) hash_stage2, SHA1_HASH_SIZE);
+ octet2hex(to, (const char*) hash_stage2, MY_SHA1_HASH_SIZE);
}
diff --git a/sql/plistsort.c b/sql/plistsort.c
index 71d287e7b45..99657410fe0 100644
--- a/sql/plistsort.c
+++ b/sql/plistsort.c
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/*
diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc
index a141d238f78..f30b7e161f2 100644
--- a/sql/rpl_mi.cc
+++ b/sql/rpl_mi.cc
@@ -40,7 +40,9 @@ Master_info::Master_info(LEX_STRING *connection_name_arg,
sync_counter(0), heartbeat_period(0), received_heartbeats(0),
master_id(0), prev_master_id(0),
using_gtid(USE_GTID_NO), events_queued_since_last_gtid(0),
- gtid_reconnect_event_skip_count(0), gtid_event_seen(false)
+ gtid_reconnect_event_skip_count(0), gtid_event_seen(false),
+ in_start_all_slaves(0), in_stop_all_slaves(0),
+ users(0), killed(0)
{
host[0] = 0; user[0] = 0; password[0] = 0;
ssl_ca[0]= 0; ssl_capath[0]= 0; ssl_cert[0]= 0;
@@ -81,6 +83,8 @@ Master_info::Master_info(LEX_STRING *connection_name_arg,
bzero((char*) &file, sizeof(file));
mysql_mutex_init(key_master_info_run_lock, &run_lock, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_master_info_data_lock, &data_lock, MY_MUTEX_INIT_FAST);
+ mysql_mutex_init(key_master_info_start_stop_lock, &start_stop_lock,
+ MY_MUTEX_INIT_SLOW);
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);
@@ -90,8 +94,27 @@ Master_info::Master_info(LEX_STRING *connection_name_arg,
mysql_cond_init(key_master_info_sleep_cond, &sleep_cond, NULL);
}
+
+/**
+ Wait until no one is using Master_info
+*/
+
+void Master_info::wait_until_free()
+{
+ mysql_mutex_lock(&sleep_lock);
+ killed= 1;
+ while (users)
+ mysql_cond_wait(&sleep_cond, &sleep_lock);
+ mysql_mutex_unlock(&sleep_lock);
+}
+
+/**
+ Delete master_info
+*/
+
Master_info::~Master_info()
{
+ wait_until_free();
#ifdef WITH_WSREP
/*
Do not free "wsrep" rpl_filter. It will eventually be freed by
@@ -106,6 +129,7 @@ Master_info::~Master_info()
mysql_mutex_destroy(&run_lock);
mysql_mutex_destroy(&data_lock);
mysql_mutex_destroy(&sleep_lock);
+ mysql_mutex_destroy(&start_stop_lock);
mysql_cond_destroy(&data_cond);
mysql_cond_destroy(&start_cond);
mysql_cond_destroy(&stop_cond);
@@ -841,12 +865,28 @@ uchar *get_key_master_info(Master_info *mi, size_t *length,
return (uchar*) mi->cmp_connection_name.str;
}
+/*
+ Delete a master info
+
+ Called from my_hash_delete(&master_info_hash)
+ Stops associated slave threads and frees master_info
+*/
+
void free_key_master_info(Master_info *mi)
{
DBUG_ENTER("free_key_master_info");
+ mysql_mutex_unlock(&LOCK_active_mi);
+
+ /* Ensure that we are not in reset_slave while this is done */
+ mi->lock_slave_threads();
terminate_slave_threads(mi,SLAVE_FORCE_ALL);
+ /* We use 2 here instead of 1 just to make it easier when debugging */
+ mi->killed= 2;
end_master_info(mi);
+ mi->unlock_slave_threads();
delete mi;
+
+ mysql_mutex_lock(&LOCK_active_mi);
DBUG_VOID_RETURN;
}
@@ -1002,9 +1042,28 @@ Master_info_index::Master_info_index()
index_file.file= -1;
}
+
+/**
+ Free all connection threads
+
+ This is done during early stages of shutdown
+ to give connection threads and slave threads time
+ to die before ~Master_info_index is called
+*/
+
+void Master_info_index::free_connections()
+{
+ mysql_mutex_assert_owner(&LOCK_active_mi);
+ my_hash_reset(&master_info_hash);
+}
+
+
+/**
+ Free all connection threads and free structures
+*/
+
Master_info_index::~Master_info_index()
{
- /* This will close connection for all objects in the cache */
my_hash_free(&master_info_hash);
end_io_cache(&index_file);
if (index_file.file >= 0)
@@ -1025,9 +1084,9 @@ bool Master_info_index::init_all_master_info()
int err_num= 0, succ_num= 0; // The number of success read Master_info
char sign[MAX_CONNECTION_NAME+1];
File index_file_nr;
+ THD *thd;
DBUG_ENTER("init_all_master_info");
- mysql_mutex_assert_owner(&LOCK_active_mi);
DBUG_ASSERT(master_info_index);
if ((index_file_nr= my_open(index_file_name,
@@ -1057,6 +1116,10 @@ bool Master_info_index::init_all_master_info()
DBUG_RETURN(1);
}
+ thd= new THD(next_thread_id()); /* Needed by start_slave_threads */
+ thd->thread_stack= (char*) &thd;
+ thd->store_globals();
+
reinit_io_cache(&index_file, READ_CACHE, 0L,0,0);
while (!init_strvar_from_file(sign, sizeof(sign),
&index_file, NULL))
@@ -1072,10 +1135,9 @@ bool Master_info_index::init_all_master_info()
mi->error())
{
delete mi;
- DBUG_RETURN(1);
+ goto error;
}
- lock_slave_threads(mi);
init_thread_mask(&thread_mask,mi,0 /*not inverse*/);
create_logfile_name_with_suffix(buf_master_info_file,
@@ -1090,6 +1152,7 @@ bool Master_info_index::init_all_master_info()
sql_print_information("Reading Master_info: '%s' Relay_info:'%s'",
buf_master_info_file, buf_relay_log_info_file);
+ mi->lock_slave_threads();
if (init_master_info(mi, buf_master_info_file, buf_relay_log_info_file,
0, thread_mask))
{
@@ -1101,17 +1164,18 @@ bool Master_info_index::init_all_master_info()
{
/* Master_info is not in HASH; Add it */
if (master_info_index->add_master_info(mi, FALSE))
- DBUG_RETURN(1);
+ goto error;
succ_num++;
- unlock_slave_threads(mi);
+ mi->unlock_slave_threads();
}
else
{
/* Master_info already in HASH */
sql_print_error(ER_THD_OR_DEFAULT(current_thd,
ER_CONNECTION_ALREADY_EXISTS),
+ (int) connection_name.length, connection_name.str,
(int) connection_name.length, connection_name.str);
- unlock_slave_threads(mi);
+ mi->unlock_slave_threads();
delete mi;
}
continue;
@@ -1128,23 +1192,23 @@ bool Master_info_index::init_all_master_info()
/* Master_info was already registered */
sql_print_error(ER_THD_OR_DEFAULT(current_thd,
ER_CONNECTION_ALREADY_EXISTS),
+ (int) connection_name.length, connection_name.str,
(int) connection_name.length, connection_name.str);
- unlock_slave_threads(mi);
+ mi->unlock_slave_threads();
delete mi;
continue;
}
/* Master_info was not registered; add it */
if (master_info_index->add_master_info(mi, FALSE))
- DBUG_RETURN(1);
+ goto error;
succ_num++;
- unlock_slave_threads(mi);
if (!opt_skip_slave_start)
{
if (start_slave_threads(current_thd,
1 /* need mutex */,
- 0 /* no wait for start*/,
+ 1 /* wait for start*/,
mi,
buf_master_info_file,
buf_relay_log_info_file,
@@ -1160,8 +1224,11 @@ bool Master_info_index::init_all_master_info()
(int) connection_name.length,
connection_name.str);
}
+ mi->unlock_slave_threads();
}
}
+ thd->reset_globals();
+ delete thd;
if (!err_num) // No Error on read Master_info
{
@@ -1169,16 +1236,19 @@ bool Master_info_index::init_all_master_info()
sql_print_information("Reading of all Master_info entries succeded");
DBUG_RETURN(0);
}
- else if (succ_num) // Have some Error and some Success
+ if (succ_num) // Have some Error and some Success
{
sql_print_warning("Reading of some Master_info entries failed");
DBUG_RETURN(1);
}
- else // All failed
- {
- sql_print_error("Reading of all Master_info entries failed!");
- DBUG_RETURN(1);
- }
+
+ sql_print_error("Reading of all Master_info entries failed!");
+ DBUG_RETURN(1);
+
+error:
+ thd->reset_globals();
+ delete thd;
+ DBUG_RETURN(1);
}
@@ -1211,6 +1281,71 @@ bool Master_info_index::write_master_name_to_index_file(LEX_STRING *name,
/**
+ Get Master_info for a connection and lock the object from deletion
+
+ @param
+ connection_name Connection name
+ warning WARN_LEVEL_NOTE -> Don't print anything
+ WARN_LEVEL_WARN -> Issue warning if not exists
+ WARN_LEVEL_ERROR-> Issue error if not exists
+*/
+
+Master_info *get_master_info(const LEX_STRING *connection_name,
+ Sql_condition::enum_warning_level warning)
+{
+ Master_info *mi;
+ DBUG_ENTER("get_master_info");
+
+ /* Protect against inserts into hash */
+ mysql_mutex_lock(&LOCK_active_mi);
+ /*
+ The following can only be true during shutdown when slave has been killed
+ but some other threads are still trying to access slave statistics.
+ */
+ if (unlikely(!master_info_index))
+ {
+ if (warning != Sql_condition::WARN_LEVEL_NOTE)
+ my_error(WARN_NO_MASTER_INFO,
+ MYF(warning == Sql_condition::WARN_LEVEL_WARN ?
+ ME_JUST_WARNING : 0),
+ (int) connection_name->length, connection_name->str);
+ mysql_mutex_unlock(&LOCK_active_mi);
+ DBUG_RETURN(0);
+ }
+ if ((mi= master_info_index->get_master_info(connection_name, warning)))
+ {
+ /*
+ We have to use sleep_lock here. If we would use LOCK_active_mi
+ then we would take locks in wrong order in Master_info::release()
+ */
+ mysql_mutex_lock(&mi->sleep_lock);
+ mi->users++;
+ DBUG_PRINT("info",("users: %d", mi->users));
+ mysql_mutex_unlock(&mi->sleep_lock);
+ }
+ mysql_mutex_unlock(&LOCK_active_mi);
+ DBUG_RETURN(mi);
+}
+
+
+/**
+ Release master info.
+ Signals ~Master_info that it's now safe to delete it
+*/
+
+void Master_info::release()
+{
+ mysql_mutex_lock(&sleep_lock);
+ if (!--users && killed)
+ {
+ /* Signal ~Master_info that it's ok to now free it */
+ mysql_cond_signal(&sleep_cond);
+ }
+ mysql_mutex_unlock(&sleep_lock);
+}
+
+
+/**
Get Master_info for a connection
@param
@@ -1232,8 +1367,6 @@ Master_info_index::get_master_info(const LEX_STRING *connection_name,
("connection_name: '%.*s'", (int) connection_name->length,
connection_name->str));
- mysql_mutex_assert_owner(&LOCK_active_mi);
-
/* Make name lower case for comparison */
res= strmake(buff, connection_name->str, connection_name->length);
my_casedn_str(system_charset_info, buff);
@@ -1299,7 +1432,12 @@ bool Master_info_index::check_duplicate_master_info(LEX_STRING *name_arg,
/* Add a Master_info class to Hash Table */
bool Master_info_index::add_master_info(Master_info *mi, bool write_to_file)
{
- if (!my_hash_insert(&master_info_hash, (uchar*) mi))
+ /*
+ We have to protect against shutdown to ensure we are not calling
+ my_hash_insert() while my_hash_free() is in progress
+ */
+ if (unlikely(shutdown_in_progress) ||
+ !my_hash_insert(&master_info_hash, (uchar*) mi))
{
if (global_system_variables.log_warnings > 1)
sql_print_information("Added new Master_info '%.*s' to hash table",
@@ -1325,105 +1463,131 @@ bool Master_info_index::add_master_info(Master_info *mi, bool write_to_file)
atomic
*/
-bool Master_info_index::remove_master_info(LEX_STRING *name)
+bool Master_info_index::remove_master_info(Master_info *mi)
{
- Master_info* mi;
DBUG_ENTER("remove_master_info");
+ mysql_mutex_assert_owner(&LOCK_active_mi);
- if ((mi= get_master_info(name, Sql_condition::WARN_LEVEL_WARN)))
+ // Delete Master_info and rewrite others to file
+ if (!my_hash_delete(&master_info_hash, (uchar*) mi))
{
- // Delete Master_info and rewrite others to file
- if (!my_hash_delete(&master_info_hash, (uchar*) mi))
+ File index_file_nr;
+
+ // Close IO_CACHE and FILE handler fisrt
+ end_io_cache(&index_file);
+ my_close(index_file.file, MYF(MY_WME));
+
+ // Reopen File and truncate it
+ if ((index_file_nr= my_open(index_file_name,
+ O_RDWR | O_CREAT | O_TRUNC | O_BINARY ,
+ MYF(MY_WME))) < 0 ||
+ init_io_cache(&index_file, index_file_nr,
+ IO_SIZE, WRITE_CACHE,
+ my_seek(index_file_nr,0L,MY_SEEK_END,MYF(0)),
+ 0, MYF(MY_WME | MY_WAIT_IF_FULL)))
{
- File index_file_nr;
-
- // Close IO_CACHE and FILE handler fisrt
- end_io_cache(&index_file);
- my_close(index_file.file, MYF(MY_WME));
-
- // Reopen File and truncate it
- if ((index_file_nr= my_open(index_file_name,
- O_RDWR | O_CREAT | O_TRUNC | O_BINARY ,
- MYF(MY_WME))) < 0 ||
- init_io_cache(&index_file, index_file_nr,
- IO_SIZE, WRITE_CACHE,
- my_seek(index_file_nr,0L,MY_SEEK_END,MYF(0)),
- 0, MYF(MY_WME | MY_WAIT_IF_FULL)))
- {
- int error= my_errno;
- if (index_file_nr >= 0)
- my_close(index_file_nr,MYF(0));
-
- sql_print_error("Create of Master Info Index file '%s' failed with "
- "error: %M",
- index_file_name, error);
- DBUG_RETURN(TRUE);
- }
+ int error= my_errno;
+ if (index_file_nr >= 0)
+ my_close(index_file_nr,MYF(0));
- // Rewrite Master_info.index
- for (uint i= 0; i< master_info_hash.records; ++i)
- {
- Master_info *tmp_mi;
- tmp_mi= (Master_info *) my_hash_element(&master_info_hash, i);
- write_master_name_to_index_file(&tmp_mi->connection_name, 0);
- }
- my_sync(index_file_nr, MYF(MY_WME));
+ sql_print_error("Create of Master Info Index file '%s' failed with "
+ "error: %M",
+ index_file_name, error);
+ DBUG_RETURN(TRUE);
+ }
+
+ // Rewrite Master_info.index
+ for (uint i= 0; i< master_info_hash.records; ++i)
+ {
+ Master_info *tmp_mi;
+ tmp_mi= (Master_info *) my_hash_element(&master_info_hash, i);
+ write_master_name_to_index_file(&tmp_mi->connection_name, 0);
}
+ if (my_sync(index_file_nr, MYF(MY_WME)))
+ DBUG_RETURN(TRUE);
}
DBUG_RETURN(FALSE);
}
/**
- Master_info_index::give_error_if_slave_running()
+ give_error_if_slave_running()
+
+ @param
+ already_locked 0 if we need to lock, 1 if we have LOCK_active_mi_locked
@return
TRUE If some slave is running. An error is printed
FALSE No slave is running
*/
-bool Master_info_index::give_error_if_slave_running()
+bool give_error_if_slave_running(bool already_locked)
{
+ bool ret= 0;
DBUG_ENTER("give_error_if_slave_running");
- mysql_mutex_assert_owner(&LOCK_active_mi);
- for (uint i= 0; i< master_info_hash.records; ++i)
+ if (!already_locked)
+ mysql_mutex_lock(&LOCK_active_mi);
+ if (!master_info_index)
{
- Master_info *mi;
- mi= (Master_info *) my_hash_element(&master_info_hash, i);
- if (mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN)
+ my_error(ER_SERVER_SHUTDOWN, MYF(0));
+ ret= 1;
+ }
+ else
+ {
+ HASH *hash= &master_info_index->master_info_hash;
+ for (uint i= 0; i< hash->records; ++i)
{
- my_error(ER_SLAVE_MUST_STOP, MYF(0), (int) mi->connection_name.length,
- mi->connection_name.str);
- DBUG_RETURN(TRUE);
+ Master_info *mi;
+ mi= (Master_info *) my_hash_element(hash, i);
+ if (mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN)
+ {
+ my_error(ER_SLAVE_MUST_STOP, MYF(0), (int) mi->connection_name.length,
+ mi->connection_name.str);
+ ret= 1;
+ break;
+ }
}
}
- DBUG_RETURN(FALSE);
+ if (!already_locked)
+ mysql_mutex_unlock(&LOCK_active_mi);
+ DBUG_RETURN(ret);
}
/**
- Master_info_index::any_slave_sql_running()
-
- The LOCK_active_mi must be held while calling this function.
+ any_slave_sql_running()
@return
0 No Slave SQL thread is running
# Number of slave SQL thread running
+
+ Note that during shutdown we return 1. This is needed to ensure we
+ don't try to resize thread pool during shutdown as during shutdown
+ master_info_hash may be freeing the hash and during that time
+ hash entries can't be accessed.
*/
-uint Master_info_index::any_slave_sql_running()
+uint any_slave_sql_running()
{
uint count= 0;
+ HASH *hash;
DBUG_ENTER("any_slave_sql_running");
- mysql_mutex_assert_owner(&LOCK_active_mi);
- for (uint i= 0; i< master_info_hash.records; ++i)
+ mysql_mutex_lock(&LOCK_active_mi);
+ if (unlikely(shutdown_in_progress || !master_info_index))
{
- Master_info *mi= (Master_info *)my_hash_element(&master_info_hash, i);
+ mysql_mutex_unlock(&LOCK_active_mi);
+ DBUG_RETURN(1);
+ }
+ hash= &master_info_index->master_info_hash;
+ for (uint i= 0; i< hash->records; ++i)
+ {
+ Master_info *mi= (Master_info *)my_hash_element(hash, i);
if (mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN)
count++;
}
+ mysql_mutex_unlock(&LOCK_active_mi);
DBUG_RETURN(count);
}
@@ -1436,15 +1600,25 @@ uint Master_info_index::any_slave_sql_running()
@return
TRUE Error
FALSE Everything ok.
+
+ This code is written so that we don't keep LOCK_active_mi active
+ while we are starting a slave.
*/
bool Master_info_index::start_all_slaves(THD *thd)
{
bool result= FALSE;
- DBUG_ENTER("warn_if_slave_running");
+ DBUG_ENTER("start_all_slaves");
mysql_mutex_assert_owner(&LOCK_active_mi);
- for (uint i= 0; i< master_info_hash.records; ++i)
+ for (uint i= 0; i< master_info_hash.records; i++)
+ {
+ Master_info *mi;
+ mi= (Master_info *) my_hash_element(&master_info_hash, i);
+ mi->in_start_all_slaves= 0;
+ }
+
+ for (uint i= 0; i< master_info_hash.records; )
{
int error;
Master_info *mi;
@@ -1454,25 +1628,40 @@ bool Master_info_index::start_all_slaves(THD *thd)
Try to start all slaves that are configured (host is defined)
and are not already running
*/
- if ((mi->slave_running == MYSQL_SLAVE_NOT_RUN ||
- !mi->rli.slave_running) && *mi->host)
+ if (!((mi->slave_running == MYSQL_SLAVE_NOT_RUN ||
+ !mi->rli.slave_running) && *mi->host) ||
+ mi->in_start_all_slaves)
{
- if ((error= start_slave(thd, mi, 1)))
- {
- my_error(ER_CANT_START_STOP_SLAVE, MYF(0),
- "START",
- (int) mi->connection_name.length,
- mi->connection_name.str);
- result= 1;
- if (error < 0) // fatal error
- break;
- }
- else if (thd)
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
- ER_SLAVE_STARTED, ER_THD(thd, ER_SLAVE_STARTED),
- (int) mi->connection_name.length,
- mi->connection_name.str);
+ i++;
+ continue;
+ }
+ mi->in_start_all_slaves= 1;
+
+ mysql_mutex_lock(&mi->sleep_lock);
+ mi->users++; // Mark used
+ mysql_mutex_unlock(&mi->sleep_lock);
+ mysql_mutex_unlock(&LOCK_active_mi);
+ error= start_slave(thd, mi, 1);
+ mi->release();
+ mysql_mutex_lock(&LOCK_active_mi);
+ if (error)
+ {
+ my_error(ER_CANT_START_STOP_SLAVE, MYF(0),
+ "START",
+ (int) mi->connection_name.length,
+ mi->connection_name.str);
+ result= 1;
+ if (error < 0) // fatal error
+ break;
}
+ else if (thd)
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
+ ER_SLAVE_STARTED, ER_THD(thd, ER_SLAVE_STARTED),
+ (int) mi->connection_name.length,
+ mi->connection_name.str);
+ /* Restart from first element as master_info_hash may have changed */
+ i= 0;
+ continue;
}
DBUG_RETURN(result);
}
@@ -1488,39 +1677,64 @@ bool Master_info_index::start_all_slaves(THD *thd)
@return
TRUE Error
FALSE Everything ok.
+
+ This code is written so that we don't keep LOCK_active_mi active
+ while we are stopping a slave.
*/
bool Master_info_index::stop_all_slaves(THD *thd)
{
bool result= FALSE;
- DBUG_ENTER("warn_if_slave_running");
+ DBUG_ENTER("stop_all_slaves");
mysql_mutex_assert_owner(&LOCK_active_mi);
DBUG_ASSERT(thd);
- for (uint i= 0; i< master_info_hash.records; ++i)
+ for (uint i= 0; i< master_info_hash.records; i++)
+ {
+ Master_info *mi;
+ mi= (Master_info *) my_hash_element(&master_info_hash, i);
+ mi->in_stop_all_slaves= 0;
+ }
+
+ for (uint i= 0; i< master_info_hash.records ;)
{
int error;
Master_info *mi;
mi= (Master_info *) my_hash_element(&master_info_hash, i);
- if ((mi->slave_running != MYSQL_SLAVE_NOT_RUN ||
- mi->rli.slave_running))
+ if (!(mi->slave_running != MYSQL_SLAVE_NOT_RUN ||
+ mi->rli.slave_running) ||
+ mi->in_stop_all_slaves)
{
- if ((error= stop_slave(thd, mi, 1)))
- {
- my_error(ER_CANT_START_STOP_SLAVE, MYF(0),
- "STOP",
- (int) mi->connection_name.length,
- mi->connection_name.str);
- result= 1;
- if (error < 0) // Fatal error
- break;
- }
- else
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
- ER_SLAVE_STOPPED, ER_THD(thd, ER_SLAVE_STOPPED),
- (int) mi->connection_name.length,
- mi->connection_name.str);
+ i++;
+ continue;
}
+ mi->in_stop_all_slaves= 1; // Protection for loops
+
+ mysql_mutex_lock(&mi->sleep_lock);
+ mi->users++; // Mark used
+ mysql_mutex_unlock(&mi->sleep_lock);
+ mysql_mutex_unlock(&LOCK_active_mi);
+ error= stop_slave(thd, mi, 1);
+ mi->release();
+ mysql_mutex_lock(&LOCK_active_mi);
+ if (error)
+ {
+ my_error(ER_CANT_START_STOP_SLAVE, MYF(0),
+ "STOP",
+ (int) mi->connection_name.length,
+ mi->connection_name.str);
+ result= 1;
+ if (error < 0) // Fatal error
+ break;
+ }
+ else
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
+ ER_SLAVE_STOPPED, ER_THD(thd, ER_SLAVE_STOPPED),
+ (int) mi->connection_name.length,
+ mi->connection_name.str);
+ /* Restart from first element as master_info_hash may have changed */
+ i= 0;
+ continue;
}
DBUG_RETURN(result);
}
diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h
index 9365c065ea9..31c0f280ac1 100644
--- a/sql/rpl_mi.h
+++ b/sql/rpl_mi.h
@@ -187,6 +187,10 @@ class Master_info : public Slave_reporting_capability
return opt_slave_parallel_threads > 0 &&
parallel_mode > SLAVE_PARALLEL_NONE;
}
+ void release();
+ void wait_until_free();
+ void lock_slave_threads();
+ void unlock_slave_threads();
/* the variables below are needed because we can change masters on the fly */
char master_log_name[FN_REFLEN+6]; /* Room for multi-*/
@@ -205,7 +209,7 @@ 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, sleep_lock;
+ mysql_mutex_t data_lock, run_lock, sleep_lock, start_stop_lock;
mysql_cond_t data_cond, start_cond, stop_cond, sleep_cond;
THD *io_thd;
MYSQL* mysql;
@@ -297,6 +301,9 @@ class Master_info : public Slave_reporting_capability
uint64 gtid_reconnect_event_skip_count;
/* gtid_event_seen is false until we receive first GTID event from master. */
bool gtid_event_seen;
+ bool in_start_all_slaves, in_stop_all_slaves;
+ uint users; /* Active user for object */
+ uint killed;
/* domain-id based filter */
Domain_id_filter domain_id_filter;
@@ -341,13 +348,12 @@ public:
bool check_duplicate_master_info(LEX_STRING *connection_name,
const char *host, uint port);
bool add_master_info(Master_info *mi, bool write_to_file);
- bool remove_master_info(LEX_STRING *connection_name);
+ bool remove_master_info(Master_info *mi);
Master_info *get_master_info(const LEX_STRING *connection_name,
Sql_condition::enum_warning_level warning);
- bool give_error_if_slave_running();
- uint any_slave_sql_running();
bool start_all_slaves(THD *thd);
bool stop_all_slaves(THD *thd);
+ void free_connections();
};
@@ -360,6 +366,8 @@ public:
};
+Master_info *get_master_info(const LEX_STRING *connection_name,
+ Sql_condition::enum_warning_level warning);
bool check_master_connection_name(LEX_STRING *name);
void create_logfile_name_with_suffix(char *res_file_name, size_t length,
const char *info_file,
@@ -369,5 +377,8 @@ void create_logfile_name_with_suffix(char *res_file_name, size_t length,
uchar *get_key_master_info(Master_info *mi, size_t *length,
my_bool not_used __attribute__((unused)));
void free_key_master_info(Master_info *mi);
+uint any_slave_sql_running();
+bool give_error_if_slave_running(bool already_lock);
+
#endif /* HAVE_REPLICATION */
#endif /* RPL_MI_H */
diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc
index f7aab704c43..6788f422cbd 100644
--- a/sql/rpl_parallel.cc
+++ b/sql/rpl_parallel.cc
@@ -1320,39 +1320,16 @@ handle_rpl_parallel_thread(void *arg)
*/
rpt->batch_free();
- for (;;)
+ if ((events= rpt->event_queue) != NULL)
{
- if ((events= rpt->event_queue) != NULL)
- {
- /*
- Take next group of events from the replication pool.
- This is faster than having to wakeup the pool manager thread to give
- us a new event.
- */
- rpt->dequeue1(events);
- mysql_mutex_unlock(&rpt->LOCK_rpl_thread);
- goto more_events;
- }
- if (!rpt->pause_for_ftwrl ||
- (in_event_group && !group_rgi->parallel_entry->force_abort))
- break;
/*
- We are currently in the delicate process of pausing parallel
- replication while FLUSH TABLES WITH READ LOCK is starting. We must
- not de-allocate the thread (setting rpt->current_owner= NULL) until
- rpl_unpause_after_ftwrl() has woken us up.
+ Take next group of events from the replication pool.
+ This is faster than having to wakeup the pool manager thread to give
+ us a new event.
*/
- mysql_mutex_lock(&rpt->current_entry->LOCK_parallel_entry);
+ rpt->dequeue1(events);
mysql_mutex_unlock(&rpt->LOCK_rpl_thread);
- if (rpt->pause_for_ftwrl)
- mysql_cond_wait(&rpt->current_entry->COND_parallel_entry,
- &rpt->current_entry->LOCK_parallel_entry);
- mysql_mutex_unlock(&rpt->current_entry->LOCK_parallel_entry);
- mysql_mutex_lock(&rpt->LOCK_rpl_thread);
- /*
- Now loop to check again for more events available, since we released
- and re-aquired the LOCK_rpl_thread mutex.
- */
+ goto more_events;
}
rpt->inuse_relaylog_refcount_update();
@@ -1379,11 +1356,35 @@ handle_rpl_parallel_thread(void *arg)
}
if (!in_event_group)
{
+ /* If we are in a FLUSH TABLES FOR READ LOCK, wait for it */
+ while (rpt->current_entry && rpt->pause_for_ftwrl)
+ {
+ /*
+ We are currently in the delicate process of pausing parallel
+ replication while FLUSH TABLES WITH READ LOCK is starting. We must
+ not de-allocate the thread (setting rpt->current_owner= NULL) until
+ rpl_unpause_after_ftwrl() has woken us up.
+ */
+ rpl_parallel_entry *e= rpt->current_entry;
+ /*
+ Wait for rpl_unpause_after_ftwrl() to wake us up.
+ Note that rpl_pause_for_ftwrl() may wait for 'e->pause_sub_id'
+ to change. This should happen eventually in finish_event_group()
+ */
+ mysql_mutex_lock(&e->LOCK_parallel_entry);
+ mysql_mutex_unlock(&rpt->LOCK_rpl_thread);
+ if (rpt->pause_for_ftwrl)
+ mysql_cond_wait(&e->COND_parallel_entry, &e->LOCK_parallel_entry);
+ mysql_mutex_unlock(&e->LOCK_parallel_entry);
+ mysql_mutex_lock(&rpt->LOCK_rpl_thread);
+ }
+
rpt->current_owner= NULL;
/* Tell wait_for_done() that we are done, if it is waiting. */
if (likely(rpt->current_entry) &&
unlikely(rpt->current_entry->force_abort))
mysql_cond_broadcast(&rpt->COND_rpl_thread_stop);
+
rpt->current_entry= NULL;
if (!rpt->stop)
rpt->pool->release_thread(rpt);
@@ -1422,10 +1423,24 @@ dealloc_gco(group_commit_orderer *gco)
my_free(gco);
}
+/**
+ Change thread count for global parallel worker threads
+
+ @param pool parallel thread pool
+ @param new_count Number of threads to be in pool. 0 in shutdown
+ @param force Force thread count to new_count even if slave
+ threads are running
+
+ By default we don't resize pool of there are running threads.
+ However during shutdown we will always do it.
+ This is needed as any_slave_sql_running() returns 1 during shutdown
+ as we don't want to access master_info while
+ Master_info_index::free_connections are running.
+*/
static int
rpl_parallel_change_thread_count(rpl_parallel_thread_pool *pool,
- uint32 new_count)
+ uint32 new_count, bool force)
{
uint32 i;
rpl_parallel_thread **old_list= NULL;
@@ -1437,6 +1452,28 @@ rpl_parallel_change_thread_count(rpl_parallel_thread_pool *pool,
if ((res= pool_mark_busy(pool, current_thd)))
return res;
+ /* Protect against parallel pool resizes */
+ if (pool->count == new_count)
+ {
+ pool_mark_not_busy(pool);
+ return 0;
+ }
+
+ /*
+ If we are about to delete pool, do an extra check that there are no new
+ slave threads running since we marked pool busy
+ */
+ if (!new_count && !force)
+ {
+ if (any_slave_sql_running())
+ {
+ DBUG_PRINT("warning",
+ ("SQL threads running while trying to reset parallel pool"));
+ pool_mark_not_busy(pool);
+ return 0; // Ok to not resize pool
+ }
+ }
+
/*
Allocate the new list of threads up-front.
That way, if we fail half-way, we only need to free whatever we managed
@@ -1450,7 +1487,7 @@ rpl_parallel_change_thread_count(rpl_parallel_thread_pool *pool,
{
my_error(ER_OUTOFMEMORY, MYF(0), (int(new_count*sizeof(*new_list) +
new_count*sizeof(*rpt_array))));
- goto err;;
+ goto err;
}
for (i= 0; i < new_count; ++i)
@@ -1575,12 +1612,26 @@ err:
return 1;
}
+/*
+ Deactivate the parallel replication thread pool, if there are now no more
+ SQL threads running.
+*/
+
+int rpl_parallel_resize_pool_if_no_slaves(void)
+{
+ /* master_info_index is set to NULL on shutdown */
+ if (opt_slave_parallel_threads > 0 && !any_slave_sql_running())
+ return rpl_parallel_inactivate_pool(&global_rpl_thread_pool);
+ return 0;
+}
+
int
rpl_parallel_activate_pool(rpl_parallel_thread_pool *pool)
{
if (!pool->count)
- return rpl_parallel_change_thread_count(pool, opt_slave_parallel_threads);
+ return rpl_parallel_change_thread_count(pool, opt_slave_parallel_threads,
+ 0);
return 0;
}
@@ -1588,7 +1639,7 @@ rpl_parallel_activate_pool(rpl_parallel_thread_pool *pool)
int
rpl_parallel_inactivate_pool(rpl_parallel_thread_pool *pool)
{
- return rpl_parallel_change_thread_count(pool, 0);
+ return rpl_parallel_change_thread_count(pool, 0, 0);
}
@@ -1866,7 +1917,7 @@ rpl_parallel_thread_pool::destroy()
{
if (!inited)
return;
- rpl_parallel_change_thread_count(this, 0);
+ rpl_parallel_change_thread_count(this, 0, 1);
mysql_mutex_destroy(&LOCK_rpl_thread_pool);
mysql_cond_destroy(&COND_rpl_thread_pool);
inited= false;
@@ -1885,6 +1936,7 @@ rpl_parallel_thread_pool::get_thread(rpl_parallel_thread **owner,
{
rpl_parallel_thread *rpt;
+ DBUG_ASSERT(count > 0);
mysql_mutex_lock(&LOCK_rpl_thread_pool);
while (unlikely(busy) || !(rpt= free_list))
mysql_cond_wait(&COND_rpl_thread_pool, &LOCK_rpl_thread_pool);
@@ -2113,6 +2165,11 @@ rpl_parallel::find(uint32 domain_id)
return e;
}
+/**
+ Wait until all sql worker threads has stopped processing
+
+ This is called when sql thread has been killed/stopped
+*/
void
rpl_parallel::wait_for_done(THD *thd, Relay_log_info *rli)
diff --git a/sql/rpl_parallel.h b/sql/rpl_parallel.h
index c6f77b0144c..a0faeae815c 100644
--- a/sql/rpl_parallel.h
+++ b/sql/rpl_parallel.h
@@ -365,6 +365,7 @@ struct rpl_parallel {
extern struct rpl_parallel_thread_pool global_rpl_thread_pool;
+extern int rpl_parallel_resize_pool_if_no_slaves(void);
extern int rpl_parallel_activate_pool(rpl_parallel_thread_pool *pool);
extern int rpl_parallel_inactivate_pool(rpl_parallel_thread_pool *pool);
extern bool process_gtid_for_restart_pos(Relay_log_info *rli, rpl_gtid *gtid);
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index cd189b4ab2d..fda922c3e12 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -207,6 +207,7 @@ a file name for --relay-log-index option", opt_relaylog_index_name);
/* For multimaster, add connection name to relay log filenames */
char buf_relay_logname[FN_REFLEN], buf_relaylog_index_name_buff[FN_REFLEN];
char *buf_relaylog_index_name= opt_relaylog_index_name;
+ mysql_mutex_t *log_lock;
create_logfile_name_with_suffix(buf_relay_logname,
sizeof(buf_relay_logname),
@@ -226,14 +227,18 @@ a file name for --relay-log-index option", opt_relaylog_index_name);
note, that if open() fails, we'll still have index file open
but a destructor will take care of that
*/
+ log_lock= relay_log.get_log_lock();
+ mysql_mutex_lock(log_lock);
if (relay_log.open_index_file(buf_relaylog_index_name, ln, TRUE) ||
relay_log.open(ln, LOG_BIN, 0, 0, SEQ_READ_APPEND,
max_relay_log_size, 1, TRUE))
{
+ mysql_mutex_unlock(log_lock);
mysql_mutex_unlock(&data_lock);
sql_print_error("Failed when trying to open logs for '%s' in Relay_log_info::init(). Error: %M", ln, my_errno);
DBUG_RETURN(1);
}
+ mysql_mutex_unlock(log_lock);
}
/* if file does not exist */
@@ -413,7 +418,7 @@ Failed to open the existing relay log info file '%s' (errno %d)",
}
inited= 1;
mysql_mutex_unlock(&data_lock);
- DBUG_RETURN(error);
+ DBUG_RETURN(0);
err:
sql_print_error("%s", msg);
@@ -1312,9 +1317,10 @@ bool Relay_log_info::is_until_satisfied(my_off_t master_beg_pos)
}
-void Relay_log_info::stmt_done(my_off_t event_master_log_pos, THD *thd,
+bool Relay_log_info::stmt_done(my_off_t event_master_log_pos, THD *thd,
rpl_group_info *rgi)
{
+ int error= 0;
DBUG_ENTER("Relay_log_info::stmt_done");
DBUG_ASSERT(!belongs_to_client());
@@ -1367,10 +1373,11 @@ void Relay_log_info::stmt_done(my_off_t event_master_log_pos, THD *thd,
}
DBUG_EXECUTE_IF("inject_crash_before_flush_rli", DBUG_SUICIDE(););
if (mi->using_gtid == Master_info::USE_GTID_NO)
- flush();
+ if (flush())
+ error= 1;
DBUG_EXECUTE_IF("inject_crash_after_flush_rli", DBUG_SUICIDE(););
}
- DBUG_VOID_RETURN;
+ DBUG_RETURN(error);
}
diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h
index 60a75859050..93e7b869be0 100644
--- a/sql/rpl_rli.h
+++ b/sql/rpl_rli.h
@@ -433,7 +433,7 @@ public:
relay log info and used to produce information for <code>SHOW
SLAVE STATUS</code>.
*/
- void stmt_done(my_off_t event_log_pos, THD *thd, rpl_group_info *rgi);
+ bool stmt_done(my_off_t event_log_pos, THD *thd, rpl_group_info *rgi);
int alloc_inuse_relaylog(const char *name);
void free_inuse_relaylog(inuse_relaylog *ir);
void reset_inuse_relaylog();
diff --git a/sql/sha2.cc b/sql/sha2.cc
deleted file mode 100644
index f2201974172..00000000000
--- a/sql/sha2.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
-
- 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; 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
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-
-/**
- @file
- A compatibility layer to our built-in SSL implementation, to mimic the
- oft-used external library, OpenSSL.
-*/
-
-#include <my_global.h>
-#include <sha2.h>
-
-#ifdef HAVE_YASSL
-
-/*
- If TaoCrypt::SHA512 or ::SHA384 are not defined (but ::SHA256 is), it's
- probably that neither of config.h's SIZEOF_LONG or SIZEOF_LONG_LONG are
- 64 bits long. At present, both OpenSSL and YaSSL require 64-bit integers
- for SHA-512. (The SIZEOF_* definitions come from autoconf's config.h .)
-*/
-
-# define GEN_YASSL_SHA2_BRIDGE(size) \
-unsigned char* SHA##size(const unsigned char *input_ptr, size_t input_length, \
- char unsigned *output_ptr) { \
- TaoCrypt::SHA##size hasher; \
- \
- hasher.Update(input_ptr, input_length); \
- hasher.Final(output_ptr); \
- return(output_ptr); \
-}
-
-
-/**
- @fn SHA512
- @fn SHA384
- @fn SHA256
- @fn SHA224
-
- Instantiate an hash object, fill in the cleartext value, compute the digest,
- and extract the result from the object.
-
- (Generate the functions. See similar .h code for the prototypes.)
-*/
-# ifndef OPENSSL_NO_SHA512
-GEN_YASSL_SHA2_BRIDGE(512);
-GEN_YASSL_SHA2_BRIDGE(384);
-# else
-# warning Some SHA2 functionality is missing. See OPENSSL_NO_SHA512.
-# endif
-GEN_YASSL_SHA2_BRIDGE(256);
-GEN_YASSL_SHA2_BRIDGE(224);
-
-# undef GEN_YASSL_SHA2_BRIDGE
-
-#endif /* HAVE_YASSL */
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index 930cd2ceaa2..e1ed868c783 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -4839,7 +4839,7 @@ WARN_DATA_TRUNCATED 01000
spa "Datos truncados para columna '%s' en la línea %lu"
ER_WARN_USING_OTHER_HANDLER
eng "Using storage engine %s for table '%s'"
- ger "Für Tabelle '%s' wird Speicher-Engine %s benutzt"
+ ger "Speicher-Engine %s wird für Tabelle '%s' benutzt"
jpn "ストレージエンジン %s が表 '%s' に利用されています。"
por "Usando engine de armazenamento %s para tabela '%s'"
spa "Usando motor de almacenamiento %s para tabla '%s'"
diff --git a/sql/slave.cc b/sql/slave.cc
index e031a424ea6..fbdb78b5c5d 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -233,16 +233,14 @@ void init_thread_mask(int* mask,Master_info* mi,bool inverse)
/*
- lock_slave_threads()
+ lock_slave_threads() against other threads doing STOP, START or RESET SLAVE
+
*/
-void lock_slave_threads(Master_info* mi)
+void Master_info::lock_slave_threads()
{
DBUG_ENTER("lock_slave_threads");
-
- //TODO: see if we can do this without dual mutex
- mysql_mutex_lock(&mi->run_lock);
- mysql_mutex_lock(&mi->rli.run_lock);
+ mysql_mutex_lock(&start_stop_lock);
DBUG_VOID_RETURN;
}
@@ -251,13 +249,10 @@ void lock_slave_threads(Master_info* mi)
unlock_slave_threads()
*/
-void unlock_slave_threads(Master_info* mi)
+void Master_info::unlock_slave_threads()
{
DBUG_ENTER("unlock_slave_threads");
-
- //TODO: see if we can do this without dual mutex
- mysql_mutex_unlock(&mi->rli.run_lock);
- mysql_mutex_unlock(&mi->run_lock);
+ mysql_mutex_unlock(&start_stop_lock);
DBUG_VOID_RETURN;
}
@@ -470,7 +465,6 @@ int init_slave()
accepted. However bootstrap may conflict with us if it does START SLAVE.
So it's safer to take the lock.
*/
- mysql_mutex_lock(&LOCK_active_mi);
if (pthread_key_create(&RPL_MASTER_INFO, NULL))
goto err;
@@ -479,7 +473,6 @@ int init_slave()
if (!master_info_index || master_info_index->init_all_master_info())
{
sql_print_error("Failed to initialize multi master structures");
- mysql_mutex_unlock(&LOCK_active_mi);
DBUG_RETURN(1);
}
if (!(active_mi= new Master_info(&default_master_connection_name,
@@ -524,13 +517,22 @@ int init_slave()
if (active_mi->host[0] && !opt_skip_slave_start)
{
- if (start_slave_threads(0, /* No active thd */
- 1 /* need mutex */,
- 0 /* no wait for start*/,
- active_mi,
- master_info_file,
- relay_log_info_file,
- SLAVE_IO | SLAVE_SQL))
+ int error;
+ THD *thd= new THD(next_thread_id());
+ thd->thread_stack= (char*) &thd;
+ thd->store_globals();
+
+ error= start_slave_threads(0, /* No active thd */
+ 1 /* need mutex */,
+ 1 /* wait for start*/,
+ active_mi,
+ master_info_file,
+ relay_log_info_file,
+ SLAVE_IO | SLAVE_SQL);
+
+ thd->reset_globals();
+ delete thd;
+ if (error)
{
sql_print_error("Failed to create slave threads");
goto err;
@@ -538,7 +540,6 @@ int init_slave()
}
end:
- mysql_mutex_unlock(&LOCK_active_mi);
DBUG_RETURN(error);
err:
@@ -711,6 +712,7 @@ int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock)
if (!mi->inited)
DBUG_RETURN(0); /* successfully do nothing */
int error,force_all = (thread_mask & SLAVE_FORCE_ALL);
+ int retval= 0;
mysql_mutex_t *sql_lock = &mi->rli.run_lock, *io_lock = &mi->run_lock;
mysql_mutex_t *log_lock= mi->rli.relay_log.get_log_lock();
@@ -730,24 +732,18 @@ int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock)
skip_lock)) &&
!force_all)
DBUG_RETURN(error);
+ retval= error;
mysql_mutex_lock(log_lock);
DBUG_PRINT("info",("Flushing relay-log info file."));
if (current_thd)
THD_STAGE_INFO(current_thd, stage_flushing_relay_log_info_file);
- if (mi->rli.flush())
- DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
-
- if (my_sync(mi->rli.info_fd, MYF(MY_WME)))
- DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
+ if (mi->rli.flush() || my_sync(mi->rli.info_fd, MYF(MY_WME)))
+ retval= ER_ERROR_DURING_FLUSH_LOGS;
mysql_mutex_unlock(log_lock);
}
- if (opt_slave_parallel_threads > 0 &&
- master_info_index &&// master_info_index is set to NULL on server shutdown
- !master_info_index->any_slave_sql_running())
- rpl_parallel_inactivate_pool(&global_rpl_thread_pool);
if (thread_mask & (SLAVE_IO|SLAVE_FORCE_ALL))
{
DBUG_PRINT("info",("Terminating IO thread"));
@@ -758,25 +754,26 @@ int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock)
skip_lock)) &&
!force_all)
DBUG_RETURN(error);
+ if (!retval)
+ retval= error;
mysql_mutex_lock(log_lock);
DBUG_PRINT("info",("Flushing relay log and master info file."));
if (current_thd)
THD_STAGE_INFO(current_thd, stage_flushing_relay_log_and_master_info_repository);
- if (flush_master_info(mi, TRUE, FALSE))
- DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
-
+ if (likely(mi->fd >= 0))
+ {
+ if (flush_master_info(mi, TRUE, FALSE) || my_sync(mi->fd, MYF(MY_WME)))
+ retval= ER_ERROR_DURING_FLUSH_LOGS;
+ }
if (mi->rli.relay_log.is_open() &&
my_sync(mi->rli.relay_log.get_log_file()->file, MYF(MY_WME)))
- DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
-
- if (my_sync(mi->fd, MYF(MY_WME)))
- DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
+ retval= ER_ERROR_DURING_FLUSH_LOGS;
mysql_mutex_unlock(log_lock);
}
- DBUG_RETURN(0);
+ DBUG_RETURN(retval);
}
@@ -939,6 +936,15 @@ int start_slave_thread(
mysql_mutex_unlock(start_lock);
DBUG_RETURN(ER_SLAVE_THREAD);
}
+
+ /*
+ In the following loop we can't check for thd->killed as we have to
+ wait until THD structures for the slave thread are created
+ before we can return.
+ This should be ok as there is no major work done in the slave
+ threads before they signal that we can stop waiting.
+ */
+
if (start_cond && cond_lock) // caller has cond_lock
{
THD* thd = current_thd;
@@ -956,16 +962,9 @@ int start_slave_thread(
registered, we could otherwise go waiting though thd->killed is
set.
*/
- if (!thd->killed)
- mysql_cond_wait(start_cond, cond_lock);
+ mysql_cond_wait(start_cond, cond_lock);
thd->EXIT_COND(& saved_stage);
mysql_mutex_lock(cond_lock); // re-acquire it as exit_cond() released
- if (thd->killed)
- {
- if (start_lock)
- mysql_mutex_unlock(start_lock);
- DBUG_RETURN(thd->killed_errno());
- }
}
}
if (start_lock)
@@ -1054,10 +1053,7 @@ int start_slave_threads(THD *thd,
mi);
if (!error && (thread_mask & SLAVE_SQL))
{
- if (opt_slave_parallel_threads > 0)
- error= rpl_parallel_activate_pool(&global_rpl_thread_pool);
- if (!error)
- error= start_slave_thread(
+ error= start_slave_thread(
#ifdef HAVE_PSI_INTERFACE
key_thread_slave_sql,
#endif
@@ -1073,10 +1069,19 @@ int start_slave_threads(THD *thd,
/*
- Release slave threads at time of executing shutdown.
+ Kill slaves preparing for shutdown
+*/
- SYNOPSIS
- end_slave()
+void slave_prepare_for_shutdown()
+{
+ mysql_mutex_lock(&LOCK_active_mi);
+ master_info_index->free_connections();
+ mysql_mutex_unlock(&LOCK_active_mi);
+ stop_slave_background_thread();
+}
+
+/*
+ Release slave threads at time of executing shutdown.
*/
void end_slave()
@@ -1094,7 +1099,10 @@ void end_slave()
startup parameter to the server was wrong.
*/
mysql_mutex_lock(&LOCK_active_mi);
- /* This will call terminate_slave_threads() on all connections */
+ /*
+ master_info_index should not have any threads anymore as they where
+ killed as part of slave_prepare_for_shutdown()
+ */
delete master_info_index;
master_info_index= 0;
active_mi= 0;
@@ -2878,7 +2886,9 @@ static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full,
mysql_mutex_lock(&mi->data_lock);
mysql_mutex_lock(&mi->rli.data_lock);
+ /* err_lock is to protect mi->last_error() */
mysql_mutex_lock(&mi->err_lock);
+ /* err_lock is to protect mi->rli.last_error() */
mysql_mutex_lock(&mi->rli.err_lock);
protocol->store(mi->host, &my_charset_bin);
protocol->store(mi->user, &my_charset_bin);
@@ -4884,6 +4894,16 @@ pthread_handler_t handle_slave_sql(void *arg)
rli->slave_running= MYSQL_SLAVE_RUN_NOT_CONNECT;
pthread_detach_this_thread();
+
+ if (opt_slave_parallel_threads > 0 &&
+ rpl_parallel_activate_pool(&global_rpl_thread_pool))
+ {
+ mysql_cond_broadcast(&rli->start_cond);
+ rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, NULL,
+ "Failed during parallel slave pool activation");
+ goto err_during_init;
+ }
+
if (init_slave_thread(thd, mi, SLAVE_THD_SQL))
{
/*
@@ -5184,8 +5204,15 @@ pthread_handler_t handle_slave_sql(void *arg)
if (rli->mi->using_gtid != Master_info::USE_GTID_NO)
{
ulong domain_count;
+ my_bool save_log_all_errors= thd->log_all_errors;
+ /*
+ We don't need to check return value for rli->flush()
+ as any errors should be logged to stderr
+ */
+ thd->log_all_errors= 1;
rli->flush();
+ thd->log_all_errors= save_log_all_errors;
if (mi->using_parallel())
{
/*
@@ -5296,17 +5323,7 @@ err_during_init:
DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5););
mysql_mutex_unlock(&rli->run_lock); // tell the world we are done
- /*
- Deactivate the parallel replication thread pool, if there are now no more
- SQL threads running. Do this here, when we have released all locks, but
- while our THD (and current_thd) is still valid.
- */
- mysql_mutex_lock(&LOCK_active_mi);
- if (opt_slave_parallel_threads > 0 &&
- master_info_index &&// master_info_index is set to NULL on server shutdown
- !master_info_index->any_slave_sql_running())
- rpl_parallel_inactivate_pool(&global_rpl_thread_pool);
- mysql_mutex_unlock(&LOCK_active_mi);
+ rpl_parallel_resize_pool_if_no_slaves();
/* TODO: Check if this lock is needed */
mysql_mutex_lock(&LOCK_thread_count);
@@ -6519,6 +6536,7 @@ err:
void end_relay_log_info(Relay_log_info* rli)
{
+ mysql_mutex_t *log_lock;
DBUG_ENTER("end_relay_log_info");
if (!rli->inited)
@@ -6536,8 +6554,11 @@ void end_relay_log_info(Relay_log_info* rli)
rli->cur_log_fd = -1;
}
rli->inited = 0;
+ log_lock= rli->relay_log.get_log_lock();
+ mysql_mutex_lock(log_lock);
rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
+ mysql_mutex_unlock(log_lock);
/*
Delete the slave's temporary tables from memory.
In the future there will be other actions than this, to ensure persistance
@@ -6688,7 +6709,7 @@ static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi,
suppress_warnings= 0;
mi->report(ERROR_LEVEL, last_errno, NULL,
"error %s to master '%s@%s:%d'"
- " - retry-time: %d retries: %lu message: %s",
+ " - retry-time: %d maximum-retries: %lu message: %s",
(reconnect ? "reconnecting" : "connecting"),
mi->user, mi->host, mi->port,
mi->connect_retry, master_retry_count,
@@ -7181,9 +7202,12 @@ static Log_event* next_event(rpl_group_info *rgi, ulonglong *event_size)
}
rli->event_relay_log_pos = BIN_LOG_HEADER_SIZE;
strmake_buf(rli->event_relay_log_name,rli->linfo.log_file_name);
- rli->flush();
+ if (rli->flush())
+ {
+ errmsg= "error flushing relay log";
+ goto err;
+ }
}
-
/*
Now we want to open this next log. To know if it's a hot log (the one
being written by the I/O thread now) or a cold log, we can use
diff --git a/sql/slave.h b/sql/slave.h
index 38f3b7c8430..ded9d76e49d 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -230,13 +230,12 @@ bool rpl_master_erroneous_autoinc(THD* thd);
const char *print_slave_db_safe(const char *db);
void skip_load_data_infile(NET* net);
+void slave_prepare_for_shutdown();
void end_slave(); /* release slave threads */
void close_active_mi(); /* clean up slave threads data */
void clear_until_condition(Relay_log_info* rli);
void clear_slave_error(Relay_log_info* rli);
void end_relay_log_info(Relay_log_info* rli);
-void lock_slave_threads(Master_info* mi);
-void unlock_slave_threads(Master_info* mi);
void init_thread_mask(int* mask,Master_info* mi,bool inverse);
Format_description_log_event *
read_relay_log_description_event(IO_CACHE *cur_log, ulonglong start_pos,
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index d18a5b4d503..5e3311d502a 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -9754,13 +9754,13 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
case USER_ACL:
acl_user->user.str= strdup_root(&acl_memroot, user_to->user.str);
acl_user->user.length= user_to->user.length;
- acl_user->host.hostname= strdup_root(&acl_memroot, user_to->host.str);
- acl_user->hostname_length= user_to->host.length;
+ update_hostname(&acl_user->host, strdup_root(&acl_memroot, user_to->host.str));
+ acl_user->hostname_length= strlen(acl_user->host.hostname);
break;
case DB_ACL:
acl_db->user= strdup_root(&acl_memroot, user_to->user.str);
- acl_db->host.hostname= strdup_root(&acl_memroot, user_to->host.str);
+ update_hostname(&acl_db->host, strdup_root(&acl_memroot, user_to->host.str));
break;
case COLUMN_PRIVILEGES_HASH:
@@ -11927,7 +11927,6 @@ get_cached_table_access(GRANT_INTERNAL_INFO *grant_internal_info,
struct MPVIO_EXT :public MYSQL_PLUGIN_VIO
{
MYSQL_SERVER_AUTH_INFO auth_info;
- THD *thd;
ACL_USER *acl_user; ///< a copy, independent from acl_users array
plugin_ref plugin; ///< what plugin we're under
LEX_STRING db; ///< db name from the handshake packet
@@ -12007,7 +12006,7 @@ static bool send_server_handshake_packet(MPVIO_EXT *mpvio,
DBUG_ASSERT(mpvio->status == MPVIO_EXT::FAILURE);
DBUG_ASSERT(data_len <= 255);
- THD *thd= mpvio->thd;
+ THD *thd= mpvio->auth_info.thd;
char *buff= (char *) my_alloca(1 + SERVER_VERSION_LENGTH + 1 + data_len + 64);
char scramble_buf[SCRAMBLE_LENGTH];
char *end= buff;
@@ -12057,14 +12056,14 @@ static bool send_server_handshake_packet(MPVIO_EXT *mpvio,
native_password_plugin will have to send it in a separate packet,
adding one more round trip.
*/
- create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand);
+ thd_create_random_password(thd, thd->scramble, SCRAMBLE_LENGTH);
data= thd->scramble;
}
data_len= SCRAMBLE_LENGTH;
}
end= strxnmov(end, SERVER_VERSION_LENGTH, RPL_VERSION_HACK, server_version, NullS) + 1;
- int4store((uchar*) end, mpvio->thd->thread_id);
+ int4store((uchar*) end, mpvio->auth_info.thd->thread_id);
end+= 4;
/*
@@ -12079,7 +12078,7 @@ static bool send_server_handshake_packet(MPVIO_EXT *mpvio,
int2store(end, thd->client_capabilities);
/* write server characteristics: up to 16 bytes allowed */
end[2]= (char) default_charset_info->number;
- int2store(end+3, mpvio->thd->server_status);
+ int2store(end+3, mpvio->auth_info.thd->server_status);
int2store(end+5, thd->client_capabilities >> 16);
end[7]= data_len;
DBUG_EXECUTE_IF("poison_srv_handshake_scramble_len", end[7]= -100;);
@@ -12093,9 +12092,9 @@ static bool send_server_handshake_packet(MPVIO_EXT *mpvio,
end= strmake(end, plugin_name(mpvio->plugin)->str,
plugin_name(mpvio->plugin)->length);
- int res= my_net_write(&mpvio->thd->net, (uchar*) buff,
+ int res= my_net_write(&mpvio->auth_info.thd->net, (uchar*) buff,
(size_t) (end - buff + 1)) ||
- net_flush(&mpvio->thd->net);
+ net_flush(&mpvio->auth_info.thd->net);
my_afree(buff);
DBUG_RETURN (res);
}
@@ -12154,7 +12153,7 @@ static bool send_plugin_request_packet(MPVIO_EXT *mpvio,
{
DBUG_ASSERT(mpvio->packets_written == 1);
DBUG_ASSERT(mpvio->packets_read == 1);
- NET *net= &mpvio->thd->net;
+ NET *net= &mpvio->auth_info.thd->net;
static uchar switch_plugin_request_buf[]= { 254 };
DBUG_ENTER("send_plugin_request_packet");
@@ -12179,7 +12178,7 @@ static bool send_plugin_request_packet(MPVIO_EXT *mpvio,
client_auth_plugin == old_password_plugin_name.str;
if (switch_from_long_to_short_scramble)
- DBUG_RETURN (secure_auth(mpvio->thd) ||
+ DBUG_RETURN (secure_auth(mpvio->auth_info.thd) ||
my_net_write(net, switch_plugin_request_buf, 1) ||
net_flush(net));
@@ -12195,8 +12194,8 @@ static bool send_plugin_request_packet(MPVIO_EXT *mpvio,
if (switch_from_short_to_long_scramble)
{
my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
- general_log_print(mpvio->thd, COM_CONNECT,
- ER_THD(mpvio->thd, ER_NOT_SUPPORTED_AUTH_MODE));
+ general_log_print(mpvio->auth_info.thd, COM_CONNECT,
+ ER_THD(mpvio->auth_info.thd, ER_NOT_SUPPORTED_AUTH_MODE));
DBUG_RETURN (1);
}
@@ -12220,7 +12219,7 @@ static bool send_plugin_request_packet(MPVIO_EXT *mpvio,
*/
static bool find_mpvio_user(MPVIO_EXT *mpvio)
{
- Security_context *sctx= mpvio->thd->security_ctx;
+ Security_context *sctx= mpvio->auth_info.thd->security_ctx;
DBUG_ENTER("find_mpvio_user");
DBUG_ASSERT(mpvio->acl_user == 0);
@@ -12228,7 +12227,7 @@ static bool find_mpvio_user(MPVIO_EXT *mpvio)
ACL_USER *user= find_user_or_anon(sctx->host, sctx->user, sctx->ip);
if (user)
- mpvio->acl_user= user->copy(mpvio->thd->mem_root);
+ mpvio->acl_user= user->copy(mpvio->auth_info.thd->mem_root);
mysql_mutex_unlock(&acl_cache->lock);
@@ -12252,12 +12251,12 @@ static bool find_mpvio_user(MPVIO_EXT *mpvio)
if (!acl_users.elements)
{
mysql_mutex_unlock(&acl_cache->lock);
- login_failed_error(mpvio->thd);
+ login_failed_error(mpvio->auth_info.thd);
DBUG_RETURN(1);
}
uint i= nr1 % acl_users.elements;
ACL_USER *acl_user_tmp= dynamic_element(&acl_users, i, ACL_USER*);
- mpvio->acl_user= acl_user_tmp->copy(mpvio->thd->mem_root);
+ mpvio->acl_user= acl_user_tmp->copy(mpvio->auth_info.thd->mem_root);
mysql_mutex_unlock(&acl_cache->lock);
mpvio->make_it_fail= true;
@@ -12266,15 +12265,15 @@ static bool find_mpvio_user(MPVIO_EXT *mpvio)
/* user account requires non-default plugin and the client is too old */
if (mpvio->acl_user->plugin.str != native_password_plugin_name.str &&
mpvio->acl_user->plugin.str != old_password_plugin_name.str &&
- !(mpvio->thd->client_capabilities & CLIENT_PLUGIN_AUTH))
+ !(mpvio->auth_info.thd->client_capabilities & CLIENT_PLUGIN_AUTH))
{
DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
native_password_plugin_name.str));
DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
old_password_plugin_name.str));
my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
- general_log_print(mpvio->thd, COM_CONNECT,
- ER_THD(mpvio->thd, ER_NOT_SUPPORTED_AUTH_MODE));
+ general_log_print(mpvio->auth_info.thd, COM_CONNECT,
+ ER_THD(mpvio->auth_info.thd, ER_NOT_SUPPORTED_AUTH_MODE));
DBUG_RETURN (1);
}
@@ -12331,7 +12330,7 @@ read_client_connect_attrs(char **ptr, char *end, CHARSET_INFO *from_cs)
/* the packet format is described in send_change_user_packet() */
static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length)
{
- THD *thd= mpvio->thd;
+ THD *thd= mpvio->auth_info.thd;
NET *net= &thd->net;
Security_context *sctx= thd->security_ctx;
@@ -12485,7 +12484,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
uchar **buff, ulong pkt_len)
{
#ifndef EMBEDDED_LIBRARY
- THD *thd= mpvio->thd;
+ THD *thd= mpvio->auth_info.thd;
NET *net= &thd->net;
char *end;
DBUG_ASSERT(mpvio->status == MPVIO_EXT::FAILURE);
@@ -12695,7 +12694,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
if ((thd->client_capabilities & CLIENT_CONNECT_ATTRS) &&
read_client_connect_attrs(&next_field, ((char *)net->read_pos) + pkt_len,
- mpvio->thd->charset()))
+ mpvio->auth_info.thd->charset()))
return packet_error;
/*
@@ -12780,13 +12779,13 @@ static int server_mpvio_write_packet(MYSQL_PLUGIN_VIO *param,
We'll escape these bytes with \1. Consequently, we
have to escape \1 byte too.
*/
- res= net_write_command(&mpvio->thd->net, 1, (uchar*)"", 0,
+ res= net_write_command(&mpvio->auth_info.thd->net, 1, (uchar*)"", 0,
packet, packet_len);
}
else
{
- res= my_net_write(&mpvio->thd->net, packet, packet_len) ||
- net_flush(&mpvio->thd->net);
+ res= my_net_write(&mpvio->auth_info.thd->net, packet, packet_len) ||
+ net_flush(&mpvio->auth_info.thd->net);
}
mpvio->packets_written++;
DBUG_RETURN(res);
@@ -12816,7 +12815,7 @@ static int server_mpvio_read_packet(MYSQL_PLUGIN_VIO *param, uchar **buf)
if (server_mpvio_write_packet(mpvio, 0, 0))
pkt_len= packet_error;
else
- pkt_len= my_net_read(&mpvio->thd->net);
+ pkt_len= my_net_read(&mpvio->auth_info.thd->net);
}
else if (mpvio->cached_client_reply.pkt)
{
@@ -12850,10 +12849,10 @@ static int server_mpvio_read_packet(MYSQL_PLUGIN_VIO *param, uchar **buf)
if (server_mpvio_write_packet(mpvio, 0, 0))
pkt_len= packet_error;
else
- pkt_len= my_net_read(&mpvio->thd->net);
+ pkt_len= my_net_read(&mpvio->auth_info.thd->net);
}
else
- pkt_len= my_net_read(&mpvio->thd->net);
+ pkt_len= my_net_read(&mpvio->auth_info.thd->net);
if (pkt_len == packet_error)
goto err;
@@ -12871,14 +12870,14 @@ static int server_mpvio_read_packet(MYSQL_PLUGIN_VIO *param, uchar **buf)
goto err;
}
else
- *buf= mpvio->thd->net.read_pos;
+ *buf= mpvio->auth_info.thd->net.read_pos;
DBUG_RETURN((int)pkt_len);
err:
if (mpvio->status == MPVIO_EXT::FAILURE)
{
- if (!mpvio->thd->is_error())
+ if (!mpvio->auth_info.thd->is_error())
my_error(ER_HANDSHAKE_ERROR, MYF(0));
}
DBUG_RETURN(-1);
@@ -12892,7 +12891,7 @@ static void server_mpvio_info(MYSQL_PLUGIN_VIO *vio,
MYSQL_PLUGIN_VIO_INFO *info)
{
MPVIO_EXT *mpvio= (MPVIO_EXT *) vio;
- mpvio_info(mpvio->thd->net.vio, info);
+ mpvio_info(mpvio->auth_info.thd->net.vio, info);
}
static bool acl_check_ssl(THD *thd, const ACL_USER *acl_user)
@@ -13027,11 +13026,11 @@ static int do_auth_once(THD *thd, const LEX_STRING *auth_plugin_name,
if (plugin)
{
st_mysql_auth *auth= (st_mysql_auth *) plugin_decl(plugin)->info;
- switch (auth->interface_version) {
- case 0x0200:
+ switch (auth->interface_version >> 8) {
+ case 0x02:
res= auth->authenticate_user(mpvio, &mpvio->auth_info);
break;
- case 0x0100:
+ case 0x01:
{
MYSQL_SERVER_AUTH_INFO_0x0100 compat;
compat.downgrade(&mpvio->auth_info);
@@ -13050,7 +13049,7 @@ static int do_auth_once(THD *thd, const LEX_STRING *auth_plugin_name,
/* Server cannot load the required plugin. */
Host_errors errors;
errors.m_no_auth_plugin= 1;
- inc_host_errors(mpvio->thd->security_ctx->ip, &errors);
+ inc_host_errors(mpvio->auth_info.thd->security_ctx->ip, &errors);
my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), auth_plugin_name->str);
res= CR_ERROR;
}
@@ -13095,9 +13094,9 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len)
mpvio.read_packet= server_mpvio_read_packet;
mpvio.write_packet= server_mpvio_write_packet;
mpvio.info= server_mpvio_info;
- mpvio.thd= thd;
mpvio.status= MPVIO_EXT::FAILURE;
mpvio.make_it_fail= false;
+ mpvio.auth_info.thd= thd;
mpvio.auth_info.host_or_ip= thd->security_ctx->host_or_ip;
mpvio.auth_info.host_or_ip_length=
(unsigned int) strlen(thd->security_ctx->host_or_ip);
@@ -13196,7 +13195,7 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len)
errors.m_auth_plugin= 1;
break;
}
- inc_host_errors(mpvio.thd->security_ctx->ip, &errors);
+ inc_host_errors(mpvio.auth_info.thd->security_ctx->ip, &errors);
if (!thd->is_error())
login_failed_error(thd);
DBUG_RETURN(1);
@@ -13223,7 +13222,7 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len)
{
Host_errors errors;
errors.m_proxy_user= 1;
- inc_host_errors(mpvio.thd->security_ctx->ip, &errors);
+ inc_host_errors(mpvio.auth_info.thd->security_ctx->ip, &errors);
if (!thd->is_error())
login_failed_error(thd);
DBUG_RETURN(1);
@@ -13243,7 +13242,7 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len)
Host_errors errors;
errors.m_proxy_user_acl= 1;
- inc_host_errors(mpvio.thd->security_ctx->ip, &errors);
+ inc_host_errors(mpvio.auth_info.thd->security_ctx->ip, &errors);
if (!thd->is_error())
login_failed_error(thd);
DBUG_RETURN(1);
@@ -13273,7 +13272,7 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len)
{
Host_errors errors;
errors.m_ssl= 1;
- inc_host_errors(mpvio.thd->security_ctx->ip, &errors);
+ inc_host_errors(mpvio.auth_info.thd->security_ctx->ip, &errors);
login_failed_error(thd);
DBUG_RETURN(1);
}
@@ -13410,13 +13409,13 @@ static int native_password_authenticate(MYSQL_PLUGIN_VIO *vio,
uchar *pkt;
int pkt_len;
MPVIO_EXT *mpvio= (MPVIO_EXT *) vio;
- THD *thd=mpvio->thd;
+ THD *thd=info->thd;
DBUG_ENTER("native_password_authenticate");
/* generate the scramble, or reuse the old one */
if (thd->scramble[SCRAMBLE_LENGTH])
{
- create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand);
+ thd_create_random_password(thd, thd->scramble, SCRAMBLE_LENGTH);
/* and send it to the client */
if (mpvio->write_packet(mpvio, (uchar*)thd->scramble, SCRAMBLE_LENGTH + 1))
DBUG_RETURN(CR_AUTH_HANDSHAKE);
@@ -13495,12 +13494,12 @@ static int old_password_authenticate(MYSQL_PLUGIN_VIO *vio,
uchar *pkt;
int pkt_len;
MPVIO_EXT *mpvio= (MPVIO_EXT *) vio;
- THD *thd=mpvio->thd;
+ THD *thd=info->thd;
/* generate the scramble, or reuse the old one */
if (thd->scramble[SCRAMBLE_LENGTH])
{
- create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand);
+ thd_create_random_password(thd, thd->scramble, SCRAMBLE_LENGTH);
/* and send it to the client */
if (mpvio->write_packet(mpvio, (uchar*)thd->scramble, SCRAMBLE_LENGTH + 1))
return CR_AUTH_HANDSHAKE;
diff --git a/sql/sql_alter.h b/sql/sql_alter.h
index faba3a14a1b..5668a0f52be 100644
--- a/sql/sql_alter.h
+++ b/sql/sql_alter.h
@@ -70,59 +70,56 @@ public:
// Set for DISABLE KEYS | ENABLE KEYS
static const uint ALTER_KEYS_ONOFF = 1L << 9;
- // Set for CONVERT TO CHARACTER SET
- static const uint ALTER_CONVERT = 1L << 10;
-
// Set for FORCE
// Set for ENGINE(same engine)
// Set by mysql_recreate_table()
- static const uint ALTER_RECREATE = 1L << 11;
+ static const uint ALTER_RECREATE = 1L << 10;
// Set for ADD PARTITION
- static const uint ALTER_ADD_PARTITION = 1L << 12;
+ static const uint ALTER_ADD_PARTITION = 1L << 11;
// Set for DROP PARTITION
- static const uint ALTER_DROP_PARTITION = 1L << 13;
+ static const uint ALTER_DROP_PARTITION = 1L << 12;
// Set for COALESCE PARTITION
- static const uint ALTER_COALESCE_PARTITION = 1L << 14;
+ static const uint ALTER_COALESCE_PARTITION = 1L << 13;
// Set for REORGANIZE PARTITION ... INTO
- static const uint ALTER_REORGANIZE_PARTITION = 1L << 15;
+ static const uint ALTER_REORGANIZE_PARTITION = 1L << 14;
// Set for partition_options
- static const uint ALTER_PARTITION = 1L << 16;
+ static const uint ALTER_PARTITION = 1L << 15;
// Set for LOAD INDEX INTO CACHE ... PARTITION
// Set for CACHE INDEX ... PARTITION
- static const uint ALTER_ADMIN_PARTITION = 1L << 17;
+ static const uint ALTER_ADMIN_PARTITION = 1L << 16;
// Set for REORGANIZE PARTITION
- static const uint ALTER_TABLE_REORG = 1L << 18;
+ static const uint ALTER_TABLE_REORG = 1L << 17;
// Set for REBUILD PARTITION
- static const uint ALTER_REBUILD_PARTITION = 1L << 19;
+ static const uint ALTER_REBUILD_PARTITION = 1L << 18;
// Set for partitioning operations specifying ALL keyword
- static const uint ALTER_ALL_PARTITION = 1L << 20;
+ static const uint ALTER_ALL_PARTITION = 1L << 19;
// Set for REMOVE PARTITIONING
- static const uint ALTER_REMOVE_PARTITIONING = 1L << 21;
+ static const uint ALTER_REMOVE_PARTITIONING = 1L << 20;
// Set for ADD FOREIGN KEY
- static const uint ADD_FOREIGN_KEY = 1L << 22;
+ static const uint ADD_FOREIGN_KEY = 1L << 21;
// Set for DROP FOREIGN KEY
- static const uint DROP_FOREIGN_KEY = 1L << 23;
+ static const uint DROP_FOREIGN_KEY = 1L << 22;
// Set for EXCHANGE PARITION
- static const uint ALTER_EXCHANGE_PARTITION = 1L << 24;
+ static const uint ALTER_EXCHANGE_PARTITION = 1L << 23;
// Set by Sql_cmd_alter_table_truncate_partition::execute()
- static const uint ALTER_TRUNCATE_PARTITION = 1L << 25;
+ static const uint ALTER_TRUNCATE_PARTITION = 1L << 24;
// Set for ADD [COLUMN] FIRST | AFTER
- static const uint ALTER_COLUMN_ORDER = 1L << 26;
+ static const uint ALTER_COLUMN_ORDER = 1L << 25;
static const uint ALTER_ADD_CHECK_CONSTRAINT = 1L << 27;
static const uint ALTER_DROP_CHECK_CONSTRAINT = 1L << 28;
diff --git a/sql/sql_analyze_stmt.cc b/sql/sql_analyze_stmt.cc
index 58f72d6b8de..cc6e0f89f75 100644
--- a/sql/sql_analyze_stmt.cc
+++ b/sql/sql_analyze_stmt.cc
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation
diff --git a/sql/sql_analyze_stmt.h b/sql/sql_analyze_stmt.h
index 2a08a842dfc..27fd7fb6d6a 100644
--- a/sql/sql_analyze_stmt.h
+++ b/sql/sql_analyze_stmt.h
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/*
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 65cfe99649e..93511bb9188 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -5811,7 +5811,7 @@ find_field_in_tables(THD *thd, Item_ident *item,
if (!table_ref->belong_to_view &&
!table_ref->belong_to_derived)
{
- SELECT_LEX *current_sel= thd->lex->current_select;
+ SELECT_LEX *current_sel= item->context->select_lex;
SELECT_LEX *last_select= table_ref->select_lex;
bool all_merged= TRUE;
for (SELECT_LEX *sl= current_sel; sl && sl!=last_select;
diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc
index d92ac15822f..5f554a3cd92 100644
--- a/sql/sql_binlog.cc
+++ b/sql/sql_binlog.cc
@@ -20,7 +20,6 @@
#include "sql_parse.h"
#include "sql_acl.h"
#include "rpl_rli.h"
-#include "base64.h"
#include "slave.h"
#include "log_event.h"
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index c3bd40cf230..f8ba23298e0 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -4408,6 +4408,28 @@ extern "C" int thd_is_connected(MYSQL_THD thd)
}
+extern "C" double thd_rnd(MYSQL_THD thd)
+{
+ return my_rnd(&thd->rand);
+}
+
+
+/**
+ Generate string of printable random characters of requested length.
+
+ @param to[out] Buffer for generation; must be at least length+1 bytes
+ long; result string is always null-terminated
+ @param length[in] How many random characters to put in buffer
+*/
+extern "C" void thd_create_random_password(MYSQL_THD thd,
+ char *to, size_t length)
+{
+ for (char *end= to + length; to < end; to++)
+ *to= (char) (my_rnd(&thd->rand)*94 + 33);
+ *to= '\0';
+}
+
+
#ifdef INNODB_COMPATIBILITY_HOOKS
/** open a table and add it to thd->open_tables
@@ -4481,7 +4503,10 @@ MYSQL_THD create_thd()
void destroy_thd(MYSQL_THD thd)
{
- delete_running_thd(thd);
+ thd->add_status_to_global();
+ unlink_not_visible_thd(thd);
+ delete thd;
+ dec_thread_running();
}
void reset_thd(MYSQL_THD thd)
@@ -4533,6 +4558,15 @@ extern "C" int thd_rpl_is_parallel(const MYSQL_THD thd)
return thd->rgi_slave && thd->rgi_slave->is_parallel_exec;
}
+
+/* Returns high resolution timestamp for the start
+ of the current query. */
+extern "C" unsigned long long thd_start_utime(const MYSQL_THD thd)
+{
+ return thd->start_utime;
+}
+
+
/*
This function can optionally be called to check if thd_rpl_deadlock_check()
needs to be called for waits done by a given transaction.
@@ -6979,7 +7013,13 @@ wait_for_commit::reinit()
So in this case, do a re-init of the mutex. In release builds, we want to
avoid the overhead of a re-init though.
+
+ To ensure that no one is locking the mutex, we take a lock of it first.
+ For full explanation, see wait_for_commit::~wait_for_commit()
*/
+ mysql_mutex_lock(&LOCK_wait_commit);
+ mysql_mutex_unlock(&LOCK_wait_commit);
+
mysql_mutex_destroy(&LOCK_wait_commit);
mysql_mutex_init(key_LOCK_wait_commit, &LOCK_wait_commit, MY_MUTEX_INIT_FAST);
#endif
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index 157e59c2446..5cb4cd87296 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -832,11 +832,7 @@ bool init_new_connection_handler_thread()
statistic_increment(connection_errors_internal, &LOCK_status);
return 1;
}
- DBUG_EXECUTE_IF("simulate_failed_connection_1",
- {
- DBUG_SET("-d,simulate_failed_connection_1");
- return(1);
- });
+ DBUG_EXECUTE_IF("simulate_failed_connection_1", return(1); );
return 0;
}
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 8b7d4ee5ed2..813a17cdfdb 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -846,7 +846,8 @@ mysql_rm_db_internal(THD *thd,char *db, bool if_exists, bool silent)
if there exists a table with the name 'db', so let's just do it
separately. We know this file exists and needs to be deleted anyway.
*/
- if (my_delete_with_symlink(path, MYF(0)) && my_errno != ENOENT)
+ if (mysql_file_delete_with_symlink(key_file_misc, path, "", MYF(0)) &&
+ my_errno != ENOENT)
{
my_error(EE_DELETE, MYF(0), path, my_errno);
DBUG_RETURN(true);
@@ -1153,9 +1154,9 @@ static bool find_db_tables_and_rm_known_files(THD *thd, MY_DIR *dirp,
strxmov(filePath, path, "/", file->name, NullS);
/*
We ignore ENOENT error in order to skip files that was deleted
- by concurrently running statement like REAPIR TABLE ...
+ by concurrently running statement like REPAIR TABLE ...
*/
- if (my_delete_with_symlink(filePath, MYF(0)) &&
+ if (mysql_file_delete_with_symlink(key_file_misc, filePath, "", MYF(0)) &&
my_errno != ENOENT)
{
my_error(EE_DELETE, MYF(0), filePath, my_errno);
@@ -1271,7 +1272,7 @@ long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path)
continue;
}
strxmov(filePath, org_path, "/", file->name, NullS);
- if (mysql_file_delete_with_symlink(key_file_misc, filePath, MYF(MY_WME)))
+ if (mysql_file_delete_with_symlink(key_file_misc, filePath, "", MYF(MY_WME)))
{
goto err;
}
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index faf6dd790a6..90b6dad313a 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -449,6 +449,9 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
{
Item *expr= derived->on_expr;
expr= and_conds(thd, expr, dt_select->join ? dt_select->join->conds : 0);
+ if (expr)
+ expr->top_level_item();
+
if (expr && (derived->prep_on_expr || expr != derived->on_expr))
{
derived->on_expr= expr;
diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc
index 131c5a3bcfa..6b5db7e923b 100644
--- a/sql/sql_explain.cc
+++ b/sql/sql_explain.cc
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation
diff --git a/sql/sql_explain.h b/sql/sql_explain.h
index 5793599f4e1..bfddf40ff33 100644
--- a/sql/sql_explain.h
+++ b/sql/sql_explain.h
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/*
diff --git a/sql/sql_expression_cache.cc b/sql/sql_expression_cache.cc
index 3ed33d97094..c79783bf561 100644
--- a/sql/sql_expression_cache.cc
+++ b/sql/sql_expression_cache.cc
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#include <my_global.h>
#include "sql_base.h"
diff --git a/sql/sql_expression_cache.h b/sql/sql_expression_cache.h
index 87be6ddb4f4..05ac51f81f2 100644
--- a/sql/sql_expression_cache.h
+++ b/sql/sql_expression_cache.h
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#ifndef SQL_EXPRESSION_CACHE_INCLUDED
#define SQL_EXPRESSION_CACHE_INCLUDED
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 27820c16543..8e5dfb4f69c 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -330,7 +330,7 @@ static bool has_no_default_value(THD *thd, Field *field, TABLE_LIST *table_list)
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_NO_DEFAULT_FOR_FIELD,
ER_THD(thd, ER_NO_DEFAULT_FOR_FIELD), field->field_name);
}
- return true;
+ return thd->really_abort_on_warning();
}
return false;
}
@@ -904,7 +904,12 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
if (fields.elements || !value_count || table_list->view != 0)
{
- if (check_that_all_fields_are_given_values(thd, table, table_list))
+ if (table->triggers &&
+ table->triggers->has_triggers(TRG_EVENT_INSERT, TRG_ACTION_BEFORE))
+ {
+ /* BEFORE INSERT triggers exist, the check will be done later, per row */
+ }
+ else if (check_that_all_fields_are_given_values(thd, table, table_list))
{
error= 1;
goto values_loop_end;
@@ -3870,8 +3875,8 @@ bool select_insert::prepare_eof()
bool select_insert::send_ok_packet() {
char message[160]; /* status message */
- ulong row_count; /* rows affected */
- ulong id; /* last insert-id */
+ ulonglong row_count; /* rows affected */
+ ulonglong id; /* last insert-id */
DBUG_ENTER("select_insert::send_ok_packet");
diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc
index 8a293956da7..12c64caa225 100644
--- a/sql/sql_join_cache.cc
+++ b/sql/sql_join_cache.cc
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/**
@file
diff --git a/sql/sql_join_cache.h b/sql/sql_join_cache.h
index fa00e309623..4ae843ebfc2 100644
--- a/sql/sql_join_cache.h
+++ b/sql/sql_join_cache.h
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/*
This file contains declarations for implementations
diff --git a/sql/sql_lifo_buffer.h b/sql/sql_lifo_buffer.h
index feec4aeb4c2..8fa13c66dd9 100644
--- a/sql/sql_lifo_buffer.h
+++ b/sql/sql_lifo_buffer.h
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/**
@defgroup Bi-directional LIFO buffers used by DS-MRR implementation
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index b41f6ffd0f0..590d2dfe681 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2542,12 +2542,12 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
#endif
case SCH_COLUMNS:
case SCH_STATISTICS:
- {
#ifdef DONT_ALLOW_SHOW_COMMANDS
my_message(ER_NOT_ALLOWED_COMMAND,
ER_THD(thd, ER_NOT_ALLOWED_COMMAND), MYF(0));
DBUG_RETURN(1);
#else
+ {
DBUG_ASSERT(table_ident);
TABLE_LIST **query_tables_last= lex->query_tables_last;
schema_select_lex= new (thd->mem_root) SELECT_LEX();
@@ -2914,7 +2914,7 @@ static bool do_execute_sp(THD *thd, sp_head *sp)
int
mysql_execute_command(THD *thd)
{
- int res= FALSE;
+ int res= 0;
int up_result= 0;
LEX *lex= thd->lex;
/* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
@@ -3593,10 +3593,17 @@ mysql_execute_command(THD *thd)
if (check_global_access(thd, SUPER_ACL))
goto error;
+ /*
+ In this code it's ok to use LOCK_active_mi as we are adding new things
+ into master_info_index
+ */
mysql_mutex_lock(&LOCK_active_mi);
-
if (!master_info_index)
+ {
+ mysql_mutex_unlock(&LOCK_active_mi);
+ my_error(ER_SERVER_SHUTDOWN, MYF(0));
goto error;
+ }
mi= master_info_index->get_master_info(&lex_mi->connection_name,
Sql_condition::WARN_LEVEL_NOTE);
@@ -3625,7 +3632,7 @@ mysql_execute_command(THD *thd)
If new master was not added, we still need to free mi.
*/
if (master_info_added)
- master_info_index->remove_master_info(&lex_mi->connection_name);
+ master_info_index->remove_master_info(mi);
else
delete mi;
}
@@ -3643,22 +3650,24 @@ mysql_execute_command(THD *thd)
/* Accept one of two privileges */
if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
goto error;
- mysql_mutex_lock(&LOCK_active_mi);
if (lex->verbose)
+ {
+ mysql_mutex_lock(&LOCK_active_mi);
res= show_all_master_info(thd);
+ mysql_mutex_unlock(&LOCK_active_mi);
+ }
else
{
LEX_MASTER_INFO *lex_mi= &thd->lex->mi;
Master_info *mi;
- mi= master_info_index->get_master_info(&lex_mi->connection_name,
- Sql_condition::WARN_LEVEL_ERROR);
- if (mi != NULL)
+ if ((mi= get_master_info(&lex_mi->connection_name,
+ Sql_condition::WARN_LEVEL_ERROR)))
{
res= show_master_info(thd, mi, 0);
+ mi->release();
}
}
- mysql_mutex_unlock(&LOCK_active_mi);
break;
}
case SQLCOM_SHOW_MASTER_STAT:
@@ -4009,22 +4018,23 @@ end_with_restore_list:
load_error= rpl_load_gtid_slave_state(thd);
- mysql_mutex_lock(&LOCK_active_mi);
-
- if ((mi= (master_info_index->
- get_master_info(&lex_mi->connection_name,
- Sql_condition::WARN_LEVEL_ERROR))))
+ /*
+ We don't need to ensure that only one user is using master_info
+ as start_slave is protected against simultaneous usage
+ */
+ if ((mi= get_master_info(&lex_mi->connection_name,
+ Sql_condition::WARN_LEVEL_ERROR)))
{
if (load_error)
{
/*
- We cannot start a slave using GTID if we cannot load the GTID position
- from the mysql.gtid_slave_pos table. But we can allow non-GTID
- replication (useful eg. during upgrade).
+ We cannot start a slave using GTID if we cannot load the
+ GTID position from the mysql.gtid_slave_pos table. But we
+ can allow non-GTID replication (useful eg. during upgrade).
*/
if (mi->using_gtid != Master_info::USE_GTID_NO)
{
- mysql_mutex_unlock(&LOCK_active_mi);
+ mi->release();
break;
}
else
@@ -4032,8 +4042,8 @@ end_with_restore_list:
}
if (!start_slave(thd, mi, 1 /* net report*/))
my_ok(thd);
+ mi->release();
}
- mysql_mutex_unlock(&LOCK_active_mi);
break;
}
case SQLCOM_SLAVE_STOP:
@@ -4063,13 +4073,17 @@ end_with_restore_list:
}
lex_mi= &thd->lex->mi;
- mysql_mutex_lock(&LOCK_active_mi);
- if ((mi= (master_info_index->
- get_master_info(&lex_mi->connection_name,
- Sql_condition::WARN_LEVEL_ERROR))))
- if (!stop_slave(thd, mi, 1/* net report*/))
+ if ((mi= get_master_info(&lex_mi->connection_name,
+ Sql_condition::WARN_LEVEL_ERROR)))
+ {
+ if (stop_slave(thd, mi, 1/* net report*/))
+ res= 1;
+ mi->release();
+ if (rpl_parallel_resize_pool_if_no_slaves())
+ res= 1;
+ if (!res)
my_ok(thd);
- mysql_mutex_unlock(&LOCK_active_mi);
+ }
break;
}
case SQLCOM_SLAVE_ALL_START:
@@ -5395,11 +5409,13 @@ end_with_restore_list:
reload_acl_and_cache binlog interactions failed
*/
res= 1;
- }
+ }
if (!res)
my_ok(thd);
}
+ else
+ res= 1; // reload_acl_and_cache failed
#ifdef HAVE_REPLICATION
if (lex->type & REFRESH_READ_LOCK)
rpl_unpause_after_ftwrl(thd);
@@ -7755,7 +7771,7 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length,
}
/*
- When you modify mysql_parse(), you may need to mofify
+ When you modify mysql_parse(), you may need to modify
mysql_test_parse_for_slave() in this same file.
*/
@@ -9696,48 +9712,24 @@ bool check_ident_length(LEX_STRING *ident)
}
-C_MODE_START
-
/*
Check if path does not contain mysql data home directory
SYNOPSIS
- test_if_data_home_dir()
- dir directory
+ path_starts_from_data_home_dir()
+ dir directory, with all symlinks resolved
RETURN VALUES
0 ok
1 error ; Given path contains data directory
*/
+extern "C" {
-int test_if_data_home_dir(const char *dir)
+int path_starts_from_data_home_dir(const char *path)
{
- char path[FN_REFLEN];
- int dir_len;
- DBUG_ENTER("test_if_data_home_dir");
-
- if (!dir)
- DBUG_RETURN(0);
+ int dir_len= strlen(path);
+ DBUG_ENTER("path_starts_from_data_home_dir");
- /*
- data_file_name and index_file_name include the table name without
- extension. Mostly this does not refer to an existing file. When
- comparing data_file_name or index_file_name against the data
- directory, we try to resolve all symbolic links. On some systems,
- we use realpath(3) for the resolution. This returns ENOENT if the
- resolved path does not refer to an existing file. my_realpath()
- does then copy the requested path verbatim, without symlink
- resolution. Thereafter the comparison can fail even if the
- requested path is within the data directory. E.g. if symlinks to
- another file system are used. To make realpath(3) return the
- resolved path, we strip the table name and compare the directory
- path only. If the directory doesn't exist either, table creation
- will fail anyway.
- */
-
- (void) fn_format(path, dir, "", "",
- (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
- dir_len= strlen(path);
if (mysql_unpacked_real_data_home_len<= dir_len)
{
if (dir_len > mysql_unpacked_real_data_home_len &&
@@ -9765,7 +9757,31 @@ int test_if_data_home_dir(const char *dir)
DBUG_RETURN(0);
}
-C_MODE_END
+}
+
+/*
+ Check if path does not contain mysql data home directory
+
+ SYNOPSIS
+ test_if_data_home_dir()
+ dir directory
+
+ RETURN VALUES
+ 0 ok
+ 1 error ; Given path contains data directory
+*/
+
+int test_if_data_home_dir(const char *dir)
+{
+ char path[FN_REFLEN];
+ DBUG_ENTER("test_if_data_home_dir");
+
+ if (!dir)
+ DBUG_RETURN(0);
+
+ (void) fn_format(path, dir, "", "", MY_RETURN_REAL_PATH);
+ DBUG_RETURN(path_starts_from_data_home_dir(path));
+}
int error_if_data_home_dir(const char *path, const char *what)
diff --git a/sql/sql_parse.h b/sql/sql_parse.h
index d669f36acef..eedb74df959 100644
--- a/sql/sql_parse.h
+++ b/sql/sql_parse.h
@@ -33,7 +33,8 @@ enum enum_mysql_completiontype {
COMMIT_RELEASE=-1, COMMIT=0, COMMIT_AND_CHAIN=6
};
-extern "C" int test_if_data_home_dir(const char *dir);
+extern "C" int path_starts_from_data_home_dir(const char *dir);
+int test_if_data_home_dir(const char *dir);
int error_if_data_home_dir(const char *path, const char *what);
my_bool net_allocate_new_packet(NET *net, void *thd, uint my_flags);
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 31d59ea47ef..101ea3fd3c7 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -724,7 +724,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
{
#ifdef HAVE_DLOPEN
char dlpath[FN_REFLEN];
- uint plugin_dir_len, dummy_errors, dlpathlen, i;
+ uint plugin_dir_len, dummy_errors, i;
struct st_plugin_dl *tmp= 0, plugin_dl;
void *sym;
st_ptr_backup tmp_backup[array_elements(list_of_services)];
@@ -760,15 +760,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
/* Open new dll handle */
if (!(plugin_dl.handle= dlopen(dlpath, RTLD_NOW)))
{
- const char *errmsg=dlerror();
- dlpathlen= strlen(dlpath);
- if (!strncmp(dlpath, errmsg, dlpathlen))
- { // if errmsg starts from dlpath, trim this prefix.
- errmsg+=dlpathlen;
- if (*errmsg == ':') errmsg++;
- if (*errmsg == ' ') errmsg++;
- }
- report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, errno, errmsg);
+ report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, errno, my_dlerror(dlpath));
goto ret;
}
dlopen_count++;
@@ -1569,8 +1561,8 @@ int plugin_init(int *argc, char **argv, int flags)
}
/* prepare debug_sync service */
- DBUG_ASSERT(strcmp(list_of_services[4].name, "debug_sync_service") == 0);
- list_of_services[4].service= *(void**)&debug_sync_C_callback_ptr;
+ DBUG_ASSERT(strcmp(list_of_services[1].name, "debug_sync_service") == 0);
+ list_of_services[1].service= *(void**)&debug_sync_C_callback_ptr;
/* prepare encryption_keys service */
finalize_encryption_plugin(0);
@@ -1657,10 +1649,11 @@ int plugin_init(int *argc, char **argv, int flags)
{
char path[FN_REFLEN + 1];
build_table_filename(path, sizeof(path) - 1, "mysql", "plugin", reg_ext, 0);
- enum legacy_db_type db_type;
- frm_type_enum frm_type= dd_frm_type(NULL, path, &db_type);
+ char engine_name_buf[NAME_CHAR_LEN + 1];
+ LEX_STRING maybe_myisam= { engine_name_buf, 0 };
+ frm_type_enum frm_type= dd_frm_type(NULL, path, &maybe_myisam);
/* if mysql.plugin table is MyISAM - load it right away */
- if (frm_type == FRMTYPE_TABLE && db_type == DB_TYPE_MYISAM)
+ if (frm_type == FRMTYPE_TABLE && !strcasecmp(maybe_myisam.str, "MyISAM"))
{
plugin_load(&tmp_root);
flags|= PLUGIN_INIT_SKIP_PLUGIN_TABLE;
@@ -3302,14 +3295,14 @@ uchar* sys_var_pluginvar::real_value_ptr(THD *thd, enum_var_type type)
{
switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
case PLUGIN_VAR_BOOL:
- thd->sys_var_tmp.my_bool_value= (my_bool)option.def_value;
+ thd->sys_var_tmp.my_bool_value= option.def_value;
return (uchar*) &thd->sys_var_tmp.my_bool_value;
case PLUGIN_VAR_INT:
- thd->sys_var_tmp.int_value= (int)option.def_value;
+ thd->sys_var_tmp.int_value= option.def_value;
return (uchar*) &thd->sys_var_tmp.int_value;
case PLUGIN_VAR_LONG:
case PLUGIN_VAR_ENUM:
- thd->sys_var_tmp.long_value= (long)option.def_value;
+ thd->sys_var_tmp.long_value= option.def_value;
return (uchar*) &thd->sys_var_tmp.long_value;
case PLUGIN_VAR_LONGLONG:
case PLUGIN_VAR_SET:
diff --git a/sql/sql_plugin_services.ic b/sql/sql_plugin_services.ic
index c3dfde18ab6..2e71fac50be 100644
--- a/sql/sql_plugin_services.ic
+++ b/sql/sql_plugin_services.ic
@@ -60,6 +60,33 @@ static struct thd_timezone_service_st thd_timezone_handler= {
thd_gmt_sec_to_TIME
};
+static struct my_sha2_service_st my_sha2_handler = {
+ my_sha224,
+ my_sha224_multi,
+ my_sha224_context_size,
+ my_sha224_init,
+ my_sha224_input,
+ my_sha224_result,
+ my_sha256,
+ my_sha256_multi,
+ my_sha256_context_size,
+ my_sha256_init,
+ my_sha256_input,
+ my_sha256_result,
+ my_sha384,
+ my_sha384_multi,
+ my_sha384_context_size,
+ my_sha384_init,
+ my_sha384_input,
+ my_sha384_result,
+ my_sha512,
+ my_sha512_multi,
+ my_sha512_context_size,
+ my_sha512_init,
+ my_sha512_input,
+ my_sha512_result,
+};
+
static struct my_sha1_service_st my_sha1_handler = {
my_sha1,
my_sha1_multi,
@@ -92,6 +119,20 @@ static struct thd_autoinc_service_st thd_autoinc_handler= {
thd_get_autoinc
};
+static struct thd_rnd_service_st thd_rnd_handler= {
+ thd_rnd,
+ thd_create_random_password
+};
+
+static struct base64_service_st base64_handler= {
+ my_base64_needed_encoded_length,
+ my_base64_encode_max_arg_length,
+ my_base64_needed_decoded_length,
+ my_base64_decode_max_arg_length,
+ my_base64_encode,
+ my_base64_decode
+};
+
static struct thd_error_context_service_st thd_error_conext_handler= {
thd_get_error_message,
thd_get_error_number,
@@ -157,21 +198,24 @@ static struct encryption_scheme_service_st encryption_scheme_handler=
static struct st_service_ref list_of_services[]=
{
+ { "base64_service", VERSION_base64, &base64_handler },
+ { "debug_sync_service", VERSION_debug_sync, 0 }, // updated in plugin_init()
+ { "encryption_scheme_service", VERSION_encryption_scheme, &encryption_scheme_handler },
+ { "encryption_service", VERSION_encryption, &encryption_handler },
+ { "logger_service", VERSION_logger, &logger_service_handler },
+ { "my_md5_service", VERSION_my_md5, &my_md5_handler},
+ { "my_sha1_service", VERSION_my_sha1, &my_sha1_handler},
+ { "my_sha2_service", VERSION_my_sha2, &my_sha2_handler},
{ "my_snprintf_service", VERSION_my_snprintf, &my_snprintf_handler },
- { "thd_alloc_service", VERSION_thd_alloc, &thd_alloc_handler },
- { "thd_wait_service", VERSION_thd_wait, &thd_wait_handler },
{ "progress_report_service", VERSION_progress_report, &progress_report_handler },
- { "debug_sync_service", VERSION_debug_sync, 0 }, // updated in plugin_init()
+ { "thd_alloc_service", VERSION_thd_alloc, &thd_alloc_handler },
+ { "thd_autoinc_service", VERSION_thd_autoinc, &thd_autoinc_handler },
+ { "thd_error_context_service", VERSION_thd_error_context, &thd_error_conext_handler },
{ "thd_kill_statement_service", VERSION_kill_statement, &thd_kill_statement_handler },
+ { "thd_rnd_service", VERSION_thd_rnd, &thd_rnd_handler },
+ { "thd_specifics_service", VERSION_thd_specifics, &thd_specifics_handler },
{ "thd_timezone_service", VERSION_thd_timezone, &thd_timezone_handler },
- { "my_sha1_service", VERSION_my_sha1, &my_sha1_handler},
- { "my_md5_service", VERSION_my_md5, &my_md5_handler},
- { "logger_service", VERSION_logger, &logger_service_handler },
- { "thd_autoinc_service", VERSION_thd_autoinc, &thd_autoinc_handler },
+ { "thd_wait_service", VERSION_thd_wait, &thd_wait_handler },
{ "wsrep_service", VERSION_wsrep, &wsrep_handler },
- { "encryption_service", VERSION_encryption, &encryption_handler },
- { "encryption_scheme_service", VERSION_encryption_scheme, &encryption_scheme_handler },
- { "thd_specifics_service", VERSION_thd_specifics, &thd_specifics_handler },
- { "thd_error_context_service", VERSION_thd_error_context, &thd_error_conext_handler },
};
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index c8765f45273..4b2d8b5fb36 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -2258,7 +2258,7 @@ static int mysql_test_handler_read(Prepared_statement *stmt,
THD *thd= stmt->thd;
LEX *lex= stmt->lex;
SQL_HANDLER *ha_table;
- DBUG_ENTER("mysql_test_select");
+ DBUG_ENTER("mysql_test_handler_read");
lex->select_lex.context.resolve_in_select_list= TRUE;
diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc
index 2d72d1052d2..463989b3805 100644
--- a/sql/sql_reload.cc
+++ b/sql/sql_reload.cc
@@ -181,24 +181,20 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options,
slave is not likely to have the same connection names.
*/
tmp_write_to_binlog= 0;
- mysql_mutex_lock(&LOCK_active_mi);
- if (master_info_index)
+
+ if (!(mi= (get_master_info(&connection_name,
+ Sql_condition::WARN_LEVEL_ERROR))))
{
- if (!(mi= (master_info_index->
- get_master_info(&connection_name,
- Sql_condition::WARN_LEVEL_ERROR))))
- {
- result= 1;
- }
- else
- {
- mysql_mutex_lock(&mi->data_lock);
- if (rotate_relay_log(mi))
- *write_to_binlog= -1;
- mysql_mutex_unlock(&mi->data_lock);
- }
+ result= 1;
+ }
+ else
+ {
+ mysql_mutex_lock(&mi->data_lock);
+ if (rotate_relay_log(mi))
+ *write_to_binlog= -1;
+ mysql_mutex_unlock(&mi->data_lock);
+ mi->release();
}
- mysql_mutex_unlock(&LOCK_active_mi);
#endif
}
#ifdef HAVE_QUERY_CACHE
@@ -375,27 +371,33 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options,
LEX_MASTER_INFO* lex_mi= &thd->lex->mi;
Master_info *mi;
tmp_write_to_binlog= 0;
- mysql_mutex_lock(&LOCK_active_mi);
- if (master_info_index)
+
+ if (!(mi= get_master_info(&lex_mi->connection_name,
+ Sql_condition::WARN_LEVEL_ERROR)))
{
- if (!(mi= (master_info_index->
- get_master_info(&lex_mi->connection_name,
- Sql_condition::WARN_LEVEL_ERROR))))
- {
- result= 1;
- }
- else if (reset_slave(thd, mi))
+ result= 1;
+ }
+ else
+ {
+ /* The following will fail if slave is running */
+ if (reset_slave(thd, mi))
{
+ mi->release();
/* NOTE: my_error() has been already called by reset_slave(). */
result= 1;
}
else if (mi->connection_name.length && thd->lex->reset_slave_info.all)
{
/* If not default connection and 'all' is used */
- master_info_index->remove_master_info(&mi->connection_name);
+ mi->release();
+ mysql_mutex_lock(&LOCK_active_mi);
+ if (master_info_index->remove_master_info(mi))
+ result= 1;
+ mysql_mutex_unlock(&LOCK_active_mi);
}
+ else
+ mi->release();
}
- mysql_mutex_unlock(&LOCK_active_mi);
}
#endif
if (options & REFRESH_USER_RESOURCES)
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 0180671977c..7c30aa38f1a 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -3040,7 +3040,16 @@ int start_slave(THD* thd , Master_info* mi, bool net_report)
relay_log_info_file, 0,
&mi->cmp_connection_name);
- lock_slave_threads(mi); // this allows us to cleanly read slave_running
+ mi->lock_slave_threads();
+ if (mi->killed)
+ {
+ /* connection was deleted while we waited for lock_slave_threads */
+ mi->unlock_slave_threads();
+ my_error(WARN_NO_MASTER_INFO, mi->connection_name.length,
+ mi->connection_name.str);
+ DBUG_RETURN(-1);
+ }
+
// Get a mask of _stopped_ threads
init_thread_mask(&thread_mask,mi,1 /* inverse */);
@@ -3169,7 +3178,7 @@ int start_slave(THD* thd , Master_info* mi, bool net_report)
if (!slave_errno)
slave_errno = start_slave_threads(thd,
- 0 /*no mutex */,
+ 1,
1 /* wait for start */,
mi,
master_info_file_tmp,
@@ -3185,7 +3194,7 @@ int start_slave(THD* thd , Master_info* mi, bool net_report)
}
err:
- unlock_slave_threads(mi);
+ mi->unlock_slave_threads();
thd_proc_info(thd, 0);
if (slave_errno)
@@ -3226,8 +3235,12 @@ int stop_slave(THD* thd, Master_info* mi, bool net_report )
DBUG_RETURN(-1);
THD_STAGE_INFO(thd, stage_killing_slave);
int thread_mask;
- lock_slave_threads(mi);
- // Get a mask of _running_ threads
+ mi->lock_slave_threads();
+ /*
+ Get a mask of _running_ threads.
+ We don't have to test for mi->killed as the thread_mask will take care
+ of checking if threads exists
+ */
init_thread_mask(&thread_mask,mi,0 /* not inverse*/);
/*
Below we will stop all running threads.
@@ -3240,8 +3253,7 @@ int stop_slave(THD* thd, Master_info* mi, bool net_report )
if (thread_mask)
{
- slave_errno= terminate_slave_threads(mi,thread_mask,
- 1 /*skip lock */);
+ slave_errno= terminate_slave_threads(mi,thread_mask, 0 /* get lock */);
}
else
{
@@ -3250,7 +3262,8 @@ int stop_slave(THD* thd, Master_info* mi, bool net_report )
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, ER_SLAVE_WAS_NOT_RUNNING,
ER_THD(thd, ER_SLAVE_WAS_NOT_RUNNING));
}
- unlock_slave_threads(mi);
+
+ mi->unlock_slave_threads();
if (slave_errno)
{
@@ -3285,11 +3298,20 @@ int reset_slave(THD *thd, Master_info* mi)
char relay_log_info_file_tmp[FN_REFLEN];
DBUG_ENTER("reset_slave");
- lock_slave_threads(mi);
+ mi->lock_slave_threads();
+ if (mi->killed)
+ {
+ /* connection was deleted while we waited for lock_slave_threads */
+ mi->unlock_slave_threads();
+ my_error(WARN_NO_MASTER_INFO, mi->connection_name.length,
+ mi->connection_name.str);
+ DBUG_RETURN(-1);
+ }
+
init_thread_mask(&thread_mask,mi,0 /* not inverse */);
if (thread_mask) // We refuse if any slave thread is running
{
- unlock_slave_threads(mi);
+ mi->unlock_slave_threads();
my_error(ER_SLAVE_MUST_STOP, MYF(0), (int) mi->connection_name.length,
mi->connection_name.str);
DBUG_RETURN(ER_SLAVE_MUST_STOP);
@@ -3353,7 +3375,7 @@ int reset_slave(THD *thd, Master_info* mi)
RUN_HOOK(binlog_relay_io, after_reset_slave, (thd, mi));
err:
- unlock_slave_threads(mi);
+ mi->unlock_slave_threads();
if (error)
my_error(sql_errno, MYF(0), errmsg);
DBUG_RETURN(error);
@@ -3466,8 +3488,8 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added)
DBUG_ENTER("change_master");
- mysql_mutex_assert_owner(&LOCK_active_mi);
DBUG_ASSERT(master_info_index);
+ mysql_mutex_assert_owner(&LOCK_active_mi);
*master_info_added= false;
/*
@@ -3487,7 +3509,16 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added)
lex_mi->port))
DBUG_RETURN(TRUE);
- lock_slave_threads(mi);
+ mi->lock_slave_threads();
+ if (mi->killed)
+ {
+ /* connection was deleted while we waited for lock_slave_threads */
+ mi->unlock_slave_threads();
+ my_error(WARN_NO_MASTER_INFO, mi->connection_name.length,
+ mi->connection_name.str);
+ DBUG_RETURN(TRUE);
+ }
+
init_thread_mask(&thread_mask,mi,0 /*not inverse*/);
if (thread_mask) // We refuse if any slave thread is running
{
@@ -3811,12 +3842,13 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added)
in-memory value at restart (thus causing errors, as the old relay log does
not exist anymore).
*/
- mi->rli.flush();
+ if (mi->rli.flush())
+ ret= 1;
mysql_cond_broadcast(&mi->data_cond);
mysql_mutex_unlock(&mi->rli.data_lock);
err:
- unlock_slave_threads(mi);
+ mi->unlock_slave_threads();
if (ret == FALSE)
my_ok(thd);
DBUG_RETURN(ret);
@@ -3896,13 +3928,9 @@ bool mysql_show_binlog_events(THD* thd)
{
if (!lex_mi->connection_name.str)
lex_mi->connection_name= thd->variables.default_master_connection;
- mysql_mutex_lock(&LOCK_active_mi);
- if (!master_info_index ||
- !(mi= master_info_index->
- get_master_info(&lex_mi->connection_name,
- Sql_condition::WARN_LEVEL_ERROR)))
+ if (!(mi= get_master_info(&lex_mi->connection_name,
+ Sql_condition::WARN_LEVEL_ERROR)))
{
- mysql_mutex_unlock(&LOCK_active_mi);
DBUG_RETURN(TRUE);
}
binary_log= &(mi->rli.relay_log);
@@ -3921,7 +3949,7 @@ bool mysql_show_binlog_events(THD* thd)
if (mi)
{
/* We can unlock the mutex as we have a lock on the file */
- mysql_mutex_unlock(&LOCK_active_mi);
+ mi->release();
mi= 0;
}
@@ -4054,7 +4082,7 @@ bool mysql_show_binlog_events(THD* thd)
mysql_mutex_unlock(log_lock);
}
else if (mi)
- mysql_mutex_unlock(&LOCK_active_mi);
+ mi->release();
// Check that linfo is still on the function scope.
DEBUG_SYNC(thd, "after_show_binlog_events");
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 6f84b4a5762..54b0b01559b 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -6017,7 +6017,7 @@ double matching_candidates_in_table(JOIN_TAB *s, bool with_found_constraint,
{
TABLE *table= s->table;
double sel= table->cond_selectivity;
- double table_records= (double)table->stat_records();
+ double table_records= table->stat_records();
dbl_records= table_records * sel;
return dbl_records;
}
@@ -6043,7 +6043,7 @@ double matching_candidates_in_table(JOIN_TAB *s, bool with_found_constraint,
if (s->table->quick_condition_rows != s->found_records)
records= s->table->quick_condition_rows;
- dbl_records= (double)records;
+ dbl_records= records;
return dbl_records;
}
@@ -8799,8 +8799,6 @@ bool JOIN::get_best_combination()
form= table[tablenr]= j->table;
used_tables|= form->map;
form->reginfo.join_tab=j;
- if (!*j->on_expr_ref)
- form->reginfo.not_exists_optimize=0; // Only with LEFT JOIN
DBUG_PRINT("info",("type: %d", j->type));
if (j->type == JT_CONST)
goto loop_end; // Handled in make_join_stat..
@@ -9363,8 +9361,6 @@ static void add_not_null_conds(JOIN *join)
UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1);
not_null_item is the t1.f1, but it's referred_tab is 0.
*/
- if (!referred_tab)
- continue;
if (!(notnull= new (join->thd->mem_root)
Item_func_isnotnull(join->thd, item)))
DBUG_VOID_RETURN;
@@ -9376,16 +9372,19 @@ static void add_not_null_conds(JOIN *join)
*/
if (notnull->fix_fields(join->thd, &notnull))
DBUG_VOID_RETURN;
+
DBUG_EXECUTE("where",print_where(notnull,
- referred_tab->table->alias.c_ptr(),
- QT_ORDINARY););
+ (referred_tab ?
+ referred_tab->table->alias.c_ptr() :
+ "outer_ref_cond"),
+ QT_ORDINARY););
if (!tab->first_inner)
- {
- COND *new_cond= referred_tab->join == join ?
+ {
+ COND *new_cond= (referred_tab && referred_tab->join == join) ?
referred_tab->select_cond :
join->outer_ref_cond;
add_cond_and_fix(join->thd, &new_cond, notnull);
- if (referred_tab->join == join)
+ if (referred_tab && referred_tab->join == join)
referred_tab->set_select_cond(new_cond, __LINE__);
else
join->outer_ref_cond= new_cond;
@@ -9537,7 +9536,10 @@ make_outerjoin_info(JOIN *join)
tab->cond_equal= tbl->cond_equal;
if (embedding && !embedding->is_active_sjm())
tab->first_upper= embedding->nested_join->first_nested;
- }
+ }
+ else if (!embedding)
+ tab->table->reginfo.not_exists_optimize= 0;
+
for ( ; embedding ; embedding= embedding->embedding)
{
if (embedding->is_active_sjm())
@@ -9547,7 +9549,10 @@ make_outerjoin_info(JOIN *join)
}
/* Ignore sj-nests: */
if (!(embedding->on_expr && embedding->outer_join))
+ {
+ tab->table->reginfo.not_exists_optimize= 0;
continue;
+ }
NESTED_JOIN *nested_join= embedding->nested_join;
if (!nested_join->counter)
{
@@ -9563,17 +9568,10 @@ make_outerjoin_info(JOIN *join)
}
if (!tab->first_inner)
tab->first_inner= nested_join->first_nested;
- if (tab->table->reginfo.not_exists_optimize)
- tab->first_inner->table->reginfo.not_exists_optimize= 1;
if (++nested_join->counter < nested_join->n_tables)
break;
/* Table tab is the last inner table for nested join. */
nested_join->first_nested->last_inner= tab;
- if (tab->first_inner->table->reginfo.not_exists_optimize)
- {
- for (JOIN_TAB *join_tab= tab->first_inner; join_tab <= tab; join_tab++)
- join_tab->table->reginfo.not_exists_optimize= 1;
- }
}
}
DBUG_RETURN(FALSE);
@@ -10348,7 +10346,7 @@ void JOIN::drop_unused_derived_keys()
continue;
if (!tmp_tbl->pos_in_table_list->is_materialized_derived())
continue;
- if (tmp_tbl->max_keys > 1)
+ if (tmp_tbl->max_keys > 1 && !tab->is_ref_for_hash_join())
tmp_tbl->use_index(tab->ref.key);
if (tmp_tbl->s->keys)
{
@@ -15934,7 +15932,9 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
DBUG_ASSERT(thd == table->in_use);
new_field= item->Item::create_tmp_field(false, table);
- if (copy_func && item->real_item()->is_result_field())
+ if (copy_func &&
+ (item->is_result_field() ||
+ (item->real_item()->is_result_field())))
*((*copy_func)++) = item; // Save for copy_funcs
if (modify_item)
item->set_result_field(new_field);
@@ -18540,32 +18540,41 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
first_unmatched->found= 1;
for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++)
{
+ /*
+ Check whether 'not exists' optimization can be used here.
+ If tab->table->reginfo.not_exists_optimize is set to true
+ then WHERE contains a conjunctive predicate IS NULL over
+ a non-nullable field of tab. When activated this predicate
+ will filter out all records with matches for the left part
+ of the outer join whose inner tables start from the
+ first_unmatched table and include table tab. To safely use
+ 'not exists' optimization we have to check that the
+ IS NULL predicate is really activated, i.e. all guards
+ that wrap it are in the 'open' state.
+ */
+ bool not_exists_opt_is_applicable=
+ tab->table->reginfo.not_exists_optimize;
+ for (JOIN_TAB *first_upper= first_unmatched->first_upper;
+ not_exists_opt_is_applicable && first_upper;
+ first_upper= first_upper->first_upper)
+ {
+ if (!first_upper->found)
+ not_exists_opt_is_applicable= false;
+ }
/* Check all predicates that has just been activated. */
/*
Actually all predicates non-guarded by first_unmatched->found
will be re-evaluated again. It could be fixed, but, probably,
it's not worth doing now.
*/
- /*
- not_exists_optimize has been created from a
- select_cond containing 'is_null'. This 'is_null'
- predicate is still present on any 'tab' with
- 'not_exists_optimize'. Furthermore, the usual rules
- for condition guards also applies for
- 'not_exists_optimize' -> When 'is_null==false' we
- know all cond. guards are open and we can apply
- the 'not_exists_optimize'.
- */
- DBUG_ASSERT(!(tab->table->reginfo.not_exists_optimize &&
- !tab->select_cond));
-
if (tab->select_cond && !tab->select_cond->val_int())
{
/* The condition attached to table tab is false */
-
if (tab == join_tab)
{
found= 0;
+ if (not_exists_opt_is_applicable)
+ DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS);
}
else
{
@@ -18574,21 +18583,10 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
not to the last table of the current nest level.
*/
join->return_tab= tab;
- }
-
- if (tab->table->reginfo.not_exists_optimize)
- {
- /*
- When not_exists_optimize is set: No need to further
- explore more rows of 'tab' for this partial result.
- Any found 'tab' matches are known to evaluate to 'false'.
- Returning .._NO_MORE_ROWS will skip rem. 'tab' rows.
- */
- DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS);
- }
- else if (tab != join_tab)
- {
- DBUG_RETURN(NESTED_LOOP_OK);
+ if (not_exists_opt_is_applicable)
+ DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS);
+ else
+ DBUG_RETURN(NESTED_LOOP_OK);
}
}
}
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index adba7ab4d33..18bc19bb85e 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -4133,6 +4133,22 @@ make_table_name_list(THD *thd, Dynamic_array<LEX_STRING*> *table_names,
}
+static void get_table_engine_for_i_s(THD *thd, char *buf, TABLE_LIST *tl,
+ LEX_STRING *db, LEX_STRING *table)
+{
+ LEX_STRING engine_name= { buf, 0 };
+
+ if (thd->get_stmt_da()->sql_errno() == ER_UNKNOWN_STORAGE_ENGINE)
+ {
+ char path[FN_REFLEN];
+ build_table_filename(path, sizeof(path) - 1,
+ db->str, table->str, reg_ext, 0);
+ if (dd_frm_type(thd, path, &engine_name) == FRMTYPE_TABLE)
+ tl->option= engine_name.str;
+ }
+}
+
+
/**
Fill I_S table with data obtained by performing full-blown table open.
@@ -4203,9 +4219,9 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys,
/*
Since make_table_list() might change database and table name passed
- to it we create copies of orig_db_name and orig_table_name here.
- These copies are used for make_table_list() while unaltered values
- are passed to process_table() functions.
+ to it (if lower_case_table_names) we create copies of orig_db_name and
+ orig_table_name here. These copies are used for make_table_list()
+ while unaltered values are passed to process_table() functions.
*/
if (!thd->make_lex_string(&db_name,
orig_db_name->str, orig_db_name->length) ||
@@ -4292,6 +4308,10 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys,
}
else
{
+ char buf[NAME_CHAR_LEN + 1];
+ if (thd->is_error())
+ get_table_engine_for_i_s(thd, buf, table_list, &db_name, &table_name);
+
result= schema_table->process_table(thd, table_list,
table, result,
orig_db_name,
@@ -4508,15 +4528,13 @@ try_acquire_high_prio_shared_mdl_lock(THD *thd, TABLE_LIST *table,
open_tables function for this table
*/
-static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables,
+static int fill_schema_table_from_frm(THD *thd, TABLE *table,
ST_SCHEMA_TABLE *schema_table,
LEX_STRING *db_name,
LEX_STRING *table_name,
- enum enum_schema_tables schema_table_idx,
Open_tables_backup *open_tables_state_backup,
bool can_deadlock)
{
- TABLE *table= tables->table;
TABLE_SHARE *share;
TABLE tbl;
TABLE_LIST table_list;
@@ -4598,7 +4616,19 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables,
share= tdc_acquire_share(thd, &table_list, GTS_TABLE | GTS_VIEW);
if (!share)
{
- res= 0;
+ if (thd->get_stmt_da()->sql_errno() == ER_NO_SUCH_TABLE ||
+ thd->get_stmt_da()->sql_errno() == ER_WRONG_OBJECT)
+ {
+ res= 0;
+ }
+ else
+ {
+ char buf[NAME_CHAR_LEN + 1];
+ get_table_engine_for_i_s(thd, buf, &table_list, db_name, table_name);
+
+ res= schema_table->process_table(thd, &table_list, table,
+ true, db_name, table_name);
+ }
goto end;
}
@@ -4874,9 +4904,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
if (!(table_open_method & ~OPEN_FRM_ONLY) &&
db_name != &INFORMATION_SCHEMA_NAME)
{
- if (!fill_schema_table_from_frm(thd, tables, schema_table,
+ if (!fill_schema_table_from_frm(thd, table, schema_table,
db_name, table_name,
- schema_table_idx,
&open_tables_state_backup,
can_deadlock))
continue;
@@ -5010,6 +5039,11 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
else
table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
+ if (tables->option)
+ {
+ table->field[4]->store(tables->option, strlen(tables->option), cs);
+ table->field[4]->set_notnull();
+ }
goto err;
}
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc
index 979852e2f6b..ad71f634265 100644
--- a/sql/sql_statistics.cc
+++ b/sql/sql_statistics.cc
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/**
@file
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 07af3b891ea..baab8e320a0 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -6607,6 +6607,9 @@ static bool fill_alter_inplace_info(THD *thd,
new_key->user_defined_key_parts))
goto index_changed;
+ if (table_key->block_size != new_key->block_size)
+ goto index_changed;
+
if (engine_options_differ(table_key->option_struct, new_key->option_struct,
table->file->ht->index_options))
goto index_changed;
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index 394fa713445..05698ce82cc 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -228,14 +228,13 @@ void udf_init()
if (dl == NULL)
{
char dlpath[FN_REFLEN];
- strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", tmp->dl,
- NullS);
+ 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 */
sql_print_error(ER_THD(new_thd, ER_CANT_OPEN_LIBRARY),
- tmp->dl, errno, dlerror());
+ tmp->dl, errno, my_dlerror(dlpath));
/* Keep the udf in the hash so that we can remove it later */
continue;
}
@@ -539,10 +538,10 @@ int mysql_create_function(THD *thd,udf_func *udf)
if (!(dl = dlopen(dlpath, RTLD_NOW)))
{
+ my_error(ER_CANT_OPEN_LIBRARY, MYF(0),
+ udf->dl, errno, my_dlerror(dlpath));
DBUG_PRINT("error",("dlopen of %s failed, error: %d (%s)",
udf->dl, errno, dlerror()));
- my_error(ER_CANT_OPEN_LIBRARY, MYF(0),
- udf->dl, errno, dlerror());
goto err;
}
new_dl=1;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index fe387ed80f2..412fcce8625 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1017,7 +1017,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%}
-%pure_parser /* We have threads */
+%pure-parser /* We have threads */
%parse-param { THD *thd }
%lex-param { THD *thd }
/*
@@ -7748,7 +7748,7 @@ alter_list_item:
$5->name, $4->csname));
if (Lex->create_info.add_alter_list_item_convert_to_charset($5))
MYSQL_YYABORT;
- Lex->alter_info.flags|= Alter_info::ALTER_CONVERT;
+ Lex->alter_info.flags|= Alter_info::ALTER_OPTIONS;
}
| create_table_options_space_separated
{
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index fd724bc7dd1..a3bc3f6d9cf 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -1596,7 +1596,6 @@ bool
Sys_var_gtid_slave_pos::do_check(THD *thd, set_var *var)
{
String str, *res;
- bool running;
DBUG_ASSERT(var->type == OPT_GLOBAL);
@@ -1607,11 +1606,7 @@ Sys_var_gtid_slave_pos::do_check(THD *thd, set_var *var)
return true;
}
- mysql_mutex_lock(&LOCK_active_mi);
- running= (!master_info_index ||
- master_info_index->give_error_if_slave_running());
- mysql_mutex_unlock(&LOCK_active_mi);
- if (running)
+ if (give_error_if_slave_running(0))
return true;
if (!(res= var->value->val_str(&str)))
return true;
@@ -1649,7 +1644,7 @@ Sys_var_gtid_slave_pos::global_update(THD *thd, set_var *var)
mysql_mutex_unlock(&LOCK_global_system_variables);
mysql_mutex_lock(&LOCK_active_mi);
- if (!master_info_index || master_info_index->give_error_if_slave_running())
+ if (give_error_if_slave_running(1))
err= true;
else
err= rpl_gtid_pos_update(thd, var->save_result.string_value.str,
@@ -1835,16 +1830,7 @@ Sys_var_last_gtid::session_value_ptr(THD *thd, const LEX_STRING *base)
static bool
check_slave_parallel_threads(sys_var *self, THD *thd, set_var *var)
{
- bool running;
-
- mysql_mutex_lock(&LOCK_active_mi);
- running= (!master_info_index ||
- master_info_index->give_error_if_slave_running());
- mysql_mutex_unlock(&LOCK_active_mi);
- if (running)
- return true;
-
- return false;
+ return give_error_if_slave_running(0);
}
static bool
@@ -1853,10 +1839,7 @@ fix_slave_parallel_threads(sys_var *self, THD *thd, enum_var_type type)
bool err;
mysql_mutex_unlock(&LOCK_global_system_variables);
- mysql_mutex_lock(&LOCK_active_mi);
- err= (!master_info_index ||
- master_info_index->give_error_if_slave_running());
- mysql_mutex_unlock(&LOCK_active_mi);
+ err= give_error_if_slave_running(0);
mysql_mutex_lock(&LOCK_global_system_variables);
return err;
@@ -1888,16 +1871,7 @@ static Sys_var_ulong Sys_slave_parallel_workers(
static bool
check_slave_domain_parallel_threads(sys_var *self, THD *thd, set_var *var)
{
- bool running;
-
- mysql_mutex_lock(&LOCK_active_mi);
- running= (!master_info_index ||
- master_info_index->give_error_if_slave_running());
- mysql_mutex_unlock(&LOCK_active_mi);
- if (running)
- return true;
-
- return false;
+ return give_error_if_slave_running(0);
}
static bool
@@ -1906,13 +1880,10 @@ fix_slave_domain_parallel_threads(sys_var *self, THD *thd, enum_var_type type)
bool running;
mysql_mutex_unlock(&LOCK_global_system_variables);
- mysql_mutex_lock(&LOCK_active_mi);
- running= (!master_info_index ||
- master_info_index->give_error_if_slave_running());
- mysql_mutex_unlock(&LOCK_active_mi);
+ running= give_error_if_slave_running(0);
mysql_mutex_lock(&LOCK_global_system_variables);
- return running ? true : false;
+ return running;
}
@@ -2055,16 +2026,7 @@ static Sys_var_bit Sys_skip_parallel_replication(
static bool
check_gtid_ignore_duplicates(sys_var *self, THD *thd, set_var *var)
{
- bool running;
-
- mysql_mutex_lock(&LOCK_active_mi);
- running= (!master_info_index ||
- master_info_index->give_error_if_slave_running());
- mysql_mutex_unlock(&LOCK_active_mi);
- if (running)
- return true;
-
- return false;
+ return give_error_if_slave_running(0);
}
static bool
@@ -2073,13 +2035,10 @@ fix_gtid_ignore_duplicates(sys_var *self, THD *thd, enum_var_type type)
bool running;
mysql_mutex_unlock(&LOCK_global_system_variables);
- mysql_mutex_lock(&LOCK_active_mi);
- running= (!master_info_index ||
- master_info_index->give_error_if_slave_running());
- mysql_mutex_unlock(&LOCK_active_mi);
+ running= give_error_if_slave_running(0);
mysql_mutex_lock(&LOCK_global_system_variables);
- return running ? true : false;
+ return running;
}
@@ -2980,10 +2939,8 @@ Sys_var_replicate_events_marked_for_skip::global_update(THD *thd, set_var *var)
DBUG_ENTER("Sys_var_replicate_events_marked_for_skip::global_update");
mysql_mutex_unlock(&LOCK_global_system_variables);
- mysql_mutex_lock(&LOCK_active_mi);
- if (master_info_index && !master_info_index->give_error_if_slave_running())
+ if (!give_error_if_slave_running(0))
result= Sys_var_enum::global_update(thd, var);
- mysql_mutex_unlock(&LOCK_active_mi);
mysql_mutex_lock(&LOCK_global_system_variables);
DBUG_RETURN(result);
}
@@ -4379,35 +4336,31 @@ static Sys_var_mybool Sys_relay_log_recovery(
bool Sys_var_rpl_filter::global_update(THD *thd, set_var *var)
{
bool result= true; // Assume error
- Master_info *mi;
LEX_STRING *base_name= &var->base;
if (!base_name->length)
base_name= &thd->variables.default_master_connection;
mysql_mutex_unlock(&LOCK_global_system_variables);
- mysql_mutex_lock(&LOCK_active_mi);
-
- mi= master_info_index->
- get_master_info(base_name, !base_name->length ?
- Sql_condition::WARN_LEVEL_ERROR :
- Sql_condition::WARN_LEVEL_WARN);
- if (mi)
+
+ if (Master_info *mi= get_master_info(base_name, !var->base.length ?
+ Sql_condition::WARN_LEVEL_ERROR :
+ Sql_condition::WARN_LEVEL_WARN))
{
if (mi->rli.slave_running)
{
my_error(ER_SLAVE_MUST_STOP, MYF(0),
- mi->connection_name.length,
- mi->connection_name.str);
+ mi->connection_name.length,
+ mi->connection_name.str);
result= true;
}
else
{
result= set_filter_value(var->save_result.string_value.str, mi);
}
+ mi->release();
}
- mysql_mutex_unlock(&LOCK_active_mi);
mysql_mutex_lock(&LOCK_global_system_variables);
return result;
}
@@ -4417,6 +4370,8 @@ bool Sys_var_rpl_filter::set_filter_value(const char *value, Master_info *mi)
bool status= true;
Rpl_filter* rpl_filter= mi->rpl_filter;
+ /* Proctect against other threads */
+ mysql_mutex_lock(&LOCK_active_mi);
switch (opt_id) {
case OPT_REPLICATE_DO_DB:
status= rpl_filter->set_do_db(value);
@@ -4437,7 +4392,7 @@ bool Sys_var_rpl_filter::set_filter_value(const char *value, Master_info *mi)
status= rpl_filter->set_wild_ignore_table(value);
break;
}
-
+ mysql_mutex_unlock(&LOCK_active_mi);
return status;
}
@@ -4451,23 +4406,20 @@ uchar *Sys_var_rpl_filter::global_value_ptr(THD *thd,
Rpl_filter *rpl_filter;
mysql_mutex_unlock(&LOCK_global_system_variables);
- mysql_mutex_lock(&LOCK_active_mi);
-
- mi= master_info_index->
- get_master_info(base_name, !base_name->length ?
- Sql_condition::WARN_LEVEL_ERROR :
- Sql_condition::WARN_LEVEL_WARN);
-
- mysql_mutex_lock(&LOCK_global_system_variables);
+ mi= get_master_info(base_name, !base_name->length ?
+ Sql_condition::WARN_LEVEL_ERROR :
+ Sql_condition::WARN_LEVEL_WARN);
if (!mi)
{
- mysql_mutex_unlock(&LOCK_active_mi);
+ mysql_mutex_lock(&LOCK_global_system_variables);
return 0;
}
+
rpl_filter= mi->rpl_filter;
tmp.length(0);
+ mysql_mutex_lock(&LOCK_active_mi);
switch (opt_id) {
case OPT_REPLICATE_DO_DB:
rpl_filter->get_do_db(&tmp);
@@ -4488,9 +4440,12 @@ uchar *Sys_var_rpl_filter::global_value_ptr(THD *thd,
rpl_filter->get_wild_ignore_table(&tmp);
break;
}
+ mysql_mutex_unlock(&LOCK_active_mi);
+ mysql_mutex_lock(&LOCK_global_system_variables);
+
+ mi->release();
ret= (uchar *) thd->strmake(tmp.ptr(), tmp.length());
- mysql_mutex_unlock(&LOCK_active_mi);
return ret;
}
@@ -4559,17 +4514,12 @@ get_master_info_ulonglong_value(THD *thd, ptrdiff_t offset)
Master_info *mi;
ulonglong res= 0; // Default value
mysql_mutex_unlock(&LOCK_global_system_variables);
- mysql_mutex_lock(&LOCK_active_mi);
- mi= master_info_index->
- get_master_info(&thd->variables.default_master_connection,
- Sql_condition::WARN_LEVEL_WARN);
- if (mi)
+ if ((mi= get_master_info(&thd->variables.default_master_connection,
+ Sql_condition::WARN_LEVEL_WARN)))
{
- mysql_mutex_lock(&mi->rli.data_lock);
res= *((ulonglong*) (((uchar*) mi) + master_info_offset));
- mysql_mutex_unlock(&mi->rli.data_lock);
+ mi->release();
}
- mysql_mutex_unlock(&LOCK_active_mi);
mysql_mutex_lock(&LOCK_global_system_variables);
return res;
}
@@ -4584,19 +4534,16 @@ bool update_multi_source_variable(sys_var *self_var, THD *thd,
if (type == OPT_GLOBAL)
mysql_mutex_unlock(&LOCK_global_system_variables);
- mysql_mutex_lock(&LOCK_active_mi);
- mi= master_info_index->
- get_master_info(&thd->variables.default_master_connection,
- Sql_condition::WARN_LEVEL_ERROR);
- if (mi)
+ if ((mi= (get_master_info(&thd->variables.default_master_connection,
+ Sql_condition::WARN_LEVEL_ERROR))))
{
mysql_mutex_lock(&mi->rli.run_lock);
mysql_mutex_lock(&mi->rli.data_lock);
result= self->update_variable(thd, mi);
mysql_mutex_unlock(&mi->rli.data_lock);
mysql_mutex_unlock(&mi->rli.run_lock);
+ mi->release();
}
- mysql_mutex_unlock(&LOCK_active_mi);
if (type == OPT_GLOBAL)
mysql_mutex_lock(&LOCK_global_system_variables);
return result;
diff --git a/sql/table.cc b/sql/table.cc
index 6b15c06cb91..6d1a3a7f8d8 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -591,7 +591,7 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags)
{
DBUG_ASSERT(flags & GTS_TABLE);
DBUG_ASSERT(flags & GTS_USE_DISCOVERY);
- mysql_file_delete_with_symlink(key_file_frm, path, MYF(0));
+ mysql_file_delete_with_symlink(key_file_frm, path, "", MYF(0));
file= -1;
}
else
diff --git a/sql/threadpool.h b/sql/threadpool.h
index 17c8b6ea4ea..ba17dc042c2 100644
--- a/sql/threadpool.h
+++ b/sql/threadpool.h
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#define MAX_THREAD_GROUPS 100000
diff --git a/sql/threadpool_common.cc b/sql/threadpool_common.cc
index 643ff80de2a..c6a3c7e44f8 100644
--- a/sql/threadpool_common.cc
+++ b/sql/threadpool_common.cc
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#include <my_global.h>
#include <violite.h>
diff --git a/sql/threadpool_generic.cc b/sql/threadpool_generic.cc
index 87c74d18aea..2ab874b2232 100644
--- a/sql/threadpool_generic.cc
+++ b/sql/threadpool_generic.cc
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#include <my_global.h>
#include <violite.h>
diff --git a/sql/threadpool_win.cc b/sql/threadpool_win.cc
index dec898d92bb..855b9b38d78 100644
--- a/sql/threadpool_win.cc
+++ b/sql/threadpool_win.cc
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
diff --git a/sql/winservice.c b/sql/winservice.c
index 74e9e56acc6..efbbb527c9b 100644
--- a/sql/winservice.c
+++ b/sql/winservice.c
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/*
Get Properties of an existing mysqld Windows service
diff --git a/sql/winservice.h b/sql/winservice.h
index c3e2bfe1b20..fe3fe526548 100644
--- a/sql/winservice.h
+++ b/sql/winservice.h
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/*
Extract properties of a windows service binary path
diff --git a/sql/wsrep_applier.h b/sql/wsrep_applier.h
index d58d3cdc54e..f19d2d46d0c 100644
--- a/sql/wsrep_applier.h
+++ b/sql/wsrep_applier.h
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#ifndef WSREP_APPLIER_H
#define WSREP_APPLIER_H
diff --git a/sql/wsrep_check_opts.cc b/sql/wsrep_check_opts.cc
index bc77c434525..8da791b3429 100644
--- a/sql/wsrep_check_opts.cc
+++ b/sql/wsrep_check_opts.cc
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#include "mysqld.h"
#include "sys_vars_shared.h"
diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc
index 2a93484002e..79dad571585 100644
--- a/sql/wsrep_hton.cc
+++ b/sql/wsrep_hton.cc
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#include <mysqld.h>
#include "sql_base.h"
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index b0275fc2fd5..9a99dffc724 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#include <mysqld.h>
#include <sql_class.h>
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index 0332432a199..8c81367d12f 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#include <wsrep.h>
diff --git a/sql/wsrep_notify.cc b/sql/wsrep_notify.cc
index d1beb9c38d6..92c685ba485 100644
--- a/sql/wsrep_notify.cc
+++ b/sql/wsrep_notify.cc
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#include <mysqld.h>
#include "wsrep_priv.h"
diff --git a/sql/wsrep_priv.h b/sql/wsrep_priv.h
index e2dc526608f..97307fcc948 100644
--- a/sql/wsrep_priv.h
+++ b/sql/wsrep_priv.h
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
//! @file declares symbols private to wsrep integration layer
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index 03cd8674242..076da23967a 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#include "wsrep_sst.h"
diff --git a/sql/wsrep_utils.cc b/sql/wsrep_utils.cc
index 9a9c2f84ac6..9c77cb49256 100644
--- a/sql/wsrep_utils.cc
+++ b/sql/wsrep_utils.cc
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
//! @file some utility functions and classes not directly related to replication
diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc
index e6d4bbbc303..b34fdf8b7ed 100644
--- a/sql/wsrep_var.cc
+++ b/sql/wsrep_var.cc
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#include "wsrep_var.h"
diff --git a/sql/wsrep_xid.cc b/sql/wsrep_xid.cc
index 876f791da69..2ff6ea0b32e 100644
--- a/sql/wsrep_xid.cc
+++ b/sql/wsrep_xid.cc
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
//! @file some utility functions and classes not directly related to replication